commit 8401142a14ef34278a09c92bf4648e476ea944e5 Author: 赵豪 <11985835+Meill2486@user.noreply.gitee.com> Date: Tue Jan 13 17:06:06 2026 +0800 init diff --git a/.flake8 b/.flake8 new file mode 100644 index 0000000..bdcfd32 --- /dev/null +++ b/.flake8 @@ -0,0 +1,4 @@ +[flake8] +max-line-length=100 +exclude=rplibs/*,data/*,hosek_wilkie_scattering,bake_gi,_DEV,*_generated.py,resources_rc.py + diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..478ed2a --- /dev/null +++ b/.gitignore @@ -0,0 +1,89 @@ +# --- Ignored extensions --- +# *.pyd +*.pyc +*.ignore +*.old +*.egg +*.psd +*.blend1 +*.blend2 +*.pdb +*.stackdump +*.exr +*.trace +*.autogen* +*.mip +mitsuba.*.log +*.exr +*.txo.pz +*.log +*.tmp +*.bak +.DS_Store +Thumbs.db + + +# --- Ignored folders and patterns --- +temp/ +models/ +data/film_grain/*.png +data/default_cubemap/filtered/ +_DEV +toolkit/pathtracing_reference/mitsuba/ +toolkit/pathtracing_reference/scene*.png +toolkit/pathtracing_reference/Scene*.blend +toolkit/pathtracing_reference/envmap.png +rpplugins/clouds/resources/slices/* + +toolkit/rp_distributor/built/ +__pycache__/ +.pytest_cache/ +.mypy_cache/ +.cache/ +build/ +dist/ +*.egg-info/ +htmlcov/ + +# Common IDE / venvs +.idea/ +.vscode +.venv +.env +.python-version + +# Big Models +assets/big_models/ + +# Samples folder +samples/ +test_models/ + +# Generated pipeline assets +data/**/*.txo +toolkit/**/__pycache__/ + +# --- Ignored files --- +TODO.txt +*.flag +desktop.ini +scattering_lut.png +old/ +data/gui/loading_screen +data/environment_brdf/scene.png +data/environment_brdf/res/scene.png +toolkit/pathtracing_reference/batch_compare/ +toolkit/pathtracing_reference/difference.png +toolkit/pathtracing_reference/res/Scene.blend +toolkit/pathtracing_reference/res/scene.png +toolkit/pathtracing_reference/scene*.png +toolkit/pathtracing_reference/res/tex/envmap.png +_tmp_material.py + +*/poisson_disk_generator/source/config_module* + +_bake_params* +raw-bake.png +toolkit/bake_gi/resources/*.bam +toolkit/bake_gi/resources/*.blend +toolkit/bake_gi/scene diff --git a/.pylintrc b/.pylintrc new file mode 100644 index 0000000..b9dbdcf --- /dev/null +++ b/.pylintrc @@ -0,0 +1,379 @@ +[MASTER] + +# Specify a configuration file. +#rcfile= + +# Python code to execute, usually for sys.path manipulation such as +# pygtk.require(). +init-hook= + +# Add files or directories to the blacklist. They should be base names, not +# paths. +ignore=CVS,rplibs,.git,scripts,build.py + +# Pickle collected data for later comparisons. +persistent=yes + +# List of plugins (as comma separated values of python modules names) to load, +# usually to register additional checkers. +load-plugins= + +# Use multiple processes to speed up Pylint. +jobs=1 + +# Allow loading of arbitrary C extensions. Extensions are imported into the +# active Python interpreter and may run arbitrary code. +unsafe-load-any-extension=no + +# A comma-separated list of package or module names from where C extensions may +# be loaded. Extensions are loading into the active Python interpreter and may +# run arbitrary code +extension-pkg-whitelist= + +# Allow optimization of some AST trees. This will activate a peephole AST +# optimizer, which will apply various small optimizations. For instance, it can +# be used to obtain the result of joining multiple strings with the addition +# operator. Joining a lot of strings can lead to a maximum recursion error in +# Pylint and this flag can prevent that. It has one side effect, the resulting +# AST will be different than the one from reality. +optimize-ast=yes + + +[MESSAGES CONTROL] + +# Only show warnings with the listed confidence levels. Leave empty to show +# all. Valid levels: HIGH, INFERENCE, INFERENCE_FAILURE, UNDEFINED +confidence= + +# Enable the message, report, category or checker with the given id(s). You can +# either give multiple identifier separated by comma (,) or put this option +# multiple time. See also the "--disable" option for examples. +#enable= + +# Disable the message, report, category or checker with the given id(s). You +# can either give multiple identifiers separated by comma (,) or put this +# option multiple times (only on the command line, not in the configuration +# file where it should appear only once).You can also use "--disable=all" to +# disable everything first and then reenable specific checks. For example, if +# you want to run only the similarities checker, you can use "--disable=all +# --enable=similarities". If you want to run only the classes checker, but have +# no Warning level messages displayed, use"--disable=all --enable=classes +# --disable=W" +disable=import-star-module-level,old-octal-literal,oct-method,print-statement,unpacking-in-except,parameter-unpacking,backtick,old-raise-syntax,old-ne-operator,long-suffix,dict-view-method,dict-iter-method,metaclass-assignment,next-method-called,raising-string,indexing-exception,raw_input-builtin,long-builtin,file-builtin,execfile-builtin,coerce-builtin,cmp-builtin,buffer-builtin,basestring-builtin,apply-builtin,filter-builtin-not-iterating,using-cmp-argument,useless-suppression,range-builtin-not-iterating,suppressed-message,no-absolute-import,old-division,cmp-method,reload-builtin,zip-builtin-not-iterating,intern-builtin,unichr-builtin,reduce-builtin,standarderror-builtin,unicode-builtin,xrange-builtin,coerce-method,delslice-method,getslice-method,setslice-method,input-builtin,round-builtin,hex-method,nonzero-method,map-builtin-not-iterating,E0611,W0622,W0201,C0111,R0201,R0913,R0902,R0904,R0914 + + +[REPORTS] + +# Set the output format. Available formats are text, parseable, colorized, msvs +# (visual studio) and html. You can also give a reporter class, eg +# mypackage.mymodule.MyReporterClass. +output-format=text + +# Put messages in a separate file for each module / package specified on the +# command line instead of printing them on stdout. Reports (if any) will be +# written in a file name "pylint_global.[txt|html]". +files-output=no + +# Tells whether to display a full report or only the messages +reports=yes + +# Python expression which should return a note less than 10 (10 is the highest +# note). You have access to the variables errors warning, statement which +# respectively contain the number of errors / warnings messages and the total +# number of statements analyzed. This is used by the global evaluation report +# (RP0004). +evaluation=10.0 - ((float(5 * error + warning + refactor + convention) / statement) * 10) + +# Template used to display messages. This is a python new-style format string +# used to format the message information. See doc for all details +#msg-template= + + +[BASIC] + +# List of builtins function names that should not be used, separated by a comma +bad-functions=map,filter,input,xrange,iteritems,raw_input + +# Good variable names which should always be accepted, separated by a comma +good-names=i,j,k,ex,Run,_,x,y,r,g,b,a,uv,w,h,np + +# Bad variable names which should always be refused, separated by a comma +bad-names=foo,bar,baz,toto,tutu,tata,tmp,temp + +# Colon-delimited sets of names that determine each other's naming style when +# the name regexes allow several styles. +name-group= + +# Include a hint for the correct naming format with invalid-name +include-naming-hint=no + +# Regular expression matching correct function names +function-rgx=[a-z_][a-z0-9_]{2,30}$ + +# Naming hint for function names +function-name-hint=[a-z_][a-z0-9_]{2,30}$ + +# Regular expression matching correct variable names +variable-rgx=[a-z_][a-z0-9_]{2,30}$ + +# Naming hint for variable names +variable-name-hint=[a-z_][a-z0-9_]{2,30}$ + +# Regular expression matching correct constant names +const-rgx=(([A-Z_][A-Z0-9_]*)|(__.*__))$ + +# Naming hint for constant names +const-name-hint=(([A-Z_][A-Z0-9_]*)|(__.*__))$ + +# Regular expression matching correct attribute names +attr-rgx=[a-z_][a-z0-9_]{2,30}$ + +# Naming hint for attribute names +attr-name-hint=[a-z_][a-z0-9_]{2,30}$ + +# Regular expression matching correct argument names +argument-rgx=[a-z_][a-z0-9_]{2,30}$ + +# Naming hint for argument names +argument-name-hint=[a-z_][a-z0-9_]{2,30}$ + +# Regular expression matching correct class attribute names +class-attribute-rgx=([A-Za-z_][A-Za-z0-9_]{2,30}|(__.*__))$ + +# Naming hint for class attribute names +class-attribute-name-hint=([A-Za-z_][A-Za-z0-9_]{2,30}|(__.*__))$ + +# Regular expression matching correct inline iteration names +inlinevar-rgx=[A-Za-z_][A-Za-z0-9_]*$ + +# Naming hint for inline iteration names +inlinevar-name-hint=[A-Za-z_][A-Za-z0-9_]*$ + +# Regular expression matching correct class names +class-rgx=[A-Z_][a-zA-Z0-9]+$ + +# Naming hint for class names +class-name-hint=[A-Z_][a-zA-Z0-9]+$ + +# Regular expression matching correct module names +module-rgx=(([a-z_][a-z0-9_]*)|([A-Z][a-zA-Z0-9]+))$ + +# Naming hint for module names +module-name-hint=(([a-z_][a-z0-9_]*)|([A-Z][a-zA-Z0-9]+))$ + +# Regular expression matching correct method names +method-rgx=[a-z_][a-z0-9_]{2,30}$ + +# Naming hint for method names +method-name-hint=[a-z_][a-z0-9_]{2,30}$ + +# Regular expression which should only match function or class names that do +# not require a docstring. +no-docstring-rgx=^_ + +# Minimum line length for functions/classes that require docstrings, shorter +# ones are exempt. +docstring-min-length=-1 + + +[ELIF] + +# Maximum number of nested blocks for function / method body +max-nested-blocks=4 + + +[FORMAT] + +# Maximum number of characters on a single line. +max-line-length=100 + +# Regexp for a line that is allowed to be longer than the limit. +ignore-long-lines=^\s*(# )??$ + +# Allow the body of an if to be on the same line as the test if there is no +# else. +single-line-if-stmt=no + +# List of optional constructs for which whitespace checking is disabled. `dict- +# separator` is used to allow tabulation in dicts, etc.: {1 : 1,\n222: 2}. +# `trailing-comma` allows a space between comma and closing bracket: (a, ). +# `empty-line` allows space-only lines. +no-space-check=trailing-comma,dict-separator + +# Maximum number of lines in a module +max-module-lines=1000 + +# String used as indentation unit. This is usually " " (4 spaces) or "\t" (1 +# tab). +indent-string=' ' + +# Number of spaces of indent required inside a hanging or continued line. +indent-after-paren=4 + +# Expected format of line ending, e.g. empty (any line ending), LF or CRLF. +expected-line-ending-format= + + +[LOGGING] + +# Logging modules to check that the string format arguments are in logging +# function parameter format +logging-modules=logging + + +[MISCELLANEOUS] + +# List of note tags to take in consideration, separated by a comma. +notes= + + +[SIMILARITIES] + +# Minimum lines number of a similarity. +min-similarity-lines=8 + +# Ignore comments when computing similarities. +ignore-comments=yes + +# Ignore docstrings when computing similarities. +ignore-docstrings=yes + +# Ignore imports when computing similarities. +ignore-imports=no + + +[SPELLING] + +# Spelling dictionary name. Available dictionaries: none. To make it working +# install python-enchant package. +spelling-dict= + +# List of comma separated words that should not be checked. +spelling-ignore-words= + +# A path to a file that contains private dictionary; one word per line. +spelling-private-dict-file= + +# Tells whether to store unknown words to indicated private dictionary in +# --spelling-private-dict-file option instead of raising a message. +spelling-store-unknown-words=no + + +[TYPECHECK] + +# Tells whether missing members accessed in mixin class should be ignored. A +# mixin class is detected if its name ends with "mixin" (case insensitive). +ignore-mixin-members=yes + +# List of module names for which member attributes should not be checked +# (useful for modules/projects where namespaces are manipulated during runtime +# and thus existing member attributes cannot be deduced by static analysis. It +# supports qualified module names, as well as Unix pattern matching. +ignored-modules= + +# List of classes names for which member attributes should not be checked +# (useful for classes with attributes dynamically set). This supports can work +# with qualified names. +ignored-classes= + +# List of members which are set dynamically and missed by pylint inference +# system, and so shouldn't trigger E1101 when accessed. Python regular +# expressions are accepted. +generated-members= + + +[VARIABLES] + +# Tells whether we should check for unused import in __init__ files. +init-import=no + +# A regular expression matching the name of dummy variables (i.e. expectedly +# not used). +dummy-variables-rgx=_$|dummy + +# List of additional names supposed to be defined in builtins. Remember that +# you should avoid to define new builtins when possible. +additional-builtins= + +# List of strings which can identify a callback function by name. A callback +# name must start or end with one of those strings. +callbacks=cb_,_cb + + +[CLASSES] + +# List of method names used to declare (i.e. assign) instance attributes. +defining-attr-methods=__init__,__new__,setup,init,load,create + +# List of valid names for the first argument in a class method. +valid-classmethod-first-arg=cls + +# List of valid names for the first argument in a metaclass class method. +valid-metaclass-classmethod-first-arg=mcs + +# List of member names, which should be excluded from the protected access +# warning. +exclude-protected=_asdict,_fields,_replace,_source,_make + + +[DESIGN] + +# Maximum number of arguments for function / method +max-args=5 + +# Argument names that match this expression will be ignored. Default to name +# with leading underscore +ignored-argument-names=_.* + +# Maximum number of locals for function / method body +max-locals=15 + +# Maximum number of return / yield for function / method body +max-returns=6 + +# Maximum number of branch for function / method body +max-branches=12 + +# Maximum number of statements in function / method body +max-statements=50 + +# Maximum number of parents for a class (see R0901). +max-parents=7 + +# Maximum number of attributes for a class (see R0902). +max-attributes=7 + +# Minimum number of public methods for a class (see R0903). +min-public-methods=2 + +# Maximum number of public methods for a class (see R0904). +max-public-methods=20 + +# Maximum number of boolean expressions in a if statement +max-bool-expr=5 + + +[IMPORTS] + +# Deprecated modules which should not be used, separated by a comma +deprecated-modules=regsub,TERMIOS,Bastion,rexec + +# Create a graph of every (i.e. internal and external) dependencies in the +# given file (report RP0402 must not be disabled) +import-graph= + +# Create a graph of external dependencies in the given file (report RP0402 must +# not be disabled) +ext-import-graph= + +# Create a graph of internal dependencies in the given file (report RP0402 must +# not be disabled) +int-import-graph= + + +[EXCEPTIONS] + +# Exceptions that will emit a warning when being caught. Defaults to +# "Exception" +overgeneral-exceptions=Exception + diff --git a/.travis.yml b/.travis.yml new file mode 100644 index 0000000..e7cad25 --- /dev/null +++ b/.travis.yml @@ -0,0 +1,18 @@ +language: cpp +sudo: required +dist: trusty +compiler: gcc +addons: + apt: + sources: + - sourceline: "deb http://archive.panda3d.org/ubuntu/ trusty-dev main" + packages: + - cmake + - libeigen3-dev + - libfreetype6-dev + - panda3d1.10 + +script: + - export PYTHONPATH=${PYTHONPATH}:/usr/lib/python2.7/dist-packages + - export PYTHONPATH=${PYTHONPATH}:/usr/share/panda3d + - python2.7 setup.py --ci-build diff --git a/Builtin/Elements.py b/Builtin/Elements.py new file mode 100644 index 0000000..031dc1d --- /dev/null +++ b/Builtin/Elements.py @@ -0,0 +1,339 @@ +""" + + + +OUTDATED + +Do not use anymore. + + +""" + + +import colorsys + +from LUIObject import LUIObject +from LUISlider import LUISlider +from LUISprite import LUISprite +from LUIVerticalLayout import LUIVerticalLayout +from LUICallback import LUICallback +from LUILabel import LUILabel +from LUIFrame import LUIFrame +from LUIButton import LUIButton + +class LUISliderWithLabel(LUIObject, LUICallback): + + def __init__(self, parent=None, width=100.0, filled=False, min_value=0, max_value=1.0, precision=2, value=None): + LUIObject.__init__(self, x=0, y=0, w=width, h=0) + LUICallback.__init__(self) + + max_numbers_before = max(len(str(int(max_value))), len(str(int(min_value)))) + number_space_required = max_numbers_before + + if precision > 0: + number_space_required += 1 + precision + + pixels_per_number = 7 + self.precision = precision + + self.slider = LUISlider(self, width=width - pixels_per_number * number_space_required - 5, filled=filled, min_value=min_value, max_value=max_value, value=value) + self.label = LUILabel(parent=self, shadow=True, text=u"1.23") + self.label.right = 0 + self.label.top = self.label.height - self.slider.height + self.label.color = (1,1,1,0.5) + + self.slider.add_change_callback(self._on_slider_changed) + self.slider.add_change_callback(self._trigger_callback) + self._on_slider_changed(self.slider, self.slider.get_value()) + + if parent is not None: + self.parent = parent + + self.fit_to_children() + + def get_value(self): + return self.slider.get_value() + + def set_value(self, val): + self.slider.set_value(val) + + def _on_slider_changed(self, obj, value): + self.label.text = ("{:." + str(self.precision) + "f}").format(value) + +class LUIKeyMarker(LUIObject): + + def __init__(self, parent=None, key=u"A"): + LUIObject.__init__(self) + self.bgLeft = LUISprite(self, "Keymarker_Left", "skin") + self.bgMid = LUISprite(self, "Keymarker", "skin") + self.bgRight = LUISprite(self, "Keymarker_Right", "skin") + + self.label = LUILabel(parent=self, text=key, shadow=True) + self.label.centered = (True, True) + self.label.margin = (-3, 0, 0, -1) + self.margin = (-1, 0, 0, -1) + + self.set_key(key) + + if parent is not None: + self.parent = parent + + self.fit_to_children() + + def set_key(self, key): + self.label.set_text(key) + self.width = self.label.width + self.bgLeft.width + self.bgRight.width + 7 + self.bgMid.width = self.width - self.bgLeft.width - self.bgRight.width + self.bgMid.left = self.bgLeft.width + self.bgRight.left = self.bgMid.width + self.bgMid.left + + self.fit_to_children() + +class LUIKeyInstruction(LUIObject): + + def __init__(self, parent=None, key=u"A", instruction=u"Instruction"): + LUIObject.__init__(self) + self.marker = LUIKeyMarker(parent=self, key=key) + self.instructionLabel = LUILabel(parent=self, text=instruction, shadow=True) + self.instructionLabel.centered = (False, True) + self.instructionLabel.margin.top = -4 + self.set_key(key) + + def set_key(self, key): + self.marker.set_key(key) + self.instructionLabel.left = self.marker.width + 5 + self.fit_to_children() + + +class LUIColorpicker(LUIObject): + + def __init__(self, parent=None, color=None): + LUIObject.__init__(self, x=0, y=0, w=27, h=27) + + self.previewBg = LUISprite(self, "ColorpickerPreviewBg", "skin") + + self.filler = LUISprite(self, "blank", "skin") + self.filler.width = 21 + self.filler.height = 21 + self.filler.pos = (5, 5) + self.filler.color = (0.2,0.6,1.0,1.0) + + self.overlay = LUISprite(self, "ColorpickerPreviewOverlay", "skin") + self.overlay.pos = (2, 2) + self.overlay.bind("click", self._open_dialog) + + self.fit_to_children() + + self.popup = LUIColorpickerPopup(self) + self.popup.hide() + + if color is not None: + self.colorValue = color + else: + # My favourite color + self.colorValue = (0.2, 0.6, 1.0) + self.set_color_value(self.colorValue) + + self.popup.add_change_callback(self._on_popup_color_changed) + + if parent is not None: + self.parent = parent + + def _open_dialog(self, event): + if self.has_focus(): + self.blur() + else: + self.request_focus() + + def on_focus(self, event): + self.popup._load_rgb(self.colorValue) + self.popup.open_at(self, 14.0) + + def set_color_value(self, rgb): + self.colorValue = rgb + self.filler.color = rgb + + def get_color_value(self): + return self.colorValue + + def on_tick(self, event): + self.popup._update(event) + + def on_blur(self, event): + self.popup.close() + + def _on_popup_color_changed(self, popup, rgb): + self.set_color_value(rgb) + + def _on_popup_closed(self): + self.blur() + + +class LUIPopup(LUIFrame): + + def __init__(self, parent=None, width=200, height=200): + LUIFrame.__init__(self, parent=parent, width=width, height=height, padding=10, innerPadding=0) + self.topmost = True + self.borderSize = 33 + self.content.bind("click", self._on_content_click) + + def open_at(self, targetElement, distance): + self.show() + + targetPos = targetElement.get_abs_pos()+ targetElement.get_size() / 2 + + showAbove = targetPos.y > self.height - self.borderSize + showLeft = targetPos.x > self.width - self.borderSize + + relative = self.get_relative_pos(targetPos) + self.pos += relative + + if showLeft: + self.left -= self.width - self.borderSize + self.left += 25 + else: + self.left -= self.borderSize + self.left -= 25 + + if showAbove: + self.top -= distance + self.top -= self.height - self.borderSize + else: + self.top += distance + self.top -= self.borderSize + + + def _on_content_click(self, event): + pass + + def close(self): + self.hide() + +class LUIColorpickerPopup(LUIPopup, LUICallback): + def __init__(self, parent=None): + LUIPopup.__init__(self, parent=parent, width=240, height=146) + LUICallback.__init__(self) + + self.field = LUIObject(self.content, x=0, y=0, w=128, h=128) + + self.fieldBG = LUISprite(self.field, "blank", "skin") + self.fieldBG.size = (128, 128) + self.fieldBG.color = (0.2,0.6,1.0) + self.fieldFG = LUISprite(self.field, "ColorpickerFieldOverlay", "skin") + self.fieldFG.pos = (-2, 0) + + self.fieldBG.bind("mousedown", self._start_field_dragging) + self.fieldBG.bind("mouseup", self._stop_field_dragging) + + self.fieldHandle = LUISprite(self.field, "ColorpickerFieldHandle", "skin") + self.fieldHandle.bind("mousedown", self._start_field_dragging) + self.fieldHandle.bind("mouseup", self._stop_field_dragging) + + self.fieldDragging = False + + self.hueSlider = LUIObject(self.content, x=140, y=0, w=40, h=128) + self.hueSliderFG = LUISprite(self.hueSlider, "ColorpickerHueSlider", "skin") + + self.hueHandle = LUISprite(self.hueSlider, "ColorpickerHueHandle", "skin") + self.hueHandle.left = (self.hueSliderFG.width - self.hueHandle.width) / 2.0 + self.hueHandle.top = 50 + + self.hueDragging = False + self.hueSlider.bind("mousedown", self._start_hue_dragging) + self.hueSlider.bind("mouseup", self._stop_hue_dragging) + + self.labels = LUIVerticalLayout(self.content, width=40) + self.labels.pos = (177, 42) + + colors = [u"R", u"G", u"B"] + self.colorLabels = [] + + for color in colors: + label = LUILabel(text=color, shadow=True) + label.color = (1,1,1,0.3) + + valueLabel = LUILabel(text=u"255", shadow=True) + valueLabel.right = 0 + self.labels.add(label, valueLabel) + self.colorLabels.append(valueLabel) + + self.activeColor = LUIObject(self.content, x=177, y=0) + self.activeColorBG = LUISprite(self.activeColor, "blank", "skin") + self.activeColorFG = LUISprite(self.activeColor, "ColorpickerActiveColorOverlay", "skin") + + self.activeColorBG.size = (40, 40) + self.activeColorBG.pos = (2, 0) + self.activeColorBG.color = (0.2,0.6,1.0,1.0) + + self.closeButton = LUIButton(parent=self.content, text=u"Done", width=45, template="ButtonGreen") + self.closeButton.left = 177 + self.closeButton.top = 98 + self.closeButton.bind("click", self._close_popup) + + self._set_hue(0.5) + self._set_sat_val(0.5, 0.5) + + self.widget = parent + + def _load_rgb(self, rgb): + hsv = colorsys.rgb_to_hsv(*rgb) + self._set_hue(hsv[0]) + self._set_sat_val(hsv[1], hsv[2]) + + def _close_popup(self, event): + self.widget._on_popup_closed() + self.close() + + def _update(self, event): + if self.hueDragging: + offset = event.coordinates.y - self.hueSliderFG.abs_pos.y + offset /= 128.0 + offset = 1.0 - max(0.0, min(1.0, offset)) + self._set_hue(offset) + + if self.fieldDragging: + offset = event.coordinates - self.fieldBG.abs_pos + saturation = max(0.0, min(1.0, offset.x / 128.0)) + value = 1.0 - max(0.0, min(1.0, offset.y / 128.0)) + self._set_sat_val(saturation, value) + + self._update_color() + + def _set_sat_val(self, sat, val): + self.saturation = sat + self.valueValue = val + + self.fieldHandle.top = (1.0 - self.valueValue) * 128.0 - self.fieldHandle.height / 2.0 + self.fieldHandle.left = self.saturation * 128.0 - self.fieldHandle.width / 2.0 + + def _set_hue(self, hue): + self.hueValue = min(0.999, hue) + self.hueHandle.top = (1.0-hue) * 128.0 - self.hueHandle.height / 2 + self.fieldBG.color = colorsys.hsv_to_rgb(self.hueValue, 1, 1) + + def _update_color(self): + rgb = colorsys.hsv_to_rgb(self.hueValue, self.saturation, self.valueValue) + self.activeColorBG.color = rgb + + self.colorLabels[0].set_text(str(int(rgb[0]*255.0))) + self.colorLabels[1].set_text(str(int(rgb[1]*255.0))) + self.colorLabels[2].set_text(str(int(rgb[2]*255.0))) + + self._trigger_callback(rgb) + + def _start_field_dragging(self, event): + if not self.fieldDragging: + self.fieldDragging = True + + def _stop_field_dragging(self, event): + if self.fieldDragging: + self.fieldDragging = False + + def _start_hue_dragging(self, event): + if not self.hueDragging: + self.hueDragging = True + + def _stop_hue_dragging(self, event): + if self.hueDragging: + self.hueDragging = False + diff --git a/Builtin/LUIBlockText.py b/Builtin/LUIBlockText.py new file mode 100644 index 0000000..d74d3c8 --- /dev/null +++ b/Builtin/LUIBlockText.py @@ -0,0 +1,100 @@ + +from panda3d.core import LVecBase2i +from LUIObject import LUIObject +from LUILabel import LUILabel +from LUIInitialState import LUIInitialState + +__all__ = ["LUIBlockText"] + + +class LUIBlockText(LUIObject): + + """ Small helper class to format labels into paragraphs. + Uses LUILabels internally """ + + def __init__(self, **kwargs): + """ Creates a new block of text. """ + LUIObject.__init__(self) + LUIInitialState.init(self, kwargs) + self._cursor = LVecBase2i(0) + self._last_size = 14 + + self.labels = [] + + + def clear(self): + """ Removes all text from this label and resets it to the initial state. + This will also detach the sub-labels from this label. """ + self._cursor.set(0, 0) + self.labels = [] + self.remove_all_children() + + + def newline(self, font_size=None): + """ Moves the cursor to the next line. The font size controls how much + the cursor will move. By default, the font size of the last added text + is used, or if no text was added yet, a size of 14.""" + self._cursor.x = 0 + if font_size is None: + font_size = self._last_size + self._cursor.y += font_size + 2 + + + def add(self, *args, **kwargs): + """ Appends a new text. The arguments are equal to the arguments of + LUILabel. The arguments shouldn't contain information about the + placement like top_left, or center_vertical, since the labels are + placed at explicit positions. """ + self._last_size = kwargs.get("font_size", 14) + label = LUILabel(parent=self, left=self._cursor.x, top=self._cursor.y, width=self.get_width(), + *args, **kwargs) + + self.labels.append(label) + + # This is a bit of a hack, we should use a horizontal layout, but we + # don't for performance reasons. + self._cursor.y += label.text_handle.height + + # After every paragraph, we add a new line. + self.newline() + + + def set_text(self, text): + """ Replaces the text with new text """ + self.clear() + self.add(text=text) + + + def update_height(self): + """ Updates the height of the element, adding a newline to the end of + every paragraph """ + top = 0 + for child in self.labels: + child.top = top + top += child._text.height + + # Newline + top += self._last_size + 2 + + + def set_wrap(self, wrap): + """ Sets text wrapping for the element. Wrapping breaks lines on + spaces, and breaks words if the word is longer than the line + length. """ + for child in self.children: + for c in child.children: + c.set_wordwrap(wrap) + + self.update_height() + + + def set_width(self, width): + """ Sets the width of this element, and turns on wrapping. """ + for child in self.children: + child.set_width(width) + + # Need to force an update to the text when the width changes. + for c in child.children: + c.set_wordwrap(True) + + self.update_height() diff --git a/Builtin/LUIButton.py b/Builtin/LUIButton.py new file mode 100644 index 0000000..93e5613 --- /dev/null +++ b/Builtin/LUIButton.py @@ -0,0 +1,52 @@ + +from LUIObject import LUIObject +from LUILayouts import LUIHorizontalStretchedLayout +from LUILabel import LUILabel +from LUIInitialState import LUIInitialState + +__all__ = ["LUIButton"] + + +class LUIButton(LUIObject): + + """ Simple button, containing three sprites and a label. """ + + def __init__(self, text="Button", template="ButtonDefault", **kwargs): + """ Constructs a new button. The template controls which sprites to use. + If the template is "ButtonDefault" for example, the sprites + "ButtonDefault_Left", "ButtonDefault" and "ButtonDefault_Right" will + be used. The sprites used when the button is pressed should be named + "ButtonDefaultFocus_Left" and so on then. + + If an explicit width is set on the button, the button will stick to + that width, otherwise it will automatically resize to fit the label """ + LUIObject.__init__(self, x=0, y=0, solid=True) + self._template = template + self._layout = LUIHorizontalStretchedLayout( + parent=self, prefix=self._template, width="100%") + self._label = LUILabel(parent=self, text=text) + self._label.z_offset = 1 + self._label.center_vertical = True + self._label.margin = 0, 20, 0, 20 + self.margin.left = -1 + LUIInitialState.init(self, kwargs) + + @property + def text(self): + """ Returns the current label text of the button """ + return self._label.text + + @text.setter + def text(self, text): + """ Sets the label text of the button """ + self._label.text = text + + def on_mousedown(self, event): + """ Internal on_mousedown handler. Do not override """ + self._layout.prefix = self._template + "Focus" + self._label.margin.top = 1 + + def on_mouseup(self, event): + """ Internal on_mouseup handler. Do not override """ + self._layout.prefix = self._template + self._label.margin.top = 0 diff --git a/Builtin/LUICheckbox.py b/Builtin/LUICheckbox.py new file mode 100644 index 0000000..11fdbc7 --- /dev/null +++ b/Builtin/LUICheckbox.py @@ -0,0 +1,83 @@ + +from __future__ import division + +from LUIObject import LUIObject +from LUISprite import LUISprite +from LUILabel import LUILabel +from LUIInitialState import LUIInitialState + +__all__ = ["LUICheckbox"] + + +class LUICheckbox(LUIObject): + + """ This is a simple checkbox, including a Label. The checkbox can either + be checked or unchecked. """ + + def __init__(self, checked=False, label=u"Checkbox", **kwargs): + """ Constructs a new checkbox with the given label and state. By default, + the checkbox is not checked. """ + LUIObject.__init__(self, x=0, y=0, solid=True) + self._checked = checked + self._checkbox_sprite = LUISprite(self, "Checkbox_Default", "skin") + self._label = LUILabel(parent=self, text=label, margin=(0, 0, 0, 25), + center_vertical=True, alpha=0.4) + self._hovered = False + self._update_sprite() + LUIInitialState.init(self, kwargs) + + @property + def checked(self): + """ Returns True if the checkbox is currently checked """ + return self._checked + + @checked.setter + def checked(self, checked): + """ Sets the checkbox state """ + self._checked = checked + self._update_sprite() + + def toggle(self): + """ Toggles the checkbox state """ + self.checked = not self.checked + + @property + def label(self): + """ Returns a handle to the label, so it can be modified """ + return self._label + + @property + def sprite(self): + """ Returns a handle to the internal checkbox sprite """ + return self._checkbox_sprite + + def on_click(self, event): + """ Internal onclick handler. Do not override """ + self._checked = not self._checked + self.trigger_event("changed") + self._update_sprite() + + def on_mousedown(self, event): + """ Internal mousedown handler. """ + self._checkbox_sprite.color = (0.9, 0.9, 0.9, 1.0) + + def on_mouseup(self, event): + """ Internal on_mouseup handler. """ + self._checkbox_sprite.color = (1, 1, 1, 1) + + def on_mouseover(self, event): + """ Internal mouseover handler """ + self._hovered = True + self._update_sprite() + + def on_mouseout(self, event): + """ Internal mouseout handler """ + self._hovered = False + self._update_sprite() + + def _update_sprite(self): + """ Internal method to update the sprites """ + img = "Checkbox_Checked" if self._checked else "Checkbox_Default" + if self._hovered: + img += "Hover" + self._checkbox_sprite.set_texture(img, "skin") diff --git a/Builtin/LUIFormattedLabel.py b/Builtin/LUIFormattedLabel.py new file mode 100644 index 0000000..fad7df3 --- /dev/null +++ b/Builtin/LUIFormattedLabel.py @@ -0,0 +1,47 @@ + +from panda3d.core import LVecBase2i +from LUIObject import LUIObject +from LUILabel import LUILabel +from LUIInitialState import LUIInitialState + +__all__ = ["LUIFormattedLabel"] + + +class LUIFormattedLabel(LUIObject): + + """ Small helper class to build a text consisting of different formatted + parts of text. Uses LUILabels internally """ + + def __init__(self, **kwargs): + """ Creates a new formatted label. """ + LUIObject.__init__(self) + LUIInitialState.init(self, kwargs) + self._cursor = LVecBase2i(0) + self._last_size = 14 + + def clear(self): + """ Removes all text from this label and resets it to the initial state. + This will also detach the sub-labels from this label. """ + self._cursor.set(0, 0) + self.remove_all_children() + + def newline(self, font_size=None): + """ Moves the cursor to the next line. The font size controls how much + the cursor will move. By default, the font size of the last added text + is used, or if no text was added yet, a size of 14.""" + self._cursor.x = 0 + if font_size is None: + font_size = self._last_size + self._cursor.y += font_size + 2 + + def add(self, *args, **kwargs): + """ Appends a new text. The arguments are equal to the arguments of + LUILabel. The arguments shouldn't contain information about the + placement like top_left, or center_vertical, since the labels are + placed at explicit positions. """ + self._last_size = kwargs.get("font_size", 14) + label = LUILabel(parent=self, left=self._cursor.x, top=self._cursor.y, + *args, **kwargs) + # This is a bit of a hack, we should use a horizontal layout, but we + # don't for performance reasons. + self._cursor.x += label.text_handle.width diff --git a/Builtin/LUIFrame.py b/Builtin/LUIFrame.py new file mode 100644 index 0000000..4408b5c --- /dev/null +++ b/Builtin/LUIFrame.py @@ -0,0 +1,66 @@ + +from __future__ import print_function + +from LUIObject import LUIObject +from LUISprite import LUISprite +from LUILayouts import LUICornerLayout +from LUIInitialState import LUIInitialState +from LUIScrollableRegion import LUIScrollableRegion + +__all__ = ["LUIFrame"] + + +class LUIFrame(LUIObject): + + """ A container which can store multiple ui-elements. If you don't want a + border/background, you should use an empty LUIObject as container instead. + """ + + FS_sunken = 1 + FS_raised = 2 + + def __init__(self, inner_padding=5, scrollable=False, style=FS_raised, + **kwargs): + """ Creates a new frame with the given options and style. If scrollable + is True, the contents of the frame will scroll if they don't fit into + the frame height. inner_padding only has effect if scrollable is True. + You can call fit_to_children() to make the frame fit automatically to + it's contents.""" + LUIObject.__init__(self) + + # Each *style* has a different border size (size of the shadow). The + # border size shouldn't get calculated to the actual framesize, so we + # are determining it first and then substracting it. + # TODO: We could do this automatically, determined by the sprite size + # probably? + self._border_size = 0 + self.padding = 10 + self.solid = True + prefix = "" + + if style == LUIFrame.FS_raised: + temp = LUISprite(self, "Frame_Left", "skin") + self._border_size = temp.width + self.remove_child(temp) + prefix = "Frame_" + elif style == LUIFrame.FS_sunken: + self._border_size = 0 + prefix = "SunkenFrame_" + else: + raise Exception("Unkown LUIFrame style: " + style) + + self._scrollable = scrollable + self._layout = LUICornerLayout(parent=self, image_prefix=prefix) + self._layout.margin = -(self.padding.top + self._border_size) + if self._scrollable: + self._content = LUIObject(self) + self._content.size = (self.width, self.height) + self._content.pos = (self._border_size, self._border_size) + self._scroll_content = LUIScrollableRegion( + self._content, + width=self.width - 2 * self.padding.left, + height=self.height - 2 * self.padding.left, + padding=inner_padding) + self.content_node = self._scroll_content.content_node + + LUIInitialState.init(self, kwargs) diff --git a/Builtin/LUIHorizontalLayout.py b/Builtin/LUIHorizontalLayout.py new file mode 100644 index 0000000..3a887a2 --- /dev/null +++ b/Builtin/LUIHorizontalLayout.py @@ -0,0 +1,20 @@ +""" + +This is a wrapper file. It contains no actual implementation + +""" + +from panda3d.lui import LUIHorizontalLayout as _LUIHorizontalLayout +from LUIInitialState import LUIInitialState + +__all__ = ["LUIHorizontalLayout"] + + +class LUIHorizontalLayout(_LUIHorizontalLayout): + """ This is a wrapper class for the C++ LUIHorizontalLayout class, to be + able to use it in a more convenient way. It leverages LUIInitialState + to be able to pass arbitrary keyword arguments. """ + + def __init__(self, parent=None, spacing=0.0, **kwargs): + _LUIHorizontalLayout.__init__(self, parent, spacing) + LUIInitialState.init(self, kwargs) diff --git a/Builtin/LUIInitialState.py b/Builtin/LUIInitialState.py new file mode 100644 index 0000000..cf3eb59 --- /dev/null +++ b/Builtin/LUIInitialState.py @@ -0,0 +1,41 @@ + +__all__ = ["LUIInitialState"] + + +class LUIInitialState: + + """ Small helper class to pass keyword arguments to the LUI-objects. It takes + all keyword arguments of a given call, and calls obj. = for + each keyword. It usually is called at the end of the __init__ method. """ + + def __init__(self): + raise Exception("LUIInitialState is a static class") + + # Some properties have alternative names, under which they can be accessed. + __MAPPINGS = { + "x": "left", + "y": "top", + "w": "width", + "h": "height" + } + + @classmethod + def init(cls, obj, kwargs): + """ Applies all keyword arguments as properties. For example, passing + dict({"left": 10, "top": 3, "color": (0.2, 0.6, 1.0)}) results in + behaviour similar to: + + element.left = 10 + element.top = 3 + element.color = 0.2, 0.6, 1.0 + + Calling this method allows setting arbitrary properties in + constructors, without having to specify each possible keyword argument. + """ + for arg_name, arg_val in kwargs.items(): + arg_name = cls.__MAPPINGS.get(arg_name, arg_name) + if hasattr(obj, arg_name): + setattr(obj, arg_name, arg_val) + else: + raise AttributeError("{0} has no attribute {1}".format( + obj.__class__.__name__, arg_name)) diff --git a/Builtin/LUIInputField.py b/Builtin/LUIInputField.py new file mode 100644 index 0000000..b3863c2 --- /dev/null +++ b/Builtin/LUIInputField.py @@ -0,0 +1,219 @@ +import re + +from LUIObject import LUIObject +from LUISprite import LUISprite +from LUILabel import LUILabel +from LUIInitialState import LUIInitialState +from LUILayouts import LUIHorizontalStretchedLayout + +__all__ = ["LUIInputField"] + + +class LUIInputField(LUIObject): + + """ Simple input field, accepting text input. This input field supports + entering text and navigating. Selecting text is (currently) not supported. + + The input field also supports various keyboard shortcuts: + + [pos1] Move to the beginning of the text + [end] Move to the end of the text + [arrow_left] Move one character to the left + [arrow_right] Move one character to the right + [ctrl] + [arrow_left] Move to the left, skipping over words + [ctrl] + [arrow_right] Move to the right, skipping over words + [escape] Un-focus input element + + """ + + re_skip = re.compile("\W*\w+\W") + + def __init__(self, parent=None, width=200, placeholder=u"Enter some text ..", value=u"", **kwargs): + """ Constructs a new input field. An input field always needs a width specified """ + LUIObject.__init__(self, x=0, y=0, solid=True) + self.set_width(width) + self._layout = LUIHorizontalStretchedLayout(parent=self, prefix="InputField", width="100%") + + # Container for the text + self._text_content = LUIObject(self) + self._text_content.margin = (5, 7, 5, 7) + self._text_content.clip_bounds = (0,0,0,0) + self._text_content.set_size("100%", "100%") + + # Scroller for the text, so we can move right and left + self._text_scroller = LUIObject(parent=self._text_content) + self._text_scroller.center_vertical = True + self._text = LUILabel(parent=self._text_scroller, text="") + + # Cursor for the current position + self._cursor = LUISprite(self._text_scroller, "blank", "skin", x=0, y=0, w=2, h=15) + self._cursor.color = (0.5, 0.5, 0.5) + self._cursor.margin.top = 2 + self._cursor.z_offset = 20 + self._cursor_index = 0 + self._cursor.hide() + self._value = value + + # Placeholder text, shown when out of focus and no value exists + self._placeholder = LUILabel(parent=self._text_content, text=placeholder, shadow=False, + center_vertical=True, alpha=0.2) + + # Various states + self._tickrate = 1.0 + self._tickstart = 0.0 + + self._render_text() + + if parent is not None: + self.parent = parent + + LUIInitialState.init(self, kwargs) + + @property + def value(self): + """ Returns the value of the input field """ + return self._value + + @value.setter + def value(self, new_value): + """ Sets the value of the input field """ + self._value = new_value + self._render_text() + self.trigger_event("changed", self._value) + + def clear(self): + """ Clears the input value """ + self.value = u"" + + @property + def cursor_pos(self): + """ Set the cursor position """ + return self._cursor_index + + @cursor_pos.setter + def cursor_pos(self, pos): + """ Set the cursor position """ + if pos >= 0: + self._cursor_index = max(0, min(len(self._value), pos)) + else: + self._cursor_index = max(len(self._value) + pos + 1, 0) + self._reset_cursor_tick() + self._render_text() + + def on_tick(self, event): + """ Tick handler, gets executed every frame """ + frame_time = globalClock.get_frame_time() - self._tickstart + show_cursor = frame_time % self._tickrate < 0.5 * self._tickrate + if show_cursor: + self._cursor.color = (0.5, 0.5, 0.5, 1) + else: + self._cursor.color = (1, 1, 1, 0) + + def on_click(self, event): + """ Internal on click handler """ + self.request_focus() + + def on_mousedown(self, event): + """ Internal mousedown handler """ + local_x_offset = self._text.text_handle.get_relative_pos(event.coordinates).x + self.cursor_pos = self._text.text_handle.get_char_index(local_x_offset) + + def _reset_cursor_tick(self): + """ Internal method to reset the cursor tick """ + self._tickstart = globalClock.get_frame_time() + + def on_focus(self, event): + """ Internal focus handler """ + self._cursor.show() + self._placeholder.hide() + self._reset_cursor_tick() + self._layout.color = (0.9, 0.9, 0.9, 1) + + def on_keydown(self, event): + """ Internal keydown handler. Processes the special keys, and if none are + present, redirects the event """ + key_name = event.message + if key_name == "backspace": + self._value = self._value[:max(0, self._cursor_index - 1)] + self._value[self._cursor_index:] + self.cursor_pos -= 1 + self.trigger_event("changed", self._value) + elif key_name == "delete": + post_value = self._value[min(len(self._value), self._cursor_index + 1):] + self._value = self._value[:self._cursor_index] + post_value + self.cursor_pos = self._cursor_index + self.trigger_event("changed", self._value) + elif key_name == "arrow_left": + if event.get_modifier_state("alt") or event.get_modifier_state("ctrl"): + self.cursor_skip_left() + else: + self.cursor_pos -= 1 + elif key_name == "arrow_right": + if event.get_modifier_state("alt") or event.get_modifier_state("ctrl"): + self.cursor_skip_right() + else: + self.cursor_pos += 1 + elif key_name == "escape": + self.blur() + elif key_name == "home": + self.cursor_pos = 0 + elif key_name == "end": + self.cursor_pos = len(self.value) + + self.trigger_event(key_name, self._value) + + def on_keyrepeat(self, event): + """ Internal keyrepeat handler """ + self.on_keydown(event) + + def on_textinput(self, event): + """ Internal textinput handler """ + self._value = self._value[:self._cursor_index] + event.message + \ + self._value[self._cursor_index:] + self.cursor_pos = self._cursor_index + len(event.message) + self.trigger_event("changed", self._value) + + def on_blur(self, event): + """ Internal blur handler """ + self._cursor.hide() + if len(self._value) < 1: + self._placeholder.show() + + self._layout.color = (1, 1, 1, 1) + + def _render_text(self): + """ Internal method to render the text """ + self._text.set_text(self._value) + self._cursor.left = self._text.left + \ + self._text.text_handle.get_char_pos(self._cursor_index) + 1 + max_left = self.width - 15 + + if self._value: + self._placeholder.hide() + else: + if not self.focused: + self._placeholder.show() + + # Scroll if the cursor is outside of the clip bounds + rel_pos = self.get_relative_pos(self._cursor.get_abs_pos()).x + if rel_pos >= max_left: + self._text_scroller.left = min(0, max_left - self._cursor.left) + if rel_pos <= 0: + self._text_scroller.left = min(0, - self._cursor.left - rel_pos) + + def cursor_skip_left(self): + """ Moves the cursor to the left, skipping the previous word """ + left_hand_str = ''.join(reversed(self.value[0:self.cursor_pos])) + match = self.re_skip.match(left_hand_str) + if match is not None: + self.cursor_pos -= match.end() - 1 + else: + self.cursor_pos = 0 + + def cursor_skip_right(self): + """ Moves the cursor to the right, skipping the next word """ + right_hand_str = self.value[self.cursor_pos:] + match = self.re_skip.match(right_hand_str) + if match is not None: + self.cursor_pos += match.end() - 1 + else: + self.cursor_pos = len(self.value) diff --git a/Builtin/LUIInputHandler.py b/Builtin/LUIInputHandler.py new file mode 100644 index 0000000..3b5e2ba --- /dev/null +++ b/Builtin/LUIInputHandler.py @@ -0,0 +1,8 @@ +""" + +This is a wrapper file. It contains no actual implementation + +""" + +from panda3d.lui import LUIInputHandler as __LUIInputHandler +LUIInputHandler = __LUIInputHandler diff --git a/Builtin/LUILabel.py b/Builtin/LUILabel.py new file mode 100644 index 0000000..0eb25a1 --- /dev/null +++ b/Builtin/LUILabel.py @@ -0,0 +1,77 @@ + +from panda3d.lui import LUIText +from LUIObject import LUIObject +from LUIInitialState import LUIInitialState + +__all__ = ["LUILabel"] + +class LUILabel(LUIObject): + + """ A simple label, displaying text. """ + + # Default variables which can be overridden by skins + DEFAULT_COLOR = (0.9, 0.9, 0.9, 1) + DEFAULT_USE_SHADOW = True + + def __init__(self, text="Label", shadow=None, font_size=14, font="label", color=None, wordwrap=False, **kwargs): + """ Creates a new label. If shadow is True, a small text shadow will be + rendered below the actual text. """ + LUIObject.__init__(self) + LUIInitialState.init(self, kwargs) + self._text = LUIText( + self, + text, + font, + font_size, + 0, + 0, + wordwrap + ) + self._text.z_offset = 1 + if color is None: + self.color = LUILabel.DEFAULT_COLOR + else: + self.color = color + if shadow is None: + shadow = LUILabel.DEFAULT_USE_SHADOW + self._have_shadow = shadow + if self._have_shadow: + self._shadow_text = LUIText( + self, + text, + font, + font_size, + 0, + 0, + wordwrap + ) + self._shadow_text.top = 1 + self._shadow_text.color = (0,0,0,0.6) + + def get_text_handle(self): + """ Returns a handle to the internal used LUIText object """ + return self._text + + text_handle = property(get_text_handle) + + def get_text(self): + """ Returns the current text of the label """ + return self._text.text + + def set_text(self, text): + """ Sets the text of the label """ + self._text.text = text + if self._have_shadow: + self._shadow_text.text = text + + text = property(get_text, set_text) + + def get_color(self): + """ Returns the current color of the label's text """ + return self._text.color + + def set_color(self, color): + """ Sets the color of the label's text """ + self._text.color = color + + color = property(get_color, set_color) diff --git a/Builtin/LUILayouts.py b/Builtin/LUILayouts.py new file mode 100644 index 0000000..2210450 --- /dev/null +++ b/Builtin/LUILayouts.py @@ -0,0 +1,105 @@ + +from __future__ import print_function, division + +from LUIObject import LUIObject +from LUISprite import LUISprite +from LUIHorizontalLayout import LUIHorizontalLayout + +from LUIInitialState import LUIInitialState + +__all__ = ["LUICornerLayout", "LUIHorizontalStretchedLayout"] + +class LUICornerLayout(LUIObject): + + """ This is a layout which is used to combine 9 sprites to a single sprite, + e.g. used for box shadow or frames.""" + + # List of all sprite identifiers required for the layout + _MODES = ["TR", "Top", "TL", "Right", "Mid", "Left", "BR", "Bottom", "BL"] + + def __init__(self, image_prefix="", **kwargs): + """ Creates a new layout, using the image_prefix as prefix. """ + LUIObject.__init__(self) + self.set_size("100%", "100%") + self._prefix = image_prefix + self._parts = {} + for i in self._MODES: + self._parts[i] = LUISprite(self, "blank", "skin") + self._update_layout() + LUIInitialState.init(self, kwargs) + + def _update_layout(self): + """ Updates the layouts components. """ + for i in self._MODES: + self._parts[i].set_texture(self._prefix + i, "skin", resize=True) + + # Top and Left + self._parts["Top"].width = "100%" + self._parts["Top"].margin = (0, self._parts["TR"].width, 0, self._parts["TL"].width) + + self._parts["Left"].height = "100%" + self._parts["Left"].margin = (self._parts["TL"].height, 0, self._parts["BL"].height, 0) + + # Mid + self._parts["Mid"].set_size("100%", "100%") + self._parts["Mid"].margin = (self._parts["Top"].height, self._parts["Right"].width, + self._parts["Bottom"].height, self._parts["Left"].width) + + # Bottom and Right + self._parts["Bottom"].width = "100%" + self._parts["Bottom"].margin = (0, self._parts["BR"].width, 0, self._parts["BL"].width) + self._parts["Bottom"].bottom = 0 + + self._parts["Right"].height = "100%" + self._parts["Right"].margin = (self._parts["TR"].height, 0, self._parts["BR"].width, 0) + self._parts["Right"].right = 0 + + # Corners + self._parts["TL"].top_left = 0, 0 + self._parts["TR"].top_right = 0, 0 + self._parts["BL"].bottom_left = 0, 0 + self._parts["BR"].bottom_right = 0, 0 + + def set_prefix(self, prefix): + """ Changes the texture of the layout """ + self._prefix = prefix + self._update_layout() + + def get_prefix(self): + """ Returns the layouts texture prefix """ + return self._prefix + + prefix = property(get_prefix, set_prefix) + + +class LUIHorizontalStretchedLayout(LUIObject): + + """ A layout which takes 3 sprites, a left sprite, a right sprite, and a + middle sprite. While the left and right sprites remain untouched, the middle + one will be stretched to fit the layout """ + + def __init__(self, parent=None, prefix="ButtonDefault", **kwargs): + LUIObject.__init__(self) + self._layout = LUIHorizontalLayout(self, spacing=0) + self._layout.width = "100%" + self._sprite_left = LUISprite(self._layout.cell(), "blank", "skin") + self._sprite_mid = LUISprite(self._layout.cell('*'), "blank", "skin") + self._sprite_right = LUISprite(self._layout.cell(), "blank", "skin") + if parent is not None: + self.parent = parent + self.prefix = prefix + LUIInitialState.init(self, kwargs) + + def set_prefix(self, prefix): + """ Sets the layout prefix, this controls which sprites will be used """ + self._sprite_left.set_texture(prefix + "_Left", "skin") + self._sprite_mid.set_texture(prefix, "skin") + self._sprite_right.set_texture(prefix + "_Right", "skin") + self._sprite_mid.width = "100%" + self._prefix = prefix + + def get_prefix(self): + """ Returns the layout prefix """ + return self._prefix + + prefix = property(get_prefix, set_prefix) diff --git a/Builtin/LUIObject.py b/Builtin/LUIObject.py new file mode 100644 index 0000000..c666efe --- /dev/null +++ b/Builtin/LUIObject.py @@ -0,0 +1,18 @@ +""" + +This is a wrapper file. It contains no actual implementation + +""" + +from panda3d.lui import LUIObject as _LUIObject +from LUIInitialState import LUIInitialState + +__all__ = ["LUIObject"] + +class LUIObject(_LUIObject): + """ This is a wrapper class for the C++ LUIObject class, to be able to + use it in a more convenient way """ + + def __init__(self, *args, **kwargs): + _LUIObject.__init__(self, *args) + LUIInitialState.init(self, kwargs) diff --git a/Builtin/LUIProgressbar.py b/Builtin/LUIProgressbar.py new file mode 100644 index 0000000..8f744ea --- /dev/null +++ b/Builtin/LUIProgressbar.py @@ -0,0 +1,72 @@ + +from LUIObject import LUIObject +from LUISprite import LUISprite + +from LUILayouts import LUIHorizontalStretchedLayout +from LUILabel import LUILabel + +class LUIProgressbar(LUIObject): + + """ A simple progress bar """ + + def __init__(self, parent=None, width=200, value=50, show_label=True): + """ Constructs a new progress bar. If show_label is True, a label indicating + the current progress is shown """ + LUIObject.__init__(self) + self.set_width(width) + + self._bg_layout = LUIHorizontalStretchedLayout( + parent=self, prefix="ProgressbarBg", width="100%") + + self._fg_left = LUISprite(self, "ProgressbarFg_Left", "skin") + self._fg_mid = LUISprite(self, "ProgressbarFg", "skin") + self._fg_right = LUISprite(self, "ProgressbarFg_Right", "skin") + self._fg_finish = LUISprite(self, "ProgressbarFg_Finish", "skin") + + self._show_label = show_label + self._progress_pixel = 0 + self._fg_finish.right = 0 + + if self._show_label: + self._progress_label = LUILabel(parent=self, text=u"33 %") + self._progress_label.centered = (True, True) + + self.set_value(value) + self._update_progress() + + if parent is not None: + self.parent = parent + + def get_value(self): + """ Returns the current value of the progress bar """ + return (self._progress_pixel / self.width * 100.0) + + def set_value(self, val): + """ Sets the value of the progress bar """ + val = max(0, min(100, val)) + self._progress_pixel = int(val / 100.0 * self.width) + self._update_progress() + + value = property(get_value, set_value) + + def _update_progress(self): + """ Internal method to update the progressbar """ + self._fg_finish.hide() + + if self._progress_pixel <= self._fg_left.width + self._fg_right.width: + self._fg_mid.hide() + self._fg_right.left = self._fg_left.width + else: + self._fg_mid.show() + self._fg_mid.left = self._fg_left.width + self._fg_mid.width = self._progress_pixel - self._fg_right.width - self._fg_left.width + self._fg_right.left = self._fg_mid.left + self._fg_mid.width + + if self._progress_pixel >= self.width - self._fg_right.width: + self._fg_finish.show() + self._fg_finish.right = - (self.width - self._progress_pixel) + self._fg_finish.clip_bounds = (0, self.width - self._progress_pixel, 0, 0) + + if self._show_label: + percentage = self._progress_pixel / self.width * 100.0 + self._progress_label.set_text("{} %".format(int(percentage))) diff --git a/Builtin/LUIRadiobox.py b/Builtin/LUIRadiobox.py new file mode 100644 index 0000000..9d7d8bf --- /dev/null +++ b/Builtin/LUIRadiobox.py @@ -0,0 +1,91 @@ + +from __future__ import division + +from LUIObject import LUIObject +from LUISprite import LUISprite +from LUIInitialState import LUIInitialState +from LUILabel import LUILabel + +class LUIRadiobox(LUIObject): + + """ A radiobox which can be used in combination with a LUIRadioboxGroup """ + + def __init__(self, parent=None, group=None, value=None, active=False, label=u"Radiobox", **kwargs): + """ Constructs a new radiobox. group should be a handle to a LUIRadioboxGroup. + value will be the value returned by group.value, in case the box was + selected. By default, the radiobox is not active. """ + assert group is not None, "LUIRadiobox needs a LUIRadioboxGroup!" + LUIObject.__init__(self, x=0, y=0, solid=True) + self._sprite = LUISprite(self, "Radiobox_Default", "skin") + self._label = LUILabel(parent=self, text=label, margin=(0, 0, 0, 23), + center_vertical=True) + self._value = value + self._active = False + self._hovered = False + self._group = group + self._group.register_box(self) + if active: + self.set_active() + if parent: + self.parent = parent + LUIInitialState.init(self, kwargs) + + def on_click(self, event): + """ Internal onclick handler. Do not override. """ + self.set_active() + + def on_mouseover(self, event): + """ Internal mouseover handler """ + self._hovered = True + self._update_sprite() + + def on_mouseout(self, event): + """ Internal mouseout handler """ + self._hovered = False + self._update_sprite() + + def set_active(self): + """ Internal function to set the radiobox active """ + if self._group is not None: + self._group.set_active_box(self) + else: + self._update_state(True) + + def get_value(self): + """ Returns the value of the radiobox """ + return self._value + + def set_value(self, value): + """ Sets the value of the radiobox """ + self._value = value + + value = property(get_value, set_value) + + def get_label(self): + """ Returns a handle to the label, so it can be modified (e.g. change + its text) """ + return self._label + + label = property(get_label) + + def _update_state(self, active): + """ Internal method to update the state of the radiobox. Called by the + LUIRadioboxGroup """ + self._active = active + self.trigger_event("changed") + self._update_sprite() + + def on_mousedown(self, event): + """ Internal onmousedown handler. Do not override. """ + self._sprite.color = (0.86,0.86,0.86,1.0) + + def on_mouseup(self, event): + """ Internal onmouseup handler. Do not override. """ + self._sprite.color = (1,1,1,1) + + def _update_sprite(self): + """ Internal function to update the sprite of the radiobox """ + img = "Radiobox_Active" if self._active else "Radiobox_Default" + if self._hovered: + img += "Hover" + self._sprite.set_texture(img, "skin") diff --git a/Builtin/LUIRadioboxGroup.py b/Builtin/LUIRadioboxGroup.py new file mode 100644 index 0000000..94117c7 --- /dev/null +++ b/Builtin/LUIRadioboxGroup.py @@ -0,0 +1,41 @@ + +from LUIObject import LUIObject + +class LUIRadioboxGroup(LUIObject): + + """ Simple helper to group a bunch of LUIRadiobox and ensure only one is + checked at one timem """ + + def __init__(self): + """ Constructs a new group without any radioboxes inside """ + self._boxes = [] + self._selected_box = None + + def register_box(self, box): + """ Registers a box to the collection """ + if box not in self._boxes: + self._boxes.append(box) + + def set_active_box(self, active_box): + """ Internal function to set the active box """ + for box in self._boxes: + if box is not active_box: + box._update_state(False) + else: + box._update_state(True) + self._selected_box = active_box + + def get_active_box(self): + """ Returns the current selected box """ + return self._selected_box + + active_box = property(get_active_box, set_active_box) + + def get_active_value(self): + """ Returns the value of the current selected box (or None if none is + selected) """ + if self._selected_box is None: + return None + return self._selected_box.get_value() + + active_value = property(get_active_value) diff --git a/Builtin/LUIRegion.py b/Builtin/LUIRegion.py new file mode 100644 index 0000000..b6bbb3d --- /dev/null +++ b/Builtin/LUIRegion.py @@ -0,0 +1,8 @@ +""" + +This is a wrapper file. It contains no actual implementation + +""" + +from panda3d.lui import LUIRegion as __LUIRegion +LUIRegion = __LUIRegion diff --git a/Builtin/LUIRoot.py b/Builtin/LUIRoot.py new file mode 100644 index 0000000..79f83f9 --- /dev/null +++ b/Builtin/LUIRoot.py @@ -0,0 +1,8 @@ +""" + +This is a wrapper file. It contains no actual implementation + +""" + +from panda3d.lui import LUIRoot as __LUIRoot +LUIRoot = __LUIRoot diff --git a/Builtin/LUIScrollableRegion.py b/Builtin/LUIScrollableRegion.py new file mode 100644 index 0000000..08105ca --- /dev/null +++ b/Builtin/LUIScrollableRegion.py @@ -0,0 +1,155 @@ + +from LUIObject import LUIObject +from LUISprite import LUISprite +from LUIInitialState import LUIInitialState +from LUILayouts import LUIHorizontalStretchedLayout + +class LUIScrollableRegion(LUIObject): + + """ Scrollable region, reparent elements to the .content_node to make them + scroll. """ + + def __init__(self, parent=None, width=100, height=100, padding=10, **kwargs): + LUIObject.__init__(self) + self.set_size(width, height) + self._content_parent = LUIObject(self) + self._content_parent.set_size("100%", "100%") + self._content_parent.clip_bounds = (0,0,0,0) + + self._content_clip = LUIObject(self._content_parent, x=padding, y=padding) + self._content_clip.set_size("100%", "100%") + + self._content_scroller = LUIObject(self._content_clip) + self._content_scroller.width = "100%" + + + self._scrollbar = LUIObject(self, x=0, y=0, w=20) + self._scrollbar.height = "100%" + self._scrollbar.right = -10 + + self._scrollbar_bg = LUISprite(self._scrollbar, "blank", "skin") + self._scrollbar_bg.color = (1,1,1,0.05) + self._scrollbar_bg.set_size(3, "100%") + self._scrollbar_bg.center_horizontal = True + + # Handle + self._scrollbar_handle = LUIObject(self._scrollbar, x=5, y=0, w=10) + self._scroll_handle_top = LUISprite(self._scrollbar_handle, "ScrollbarHandle_Top", "skin") + self._scroll_handle_mid = LUISprite(self._scrollbar_handle, "ScrollbarHandle", "skin") + self._scroll_handle_bottom = LUISprite(self._scrollbar_handle, "ScrollbarHandle_Bottom", "skin") + + self._scrollbar_handle.solid = True + self._scrollbar.solid = True + + self._scrollbar_handle.bind("mousedown", self._start_scrolling) + self._scrollbar_handle.bind("mouseup", self._stop_scrolling) + self._scrollbar.bind("mousedown", self._on_bar_click) + self._scrollbar.bind("mouseup", self._stop_scrolling) + + self._handle_dragging = False + self._drag_start_y = 0 + + self._scroll_top_position = 0 + self._content_height = 400 + + # Scroll shadow + self._scroll_shadow_top = LUIHorizontalStretchedLayout(parent=self, prefix="ScrollShadowTop", width="100%") + self._scroll_shadow_bottom = LUIHorizontalStretchedLayout(parent=self, prefix="ScrollShadowBottom", width="100%") + self._scroll_shadow_bottom.bottom = 0 + + self._handle_height = 100 + + if parent is not None: + self.parent = parent + + LUIInitialState.init(self, kwargs) + self.content_node = self._content_scroller + taskMgr.doMethodLater(0.05, lambda task: self._update(), "update_scrollbar") + + def _on_bar_click(self, event): + """ Internal handler when the user clicks on the scroll bar """ + self._scroll_to_bar_pixels(event.coordinates.y - self._scrollbar.abs_pos.y - self._handle_height / 2.0) + self._update() + self._start_scrolling(event) + + def _start_scrolling(self, event): + """ Internal method when we start scrolling """ + self.request_focus() + if not self._handle_dragging: + self._drag_start_y = event.coordinates.y + self._handle_dragging = True + + def _stop_scrolling(self, event): + """ Internal handler when we should stop scrolling """ + if self._handle_dragging: + self._handle_dragging = False + self.blur() + + def _scroll_to_bar_pixels(self, pixels): + """ Internal method to convert from pixels to a relative position """ + offset = pixels * self._content_height / self.height + self._scroll_top_position = offset + self._scroll_top_position = max(0, min(self._content_height - self._content_clip.height, self._scroll_top_position)) + + def on_tick(self, event): + """ Internal on tick handler """ + if self._handle_dragging: + scroll_abs_pos = self._scrollbar.abs_pos + clamped_coord_y = max(scroll_abs_pos.y, min(scroll_abs_pos.y + self.height, event.coordinates.y)) + offset = clamped_coord_y - self._drag_start_y + self._drag_start_y = clamped_coord_y + self._scroll_to_bar_pixels(self._scroll_top_position/self._content_height*self.height + offset) + self._update() + + def _set_handle_height(self, height): + """ Internal method to set the scrollbar height """ + self._scroll_handle_mid.top = float(self._scroll_handle_top.height) + + self._scroll_handle_mid.height = max(0.0, height - self._scroll_handle_top.height - self._scroll_handle_bottom.height) + self._scroll_handle_bottom.top = self._scroll_handle_mid.height + self._scroll_handle_mid.top + self._handle_height = height + + def _update(self): + """ Internal method to update the scroll bar """ + self._content_height = max(1, self._content_scroller.get_height() + 20) + self._content_scroller.top = -self._scroll_top_position + scrollbar_height = max(0.1, min(1.0, self._content_clip.height / self._content_height)) + scrollbar_height_px = scrollbar_height * self.height + + self._set_handle_height(scrollbar_height_px) + self._scrollbar_handle.top = self._scroll_top_position / self._content_height * self.height + + top_alpha = max(0.0, min(1.0, self._scroll_top_position / 50.0)) + bottom_alpha = max(0.0, min(1.0, (self._content_height - self._scroll_top_position - self._content_clip.height) / 50.0 )) + self._scroll_shadow_top.color = (1,1,1,top_alpha) + self._scroll_shadow_bottom.color = (1,1,1,bottom_alpha) + + if self._content_height <= self.height: + self._scrollbar_handle.hide() + else: + self._scrollbar_handle.show() + + def on_element_added(self): + taskMgr.doMethodLater(0.05, lambda task: self._update(), "update_layout") + + def get_scroll_percentage(self): + """ Returns the current scroll height in percentage from 0 to 1 """ + return self._scroll_top_position / max(1, self._content_height - self._content_clip.height) + + def set_scroll_percentage(self, percentage): + """ Sets the scroll position in percentage, 0 means top and 1 means bottom """ + percentage = max(0.0, min(1.0, percentage)) + pixels = max(0.0, self._content_height - self._content_clip.height) * percentage + self._scroll_top_position = pixels + self._update() + + scroll_percentage = property(get_scroll_percentage, set_scroll_percentage) + + def scroll_to_bottom(self): + """ Scrolls to the bottom of the frame """ + taskMgr.doMethodLater(0.07, lambda task: self.set_scroll_percentage(1.0), "scroll_to_bottom") + + def scroll_to_top(self): + """ Scrolls to the top of the frame """ + taskMgr.doMethodLater(0.07, lambda task: self.set_scroll_percentage(0.0), "scroll_to_top") + diff --git a/Builtin/LUISelectbox.py b/Builtin/LUISelectbox.py new file mode 100644 index 0000000..f2fa4a7 --- /dev/null +++ b/Builtin/LUISelectbox.py @@ -0,0 +1,207 @@ + +from LUIObject import LUIObject +from LUISprite import LUISprite +from LUILabel import LUILabel +from LUILayouts import LUICornerLayout, LUIHorizontalStretchedLayout +from LUIInitialState import LUIInitialState + +from functools import partial + +__all__ = ["LUISelectbox"] + +class LUISelectbox(LUIObject): + + """ Selectbox widget, showing several options whereas the user can select + only one. """ + + def __init__(self, width=200, options=None, selected_option=None, **kwargs): + """ Constructs a new selectbox with a given width """ + LUIObject.__init__(self, x=0, y=0, w=width+4, solid=True) + LUIInitialState.init(self, kwargs) + + # The selectbox has a small border, to correct this we move it + self.margin.left = -2 + + self._bg_layout = LUIHorizontalStretchedLayout(parent=self, prefix="Selectbox", width="100%") + + self._label_container = LUIObject(self, x=10, y=0) + self._label_container.set_size("100%", "100%") + self._label_container.clip_bounds = (0,0,0,0) + self._label = LUILabel(parent=self._label_container, text=u"Select an option ..") + self._label.center_vertical = True + + self._drop_menu = LUISelectdrop(parent=self, width=width) + self._drop_menu.top = self._bg_layout._sprite_right.height - 7 + self._drop_menu.topmost = True + + self._drop_open = False + self._drop_menu.hide() + + self._options = [] + self._current_option_id = None + + if options is not None: + self._options = options + + self._select_option(selected_option) + + def get_selected_option(self): + """ Returns the selected option """ + return self._current_option_id + + def set_selected_option(self, option_id): + """ Sets the selected option """ + raise NotImplementedError() + + selected_option = property(get_selected_option, set_selected_option) + + def _render_options(self): + """ Internal method to render all available options """ + self._drop_menu._render_options(self._options) + + def get_options(self): + """ Returns the list of options """ + return self._options + + def set_options(self, options): + """ Sets the list of options, options should be a list containing entries + whereas each entry is a tuple in the format (option_id, option_label). + The option ID can be an arbitrary object, and will not get modified. """ + self._options = options + self._current_option_id = None + self._render_options() + + options = property(get_options, set_options) + + def _select_option(self, opt_id): + """ Internal method to select an option """ + self._label.alpha = 1.0 + for elem_opt_id, opt_val in self._options: + if opt_id == elem_opt_id: + self._label.text = opt_val + self._current_option_id = opt_id + return + self._label.alpha = 0.3 + + # def on_mouseover(self, event): + # """ Internal handle when the select-knob was hovered """ + # self._bg_layout.color = (0.9,0.9,0.9,1.0) + + # def on_mouseout(self, event): + # """ Internal handle when the select-knob was no longer hovered """ + # self._bg_layout.color = (1,1,1,1.0) + + def on_click(self, event): + """ On-Click handler """ + self.request_focus() + if self._drop_open: + self._close_drop() + else: + self._open_drop() + + def on_mousedown(self, event): + """ Mousedown handler """ + self._bg_layout.alpha = 0.9 + + def on_mouseup(self, event): + """ Mouseup handler """ + self._bg_layout.alpha = 1 + + def on_blur(self, event): + """ Internal handler when the selectbox lost focus """ + if not self._drop_menu.focused: + self._close_drop() + + def _open_drop(self): + """ Internal method to show the dropdown menu """ + if not self._drop_open: + self._render_options() + self._drop_menu.show() + self.request_focus() + self._drop_open = True + + def _close_drop(self): + """ Internal method to close the dropdown menu """ + if self._drop_open: + self._drop_menu.hide() + self._drop_open = False + + def _on_option_selected(self, opt_id): + """ Internal method when an option got selected """ + self._select_option(opt_id) + self._close_drop() + + +class LUISelectdrop(LUIObject): + + """ Internal class used by the selectbox, representing the dropdown menu """ + + def __init__(self, parent, width=200): + LUIObject.__init__(self, x=0, y=0, w=width, h=1, solid=True) + + self._layout = LUICornerLayout(parent=self, image_prefix="Selectdrop_", + width=width + 10, height=100) + self._layout.margin.left = -3 + + self._opener = LUISprite(self, "SelectboxOpen_Right", "skin") + self._opener.right = -4 + self._opener.top = -25 + self._opener.z_offset = 3 + + self._container = LUIObject(self._layout, 0, 0, 0, 0) + self._container.width = self.width + self._container.clip_bounds = (0,0,0,0) + self._container.left = 5 + self._container.solid = True + self._container.bind("mousedown", lambda *args: self.request_focus()) + + self._selectbox = parent + self._option_focus = False + self.parent = self._selectbox + + def _on_opt_over(self, event): + """ Inernal handler when an option got hovered """ + event.sender.color = (0,0,0,0.1) + + def _on_opt_out(self, event): + """ Inernal handler when an option got no longer hovered """ + event.sender.color = (0,0,0,0) + + def _on_opt_click(self, opt_id, event): + """ Internal handler when an option got clicked """ + self._selectbox._on_option_selected(opt_id) + + def _render_options(self, options): + """ Internal method to update the options """ + num_visible_options = min(30, len(options)) + offset_top = 6 + self._layout.height = num_visible_options * 30 + offset_top + 11 + self._container.height = num_visible_options * 30 + offset_top + 1 + self._container.remove_all_children() + + current_y = offset_top + for opt_id, opt_val in options: + opt_container = LUIObject(self._container, x=0, y=current_y, w=self._container.width - 30, h=30) + + opt_bg = LUISprite(opt_container, "blank", "skin") + opt_bg.width = self._container.width + opt_bg.height = opt_container.height + opt_bg.color = (0,0,0,0) + opt_bg.bind("mouseover", self._on_opt_over) + opt_bg.bind("mouseout", self._on_opt_out) + opt_bg.bind("mousedown", lambda *args: self.request_focus()) + opt_bg.bind("click", partial(self._on_opt_click, opt_id)) + opt_bg.solid = True + + opt_label = LUILabel(parent=opt_container, text=opt_val) + opt_label.top = 8 + opt_label.left = 8 + + if opt_id == self._selectbox.selected_option: + opt_label.color = (0.6, 0.9, 0.4, 1.0) + + divider = LUISprite(opt_container, "SelectdropDivider", "skin") + divider.top = 30 - divider.height / 2 + divider.width = self._container.width + + current_y += 30 diff --git a/Builtin/LUISkin.py b/Builtin/LUISkin.py new file mode 100644 index 0000000..0f0e774 --- /dev/null +++ b/Builtin/LUISkin.py @@ -0,0 +1,53 @@ + +import os +from os.path import join + +from panda3d.core import Filename +from panda3d.lui import LUIFontPool, LUIAtlasPool + +class LUISkin: + + """ Abstract class, each skin derives from this class """ + + skin_location = "" + + def __init__(self): + pass + + def load(self): + """ Skins should override this. Each skin should at least provide the fonts + 'default' and 'label', and at least one atlas named 'skin' """ + raise NotImplementedError() + + def get_resource(self, pth): + """ Turns a relative path into an absolute one, using the skin_location """ + return Filename.from_os_specific(join(self.skin_location, pth)).get_fullpath() + + +class LUIDefaultSkin(LUISkin): + + """ The default skin which comes with LUI """ + + skin_location = os.path.join(os.path.dirname(os.path.abspath(__file__)), "../Skins/Default/") + + def __init__(self): + pass + + def load(self): + LUIFontPool.get_global_ptr().register_font( + "default", loader.loadFont(self.get_resource("font/SourceSansPro-Semibold.ttf"))) + + labelFont = loader.loadFont(self.get_resource("font/SourceSansPro-Semibold.ttf")) + labelFont.setPixelsPerUnit(32) + + LUIFontPool.get_global_ptr().register_font( + "label", labelFont) + + headerFont = loader.loadFont(self.get_resource("font/SourceSansPro-Light.ttf")) + headerFont.setPixelsPerUnit(80) + + LUIFontPool.get_global_ptr().register_font("header", headerFont) + + LUIAtlasPool.get_global_ptr().load_atlas("skin", + self.get_resource("res/atlas.txt"), + self.get_resource("res/atlas.png")) diff --git a/Builtin/LUISlider.py b/Builtin/LUISlider.py new file mode 100644 index 0000000..edf8fa3 --- /dev/null +++ b/Builtin/LUISlider.py @@ -0,0 +1,131 @@ + +from LUIObject import LUIObject +from LUISprite import LUISprite +from LUIInitialState import LUIInitialState +from LUILayouts import LUIHorizontalStretchedLayout + +class LUISlider(LUIObject): + + """ Slider which can be used to control values """ + + def __init__(self, parent=None, filled=True, min_value=0.0, max_value=1.0, width=100.0, value=None, **kwargs): + """ Constructs a new slider. If filled is True, the part behind the knob + will be solid """ + LUIObject.__init__(self, x=0, y=0, solid=True) + self.set_width(width) + self._knob = LUISprite(self, "SliderKnob", "skin") + self._knob.z_offset = 2 + self._knob.solid = True + + # Construct the background + self._slider_bg = LUIHorizontalStretchedLayout(parent=self, prefix="SliderBg", center_vertical=True, width="100%", margin=(-1, 0, 0, 0)) + + self._filled = filled + self._min_value = min_value + self._max_value = max_value + + self._side_margin = self._knob.width / 4 + self._effective_width = self.width - 2 * self._side_margin + + if self._filled: + self._slider_fill = LUIObject(self) + self._fill_left = LUISprite(self._slider_fill, "SliderBgFill_Left", "skin") + self._fill_mid = LUISprite(self._slider_fill, "SliderBgFill", "skin") + self._fill_mid.left = self._fill_left.width + self._slider_fill.z_offset = 1 + self._slider_fill.center_vertical = True + + if parent is not None: + self.parent = parent + + # Handle various events + self._knob.bind("mousedown", self._start_drag) + self._knob.bind("mousemove", self._update_drag) + self._knob.bind("mouseup", self._stop_drag) + self._knob.bind("keydown", self._on_keydown) + self._knob.bind("blur", self._stop_drag) + self._knob.bind("keyrepeat", self._on_keydown) + + self._drag_start_pos = None + self._dragging = False + self._drag_start_val = 0 + self.current_val = 10 + + # Set initial value + if value is None: + self.set_value( (self._min_value + self._max_value) / 2.0 ) + else: + self.set_value(value) + + self._update_knob() + + LUIInitialState.init(self, kwargs) + + def on_click(self, event): + """ Internal on click handler """ + # I don't like this behaviour + # relative_pos = self.get_relative_pos(event.coordinates) + # if not self._dragging: + # self._set_current_val(relative_pos.x) + + def _update_knob(self): + """ Internal method to update the slider knob """ + self._knob.left = self.current_val - (self._knob.width / 2) + self._side_margin + if self._filled: + self._fill_mid.width = self.current_val - self._fill_left.width + self._side_margin + + def _set_current_val(self, pixels): + """ Internal method to set the current value in pixels """ + pixels = max(0, min(self._effective_width, pixels)) + self.current_val = pixels + self.trigger_event("changed") + self._update_knob() + + def _start_drag(self, event): + """ Internal drag start handler """ + self._knob.request_focus() + if not self._dragging: + self._drag_start_pos = event.coordinates + self._dragging = True + self._drag_start_val = self.current_val + self._knob.color = (0.8,0.8,0.8,1.0) + + def set_value(self, value): + """ Sets the value of the slider, should be between minimum and maximum. """ + scaled = (float(value) - float(self._min_value)) \ + / (float(self._max_value) - float(self._min_value)) \ + * self._effective_width + self._set_current_val(scaled) + + def get_value(self): + """ Returns the current value of the slider """ + return (self.current_val / float(self._effective_width)) \ + * (float(self._max_value) - float(self._min_value)) \ + + self._min_value + + value = property(get_value, set_value) + + def _on_keydown(self, event): + """ Internal keydown handler """ + if event.message == "arrow_right": + self._set_current_val(self.current_val + 2) + elif event.message == "arrow_left": + self._set_current_val(self.current_val - 2) + elif event.message == "escape": + self.current_val = self._drag_start_val + self._stop_drag(event) + self._update_knob() + + def _update_drag(self, event): + """ Internal drag handler """ + if self._dragging: + dragOffset = event.coordinates.x - self._drag_start_pos.x + finalValue = self._drag_start_val + dragOffset + self._set_current_val(finalValue) + + def _stop_drag(self, event): + """ Internal drag stop handelr """ + self._drag_start_pos = None + self._dragging = False + self._drag_start_val = self.current_val + self._knob.color = (1,1,1,1) diff --git a/Builtin/LUISprite.py b/Builtin/LUISprite.py new file mode 100644 index 0000000..b04b422 --- /dev/null +++ b/Builtin/LUISprite.py @@ -0,0 +1,18 @@ +""" + +This is a wrapper file. It contains no actual implementation + +""" + +from panda3d.lui import LUISprite as _LUISprite +from LUIInitialState import LUIInitialState + +__all__ = ["LUISprite"] + +class LUISprite(_LUISprite): + """ This is a wrapper class for the C++ LUISprite class, to be able to + use it in a more convenient way """ + + def __init__(self, *args, **kwargs): + _LUISprite.__init__(self, *args) + LUIInitialState.init(self, kwargs) diff --git a/Builtin/LUISpriteButton.py b/Builtin/LUISpriteButton.py new file mode 100644 index 0000000..348a197 --- /dev/null +++ b/Builtin/LUISpriteButton.py @@ -0,0 +1,30 @@ + +from LUIObject import LUIObject +from LUISprite import LUISprite +from LUIInitialState import LUIInitialState + +class LUISpriteButton(LUIObject): + + """ Simple button that uses only two images: Default and focus. """ + + def __init__(self, template="ButtonDefault", **kwargs): + LUIObject.__init__(self, x=0, y=0, solid=True) + self._template = template + self._button_sprite = LUISprite(self, template, "skin") + if 'width' in kwargs: + self._button_sprite.width = kwargs['width'] + if 'height' in kwargs: + self._button_sprite.height = kwargs['height'] + LUIInitialState.init(self, kwargs) + + def on_mousedown(self, event): + """ Internal on_mousedown handler. Do not override """ + self._button_sprite.set_texture(self.template + "Focus", "skin", resize=False) + + def on_mouseup(self, event): + """ Internal on_mouseup handler. Do not override """ + self._button_sprite.set_texture(self.template, "skin", resize=False) + + def on_click(self, event): + """ Internal onclick handler. Do not override """ + self.trigger_event("changed") diff --git a/Builtin/LUITabbedFrame.py b/Builtin/LUITabbedFrame.py new file mode 100644 index 0000000..4e210f5 --- /dev/null +++ b/Builtin/LUITabbedFrame.py @@ -0,0 +1,87 @@ +from LUIFrame import LUIFrame +from LUILabel import LUILabel +from LUIObject import LUIObject +from LUIVerticalLayout import LUIVerticalLayout +from LUIHorizontalLayout import LUIHorizontalLayout + +class LUITabbedFrame(LUIFrame): + def __init__(self, **kwargs): + super(LUITabbedFrame, self).__init__(**kwargs) + + # The main window layout + bar_spacing = kwargs.get('bar_spacing', 3) + self.root_layout = LUIVerticalLayout(parent = self, + spacing = bar_spacing) + self.root_layout.height = "100%" + self.root_layout.width = "100%" + self.root_layout.margin = 0 + + # The header bar + header_spacing = kwargs.get('header_spacing', 3) + self.header_bar = LUIHorizontalLayout(parent = self.root_layout.cell("?"), + spacing = header_spacing) + self.root_layout.add(self.header_bar, "?") + self.header_to_frame = {} + self.current_frame = None + + # The main window contents + self.main_frame = LUIObject() + self.main_frame.height = "100%" + self.main_frame.width = "100%" + self.main_frame.margin = 0 + # self.main_frame.padding = 0 + self.root_layout.add(self.main_frame, "*") + self.bind("expose", self.on_expose) + self.bind("unexpose", self.on_unexpose) + + def add(self, header, frame): + # header + if isinstance(header, str): + header = LUILabel(text = header) + self.header_bar.add(header, "?") + self.header_to_frame[header] = frame + header.solid = True + header.bind("click", self._change_to_tab) + # Frame + frame.parent = self.main_frame + frame.width = "100%" + frame.height = "100%" + # Put frame in front + if self.current_frame is None: + self.current_frame = frame + self.current_frame.show() + else: + frame.hide() + return header + + def _find_header_index(self, header): + for idx, child in enumerate(self.header_bar.children): + if any([grandchild == header for grandchild in child.children]): + break + else: + raise ValueError("Given object is not a header bar item.") + return idx + + def remove(self, header): + idx = self._find_header_index(header) + self.header_bar.remove_cell(idx) + frame = self.header_to_frame[header] + frame.parent = None + del self.header_to_frame[header] + if self.current_frame == frame: + self.current_frame = None + + def _change_to_tab(self, lui_event): + header = lui_event.sender + if self.current_frame is not None: + self.current_frame.trigger_event("unexpose") + self.current_frame.hide() + self.current_frame = self.header_to_frame[header] + self.current_frame.show() + self.current_frame.trigger_event("expose") + + def on_expose(self, event): + self.current_frame.trigger_event("expose") + + def on_unexpose(self, event): + self.current_frame.trigger_event("unexpose") diff --git a/Builtin/LUIVerticalLayout.py b/Builtin/LUIVerticalLayout.py new file mode 100644 index 0000000..fd15f81 --- /dev/null +++ b/Builtin/LUIVerticalLayout.py @@ -0,0 +1,20 @@ +""" + +This is a wrapper file. It contains no actual implementation + +""" + +from panda3d.lui import LUIVerticalLayout as _LUIVerticalLayout +from LUIInitialState import LUIInitialState + +__all__ = ["LUIVerticalLayout"] + + +class LUIVerticalLayout(_LUIVerticalLayout): + """ This is a wrapper class for the C++ LUIVerticalLayout class, to be + able to use it in a more convenient way. It leverages LUIInitialState + to be able to pass arbitrary keyword arguments. """ + + def __init__(self, parent=None, spacing=0.0, **kwargs): + _LUIVerticalLayout.__init__(self, parent, spacing) + LUIInitialState.init(self, kwargs) diff --git a/Builtin/__init__.py b/Builtin/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/Demos/.gitignore b/Demos/.gitignore new file mode 100644 index 0000000..b8cceff --- /dev/null +++ b/Demos/.gitignore @@ -0,0 +1 @@ +Test.py diff --git a/Demos/01_MinimalExample.py b/Demos/01_MinimalExample.py new file mode 100644 index 0000000..e57323c --- /dev/null +++ b/Demos/01_MinimalExample.py @@ -0,0 +1,56 @@ +import sys +from pathlib import Path + +lui_path = Path(__file__).parent.parent.absolute() +builtin_path = lui_path / "Builtin" +sys.path.insert(0, str(lui_path)) +sys.path.insert(0, str(builtin_path)) +import panda3d.core +import lui +import panda3d +panda3d.lui = lui +sys.modules["panda3d.lui"] = lui + +# Load some builtin LUI classes. When lui is included in panda, this will be +# from direct.lui.LUIButton import LUIButton +from Builtin.LUIButton import LUIButton +from Builtin.LUISkin import LUIDefaultSkin +from Builtin.LUIRegion import LUIRegion +from Builtin.LUIInputHandler import LUIInputHandler + +# Setup panda, nothing special here +from panda3d.core import load_prc_file_data +load_prc_file_data("", """ + text-minfilter linear + text-magfilter linear + text-pixels-per-unit 32 + sync-video #f + textures-power-2 none + show-frame-rate-meter #t + win-size 700 600 + window-title LUI Minimal Example +""") + +from direct.showbase.ShowBase import ShowBase + +class Application(ShowBase): + + def __init__(self): + ShowBase.__init__(self) + + # Construct a new LUIRegion + region = LUIRegion.make("LUI", base.win) + + # Construct a new InputHandler to catch and process events + handler = LUIInputHandler() + base.mouseWatcher.attach_new_node(handler) + region.set_input_handler(handler) + + # Load the default LUI skin + skin = LUIDefaultSkin() + skin.load() + + # LUI is initialized now, so we can start adding elements, for example: + button = LUIButton(parent=region.root, text="Hello world!", top=30, left=30) + +Application().run() diff --git a/Demos/02_SimpleConsole.py b/Demos/02_SimpleConsole.py new file mode 100644 index 0000000..e0e51bd --- /dev/null +++ b/Demos/02_SimpleConsole.py @@ -0,0 +1,107 @@ +import sys +from pathlib import Path + +lui_path = Path(__file__).parent.parent.absolute() +builtin_path = lui_path / "Builtin" +sys.path.insert(0, str(lui_path)) +sys.path.insert(0, str(builtin_path)) +import panda3d.core +import lui +import panda3d +panda3d.lui = lui +sys.modules["panda3d.lui"] = lui + +from direct.showbase.ShowBase import ShowBase +from direct.showbase.DirectObject import DirectObject + +from panda3d.core import * +load_prc_file_data("", """ + notify-level-lui info + text-minfilter linear + text-magfilter linear + text-pixels-per-unit 32 + sync-video #f + textures-power-2 none + show-frame-rate-meter #t + win-size 780 630 + window-title LUI Demo + win-fixed-size #f +""") + +# Imports + +import codecs + +from LUISkin import LUIDefaultSkin +from LUIFrame import LUIFrame +from LUILabel import LUILabel +from LUIInputField import LUIInputField +from LUIFormattedLabel import LUIFormattedLabel +from LUIScrollableRegion import LUIScrollableRegion +from LUIObject import LUIObject +from LUIRegion import LUIRegion +from LUIInputHandler import LUIInputHandler +from LUIVerticalLayout import LUIVerticalLayout + +from Skins.Metro.LUIMetroSkin import LUIMetroSkin + +s = ShowBase() + +# Load a LUI Skin +if False: + skin = LUIMetroSkin() + base.win.set_clear_color(Vec4(1)) +else: + skin = LUIDefaultSkin() + base.win.set_clear_color(Vec4(0.1, 0.0, 0.0, 1)) + +skin.load() + +# Initialize LUI +region = LUIRegion.make("LUI", base.win) +handler = LUIInputHandler() +base.mouseWatcher.attach_new_node(handler) +region.set_input_handler(handler) + +# Title +title_label = LUILabel(parent=region.root, text="LUI Console Example", font_size=40, + font="header", pos=(25, 17)) + +# Container +container = LUIFrame(parent = region.root, width=700, height=500, + style=LUIFrame.FS_sunken, margin=30, top=50) + +text_container = LUIScrollableRegion(parent=container, width=675, height=440, + padding=0) + +base.win.set_clear_color(Vec4(0.1, 0.1, 0.1, 1.0)) +layout = LUIVerticalLayout(parent=text_container.content_node) + +def send_command(event): + """ Called when the user presses enter in the input field, submits the + command and prints something on the console """ + label = LUIFormattedLabel() + color = (0.9, 0.9, 0.9, 1.0) + if event.message.startswith(u"/"): + color = (0.35, 0.65, 0.24, 1.0) + label.add(text=">>> ", color=(0.35, 0.65, 0.24, 1.0)) + label.add(text=event.message, color=color) + layout.add(label) + + result = LUIFormattedLabel() + result.add("Your command in rot13: " + codecs.encode(event.message, "rot13"), color=(0.4, 0.4, 0.4, 1.0)) + layout.add(result) + input_field.clear() + + text_container.scroll_to_bottom() + +# Create the input box +input_field = LUIInputField(parent=container, bottom=0, left=0, width="100%") +input_field.bind("enter", send_command) +input_field.request_focus() + +# Add some initial commands +for demo_command in ["Hello world!", "This is a simple console", "You can type commands like this:", "/test"]: + input_field.trigger_event("enter", demo_command) + +s.run() diff --git a/Demos/B_BlockText.py b/Demos/B_BlockText.py new file mode 100644 index 0000000..e3d8791 --- /dev/null +++ b/Demos/B_BlockText.py @@ -0,0 +1,103 @@ +import sys +from pathlib import Path + +lui_path = Path(__file__).parent.parent.absolute() +builtin_path = lui_path / "Builtin" +sys.path.insert(0, str(lui_path)) +sys.path.insert(0, str(builtin_path)) +import panda3d.core +import lui +import panda3d +panda3d.lui = lui +sys.modules["panda3d.lui"] = lui + +from DemoFramework import DemoFramework +from LUILabel import LUILabel +from LUIBlockText import LUIBlockText +from LUIScrollableRegion import LUIScrollableRegion + +import random + +f = DemoFramework() +f.prepare_demo("LUIBlockText") + +# Constructor + +f.add_constructor_parameter("text", "u'Label'") +f.add_constructor_parameter("shadow", "True") +f.add_constructor_parameter("font_size", "14") +f.add_constructor_parameter("font", "'label'") + +# Functions +f.add_public_function("clear", []) +f.add_public_function("set_text", [("text", "string")]) +f.add_public_function("set_wrap", [("wrap", "boolean")]) +f.add_public_function("set_width", [("width", "integer")]) + +f.add_property("labels", "list") + +# Events +f.construct_sourcecode("LUIBlockText") + +text_container = LUIScrollableRegion( + parent=f.get_widget_node(), + width=340, + height=190, + padding=0, +) + +#TODO: Support newline through charcode 10 +#TODO: If space causes next line, dont print it + +# Create a new label +label = LUIBlockText(parent=text_container, width=310) + +# Paragraph with no line breaks +label.add( + text='''Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed malesuada sit amet erat non gravida. Pellentesque sit amet cursus risus Sed egestas, nulla in tempor cursus, ante felis cursus magna, nec vehicula nisi nulla eu nulla.''', + color=(0.9,0.9,.9), + wordwrap=True, + padding=5, +) + + +# Paragraph with some linebreaks +label.add( + text='''Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed malesuada sit amet erat non gravida. +Pellentesque sit amet cursus risus Sed egestas, nulla in tempor cursus, ante felis cursus magna, nec vehicula nisi nulla eu nulla. +Nulla sed pellentesque erat. Morbi facilisis at erat id auctor. Phasellus euismod facilisis sem, at molestie velit condimentum sit amet. + +Nulla posuere rhoncus aliquam.''', + color=(0.9,0.9,.9), + wordwrap=True, + padding=5, +) + +# Paragraph with no spaces or linebreaks +label.add( + text='''Loremipsumolorsitamet,consecteturadipiscingelit.Sedmalesuadasitameteratnongravida.PellentesquesitametcursusrisusSedegestas,nullaintemporcursus,antefeliscursusmagna,necvehiculanisinullaeunulla.''', + color=(0.9,0.9,.9), + wordwrap=True, + padding=5, +) + +def setWidth(width): + label.set_width(width) + text_container.on_element_added() + +def setWrap(wrap): + label.set_wrap(wrap) + text_container.on_element_added() + + +f.set_actions({ + "Set Random Text": lambda: label.set_text(str(random.randint(100, 10000))), + "Set Random Color": lambda: label.set_color((random.random(), random.random(), random.random(), 1)), + "Clear": lambda: label.clear(), + "Smaller": lambda: setWidth(200), + "Larger": lambda: setWidth(310), + "Wrapping on": lambda: setWrap(True), + "Wrapping off": lambda: setWrap(False), + }) + +base.run() diff --git a/Demos/B_Button.py b/Demos/B_Button.py new file mode 100644 index 0000000..903325d --- /dev/null +++ b/Demos/B_Button.py @@ -0,0 +1,64 @@ +""" + +This file shows the smallest working LUI example, on which you can base your +LUI projects. + +""" + +# Add lui modules to the path. This will not be required when LUI is included +# in panda. +import sys +from pathlib import Path + +lui_path = Path(__file__).parent.parent.absolute() +builtin_path = lui_path / "Builtin" + +# Make sure the compiled lui.pyd and Builtin helpers can be found +sys.path.insert(0, str(lui_path)) +sys.path.insert(0, str(builtin_path)) + +# Load Panda3D core first so the dll dependencies for lui are present, then +# register the bundled lui module as panda3d.lui (expected by wrappers). +import panda3d.core +import lui +import panda3d +panda3d.lui = lui +sys.modules["panda3d.lui"] = lui + +from DemoFramework import DemoFramework +from LUIButton import LUIButton +from LUIHorizontalLayout import LUIHorizontalLayout + +import random + +f = DemoFramework() +f.prepare_demo("LUIButton") + +# Constructor +f.add_constructor_parameter("text", "u'Button'") +f.add_constructor_parameter("template", "'ButtonDefault'") + +# Functions +f.add_public_function("set_text", [("text", "string")]) +f.add_public_function("get_text", [], "string") +f.add_property("text", "string") + +# Construct source code +f.construct_sourcecode("LUIButton") + +# Create 2 new buttons, and store them in a vertical layout +layout = LUIHorizontalLayout(parent=f.get_widget_node(), spacing=10) + +button1 = LUIButton(text="Do not click me") +button2 = LUIButton(text="Instead click me", template="ButtonGreen") + +layout.add(button1) +layout.add(button2) +def set_btn_text(text): + button1.text = text + +f.set_actions({ + "Set Random Text": lambda: set_btn_text("Text: " + str(random.randint(100, 10000000))), + }) + +run() diff --git a/Demos/B_Checkbox.py b/Demos/B_Checkbox.py new file mode 100644 index 0000000..ef99471 --- /dev/null +++ b/Demos/B_Checkbox.py @@ -0,0 +1,49 @@ +import sys +from pathlib import Path + +lui_path = Path(__file__).parent.parent.absolute() +builtin_path = lui_path / "Builtin" +sys.path.insert(0, str(lui_path)) +sys.path.insert(0, str(builtin_path)) +import panda3d.core +import lui +import panda3d +panda3d.lui = lui +sys.modules["panda3d.lui"] = lui + +from DemoFramework import DemoFramework +from LUICheckbox import LUICheckbox + +import random + +f = DemoFramework() +f.prepare_demo("LUICheckbox") + +# Constructor +f.add_constructor_parameter("checked", "False") +f.add_constructor_parameter("label", "'Checkbox'") + +# Functions +f.add_public_function("get_checked", [], "bool") +f.add_public_function("toggle_checked", [], "bool") +f.add_public_function("set_checked", [("checked", "bool")]) +f.add_public_function("get_label", [], "UILabel") + +f.add_property("checked", "bool") +f.add_property("label", "LUILabel") + +# Events +f.add_event("changed") +f.construct_sourcecode("LUICheckbox") + +# Create the checkbox +checkbox = LUICheckbox(parent=f.get_widget_node()) + +f.set_actions({ + "Set Checked": lambda: checkbox.set_checked(True), + "Set Unchecked": lambda: checkbox.set_checked(False), + "Toggle Checked": lambda: checkbox.toggle_checked(), + "Set Random Text": lambda: checkbox.get_label().set_text("Text: " + str(random.randint(100, 10000))), + }) + +run() diff --git a/Demos/B_FormattedLabel.py b/Demos/B_FormattedLabel.py new file mode 100644 index 0000000..32903d3 --- /dev/null +++ b/Demos/B_FormattedLabel.py @@ -0,0 +1,58 @@ + + +from DemoFramework import DemoFramework +from LUIFormattedLabel import LUIFormattedLabel + +import random + +f = DemoFramework() +f.prepare_demo("LUIFormattedLabel") + +# Functions +f.add_public_function("clear", [], "void") +f.add_public_function("newline", [], "void") +f.add_public_function("add", [("*args", "List"), ("**kwargs", "Dict")]) + +# Events +f.construct_sourcecode("LUIFormattedLabel") + +# Create a new label +label = LUIFormattedLabel(parent=f.get_widget_node()) + +# Add parts to the label +label.add(text="Hello ", color=(0.2,0.6,1.0)) +label.add(text="World", color=(1.0,0.6,0.2)) +label.add(text="! ") +label.add(text="This ", font_size=20, margin=(-6, 0, 0, 0), color=(0.4,0.2,1.0)) +label.add(text="is ", color=(1.0,0.2,1.0)) +label.add(text="a formatted ", font_size=10, color=(0.6,0.3,0.6)) +label.add(text="Label", font_size=25, margin =(-11, 0, 0, 0), color=(0.2,1.0,0.6)) + +# Go to next line +label.newline() +label.newline() + +# Add some more parts +label.add(text="This is the same label ..", color=(0.3,0.7,0.32)) + +# Go to next line +label.newline() +label.newline() + +# Add some more parts +label.add(text="... but another line forced with ", color=(0.6,0.3,0.8)) +label.add(text="newline() ", color=(1.0,0.6,0.2)) + +def make_random_color(): + return (random.random(), random.random(), random.random()) + +def newline(): + label.newline() + label.add(text="New Line!", color=make_random_color()) + +f.set_actions({ + "Add random text": lambda: label.add(text="Text ", color=make_random_color()), + "Go to next line": newline + }) + +run() diff --git a/Demos/B_Frame.py b/Demos/B_Frame.py new file mode 100644 index 0000000..262f005 --- /dev/null +++ b/Demos/B_Frame.py @@ -0,0 +1,43 @@ + + +from DemoFramework import DemoFramework +from LUIVerticalLayout import LUIVerticalLayout +from LUIFrame import LUIFrame +from LUILabel import LUILabel +from LUIButton import LUIButton +from LUIObject import LUIObject + +import random + +f = DemoFramework() +f.prepare_demo("LUIFrame") + +# Constructor +f.add_constructor_parameter("width", "200") +f.add_constructor_parameter("height", "200") +f.add_constructor_parameter("innerPadding", "5") +f.add_constructor_parameter("scrollable", "False") +f.add_constructor_parameter("style", "UIFrame.Raised") + +# Functions + +# Events +f.construct_sourcecode("LUIFrame") + +# Construct a new frame +frame = LUIFrame(parent=f.get_widget_node()) + +layout = LUIVerticalLayout(parent=frame, spacing=5) +layout.add(LUILabel(text="This is some frame ..", color=(0.2, 0.6, 1.0, 1.0), font_size=20)) +layout.add(LUILabel(text="It can contain arbitrary elements.")) +layout.add(LUILabel(text="For example this button:")) +layout.add(LUIButton(text="Fancy button")) + +# frame.fit_to_children() + +f.set_actions({ + "Resize to 300x160": lambda: frame.set_size(300, 160), + "Fit to children": lambda: frame.clear_size(), + }) + +run() diff --git a/Demos/B_InputField.py b/Demos/B_InputField.py new file mode 100644 index 0000000..c378e30 --- /dev/null +++ b/Demos/B_InputField.py @@ -0,0 +1,27 @@ + +from DemoFramework import DemoFramework +from LUIInputField import LUIInputField + +import random + +f = DemoFramework() +f.prepare_demo("LUIInputField") + +# Constructor +f.add_constructor_parameter("value", "u''") +f.add_constructor_parameter("placeholder", "u'Enter some text ..'") +f.add_property("value", "string") +f.add_event("changed") + +# Construct source code +f.construct_sourcecode("LUIInputField") + +# Create 2 new buttons, and store them in a vertical layout +field = LUIInputField(parent=f.get_widget_node()) + +f.set_actions({ + "Set Random Text": lambda: field.set_value(u"Text: " + unicode(random.randint(100, 10000000))), + "Clear": lambda: field.clear(), + }) + +run() diff --git a/Demos/B_Label.py b/Demos/B_Label.py new file mode 100644 index 0000000..206ecc4 --- /dev/null +++ b/Demos/B_Label.py @@ -0,0 +1,36 @@ + + +from DemoFramework import DemoFramework +from LUILabel import LUILabel + +import random + +f = DemoFramework() +f.prepare_demo("LUILabel") + +# Constructor + +f.add_constructor_parameter("text", "Label") +f.add_constructor_parameter("shadow", "True") +f.add_constructor_parameter("font_size", "14") +f.add_constructor_parameter("font", "'label'") + +# Functions +f.add_public_function("get_text", [], "string") +f.add_public_function("set_text", [("text", "string")]) + +f.add_property("text", "string") +f.add_property("text_handle", "LUIText") + +# Events +f.construct_sourcecode("LUILabel") + +# Create a new label +label = LUILabel(parent=f.get_widget_node(), text="This is a fancy label") + +f.set_actions({ + "Set Random Text": lambda: label.set_text(str(random.randint(100, 10000))), + "Set Random Color": lambda: label.set_color(random.random(), random.random(), random.random(), 1) + }) + +run() diff --git a/Demos/B_Progressbar.py b/Demos/B_Progressbar.py new file mode 100644 index 0000000..766c285 --- /dev/null +++ b/Demos/B_Progressbar.py @@ -0,0 +1,40 @@ + + +from DemoFramework import DemoFramework +from LUIProgressbar import LUIProgressbar +from LUISlider import LUISlider +from LUILabel import LUILabel +from LUIVerticalLayout import LUIVerticalLayout + +import random + +f = DemoFramework() +f.prepare_demo("LUIProgressbar") + +# Constructor +f.add_constructor_parameter("show_label", "False") + +# Functions +f.add_public_function("get_value", [], "float") +f.add_public_function("set_value", [("value", "float")]) + +f.add_property("value", "float") + +# Events +f.construct_sourcecode("LUIProgressbar") + +# Create the checkbox +layout = LUIVerticalLayout(parent=f.get_widget_node(), spacing=10) + +LUILabel(parent=layout.cell(), text="This is a progressbar:", color=(1, 1, 1, 0.4)) +bar = LUIProgressbar(parent=layout.cell(), width=200.0) + +LUILabel(parent=layout.cell(), text="You can control it with this slider:", color=(1, 1, 1, 0.4)) +slider = LUISlider(parent=layout.cell(), width=200.0, filled=True) +slider.bind("changed", lambda event: bar.set_value(slider.value * 100.0)) + +f.set_actions({ + "Set to 30%": lambda: bar.set_value(30), + }) + +run() diff --git a/Demos/B_Radiobox.py b/Demos/B_Radiobox.py new file mode 100644 index 0000000..f131617 --- /dev/null +++ b/Demos/B_Radiobox.py @@ -0,0 +1,49 @@ + + +from DemoFramework import DemoFramework +from LUIRadiobox import LUIRadiobox +from LUIRadioboxGroup import LUIRadioboxGroup +from LUIVerticalLayout import LUIVerticalLayout + +import random + +f = DemoFramework() +f.prepare_demo("LUIRadiobox") + +# Constructor +f.add_constructor_parameter("group", "None") +f.add_constructor_parameter("value", "None") +f.add_constructor_parameter("label", "'Radiobox'") + +# Functions +f.add_public_function("get_value", [], "object") +f.add_public_function("get_label", [], "LUILabel") +f.add_public_function("set_active", [], "void") + +f.add_property("value", "object") +f.add_property("label", "LUILabel") + +# Events +f.add_event("changed") +f.construct_sourcecode("LUIRadiobox") + +# Create a group to connect the boxes +group = LUIRadioboxGroup() + +# Create a layout for the boxes +grid = LUIVerticalLayout(parent=f.get_widget_node(), spacing=5) + +# Create the boxes +boxes = [] +for i in range(1, 4): + boxes.append(LUIRadiobox(group=group, value=i, label="Radiobox {0}".format(i), active=i==2)) + grid.add(boxes[-1]) + +f.set_actions({ + "Select Box 1": lambda: boxes[0].set_active(), + "Select Box 2": lambda: boxes[1].set_active(), + "Select Box 3": lambda: boxes[2].set_active(), + "Set Random Text": lambda: boxes[0].label.set_text("Text: " + str(random.randint(100, 10000))), + }) + +run() diff --git a/Demos/B_Slider.py b/Demos/B_Slider.py new file mode 100644 index 0000000..10b3ecd --- /dev/null +++ b/Demos/B_Slider.py @@ -0,0 +1,53 @@ +import sys +from pathlib import Path + +lui_path = Path(__file__).parent.parent.absolute() +builtin_path = lui_path / "Builtin" +sys.path.insert(0, str(lui_path)) +sys.path.insert(0, str(builtin_path)) +import panda3d.core +import lui +import panda3d +panda3d.lui = lui +sys.modules["panda3d.lui"] = lui + +from DemoFramework import DemoFramework +from LUISlider import LUISlider +from LUILabel import LUILabel +from LUIVerticalLayout import LUIVerticalLayout + +import random + +f = DemoFramework() +f.prepare_demo("LUISlider") + +# Constructor +f.add_constructor_parameter("filled", "False") +f.add_constructor_parameter("min_value", "0.0") +f.add_constructor_parameter("max_value", "0.0") +f.add_constructor_parameter("value", "None") + +# Functions +f.add_public_function("get_value", [], "float") +f.add_public_function("set_value", [("value", "float")]) + +f.add_property("value", "float") + +# Events +f.add_event("changed") +f.construct_sourcecode("LUISlider") + +# Create the checkbox +layout = LUIVerticalLayout(parent=f.get_widget_node(), spacing=10) + +LUILabel(parent=layout.cell(), text="This is a filled slider:", color=(1, 1, 1, 0.4)) +slider = LUISlider(parent=layout.cell(), width=200.0) + +LUILabel(parent=layout.cell(), text="This is a regular slider:", color=(1, 1, 1, 0.4)) +slider_nofill = LUISlider(parent=layout.cell(), width=200.0, filled=False) + +f.set_actions({ + "Set to 30%": lambda: slider.set_value(0.3), + }) + +run() diff --git a/Demos/DemoFramework.py b/Demos/DemoFramework.py new file mode 100644 index 0000000..fd44863 --- /dev/null +++ b/Demos/DemoFramework.py @@ -0,0 +1,251 @@ +""" + + +This file contains some setup code for all the widget examples + + +""" + +import sys +from pathlib import Path + +lui_path = Path(__file__).parent.parent.absolute() +builtin_path = lui_path / "Builtin" +sys.path.insert(0, str(lui_path)) +sys.path.insert(0, str(builtin_path)) +import panda3d.core +import lui +import panda3d +panda3d.lui = lui +sys.modules["panda3d.lui"] = lui + +from panda3d.core import * + +from LUIRegion import LUIRegion +from LUIInputHandler import LUIInputHandler +from LUISprite import LUISprite +from LUIObject import LUIObject +from LUIVerticalLayout import LUIVerticalLayout +from LUILabel import LUILabel +from LUIFrame import LUIFrame + +load_prc_file_data("", """ + text-minfilter linear + text-magfilter linear + text-pixels-per-unit 32 + sync-video #f + textures-power-2 none + notify-level-lui info + show-frame-rate-meter #t + win-size 780 630 + window-title LUI Demo + win-fixed-size #f +""") + +import direct.directbase.DirectStart +from LUISkin import LUIDefaultSkin +from LUICheckbox import LUICheckbox +from LUIFormattedLabel import LUIFormattedLabel +from LUISelectbox import LUISelectbox +from LUIButton import LUIButton + +from Skins.Metro.LUIMetroSkin import LUIMetroSkin + +class DemoFramework: + + """ This is a small helper class to setup common stuff for the demos """ + + def __init__(self): + """ Constructs the demo framework """ + + if False: + self._skin = LUIMetroSkin() + base.win.set_clear_color(Vec4(1)) + else: + self._skin = LUIDefaultSkin() + base.win.set_clear_color(Vec4(0.1, 0.0, 0.0, 1)) + self._skin.load() + + # Construct the LUIRegion + region = LUIRegion.make("LUI", base.win) + handler = LUIInputHandler() + base.mouseWatcher.attach_new_node(handler) + region.set_input_handler(handler) + + self._root = region.root + self._constructor_params = [] + + def prepare_demo(self, demo_title=u"Some Demo"): + + # Background + self._background = LUISprite(self._root, "res/DemoBackground.png") + # Make the background solid and recieve events + self._background.solid = True + + # Logo + self._logo = LUISprite(self._root, "res/LUILogo.png") + self._logo.top_left = 15, 20 + + # Title + self._title_label = LUILabel(parent=self._root, text=demo_title, font_size=40, + font="header", pos=(120, 27)) + self._subtitle_label = LUILabel(parent=self._root, text="Widget Demo", font_size=14, + font="default", pos=(121, 70), alpha=0.3) + + # Right bar + + self._right_bar = LUIVerticalLayout(parent=self._root) + self._left_bar = LUIVerticalLayout(parent=self._root) + self._right_bar.width = 350 + self._right_bar.pos = (410, 120) + self._right_bar.spacing = 10 + self._left_bar.width = 350 + self._left_bar.pos=(20, 120) + self._left_bar.spacing = 10 + + # Public functions + self._public_functions = LUIFrame(width=340, style=LUIFrame.FS_sunken) + self._functions_label = LUILabel(text=U"Additional Public functions") + self._functions_layout = LUIVerticalLayout(parent=self._public_functions) + self._functions_layout.add(self._functions_label, 30) + + # Events + self._events = LUIFrame(width=340, style=LUIFrame.FS_sunken) + self._events_label = LUILabel(text=U"Additional Events") + self._events_layout = LUIVerticalLayout(parent=self._events) + self._events_layout.add(self._events_label, 30) + + # Actions + self._actions = LUIFrame(width=340, style=LUIFrame.FS_sunken) + self._actions_label = LUILabel(parent=self._actions, text=U"Demo-Actions") + self._actions_select = LUISelectbox(parent=self._actions, width=225, top=30) + self._actions_btn = LUIButton(parent=self._actions, right=0, top=30, text=u"Execute", template="ButtonGreen") + self._actions_btn.bind("click", self._exec_action) + + # Properties + self._properties = LUIFrame(width=340, style=LUIFrame.FS_sunken) + self._properties_label = LUILabel(text=u"Additional Properties") + self._properties_layout = LUIVerticalLayout(parent=self._properties) + self._properties_layout.add(self._properties_label, 30) + + self._right_bar.add(self._actions) + self._right_bar.add(self._public_functions) + self._right_bar.add(self._properties) + self._right_bar.add(self._events) + + # Widget + self._widget_container = LUIFrame(width=360, height=250, style=LUIFrame.FS_sunken) + self._widget_label = LUILabel(parent=self._widget_container, text=u"Widget Demo") + self._left_bar.add(self._widget_container) + + # Source Code + self._source_container = LUIFrame(width=360, height=190, style=LUIFrame.FS_sunken) + self._source_label = LUILabel(parent=self._source_container, text=u"Default Constructor") + self._copy_code_button = LUIButton(parent=self._source_container, + text=u"Copy to Clipboard", template="ButtonGreen", bottom_right=(0, 0)) + self._source_content = LUIObject(self._source_container) + self._source_content.top = 40 + self._left_bar.add(self._source_container) + + self._widget_node = LUIObject(self._widget_container, x=0, y=40) + + def _exec_action(self, event): + selected = self._actions_select.get_selected_option() + if selected is not None: + selected() + + def set_actions(self, actions): + opts = [] + + for name, action in actions.items(): + opts.append((action, name)) + + self._actions_select.set_options(opts) + + def add_public_function(self, name, parameters=None, return_type="void"): + label = LUIFormattedLabel() + label.add(text=return_type + " ", color = (102/255.0, 217/255.0, 239/255.0)) + label.add(text=name + " ", color = (166/255.0, 226/255.0, 46/255.0)) + + label.add(text="( ", color=(0.9,0.9,0.9)) + + if parameters is not None: + for index, (pname, ptype) in enumerate(parameters): + label.add(text=pname, color=(255/255.0, 151/255.0, 31/255.0)) + label.add(text=" : ", color=(0.9,0.9,0.9)) + label.add(text=ptype, color=(102/255.0, 217/255.0, 239/255.0)) + + if index < len(parameters) - 1: + label.add(text=",", color=(0.9,0.9,0.9)) + label.add(text=" )", color=(0.9,0.9,0.9)) + self._functions_layout.add(label) + self.update_layouts() + + def add_constructor_parameter(self, name, default): + self._constructor_params.append((name, default)) + self.update_layouts() + + def add_event(self, event_name): + label = LUILabel(text=event_name) + label.color = (1,1,1,0.5) + self._events_layout.add(label) + self.update_layouts() + + def add_property(self, property_name, property_type): + label = LUIFormattedLabel() + label.add(text=property_name, color=(255/255.0, 151/255.0, 31/255.0) ) + label.add(" : ", color=(0.9,0.9,0.9) ) + label.add(text=property_type + " ", color=(102/255.0, 217/255.0, 239/255.0) ) + self._properties_layout.add(label) + self.update_layouts() + + def update_layouts(self): + pass + + def construct_sourcecode(self, classname): + self._source_content.remove_all_children() + label = LUIFormattedLabel(parent=self._source_content) + label.add(text="element ", color=(0.9,0.9,0.9)) + label.add(text="= ", color=(249/255.0, 38/255.0, 114/255.0)) + label.add(text=classname, color=(166/255.0, 226/255.0, 46/255.0)) + label.add(text="(", color=(0.9,0.9,0.9)) + + for index, (pname, pvalue) in enumerate(self._constructor_params): + label.newline() + label.add(text=" " * 15) + label.add(text=pname, color=(255/255.0, 151/255.0, 31/255.0)) + label.add(text=" = ") + label.add(text=pvalue, color=(153/255.0, 129/255.0, 255/255.0)) + + if index < len(self._constructor_params) - 1: + label.add(text=",") + + label.add(text=")") + + copy_text = "element = " + classname + "(" + + for index, (pname, pvalue) in enumerate(self._constructor_params): + copy_text += pname + "=" + pvalue + + if index < len(self._constructor_params) - 1: + copy_text += ", " + copy_text += ")" + + def copy_code(event): + # Copies the source code to clipboard + from Tkinter import Tk + r = Tk() + r.withdraw() + r.clipboard_clear() + r.clipboard_append(copy_text) + r.destroy() + + self._copy_code_button.bind("click", copy_code) + + # self._source_content.fit_height_to_children() + # self._source_container.fit_height_to_children() + self._source_container.height += 40 + + + def get_widget_node(self): + return self._widget_node diff --git a/Demos/README.md b/Demos/README.md new file mode 100644 index 0000000..8f203b4 --- /dev/null +++ b/Demos/README.md @@ -0,0 +1,7 @@ + + +This directory contains various LUI demos. You should start with the demos +01 and 02. + +After that, you can try out the demos starting with B_, showing builtin +LUI components. diff --git a/Demos/__init__.py b/Demos/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/Demos/res/DemoBackground.png b/Demos/res/DemoBackground.png new file mode 100644 index 0000000..fa9d41f Binary files /dev/null and b/Demos/res/DemoBackground.png differ diff --git a/Demos/res/LUILogo.png b/Demos/res/LUILogo.png new file mode 100644 index 0000000..b067942 Binary files /dev/null and b/Demos/res/LUILogo.png differ diff --git a/Demos/res/LUILogoBlack.png b/Demos/res/LUILogoBlack.png new file mode 100644 index 0000000..921b99b Binary files /dev/null and b/Demos/res/LUILogoBlack.png differ diff --git a/LICENSE.txt b/LICENSE.txt new file mode 100644 index 0000000..38e9c74 --- /dev/null +++ b/LICENSE.txt @@ -0,0 +1,22 @@ + +RenderPipeline + +Copyright (c) 2014-2016 tobspr + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. diff --git a/README.md b/README.md new file mode 100644 index 0000000..35d3903 --- /dev/null +++ b/README.md @@ -0,0 +1,70 @@ +[![Join the chat at https://gitter.im/tobspr/RenderPipeline](https://badges.gitter.im/tobspr/RenderPipeline.svg)](https://gitter.im/tobspr/RenderPipeline?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge) +[![Build Status](https://travis-ci.org/tobspr/RenderPipeline.svg?branch=master)](https://travis-ci.org/tobspr/RenderPipeline) + + +Deferred Rendering Pipeline with Physically Based Shading + +Deferred Realtime Rendering Pipeline with Physically Based Shading for the Panda3D Game Engine. + +### Core Features + +- Physically Based Shading +- Deferred Rendering +- Advanced Post-Processing Effects and Framework +- Time of Day System +- Plugin System + +## Screenshots + +You can click on the images to enlarge them. Besides of that, you can find many more screenshots in my dropbox folder. + +**Forest** + + +**Material demo** + + +**Screen space reflections** + + +**Car rendering** +Car rendering + +**Plugin and Time of Day editor:** + + +**Terrain and volumetric clouds** + + + +See the Feature List +for a list of features, and list of techniques I intend to implement. + +You can find my todo list for the render pipeline here: Render Pipeline Roadmap. + +### Getting Started / Wiki + +You should checkout the wiki if you want to find out more about the pipeline: +Render Pipeline WIKI + +There is also a page about getting started there: Getting Started + +### Requirements + +- OpenGL 4.3 capable GPU (and drivers) +- Panda3D Development Build +- 1 GB Graphics Memory recommended *(Can run with less, depends on enabled plugins and resolution)* + +**Notice**: It seems that the drivers for Intel HD Graphics on Linux are not +capable of all 4.3 features, so the pipeline is not able to run there! + +If you want to use the C++ Modules, checkout +Building the C++ Modules to get a list of requirements for them. + +### Reporting Bugs / Contributing + +If you find bugs, or find information missing in the wiki, or want to contribute, +you can find me most of the time in the `#panda3d` channel on freenode. + +If I shouldn't be there, feel free to contact me per E-Mail: `tobias.springer1@googlemail.com` + diff --git a/Skins/Default/GenerateAtlas.bat b/Skins/Default/GenerateAtlas.bat new file mode 100644 index 0000000..3ae0bb0 --- /dev/null +++ b/Skins/Default/GenerateAtlas.bat @@ -0,0 +1,5 @@ +@echo off + +cd res +ppython ../../../Misc/LUIAtlasGen.py +pause diff --git a/Skins/Default/__init__.py b/Skins/Default/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/Skins/Default/font/SourceSansPro-Black.ttf b/Skins/Default/font/SourceSansPro-Black.ttf new file mode 100644 index 0000000..0243842 Binary files /dev/null and b/Skins/Default/font/SourceSansPro-Black.ttf differ diff --git a/Skins/Default/font/SourceSansPro-BlackIt.ttf b/Skins/Default/font/SourceSansPro-BlackIt.ttf new file mode 100644 index 0000000..167045f Binary files /dev/null and b/Skins/Default/font/SourceSansPro-BlackIt.ttf differ diff --git a/Skins/Default/font/SourceSansPro-Bold.ttf b/Skins/Default/font/SourceSansPro-Bold.ttf new file mode 100644 index 0000000..be46652 Binary files /dev/null and b/Skins/Default/font/SourceSansPro-Bold.ttf differ diff --git a/Skins/Default/font/SourceSansPro-BoldIt.ttf b/Skins/Default/font/SourceSansPro-BoldIt.ttf new file mode 100644 index 0000000..fd5c4f3 Binary files /dev/null and b/Skins/Default/font/SourceSansPro-BoldIt.ttf differ diff --git a/Skins/Default/font/SourceSansPro-ExtraLight.ttf b/Skins/Default/font/SourceSansPro-ExtraLight.ttf new file mode 100644 index 0000000..182165c Binary files /dev/null and b/Skins/Default/font/SourceSansPro-ExtraLight.ttf differ diff --git a/Skins/Default/font/SourceSansPro-ExtraLightIt.ttf b/Skins/Default/font/SourceSansPro-ExtraLightIt.ttf new file mode 100644 index 0000000..5846588 Binary files /dev/null and b/Skins/Default/font/SourceSansPro-ExtraLightIt.ttf differ diff --git a/Skins/Default/font/SourceSansPro-It.ttf b/Skins/Default/font/SourceSansPro-It.ttf new file mode 100644 index 0000000..c689cd2 Binary files /dev/null and b/Skins/Default/font/SourceSansPro-It.ttf differ diff --git a/Skins/Default/font/SourceSansPro-Light.ttf b/Skins/Default/font/SourceSansPro-Light.ttf new file mode 100644 index 0000000..dcff4e9 Binary files /dev/null and b/Skins/Default/font/SourceSansPro-Light.ttf differ diff --git a/Skins/Default/font/SourceSansPro-LightIt.ttf b/Skins/Default/font/SourceSansPro-LightIt.ttf new file mode 100644 index 0000000..0c3451f Binary files /dev/null and b/Skins/Default/font/SourceSansPro-LightIt.ttf differ diff --git a/Skins/Default/font/SourceSansPro-Regular.ttf b/Skins/Default/font/SourceSansPro-Regular.ttf new file mode 100644 index 0000000..a011dff Binary files /dev/null and b/Skins/Default/font/SourceSansPro-Regular.ttf differ diff --git a/Skins/Default/font/SourceSansPro-Semibold.ttf b/Skins/Default/font/SourceSansPro-Semibold.ttf new file mode 100644 index 0000000..dbf946a Binary files /dev/null and b/Skins/Default/font/SourceSansPro-Semibold.ttf differ diff --git a/Skins/Default/font/SourceSansPro-SemiboldIt.ttf b/Skins/Default/font/SourceSansPro-SemiboldIt.ttf new file mode 100644 index 0000000..d1bc7f0 Binary files /dev/null and b/Skins/Default/font/SourceSansPro-SemiboldIt.ttf differ diff --git a/Skins/Default/res/ButtonDefault.png b/Skins/Default/res/ButtonDefault.png new file mode 100644 index 0000000..b3e08cb Binary files /dev/null and b/Skins/Default/res/ButtonDefault.png differ diff --git a/Skins/Default/res/ButtonDefaultFocus.png b/Skins/Default/res/ButtonDefaultFocus.png new file mode 100644 index 0000000..3dee247 Binary files /dev/null and b/Skins/Default/res/ButtonDefaultFocus.png differ diff --git a/Skins/Default/res/ButtonDefaultFocus_Left.png b/Skins/Default/res/ButtonDefaultFocus_Left.png new file mode 100644 index 0000000..8702ed6 Binary files /dev/null and b/Skins/Default/res/ButtonDefaultFocus_Left.png differ diff --git a/Skins/Default/res/ButtonDefaultFocus_Right.png b/Skins/Default/res/ButtonDefaultFocus_Right.png new file mode 100644 index 0000000..c60bccc Binary files /dev/null and b/Skins/Default/res/ButtonDefaultFocus_Right.png differ diff --git a/Skins/Default/res/ButtonDefault_Left.png b/Skins/Default/res/ButtonDefault_Left.png new file mode 100644 index 0000000..3415584 Binary files /dev/null and b/Skins/Default/res/ButtonDefault_Left.png differ diff --git a/Skins/Default/res/ButtonDefault_Right.png b/Skins/Default/res/ButtonDefault_Right.png new file mode 100644 index 0000000..60a8e17 Binary files /dev/null and b/Skins/Default/res/ButtonDefault_Right.png differ diff --git a/Skins/Default/res/ButtonGreen.png b/Skins/Default/res/ButtonGreen.png new file mode 100644 index 0000000..e2a42a4 Binary files /dev/null and b/Skins/Default/res/ButtonGreen.png differ diff --git a/Skins/Default/res/ButtonGreenFocus.png b/Skins/Default/res/ButtonGreenFocus.png new file mode 100644 index 0000000..d340eb7 Binary files /dev/null and b/Skins/Default/res/ButtonGreenFocus.png differ diff --git a/Skins/Default/res/ButtonGreenFocus_Left.png b/Skins/Default/res/ButtonGreenFocus_Left.png new file mode 100644 index 0000000..2b9e8d3 Binary files /dev/null and b/Skins/Default/res/ButtonGreenFocus_Left.png differ diff --git a/Skins/Default/res/ButtonGreenFocus_Right.png b/Skins/Default/res/ButtonGreenFocus_Right.png new file mode 100644 index 0000000..5d5196e Binary files /dev/null and b/Skins/Default/res/ButtonGreenFocus_Right.png differ diff --git a/Skins/Default/res/ButtonGreen_Left.png b/Skins/Default/res/ButtonGreen_Left.png new file mode 100644 index 0000000..3291d7b Binary files /dev/null and b/Skins/Default/res/ButtonGreen_Left.png differ diff --git a/Skins/Default/res/ButtonGreen_Right.png b/Skins/Default/res/ButtonGreen_Right.png new file mode 100644 index 0000000..46e16de Binary files /dev/null and b/Skins/Default/res/ButtonGreen_Right.png differ diff --git a/Skins/Default/res/Checkbox_Checked.png b/Skins/Default/res/Checkbox_Checked.png new file mode 100644 index 0000000..d082280 Binary files /dev/null and b/Skins/Default/res/Checkbox_Checked.png differ diff --git a/Skins/Default/res/Checkbox_CheckedHover.png b/Skins/Default/res/Checkbox_CheckedHover.png new file mode 100644 index 0000000..fd9eadd Binary files /dev/null and b/Skins/Default/res/Checkbox_CheckedHover.png differ diff --git a/Skins/Default/res/Checkbox_Default.png b/Skins/Default/res/Checkbox_Default.png new file mode 100644 index 0000000..f8ff012 Binary files /dev/null and b/Skins/Default/res/Checkbox_Default.png differ diff --git a/Skins/Default/res/Checkbox_DefaultHover.png b/Skins/Default/res/Checkbox_DefaultHover.png new file mode 100644 index 0000000..2619443 Binary files /dev/null and b/Skins/Default/res/Checkbox_DefaultHover.png differ diff --git a/Skins/Default/res/ColorpickerActiveColorOverlay.png b/Skins/Default/res/ColorpickerActiveColorOverlay.png new file mode 100644 index 0000000..0527409 Binary files /dev/null and b/Skins/Default/res/ColorpickerActiveColorOverlay.png differ diff --git a/Skins/Default/res/ColorpickerFieldHandle.png b/Skins/Default/res/ColorpickerFieldHandle.png new file mode 100644 index 0000000..f6109c0 Binary files /dev/null and b/Skins/Default/res/ColorpickerFieldHandle.png differ diff --git a/Skins/Default/res/ColorpickerFieldOverlay.png b/Skins/Default/res/ColorpickerFieldOverlay.png new file mode 100644 index 0000000..89289a3 Binary files /dev/null and b/Skins/Default/res/ColorpickerFieldOverlay.png differ diff --git a/Skins/Default/res/ColorpickerHueHandle.png b/Skins/Default/res/ColorpickerHueHandle.png new file mode 100644 index 0000000..287020c Binary files /dev/null and b/Skins/Default/res/ColorpickerHueHandle.png differ diff --git a/Skins/Default/res/ColorpickerHueSlider.png b/Skins/Default/res/ColorpickerHueSlider.png new file mode 100644 index 0000000..bb73fea Binary files /dev/null and b/Skins/Default/res/ColorpickerHueSlider.png differ diff --git a/Skins/Default/res/ColorpickerPreviewBg.png b/Skins/Default/res/ColorpickerPreviewBg.png new file mode 100644 index 0000000..7c5759a Binary files /dev/null and b/Skins/Default/res/ColorpickerPreviewBg.png differ diff --git a/Skins/Default/res/ColorpickerPreviewOverlay.png b/Skins/Default/res/ColorpickerPreviewOverlay.png new file mode 100644 index 0000000..0d691ff Binary files /dev/null and b/Skins/Default/res/ColorpickerPreviewOverlay.png differ diff --git a/Skins/Default/res/Frame_BL.png b/Skins/Default/res/Frame_BL.png new file mode 100644 index 0000000..31c6705 Binary files /dev/null and b/Skins/Default/res/Frame_BL.png differ diff --git a/Skins/Default/res/Frame_BR.png b/Skins/Default/res/Frame_BR.png new file mode 100644 index 0000000..62b0381 Binary files /dev/null and b/Skins/Default/res/Frame_BR.png differ diff --git a/Skins/Default/res/Frame_Bottom.png b/Skins/Default/res/Frame_Bottom.png new file mode 100644 index 0000000..0023580 Binary files /dev/null and b/Skins/Default/res/Frame_Bottom.png differ diff --git a/Skins/Default/res/Frame_Left.png b/Skins/Default/res/Frame_Left.png new file mode 100644 index 0000000..1d781ff Binary files /dev/null and b/Skins/Default/res/Frame_Left.png differ diff --git a/Skins/Default/res/Frame_Mid.png b/Skins/Default/res/Frame_Mid.png new file mode 100644 index 0000000..7a96c24 Binary files /dev/null and b/Skins/Default/res/Frame_Mid.png differ diff --git a/Skins/Default/res/Frame_Right.png b/Skins/Default/res/Frame_Right.png new file mode 100644 index 0000000..fa9355e Binary files /dev/null and b/Skins/Default/res/Frame_Right.png differ diff --git a/Skins/Default/res/Frame_TL.png b/Skins/Default/res/Frame_TL.png new file mode 100644 index 0000000..aa18852 Binary files /dev/null and b/Skins/Default/res/Frame_TL.png differ diff --git a/Skins/Default/res/Frame_TR.png b/Skins/Default/res/Frame_TR.png new file mode 100644 index 0000000..08b46bb Binary files /dev/null and b/Skins/Default/res/Frame_TR.png differ diff --git a/Skins/Default/res/Frame_Top.png b/Skins/Default/res/Frame_Top.png new file mode 100644 index 0000000..cec2bf2 Binary files /dev/null and b/Skins/Default/res/Frame_Top.png differ diff --git a/Skins/Default/res/HorizontalListDivider.png b/Skins/Default/res/HorizontalListDivider.png new file mode 100644 index 0000000..6e48500 Binary files /dev/null and b/Skins/Default/res/HorizontalListDivider.png differ diff --git a/Skins/Default/res/InputField.png b/Skins/Default/res/InputField.png new file mode 100644 index 0000000..db58301 Binary files /dev/null and b/Skins/Default/res/InputField.png differ diff --git a/Skins/Default/res/InputField_Left.png b/Skins/Default/res/InputField_Left.png new file mode 100644 index 0000000..8ecd16a Binary files /dev/null and b/Skins/Default/res/InputField_Left.png differ diff --git a/Skins/Default/res/InputField_Right.png b/Skins/Default/res/InputField_Right.png new file mode 100644 index 0000000..e9a1b43 Binary files /dev/null and b/Skins/Default/res/InputField_Right.png differ diff --git a/Skins/Default/res/Keymarker.png b/Skins/Default/res/Keymarker.png new file mode 100644 index 0000000..e5723fc Binary files /dev/null and b/Skins/Default/res/Keymarker.png differ diff --git a/Skins/Default/res/Keymarker_Left.png b/Skins/Default/res/Keymarker_Left.png new file mode 100644 index 0000000..0fd4ce2 Binary files /dev/null and b/Skins/Default/res/Keymarker_Left.png differ diff --git a/Skins/Default/res/Keymarker_Right.png b/Skins/Default/res/Keymarker_Right.png new file mode 100644 index 0000000..f6c3ca9 Binary files /dev/null and b/Skins/Default/res/Keymarker_Right.png differ diff --git a/Skins/Default/res/ListDivider.png b/Skins/Default/res/ListDivider.png new file mode 100644 index 0000000..6e48500 Binary files /dev/null and b/Skins/Default/res/ListDivider.png differ diff --git a/Skins/Default/res/Popup_BL.png b/Skins/Default/res/Popup_BL.png new file mode 100644 index 0000000..b268f11 Binary files /dev/null and b/Skins/Default/res/Popup_BL.png differ diff --git a/Skins/Default/res/Popup_BR.png b/Skins/Default/res/Popup_BR.png new file mode 100644 index 0000000..648c791 Binary files /dev/null and b/Skins/Default/res/Popup_BR.png differ diff --git a/Skins/Default/res/Popup_Bottom.png b/Skins/Default/res/Popup_Bottom.png new file mode 100644 index 0000000..690ff31 Binary files /dev/null and b/Skins/Default/res/Popup_Bottom.png differ diff --git a/Skins/Default/res/Popup_Left.png b/Skins/Default/res/Popup_Left.png new file mode 100644 index 0000000..d87d698 Binary files /dev/null and b/Skins/Default/res/Popup_Left.png differ diff --git a/Skins/Default/res/Popup_Mid.png b/Skins/Default/res/Popup_Mid.png new file mode 100644 index 0000000..cb210d7 Binary files /dev/null and b/Skins/Default/res/Popup_Mid.png differ diff --git a/Skins/Default/res/Popup_Right.png b/Skins/Default/res/Popup_Right.png new file mode 100644 index 0000000..595d862 Binary files /dev/null and b/Skins/Default/res/Popup_Right.png differ diff --git a/Skins/Default/res/Popup_TL.png b/Skins/Default/res/Popup_TL.png new file mode 100644 index 0000000..3815592 Binary files /dev/null and b/Skins/Default/res/Popup_TL.png differ diff --git a/Skins/Default/res/Popup_TR.png b/Skins/Default/res/Popup_TR.png new file mode 100644 index 0000000..10ba6b7 Binary files /dev/null and b/Skins/Default/res/Popup_TR.png differ diff --git a/Skins/Default/res/Popup_Top.png b/Skins/Default/res/Popup_Top.png new file mode 100644 index 0000000..15ebd9d Binary files /dev/null and b/Skins/Default/res/Popup_Top.png differ diff --git a/Skins/Default/res/ProgressbarBg.png b/Skins/Default/res/ProgressbarBg.png new file mode 100644 index 0000000..324a30b Binary files /dev/null and b/Skins/Default/res/ProgressbarBg.png differ diff --git a/Skins/Default/res/ProgressbarBg_Left.png b/Skins/Default/res/ProgressbarBg_Left.png new file mode 100644 index 0000000..35ea1af Binary files /dev/null and b/Skins/Default/res/ProgressbarBg_Left.png differ diff --git a/Skins/Default/res/ProgressbarBg_Right.png b/Skins/Default/res/ProgressbarBg_Right.png new file mode 100644 index 0000000..4a250d5 Binary files /dev/null and b/Skins/Default/res/ProgressbarBg_Right.png differ diff --git a/Skins/Default/res/ProgressbarFg.png b/Skins/Default/res/ProgressbarFg.png new file mode 100644 index 0000000..d0e9349 Binary files /dev/null and b/Skins/Default/res/ProgressbarFg.png differ diff --git a/Skins/Default/res/ProgressbarFg_Finish.png b/Skins/Default/res/ProgressbarFg_Finish.png new file mode 100644 index 0000000..e7c5e43 Binary files /dev/null and b/Skins/Default/res/ProgressbarFg_Finish.png differ diff --git a/Skins/Default/res/ProgressbarFg_Left.png b/Skins/Default/res/ProgressbarFg_Left.png new file mode 100644 index 0000000..924f3f3 Binary files /dev/null and b/Skins/Default/res/ProgressbarFg_Left.png differ diff --git a/Skins/Default/res/ProgressbarFg_Right.png b/Skins/Default/res/ProgressbarFg_Right.png new file mode 100644 index 0000000..355a7ef Binary files /dev/null and b/Skins/Default/res/ProgressbarFg_Right.png differ diff --git a/Skins/Default/res/Radiobox_Active.png b/Skins/Default/res/Radiobox_Active.png new file mode 100644 index 0000000..0859618 Binary files /dev/null and b/Skins/Default/res/Radiobox_Active.png differ diff --git a/Skins/Default/res/Radiobox_ActiveHover.png b/Skins/Default/res/Radiobox_ActiveHover.png new file mode 100644 index 0000000..fd0f0a1 Binary files /dev/null and b/Skins/Default/res/Radiobox_ActiveHover.png differ diff --git a/Skins/Default/res/Radiobox_Default.png b/Skins/Default/res/Radiobox_Default.png new file mode 100644 index 0000000..25a0a2b Binary files /dev/null and b/Skins/Default/res/Radiobox_Default.png differ diff --git a/Skins/Default/res/Radiobox_DefaultHover.png b/Skins/Default/res/Radiobox_DefaultHover.png new file mode 100644 index 0000000..1fef48b Binary files /dev/null and b/Skins/Default/res/Radiobox_DefaultHover.png differ diff --git a/Skins/Default/res/ScrollShadowBottom.png b/Skins/Default/res/ScrollShadowBottom.png new file mode 100644 index 0000000..ab3e37b Binary files /dev/null and b/Skins/Default/res/ScrollShadowBottom.png differ diff --git a/Skins/Default/res/ScrollShadowBottom_Left.png b/Skins/Default/res/ScrollShadowBottom_Left.png new file mode 100644 index 0000000..929a34a Binary files /dev/null and b/Skins/Default/res/ScrollShadowBottom_Left.png differ diff --git a/Skins/Default/res/ScrollShadowBottom_Right.png b/Skins/Default/res/ScrollShadowBottom_Right.png new file mode 100644 index 0000000..7363bf6 Binary files /dev/null and b/Skins/Default/res/ScrollShadowBottom_Right.png differ diff --git a/Skins/Default/res/ScrollShadowTop.png b/Skins/Default/res/ScrollShadowTop.png new file mode 100644 index 0000000..55f4250 Binary files /dev/null and b/Skins/Default/res/ScrollShadowTop.png differ diff --git a/Skins/Default/res/ScrollShadowTop_Left.png b/Skins/Default/res/ScrollShadowTop_Left.png new file mode 100644 index 0000000..e4d93db Binary files /dev/null and b/Skins/Default/res/ScrollShadowTop_Left.png differ diff --git a/Skins/Default/res/ScrollShadowTop_Right.png b/Skins/Default/res/ScrollShadowTop_Right.png new file mode 100644 index 0000000..bb52bcd Binary files /dev/null and b/Skins/Default/res/ScrollShadowTop_Right.png differ diff --git a/Skins/Default/res/ScrollbarHandle.png b/Skins/Default/res/ScrollbarHandle.png new file mode 100644 index 0000000..6455956 Binary files /dev/null and b/Skins/Default/res/ScrollbarHandle.png differ diff --git a/Skins/Default/res/ScrollbarHandle_Bottom.png b/Skins/Default/res/ScrollbarHandle_Bottom.png new file mode 100644 index 0000000..f475f5d Binary files /dev/null and b/Skins/Default/res/ScrollbarHandle_Bottom.png differ diff --git a/Skins/Default/res/ScrollbarHandle_Top.png b/Skins/Default/res/ScrollbarHandle_Top.png new file mode 100644 index 0000000..62faa39 Binary files /dev/null and b/Skins/Default/res/ScrollbarHandle_Top.png differ diff --git a/Skins/Default/res/Selectbox.png b/Skins/Default/res/Selectbox.png new file mode 100644 index 0000000..e3ae52e Binary files /dev/null and b/Skins/Default/res/Selectbox.png differ diff --git a/Skins/Default/res/SelectboxActive.png b/Skins/Default/res/SelectboxActive.png new file mode 100644 index 0000000..c1fe8b6 Binary files /dev/null and b/Skins/Default/res/SelectboxActive.png differ diff --git a/Skins/Default/res/SelectboxActive_Left.png b/Skins/Default/res/SelectboxActive_Left.png new file mode 100644 index 0000000..511c2d4 Binary files /dev/null and b/Skins/Default/res/SelectboxActive_Left.png differ diff --git a/Skins/Default/res/SelectboxOpen_Right.png b/Skins/Default/res/SelectboxOpen_Right.png new file mode 100644 index 0000000..020a360 Binary files /dev/null and b/Skins/Default/res/SelectboxOpen_Right.png differ diff --git a/Skins/Default/res/Selectbox_Left.png b/Skins/Default/res/Selectbox_Left.png new file mode 100644 index 0000000..1bf301f Binary files /dev/null and b/Skins/Default/res/Selectbox_Left.png differ diff --git a/Skins/Default/res/Selectbox_Right.png b/Skins/Default/res/Selectbox_Right.png new file mode 100644 index 0000000..05e88d9 Binary files /dev/null and b/Skins/Default/res/Selectbox_Right.png differ diff --git a/Skins/Default/res/SelectdropDivider.png b/Skins/Default/res/SelectdropDivider.png new file mode 100644 index 0000000..c83b68e Binary files /dev/null and b/Skins/Default/res/SelectdropDivider.png differ diff --git a/Skins/Default/res/Selectdrop_BL.png b/Skins/Default/res/Selectdrop_BL.png new file mode 100644 index 0000000..0cd0b31 Binary files /dev/null and b/Skins/Default/res/Selectdrop_BL.png differ diff --git a/Skins/Default/res/Selectdrop_BR.png b/Skins/Default/res/Selectdrop_BR.png new file mode 100644 index 0000000..9a39f01 Binary files /dev/null and b/Skins/Default/res/Selectdrop_BR.png differ diff --git a/Skins/Default/res/Selectdrop_Bottom.png b/Skins/Default/res/Selectdrop_Bottom.png new file mode 100644 index 0000000..1cff174 Binary files /dev/null and b/Skins/Default/res/Selectdrop_Bottom.png differ diff --git a/Skins/Default/res/Selectdrop_Left.png b/Skins/Default/res/Selectdrop_Left.png new file mode 100644 index 0000000..d223578 Binary files /dev/null and b/Skins/Default/res/Selectdrop_Left.png differ diff --git a/Skins/Default/res/Selectdrop_Mid.png b/Skins/Default/res/Selectdrop_Mid.png new file mode 100644 index 0000000..71ff34c Binary files /dev/null and b/Skins/Default/res/Selectdrop_Mid.png differ diff --git a/Skins/Default/res/Selectdrop_Right.png b/Skins/Default/res/Selectdrop_Right.png new file mode 100644 index 0000000..5958be4 Binary files /dev/null and b/Skins/Default/res/Selectdrop_Right.png differ diff --git a/Skins/Default/res/Selectdrop_TL.png b/Skins/Default/res/Selectdrop_TL.png new file mode 100644 index 0000000..52f1204 Binary files /dev/null and b/Skins/Default/res/Selectdrop_TL.png differ diff --git a/Skins/Default/res/Selectdrop_TR.png b/Skins/Default/res/Selectdrop_TR.png new file mode 100644 index 0000000..e091f82 Binary files /dev/null and b/Skins/Default/res/Selectdrop_TR.png differ diff --git a/Skins/Default/res/Selectdrop_Top.png b/Skins/Default/res/Selectdrop_Top.png new file mode 100644 index 0000000..d97b68a Binary files /dev/null and b/Skins/Default/res/Selectdrop_Top.png differ diff --git a/Skins/Default/res/SliderBg.png b/Skins/Default/res/SliderBg.png new file mode 100644 index 0000000..520e627 Binary files /dev/null and b/Skins/Default/res/SliderBg.png differ diff --git a/Skins/Default/res/SliderBgFill.png b/Skins/Default/res/SliderBgFill.png new file mode 100644 index 0000000..8a94104 Binary files /dev/null and b/Skins/Default/res/SliderBgFill.png differ diff --git a/Skins/Default/res/SliderBgFill_Left.png b/Skins/Default/res/SliderBgFill_Left.png new file mode 100644 index 0000000..eef5890 Binary files /dev/null and b/Skins/Default/res/SliderBgFill_Left.png differ diff --git a/Skins/Default/res/SliderBg_Left.png b/Skins/Default/res/SliderBg_Left.png new file mode 100644 index 0000000..d53ab94 Binary files /dev/null and b/Skins/Default/res/SliderBg_Left.png differ diff --git a/Skins/Default/res/SliderBg_Right.png b/Skins/Default/res/SliderBg_Right.png new file mode 100644 index 0000000..cecf516 Binary files /dev/null and b/Skins/Default/res/SliderBg_Right.png differ diff --git a/Skins/Default/res/SliderKnob.png b/Skins/Default/res/SliderKnob.png new file mode 100644 index 0000000..f7ba432 Binary files /dev/null and b/Skins/Default/res/SliderKnob.png differ diff --git a/Skins/Default/res/SunkenFrame_BL.png b/Skins/Default/res/SunkenFrame_BL.png new file mode 100644 index 0000000..2557ef9 Binary files /dev/null and b/Skins/Default/res/SunkenFrame_BL.png differ diff --git a/Skins/Default/res/SunkenFrame_BR.png b/Skins/Default/res/SunkenFrame_BR.png new file mode 100644 index 0000000..58f43ac Binary files /dev/null and b/Skins/Default/res/SunkenFrame_BR.png differ diff --git a/Skins/Default/res/SunkenFrame_Bottom.png b/Skins/Default/res/SunkenFrame_Bottom.png new file mode 100644 index 0000000..c5e6b43 Binary files /dev/null and b/Skins/Default/res/SunkenFrame_Bottom.png differ diff --git a/Skins/Default/res/SunkenFrame_Left.png b/Skins/Default/res/SunkenFrame_Left.png new file mode 100644 index 0000000..e5ded00 Binary files /dev/null and b/Skins/Default/res/SunkenFrame_Left.png differ diff --git a/Skins/Default/res/SunkenFrame_Mid.png b/Skins/Default/res/SunkenFrame_Mid.png new file mode 100644 index 0000000..53b37c0 Binary files /dev/null and b/Skins/Default/res/SunkenFrame_Mid.png differ diff --git a/Skins/Default/res/SunkenFrame_Right.png b/Skins/Default/res/SunkenFrame_Right.png new file mode 100644 index 0000000..e11ea86 Binary files /dev/null and b/Skins/Default/res/SunkenFrame_Right.png differ diff --git a/Skins/Default/res/SunkenFrame_TL.png b/Skins/Default/res/SunkenFrame_TL.png new file mode 100644 index 0000000..3d9c89f Binary files /dev/null and b/Skins/Default/res/SunkenFrame_TL.png differ diff --git a/Skins/Default/res/SunkenFrame_TR.png b/Skins/Default/res/SunkenFrame_TR.png new file mode 100644 index 0000000..d65b509 Binary files /dev/null and b/Skins/Default/res/SunkenFrame_TR.png differ diff --git a/Skins/Default/res/SunkenFrame_Top.png b/Skins/Default/res/SunkenFrame_Top.png new file mode 100644 index 0000000..aa396eb Binary files /dev/null and b/Skins/Default/res/SunkenFrame_Top.png differ diff --git a/Skins/Default/res/atlas.png b/Skins/Default/res/atlas.png new file mode 100644 index 0000000..df6ecf3 Binary files /dev/null and b/Skins/Default/res/atlas.png differ diff --git a/Skins/Default/res/atlas.txt b/Skins/Default/res/atlas.txt new file mode 100644 index 0000000..8ecaa54 --- /dev/null +++ b/Skins/Default/res/atlas.txt @@ -0,0 +1,101 @@ +ColorpickerFieldOverlay 0 0 132 132 +ColorpickerHueSlider 132 0 24 132 +ColorpickerActiveColorOverlay 156 0 44 44 +Frame_BL 200 0 36 36 +Frame_BR 200 36 36 36 +Frame_TL 156 44 36 36 +Frame_TR 192 72 36 36 +Popup_BL 156 80 36 36 +Popup_BR 192 108 36 36 +Popup_TL 156 116 36 36 +Popup_TR 0 132 36 36 +Frame_Bottom 36 132 31 36 +Frame_Left 67 132 36 31 +Frame_Right 103 132 36 31 +Frame_Top 192 144 31 36 +Popup_Bottom 223 144 31 36 +Popup_Left 139 152 36 31 +Popup_Right 67 163 36 31 +Popup_Top 103 163 31 36 +ColorpickerHueHandle 0 168 50 22 +SelectboxOpen_Right 175 180 32 32 +Selectbox_Right 207 180 32 32 +ColorpickerPreviewBg 134 183 31 31 +ColorpickerPreviewOverlay 228 72 27 27 +ScrollShadowBottom_Left 236 0 18 18 +ScrollShadowBottom_Right 236 18 18 18 +ScrollShadowTop_Left 236 36 18 18 +ScrollShadowTop_Right 236 54 18 18 +SliderKnob 228 99 18 18 +Checkbox_Checked 228 117 17 17 +Checkbox_CheckedHover 139 132 17 17 +Checkbox_Default 175 152 17 17 +Checkbox_DefaultHover 50 168 17 17 +Radiobox_Active 239 180 17 17 +Radiobox_Default 50 185 17 17 +ColorpickerFieldHandle 0 190 16 17 +Radiobox_ActiveHover 16 190 16 17 +Radiobox_DefaultHover 32 190 16 17 +ProgressbarFg_Finish 67 194 13 20 +ProgressbarFg_Right 245 117 11 20 +Keymarker_Left 192 44 6 27 +Keymarker_Right 165 183 6 27 +ButtonDefaultFocus_Left 80 194 5 32 +ButtonDefaultFocus_Right 85 194 5 32 +ButtonDefault_Left 90 194 5 32 +ButtonDefault_Right 95 194 5 32 +ButtonGreenFocus_Left 239 197 5 32 +ButtonGreenFocus_Right 244 197 5 32 +ButtonGreen_Left 171 183 4 32 +ButtonGreen_Right 249 197 4 32 +SelectboxActive_Left 100 199 4 32 +Selectbox_Left 104 199 4 32 +SunkenFrame_Left 108 199 5 24 +SunkenFrame_Right 113 199 5 24 +SunkenFrame_Bottom 228 137 23 5 +SunkenFrame_Top 0 207 23 5 +InputField_Left 253 197 3 29 +InputField_Right 118 199 3 29 +Selectdrop_BL 246 99 9 9 +Selectdrop_BR 246 108 9 9 +ScrollbarHandle_Top 175 169 11 6 +ProgressbarFg_Left 134 163 3 20 +ProgressbarBg_Left 121 199 3 19 +ProgressbarBg_Right 124 199 3 19 +ScrollbarHandle_Bottom 175 175 11 5 +ButtonDefault 254 0 1 32 +ButtonDefaultFocus 255 0 1 32 +ButtonGreen 254 32 1 32 +ButtonGreenFocus 255 32 1 32 +Selectbox 255 64 1 32 +SelectboxActive 254 137 1 32 +SliderBgFill_Left 186 169 4 8 +Frame_Mid 255 137 1 31 +Popup_Mid 48 190 1 31 +Selectdrop_TL 127 199 6 5 +Selectdrop_TR 49 202 6 5 +InputField 133 199 1 29 +Keymarker 198 44 1 27 +SunkenFrame_BL 55 202 5 5 +SunkenFrame_BR 60 202 5 5 +SunkenFrame_TL 127 204 5 5 +SunkenFrame_TR 23 207 5 5 +SunkenFrame_Mid 199 44 1 24 +SliderBg_Left 251 137 3 7 +SliderBg_Right 28 207 3 7 +ProgressbarFg 255 96 1 20 +ProgressbarBg 137 163 1 19 +ScrollShadowBottom 138 163 1 18 +ScrollShadowTop 65 202 1 18 +ScrollbarHandle 228 134 11 1 +SliderBgFill 254 64 1 8 +SliderBg 255 168 1 7 +Selectdrop_Bottom 190 169 1 6 +Selectdrop_Left 192 71 6 1 +Selectdrop_Right 239 134 6 1 +Selectdrop_Top 191 169 1 5 +SelectdropDivider 199 68 1 2 +blank 199 70 1 1 +HorizontalListDivider 198 71 1 1 +ListDivider 199 71 1 1 +Selectdrop_Mid 255 116 1 1 diff --git a/Skins/Default/res/blank.png b/Skins/Default/res/blank.png new file mode 100644 index 0000000..fc4efe0 Binary files /dev/null and b/Skins/Default/res/blank.png differ diff --git a/Skins/Metro/GenerateAtlas.bat b/Skins/Metro/GenerateAtlas.bat new file mode 100644 index 0000000..3ae0bb0 --- /dev/null +++ b/Skins/Metro/GenerateAtlas.bat @@ -0,0 +1,5 @@ +@echo off + +cd res +ppython ../../../Misc/LUIAtlasGen.py +pause diff --git a/Skins/Metro/LUIMetroSkin.py b/Skins/Metro/LUIMetroSkin.py new file mode 100644 index 0000000..5c454ee --- /dev/null +++ b/Skins/Metro/LUIMetroSkin.py @@ -0,0 +1,35 @@ + +from panda3d.lui import LUIFontPool, LUIAtlasPool +from panda3d.core import Filename +import os +from os.path import join + +from LUISkin import LUISkin +from LUILabel import LUILabel + +class LUIMetroSkin(LUISkin): + + """ Simple Metro / Flat UI skin """ + + skin_location = os.path.dirname(os.path.abspath(__file__)) + + def load(self): + LUIFontPool.get_global_ptr().register_font( + "default", loader.loadFont(self.get_resource("font/Roboto-Medium.ttf"))) + + label_font = loader.loadFont(self.get_resource("font/Roboto-Medium.ttf")) + label_font.set_pixels_per_unit(32) + LUIFontPool.get_global_ptr().register_font("label", label_font) + + headerFont = loader.loadFont(self.get_resource("font/Roboto-Light.ttf")) + headerFont.set_pixels_per_unit(80) + + LUIFontPool.get_global_ptr().register_font("header", headerFont) + + LUIAtlasPool.get_global_ptr().load_atlas("skin", + self.get_resource("res/atlas.txt"), + self.get_resource("res/atlas.png")) + + # Label color + # LUILabel.DEFAULT_COLOR = (0.0, 0.0, 0.0, 0.6) + # LUILabel.DEFAULT_USE_SHADOW = False diff --git a/Skins/Metro/__init__.py b/Skins/Metro/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/Skins/Metro/border.png b/Skins/Metro/border.png new file mode 100644 index 0000000..54f1514 Binary files /dev/null and b/Skins/Metro/border.png differ diff --git a/Skins/Metro/copy_frames.py b/Skins/Metro/copy_frames.py new file mode 100644 index 0000000..eb2d29f --- /dev/null +++ b/Skins/Metro/copy_frames.py @@ -0,0 +1,41 @@ + +import os +from shutil import copyfile as copy +os.chdir("res/") + +for f in os.listdir("."): + if f.startswith("Popup_") or f.startswith("Frame_") or f.startswith("SunkenFrame_"): + copy("../flat.png" if "_Mid" in f else "../border.png", f) + + +copy("ButtonDefault.png", "ButtonDefaultFocus.png") +copy("ButtonDefault.png", "ButtonDefaultFocus_Left.png") +copy("ButtonDefault.png", "ButtonDefaultFocus_Right.png") +copy("ButtonDefault.png", "ButtonDefault_Left.png") +copy("ButtonDefault.png", "ButtonDefault_Right.png") + +copy("ButtonGreen.png", "ButtonGreenFocus.png") +copy("ButtonGreen.png", "ButtonGreenFocus_Left.png") +copy("ButtonGreen.png", "ButtonGreenFocus_Right.png") +copy("ButtonGreen.png", "ButtonGreen_Left.png") +copy("ButtonGreen.png", "ButtonGreen_Right.png") + +copy("Selectbox.png", "Selectbox_Left.png") +copy("Selectbox.png", "SelectboxActive.png") +copy("Selectbox.png", "SelectboxActive_Left.png") + +copy("ProgressbarFg.png", "ProgressbarFg_Right.png") +copy("ProgressbarFg.png", "ProgressbarFg_Left.png") +copy("ProgressbarFg.png", "ProgressbarFg_Finish.png") +copy("ProgressbarBg.png", "ProgressbarBg_Right.png") +copy("ProgressbarBg.png", "ProgressbarBg_Left.png") + +copy("SliderBgFill.png", "SliderBgFill_Left.png") +copy("SliderBg.png", "SliderBg_Left.png") +copy("SliderBg.png", "SliderBg_Right.png") + +copy("InputField.png", "InputField_Left.png") +copy("InputField.png", "InputField_Right.png") + +for align in "TR TL BR BL Top Right Bottom Left".split(): + copy("Selectdrop_Mid.png", "Selectdrop_" + align + ".png") diff --git a/Skins/Metro/flat.png b/Skins/Metro/flat.png new file mode 100644 index 0000000..77a13c5 Binary files /dev/null and b/Skins/Metro/flat.png differ diff --git a/Skins/Metro/font/Roboto-Bold.ttf b/Skins/Metro/font/Roboto-Bold.ttf new file mode 100644 index 0000000..aaf374d Binary files /dev/null and b/Skins/Metro/font/Roboto-Bold.ttf differ diff --git a/Skins/Metro/font/Roboto-LICENSE.txt b/Skins/Metro/font/Roboto-LICENSE.txt new file mode 100644 index 0000000..817dcac --- /dev/null +++ b/Skins/Metro/font/Roboto-LICENSE.txt @@ -0,0 +1,178 @@ +Font data copyright Google 2012 + + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + “License” shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + “Licensor” shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + “Legal Entity” shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + “control” means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + “You” (or “Your”) shall mean an individual or Legal Entity + exercising permissions granted by this License. + + “Source” form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + “Object” form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + “Work” shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + “Derivative Works” shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + “Contribution” shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, “submitted” + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as “Not a Contribution.” + + “Contributor” shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a “NOTICE” text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an “AS IS” BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS diff --git a/Skins/Metro/font/Roboto-Light.ttf b/Skins/Metro/font/Roboto-Light.ttf new file mode 100644 index 0000000..664e1b2 Binary files /dev/null and b/Skins/Metro/font/Roboto-Light.ttf differ diff --git a/Skins/Metro/font/Roboto-Medium.ttf b/Skins/Metro/font/Roboto-Medium.ttf new file mode 100644 index 0000000..8798341 Binary files /dev/null and b/Skins/Metro/font/Roboto-Medium.ttf differ diff --git a/Skins/Metro/font/Roboto-Thin.ttf b/Skins/Metro/font/Roboto-Thin.ttf new file mode 100644 index 0000000..d262d14 Binary files /dev/null and b/Skins/Metro/font/Roboto-Thin.ttf differ diff --git a/Skins/Metro/res/ButtonDefault.png b/Skins/Metro/res/ButtonDefault.png new file mode 100644 index 0000000..8baf82e Binary files /dev/null and b/Skins/Metro/res/ButtonDefault.png differ diff --git a/Skins/Metro/res/ButtonDefaultFocus.png b/Skins/Metro/res/ButtonDefaultFocus.png new file mode 100644 index 0000000..8baf82e Binary files /dev/null and b/Skins/Metro/res/ButtonDefaultFocus.png differ diff --git a/Skins/Metro/res/ButtonDefaultFocus_Left.png b/Skins/Metro/res/ButtonDefaultFocus_Left.png new file mode 100644 index 0000000..8baf82e Binary files /dev/null and b/Skins/Metro/res/ButtonDefaultFocus_Left.png differ diff --git a/Skins/Metro/res/ButtonDefaultFocus_Right.png b/Skins/Metro/res/ButtonDefaultFocus_Right.png new file mode 100644 index 0000000..8baf82e Binary files /dev/null and b/Skins/Metro/res/ButtonDefaultFocus_Right.png differ diff --git a/Skins/Metro/res/ButtonDefault_Left.png b/Skins/Metro/res/ButtonDefault_Left.png new file mode 100644 index 0000000..8baf82e Binary files /dev/null and b/Skins/Metro/res/ButtonDefault_Left.png differ diff --git a/Skins/Metro/res/ButtonDefault_Right.png b/Skins/Metro/res/ButtonDefault_Right.png new file mode 100644 index 0000000..8baf82e Binary files /dev/null and b/Skins/Metro/res/ButtonDefault_Right.png differ diff --git a/Skins/Metro/res/ButtonGreen.png b/Skins/Metro/res/ButtonGreen.png new file mode 100644 index 0000000..e4d1fbf Binary files /dev/null and b/Skins/Metro/res/ButtonGreen.png differ diff --git a/Skins/Metro/res/ButtonGreenFocus.png b/Skins/Metro/res/ButtonGreenFocus.png new file mode 100644 index 0000000..e4d1fbf Binary files /dev/null and b/Skins/Metro/res/ButtonGreenFocus.png differ diff --git a/Skins/Metro/res/ButtonGreenFocus_Left.png b/Skins/Metro/res/ButtonGreenFocus_Left.png new file mode 100644 index 0000000..e4d1fbf Binary files /dev/null and b/Skins/Metro/res/ButtonGreenFocus_Left.png differ diff --git a/Skins/Metro/res/ButtonGreenFocus_Right.png b/Skins/Metro/res/ButtonGreenFocus_Right.png new file mode 100644 index 0000000..e4d1fbf Binary files /dev/null and b/Skins/Metro/res/ButtonGreenFocus_Right.png differ diff --git a/Skins/Metro/res/ButtonGreen_Left.png b/Skins/Metro/res/ButtonGreen_Left.png new file mode 100644 index 0000000..e4d1fbf Binary files /dev/null and b/Skins/Metro/res/ButtonGreen_Left.png differ diff --git a/Skins/Metro/res/ButtonGreen_Right.png b/Skins/Metro/res/ButtonGreen_Right.png new file mode 100644 index 0000000..e4d1fbf Binary files /dev/null and b/Skins/Metro/res/ButtonGreen_Right.png differ diff --git a/Skins/Metro/res/Checkbox_Checked.png b/Skins/Metro/res/Checkbox_Checked.png new file mode 100644 index 0000000..cec474b Binary files /dev/null and b/Skins/Metro/res/Checkbox_Checked.png differ diff --git a/Skins/Metro/res/Checkbox_CheckedHover.png b/Skins/Metro/res/Checkbox_CheckedHover.png new file mode 100644 index 0000000..cec474b Binary files /dev/null and b/Skins/Metro/res/Checkbox_CheckedHover.png differ diff --git a/Skins/Metro/res/Checkbox_Default.png b/Skins/Metro/res/Checkbox_Default.png new file mode 100644 index 0000000..46ab47d Binary files /dev/null and b/Skins/Metro/res/Checkbox_Default.png differ diff --git a/Skins/Metro/res/Checkbox_DefaultHover.png b/Skins/Metro/res/Checkbox_DefaultHover.png new file mode 100644 index 0000000..46ab47d Binary files /dev/null and b/Skins/Metro/res/Checkbox_DefaultHover.png differ diff --git a/Skins/Metro/res/ColorpickerActiveColorOverlay.png b/Skins/Metro/res/ColorpickerActiveColorOverlay.png new file mode 100644 index 0000000..0527409 Binary files /dev/null and b/Skins/Metro/res/ColorpickerActiveColorOverlay.png differ diff --git a/Skins/Metro/res/ColorpickerFieldHandle.png b/Skins/Metro/res/ColorpickerFieldHandle.png new file mode 100644 index 0000000..f6109c0 Binary files /dev/null and b/Skins/Metro/res/ColorpickerFieldHandle.png differ diff --git a/Skins/Metro/res/ColorpickerFieldOverlay.png b/Skins/Metro/res/ColorpickerFieldOverlay.png new file mode 100644 index 0000000..89289a3 Binary files /dev/null and b/Skins/Metro/res/ColorpickerFieldOverlay.png differ diff --git a/Skins/Metro/res/ColorpickerHueHandle.png b/Skins/Metro/res/ColorpickerHueHandle.png new file mode 100644 index 0000000..287020c Binary files /dev/null and b/Skins/Metro/res/ColorpickerHueHandle.png differ diff --git a/Skins/Metro/res/ColorpickerHueSlider.png b/Skins/Metro/res/ColorpickerHueSlider.png new file mode 100644 index 0000000..bb73fea Binary files /dev/null and b/Skins/Metro/res/ColorpickerHueSlider.png differ diff --git a/Skins/Metro/res/ColorpickerPreviewBg.png b/Skins/Metro/res/ColorpickerPreviewBg.png new file mode 100644 index 0000000..7c5759a Binary files /dev/null and b/Skins/Metro/res/ColorpickerPreviewBg.png differ diff --git a/Skins/Metro/res/ColorpickerPreviewOverlay.png b/Skins/Metro/res/ColorpickerPreviewOverlay.png new file mode 100644 index 0000000..0d691ff Binary files /dev/null and b/Skins/Metro/res/ColorpickerPreviewOverlay.png differ diff --git a/Skins/Metro/res/Frame_BL.png b/Skins/Metro/res/Frame_BL.png new file mode 100644 index 0000000..54f1514 Binary files /dev/null and b/Skins/Metro/res/Frame_BL.png differ diff --git a/Skins/Metro/res/Frame_BR.png b/Skins/Metro/res/Frame_BR.png new file mode 100644 index 0000000..54f1514 Binary files /dev/null and b/Skins/Metro/res/Frame_BR.png differ diff --git a/Skins/Metro/res/Frame_Bottom.png b/Skins/Metro/res/Frame_Bottom.png new file mode 100644 index 0000000..54f1514 Binary files /dev/null and b/Skins/Metro/res/Frame_Bottom.png differ diff --git a/Skins/Metro/res/Frame_Left.png b/Skins/Metro/res/Frame_Left.png new file mode 100644 index 0000000..54f1514 Binary files /dev/null and b/Skins/Metro/res/Frame_Left.png differ diff --git a/Skins/Metro/res/Frame_Mid.png b/Skins/Metro/res/Frame_Mid.png new file mode 100644 index 0000000..77a13c5 Binary files /dev/null and b/Skins/Metro/res/Frame_Mid.png differ diff --git a/Skins/Metro/res/Frame_Right.png b/Skins/Metro/res/Frame_Right.png new file mode 100644 index 0000000..54f1514 Binary files /dev/null and b/Skins/Metro/res/Frame_Right.png differ diff --git a/Skins/Metro/res/Frame_TL.png b/Skins/Metro/res/Frame_TL.png new file mode 100644 index 0000000..54f1514 Binary files /dev/null and b/Skins/Metro/res/Frame_TL.png differ diff --git a/Skins/Metro/res/Frame_TR.png b/Skins/Metro/res/Frame_TR.png new file mode 100644 index 0000000..54f1514 Binary files /dev/null and b/Skins/Metro/res/Frame_TR.png differ diff --git a/Skins/Metro/res/Frame_Top.png b/Skins/Metro/res/Frame_Top.png new file mode 100644 index 0000000..54f1514 Binary files /dev/null and b/Skins/Metro/res/Frame_Top.png differ diff --git a/Skins/Metro/res/HorizontalListDivider.png b/Skins/Metro/res/HorizontalListDivider.png new file mode 100644 index 0000000..95007b9 Binary files /dev/null and b/Skins/Metro/res/HorizontalListDivider.png differ diff --git a/Skins/Metro/res/InputField.png b/Skins/Metro/res/InputField.png new file mode 100644 index 0000000..c03ab63 Binary files /dev/null and b/Skins/Metro/res/InputField.png differ diff --git a/Skins/Metro/res/InputField_Left.png b/Skins/Metro/res/InputField_Left.png new file mode 100644 index 0000000..c03ab63 Binary files /dev/null and b/Skins/Metro/res/InputField_Left.png differ diff --git a/Skins/Metro/res/InputField_Right.png b/Skins/Metro/res/InputField_Right.png new file mode 100644 index 0000000..c03ab63 Binary files /dev/null and b/Skins/Metro/res/InputField_Right.png differ diff --git a/Skins/Metro/res/Keymarker.png b/Skins/Metro/res/Keymarker.png new file mode 100644 index 0000000..e5723fc Binary files /dev/null and b/Skins/Metro/res/Keymarker.png differ diff --git a/Skins/Metro/res/Keymarker_Left.png b/Skins/Metro/res/Keymarker_Left.png new file mode 100644 index 0000000..0fd4ce2 Binary files /dev/null and b/Skins/Metro/res/Keymarker_Left.png differ diff --git a/Skins/Metro/res/Keymarker_Right.png b/Skins/Metro/res/Keymarker_Right.png new file mode 100644 index 0000000..f6c3ca9 Binary files /dev/null and b/Skins/Metro/res/Keymarker_Right.png differ diff --git a/Skins/Metro/res/ListDivider.png b/Skins/Metro/res/ListDivider.png new file mode 100644 index 0000000..6e48500 Binary files /dev/null and b/Skins/Metro/res/ListDivider.png differ diff --git a/Skins/Metro/res/Popup_BL.png b/Skins/Metro/res/Popup_BL.png new file mode 100644 index 0000000..54f1514 Binary files /dev/null and b/Skins/Metro/res/Popup_BL.png differ diff --git a/Skins/Metro/res/Popup_BR.png b/Skins/Metro/res/Popup_BR.png new file mode 100644 index 0000000..54f1514 Binary files /dev/null and b/Skins/Metro/res/Popup_BR.png differ diff --git a/Skins/Metro/res/Popup_Bottom.png b/Skins/Metro/res/Popup_Bottom.png new file mode 100644 index 0000000..54f1514 Binary files /dev/null and b/Skins/Metro/res/Popup_Bottom.png differ diff --git a/Skins/Metro/res/Popup_Left.png b/Skins/Metro/res/Popup_Left.png new file mode 100644 index 0000000..54f1514 Binary files /dev/null and b/Skins/Metro/res/Popup_Left.png differ diff --git a/Skins/Metro/res/Popup_Mid.png b/Skins/Metro/res/Popup_Mid.png new file mode 100644 index 0000000..77a13c5 Binary files /dev/null and b/Skins/Metro/res/Popup_Mid.png differ diff --git a/Skins/Metro/res/Popup_Right.png b/Skins/Metro/res/Popup_Right.png new file mode 100644 index 0000000..54f1514 Binary files /dev/null and b/Skins/Metro/res/Popup_Right.png differ diff --git a/Skins/Metro/res/Popup_TL.png b/Skins/Metro/res/Popup_TL.png new file mode 100644 index 0000000..54f1514 Binary files /dev/null and b/Skins/Metro/res/Popup_TL.png differ diff --git a/Skins/Metro/res/Popup_TR.png b/Skins/Metro/res/Popup_TR.png new file mode 100644 index 0000000..54f1514 Binary files /dev/null and b/Skins/Metro/res/Popup_TR.png differ diff --git a/Skins/Metro/res/Popup_Top.png b/Skins/Metro/res/Popup_Top.png new file mode 100644 index 0000000..54f1514 Binary files /dev/null and b/Skins/Metro/res/Popup_Top.png differ diff --git a/Skins/Metro/res/ProgressbarBg.png b/Skins/Metro/res/ProgressbarBg.png new file mode 100644 index 0000000..0e6c65b Binary files /dev/null and b/Skins/Metro/res/ProgressbarBg.png differ diff --git a/Skins/Metro/res/ProgressbarBg_Left.png b/Skins/Metro/res/ProgressbarBg_Left.png new file mode 100644 index 0000000..0e6c65b Binary files /dev/null and b/Skins/Metro/res/ProgressbarBg_Left.png differ diff --git a/Skins/Metro/res/ProgressbarBg_Right.png b/Skins/Metro/res/ProgressbarBg_Right.png new file mode 100644 index 0000000..0e6c65b Binary files /dev/null and b/Skins/Metro/res/ProgressbarBg_Right.png differ diff --git a/Skins/Metro/res/ProgressbarFg.png b/Skins/Metro/res/ProgressbarFg.png new file mode 100644 index 0000000..62b2190 Binary files /dev/null and b/Skins/Metro/res/ProgressbarFg.png differ diff --git a/Skins/Metro/res/ProgressbarFg_Finish.png b/Skins/Metro/res/ProgressbarFg_Finish.png new file mode 100644 index 0000000..62b2190 Binary files /dev/null and b/Skins/Metro/res/ProgressbarFg_Finish.png differ diff --git a/Skins/Metro/res/ProgressbarFg_Left.png b/Skins/Metro/res/ProgressbarFg_Left.png new file mode 100644 index 0000000..62b2190 Binary files /dev/null and b/Skins/Metro/res/ProgressbarFg_Left.png differ diff --git a/Skins/Metro/res/ProgressbarFg_Right.png b/Skins/Metro/res/ProgressbarFg_Right.png new file mode 100644 index 0000000..62b2190 Binary files /dev/null and b/Skins/Metro/res/ProgressbarFg_Right.png differ diff --git a/Skins/Metro/res/Radiobox_Active.png b/Skins/Metro/res/Radiobox_Active.png new file mode 100644 index 0000000..ecffab4 Binary files /dev/null and b/Skins/Metro/res/Radiobox_Active.png differ diff --git a/Skins/Metro/res/Radiobox_ActiveHover.png b/Skins/Metro/res/Radiobox_ActiveHover.png new file mode 100644 index 0000000..ecffab4 Binary files /dev/null and b/Skins/Metro/res/Radiobox_ActiveHover.png differ diff --git a/Skins/Metro/res/Radiobox_Default.png b/Skins/Metro/res/Radiobox_Default.png new file mode 100644 index 0000000..10647eb Binary files /dev/null and b/Skins/Metro/res/Radiobox_Default.png differ diff --git a/Skins/Metro/res/Radiobox_DefaultHover.png b/Skins/Metro/res/Radiobox_DefaultHover.png new file mode 100644 index 0000000..10647eb Binary files /dev/null and b/Skins/Metro/res/Radiobox_DefaultHover.png differ diff --git a/Skins/Metro/res/ScrollShadowBottom.png b/Skins/Metro/res/ScrollShadowBottom.png new file mode 100644 index 0000000..ab3e37b Binary files /dev/null and b/Skins/Metro/res/ScrollShadowBottom.png differ diff --git a/Skins/Metro/res/ScrollShadowBottom_Left.png b/Skins/Metro/res/ScrollShadowBottom_Left.png new file mode 100644 index 0000000..929a34a Binary files /dev/null and b/Skins/Metro/res/ScrollShadowBottom_Left.png differ diff --git a/Skins/Metro/res/ScrollShadowBottom_Right.png b/Skins/Metro/res/ScrollShadowBottom_Right.png new file mode 100644 index 0000000..7363bf6 Binary files /dev/null and b/Skins/Metro/res/ScrollShadowBottom_Right.png differ diff --git a/Skins/Metro/res/ScrollShadowTop.png b/Skins/Metro/res/ScrollShadowTop.png new file mode 100644 index 0000000..55f4250 Binary files /dev/null and b/Skins/Metro/res/ScrollShadowTop.png differ diff --git a/Skins/Metro/res/ScrollShadowTop_Left.png b/Skins/Metro/res/ScrollShadowTop_Left.png new file mode 100644 index 0000000..e4d93db Binary files /dev/null and b/Skins/Metro/res/ScrollShadowTop_Left.png differ diff --git a/Skins/Metro/res/ScrollShadowTop_Right.png b/Skins/Metro/res/ScrollShadowTop_Right.png new file mode 100644 index 0000000..bb52bcd Binary files /dev/null and b/Skins/Metro/res/ScrollShadowTop_Right.png differ diff --git a/Skins/Metro/res/ScrollbarHandle.png b/Skins/Metro/res/ScrollbarHandle.png new file mode 100644 index 0000000..6455956 Binary files /dev/null and b/Skins/Metro/res/ScrollbarHandle.png differ diff --git a/Skins/Metro/res/ScrollbarHandle_Bottom.png b/Skins/Metro/res/ScrollbarHandle_Bottom.png new file mode 100644 index 0000000..f475f5d Binary files /dev/null and b/Skins/Metro/res/ScrollbarHandle_Bottom.png differ diff --git a/Skins/Metro/res/ScrollbarHandle_Top.png b/Skins/Metro/res/ScrollbarHandle_Top.png new file mode 100644 index 0000000..62faa39 Binary files /dev/null and b/Skins/Metro/res/ScrollbarHandle_Top.png differ diff --git a/Skins/Metro/res/Selectbox.png b/Skins/Metro/res/Selectbox.png new file mode 100644 index 0000000..4f2fa11 Binary files /dev/null and b/Skins/Metro/res/Selectbox.png differ diff --git a/Skins/Metro/res/SelectboxActive.png b/Skins/Metro/res/SelectboxActive.png new file mode 100644 index 0000000..4f2fa11 Binary files /dev/null and b/Skins/Metro/res/SelectboxActive.png differ diff --git a/Skins/Metro/res/SelectboxActive_Left.png b/Skins/Metro/res/SelectboxActive_Left.png new file mode 100644 index 0000000..4f2fa11 Binary files /dev/null and b/Skins/Metro/res/SelectboxActive_Left.png differ diff --git a/Skins/Metro/res/SelectboxOpen_Right.png b/Skins/Metro/res/SelectboxOpen_Right.png new file mode 100644 index 0000000..5898630 Binary files /dev/null and b/Skins/Metro/res/SelectboxOpen_Right.png differ diff --git a/Skins/Metro/res/Selectbox_Left.png b/Skins/Metro/res/Selectbox_Left.png new file mode 100644 index 0000000..4f2fa11 Binary files /dev/null and b/Skins/Metro/res/Selectbox_Left.png differ diff --git a/Skins/Metro/res/Selectbox_Right.png b/Skins/Metro/res/Selectbox_Right.png new file mode 100644 index 0000000..d5d32ab Binary files /dev/null and b/Skins/Metro/res/Selectbox_Right.png differ diff --git a/Skins/Metro/res/SelectdropDivider.png b/Skins/Metro/res/SelectdropDivider.png new file mode 100644 index 0000000..95007b9 Binary files /dev/null and b/Skins/Metro/res/SelectdropDivider.png differ diff --git a/Skins/Metro/res/Selectdrop_BL.png b/Skins/Metro/res/Selectdrop_BL.png new file mode 100644 index 0000000..264bb30 Binary files /dev/null and b/Skins/Metro/res/Selectdrop_BL.png differ diff --git a/Skins/Metro/res/Selectdrop_BR.png b/Skins/Metro/res/Selectdrop_BR.png new file mode 100644 index 0000000..264bb30 Binary files /dev/null and b/Skins/Metro/res/Selectdrop_BR.png differ diff --git a/Skins/Metro/res/Selectdrop_Bottom.png b/Skins/Metro/res/Selectdrop_Bottom.png new file mode 100644 index 0000000..264bb30 Binary files /dev/null and b/Skins/Metro/res/Selectdrop_Bottom.png differ diff --git a/Skins/Metro/res/Selectdrop_Left.png b/Skins/Metro/res/Selectdrop_Left.png new file mode 100644 index 0000000..264bb30 Binary files /dev/null and b/Skins/Metro/res/Selectdrop_Left.png differ diff --git a/Skins/Metro/res/Selectdrop_Mid.png b/Skins/Metro/res/Selectdrop_Mid.png new file mode 100644 index 0000000..264bb30 Binary files /dev/null and b/Skins/Metro/res/Selectdrop_Mid.png differ diff --git a/Skins/Metro/res/Selectdrop_Right.png b/Skins/Metro/res/Selectdrop_Right.png new file mode 100644 index 0000000..264bb30 Binary files /dev/null and b/Skins/Metro/res/Selectdrop_Right.png differ diff --git a/Skins/Metro/res/Selectdrop_TL.png b/Skins/Metro/res/Selectdrop_TL.png new file mode 100644 index 0000000..264bb30 Binary files /dev/null and b/Skins/Metro/res/Selectdrop_TL.png differ diff --git a/Skins/Metro/res/Selectdrop_TR.png b/Skins/Metro/res/Selectdrop_TR.png new file mode 100644 index 0000000..264bb30 Binary files /dev/null and b/Skins/Metro/res/Selectdrop_TR.png differ diff --git a/Skins/Metro/res/Selectdrop_Top.png b/Skins/Metro/res/Selectdrop_Top.png new file mode 100644 index 0000000..264bb30 Binary files /dev/null and b/Skins/Metro/res/Selectdrop_Top.png differ diff --git a/Skins/Metro/res/SliderBg.png b/Skins/Metro/res/SliderBg.png new file mode 100644 index 0000000..0e6c65b Binary files /dev/null and b/Skins/Metro/res/SliderBg.png differ diff --git a/Skins/Metro/res/SliderBgFill.png b/Skins/Metro/res/SliderBgFill.png new file mode 100644 index 0000000..62b2190 Binary files /dev/null and b/Skins/Metro/res/SliderBgFill.png differ diff --git a/Skins/Metro/res/SliderBgFill_Left.png b/Skins/Metro/res/SliderBgFill_Left.png new file mode 100644 index 0000000..62b2190 Binary files /dev/null and b/Skins/Metro/res/SliderBgFill_Left.png differ diff --git a/Skins/Metro/res/SliderBg_Left.png b/Skins/Metro/res/SliderBg_Left.png new file mode 100644 index 0000000..0e6c65b Binary files /dev/null and b/Skins/Metro/res/SliderBg_Left.png differ diff --git a/Skins/Metro/res/SliderBg_Right.png b/Skins/Metro/res/SliderBg_Right.png new file mode 100644 index 0000000..0e6c65b Binary files /dev/null and b/Skins/Metro/res/SliderBg_Right.png differ diff --git a/Skins/Metro/res/SliderKnob.png b/Skins/Metro/res/SliderKnob.png new file mode 100644 index 0000000..507e900 Binary files /dev/null and b/Skins/Metro/res/SliderKnob.png differ diff --git a/Skins/Metro/res/SunkenFrame_BL.png b/Skins/Metro/res/SunkenFrame_BL.png new file mode 100644 index 0000000..54f1514 Binary files /dev/null and b/Skins/Metro/res/SunkenFrame_BL.png differ diff --git a/Skins/Metro/res/SunkenFrame_BR.png b/Skins/Metro/res/SunkenFrame_BR.png new file mode 100644 index 0000000..54f1514 Binary files /dev/null and b/Skins/Metro/res/SunkenFrame_BR.png differ diff --git a/Skins/Metro/res/SunkenFrame_Bottom.png b/Skins/Metro/res/SunkenFrame_Bottom.png new file mode 100644 index 0000000..54f1514 Binary files /dev/null and b/Skins/Metro/res/SunkenFrame_Bottom.png differ diff --git a/Skins/Metro/res/SunkenFrame_Left.png b/Skins/Metro/res/SunkenFrame_Left.png new file mode 100644 index 0000000..54f1514 Binary files /dev/null and b/Skins/Metro/res/SunkenFrame_Left.png differ diff --git a/Skins/Metro/res/SunkenFrame_Mid.png b/Skins/Metro/res/SunkenFrame_Mid.png new file mode 100644 index 0000000..77a13c5 Binary files /dev/null and b/Skins/Metro/res/SunkenFrame_Mid.png differ diff --git a/Skins/Metro/res/SunkenFrame_Right.png b/Skins/Metro/res/SunkenFrame_Right.png new file mode 100644 index 0000000..54f1514 Binary files /dev/null and b/Skins/Metro/res/SunkenFrame_Right.png differ diff --git a/Skins/Metro/res/SunkenFrame_TL.png b/Skins/Metro/res/SunkenFrame_TL.png new file mode 100644 index 0000000..54f1514 Binary files /dev/null and b/Skins/Metro/res/SunkenFrame_TL.png differ diff --git a/Skins/Metro/res/SunkenFrame_TR.png b/Skins/Metro/res/SunkenFrame_TR.png new file mode 100644 index 0000000..54f1514 Binary files /dev/null and b/Skins/Metro/res/SunkenFrame_TR.png differ diff --git a/Skins/Metro/res/SunkenFrame_Top.png b/Skins/Metro/res/SunkenFrame_Top.png new file mode 100644 index 0000000..54f1514 Binary files /dev/null and b/Skins/Metro/res/SunkenFrame_Top.png differ diff --git a/Skins/Metro/res/atlas.png b/Skins/Metro/res/atlas.png new file mode 100644 index 0000000..732a2a6 Binary files /dev/null and b/Skins/Metro/res/atlas.png differ diff --git a/Skins/Metro/res/atlas.txt b/Skins/Metro/res/atlas.txt new file mode 100644 index 0000000..c6dd47b --- /dev/null +++ b/Skins/Metro/res/atlas.txt @@ -0,0 +1,101 @@ +ColorpickerFieldOverlay 0 0 132 132 +ColorpickerHueSlider 132 0 24 132 +ColorpickerActiveColorOverlay 156 0 44 44 +SelectboxOpen_Right 200 0 37 36 +Selectbox_Right 200 36 37 36 +ColorpickerHueHandle 156 72 50 22 +ColorpickerPreviewBg 206 72 31 31 +ColorpickerPreviewOverlay 156 44 27 27 +ScrollShadowBottom_Left 237 0 18 18 +ScrollShadowBottom_Right 237 18 18 18 +ScrollShadowTop_Left 237 36 18 18 +ScrollShadowTop_Right 237 54 18 18 +Checkbox_Checked 183 44 17 17 +Checkbox_CheckedHover 237 72 17 17 +Checkbox_Default 237 89 17 17 +Checkbox_DefaultHover 156 94 17 17 +Radiobox_Active 173 94 17 17 +Radiobox_ActiveHover 190 103 17 17 +Radiobox_Default 207 103 17 17 +Radiobox_DefaultHover 224 106 17 17 +ColorpickerFieldHandle 156 111 16 17 +Keymarker_Left 241 106 6 27 +Keymarker_Right 247 106 6 27 +SliderKnob 172 111 8 18 +ScrollbarHandle_Top 183 61 11 6 +ScrollbarHandle_Bottom 183 67 11 5 +InputField 255 0 1 39 +InputField_Left 255 39 1 39 +InputField_Right 254 72 1 39 +ButtonDefault 255 78 1 36 +ButtonDefaultFocus 253 106 1 36 +ButtonDefaultFocus_Left 180 111 1 36 +ButtonDefaultFocus_Right 181 111 1 36 +ButtonDefault_Left 182 111 1 36 +ButtonDefault_Right 183 111 1 36 +ButtonGreen 184 111 1 36 +ButtonGreenFocus 185 111 1 36 +ButtonGreenFocus_Left 186 111 1 36 +ButtonGreenFocus_Right 187 111 1 36 +ButtonGreen_Left 188 111 1 36 +ButtonGreen_Right 189 111 1 36 +Selectbox 254 111 1 36 +SelectboxActive 255 114 1 36 +SelectboxActive_Left 190 120 1 36 +Selectbox_Left 191 120 1 36 +Keymarker 192 120 1 27 +ScrollShadowBottom 193 120 1 18 +ScrollShadowTop 194 120 1 18 +ScrollbarHandle 156 71 11 1 +ProgressbarBg 194 61 1 5 +ProgressbarBg_Left 195 61 1 5 +ProgressbarBg_Right 196 61 1 5 +ProgressbarFg 197 61 1 5 +ProgressbarFg_Finish 198 61 1 5 +ProgressbarFg_Left 199 61 1 5 +ProgressbarFg_Right 194 66 1 5 +SliderBg 195 66 1 5 +SliderBgFill 196 66 1 5 +SliderBgFill_Left 197 66 1 5 +SliderBg_Left 198 66 1 5 +SliderBg_Right 199 66 1 5 +blank 167 71 1 1 +Frame_BL 168 71 1 1 +Frame_Bottom 169 71 1 1 +Frame_BR 170 71 1 1 +Frame_Left 171 71 1 1 +Frame_Mid 172 71 1 1 +Frame_Right 173 71 1 1 +Frame_TL 174 71 1 1 +Frame_Top 175 71 1 1 +Frame_TR 176 71 1 1 +HorizontalListDivider 177 71 1 1 +ListDivider 178 71 1 1 +Popup_BL 179 71 1 1 +Popup_Bottom 180 71 1 1 +Popup_BR 181 71 1 1 +Popup_Left 182 71 1 1 +Popup_Mid 194 71 1 1 +Popup_Right 195 71 1 1 +Popup_TL 196 71 1 1 +Popup_Top 197 71 1 1 +Popup_TR 198 71 1 1 +SelectdropDivider 199 71 1 1 +Selectdrop_BL 190 94 1 1 +Selectdrop_Bottom 191 94 1 1 +Selectdrop_BR 192 94 1 1 +Selectdrop_Left 193 94 1 1 +Selectdrop_Mid 194 94 1 1 +Selectdrop_Right 195 94 1 1 +Selectdrop_TL 196 94 1 1 +Selectdrop_Top 197 94 1 1 +Selectdrop_TR 198 94 1 1 +SunkenFrame_BL 199 94 1 1 +SunkenFrame_Bottom 200 94 1 1 +SunkenFrame_BR 201 94 1 1 +SunkenFrame_Left 202 94 1 1 +SunkenFrame_Mid 203 94 1 1 +SunkenFrame_Right 204 94 1 1 +SunkenFrame_TL 205 94 1 1 +SunkenFrame_Top 190 95 1 1 +SunkenFrame_TR 191 95 1 1 diff --git a/Skins/Metro/res/blank.png b/Skins/Metro/res/blank.png new file mode 100644 index 0000000..fc4efe0 Binary files /dev/null and b/Skins/Metro/res/blank.png differ diff --git a/Skins/__init__.py b/Skins/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/TransformGizmo/docs/transform_gizmo_events.md b/TransformGizmo/docs/transform_gizmo_events.md new file mode 100644 index 0000000..befac8e --- /dev/null +++ b/TransformGizmo/docs/transform_gizmo_events.md @@ -0,0 +1,99 @@ +# TransformGizmo 事件钩子使用说明 + +本文档说明如何在 `TransformGizmo` 初始化时注入拖拽事件回调(类似 C# 委托),以及各事件的负载字段。 + +## 事件常量 + +所有事件名集中在 `TransformGizmo.events.GizmoEvent`,避免拼写错误: + +```python +from TransformGizmo.events import GizmoEvent + +GizmoEvent.DRAG_START # "drag_start" +GizmoEvent.DRAG_MOVE # "drag_move" +GizmoEvent.DRAG_END # "drag_end" +GizmoEvent.ALL # ("drag_start", "drag_move", "drag_end") +``` + +## 基础用法示例 + +在构造 `TransformGizmo` 时传入 `event_hooks`,按 handle 类型分组(`"move"`, `"rotate"`, `"scale"` 或对应 `TransformGizmoMode` 值),每组里是事件名到回调列表的映射: + +```python +from TransformGizmo.transform_gizmo import TransformGizmo, TransformGizmoMode +from TransformGizmo.events import GizmoEvent + +def on_move_start(info): + print("[move] start", "axis", info["axis"], "plane", info["plane"]) + +def on_move_drag(info): + print("[move] pos ->", info["new_pos"]) + +def on_rotate_drag(info): + print("[rotate] delta_deg =", info["delta_deg"]) + +def on_scale_end(info): + print("[scale] final_scale =", info["final_scale"]) + +hooks = { + TransformGizmoMode.MOVE: { + GizmoEvent.DRAG_START: [on_move_start], + GizmoEvent.DRAG_MOVE: [on_move_drag], + }, + TransformGizmoMode.ROTATE: { + GizmoEvent.DRAG_MOVE: [on_rotate_drag], + }, + TransformGizmoMode.SCALE: { + GizmoEvent.DRAG_END: [on_scale_end], + }, +} + +# world: 你的 Panda3DWorld 实例 +gizmo = TransformGizmo(world, event_hooks=hooks) +``` + +### 运行时追加 / 移除 + +初始化后也可以直接操作子 gizmo 的钩子列表: + +```python +from TransformGizmo.events import GizmoEvent + +gizmo.move_gizmo._event_hooks[GizmoEvent.DRAG_MOVE].append(on_move_drag) +# 移除同理,用 list.remove(on_move_drag) +``` + +## 回调负载字段 + +各事件都会传入一个 `dict`,常见字段如下(不存在的字段将为 `None` 或缺省): + +### Move +- `axis`:0/1/2(X/Y/Z),平面拖拽时为 `None` +- `plane`:0/1/2(XY/YZ/ZX),轴拖拽时为 `None` +- `mouse`:`Point2`,拖拽开始/过程中鼠标 NDC 坐标 +- `start_pos` / `new_pos` / `final_pos`:世界坐标 `Vec3` +- `target`:当前绑定的 `NodePath` +- `gizmo`:字符串 `"move"` + +### Rotate +- `mode`:`"axis"` 或 `"trackball"` +- `axis`:0/1/2(X/Y/Z),轨迹球时为 `None` +- `delta_deg`:本次 `drag_move` 的角度增量(度) +- `start_quat`:拖拽开始时的世界四元数 +- `final_hpr`:拖拽结束时的世界 HPR(仅 `drag_end`) +- `center`:gizmo 中心点(世界坐标) +- `axis_world`:当前旋转轴的世界方向 +- `mouse`:`Point2` +- `target`,`gizmo` 同上 + +### Scale +- `axis`:0/1/2 对应 X/Y/Z,3 表示中心均匀缩放 +- `scale_factor`:本次 `drag_move` 计算出的缩放倍率 +- `start_scale` / `new_scale` / `final_scale`:`Vec3` +- `mouse`:`Point2` +- `target`,`gizmo` 同上 + +## 小贴士 +- 事件字典的键可以用字符串 `"move"`/`"rotate"`/`"scale"`,也可以用 `TransformGizmoMode` 的对应值,内部都会匹配。 +- 每个事件支持多个回调(列表),内部对单个回调异常做了 try/except,互不影响。 +- 如果只想监听部分事件,留空即可,内部会自动填充为空列表。 diff --git a/TransformGizmo/events.py b/TransformGizmo/events.py new file mode 100644 index 0000000..1e8b49b --- /dev/null +++ b/TransformGizmo/events.py @@ -0,0 +1,21 @@ +class GizmoEvent: + """String constants for gizmo event hook names.""" + + DRAG_START = "drag_start" + DRAG_MOVE = "drag_move" + DRAG_END = "drag_end" + + ALL = (DRAG_START, DRAG_MOVE, DRAG_END) + + +class TransformGizmoMode: + """Simple string constants for gizmo modes.""" + + NONE = "none" + MOVE = "move" + ROTATE = "rotate" + SCALE = "scale" # reserved for future implementation + ALL = "all" # move + rotate together (matches existing UI semantics) + + +__all__ = ["GizmoEvent", "TransformGizmoMode"] diff --git a/TransformGizmo/move_gizmo.py b/TransformGizmo/move_gizmo.py new file mode 100644 index 0000000..08f74a1 --- /dev/null +++ b/TransformGizmo/move_gizmo.py @@ -0,0 +1,1127 @@ +import importlib +import importlib.util +import math +from typing import Optional, Tuple, Callable, Dict, Any, List + +from panda3d.core import ( + NodePath, + Vec3, + Point3, + Point2, + Vec4, + Quat, + CardMaker, + GeomNode, + GeomVertexFormat, + GeomVertexData, + GeomVertexWriter, + GeomLines, + GeomTriangles, + Geom, + CollisionNode, + CollisionRay, + CollisionHandlerQueue, + CollisionTraverser, + CollisionTube, + CollisionSphere, + CollisionPolygon, + BitMask32, + CollisionEntry, + Point3, + Lens, + PerspectiveLens +) +from direct.showbase.DirectObject import DirectObject +from direct.task import Task +from direct.task.TaskManagerGlobal import taskMgr +from panda3d.core import Material,BitMask32,LPoint2f +from direct.showbase.ShowBase import ShowBase + +from .events import GizmoEvent + + +class MoveGizmo(DirectObject): + """ + A Unity-like Move Gizmo for Panda3D. + Features: + - 3 Axes (X=Red, Y=Green, Z=Blue) with Cylinder + Cone. + - Renders on top of other geometry. + - Handles mouse interaction for dragging. + """ + + def __init__( + self, + world:ShowBase, + camera_np: NodePath = None, + on_action_committed: Optional[Callable[[Dict[str, Any]], None]] = None, + event_hooks: Optional[Dict[str, List[Callable[[Dict[str, Any]], None]]]] = None, + use_renderpipeline: bool = False + ): + super().__init__() + self.world = world + self.is_local = True + self.debug = False + self._debug_drag_counter = 0 + self._picker_added = False + self.is_hovering = False + self.use_renderpipeline = use_renderpipeline + # Optional callback to report completed move actions to a higher-level + # manager (e.g. TransformGizmo) so it can build a global undo stack. + self.on_action_committed = on_action_committed + # Event hooks: drag_start / drag_move / drag_end + self._event_hooks = self._normalize_event_hooks(event_hooks) + # If camera is not provided, try to find it in the world or base + self.camera = camera_np if camera_np else getattr(world, 'cam', None) + if not self.camera and hasattr(world, 'base'): + self.camera = world.base.cam + if not self.camera: + self._log("No camera found") + else: + self._log(f"Camera found: {self.camera}") + + self.root = NodePath("MoveGizmo") + self.color_higher = 0.05 + self.color_normal = 0.01 + + self.target_node: Optional[NodePath] = None + self.attached = False + + # 控制柄外观设置 + self.arrow_cylider_length = 0.45 # 圆柱长度 + self.arrow_cylider_radius = 0.005 # 圆柱粗细 + # 碰撞体半径,可独立于可视半径调整 + self.arrow_cylider_col_radius = max(0.02, self.arrow_cylider_radius * 5.0) + self.arrow_cone_height = 0.1 # 圆锥高度 + self.arrow_cone_radius = 0.03 # 圆锥半径 + self.arrow_transparency: float = 0.8 # 箭头透明度 + + self.panel_transparency: float = 0.65 + self.plane_size: float = 0.1 + self.plane_offset: float = self.plane_size * 0.5 + 0.01 + + # Collision setup for picking + self.picker_ray = CollisionRay() + self.picker_node = CollisionNode('gizmo_picker_ray') + self.picker_node.addSolid(self.picker_ray) + self.picker_node.setFromCollideMask(BitMask32.bit(20)) # Specific mask for gizmo + self.picker_node.setIntoCollideMask(BitMask32.allOff()) + self.picker_np = NodePath(self.picker_node) + + self.c_trav = CollisionTraverser() + self.c_queue = CollisionHandlerQueue() + + # Dragging state + self.dragging: bool = False + self.drag_axis: int = None # 0=X, 1=Y, 2=Z + self.start_mouse: Point2 = None # NDC Point2 + self.start_node_pos = None + # param value of closest point on axis at drag start + self._start_param_on_ray: float = 0.0 + # sign so that dragging along axis arrow matches mouse direction + self._axis_param_sign: float = 1.0 + self.last_mouse_pos: Point3 = None + self.drag_axis_dir: Vec3 = Vec3(0, 0, 0) # world-space axis dir + self.drag_axis_screen: Point2 = Point2(1, 0) # axis direction in screen space + self.drag_base_dist: float = 1.0 # camera distance at drag start + + # Visuals + self.axes: list[NodePath] = [] + self.planes: list[NodePath] = [] # plane handles: 0=XY,1=YZ,2=ZX + self.axes_base_colors: list[Tuple[NodePath,Vec4]] = [] + self.planes_base_colors: list[Tuple[NodePath,Vec4]] = [] + # Plane drag state + self.drag_plane_id: Optional[int] = None # 0=XY,1=YZ,2=ZX + self.drag_plane_normal: Vec3 = Vec3(0, 0, 0) + self.drag_plane_origin: Point3 = Point3(0, 0, 0) # point on plane at drag start + # target_pos - hit_point at drag start + self._plane_drag_offset: Vec3 = Vec3(0, 0, 0) + + # --- Undo stack for move operations --------------------------------- + # Each entry: (target_node, old_pos(world), new_pos(world)) + self._move_undo_stack: list[Tuple[NodePath, Vec3, Vec3]] = [] + # Minimal distance to consider as a real move (avoid float noise) + self._undo_pos_epsilon: float = 1e-4 + + self._build_gizmo() + + # Event listeners will be activated on attach + self.root.reparentTo(self.world.render) + if not self.use_renderpipeline: + self.root.setBin('fixed',40) + self.root.setDepthTest(False) + self.root.setDepthWrite(False) + self.root.setLightOff() + self.root.hide() + + # Update gizmo scale every frame so that it + # stays roughly the same size on screen + # taskMgr.add(self._update_task, "MoveGizmoUpdateTask") + + def _log(self, msg: str): + if self.debug: + print(f"[MoveGizmo] {msg}") + + def _normalize_event_hooks(self, hooks): + base = {name: [] for name in GizmoEvent.ALL} + if not hooks: + return base + for name in list(base.keys()): + cbs = hooks.get(name) + if cbs: + base[name] = list(cbs) + return base + + def _emit_event(self, name: str, payload: Dict[str, Any]): + handlers = self._event_hooks.get(name, []) + for cb in handlers: + try: + cb(payload) + except Exception as exc: + self._log(f"event hook '{name}' error: {exc}") + + def _build_gizmo(self): + """Builds the 3 axes geometry and plane handles.""" + # Axis params + + # X Axis (Red) + self.axes.append(self._create_axis(Vec3(1, 0, 0), Vec4( + 1, 0, 0, 1), self.arrow_cylider_length, self.arrow_cylider_radius, self.arrow_cylider_col_radius, self.arrow_cone_height, self.arrow_cone_radius, 0)) + # Y Axis (Green) + self.axes.append(self._create_axis(Vec3(0, 1, 0), Vec4( + 0, 1, 0, 1), self.arrow_cylider_length, self.arrow_cylider_radius, self.arrow_cylider_col_radius, self.arrow_cone_height, self.arrow_cone_radius, 1)) + # Z Axis (Blue) + self.axes.append(self._create_axis(Vec3(0, 0, 1), Vec4( + 0, 0, 1, 1), self.arrow_cylider_length, self.arrow_cylider_radius, self.arrow_cylider_col_radius, self.arrow_cone_height, self.arrow_cone_radius, 2)) + + # Plane handles: small squares between axes, slightly offset from origin. + # 0 = XY, 1 = YZ, 2 = ZX + half = self.plane_size * 0.5 + inner = self.plane_offset + half + # XY plane:贴近 +X/+Y 象限 + self.planes.append( + self._create_plane_handle( + name="plane_xy", + plane_id=0, + axis_a=0, + axis_b=1, + color=Vec4(1, 1, 0, self.panel_transparency), # 黄色 + size=self.plane_size, + # 以平面中心为轴心,让靠近原点的角距离原点 plane_offset + offset_vec=Vec3(inner, inner, 0.0), + hpr=Vec3(0, -90, 0), + ) + ) + # YZ plane (normal +X) + self.planes.append( + self._create_plane_handle( + name="plane_yz", + plane_id=1, + axis_a=1, + axis_b=2, + color=Vec4(0, 1, 1, self.panel_transparency), # 青色 + size=self.plane_size, + offset_vec=Vec3(0.0, inner, inner), + hpr=Vec3(90, 0, 0), # rotate XY card to YZ + ) + ) + # ZX plane (normal +Y) + self.planes.append( + self._create_plane_handle( + name="plane_zx", + plane_id=2, + axis_a=2, + axis_b=0, + color=Vec4(0.5, 0, 0, self.panel_transparency), # 深红 + size=self.plane_size, + offset_vec=Vec3(inner, 0.0, inner), + # Rotate XY card so it lies in the ZX plane (normal ±Y) + hpr=Vec3(0, 0, 0), + ) + ) + + def _create_axis(self, direction: Vec3, color: Vec4, length, radius_visual, radius_collision, cone_height, cone_radius, axis_id): + """Creates a single axis arrow.""" + axis_root:NodePath = self.root.attachNewNode(f"axis_{axis_id}") + + # Align axis (default geometry faces +Z) to the requested direction. + align_quat = self._quat_from_z(direction) + axis_root.setQuat(align_quat) + self._log( + f"axis {axis_id} dir={direction} quat={align_quat} " + f"world_dir={axis_root.getQuat(self.world.render).xform(Vec3(0, 0, 1))}" + ) + + # Visual Geometry + geom = self._create_arrow_geom(length, radius_visual, cone_height, cone_radius, color) + geom_np: NodePath = axis_root.attachNewNode(geom) + geom_np.setTransparency(True) + geom_np.setAlphaScale(self.arrow_transparency) + self._log(f"created geom_np -> {geom_np}") + + # Collision Geometry (Tube) + # Tube is defined by point A and B. + shaft_len = max(length - cone_height, 0.0) + shaft_radius = max(1e-6, radius_collision) + c_node = CollisionNode(f"axis_col_{axis_id}") + # Shaft collider + if shaft_len > 0.0: + c_node.addSolid(CollisionTube( + Point3(0, 0, 0), + Point3(0, 0, shaft_len), + shaft_radius)) + # Cone collider: a slightly wider tube plus a small sphere at the tip + if cone_height > 0.0: + cone_start = Point3(0, 0, shaft_len) + cone_tip = Point3(0, 0, length) + cone_radius_pad = max(cone_radius, shaft_radius) + c_node.addSolid(CollisionTube(cone_start, cone_tip, cone_radius_pad)) + c_node.addSolid(CollisionSphere(cone_tip, cone_radius_pad)) + c_node.setIntoCollideMask(BitMask32.bit(20)) + c_node.setFromCollideMask(BitMask32.allOff()) + c_node.setTag('gizmo_axis', str(axis_id)) + + col_np = axis_root.attachNewNode(c_node) + # col_np.show() # Debug collision + self._log(f"created col_np -> {col_np}") + + if self.use_renderpipeline: + geom_np.copy_to(geom_np.get_parent()) + mat = Material('default') + mat.set_emission((1,0,1,1)) + mat.base_color = color * self.color_normal + geom_np.set_material(mat) + geom_np.set_bin('fixed',40) + geom_np.set_depth_test(False) + geom_np.set_depth_write(False) + self.axes_base_colors.append((geom_np,color)) + + return axis_root + + def _create_plane_handle( + self, + name: str, + plane_id: int, + axis_a: int, + axis_b: int, + color: Vec4, + size: float, + offset_vec: Vec3, + hpr: Vec3 = Vec3(0, 0, 0), + ) -> NodePath: + """ + Create a small square plane handle between two axes. + plane_id: 0=XY, 1=YZ, 2=ZX + axis_a / axis_b: not currently used for math, kept for clarity. + """ + cm = CardMaker(name) + # Square centered at origin in local X/Z (pivot at center) + half = size * 0.5 + cm.setFrame(-half, half, -half, half) + card_np: NodePath = self.root.attachNewNode(cm.generate()) + card_np.setPos(offset_vec) + card_np.setHpr(hpr) + card_np.setColor(color) + card_np.setTransparency(True) + # Double-sided rendering so the plane looks like Unity handles + card_np.setTwoSided(True) + + if self.use_renderpipeline: + card_copy = card_np.copy_to(card_np) + card_copy.set_pos(0,0,0) + card_copy.set_hpr(0,0,0) + mat = Material("default") + mat.setTwoside(True) + mat.base_color = color * self.color_normal + mat.set_emission((1,0,1,1)) + card_copy.set_material(mat) + card_copy.set_bin('fixed',40) + card_copy.set_depth_test(False) + card_copy.set_depth_write(False) + self.planes_base_colors.append((card_copy,color)) + + # Collision polygon matching the card in local space + # Define square in the same local coordinates as the CardMaker frame. + p0 = Point3(-half, 0.0, -half) + p1 = Point3(half, 0.0, -half) + p2 = Point3(half, 0.0, half) + p3 = Point3(-half, 0.0, half) + # Create two polygons with opposite winding so the plane is hit + # from both sides by the picking ray. + poly_front = CollisionPolygon(p0, p1, p2, p3) + poly_back = CollisionPolygon(p3, p2, p1, p0) + + c_node = CollisionNode(f"plane_col_{plane_id}") + c_node.addSolid(poly_front) + c_node.addSolid(poly_back) + c_node.setIntoCollideMask(BitMask32.bit(20)) + c_node.setFromCollideMask(BitMask32.allOff()) + c_node.setTag("gizmo_plane", str(plane_id)) + + col_np = card_np.attachNewNode(c_node) + # col_np.show() + self._log(f"created plane {name} col_np -> {col_np}") + + return card_np + + def _create_arrow_geom(self, length, radius, cone_height, cone_radius, color): + """Creates the mesh for cylinder + cone.""" + # Using simple line or loading model is easier, but let's try procedural for "no external assets" requirement + # Actually, Panda has `loader.loadModel("models/misc/cylinder")` but let's make a simple one or use LineSegs for shaft? + # User requested "Cylinder + Cone". + + # Let's use a helper function to generate a cylinder and cone using GeomVertexWriter + # For simplicity in this script, I will use a very thin box or simple geometry. + # Or better, load a basic shape if available, but procedural is safer to avoid missing assets. + + # Simplified: Use Line for shaft (thick) and Triangle fan for cone? + # No, user wants "Cylinder". + + # Let's use CardMaker for a cross-section look or just build a simple mesh. + # To save code space, I'll implement a basic procedural cylinder/cone generator. + + vdata = GeomVertexData( + 'name', GeomVertexFormat.getV3c4(), Geom.UHStatic) + vertex = GeomVertexWriter(vdata, 'vertex') + vcolor = GeomVertexWriter(vdata, 'color') + + # Shaft (Cylinder) - Simplified as a prism with 8 sides + segments = 12 + shaft_len = length - cone_height + + def add_circle_verts(z, r): + start_idx = vertex.getWriteRow() + for i in range(segments): + angle = 2 * math.pi * i / segments + x = r * math.cos(angle) + y = r * math.sin(angle) + vertex.addData3(x, y, z) + vcolor.addData4(color) + return start_idx + + # Bottom circle + base_idx = add_circle_verts(0, radius) + # Top of shaft + top_shaft_idx = add_circle_verts(shaft_len, radius) + + prim = GeomTriangles(Geom.UHStatic) + for i in range(segments): + next_i = (i + 1) % segments + # Side quads (2 tris) + prim.addVertices(base_idx + i, base_idx + + next_i, top_shaft_idx + next_i) + prim.addVertices(base_idx + i, top_shaft_idx + + next_i, top_shaft_idx + i) + + # Cone base + cone_base_idx = add_circle_verts(shaft_len, cone_radius) + # Cone tip + vertex.addData3(0, 0, length) + vcolor.addData4(color) + tip_idx = vertex.getWriteRow() - 1 + + # Cone sides + for i in range(segments): + next_i = (i + 1) % segments + prim.addVertices(cone_base_idx + i, + cone_base_idx + next_i, tip_idx) + # Cone bottom cap (optional, usually hidden by shaft) + prim.addVertices(cone_base_idx + next_i, + cone_base_idx + i, top_shaft_idx + i) # Stitching? + + geom = Geom(vdata) + geom.addPrimitive(prim) + node = GeomNode('axis_geom') + node.addGeom(geom) + return node + + def _quat_from_z(self, direction: Vec3) -> Quat: + """Return a quaternion rotating +Z to the given (normalized) direction.""" + dir_norm = Vec3(direction) + if dir_norm.length_squared() == 0: + return Quat.identQuat() + dir_norm.normalize() + z_axis = Vec3(0, 0, 1) + dot = z_axis.dot(dir_norm) + if abs(dot - 1.0) < 1e-6: + return Quat.identQuat() # Already aligned + if abs(dot + 1.0) < 1e-6: + # Opposite; rotate 180° around any axis perpendicular to Z + ortho = Vec3(1, 0, 0) if abs(z_axis.dot( + Vec3(1, 0, 0))) < 0.9 else Vec3(0, 1, 0) + axis = z_axis.cross(ortho) + axis.normalize() + q = Quat() + q.setFromAxisAngle(180.0, axis) + return q + axis = z_axis.cross(dir_norm) + axis_len = axis.length() + if axis_len == 0: + return Quat.identQuat() + axis.normalize() + angle_rad = math.atan2(axis_len, dot) + q = Quat() + q.setFromAxisAngle(math.degrees(angle_rad), axis) + return q + + def attach(self, node_path: NodePath): + """Attach gizmo to a node.""" + if not node_path: + return + self.target_node = node_path + self.attached = True + self._update_root_transform() + self.root.show() + self._log( + f"attached to {node_path.getName()} world_pos={self.root.getPos(self.world.render)} " + f"target_hpr={node_path.getHpr(self.world.render)}" + ) + self._register_events() + self._reset_planels() + + def detach(self): + """Detach gizmo.""" + self.target_node = None + self.root.hide() + self.attached = False + self.drag_plane_id = None + self._log("detached") + self._ignore_events() + + # --- Undo support ------------------------------------------------- + def _record_move_action(self, node: NodePath, old_pos: Vec3, new_pos: Vec3): + """ + Push a move operation to the undo stack if the position changed + by more than a small epsilon. + """ + if node is None or node.isEmpty(): + return + if old_pos is None or new_pos is None: + return + delta = new_pos - old_pos + if delta.length() < self._undo_pos_epsilon: + # Ignore tiny moves caused by float noise + return + # Store copies so later modifications don't affect history + old_copy = Vec3(old_pos) + new_copy = Vec3(new_pos) + self._move_undo_stack.append((node, old_copy, new_copy)) + self._log( + f"record move action: node={node.getName()} " + f"old_pos={old_copy} new_pos={new_copy} stack_size={len(self._move_undo_stack)}" + ) + # Report to external listener (e.g. TransformGizmo) to build a + # unified, cross-gizmo undo history. + if self.on_action_committed is not None: + try: + self.on_action_committed( + { + "kind": "move", + "node": node, + "old_pos": Vec3(old_copy), + "new_pos": Vec3(new_copy), + } + ) + except Exception as exc: + # Avoid breaking interaction if user callback fails. + self._log(f"on_action_committed(move) error: {exc}") + + def undo_last_move(self): + """ + Undo the last committed move. + Default hotkey (from Qt -> Panda3D translation): Ctrl+Z => 'control-z'. + """ + if not self._move_undo_stack: + self._log("undo_last_move: stack empty") + return + node, old_pos, new_pos = self._move_undo_stack.pop() + if node is None or node.isEmpty(): + self._log("undo_last_move: target node invalid") + return + node.setPos(self.world.render, old_pos) + self._log( + f"undo_last_move: node={node.getName()} " + f"old_pos={old_pos} new_pos={new_pos} remaining={len(self._move_undo_stack)}" + ) + + def _register_events(self): + self.accept("mouse1", self._on_mouse_down) + self.accept("mouse1-up", self._on_mouse_up) + self.accept("mouse2-up", self._on_mouse_up) + self.accept("mouse3-up", self._on_mouse_up) + self.accept("mouse-move", self._on_mouse_move) + self._log("event listeners registered (mouse)") + + def _ignore_events(self): + self.ignore("mouse1") + self.ignore("mouse1-up") + self.ignore("mouse2-up") + self.ignore("mouse3-up") + self.ignore("mouse-move") + self._log("event listeners removed") + + # --- Mouse helpers ------------------------------------------------- + def _get_normalized_mouse(self, extra) -> Optional[Point3]: + """ + Convert Qt pixel coordinates (from QPanda3DWidget) to Panda's + normalized device coordinates (-1..1), or fall back to + mouseWatcherNode when available. + """ + if self.world.mouseWatcherNode.hasMouse(): + mouse = self.world.mouseWatcherNode.getMouse() + return Point3(mouse.x, mouse.y, 0) + + # 1) Extra payload from QPanda3DWidget (pixels) + if isinstance(extra, dict) and "x" in extra and "y" in extra: + parent = getattr(self.world, "parent", None) + if parent is not None: + w = max(parent.width(), 1) + h = max(parent.height(), 1) + nx = (extra["x"] / w) * 2.0 - 1.0 + # Qt origin is top‑left, Panda origin is center with +Y up + ny = 1.0 - (extra["y"] / h) * 2.0 + return Point3(nx, ny, 0) + + return None + + def _on_mouse_down(self, extra=None): + if not self.attached or not self.camera: + return + + # Check for picking + mpos = self._get_normalized_mouse(extra) + + if mpos is None: + self._log("mouse_down ignored: no mouse pos") + return + + # Setup ray + self.picker_np.reparentTo(self.camera) + if not self._picker_added: + self.c_trav.addCollider(self.picker_np, self.c_queue) + self._picker_added = True + self.picker_ray.setFromLens(self.camera.node(), mpos.x, mpos.y) + + self.c_queue.clearEntries() + self.c_trav.traverse(self.root) + + self._log( + f"mouse_down mpos={mpos} cam_pos={self.camera.getPos(self.world.render)} " + f"cam_hpr={self.camera.getHpr(self.world.render)} entries={self.c_queue.getNumEntries()}" + ) + + num_entries = self.c_queue.getNumEntries() + if num_entries > 0: + self.c_queue.sortEntries() + + # Unity 风格:优先选择平面,其次才是轴。 + plane_entry: Optional[CollisionEntry] = None + axis_entry: Optional[CollisionEntry] = None + for i in range(num_entries): + e: CollisionEntry = self.c_queue.getEntry(i) + if not plane_entry and e.getIntoNode().getTag("gizmo_plane"): + plane_entry = e + if not axis_entry and e.getIntoNode().getTag("gizmo_axis"): + axis_entry = e + if plane_entry and axis_entry: + break + + # Prefer plane hit when available + if plane_entry is not None: + entry = plane_entry + plane_tag: str = entry.getIntoNode().getTag("gizmo_plane") + # --- Begin plane dragging --- + # --- Begin plane dragging --- + self.dragging = True + self.drag_plane_id = int(plane_tag) # 0=XY,1=YZ,2=ZX + # print(f"[Gizmo] drag_plane_id={self.drag_plane_id}") + self.drag_axis = None + + cam_pos = self.camera.getPos(self.world.render) + node_pos_w = self.target_node.getPos(self.world.render) + lens: PerspectiveLens = self.camera.node().getLens() + + # Determine plane normal in world space from the actual plane node, + # so that dragging follows the visual orientation even when the + # target node is rotated (local mode). + plane_np = self.planes[self.drag_plane_id] + plane_normal: Vec3 = Quat(plane_np.getQuat(self.world.render)).xform( + Vec3(0, 1, 0) + ) + plane_normal.normalize() + self.drag_plane_normal = plane_normal + self.drag_plane_origin = node_pos_w + self.start_node_pos = node_pos_w + self.start_mouse = Point2(mpos.x, mpos.y) + + # Build initial mouse ray and compute intersection with plane + p_from = Point3() + p_to = Point3() + hit_point = None + if lens.extrude(Point2(mpos.x, mpos.y), p_from, p_to): + ray_origin = self.world.render.getRelativePoint( + self.camera, p_from + ) + ray_to = self.world.render.getRelativePoint( + self.camera, p_to + ) + ray_dir = ray_to - ray_origin + if ray_dir.length_squared() != 0: + ray_dir.normalize() + denom = ray_dir.dot(plane_normal) + if abs(denom) > 1e-6: + t = (self.drag_plane_origin - + ray_origin).dot(plane_normal) / denom + hit_point = ray_origin + ray_dir * t + + if hit_point is None: + # Fallback: use current node position as hit point + hit_point = node_pos_w + + self._plane_drag_offset = node_pos_w - hit_point + self._debug_drag_counter = 0 + self._highlight_plane(self.drag_plane_id) + self._log( + f"pick plane={self.drag_plane_id} target={self.target_node.getName()} " + f"plane_origin={self.drag_plane_origin} plane_normal={self.drag_plane_normal} " + f"hit_point={hit_point}" + ) + self._emit_event( + GizmoEvent.DRAG_START, + { + "gizmo": "move", + "target": self.target_node, + "axis": None, + "plane": self.drag_plane_id, + "mouse": Point2(mpos.x, mpos.y), + "start_pos": self.start_node_pos, + }, + ) + + elif axis_entry is not None: + entry = axis_entry + axis_tag: str = entry.getIntoNode().getTag("gizmo_axis") + # --- Begin axis dragging (existing behavior) --- + self.dragging = True + self.drag_axis = int(axis_tag) + self.drag_plane_id = None + + # --- Freeze axis direction & screen-space mapping at drag start --- + axis_index = int(axis_tag) + axis_np: NodePath = self.axes[axis_index] + axis_dir: Vec3 = axis_np.getQuat( + self.world.render + ).xform(Vec3(0, 0, 1)) + if axis_dir.length_squared() == 0: + axis_dir = Vec3(0, 0, 1) + axis_dir.normalize() + cam_pos = self.camera.getPos(self.world.render) + node_pos_w = self.target_node.getPos(self.world.render) + view_dir = node_pos_w - cam_pos + if view_dir.length_squared() != 0: + view_dir.normalize() + + self.drag_axis_dir = axis_dir + + lens: PerspectiveLens = self.camera.node().getLens() + self.drag_base_dist = (cam_pos - node_pos_w).length() + sample_len = max(self.drag_base_dist * 0.25, 0.25) + + p0_cam = self.camera.getRelativePoint( + self.world.render, node_pos_w + ) + p1_cam = self.camera.getRelativePoint( + self.world.render, node_pos_w + axis_dir * sample_len + ) + p0_2d = Point2() + p1_2d = Point2() + if lens.project(p0_cam, p0_2d) and lens.project(p1_cam, p1_2d): + axis_screen: Point2 = p1_2d - p0_2d + if axis_screen.length_squared() > 0: + axis_screen.normalize() + else: + axis_screen = Point2(1, 0) + else: + axis_screen = Point2(1, 0) + self.drag_axis_screen = axis_screen + + self.drag_base_dist = max(self.drag_base_dist, 0.5) + self.start_mouse = Point2(mpos.x, mpos.y) + self.start_node_pos = node_pos_w + self.last_mouse_pos = Point3(mpos.x, mpos.y, 0) + + p_from = Point3() + p_to = Point3() + if lens.extrude(Point2(mpos.x, mpos.y), p_from, p_to): + ray_origin: Point3 = self.world.render.getRelativePoint( + self.camera, p_from + ) + ray_to: Point3 = self.world.render.getRelativePoint( + self.camera, p_to + ) + ray_dir: Vec3 = ray_to - ray_origin + if ray_dir.length_squared() != 0: + ray_dir.normalize() + axis_origin = self.start_node_pos + a = self.drag_axis_dir + d = ray_dir + w0 = ray_origin - axis_origin + a_dot_a = a.dot(a) + d_dot_d = d.dot(d) + a_dot_d = a.dot(d) + a_dot_w0 = a.dot(w0) + d_dot_w0 = d.dot(w0) + denom = a_dot_a * d_dot_d - a_dot_d * a_dot_d + if abs(denom) >= 1e-6: + s0 = (a_dot_d * d_dot_w0 - + d_dot_d * a_dot_w0) / denom + self._start_param_on_ray = s0 + else: + self._start_param_on_ray = 0.0 + else: + self._start_param_on_ray = 0.0 + else: + self._start_param_on_ray = 0.0 + + self._debug_drag_counter = 0 + self._highlight_axis(self.drag_axis) + self._log( + f"pick axis={self.drag_axis} target={self.target_node.getName()} " + f"start_pos={self.start_node_pos} world_root={self.root.getPos(self.world.render)} " + f"axis_dir={axis_dir} axis_screen={self.drag_axis_screen}" + ) + self._emit_event( + GizmoEvent.DRAG_START, + { + "gizmo": "move", + "target": self.target_node, + "axis": self.drag_axis, + "plane": None, + "mouse": Point2(mpos.x, mpos.y), + "start_pos": self.start_node_pos, + }, + ) + else: + self._log( + "pick hit but no gizmo_axis or gizmo_plane tag on node") + else: + self._log("mouse_down: no collision entries on gizmo") + + def _on_mouse_up(self, extra=None): + if self.dragging and self.target_node is not None: + # Commit a move action to the undo stack if position changed + try: + final_pos = self.target_node.getPos(self.world.render) + except Exception: + final_pos = None + old_pos = self.start_node_pos + if old_pos is not None and final_pos is not None: + self._record_move_action(self.target_node, old_pos, final_pos) + + axis_id = self.drag_axis + plane_id = self.drag_plane_id + self._emit_event( + GizmoEvent.DRAG_END, + { + "gizmo": "move", + "target": self.target_node, + "axis": axis_id, + "plane": plane_id, + "final_pos": final_pos, + "start_pos": old_pos, + }, + ) + self.dragging = False + self.drag_axis = None + self.drag_plane_id = None + if not self.is_local: + self.root.setHpr(self.world.render, 0, 0, 0) + self._reset_highlights() + self._log("mouse_up -> stop dragging") + + self._reset_planels() + + def _reset_planels(self): + if not self.camera: + return + + # 摄像机在 gizmo 局部坐标系中的位置(会跟随 root 旋转) + local_cam_pos: Vec3 = self.camera.getPos(self.root) + + # 三个轴向的符号:摄像机在 gizmo 局部坐标系里的哪一侧 + sx = 1.0 if local_cam_pos.x >= 0.0 else -1.0 + sy = 1.0 if local_cam_pos.y >= 0.0 else -1.0 + sz = 1.0 if local_cam_pos.z >= 0.0 else -1.0 + + o = self.plane_offset + + # XY 平面:在 X/Y 方向选离摄像机最近的那一角,Z 固定 0 + self.planes[0].setPos(sx * o, sy * o, 0.0) + + # YZ 平面:在 Y/Z 方向选离摄像机最近的那一角,X 固定 0 + self.planes[1].setPos(0.0, sy * o, sz * o) + + # ZX 平面:在 Z/X 方向选离摄像机最近的那一角,Y 固定 0 + self.planes[2].setPos(sx * o, 0.0, sz * o) + + def _on_mouse_move(self, extra=None): + if not self.attached or not self.camera: + return + + mpos = self._get_normalized_mouse(extra) + if mpos is None: + if self.dragging: + self._log("mouse_move ignored: no mouse pos while dragging") + return + + # Hover highlight when not dragging. + if not self.dragging: + self._update_hover_highlight(mpos) + return + + if not self.target_node: + return + + # Build world-space mouse ray from current mouse position + lens:Lens = self.camera.node().getLens() + p_from = Point3() + p_to = Point3() + if not lens.extrude(Point2(mpos.x, mpos.y), p_from, p_to): + self._log("mouse_move: lens.extrude failed") + return + + ray_origin = self.world.render.getRelativePoint(self.camera, p_from) + ray_to = self.world.render.getRelativePoint(self.camera, p_to) + ray_dir = ray_to - ray_origin + if ray_dir.length_squared() == 0: + return + ray_dir.normalize() + + # Plane dragging: move freely within the plane defined at drag start. + if self.drag_plane_id is not None: + n = self.drag_plane_normal + if n.length_squared() == 0: + return + denom = ray_dir.dot(n) + if abs(denom) < 1e-6: + # Ray nearly parallel to plane; skip this move to avoid jumps. + return + t = (self.drag_plane_origin - ray_origin).dot(n) / denom + hit_point = ray_origin + ray_dir * t + new_pos = hit_point + self._plane_drag_offset + self.target_node.setPos(self.world.render, new_pos) + + if self._debug_drag_counter % 4 == 0: + self._log( + f"drag plane={self.drag_plane_id} mpos={mpos} " + f"ray_origin={ray_origin} ray_dir={ray_dir} " + f"plane_origin={self.drag_plane_origin} plane_normal={n} " + f"hit_point={hit_point} new_pos={new_pos}" + ) + self._debug_drag_counter += 1 + self._emit_event( + GizmoEvent.DRAG_MOVE, + { + "gizmo": "move", + "target": self.target_node, + "axis": None, + "plane": self.drag_plane_id, + "mouse": Point2(mpos.x, mpos.y), + "new_pos": new_pos, + }, + ) + return + + # --- 3D-based drag along axis: use closest point between mouse ray and axis line --- + axis_dir = self.drag_axis_dir + if axis_dir.length_squared() == 0: + return + + axis_origin = self.start_node_pos + a = axis_dir + d = ray_dir + w0 = ray_origin - axis_origin + + a_dot_a = a.dot(a) + d_dot_d = d.dot(d) + a_dot_d = a.dot(d) + a_dot_w0 = a.dot(w0) + d_dot_w0 = d.dot(w0) + + denom = a_dot_a * d_dot_d - a_dot_d * a_dot_d + if abs(denom) < 1e-6: + mouse_ndc = Point2(mpos.x, mpos.y) + delta = mouse_ndc - self.start_mouse + s_scalar = delta.dot(self.drag_axis_screen) + move_amount = s_scalar * self.drag_base_dist * 0.5 + new_pos = axis_origin + a * move_amount + self._log( + f"drag fallback (parallel): s={s_scalar:.4f} move={move_amount:.4f}" + ) + else: + s = (a_dot_d * d_dot_w0 - d_dot_d * a_dot_w0) / denom + delta_s = self._start_param_on_ray - s + new_pos = axis_origin + a * delta_s + + self.target_node.setPos(self.world.render, new_pos) + + if self._debug_drag_counter % 4 == 0: + self._log( + f"drag axis={self.drag_axis} mpos={mpos} " + f"ray_origin={ray_origin} ray_dir={ray_dir} " + f"axis_origin={axis_origin} axis_dir={axis_dir} new_pos={new_pos}" + ) + self._debug_drag_counter += 1 + self._emit_event( + GizmoEvent.DRAG_MOVE, + { + "gizmo": "move", + "target": self.target_node, + "axis": self.drag_axis, + "plane": None, + "mouse": Point2(mpos.x, mpos.y), + "new_pos": new_pos, + }, + ) + + def _update_hover_highlight(self, mpos: Point3): + """Highlight the handle under cursor during hover (no drag).""" + self.picker_np.reparentTo(self.camera) + if not self._picker_added: + self.c_trav.addCollider(self.picker_np, self.c_queue) + self._picker_added = True + self.picker_ray.setFromLens(self.camera.node(), mpos.x, mpos.y) + + self.c_queue.clearEntries() + self.c_trav.traverse(self.root) + + num_entries = self.c_queue.getNumEntries() + if num_entries <= 0: + self._reset_highlights() + self.is_hovering = False + return + + self.c_queue.sortEntries() + + plane_entry: Optional[CollisionEntry] = None + axis_entry: Optional[CollisionEntry] = None + for i in range(num_entries): + e = self.c_queue.getEntry(i) + if plane_entry is None and e.getIntoNode().getTag("gizmo_plane"): + plane_entry = e + if axis_entry is None and e.getIntoNode().getTag("gizmo_axis"): + axis_entry = e + if plane_entry and axis_entry: + break + + if plane_entry is not None: + plane_tag = plane_entry.getIntoNode().getTag("gizmo_plane") + self._highlight_plane(int(plane_tag)) + self.is_hovering = True + elif axis_entry is not None: + axis_tag = axis_entry.getIntoNode().getTag("gizmo_axis") + self._highlight_axis(int(axis_tag)) + self.is_hovering = True + else: + self._reset_highlights() + self.is_hovering = False + + def _highlight_axis(self, axis_id): + """高亮被选中的轴,其他轴和平面变暗。""" + if self.use_renderpipeline: + for i, ax in enumerate(self.axes): + ax,color = self.axes_base_colors[i] + if i == axis_id: + ax.get_material().base_color = color * self.color_higher + else: + ax.get_material().base_color = color * self.color_normal + # 所有平面也变暗 + for i,plane in enumerate(self.planes): + plane,color = self.planes_base_colors[i] + plane.get_material().base_color = color * self.color_normal + else: + for i, ax in enumerate(self.axes): + if i == axis_id: + ax.setColor(1, 1, 0, 1) + ax.clearColorScale() + else: + ax.clearColor() + ax.setAlphaScale(0.3) + # 所有平面也变暗 + for plane in self.planes: + plane.setAlphaScale(0.3) + + def _reset_highlights(self): + """重置所有高亮效果。""" + if self.use_renderpipeline: + for i,ax in enumerate(self.axes): + ax,color = self.axes_base_colors[i] + ax.get_material().base_color = color * self.color_normal + for i,plane in enumerate(self.planes): + plane,color = self.planes_base_colors[i] + plane.get_material().base_color = color * self.color_normal + else: + for ax in self.axes: + ax.clearColor() + ax.clearColorScale() + ax.setAlphaScale(self.arrow_transparency) + for plane in self.planes: + plane.clearColorScale() + plane.setAlphaScale(self.panel_transparency) + + def _highlight_plane(self, plane_id: int): + """高亮被选中的平面,其他平面和轴变暗。""" + if self.use_renderpipeline: + for i, plane in enumerate(self.planes): + plane,color = self.planes_base_colors[i] + if i == plane_id: + plane.get_material().base_color = color * self.color_higher + else: + plane.get_material().base_color = color * self.color_normal + # 所有轴也变暗 + for i,ax in enumerate(self.axes): + ax,color = self.axes_base_colors[i] + ax.get_material().base_color = color * self.color_normal + else: + for i, plane in enumerate(self.planes): + if i == plane_id: + plane.setColorScale(1.6, 1.6, 1.6, 2.0) + else: + plane.setAlphaScale(0.3) + # 所有轴也变暗 + for ax in self.axes: + ax.clearColor() + ax.setAlphaScale(0.3) + + def update(self): + """Update gizmo scale based on camera distance.""" + if self.world.mouseWatcherNode.has_mouse(): + current_mouse = LPoint2f(self.world.mouseWatcherNode.get_mouse()) + if current_mouse != self.last_mouse_pos: + self._on_mouse_move() + self.last_mouse_pos = current_mouse + if self.attached and self.camera: + self._update_root_transform() + dist = (self.camera.getPos(self.world.render) - + self.root.getPos(self.world.render)).length() + scale = dist * 0.15 # Constant screen size factor + self.root.setScale(self.world.render, scale) + + def _update_task(self, task: Task): + """Panda3D task that keeps the gizmo updated every frame.""" + self.update() + return Task.cont + + # ------------------------------------------------------------------ # + # Internal transform sync + # ------------------------------------------------------------------ # + def _update_root_transform(self): + """Keep gizmo root aligned to target without inheriting its render state.""" + if not self.attached or not self.target_node: + return + render = self.world.render + tgt = self.target_node + self.root.setPos(render, tgt.getPos(render)) + if self.is_local: + self.root.setQuat(render, tgt.getQuat(render)) + else: + self.root.setQuat(render, Quat.identQuat()) diff --git a/TransformGizmo/rotate_gizmo.py b/TransformGizmo/rotate_gizmo.py new file mode 100644 index 0000000..1e254e2 --- /dev/null +++ b/TransformGizmo/rotate_gizmo.py @@ -0,0 +1,1685 @@ +import math +from typing import Optional, Tuple, Callable, Dict, Any, List + +from panda3d.core import ( + NodePath, + Vec3, + Point3, + Point2, + Vec4, + Quat, + GeomNode, + GeomVertexFormat, + GeomVertexData, + GeomVertexWriter, + GeomLines, + GeomTriangles, + Geom, + CollisionNode, + CollisionRay, + CollisionHandlerQueue, + CollisionTraverser, + CollisionTube, + CollisionSphere, + CollisionEntry, + BitMask32, + PerspectiveLens, + TransparencyAttrib, + Material, + LPoint2f +) +from direct.showbase.DirectObject import DirectObject +from direct.task import Task +from direct.task.TaskManagerGlobal import taskMgr +from direct.showbase.ShowBase import ShowBase + +from .events import GizmoEvent + + +""" +旋转控制柄(Rotate Gizmo) +========================= + +功能概述: + - 模仿 Unity 的旋转控制柄,使用 3 个彩色圆环表示绕 X/Y/Z 轴旋转 + - X 轴:红色圆环(绕局部 X 轴旋转) + - Y 轴:绿色圆环(绕局部 Y 轴旋转) + - Z 轴:蓝色圆环(绕局部 Z 轴旋转) + - 额外提供屏幕对齐的外圈(view handle)与轨迹球(trackball)方便视图方向与自由旋转 + - 拖拽时展示半透明角度扇形与箭头,辅助观察旋转量 + - 中心轴线辅助观察当前坐标系朝向 + - 使用 Panda3D 的碰撞系统进行鼠标拾取与拖拽 + - 控件跟随目标节点的局部坐标系(即“局部模式”), + 当目标有旋转时,三个圆环会随之旋转 + - 控件会根据摄像机距离自动缩放,屏幕大小保持近似不变 + +集成方式(示例): + from QPanda3D.Panda3DWorld import Panda3DWorld + from QPanda3DExamples.rotate_gizmo import RotateGizmo + + world = Panda3DWorld() + model_np = world.render.attachNewNode("Box") + # ... 在 model_np 下加载模型 + + gizmo = RotateGizmo(world) # 创建旋转 Gizmo + gizmo.attach(model_np) # 绑定到某个模型 + + # 当需要切换目标时: + gizmo.attach(another_np) + + # 当不需要时,可隐藏: + gizmo.detach() + +鼠标事件要求: + - 本类默认监听 Panda3D 的 "mouse1" / "mouse1-up" / "mouse-move" 事件 + - 如果从 Qt / 自定义 UI 传递鼠标像素坐标,可以在发送事件时传入 extra 字典: + messenger.send("mouse1", [{"x": mouse_x, "y": mouse_y}]) + 本类会自动将像素坐标转换到 [-1, 1] 的标准化设备坐标 +""" + + +class RotateGizmo(DirectObject): + """ + Unity 风格的旋转控制柄: + - 3 个圆环分别代表绕局部 X/Y/Z 轴旋转 + - 额外的视图对齐圆环与屏幕轨迹球,便于自由旋转 + - 左键点击圆环并拖拽,可以绕对应轴旋转绑定的 NodePath + """ + + def __init__( + self, + world, + camera_np: NodePath | None = None, + on_action_committed: Optional[Callable[[Dict[str, Any]], None]] = None, + event_hooks: Optional[Dict[str, List[Callable[[Dict[str, Any]], None]]]] = None, + use_renderpipeline: bool = False + ): + super().__init__() + + self.world:ShowBase = world + self.is_local: bool = True + self.debug: bool = False + self.is_hovering = False + self._picker_added: bool = False + self.use_renderpipeline = use_renderpipeline + # Optional callback to report completed rotate actions to a higher-level + # manager (e.g. TransformGizmo) so it can build a global undo stack. + self.on_action_committed = on_action_committed + # Event hooks: drag_start / drag_move / drag_end + self._event_hooks = self._normalize_event_hooks(event_hooks) + + # 摄像机节点,如果未手动传入,则尝试从 world/base 中自动获取 + self.camera: Optional[NodePath] = camera_np or getattr(world, "cam", None) + if not self.camera and hasattr(world, "base"): + self.camera = world.base.cam + if not self.camera: + self._log("No camera found for RotateGizmo") + else: + self._log(f"Camera found for RotateGizmo: {self.camera}") + + # 控制柄根节点 + self.root: NodePath = NodePath("RotateGizmo") + self.color_higher = 0.05 + self.color_normal = 0.01 + + # 当前绑定的目标节点 + self.target_node: Optional[NodePath] = None + self.attached: bool = False + + self.last_mouse_pos = None + + # 控制柄视觉参数 + self.ring_radius: float = 0.45 # 圆环半径(局部空间) + self.ring_thickness: float = 0.04 # 圆环粗细(碰撞体半径) + self.ring_alpha: float = 0.9 # 圆环透明度 + self.trackball_radius: float = self.ring_radius * 1.0 # 轨迹球半径(略小,避免遮挡轴拾取) + self.trackball_color: Vec4 = Vec4(0.25, 0.25, 0.25, 0.45) + self.trackball_edge_color: Vec4 = Vec4(1, 1, 1, 0.75) + self.highlight_color: Vec4 = Vec4(1.0, 1.0, 1.0, 1.0) + self.arrow_length_factor: float = 0.35 # 箭头长度相对圆环半径的倍数 + self.arrow_head_width_factor: float = 0.25 # 箭头头部宽度相对箭长的倍数 + + # 拾取射线与碰撞系统 + self.picker_ray = CollisionRay() + self.picker_node = CollisionNode("rotate_gizmo_picker_ray") + self.picker_node.addSolid(self.picker_ray) + self.picker_node.setFromCollideMask(BitMask32.bit(20)) + self.picker_node.setIntoCollideMask(BitMask32.allOff()) + self.picker_np: NodePath = NodePath(self.picker_node) + + self.c_trav = CollisionTraverser() + self.c_queue = CollisionHandlerQueue() + + # 拖拽状态 + self.dragging: bool = False + self.drag_axis: Optional[int] = None # 0 = X, 1 = Y, 2 = Z + self.drag_mode: Optional[str] = None # "axis" / "view" / "trackball" + self.drag_local_axis: Optional[Vec3] = None + self.start_mouse: Optional[Point2] = None + self._axis_screen_dir: Point2 | None = None + # 起始姿态:世界与父坐标系两份,方便选用一致的参考系进行旋转 + self.start_quat: Optional[Quat] = None # 世界四元数 + self.start_quat_local: Optional[Quat] = None # 父坐标系四元数 + self.start_root_axis_dir: Optional[Vec3] = None + self.rotate_axis_world: Vec3 = Vec3(0, 0, 0) # 当前轴的世界方向 + self.start_vec_on_plane: Vec3 = Vec3(0, 0, 0) # 旋转平面上的起始向量 + self.center_world: Point3 = Point3(0, 0, 0) # Gizmo 中心(世界坐标) + self._trackball_start_vec: Optional[Vec3] = None # 屏幕空间轨迹球起始向量 + self._angle_start_offset: float = 0.0 # 扇形起点(弧度) + self._drag_root_quat_world: Optional[Quat] = None # 拖拽时保持的 Gizmo 世界朝向 + self._arrow_tangent_angle_deg: float = 0.0 # 箭头朝向(在扇形平面内的角度) + self._start_vec_local: Optional[Vec3] = None # 起始向量(扇形局部坐标) + + # 撤销栈:每项为 (node, old_hpr(world), new_hpr(world)) + self._rotate_undo_stack: list[Tuple[NodePath, Vec3, Vec3]] = [] + self._undo_angle_epsilon: float = 0.01 # 角度变化阈值(防止浮点抖动) + + # 边缘视角(grazing angle)时使用屏幕空间旋转的参数 + self._grazing_threshold: float = 0.15 # denom 小于此值时启用屏幕空间计算 + self._center_screen: Optional[Point2] = None # Gizmo 中心的屏幕投影 + self._start_screen_angle: float = 0.0 # 起始鼠标相对于屏幕中心的角度 + self._axis_screen_sign: float = 1.0 # 屏幕空间旋转方向符号 + + # 三个圆环节点:0=X, 1=Y, 2=Z + self.rings: list[NodePath] = [] + self.ring_colors: list[Tuple[NodePath, Vec4]] = [] + # (front_geom_np, back_geom_np, front_col_np, back_col_np) + self.ring_halves: list[Tuple[NodePath,NodePath, NodePath, NodePath]] = [] + self.center_axes: list[NodePath] = [] + self.center_axes_colors: list[Tuple[NodePath, Vec4]] = [] + self.view_ring: Optional[NodePath] = None + self.trackball_np: Optional[NodePath] = None + self.angle_disc_root: Optional[NodePath] = None + self.angle_fill_np: Optional[NodePath] = None + self.angle_fill_np_copy: Optional[NodePath] = None + + self.angle_arrow_np: Optional[NodePath] = None + + # 构建几何与碰撞体 + self._build_gizmo() + + # 初始挂在 world.render,后续通过更新同步到目标 + self.root.reparentTo(self.world.render) + if not self.use_renderpipeline: + self.root.setBin('fixed',40) + self.root.setDepthTest(False) + self.root.setDepthWrite(False) + self.root.setLightOff() + self.root.hide() + + # 每帧更新 Gizmo 缩放 + # taskMgr.add(self._update_task, "RotateGizmoUpdateTask") + + # ------------------------------------------------------------------ # + # 内部工具 + # ------------------------------------------------------------------ # + def _log(self, msg: str): + if self.debug: + print(f"[RotateGizmo] {msg}") + + def _normalize_event_hooks(self, hooks): + base = {name: [] for name in GizmoEvent.ALL} + if not hooks: + return base + for name in list(base.keys()): + cbs = hooks.get(name) + if cbs: + base[name] = list(cbs) + return base + + def _emit_event(self, name: str, payload: Dict[str, Any]): + handlers = self._event_hooks.get(name, []) + for cb in handlers: + try: + cb(payload) + except Exception as exc: + self._log(f"event hook '{name}' error: {exc}") + + def _build_gizmo(self): + """构建旋转 Gizmo 的可视化元素(轴环、屏幕外圈、轨迹球、角度扇形等)。""" + # 屏幕对齐的轨迹球,用于自由旋转 + # 轨迹球:默认隐藏可视几何,仅在选中时显示 + self.trackball_np = self._create_trackball_disc( + radius=self.trackball_radius, + color=self.trackball_color, + visual=True, + ) + if self.trackball_np: + trackball_geom = self.trackball_np.find("**/trackball_geom") + if not trackball_geom.isEmpty(): + trackball_geom.hide() + # X 轴(红)—— 绕局部 X 轴旋转 + self.rings.append( + self._create_ring( + axis_dir=Vec3(1, 0, 0), + color=Vec4(1, 0, 0, 1), + radius=self.ring_radius, + thickness=self.ring_thickness, + axis_id=0, + ) + ) + # Y 轴(绿)—— 绕局部 Y 轴旋转 + self.rings.append( + self._create_ring( + axis_dir=Vec3(0, 1, 0), + color=Vec4(0, 1, 0, 1), + radius=self.ring_radius, + thickness=self.ring_thickness, + axis_id=1, + ) + ) + # Z 轴(蓝)—— 绕局部 Z 轴旋转 + self.rings.append( + self._create_ring( + axis_dir=Vec3(0, 0, 1), + color=Vec4(0, 0, 1, 1), + radius=self.ring_radius, + thickness=self.ring_thickness, + axis_id=2, + ) + ) + # 轨迹球边缘辅助圆,标示球的尺寸(无碰撞) + self.trackball_edge = self._create_trackball_edge( + radius=self.trackball_radius, + color=self.trackball_edge_color, + ) + # 中心轴线,帮助观察旋转轴朝向 + self.center_axes = [ + self._create_center_axis(Vec3(1, 0, 0), Vec4(0.3, 0.0, 0.0, 1.0)), + self._create_center_axis(Vec3(0, 1, 0), Vec4(0.0, 0.3, 0.0, 1.0)), + self._create_center_axis(Vec3(0, 0, 1), Vec4(0.0, 0.0, 0.3, 1.0)), + ] + # 角度可视化扇形 + self._build_angle_disc() + + def _create_ring( + self, + axis_dir: Vec3, + color: Vec4, + radius: float, + thickness: float, + axis_id: int, + ) -> NodePath: + """ + 构建一个圆环: + - 几何:使用 GeomLines 画出若干线段组成的圆 + - 碰撞体:使用多段 CollisionTube 近似圆环 + 默认圆环在局部 XY 平面,法线为 +Z,通过四元数旋转到指定 axis_dir。 + """ + ring_root = self.root.attachNewNode(f"ring_{axis_id}") + + # 本地 +Z 对齐到目标“旋转轴方向”(即圆环法线) + align_quat = self._quat_from_z(axis_dir) + ring_root.setQuat(align_quat) + + # -------------------- 几何圆环 -------------------- + vdata = GeomVertexData("ring", GeomVertexFormat.getV3c4(), Geom.UHStatic) + vertex = GeomVertexWriter(vdata, "vertex") + vcolor = GeomVertexWriter(vdata, "color") + + segments = 64 + for i in range(segments + 1): + angle = 2 * math.pi * i / segments + x = radius * math.cos(angle) + y = radius * math.sin(angle) + vertex.addData3(x, y, 0.0) + vcolor.addData4(color) + + # 将圆拆分为两个半圆环,方便根据摄像机方向隐藏背面的半圆。 + half_segments = segments // 2 + + # 前半圆:索引 [0, half_segments] + prim_front = GeomLines(Geom.UHStatic) + for i in range(half_segments): + prim_front.addVertices(i, i + 1) + geom_front = Geom(vdata) + geom_front.addPrimitive(prim_front) + node_front = GeomNode("ring_geom_front") + node_front.addGeom(geom_front) + np_front = ring_root.attachNewNode(node_front) + np_front.setTransparency(True) + np_front.setColorScale(1, 1, 1, self.ring_alpha) + + # 后半圆:索引 [half_segments, segments] + prim_back = GeomLines(Geom.UHStatic) + for i in range(half_segments, segments): + prim_back.addVertices(i, i + 1) + geom_back = Geom(vdata) + geom_back.addPrimitive(prim_back) + node_back = GeomNode("ring_geom_back") + node_back.addGeom(geom_back) + np_back = ring_root.attachNewNode(node_back) + np_back.setTransparency(True) + np_back.setColorScale(1, 1, 1, self.ring_alpha) + if self.use_renderpipeline: + ring_root.copy_to(ring_root.get_parent()) + mat = Material('default') + mat.set_emission((1,0,1,1)) + mat.base_color = color * self.color_normal + ring_root.set_material(mat) + ring_root.set_bin('fixed',40) + ring_root.set_depth_test(False) + ring_root.set_depth_write(False) + self.ring_colors.append((ring_root,color)) + + # -------------------- 碰撞圆环拆分为两半 -------------------- + col_segments = 24 + half_col = col_segments // 2 + + c_node_front = CollisionNode(f"ring_col_front_{axis_id}") + c_node_front.setIntoCollideMask(BitMask32.bit(20)) + c_node_front.setFromCollideMask(BitMask32.allOff()) + c_node_front.setTag("gizmo_axis", str(axis_id)) + for i in range(half_col): + a0 = 2 * math.pi * i / col_segments + a1 = 2 * math.pi * (i + 1) / col_segments + p0 = Point3(radius * math.cos(a0), radius * math.sin(a0), 0.0) + p1 = Point3(radius * math.cos(a1), radius * math.sin(a1), 0.0) + c_node_front.addSolid(CollisionTube(p0, p1, thickness)) + col_front_np = ring_root.attachNewNode(c_node_front) + + c_node_back = CollisionNode(f"ring_col_back_{axis_id}") + c_node_back.setIntoCollideMask(BitMask32.bit(20)) + c_node_back.setFromCollideMask(BitMask32.allOff()) + c_node_back.setTag("gizmo_axis", str(axis_id)) + for i in range(half_col, col_segments): + a0 = 2 * math.pi * i / col_segments + a1 = 2 * math.pi * (i + 1) / col_segments + p0 = Point3(radius * math.cos(a0), radius * math.sin(a0), 0.0) + p1 = Point3(radius * math.cos(a1), radius * math.sin(a1), 0.0) + c_node_back.addSolid(CollisionTube(p0, p1, thickness)) + col_back_np = ring_root.attachNewNode(c_node_back) + + # 默认先都显示,后续在 update() 中根据摄像机位置只显示靠近摄像机的一半(含碰撞) + self.ring_halves.append((np_front, np_back, col_front_np, col_back_np)) + + return ring_root + + def _create_center_axis(self, axis_dir: Vec3, color: Vec4) -> NodePath: + """创建中心轴线,方便观察轴向。""" + vdata = GeomVertexData( + "center_axis", GeomVertexFormat.getV3c4(), Geom.UHStatic) + vertex = GeomVertexWriter(vdata, "vertex") + vcolor = GeomVertexWriter(vdata, "color") + + vertex.addData3(0.0, 0.0, 0.0) + vcolor.addData4(color) + tip = axis_dir * (self.ring_radius * 0.8) + vertex.addData3(tip) + vcolor.addData4(color) + + lines = GeomLines(Geom.UHStatic) + lines.addVertices(0, 1) + geom = Geom(vdata) + geom.addPrimitive(lines) + node = GeomNode("center_axis_geom") + node.addGeom(geom) + np = self.root.attachNewNode(node) + np.setTransparency(True) + np.setColorScale(1, 1, 1, 0.9) + + if self.use_renderpipeline: + np.copy_to(np.get_parent()) + mat = Material('default') + mat.set_emission((1,0,1,1)) + mat.base_color = color * self.color_normal + np.set_material(mat) + np.set_bin('fixed',40) + np.set_depth_test(False) + np.set_depth_write(False) + self.center_axes_colors.append((np,color)) + return np + + def _create_trackball_edge(self, radius: float, color: Vec4) -> NodePath: + """创建轨迹球尺寸辅助圆(无碰撞,仅显示)。""" + edge_root = self.root.attachNewNode("trackball_edge") + vdata = GeomVertexData("trackball_edge", GeomVertexFormat.getV3c4(), Geom.UHStatic) + vertex = GeomVertexWriter(vdata, "vertex") + vcolor = GeomVertexWriter(vdata, "color") + + segments = 96 + for i in range(segments + 1): + ang = 2 * math.pi * i / segments + x = radius * math.cos(ang) + z = radius * math.sin(ang) + vertex.addData3(x, 0.0, z) + vcolor.addData4(color) + + prim = GeomLines(Geom.UHStatic) + for i in range(segments): + prim.addVertices(i, i + 1) + geom = Geom(vdata) + geom.addPrimitive(prim) + node = GeomNode("trackball_edge_geom") + node.addGeom(geom) + np_geom = edge_root.attachNewNode(node) + np_geom.setRenderModeThickness(1.5) + np_geom.setBillboardPointEye() + np_geom.setTransparency(True) + np_geom.setColorScale(color) + + if self.use_renderpipeline: + np_geom.copy_to(np_geom.get_parent()) + mat = Material('default') + mat.set_emission((1,0,1,1)) + mat.base_color = color * self.color_normal + np_geom.set_material(mat) + np_geom.set_bin('fixed', 40) + np_geom.set_depth_test(False) + np_geom.set_depth_write(False) + return edge_root + + def _create_trackball_disc(self, radius: float, color: Vec4, visual: bool = True) -> NodePath: + """创建屏幕对齐的轨迹球圆盘。visual=False 时仅保留拾取体。""" + disc_root = self.root.attachNewNode("trackball_disc") + + if visual: + np_geom = self.make_sphere(radius=radius,color=color) + np_geom.set_name("trackball_geom") + np_geom.wrt_reparent_to(disc_root) + np_geom.setTransparency(True) + + if self.use_renderpipeline: + mat = Material('default') + # mat.set_emission((1,0,1,1)) + # mat.base_color = color * self.color_normal * 0.2 + mat.base_color = (1,1,1,0.2) + np_geom.setMaterial(mat) + np_geom.set_bin("fixed", 40) + np_geom.set_depth_test(False) + np_geom.set_depth_write(False) + + + # 拾取使用球体,方便捕获整个圆盘区域 + c_node = CollisionNode("trackball_col") + c_node.setIntoCollideMask(BitMask32.bit(20)) + c_node.setFromCollideMask(BitMask32.allOff()) + c_node.setTag("gizmo_handle", "trackball") + c_node.addSolid(CollisionSphere(0, 0, 0, radius + self.ring_thickness * 0.25)) + disc_root.attachNewNode(c_node) + + return disc_root + + def make_sphere(self,radius=0.5, lat_steps=32, lon_steps=64, color=(1,1,1,0.5)) -> NodePath: + fmt = GeomVertexFormat.getV3c4() + vdata = GeomVertexData("sphere", fmt, Geom.UHStatic) + vw = GeomVertexWriter(vdata, "vertex") + cw = GeomVertexWriter(vdata, "color") + tris = GeomTriangles(Geom.UHStatic) + + # 顶点 + for i in range(lat_steps + 1): # 纬度 0..pi + theta = math.pi * i / lat_steps + st, ct = math.sin(theta), math.cos(theta) + for j in range(lon_steps): # 经度 0..2pi + phi = 2 * math.pi * j / lon_steps + sp, cp = math.sin(phi), math.cos(phi) + x, y, z = radius * cp * st, radius * sp * st, radius * ct + vw.addData3(x, y, z) + cw.addData4(*color) + + # 索引 + def vid(i, j): # i:0..lat_steps, j:0..lon_steps-1 + return i * lon_steps + (j % lon_steps) + + for i in range(lat_steps): + for j in range(lon_steps): + a = vid(i, j) + b = vid(i+1, j) + c = vid(i+1, j+1) + d = vid(i, j+1) + tris.addVertices(a, b, c) + tris.addVertices(a, c, d) + + geom = Geom(vdata); geom.addPrimitive(tris) + node = GeomNode("hi_sphere"); node.addGeom(geom) + np = NodePath(node) + return np + + def _build_angle_disc(self): + """搭建旋转角度的可视化扇形。""" + self.angle_disc_root = self.root.attachNewNode("angle_disc_root") + self.angle_disc_root.setTransparency(TransparencyAttrib.M_alpha) + self.angle_disc_root.setTwoSided(True) + self.angle_disc_root.hide() + + self.angle_fill_np = self.angle_disc_root.attachNewNode(GeomNode("angle_sector")) + self.angle_fill_np.setTransparency(TransparencyAttrib.M_alpha) + self.angle_fill_np.setColor(0.9, 0.9, 0.9, 0.5) + + # 动态扇形,用于实时显示旋转角度 + if self.use_renderpipeline: + self.angle_fill_np_copy = self.angle_disc_root.attachNewNode(GeomNode("angle_sector_copy")) + mat = Material('unlit') + self.angle_fill_np_copy.set_material(mat) + + mat = Material('unlit') + mat.set_emission((1,0,1,1)) + mat.base_color = Vec4(0.9, 0.9, 0.9, 0.5) * self.color_normal + self.angle_fill_np.set_material(mat) + self.angle_fill_np.set_bin('fixed',40) + self.angle_fill_np.set_depth_test(False) + self.angle_fill_np.set_depth_write(False) + + # 末端箭头 + self.angle_arrow_np = self._create_angle_arrow( + self.angle_disc_root, + self.ring_radius * self.arrow_length_factor, + self.arrow_head_width_factor, + ) + self.angle_arrow_np.setColor(1.0, 1.0, 1.0, 1.0) + self.angle_arrow_np.hide() + + def _create_angle_disc_half(self, parent: NodePath, mirror: bool = False) -> NodePath: + """创建角度盘的一半,方便做基础背景。""" + segments = 50 + angle = math.pi / segments + angle = -angle if mirror else angle + offset = math.pi * 0.5 + + vdata = GeomVertexData("angle_disc_half", GeomVertexFormat.getV3(), Geom.UHStatic) + vertex = GeomVertexWriter(vdata, "vertex") + + for i in range(segments + 1): + x = math.cos(angle * i - offset) + y = math.sin(angle * i - offset) + vertex.addData3(x, y, 0.0) + + prim = GeomTriangles(Geom.UHStatic) + for i in range(1, segments): + prim.addVertices(0, i, i + 1) + geom = Geom(vdata) + geom.addPrimitive(prim) + node = GeomNode("angle_disc_half_node") + node.addGeom(geom) + half_np = parent.attachNewNode(node) + half_np.setTransparency(TransparencyAttrib.M_alpha) + half_np.setColor(1, 1, 1, 0.1) + return half_np + + def _create_angle_arrow(self, parent: NodePath, length: float, head_width_factor: float) -> NodePath: + """创建显示末端角度的箭头。""" + vdata = GeomVertexData( + "angle_arrow", GeomVertexFormat.getV3(), Geom.UHStatic) + vertex = GeomVertexWriter(vdata, "vertex") + + # 箭头沿 +X 方向,从原点出发,便于通过平面内旋转对齐切线 + head_w = max(length * head_width_factor, length * 0.02) + vertex.addData3(0.0, 0.0, 0.0) + vertex.addData3(length, 0.0, 0.0) + vertex.addData3(length * 0.7, head_w, 0.0) + vertex.addData3(length * 0.7, -head_w, 0.0) + + prim = GeomLines(Geom.UHStatic) + prim.addVertices(0, 1) + prim.addVertices(1, 2) + prim.addVertices(1, 3) + geom = Geom(vdata) + geom.addPrimitive(prim) + node = GeomNode("angle_arrow_geom") + node.addGeom(geom) + np = parent.attachNewNode(node) + np.setTransparency(TransparencyAttrib.M_alpha) + np.setTwoSided(True) + + if self.use_renderpipeline: + np_copy = np.copy_to(np) + mat = Material('default') + mat.base_color = Vec4(1,1,1,1) * self.color_normal + mat.set_emission((1,0,1,1)) + np_copy.set_material(mat) + np_copy.set_bin('fixed',40) + np_copy.set_depth_test(False) + np_copy.set_depth_write(False) + return np + + def _build_sector_geom(self, start_rad: float, end_rad: float) -> Geom: + """根据起止弧度创建扇形几何。""" + radius = self.ring_radius + span = end_rad - start_rad + direction = 1.0 if span >= 0.0 else -1.0 + span = abs(span) + segments = max(8, int(48 * (span / (2 * math.pi)))) + + vdata = GeomVertexData("angle_sector_data", GeomVertexFormat.getV3(), Geom.UHStatic) + vertex = GeomVertexWriter(vdata, "vertex") + + # 中心点 + vertex.addData3(0.0, 0.0, 0.0) + for i in range(segments + 1): + a = start_rad + direction * (span * i / segments) + x = radius * math.cos(a) + y = radius * math.sin(a) + vertex.addData3(x, y, 0.0) + + prim = GeomTriangles(Geom.UHStatic) + for i in range(1, segments + 1): + prim.addVertices(0, i, i + 1) + geom = Geom(vdata) + geom.addPrimitive(prim) + + return geom + + def _quat_from_z(self, direction: Vec3) -> Quat: + """ + 与 MoveGizmo 保持一致: + 返回一个四元数,使本地 +Z 旋转到指定 direction(自动归一化)。 + """ + dir_norm = Vec3(direction) + if dir_norm.length_squared() == 0: + return Quat.identQuat() + dir_norm.normalize() + z_axis = Vec3(0, 0, 1) + dot = z_axis.dot(dir_norm) + if abs(dot - 1.0) < 1e-6: + return Quat.identQuat() # 已经对齐 + if abs(dot + 1.0) < 1e-6: + # 反向,绕任意垂直于 Z 的轴旋转 180° + ortho = Vec3(1, 0, 0) if abs(z_axis.dot( + Vec3(1, 0, 0))) < 0.9 else Vec3(0, 1, 0) + axis = z_axis.cross(ortho) + axis.normalize() + q = Quat() + q.setFromAxisAngle(180.0, axis) + return q + axis = z_axis.cross(dir_norm) + axis_len = axis.length() + if axis_len == 0: + return Quat.identQuat() + axis.normalize() + angle_rad = math.atan2(axis_len, dot) + q = Quat() + q.setFromAxisAngle(math.degrees(angle_rad), axis) + return q + + def _begin_angle_visual(self, axis_world: Vec3): + """开始显示角度扇形,基于当前旋转轴和起始向量。""" + if self.angle_disc_root is None: + return + if axis_world.length_squared() == 0: + return + + align_q = self._quat_from_z(axis_world) + self.angle_disc_root.setQuat(self.world.render, align_q) + self.angle_disc_root.setPos(self.root, 0, 0, 0) + + # 计算起始向量在扇形平面上的角度,作为扇形起点 + if self.start_vec_on_plane.length_squared() > 0: + q_inv = Quat(self.angle_disc_root.getQuat(self.world.render)) + q_inv.invertInPlace() + local_vec = q_inv.xform(self.start_vec_on_plane) + if local_vec.length_squared() == 0: + local_vec = Vec3(1, 0, 0) + local_vec.normalize() + self._start_vec_local = local_vec + self._angle_start_offset = math.atan2(local_vec.y, local_vec.x) + + # 箭头朝向:起始向量的切线方向(轴 x start_vec),并记录为局部平面角度 + axis_world_norm = Vec3(axis_world) + axis_world_norm.normalize() + tangent_world = axis_world_norm.cross(self.start_vec_on_plane) + if tangent_world.length_squared() == 0: + tangent_world = Vec3(-self.start_vec_on_plane.y, + self.start_vec_on_plane.x, 0) + tangent_world.normalize() + tangent_local = q_inv.xform(tangent_world) + self._arrow_tangent_angle_deg = math.degrees( + math.atan2(tangent_local.y, tangent_local.x)) + + # 将箭头放在起始点位置,面向相机 + if self.angle_arrow_np: + self.angle_arrow_np.setPos( + self.angle_disc_root, + Vec3(local_vec.x * self.ring_radius, + local_vec.y * self.ring_radius, + 0.0), + ) + # 初始朝向即切线方向 + self.angle_arrow_np.setH(self._arrow_tangent_angle_deg) + else: + self._start_vec_local = Vec3(1, 0, 0) + self._angle_start_offset = 0.0 + self._arrow_tangent_angle_deg = 90.0 + + # 初始化扇形(零度) + self._update_angle_sector( + self._angle_start_offset, self._angle_start_offset) + self.angle_disc_root.show() + if self.angle_arrow_np: + self.angle_arrow_np.hide() + + def _update_angle_visual(self, delta_deg: float): + """根据当前旋转角度更新扇形与箭头。""" + if self.angle_disc_root is None or self.angle_fill_np is None: + return + start_rad = self._angle_start_offset + end_rad = start_rad + math.radians(delta_deg) + self._update_angle_sector(start_rad, end_rad) + if self.angle_arrow_np: + arrow_angle = self._arrow_tangent_angle_deg + if delta_deg < 0.0: + arrow_angle += 180.0 + self.angle_arrow_np.setH(arrow_angle) + if self.angle_arrow_np.isHidden(): + self.angle_arrow_np.show() + + def _update_angle_sector(self, start_rad: float, end_rad: float): + """生成并替换当前的角度扇形几何。""" + if self.angle_fill_np is None: + return + geom = self._build_sector_geom(start_rad, end_rad) + node = self.angle_fill_np.node() + node.removeAllGeoms() + node.addGeom(geom) + + if self.use_renderpipeline: + node_copy = self.angle_fill_np_copy.node() + node_copy.removeAllGeoms() + node_copy.addGeom(geom) + + self.angle_fill_np.setTwoSided(True) + + def _hide_angle_disc(self): + """结束旋转时隐藏角度扇形。""" + if self.angle_disc_root: + self.angle_disc_root.hide() + if self.angle_fill_np: + self.angle_fill_np.node().removeAllGeoms() + if self.angle_arrow_np: + self.angle_arrow_np.hide() + self._angle_start_offset = 0.0 + + def _map_to_trackball(self, mpos: Point3) -> Vec3: + """将屏幕坐标映射到轨迹球上的向量。""" + x = mpos.x + y = mpos.y + length_sq = x * x + y * y + if length_sq <= 1.0: + z = math.sqrt(max(0.0, 1.0 - length_sq)) + v = Vec3(x, y, z) + else: + v = Vec3(x, y, 0.0) + v.normalize() + return v + + def _apply_trackball_rotation(self, mpos: Point3): + """轨迹球旋转计算:基于屏幕向量的弧球算法。""" + if self._trackball_start_vec is None or self.start_quat is None: + return + curr_vec = self._map_to_trackball(mpos) + axis_cam = self._trackball_start_vec.cross(curr_vec) + axis_len_sq = axis_cam.length_squared() + if axis_len_sq < 1e-8: + return + axis_cam.normalize() + dot = max(min(self._trackball_start_vec.dot(curr_vec), 1.0), -1.0) + angle_rad = math.acos(dot) + axis_world = self.camera.getQuat(self.world.render).xform(axis_cam) + q_delta = Quat() + q_delta.setFromAxisAngle(math.degrees(angle_rad), axis_world) + new_quat_world = q_delta * self.start_quat + self.target_node.setQuat(self.world.render, new_quat_world) + self._emit_event( + GizmoEvent.DRAG_MOVE, + { + "gizmo": "rotate", + "mode": "trackball", + "axis": None, + "target": self.target_node, + "mouse": Point2(mpos.x, mpos.y), + "delta_deg": math.degrees(angle_rad), + }, + ) + + # ------------------------------------------------------------------ # + # 公共接口:绑定 / 解绑 + # ------------------------------------------------------------------ # + def attach(self, node_path: NodePath): + """ + 绑定控制柄到指定 NodePath。 + 当前实现采用 Unity 类似的“世界模式(Global)”: + - Gizmo 的三个旋转轴始终对齐世界坐标系的 X/Y/Z 方向。 + """ + if not node_path: + return + + self.target_node = node_path + self.attached = True + self._update_root_transform() + self.root.show() + self._log( + f"attached to {node_path.getName()} " + f"world_pos={self.root.getPos(self.world.render)} " + f"target_hpr={node_path.getHpr(self.world.render)}" + ) + # 根据当前相机位置初始化半圆环的正反显示 + self._update_ring_halves_visibility() + self._register_events() + + def detach(self): + """解绑并隐藏 Gizmo。""" + self.target_node = None + self.root.hide() + self.attached = False + self.dragging = False + self.drag_axis = None + self.drag_mode = None + self._trackball_start_vec = None + self._drag_root_quat_world = None + self._hide_angle_disc() + self._reset_highlights() + self._ignore_events() + self._log("detached") + + def _update_ring_halves_visibility(self): + """根据摄像机与 Gizmo 相对位置,切换每个轴的前/后半圆显示。""" + if not self.camera: + return + + cam_pos = self.camera.getPos(self.world.render) + center = self.root.getPos(self.world.render) + view_vec = cam_pos - center + + for axis_id, ring_root in enumerate(self.rings): + if axis_id >= len(self.ring_halves): + continue + front_np, back_np, col_front_np, col_back_np = self.ring_halves[axis_id] + if front_np.isEmpty() or back_np.isEmpty(): + continue + + # 圆环所在平面的法线(世界坐标) + plane_normal = ring_root.getQuat(self.world.render).xform(Vec3(0, 0, 1)) + if plane_normal.length_squared() == 0: + continue + plane_normal.normalize() + + # 将摄像机方向投影到圆环平面内,确定“近半圆”切分线的朝向 + d = view_vec - plane_normal * view_vec.dot(plane_normal) + if d.length_squared() == 0: + # 摄像机几乎正对法线,保持显示近侧半圆 + front_np.show() + back_np.hide() + if not col_front_np.isEmpty(): + col_front_np.node().setIntoCollideMask(BitMask32.bit(20)) + if not col_back_np.isEmpty(): + col_back_np.node().setIntoCollideMask(BitMask32.allOff()) + front_np.setHpr(ring_root, 0, 0, 0) + back_np.setHpr(ring_root, 0, 0, 0) + continue + + q_world = ring_root.getQuat(self.world.render) + q_inv = Quat(q_world) + q_inv.invertInPlace() + d_local = q_inv.xform(d) + if d_local.length_squared() == 0: + front_np.show() + back_np.hide() + if not col_front_np.isEmpty(): + col_front_np.node().setIntoCollideMask(BitMask32.bit(20)) + if not col_back_np.isEmpty(): + col_back_np.node().setIntoCollideMask(BitMask32.allOff()) + if not col_front_np.isEmpty(): + col_front_np.setHpr(ring_root, 0, 0, 0) + if not col_back_np.isEmpty(): + col_back_np.setHpr(ring_root, 0, 0, 0) + continue + d_local.normalize() + + # 将半圆几何整体绕轴旋转,让切分线对齐相机投影方向 + angle = math.atan2(d_local.y, d_local.x) + # 将近侧半圆的中心对准相机投影方向(边界垂直于视线投影) + angle_deg = math.degrees(angle) - 90.0 + front_np.setHpr(ring_root, angle_deg, 0, 0) + back_np.setHpr(ring_root, angle_deg, 0, 0) + if not col_front_np.isEmpty(): + col_front_np.setHpr(ring_root, angle_deg, 0, 0) + if not col_back_np.isEmpty(): + col_back_np.setHpr(ring_root, angle_deg, 0, 0) + + # 近侧半圆显示,远侧隐藏 + front_np.show() + back_np.hide() + if not col_front_np.isEmpty(): + col_front_np.node().setIntoCollideMask(BitMask32.bit(20)) + if not col_back_np.isEmpty(): + col_back_np.node().setIntoCollideMask(BitMask32.allOff()) + + # ------------------------------------------------------------------ # + # 撤销支持(可选使用) + # ------------------------------------------------------------------ # + + def _record_rotate_action(self, node: NodePath, old_hpr: Vec3, new_hpr: Vec3): + """将一次旋转操作压入撤销栈,并在需要时通知外部监听者。""" + if node is None or node.isEmpty(): + return + if old_hpr is None or new_hpr is None: + return + + delta = new_hpr - old_hpr + if ( + abs(delta.x) < self._undo_angle_epsilon + and abs(delta.y) < self._undo_angle_epsilon + and abs(delta.z) < self._undo_angle_epsilon + ): + return + + old_copy = Vec3(old_hpr) + new_copy = Vec3(new_hpr) + self._rotate_undo_stack.append((node, old_copy, new_copy)) + self._log( + f"record rotate action: node={node.getName()} " + f"old_hpr={old_copy} new_hpr={new_copy} stack_size={len(self._rotate_undo_stack)}" + ) + + # 把这次旋转操作上报给 TransformGizmo,用于全局撤销栈 + if self.on_action_committed is not None: + try: + self.on_action_committed( + { + "kind": "rotate", + "node": node, + "old_hpr": Vec3(old_copy), + "new_hpr": Vec3(new_copy), + } + ) + except Exception as exc: + self._log(f"on_action_committed(rotate) error: {exc}") + + def undo_last_rotate(self): + """ + 撤销最近一次旋转操作。 + 可在 UI 中绑定快捷键调用。 + """ + if not self._rotate_undo_stack: + self._log("undo_last_rotate: stack empty") + return + node, old_hpr, new_hpr = self._rotate_undo_stack.pop() + if node is None or node.isEmpty(): + self._log("undo_last_rotate: target node invalid") + return + node.setHpr(self.world.render, old_hpr) + self._log( + f"undo_last_rotate: node={node.getName()} " + f"old_hpr={old_hpr} new_hpr={new_hpr} remaining={len(self._rotate_undo_stack)}" + ) + + # ------------------------------------------------------------------ # + # 事件注册 / 取消 + # ------------------------------------------------------------------ # + def _register_events(self): + """注册鼠标事件监听。""" + self.accept("mouse1", self._on_mouse_down) + self.accept("mouse1-up", self._on_mouse_up) + self.accept("mouse2-up", self._on_mouse_up) + self.accept("mouse3-up", self._on_mouse_up) + self.accept("mouse-move", self._on_mouse_move) + self._log("event listeners registered (mouse)") + + def _ignore_events(self): + """取消事件监听。""" + self.ignore("mouse1") + self.ignore("mouse1-up") + self.ignore("mouse2-up") + self.ignore("mouse3-up") + self.ignore("mouse-move") + self._log("event listeners removed") + + # ------------------------------------------------------------------ # + # 鼠标坐标工具 + # ------------------------------------------------------------------ # + def _get_normalized_mouse(self, extra) -> Optional[Point3]: + """ + 将鼠标转换到 Panda3D 的标准化设备坐标 [-1, 1]。 + + 优先使用 Qt / 外部 UI 传入的像素坐标(extra 字典), + 如果没有,则回退到 Panda3D 的 mouseWatcherNode。 + """ + if self.world.mouseWatcherNode.hasMouse(): + mouse = self.world.mouseWatcherNode.getMouse() + return Point3(mouse.x, mouse.y, 0) + + # 1) 外部 UI:通过 messenger 传入像素坐标 + if isinstance(extra, dict) and "x" in extra and "y" in extra: + parent = getattr(self.world, "parent", None) + if parent is not None: + w = max(parent.width(), 1) + h = max(parent.height(), 1) + nx = (extra["x"] / w) * 2.0 - 1.0 + # Qt 原点在左上,Panda3D 原点在中心,Y 轴向上 + ny = 1.0 - (extra["y"] / h) * 2.0 + return Point3(nx, ny, 0.0) + + return None + + # ------------------------------------------------------------------ # + # 屏幕空间旋转辅助方法 + # ------------------------------------------------------------------ # + def _compute_screen_space_params(self, mpos: Point3): + """ + 计算屏幕空间旋转所需的参数: + - Gizmo 中心在屏幕上的投影位置 + - 旋转轴在屏幕上的投影方向(2D向量) + - 起始鼠标位置 + """ + if not self.camera: + return + + lens = self.camera.node().getLens() + + # 将 Gizmo 中心投影到屏幕空间 + center_cam = self.camera.getRelativePoint( + self.world.render, self.center_world) + center_2d = Point2() + if lens.project(center_cam, center_2d): + self._center_screen = center_2d + else: + self._center_screen = Point2(0, 0) + + # 将旋转轴末端投影到屏幕空间,计算轴在屏幕上的方向 + axis_end_world = self.center_world + self.rotate_axis_world + axis_end_cam = self.camera.getRelativePoint( + self.world.render, axis_end_world) + axis_end_2d = Point2() + if lens.project(axis_end_cam, axis_end_2d): + # 屏幕上的轴方向向量 + self._axis_screen_dir = Point2( + axis_end_2d.x - self._center_screen.x, + axis_end_2d.y - self._center_screen.y + ) + # 归一化 + axis_len = math.sqrt( + self._axis_screen_dir.x ** 2 + self._axis_screen_dir.y ** 2) + if axis_len > 1e-6: + self._axis_screen_dir = Point2( + self._axis_screen_dir.x / axis_len, + self._axis_screen_dir.y / axis_len + ) + else: + self._axis_screen_dir = Point2(0, 1) + else: + self._axis_screen_dir = Point2(0, 1) + + # 记录起始鼠标位置 + self._start_mouse_screen = Point2(mpos.x, mpos.y) + + # 旋转灵敏度(屏幕单位到角度的转换系数) + self._screen_sensitivity = 180.0 # 移动1个屏幕单位 = 180度 + + self._log( + f"screen params: center={self._center_screen} " + f"axis_dir={self._axis_screen_dir} " + f"start_mouse={self._start_mouse_screen}" + ) + + def _calc_screen_space_angle(self, mpos: Point3) -> float: + """ + 使用屏幕空间计算旋转角度(度)。 + 基于鼠标移动在旋转轴屏幕投影的垂直方向上的分量。 + """ + if self._center_screen is None or self._axis_screen_dir is None: + self._log("screen params not ready") + return 0.0 + + # 鼠标移动向量(从起始位置) + move_x = mpos.x - self._start_mouse_screen.x + move_y = mpos.y - self._start_mouse_screen.y + + # 轴的垂直方向(屏幕空间):将轴方向旋转90度 + # 原方向 (ax, ay),垂直方向 (-ay, ax) + perp_x = -self._axis_screen_dir.y + perp_y = self._axis_screen_dir.x + + # 鼠标移动在垂直方向上的投影(点积) + perp_component = move_x * perp_x + move_y * perp_y + + # 转换为角度 + delta_deg = perp_component * self._screen_sensitivity + + self._log( + f"screen calc: mouse=({mpos.x:.3f},{mpos.y:.3f}) " + f"move=({move_x:.3f},{move_y:.3f}) " + f"perp=({perp_x:.3f},{perp_y:.3f}) " + f"perp_comp={perp_component:.4f} delta={delta_deg:.2f}" + ) + + # print(f"screen calc: mouse=({mpos.x:.3f},{mpos.y:.3f}) ") + # print(f"move=({move_x:.3f},{move_y:.3f}) ") + # print(f"perp=({perp_x:.3f},{perp_y:.3f}) ") + # print(f"perp_comp={perp_component:.4f} delta={delta_deg:.2f}") + + return -delta_deg + + # ------------------------------------------------------------------ # + # 鼠标事件:按下 / 弹起 / 移动 + # ------------------------------------------------------------------ # + def _on_mouse_down(self, extra=None): + if not self.attached or not self.camera or self.target_node is None: + return + + mpos = self._get_normalized_mouse(extra) + if mpos is None: + self._log("mouse_down ignored: no mouse pos") + return + + # 设置拾取射线 + self.picker_np.reparentTo(self.camera) + if not self._picker_added: + self.c_trav.addCollider(self.picker_np, self.c_queue) + self._picker_added = True + self.picker_ray.setFromLens(self.camera.node(), mpos.x, mpos.y) + + self.c_queue.clearEntries() + self.c_trav.traverse(self.root) + + self._log( + f"mouse_down mpos={mpos} cam_pos={self.camera.getPos(self.world.render)} " + f"cam_hpr={self.camera.getHpr(self.world.render)} " + f"entries={self.c_queue.getNumEntries()}" + ) + + num_entries = self.c_queue.getNumEntries() + if num_entries <= 0: + self._log("mouse_down: no collision entries on rotate gizmo") + return + + self.c_queue.sortEntries() + + axis_entry: Optional[CollisionEntry] = None + trackball_entry: Optional[CollisionEntry] = None + picked_kind: Optional[str] = None # "axis" / "view" / "trackball" + picked_axis_id: Optional[int] = None + for i in range(num_entries): + e = self.c_queue.getEntry(i) + axis_tag = e.getIntoNode().getTag("gizmo_axis") + handle_tag = e.getIntoNode().getTag("gizmo_handle") + if axis_tag: + axis_entry = e + picked_axis_id = int(axis_tag) + break + if handle_tag == "view": + # 外圈已移除,忽略 + continue + elif handle_tag == "trackball" and trackball_entry is None: + trackball_entry = e + + if axis_entry is not None: + picked_kind = "axis" + elif trackball_entry is not None: + axis_entry = trackball_entry + picked_kind = "trackball" + + if axis_entry is None or picked_kind is None: + self._log("mouse_down: hit something but no gizmo handle tag") + return + + self.dragging = True + self.drag_mode = "axis" if picked_kind == "axis" else picked_kind + self.drag_axis = picked_axis_id if self.drag_mode == "axis" else None + + self.center_world = self.root.getPos(self.world.render) + self.start_quat = self.target_node.getQuat(self.world.render) + self.start_quat_local = self.target_node.getQuat() + self.start_mouse = Point2(mpos.x, mpos.y) + self._trackball_start_vec = None + self._drag_root_quat_world = self.root.getQuat(self.world.render) + self._hide_angle_disc() + + # 轨迹球模式:屏幕空间自由旋转,不需要射线平面求交 + if self.drag_mode == "trackball": + self._trackball_start_vec = self._map_to_trackball(mpos) + self._highlight_axis("trackball") + self._emit_event( + GizmoEvent.DRAG_START, + { + "gizmo": "rotate", + "mode": self.drag_mode, + "axis": self.drag_axis, + "target": self.target_node, + "mouse": Point2(mpos.x, mpos.y), + "start_quat": self.start_quat, + }, + ) + return + + # 以“可见圆环”的朝向为准,避免目标节点已有旋转时出现视觉/数学轴不一致 + if self.drag_mode == "axis" and self.drag_axis is not None: + ring_np = self.rings[self.drag_axis] + # 环所在平面法线:本地 +Z + ring_axis_local = ring_np.getQuat().xform(Vec3(0, 0, 1)) + if ring_axis_local.length_squared() == 0: + ring_axis_local = Vec3(0, 0, 1) + ring_axis_local.normalize() + self.drag_local_axis = ring_axis_local # 父坐标系下的轴(与控件视觉一致) + + if self.drag_axis == 0: + self.start_root_axis_dir = Quat(self.root.getQuat()).getRight() + elif self.drag_axis == 1: + self.start_root_axis_dir = Quat( + self.root.getQuat()).getForward() + elif self.drag_axis == 2: + self.start_root_axis_dir = Quat(self.root.getQuat()).getUp() + + # 使用圆环本身的朝向来定义平面法线(可见轴与数学轴一致) + ring_np_world_quat = ring_np.getQuat(self.world.render) + axis_dir: Vec3 = ring_np_world_quat.xform(Vec3(0, 0, 1)) + else: + # 视图对齐模式:轴朝向摄像机前向 + axis_dir = self.camera.getQuat(self.world.render).getForward() + self.drag_local_axis = None + self.start_root_axis_dir = Vec3(axis_dir) + + if axis_dir.length_squared() == 0: + axis_dir = Vec3(0, 0, 1) + axis_dir.normalize() + self.rotate_axis_world = axis_dir + + # 计算当前鼠标射线与“旋转平面”(法线为当前轴,过 center_world)之间的交点 + lens: PerspectiveLens = self.camera.node().getLens() + p_from = Point3() + p_to = Point3() + hit_point: Optional[Point3] = None + if lens.extrude(Point2(mpos.x, mpos.y), p_from, p_to): + ray_origin = self.world.render.getRelativePoint( + self.camera, p_from) + ray_to = self.world.render.getRelativePoint(self.camera, p_to) + ray_dir = ray_to - ray_origin + if ray_dir.length_squared() != 0: + ray_dir.normalize() + n = self.rotate_axis_world + denom = ray_dir.dot(n) + if abs(denom) > 1e-6: + t = (self.center_world - ray_origin).dot(n) / denom + hit_point = ray_origin + ray_dir * t + + # 如果无法求交(几乎平行),回退到“摄像机投影向量” + if hit_point is None: + cam_pos = self.camera.getPos(self.world.render) + v = cam_pos - self.center_world + n = self.rotate_axis_world + proj = v - n * v.dot(n) + if proj.length_squared() == 0: + proj = Vec3(1, 0, 0) if abs(n.x) < 0.9 else Vec3(0, 1, 0) + hit_point = self.center_world + proj + + start_vec = hit_point - self.center_world + if start_vec.length_squared() == 0: + start_vec = Vec3(1, 0, 0) + start_vec.normalize() + self.start_vec_on_plane = start_vec + + # 计算屏幕空间参数,用于边缘视角时的备用旋转计算 + self._compute_screen_space_params(mpos) + + # 初始化角度扇形 + self._begin_angle_visual(self.rotate_axis_world) + + self._highlight_axis( + self.drag_axis if self.drag_mode == "axis" else self.drag_mode) + if self.debug: + t_quat_world = self.target_node.getQuat(self.world.render) + t_quat_local = self.target_node.getQuat() + self._log( + " / ".join( + [ + f"pick handle={self.drag_mode} axis={self.drag_axis} target={self.target_node.getName()}", + f"center={self.center_world}", + f"axis_world(from ring)={self.rotate_axis_world}", + f"axis_local(from ring)={self.drag_local_axis}", + f"start_vec={self.start_vec_on_plane}", + f"t_quat_world={t_quat_world}", + f"t_quat_local={t_quat_local}", + ] + ) + ) + self._emit_event( + GizmoEvent.DRAG_START, + { + "gizmo": "rotate", + "mode": self.drag_mode, + "axis": self.drag_axis, + "target": self.target_node, + "mouse": Point2(mpos.x, mpos.y), + "start_quat": self.start_quat, + "center": Point3(self.center_world), + "axis_world": Vec3(self.rotate_axis_world), + }, + ) + + def _on_mouse_up(self, extra=None): + self._update_ring_halves_visibility() + if self.dragging and self.target_node is not None: + try: + final_hpr = self.target_node.getHpr(self.world.render) + except Exception: + final_hpr = None + old_hpr = None + if self.start_quat is not None: + # 将起始四元数转换为 HPR(世界坐标系) + tmp_np = NodePath("tmp_quat_to_hpr") + tmp_np.reparentTo(self.world.render) + tmp_np.setQuat(self.world.render, self.start_quat) + old_hpr = tmp_np.getHpr(self.world.render) + tmp_np.removeNode() + + if old_hpr is not None and final_hpr is not None: + self._record_rotate_action( + self.target_node, old_hpr, final_hpr) + + mode = self.drag_mode + axis_id = self.drag_axis + self._emit_event( + GizmoEvent.DRAG_END, + { + "gizmo": "rotate", + "mode": mode, + "axis": axis_id, + "target": self.target_node, + "start_quat": self.start_quat, + "final_hpr": final_hpr if "final_hpr" in locals() else None, + }, + ) + self.dragging = False + self.drag_axis = None + self.drag_mode = None + self._trackball_start_vec = None + self._drag_root_quat_world = None + self._hide_angle_disc() + # 结束拖拽后恢复 Gizmo 与目标的对齐方式 + if self.is_local: + self.root.setHpr(self.root.parent, 0, 0, 0) + else: + self.root.setHpr(self.world.render, 0, 0, 0) + self._reset_highlights() + self._log("mouse_up -> stop rotating") + + def _on_mouse_move(self, extra=None): + if not self.attached or not self.camera: + return + + mpos = self._get_normalized_mouse(extra) + if mpos is None: + if self.dragging: + self._log("mouse_move ignored: no mouse pos while rotating") + return + + # Hover highlight when idle (not dragging). + if not self.dragging: + self._update_ring_halves_visibility() + self._update_hover_highlight(mpos) + return + + if not self.target_node: + return + + # 拖拽过程中持续更新半圆可见性与分割线朝向 + self._update_ring_halves_visibility() + + # 轨迹球模式:直接基于屏幕向量计算旋转 + if self.drag_mode == "trackball": + self._apply_trackball_rotation(mpos) + return + + lens: PerspectiveLens = self.camera.node().getLens() + p_from = Point3() + p_to = Point3() + if not lens.extrude(Point2(mpos.x, mpos.y), p_from, p_to): + self._log("mouse_move: lens.extrude failed") + return + + ray_origin = self.world.render.getRelativePoint(self.camera, p_from) + ray_to = self.world.render.getRelativePoint(self.camera, p_to) + ray_dir = ray_to - ray_origin + if ray_dir.length_squared() == 0: + return + ray_dir.normalize() + + # 与旋转平面求交:平面法线为当前轴向,过 Gizmo 中心 + axis_world = Vec3(self.rotate_axis_world) + if axis_world.length_squared() == 0: + return + axis_world.normalize() + + denom = ray_dir.dot(axis_world) + + # 判断是否处于边缘视角(grazing angle) + use_screen_space = abs(denom) < self._grazing_threshold + + if use_screen_space: + # 边缘视角:使用屏幕空间计算旋转角度 + delta_deg = self._calc_screen_space_angle(mpos) + curr_vec = None + if self.debug: + self._log( + f"grazing angle detected: denom={denom:.4f}, " + f"using screen space, delta_deg={delta_deg:.2f}" + ) + else: + # 正常视角:使用射线-平面交点计算 + t = (self.center_world - ray_origin).dot(axis_world) / denom + hit_point = ray_origin + ray_dir * t + curr_vec = hit_point - self.center_world + if curr_vec.length_squared() == 0: + return + curr_vec.normalize() + + # 计算 start_vec -> curr_vec 的有符号夹角(使用 atan2 提高数值稳定性) + s = self.start_vec_on_plane + dot = max(min(s.dot(curr_vec), 1.0), -1.0) + cross = s.cross(curr_vec) + angle_rad = math.atan2(cross.dot(axis_world), dot) + delta_deg = math.degrees(angle_rad) + + # 视图圈使用世界模式,轴向旋转也可根据 is_local 切换 + if self.drag_mode == "axis" and self.is_local: + # 本地模式:绕父坐标系下的轴旋转,保持与可见圆环一致。 + if self.drag_local_axis is None or self.start_quat_local is None: + return + q_delta = Quat() + q_delta.setFromAxisAngle(delta_deg, self.drag_local_axis) + if self.debug: + self._log( + f"[RotateGizmo] local q_delta={q_delta} delta_deg={delta_deg} axis_world={axis_world} axis_local={self.drag_local_axis}" + ) + new_quat_local = q_delta * self.start_quat_local + self.target_node.setQuat(new_quat_local) + else: + # 世界模式:绕固定的世界轴旋转,直接在世界坐标系应用。 + q_delta = Quat() + axis_for_world = self.start_root_axis_dir or axis_world + if axis_for_world.length_squared() == 0: + axis_for_world = axis_world + else: + axis_for_world.normalize() + q_delta.setFromAxisAngle(delta_deg, axis_for_world) + if self.debug: + self._log( + f"[RotateGizmo] world q_delta={q_delta} delta_deg={delta_deg} axis_world={axis_world}" + ) + new_quat_world = q_delta * self.start_quat + self.target_node.setQuat(self.world.render, new_quat_world) + + # 更新角度扇形可视化 + self._update_angle_visual(delta_deg) + # 拖拽时锁定 Gizmo 的世界朝向,避免扇形跟随目标旋转 + if self._drag_root_quat_world is not None: + self.root.setQuat(self.world.render, self._drag_root_quat_world) + + self._emit_event( + GizmoEvent.DRAG_MOVE, + { + "gizmo": "rotate", + "mode": self.drag_mode, + "axis": self.drag_axis, + "target": self.target_node, + "mouse": Point2(mpos.x, mpos.y), + "delta_deg": delta_deg, + }, + ) + + if self.debug: + if use_screen_space: + self._log( + f"rotate handle={self.drag_mode} angle={delta_deg:.2f} center={self.center_world} n={axis_world} (screen space)" + ) + else: + self._log( + f"rotate handle={self.drag_mode} axis={self.drag_axis} angle={delta_deg:.2f} " + f"center={self.center_world} n={axis_world} " + f"start_vec={self.start_vec_on_plane} curr_vec={curr_vec}" + ) + + def _update_hover_highlight(self, mpos: Point3): + """Highlight the hovered rotate handle without starting a drag.""" + self.picker_np.reparentTo(self.camera) + if not self._picker_added: + self.c_trav.addCollider(self.picker_np, self.c_queue) + self._picker_added = True + self.picker_ray.setFromLens(self.camera.node(), mpos.x, mpos.y) + + self.c_queue.clearEntries() + self.c_trav.traverse(self.root) + + num_entries = self.c_queue.getNumEntries() + if num_entries <= 0: + self._reset_highlights() + self.is_hovering = False + return + + self.c_queue.sortEntries() + + axis_entry: Optional[CollisionEntry] = None + trackball_entry: Optional[CollisionEntry] = None + for i in range(num_entries): + e = self.c_queue.getEntry(i) + axis_tag = e.getIntoNode().getTag("gizmo_axis") + handle_tag = e.getIntoNode().getTag("gizmo_handle") + if axis_tag: + axis_entry = e + break + if handle_tag == "trackball" and trackball_entry is None: + trackball_entry = e + + if axis_entry is not None: + self._highlight_axis(int(axis_entry.getIntoNode().getTag("gizmo_axis"))) + self.is_hovering = True + elif trackball_entry is not None: + self._highlight_axis("trackball") + self.is_hovering = True + else: + self._reset_highlights() + self.is_hovering = False + + # ------------------------------------------------------------------ # + # 高亮与更新 + # ------------------------------------------------------------------ # + def _highlight_axis(self, axis_id: Optional[int | str]): + """高亮指定的旋转手柄(轴 / 视图圈 / 轨迹球)。""" + if self.use_renderpipeline: + for i, ring in enumerate(self.rings): + node,color = self.ring_colors[i] + if i == axis_id: + node.get_material().base_color = color * self.color_higher + else: + node.get_material().base_color = color * self.color_normal + else: + for i, ring in enumerate(self.rings): + if i == axis_id: + ring.setColorScale(2, 2, 2, 1.0) + ring.setAlphaScale(1.0) + else: + ring.clearColorScale() + ring.setAlphaScale(0.3) + + if self.use_renderpipeline: + for idx, axis_np in enumerate(self.center_axes): + node,color = self.center_axes_colors[idx] + if axis_id == idx: + node.get_material().base_color = color * self.color_higher + else: + node.get_material().base_color = color * self.color_normal + else: + for idx, axis_np in enumerate(self.center_axes): + if axis_id == idx: + axis_np.setColorScale(1.5, 1.5, 1.5, 1.0) + else: + axis_np.clearColorScale() + + if self.trackball_np: + geom_np = self.trackball_np.find("**/trackball_geom") + if not geom_np.isEmpty(): + if axis_id == "trackball": + geom_np.show() + geom_np.setColorScale(self.highlight_color.x, self.highlight_color.y,self.highlight_color.z, 0.4) + if self.trackball_edge: + self.trackball_edge.setColorScale(self.highlight_color.x, self.highlight_color.y, self.highlight_color.z, 0.6) + else: + geom_np.hide() + if self.trackball_edge: + self.trackball_edge.setColorScale(self.trackball_edge_color) + + def _reset_highlights(self): + if self.use_renderpipeline: + for node,color in self.ring_colors: + node.get_material().base_color = color * self.color_normal + for node,color in self.center_axes_colors: + node.get_material().base_color = color * self.color_normal + else: + for ring in self.rings: + ring.clearColorScale() + ring.setAlphaScale(self.ring_alpha) + if self.trackball_edge: + self.trackball_edge.setColorScale(self.trackball_edge_color) + for axis_np in self.center_axes: + axis_np.clearColorScale() + + if self.trackball_np: + geom_np = self.trackball_np.find("**/trackball_geom") + if not geom_np.isEmpty(): + geom_np.hide() + + def update(self): + """根据摄像机距离自动缩放 Gizmo。""" + if self.world.mouseWatcherNode.has_mouse(): + current_mouse = LPoint2f(self.world.mouseWatcherNode.get_mouse()) + if current_mouse != self.last_mouse_pos or self.last_mouse_pos is None: + self._on_mouse_move() + self.last_mouse_pos = current_mouse + + if self.attached and self.camera: + self._update_root_transform() + # 持续调整半圆的可见性与分割线朝向 + self._update_ring_halves_visibility() + dist = ( + self.camera.getPos(self.world.render) + - self.root.getPos(self.world.render) + ).length() + scale = dist * 0.15 + self.root.setScale(self.world.render, scale) + + # print(f"target_node_hpr -> {self.target_node.getHpr()}") + + def _update_task(self, task: Task): + """每帧调用,用于持续更新 Gizmo 的缩放。""" + self.update() + return Task.cont + + # ------------------------------------------------------------------ # + # 内部:跟随目标更新根节点变换 + # ------------------------------------------------------------------ # + def _update_root_transform(self): + if not self.attached or not self.target_node: + return + render = self.world.render + tgt = self.target_node + self.root.setPos(render, tgt.getPos(render)) + # 拖拽过程中保持根节点朝向锁定,避免 gizmo 轴随目标旋转而跳动 + if self.dragging and self._drag_root_quat_world is not None: + self.root.setQuat(render, self._drag_root_quat_world) + else: + if self.is_local: + self.root.setQuat(render, tgt.getQuat(render)) + else: + self.root.setQuat(render, Quat.identQuat()) + + +__all__ = ["RotateGizmo"] diff --git a/TransformGizmo/scale_gizmo.py b/TransformGizmo/scale_gizmo.py new file mode 100644 index 0000000..4d5fdc2 --- /dev/null +++ b/TransformGizmo/scale_gizmo.py @@ -0,0 +1,1015 @@ +import math +from typing import Optional, Tuple, Callable, Dict, Any, List + +from panda3d.core import ( + NodePath, + Vec3, + Point3, + Point2, + Vec4, + Quat, + GeomNode, + GeomVertexFormat, + GeomVertexData, + GeomVertexWriter, + GeomTriangles, + GeomLines, + Geom, + CollisionNode, + CollisionRay, + CollisionHandlerQueue, + CollisionTraverser, + CollisionTube, + CollisionBox, + BitMask32, + PerspectiveLens, + Material, + LPoint2f +) +from direct.showbase.DirectObject import DirectObject +from direct.task import Task +from direct.task.TaskManagerGlobal import taskMgr +from direct.showbase.ShowBase import ShowBase + +from .events import GizmoEvent + + +""" +缩放控制柄(Scale Gizmo) +========================= + +功能概述: + - 模仿 Unity 的缩放控制柄,使用 3 个彩色轴线表示沿 X/Y/Z 轴缩放 + - X 轴:红色线条 + 方块(沿局部 X 轴缩放) + - Y 轴:绿色线条 + 方块(沿局部 Y 轴缩放) + - Z 轴:蓝色线条 + 方块(沿局部 Z 轴缩放) + - 中心有一个白色小方块,用于均匀缩放(沿所有轴同时缩放) + - 使用 Panda3D 的碰撞系统进行鼠标拾取与拖拽 + - 控件会根据摄像机距离自动缩放,屏幕大小保持近似不变 + +集成方式(示例): + from QPanda3D.Panda3DWorld import Panda3DWorld + from QPanda3DExamples.scale_gizmo import ScaleGizmo + + world = Panda3DWorld() + model_np = world.render.attachNewNode("Box") + # ... 在 model_np 下加载模型 + + gizmo = ScaleGizmo(world) # 创建缩放 Gizmo + gizmo.attach(model_np) # 绑定到某个模型 + + # 当需要切换目标时: + gizmo.attach(another_np) + + # 当不需要时,可隐藏: + gizmo.detach() + +鼠标事件要求: + - 本类默认监听 Panda3D 的 "mouse1" / "mouse1-up" / "mouse-move" 事件 + - 如果从 Qt / 自定义 UI 传递鼠标像素坐标,可以在发送事件时传入 extra 字典: + messenger.send("mouse1", [{"x": mouse_x, "y": mouse_y}]) + 本类会自动将像素坐标转换到 [-1, 1] 的标准化设备坐标 +""" + + +class ScaleGizmo(DirectObject): + """ + Unity 风格的缩放控制柄: + - 3 个轴线 + 方块分别代表沿局部 X/Y/Z 轴缩放 + - 中心方块代表均匀缩放 + - 左键点击并拖拽,可以缩放绑定的 NodePath + """ + + def __init__( + self, + world:ShowBase, + camera_np: NodePath | None = None, + on_action_committed: Optional[Callable[[Dict[str, Any]], None]] = None, + event_hooks: Optional[Dict[str, List[Callable[[Dict[str, Any]], None]]]] = None, + use_renderpipeline: bool = False + ): + super().__init__() + + self.world = world + self.is_local = True + self.debug: bool = False + self.is_hovering = False + self._picker_added: bool = False + self.use_renderpipeline = use_renderpipeline + self._debug_drag_counter: int = 0 + self.on_action_committed = on_action_committed + # Event hooks: drag_start / drag_move / drag_end + self._event_hooks = self._normalize_event_hooks(event_hooks) + + self.camera: Optional[NodePath] = camera_np or getattr( + world, "cam", None) + if not self.camera and hasattr(world, "base"): + self.camera = world.base.cam + if not self.camera: + self._log("No camera found for ScaleGizmo") + else: + self._log(f"Camera found for ScaleGizmo: {self.camera}") + + self.root: NodePath = NodePath("ScaleGizmo") + self.color_higher = 0.05 + self.color_normal = 0.01 + self.last_mouse_pos = None + # self.root.setBin("fixed", 40) + # self.root.setDepthTest(False) + # self.root.setDepthWrite(False) + # self.root.setLightOff() + + self.target_node: Optional[NodePath] = None + self.attached: bool = False + + # 控制柄视觉参数 + self.axis_length: float = 0.5 + self.axis_thickness: float = 0.02 + self.cube_size: float = 0.04 + self.center_cube_size: float = 0.06 + self.axis_alpha: float = 0.75 + # 记录基准尺寸,用于拖拽时的可视放缩 + self._axis_length0: float = self.axis_length + self._cube_size0: float = self.cube_size + self._center_cube_size0: float = self.center_cube_size + + # 拾取射线与碰撞系统 + self.picker_ray = CollisionRay() + self.picker_node = CollisionNode("scale_gizmo_picker_ray") + self.picker_node.addSolid(self.picker_ray) + self.picker_node.setFromCollideMask(BitMask32.bit(20)) + self.picker_node.setIntoCollideMask(BitMask32.allOff()) + self.picker_np: NodePath = NodePath(self.picker_node) + + self.c_trav = CollisionTraverser() + self.c_queue = CollisionHandlerQueue() + + # 拖拽状态 + self.dragging: bool = False + self.drag_axis: Optional[int] = None # 0=X, 1=Y, 2=Z, 3=Uniform + self.start_mouse: Optional[Point2] = None + self.start_scale: Optional[Vec3] = None + self.drag_axis_dir: Vec3 = Vec3(0, 0, 0) + self.drag_axis_screen: Point2 = Point2(1, 0) + self.drag_base_dist: float = 1.0 + self._start_param_on_ray: float = 0.0 + + # 撤销栈 + self._scale_undo_stack: list[Tuple[NodePath, Vec3, Vec3]] = [] + self._undo_scale_epsilon: float = 1e-4 + + # 轴和中心控制柄节点 + self.axes: list[NodePath] = [] + self.axes_colors: list[Tuple[NodePath,NodePath, Vec4]] = [] + # 可视节点(线与端点立方体),与碰撞体分离,便于单独放缩 + self.axis_visuals: list[Dict[str, NodePath]] = [] + self.axis_visual_colors: list[Tuple[NodePath, Vec4]] = [] + + self.center_handle: Optional[NodePath] = None + self.center_handle_color = Vec4(1,1,1,1) + + self._build_gizmo() + + self.root.reparentTo(self.world.render) + if not self.use_renderpipeline: + self.root.setBin('fixed',40) + self.root.setDepthTest(False) + self.root.setDepthWrite(False) + self.root.setLightOff() + self.root.hide() + + # taskMgr.add(self._update_task, "ScaleGizmoUpdateTask") + + def _log(self, msg: str): + if self.debug: + print(f"[ScaleGizmo] {msg}") + + def _normalize_event_hooks(self, hooks): + base = {name: [] for name in GizmoEvent.ALL} + if not hooks: + return base + for name in list(base.keys()): + cbs = hooks.get(name) + if cbs: + base[name] = list(cbs) + return base + + def _emit_event(self, name: str, payload: Dict[str, Any]): + handlers = self._event_hooks.get(name, []) + for cb in handlers: + try: + cb(payload) + except Exception as exc: + self._log(f"event hook '{name}' error: {exc}") + + def _build_gizmo(self): + """构建三个轴控制柄和中心均匀缩放控制柄。""" + # X 轴(红) + axis_root, line_np, cube_np = self._create_axis( + axis_dir=Vec3(1, 0, 0), + color=Vec4(1, 0, 0, 1), + length=self.axis_length, + thickness=self.axis_thickness, + cube_size=self.cube_size, + axis_id=0, + ) + self.axes.append(axis_root) + self.axis_visuals.append( + {"line": line_np, "cube": cube_np, "length": self.axis_length, "cube_size": self.cube_size} + ) + # Y 轴(绿) + axis_root, line_np, cube_np = self._create_axis( + axis_dir=Vec3(0, 1, 0), + color=Vec4(0, 1, 0, 1), + length=self.axis_length, + thickness=self.axis_thickness, + cube_size=self.cube_size, + axis_id=1, + ) + self.axes.append(axis_root) + self.axis_visuals.append( + {"line": line_np, "cube": cube_np, "length": self.axis_length, "cube_size": self.cube_size} + ) + # Z 轴(蓝) + axis_root, line_np, cube_np = self._create_axis( + axis_dir=Vec3(0, 0, 1), + color=Vec4(0, 0, 1, 1), + length=self.axis_length, + thickness=self.axis_thickness, + cube_size=self.cube_size, + axis_id=2, + ) + self.axes.append(axis_root) + self.axis_visuals.append({"line": line_np, "cube": cube_np, "length": self.axis_length, "cube_size": self.cube_size}) + # 中心控制柄(白色方块,用于均匀缩放) + self.center_handle = self._create_center_handle( + size=self.center_cube_size, + color=Vec4(1, 1, 1, 1), + ) + + def _set_node_dept(self,node:NodePath,color:Vec4 = None): + if node is None or node.is_empty():return + mat = Material('default') + mat.set_emission((1,0,1,1)) + if color: mat.base_color = color * self.color_normal + node.set_material(mat) + node.set_bin('fixed',40) + node.set_depth_test(False) + node.set_depth_write(False) + + def _create_axis( + self, + axis_dir: Vec3, + color: Vec4, + length: float, + thickness: float, + cube_size: float, + axis_id: int, + ) -> Tuple[NodePath, NodePath, NodePath]: + """创建一个轴控制柄:线条 + 末端方块。""" + axis_root = self.root.attachNewNode(f"scale_axis_{axis_id}") + + align_quat = self._quat_from_z(axis_dir) + axis_root.setQuat(align_quat) + + # 几何:线条 + line_geom = self._create_line_geom(length, color) + line_np: NodePath = axis_root.attachNewNode(line_geom) + line_np.setTransparency(True) + line_np.setAlphaScale(self.axis_alpha) + line_np_copy = line_np.copyTo(line_np) + line_np_copy.set_pos(0,0,0) + line_np_copy.set_hpr(0,0,0) + if self.use_renderpipeline: + self._set_node_dept(line_np_copy,color) + + # 几何:末端方块 + cube_geom = self._create_cube_geom(cube_size, color) + cube_np: NodePath = axis_root.attachNewNode(cube_geom) + cube_np.setPos(0, 0, length) + cube_np.setTransparency(True) + cube_np.setAlphaScale(self.axis_alpha) + cube_np_copy = cube_np.copy_to(cube_np) + cube_np_copy.set_pos(0,0,0) + cube_np_copy.set_hpr(0,0,0) + + if self.use_renderpipeline: + self._set_node_dept(cube_np_copy,color) + self.axes_colors.append((line_np_copy,cube_np_copy,color)) + + # 碰撞体:线条使用 Tube + c_node = CollisionNode(f"scale_axis_col_{axis_id}") + tube = CollisionTube(Point3(0, 0, 0), Point3(0, 0, length), thickness * 2) + c_node.addSolid(tube) + c_node.setIntoCollideMask(BitMask32.bit(20)) + c_node.setFromCollideMask(BitMask32.allOff()) + c_node.setTag("gizmo_axis", str(axis_id)) + axis_root.attachNewNode(c_node) + + # 碰撞体:末端方块 + c_cube_node = CollisionNode(f"scale_cube_col_{axis_id}") + half = cube_size * 0.5 + box = CollisionBox(Point3(0, 0, length), half, half, half) + c_cube_node.addSolid(box) + c_cube_node.setIntoCollideMask(BitMask32.bit(20)) + c_cube_node.setFromCollideMask(BitMask32.allOff()) + c_cube_node.setTag("gizmo_axis", str(axis_id)) + axis_root.attachNewNode(c_cube_node) + + return axis_root, line_np, cube_np + + def _create_center_handle(self, size: float, color: Vec4) -> NodePath: + """创建中心均匀缩放控制柄(方块)。""" + center_root = self.root.attachNewNode("scale_center") + + cube_geom = self._create_cube_geom(size, color) + cube_np: NodePath = center_root.attachNewNode(cube_geom) + cube_np.setTransparency(True) + cube_np.setAlphaScale(self.axis_alpha) + + if self.use_renderpipeline: + center_root.copy_to(center_root.get_parent()) + self._set_node_dept(center_root,color) + self.center_handle_color = color + + c_node = CollisionNode("scale_center_col") + half = size * 0.5 + box = CollisionBox(Point3(0, 0, 0), half, half, half) + c_node.addSolid(box) + c_node.setIntoCollideMask(BitMask32.bit(20)) + c_node.setFromCollideMask(BitMask32.allOff()) + c_node.setTag("gizmo_center", "1") + center_root.attachNewNode(c_node) + + return center_root + + def _create_line_geom(self, length: float, color: Vec4) -> GeomNode: + """创建一条沿 +Z 方向的线段几何。""" + vdata = GeomVertexData( + "line", GeomVertexFormat.getV3c4(), Geom.UHStatic) + vertex = GeomVertexWriter(vdata, "vertex") + vcolor = GeomVertexWriter(vdata, "color") + + vertex.addData3(0, 0, 0) + vcolor.addData4(color) + vertex.addData3(0, 0, length) + vcolor.addData4(color) + + prim = GeomLines(Geom.UHStatic) + prim.addVertices(0, 1) + + geom = Geom(vdata) + geom.addPrimitive(prim) + node = GeomNode("line_geom") + node.addGeom(geom) + return node + + def _create_cube_geom(self, size: float, color: Vec4) -> GeomNode: + """创建一个以原点为中心的立方体几何。""" + vdata = GeomVertexData( + "cube", GeomVertexFormat.getV3c4(), Geom.UHStatic) + vertex = GeomVertexWriter(vdata, "vertex") + vcolor = GeomVertexWriter(vdata, "color") + + half = size * 0.5 + + # 8个顶点 + vertices = [ + Point3(-half, -half, -half), # 0 + Point3(half, -half, -half), # 1 + Point3(half, half, -half), # 2 + Point3(-half, half, -half), # 3 + Point3(-half, -half, half), # 4 + Point3(half, -half, half), # 5 + Point3(half, half, half), # 6 + Point3(-half, half, half), # 7 + ] + + for v in vertices: + vertex.addData3(v) + vcolor.addData4(color) + + prim = GeomTriangles(Geom.UHStatic) + + # 6个面,每个面2个三角形 + faces = [ + (0, 1, 2, 3), # 底面 -Z + (4, 7, 6, 5), # 顶面 +Z + (0, 4, 5, 1), # 前面 -Y + (2, 6, 7, 3), # 后面 +Y + (0, 3, 7, 4), # 左面 -X + (1, 5, 6, 2), # 右面 +X + ] + + for f in faces: + prim.addVertices(f[0], f[1], f[2]) + prim.addVertices(f[0], f[2], f[3]) + + geom = Geom(vdata) + geom.addPrimitive(prim) + node = GeomNode("cube_geom") + node.addGeom(geom) + return node + + def _quat_from_z(self, direction: Vec3) -> Quat: + """返回一个四元数,使本地 +Z 旋转到指定 direction。""" + dir_norm = Vec3(direction) + if dir_norm.length_squared() == 0: + return Quat.identQuat() + dir_norm.normalize() + z_axis = Vec3(0, 0, 1) + dot = z_axis.dot(dir_norm) + if abs(dot - 1.0) < 1e-6: + return Quat.identQuat() + if abs(dot + 1.0) < 1e-6: + ortho = Vec3(1, 0, 0) if abs(z_axis.dot( + Vec3(1, 0, 0))) < 0.9 else Vec3(0, 1, 0) + axis = z_axis.cross(ortho) + axis.normalize() + q = Quat() + q.setFromAxisAngle(180.0, axis) + return q + axis = z_axis.cross(dir_norm) + axis_len = axis.length() + if axis_len == 0: + return Quat.identQuat() + axis.normalize() + angle_rad = math.atan2(axis_len, dot) + q = Quat() + q.setFromAxisAngle(math.degrees(angle_rad), axis) + return q + + def attach(self, node_path: NodePath): + """绑定控制柄到指定 NodePath。""" + if not node_path: + return + + self.target_node = node_path + self.attached = True + self._update_root_transform() + self.root.show() + self._log( + f"attached to {node_path.getName()} " + f"world_pos={self.root.getPos(self.world.render)} " + f"target_scale={node_path.getScale()}" + ) + self._register_events() + + def detach(self): + """解绑并隐藏 Gizmo。""" + self.target_node = None + self.root.hide() + self.attached = False + self.dragging = False + self.drag_axis = None + self._reset_axis_visuals() + self._ignore_events() + self._log("detached") + + def _record_scale_action(self, node: NodePath, old_scale: Vec3, new_scale: Vec3): + """将一次缩放操作压入撤销栈。""" + if node is None or node.isEmpty(): + return + if old_scale is None or new_scale is None: + return + + delta = new_scale - old_scale + if delta.length() < self._undo_scale_epsilon: + return + + old_copy = Vec3(old_scale) + new_copy = Vec3(new_scale) + self._scale_undo_stack.append((node, old_copy, new_copy)) + self._log( + f"record scale action: node={node.getName()} " + f"old_scale={old_copy} new_scale={new_copy} stack_size={len(self._scale_undo_stack)}" + ) + + if self.on_action_committed is not None: + try: + self.on_action_committed( + { + "kind": "scale", + "node": node, + "old_scale": Vec3(old_copy), + "new_scale": Vec3(new_copy), + } + ) + except Exception as exc: + self._log(f"on_action_committed(scale) error: {exc}") + + def undo_last_scale(self): + """撤销最近一次缩放操作。""" + if not self._scale_undo_stack: + self._log("undo_last_scale: stack empty") + return + node, old_scale, new_scale = self._scale_undo_stack.pop() + if node is None or node.isEmpty(): + self._log("undo_last_scale: target node invalid") + return + node.setScale(old_scale) + self._log( + f"undo_last_scale: node={node.getName()} " + f"old_scale={old_scale} new_scale={new_scale} remaining={len(self._scale_undo_stack)}" + ) + + def _register_events(self): + """注册鼠标事件监听。""" + self.accept("mouse1", self._on_mouse_down) + self.accept("mouse1-up", self._on_mouse_up) + self.accept("mouse2-up", self._on_mouse_up) + self.accept("mouse3-up", self._on_mouse_up) + self.accept("mouse-move", self._on_mouse_move) + self._log("event listeners registered (mouse)") + + def _ignore_events(self): + """取消事件监听。""" + self.ignore("mouse1") + self.ignore("mouse1-up") + self.ignore("mouse2-up") + self.ignore("mouse3-up") + self.ignore("mouse-move") + self._log("event listeners removed") + + def _get_normalized_mouse(self, extra) -> Optional[Point3]: + if self.world.mouseWatcherNode.hasMouse(): + mouse = self.world.mouseWatcherNode.getMouse() + return Point3(mouse.x, mouse.y, 0) + + """将鼠标转换到 Panda3D 的标准化设备坐标 [-1, 1]。""" + if isinstance(extra, dict) and "x" in extra and "y" in extra: + parent = getattr(self.world, "parent", None) + if parent is not None: + w = max(parent.width(), 1) + h = max(parent.height(), 1) + nx = (extra["x"] / w) * 2.0 - 1.0 + ny = 1.0 - (extra["y"] / h) * 2.0 + return Point3(nx, ny, 0.0) + + return None + + def _on_mouse_down(self, extra=None): + if not self.attached or not self.camera or self.target_node is None: + return + + mpos = self._get_normalized_mouse(extra) + if mpos is None: + self._log("mouse_down ignored: no mouse pos") + return + + self.picker_np.reparentTo(self.camera) + if not self._picker_added: + self.c_trav.addCollider(self.picker_np, self.c_queue) + self._picker_added = True + self.picker_ray.setFromLens(self.camera.node(), mpos.x, mpos.y) + + self.c_queue.clearEntries() + self.c_trav.traverse(self.root) + + self._log( + f"mouse_down mpos={mpos} cam_pos={self.camera.getPos(self.world.render)} " + f"entries={self.c_queue.getNumEntries()}" + ) + + num_entries = self.c_queue.getNumEntries() + if num_entries <= 0: + self._log("mouse_down: no collision entries on scale gizmo") + return + + self.c_queue.sortEntries() + + axis_entry = None + center_entry = None + for i in range(num_entries): + e = self.c_queue.getEntry(i) + if not center_entry and e.getIntoNode().getTag("gizmo_center"): + center_entry = e + if not axis_entry and e.getIntoNode().getTag("gizmo_axis"): + axis_entry = e + if center_entry and axis_entry: + break + + # 优先选择中心控制柄 + if center_entry is not None: + self.dragging = True + self.drag_axis = 3 # Uniform scale + self.start_scale = self.target_node.getScale() + self.start_mouse = Point2(mpos.x, mpos.y) + node_pos_w = self.target_node.getPos(self.world.render) + cam_pos = self.camera.getPos(self.world.render) + self.drag_base_dist = max((cam_pos - node_pos_w).length(), 0.5) + self._debug_drag_counter = 0 + self._highlight_center() + self._log( + f"pick center (uniform scale) target={self.target_node.getName()} " + f"start_scale={self.start_scale}" + ) + self._emit_event( + GizmoEvent.DRAG_START, + { + "gizmo": "scale", + "target": self.target_node, + "axis": self.drag_axis, + "mouse": Point2(mpos.x, mpos.y), + "start_scale": self.start_scale, + }, + ) + elif axis_entry is not None: + axis_tag: str = axis_entry.getIntoNode().getTag("gizmo_axis") + self.dragging = True + self.drag_axis = int(axis_tag) + self.start_scale = self.target_node.getScale() + self.start_mouse = Point2(mpos.x, mpos.y) + + axis_index = int(axis_tag) + axis_np: NodePath = self.axes[axis_index] + axis_dir: Vec3 = axis_np.getQuat( + self.world.render).xform(Vec3(0, 0, 1)) + if axis_dir.length_squared() == 0: + axis_dir = Vec3(0, 0, 1) + axis_dir.normalize() + self.drag_axis_dir = axis_dir + + cam_pos = self.camera.getPos(self.world.render) + node_pos_w = self.target_node.getPos(self.world.render) + lens: PerspectiveLens = self.camera.node().getLens() + self.drag_base_dist = max((cam_pos - node_pos_w).length(), 0.5) + + sample_len = max(self.drag_base_dist * 0.25, 0.25) + p0_cam = self.camera.getRelativePoint( + self.world.render, node_pos_w) + p1_cam = self.camera.getRelativePoint( + self.world.render, node_pos_w + axis_dir * sample_len + ) + p0_2d = Point2() + p1_2d = Point2() + # 注意:即使 lens.project 返回 False(点可能超出裁剪范围), + # 它仍然会填充 p0_2d/p1_2d,我们可以使用这些值来计算方向 + proj_ok_0 = lens.project(p0_cam, p0_2d) + proj_ok_1 = lens.project(p1_cam, p1_2d) + + # 无论 project 返回值如何,都尝试计算屏幕方向 + axis_screen_raw: Point2 = p1_2d - p0_2d + axis_screen_len = axis_screen_raw.length() + if axis_screen_len > 1e-6: + axis_screen = axis_screen_raw / axis_screen_len + else: + # 只有当投影长度真的为0时才使用默认值 + axis_screen = Point2(1, 0) + self.drag_axis_screen = axis_screen + self._axis_screen_len = axis_screen_len # 保存用于诊断 + + # 计算摄像机视线方向与轴的夹角(用于诊断) + view_dir = node_pos_w - cam_pos + if view_dir.length_squared() > 0: + view_dir.normalize() + axis_view_dot = abs(axis_dir.dot(view_dir)) + + self._debug_drag_counter = 0 + self._highlight_axis(self.drag_axis) + + # 诊断打印 + strer: list[str] = [] + strer.append(f"[ScaleGizmo DEBUG] ========== AXIS PICK ==========") + strer.append( + f" axis_id: {self.drag_axis} ({'XYZ'[self.drag_axis]})") + strer.append(f" axis_dir (world): {axis_dir}") + strer.append(f" cam_pos: {cam_pos}") + strer.append(f" node_pos: {node_pos_w}") + strer.append(f" view_dir: {view_dir}") + strer.append(f" axis_view_dot (|axis·view|): {axis_view_dot:.4f}") + strer.append(f" p0_cam: {p0_cam}, p1_cam: {p1_cam}") + strer.append(f" proj_ok: p0={proj_ok_0}, p1={proj_ok_1}") + strer.append(f" p0_2d: {p0_2d}, p1_2d: {p1_2d}") + strer.append( + f" axis_screen_raw: ({axis_screen_raw.x:.4f}, {axis_screen_raw.y:.4f})") + strer.append( + f" axis_screen_len (before normalize): {axis_screen_len:.6f}") + strer.append( + f" axis_screen (normalized): ({axis_screen.x:.4f}, {axis_screen.y:.4f})") + if axis_view_dot > 0.9: + strer.append( + f" WARNING: Axis nearly parallel to view direction!") + if axis_screen_len < 0.01: + strer.append(f" WARNING: Axis screen projection very short!") + strer.append(f" ==========================================") + self._log("\n".join(strer)) + + self._log( + f"pick axis={self.drag_axis} target={self.target_node.getName()} " + f"start_scale={self.start_scale} axis_dir={axis_dir}" + ) + self._emit_event( + GizmoEvent.DRAG_START, + { + "gizmo": "scale", + "target": self.target_node, + "axis": self.drag_axis, + "mouse": Point2(mpos.x, mpos.y), + "start_scale": self.start_scale, + }, + ) + else: + self._log( + "mouse_down: hit something but no gizmo_axis or gizmo_center tag") + + def _on_mouse_up(self, extra=None): + if self.dragging and self.target_node is not None: + try: + final_scale = self.target_node.getScale() + except Exception: + final_scale = None + old_scale = self.start_scale + if old_scale is not None and final_scale is not None: + self._record_scale_action( + self.target_node, old_scale, final_scale) + + axis_id = self.drag_axis + self._emit_event( + GizmoEvent.DRAG_END, + { + "gizmo": "scale", + "target": self.target_node, + "axis": axis_id, + "start_scale": old_scale, + "final_scale": final_scale, + }, + ) + self.dragging = False + self.drag_axis = None + self._reset_axis_visuals() + self._reset_highlights() + self._log("mouse_up -> stop scaling") + + def _on_mouse_move(self, extra=None): + if not self.attached or not self.camera: + return + + mpos = self._get_normalized_mouse(extra) + if mpos is None: + if self.dragging: + self._log("mouse_move ignored: no mouse pos while scaling") + return + + # Hover highlight when idle. + if not self.dragging: + self._update_hover_highlight(mpos) + return + + if not self.target_node: + return + + mouse_ndc = Point2(mpos.x, mpos.y) + delta = mouse_ndc - self.start_mouse + + if self.drag_axis == 3: + # 均匀缩放:基于鼠标在屏幕上的垂直移动 + scale_factor = 1.0 + delta.y * 2.0 + scale_factor = max(scale_factor, 0.01) # 防止负缩放 + new_scale = self.start_scale * scale_factor + self.target_node.setScale(new_scale) + + if self._debug_drag_counter % 4 == 0: + self._log( + f"uniform scale factor={scale_factor:.4f} " + f"new_scale={new_scale}" + ) + self._debug_drag_counter += 1 + self._emit_event( + GizmoEvent.DRAG_MOVE, + { + "gizmo": "scale", + "target": self.target_node, + "axis": self.drag_axis, + "mouse": Point2(mpos.x, mpos.y), + "new_scale": new_scale, + "scale_factor": scale_factor, + }, + ) + self._update_axis_visuals_for_scale(new_scale) + else: + # 单轴缩放 + s_scalar = delta.dot(self.drag_axis_screen) + scale_factor = 1.0 + s_scalar * 2.0 + scale_factor = max(scale_factor, 0.01) + + new_scale = Vec3(self.start_scale) + if self.drag_axis == 0: + new_scale.x = self.start_scale.x * scale_factor + elif self.drag_axis == 1: + new_scale.y = self.start_scale.y * scale_factor + elif self.drag_axis == 2: + new_scale.z = self.start_scale.z * scale_factor + + self.target_node.setScale(new_scale) + + # 诊断打印(每16帧打印一次,避免刷屏) + # if self._debug_drag_counter % 16 == 0: + # axis_screen_len = getattr(self, '_axis_screen_len', 0.0) + # print(f"[ScaleGizmo DRAG] axis={self.drag_axis}({'XYZ'[self.drag_axis]}) " + # f"delta=({delta.x:.4f}, {delta.y:.4f}) " + # f"axis_screen=({self.drag_axis_screen.x:.4f}, {self.drag_axis_screen.y:.4f}) " + # f"axis_screen_len={axis_screen_len:.4f} " + # f"s_scalar={s_scalar:.4f} " + # f"scale_factor={scale_factor:.4f}") + self._debug_drag_counter += 1 + self._emit_event( + GizmoEvent.DRAG_MOVE, + { + "gizmo": "scale", + "target": self.target_node, + "axis": self.drag_axis, + "mouse": Point2(mpos.x, mpos.y), + "new_scale": new_scale, + "scale_factor": scale_factor, + }, + ) + self._update_axis_visuals_for_scale(new_scale) + + def _update_hover_highlight(self, mpos: Point3): + """Highlight hovered handle during mouse move without dragging.""" + self.picker_np.reparentTo(self.camera) + if not self._picker_added: + self.c_trav.addCollider(self.picker_np, self.c_queue) + self._picker_added = True + self.picker_ray.setFromLens(self.camera.node(), mpos.x, mpos.y) + + self.c_queue.clearEntries() + self.c_trav.traverse(self.root) + + num_entries = self.c_queue.getNumEntries() + if num_entries <= 0: + self._reset_highlights() + self.is_hovering = False + return + + self.c_queue.sortEntries() + + axis_entry = None + center_entry = None + for i in range(num_entries): + e = self.c_queue.getEntry(i) + if center_entry is None and e.getIntoNode().getTag("gizmo_center"): + center_entry = e + if axis_entry is None and e.getIntoNode().getTag("gizmo_axis"): + axis_entry = e + if center_entry and axis_entry: + break + + if center_entry is not None: + self._highlight_center() + self.is_hovering = True + elif axis_entry is not None: + axis_tag: str = axis_entry.getIntoNode().getTag("gizmo_axis") + self._highlight_axis(int(axis_tag)) + self.is_hovering = True + else: + self._reset_highlights() + self.is_hovering = False + + def _highlight_axis(self, axis_id: Optional[int]): + """高亮被选中的轴。""" + if self.use_renderpipeline: + for i, ax in enumerate(self.axes): + line,node,color = self.axes_colors[i] + if i == axis_id: + line.get_material().base_color = color * self.color_higher + node.get_material().base_color = color * self.color_higher + else: + line.get_material().base_color = color * self.color_normal + node.get_material().base_color = color * self.color_normal + if self.center_handle: + self.center_handle.get_material().base_color = self.center_handle_color * self.color_normal + else: + for i, ax in enumerate(self.axes): + if i == axis_id: + ax.setColor(1, 1, 0, 1) + ax.clearColorScale() + else: + ax.clearColor() + ax.setAlphaScale(0.3) + if self.center_handle: + self.center_handle.setAlphaScale(0.3) + + def _highlight_center(self): + """高亮中心控制柄。""" + if self.use_renderpipeline: + for line,node,color in self.axes_colors: + line.get_material().base_color = color * self.color_normal + node.get_material().base_color = color * self.color_normal + if self.center_handle: + self.center_handle.get_material().base_color = self.center_handle_color * self.color_higher + else: + for ax in self.axes: + ax.clearColor() + ax.setAlphaScale(0.3) + if self.center_handle: + self.center_handle.setColor(1, 1, 0, 1) + self.center_handle.clearColorScale() + + def _reset_highlights(self): + """重置所有高亮。""" + if self.use_renderpipeline: + for line,node,color in self.axes_colors: + line.get_material().base_color = color * self.color_normal + node.get_material().base_color = color * self.color_normal + if self.center_handle: + self.center_handle.get_material().base_color = self.center_handle_color * self.color_normal + else: + for ax in self.axes: + ax.clearColor() + ax.clearColorScale() + ax.setAlphaScale(self.axis_alpha) + if self.center_handle: + self.center_handle.clearColor() + self.center_handle.clearColorScale() + self.center_handle.setAlphaScale(self.axis_alpha) + + # --- 可视轴动态长度 ------------------------------------------------- + def _set_axis_visual_factor(self, axis_id: int, factor: float): + """仅调整可视几何长度/末端大小,不改碰撞体。""" + if axis_id < 0 or axis_id >= len(self.axis_visuals): + return + info = self.axis_visuals[axis_id] + line = info.get("line") + cube = info.get("cube") + base_len = info.get("length", self._axis_length0) + base_cube = info.get("cube_size", self._cube_size0) + if line is None or cube is None: + return + factor = max(0.3, min(factor, 3.0)) + line.setScale(1, 1, factor) + cube.setZ(base_len * factor) + cube.setScale(factor) + + def _reset_axis_visuals(self): + """恢复所有轴的可视长度/端点大小。""" + for i in range(len(self.axis_visuals)): + self._set_axis_visual_factor(i, 1.0) + + def _update_axis_visuals_for_scale(self, new_scale: Vec3): + """根据当前缩放比例动态调整可视轴长度。""" + if self.start_scale is None: + return + + def safe_ratio(a: float, b: float) -> float: + return a / b if abs(b) > 1e-6 else 1.0 + + sx0, sy0, sz0 = self.start_scale + sx1, sy1, sz1 = new_scale + + if self.drag_axis == 3: + ratios = [] + if abs(sx0) > 1e-6: + ratios.append(sx1 / sx0) + if abs(sy0) > 1e-6: + ratios.append(sy1 / sy0) + if abs(sz0) > 1e-6: + ratios.append(sz1 / sz0) + if not ratios: + return + factor = sum(ratios) / len(ratios) + for i in range(3): + self._set_axis_visual_factor(i, factor) + elif self.drag_axis is not None and 0 <= self.drag_axis <= 2: + ratio = [safe_ratio(sx1, sx0), safe_ratio(sy1, sy0), safe_ratio(sz1, sz0)] + self._set_axis_visual_factor(self.drag_axis, ratio[self.drag_axis]) + + def update(self): + """根据摄像机距离自动缩放 Gizmo。""" + if self.world.mouseWatcherNode.has_mouse(): + current_mouse = LPoint2f(self.world.mouseWatcherNode.get_mouse()) + if current_mouse != self.last_mouse_pos or self.last_mouse_pos is None: + self._on_mouse_move() + self.last_mouse_pos = current_mouse + + if self.attached and self.camera: + self._update_root_transform() + dist = ( + self.camera.getPos(self.world.render) + - self.root.getPos(self.world.render) + ).length() + scale = dist * 0.15 + self.root.setScale(self.world.render, scale) + + def _update_task(self, task: Task): + """每帧调用,用于持续更新 Gizmo 的缩放。""" + self.update() + return Task.cont + + # ------------------------------------------------------------------ # + # 内部:跟随目标更新根节点变换 + # ------------------------------------------------------------------ # + def _update_root_transform(self): + if not self.attached or not self.target_node: + return + render = self.world.render + tgt = self.target_node + self.root.setPos(render, tgt.getPos(render)) + if self.is_local: + self.root.setQuat(render, tgt.getQuat(render)) + else: + self.root.setQuat(render, Quat.identQuat()) + + +__all__ = ["ScaleGizmo"] diff --git a/TransformGizmo/transform_gizmo.py b/TransformGizmo/transform_gizmo.py new file mode 100644 index 0000000..a386ab6 --- /dev/null +++ b/TransformGizmo/transform_gizmo.py @@ -0,0 +1,439 @@ +from __future__ import annotations + +import importlib +import importlib.util +from typing import Callable, Optional, List, Dict, Any + +from direct.task import Task +from panda3d.core import NodePath +from direct.showbase.DirectObject import DirectObject +from direct.showbase.ShowBase import ShowBase + +HAS_IMGUI = False +if importlib.util.find_spec("imgui_bundle"): + from imgui_bundle import imgui + HAS_IMGUI = True + +from .move_gizmo import MoveGizmo +from .rotate_gizmo import RotateGizmo +from .scale_gizmo import ScaleGizmo +from .events import GizmoEvent +import panda3d.core as p3d + + +class TransformGizmoMode: + """Simple string constants for gizmo modes.""" + + NONE = "none" + MOVE = "move" + ROTATE = "rotate" + SCALE = "scale" # reserved for future implementation + ALL = "all" # move + rotate together (matches existing UI semantics) + + +class TransformGizmo(DirectObject): + """ + A unified Transform Gizmo wrapper for Panda3D. + + It internally manages: + - MoveGizmo (translation) + - RotateGizmo (rotation) + + and exposes a single API to: + - attach / detach to a target NodePath + - switch transform mode: move / rotate / all / none + - forward undo operations for move / rotate + + Typical usage: + + world = Panda3DWorld() + gizmo = TransformGizmo(world) + gizmo.set_mode(TransformGizmoMode.MOVE) + gizmo.attach(some_node) + + # Later: + gizmo.set_mode(TransformGizmoMode.ROTATE) + gizmo.attach(other_node) + """ + + def __init__( + self, + world: ShowBase, + camera_np: Optional[NodePath] = None, + on_action_handler_changed: Optional[Callable[[str], None]] = None, + event_hooks: Optional[Dict[str, Dict[str, List[Callable[[Dict[str, Any]], None]]]]] = None, + use_renderpipeline: bool = False + ): + super().__init__() + + self.world = world + self.__debug: bool = False + self.enabled: bool = True + self.on_action_handler_changed = on_action_handler_changed + + # Try to reuse the same camera for all internal gizmos + self.camera: Optional[NodePath] = camera_np or getattr( + world, "cam", None) + if not self.camera and hasattr(world, "base"): + self.camera = world.base.cam + + # Global history stack of transform actions pushed by sub gizmos. + # Each entry is a dict, e.g.: + # {"kind": "move", "node": node, "old_pos": Vec3, "new_pos": Vec3} + # {"kind": "rotate", "node": node, "old_hpr": Vec3, "new_hpr": Vec3} + self._history: List[Dict[str, Any]] = [] + self._event_hooks = event_hooks or {} + + # Internal gizmos – they report actions back via a callback so that + # TransformGizmo can build a unified, time-ordered undo stack. + if not use_renderpipeline: + self.overlay_cam = None + self.last_cam_transform: Optional[p3d.LMatrix4f] = None + self._setup_overlay_rendering() + + self.move_gizmo = MoveGizmo( + self.world, + self.overlay_cam_np if not use_renderpipeline else None, + on_action_committed=self._on_subgizmo_action, + event_hooks=self._extract_event_hooks(TransformGizmoMode.MOVE), + use_renderpipeline=use_renderpipeline + ) + self.rotate_gizmo = RotateGizmo( + self.world, + self.overlay_cam_np if not use_renderpipeline else None, + on_action_committed=self._on_subgizmo_action, + event_hooks=self._extract_event_hooks(TransformGizmoMode.ROTATE), + use_renderpipeline=use_renderpipeline + ) + self.scale_gizmo = ScaleGizmo( + self.world, + self.overlay_cam_np if not use_renderpipeline else None, + on_action_committed=self._on_subgizmo_action, + event_hooks=self._extract_event_hooks(TransformGizmoMode.SCALE), + use_renderpipeline=use_renderpipeline + ) + + if not use_renderpipeline: + self.move_gizmo.root.reparentTo(self.gizmo_render) + self.rotate_gizmo.root.reparentTo(self.gizmo_render) + self.scale_gizmo.root.reparentTo(self.gizmo_render) + + # Keep debug flag consistent across all gizmos + self.move_gizmo.debug = self.__debug + self.rotate_gizmo.debug = self.__debug + self.scale_gizmo.debug = self.__debug + + # Current attached target and mode + self.target_node: Optional[NodePath] = None + self.__mode: str = TransformGizmoMode.MOVE + # Fine-grained switch for each handle type; combined with mode below. + self._handle_enabled: Dict[str, bool] = { + TransformGizmoMode.MOVE: True, + TransformGizmoMode.ROTATE: True, + TransformGizmoMode.SCALE: True, + } + # Track right mouse button so that when RMB is held + # (used by CameraOrbitController for free-look + WASD fly), + # we ignore W/E/R transform hotkeys, matching Unity behaviour. + self._rmb_down: bool = False + + # Register global undo shortcut: Ctrl+Z (Qt) -> 'control-z' (Panda3D) + self.accept("control-z", self.undo_last) + # Mode switch hotkeys (Unity style), but disabled while RMB is pressed. + self.accept("w", self._on_key_w) + self.accept("e", self._on_key_e) + self.accept("r", self._on_key_r) + # Track right mouse button state. + self.accept("mouse2", self._on_mouse2_down) + self.accept("mouse2-up", self._on_mouse2_up) + self.world.task_mgr.add(self._update_task, "transform_gizmo_update") + + def _setup_overlay_rendering(self): + """ + 创建独立的3D渲染场景用于Gizmo,完全绕过RenderPipeline后处理。 + + 原理: + - 创建一个独立的render场景(gizmo_render),不属于主render场景 + - 创建一个Sort值极高的DisplayRegion,在RP完成后渲染 + - 由于Gizmo不在主render下,RenderPipeline完全不会处理它 + - overlay相机与主相机同步变换,保持透视效果一致 + """ + if not hasattr(self.world, 'win') or self.world.win is None: + raise RuntimeError("No world showbase.win found") + # 创建独立的Gizmo渲染场景(不在主render下,RP不会处理) + self.gizmo_render = NodePath("gizmo_render") + # 创建高Sort值的DisplayRegion + self.overlay_dr = self.world.win.makeDisplayRegion() + self.overlay_dr.setSort(8) # 极高值,确保在RP后处理之后 + + self.overlay_dr.setClearColorActive(False) # 透明背景,保留3D画面 + self.overlay_dr.setClearDepthActive(True) # 清除深度,Gizmo始终在前 + # 创建overlay专用相机 + self.overlay_cam = p3d.Camera("gizmo_overlay_cam") + self.overlay_cam.setLens(self.world.camLens) # 共享主相机镜头 + self.overlay_cam.setScene(self.gizmo_render) # 渲染gizmo_render场景 + # 创建相机节点(独立于主相机,但会同步变换) + self.overlay_cam_np = self.gizmo_render.attachNewNode(self.overlay_cam) + self.overlay_dr.setCamera(self.overlay_cam_np) + # 每帧同步overlay相机位置到主相机 + from direct.task.TaskManagerGlobal import taskMgr + taskMgr.add(self._sync_overlay_camera, "GizmoOverlayCameraSync") + + def _sync_overlay_camera(self, task:Task): + """每帧同步overlay相机变换到主相机。""" + curr = self.world.camera.getTransform(self.world.render) + if self.overlay_cam_np and self.last_cam_transform != curr: + # 从主相机获取世界坐标变换,应用到overlay相机 + self.overlay_cam_np.setTransform(curr) + self.last_cam_transform = curr + return task.cont + + def _update_task(self,task:Task): + if HAS_IMGUI: + io = imgui.get_io() + if io.want_capture_mouse: + return task.cont + + self.move_gizmo.update() + self.rotate_gizmo.update() + self.scale_gizmo.update() + return task.cont + + @property + def is_hovering(self)->bool: + return self.move_gizmo.is_hovering or self.rotate_gizmo.is_hovering or self.scale_gizmo.is_hovering + + # ------------------------------------------------------------------ # + # Public API + # ------------------------------------------------------------------ # + def set_debug(self, enabled: bool) -> None: + """Enable / disable debug logs for all internal gizmos.""" + self.__debug = bool(enabled) + self.move_gizmo.debug = self.__debug + self.rotate_gizmo.debug = self.__debug + self.scale_gizmo.debug = self.__debug + + def attach(self, node_path: NodePath) -> None: + """ + Attach the transform gizmo to a target node. + + Only the gizmos corresponding to the current mode will be attached. + """ + if not node_path or not self.enabled: + return + + self.target_node = node_path + self._apply_mode_to_subgizmos() + + def detach(self) -> None: + """ + Detach from the current target and hide all gizmos. + """ + self.target_node = None + # Detach all sub gizmos to ensure they stop listening to events + self.move_gizmo.detach() + self.rotate_gizmo.detach() + self.scale_gizmo.detach() + + def set_handles_enabled( + self, + *, + move: Optional[bool] = False, + rotate: Optional[bool] = False, + scale: Optional[bool] = False, + ) -> None: + """ + Enable / disable each handle type independently of the current mode. + + Args: + move: True/False to enable/disable move handle; None keeps current. + rotate: True/False to enable/disable rotate handle; None keeps current. + scale: True/False to enable/disable scale handle; None keeps current. + + Example: + gizmo.set_mode(TransformGizmoMode.ALL) + gizmo.set_handles_enabled(move=True, rotate=False, scale=False) + # => only move handle stays active even though mode is ALL. + """ + changed = False + if move is not None: + new_val = bool(move) + if self._handle_enabled[TransformGizmoMode.MOVE] != new_val: + self._handle_enabled[TransformGizmoMode.MOVE] = new_val + changed = True + if rotate is not None: + new_val = bool(rotate) + if self._handle_enabled[TransformGizmoMode.ROTATE] != new_val: + self._handle_enabled[TransformGizmoMode.ROTATE] = new_val + changed = True + if scale is not None: + new_val = bool(scale) + if self._handle_enabled[TransformGizmoMode.SCALE] != new_val: + self._handle_enabled[TransformGizmoMode.SCALE] = new_val + changed = True + + # Re-attach handles to reflect the new mask if we already have a target. + if changed and self.target_node is not None: + self._apply_mode_to_subgizmos() + + def get_handles_enabled(self) -> Dict[str, bool]: + """Return current per-handle enable states.""" + return dict(self._handle_enabled) + + def set_mode(self, mode: str) -> None: + """ + Set current transform mode. + + Supported values (see TransformGizmoMode): + - "move" + - "rotate" + - "all" (move + rotate) + - "none" + - "scale" (reserved, not implemented yet) + """ + mode = (mode or "").lower() + if mode not in { + TransformGizmoMode.NONE, + TransformGizmoMode.MOVE, + TransformGizmoMode.ROTATE, + TransformGizmoMode.SCALE, + TransformGizmoMode.ALL, + }: + raise ValueError(f"Unsupported gizmo mode: {mode}") + + if mode == self.__mode: + return + + self.__mode = mode + self._apply_mode_to_subgizmos() + if self.on_action_handler_changed is not None: + self.on_action_handler_changed(self.__mode) + + def get_mode(self) -> str: + """Return current mode as a string.""" + return self.__mode + + def undo_last(self) -> None: + """ + Undo the most recent transform operation (move or rotate), + regardless of current mode. + """ + if not self._history: + return + + action = self._history.pop() + kind = action.get("kind") + node: NodePath = action.get("node") + if node is None or node.isEmpty(): + return + + if kind == "move": + old_pos = action.get("old_pos") + if old_pos is not None: + node.setPos(self.world.render, old_pos) + elif kind == "rotate": + old_hpr = action.get("old_hpr") + if old_hpr is not None: + node.setHpr(self.world.render, old_hpr) + elif kind == "scale": + old_scale = action.get("old_scale") + if old_scale is not None: + node.setScale(old_scale) + + def update(self) -> None: + """ + Forward update to internal gizmos. + + Both MoveGizmo and RotateGizmo already have their own Panda3D + tasks to keep screen-size scaling; this is provided mainly for + explicit/manual calls if needed. + """ + self.move_gizmo.update() + self.rotate_gizmo.update() + self.scale_gizmo.update() + + # ------------------------------------------------------------------ # + # Internal helpers + # ------------------------------------------------------------------ # + def _extract_event_hooks(self, key: str) -> Dict[str, List[Callable[[Dict[str, Any]], None]]]: + """Return per-gizmo event hooks (drag_start / drag_move / drag_end).""" + base = {name: [] for name in GizmoEvent.ALL} + if not self._event_hooks: + return base + sub = self._event_hooks.get(key) or self._event_hooks.get(key.lower()) + if not isinstance(sub, dict): + return base + for name in list(base.keys()): + cbs = sub.get(name) + if cbs: + base[name] = list(cbs) + return base + + def _apply_mode_to_subgizmos(self) -> None: + """ + Attach / detach internal gizmos based on current mode and target. + """ + # Always detach first to ensure we don't keep stale event listeners. + self.move_gizmo.detach() + self.rotate_gizmo.detach() + self.scale_gizmo.detach() + + if self.target_node is None: + return + + if self.__mode in (TransformGizmoMode.MOVE, TransformGizmoMode.ALL) and self._handle_enabled.get(TransformGizmoMode.MOVE, True): + self.move_gizmo.attach(self.target_node) + + if self.__mode in (TransformGizmoMode.ROTATE, TransformGizmoMode.ALL) and self._handle_enabled.get(TransformGizmoMode.ROTATE, True): + self.rotate_gizmo.attach(self.target_node) + + if self.__mode in (TransformGizmoMode.SCALE, TransformGizmoMode.ALL) and self._handle_enabled.get(TransformGizmoMode.SCALE, True): + self.scale_gizmo.attach(self.target_node) + + def _on_subgizmo_action(self, action: Dict[str, Any]) -> None: + """ + Callback used by MoveGizmo / RotateGizmo / ScaleGizmo to report that a + transform action (move/rotate/scale) has been committed. + """ + self._history.append(action) + + # ------------------------------------------------------------------ # + # Input helpers (hotkeys / mouse states) + # ------------------------------------------------------------------ # + def _on_mouse2_down(self, extra=None) -> None: + """Right mouse button pressed: used by camera controller for fly mode.""" + self._rmb_down = True + + def _on_mouse2_up(self, extra=None) -> None: + """Right mouse button released.""" + self._rmb_down = False + + def _on_key_w(self, *args) -> None: + """Switch to Move mode unless RMB is held (camera fly).""" + if self._rmb_down: + return + if HAS_IMGUI: + io = imgui.get_io() + if io.want_capture_mouse: return + self.set_mode(TransformGizmoMode.MOVE) + + def _on_key_e(self, *args) -> None: + """Switch to Rotate mode unless RMB is held (camera fly).""" + if self._rmb_down: + return + if HAS_IMGUI: + io = imgui.get_io() + if io.want_capture_mouse: return + self.set_mode(TransformGizmoMode.ROTATE) + + def _on_key_r(self, *args) -> None: + """Switch to Scale mode unless RMB is held (camera fly).""" + if self._rmb_down: + return + if HAS_IMGUI: + io = imgui.get_io() + if io.want_capture_mouse: return + self.set_mode(TransformGizmoMode.SCALE) + + +__all__ = ["TransformGizmo", "TransformGizmoMode"] diff --git a/__init__.py b/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/assets/Fox.glb b/assets/Fox.glb new file mode 100644 index 0000000..1ef5c0d Binary files /dev/null and b/assets/Fox.glb differ diff --git a/assets/icons/model-color.png b/assets/icons/model-color.png new file mode 100644 index 0000000..6556c08 Binary files /dev/null and b/assets/icons/model-color.png differ diff --git a/classes/colors.py b/classes/colors.py new file mode 100644 index 0000000..1436d6b --- /dev/null +++ b/classes/colors.py @@ -0,0 +1,79 @@ +# src/tools/color.py +import panda3d.core as p3d + + +class Color: + """ + Unity-style color utility for Panda3D. + Usage: + from src.tools.color import Color + np.setColor(Color.red) + np.setColor(Color.from_hex("#FF8800")) + """ + + # --- Basic colors --- + clear = p3d.Vec4(0, 0, 0, 0) + black = p3d.Vec4(0, 0, 0, 1) + white = p3d.Vec4(1, 1, 1, 1) + + red = p3d.Vec4(1, 0, 0, 1) + green = p3d.Vec4(0, 1, 0, 1) + blue = p3d.Vec4(0, 0, 1, 1) + + yellow = p3d.Vec4(1, 1, 0, 1) + cyan = p3d.Vec4(0, 1, 1, 1) + magenta = p3d.Vec4(1, 0, 1, 1) + + gray = p3d.Vec4(0.5, 0.5, 0.5, 1) + grey = gray # alias + + # --- Extra common colors --- + orange = p3d.Vec4(1.0, 0.5, 0.0, 1) + purple = p3d.Vec4(0.5, 0.0, 0.5, 1) + pink = p3d.Vec4(1.0, 0.4, 0.7, 1) + brown = p3d.Vec4(0.6, 0.3, 0.1, 1) + + @staticmethod + def rgba(r: float, g: float, b: float, a: float = 1.0) -> p3d.Vec4: + """Create a Vec4 from 0~1 floats.""" + return p3d.Vec4(r, g, b, a) + + @staticmethod + def rgb255(r: int, g: int, b: int, a: int = 255) -> p3d.Vec4: + """Create a Vec4 from 0~255 ints.""" + return p3d.Vec4(r / 255.0, g / 255.0, b / 255.0, a / 255.0) + + @staticmethod + def from_hex(hex_str: str) -> p3d.Vec4: + """ + Parse hex color: "#RRGGBB" or "#RRGGBBAA" + Also supports "RRGGBB" / "RRGGBBAA" + """ + s = hex_str.strip().lstrip("#") + if len(s) not in (6, 8): + raise ValueError("hex must be RRGGBB or RRGGBBAA") + + r = int(s[0:2], 16) + g = int(s[2:4], 16) + b = int(s[4:6], 16) + a = int(s[6:8], 16) if len(s) == 8 else 255 + return Color.rgb255(r, g, b, a) + + @staticmethod + def with_alpha(c: p3d.Vec4, a: float) -> p3d.Vec4: + """Return a copy with modified alpha.""" + return p3d.Vec4(c.x, c.y, c.z, a) + + @staticmethod + def lerp(a: p3d.Vec4, b: p3d.Vec4, t: float) -> p3d.Vec4: + """Linear interpolation between two colors (t in [0,1]).""" + t = max(0.0, min(1.0, t)) + return a * (1.0 - t) + b * t + + @staticmethod + def to_vec4(c: p3d.Vec4) -> p3d.Vec4: + """ + Return a copy (useful if you worry about accidental mutation + of the static constants). + """ + return p3d.Vec4(c) diff --git a/classes/cornerBBox.py b/classes/cornerBBox.py new file mode 100644 index 0000000..456ef95 --- /dev/null +++ b/classes/cornerBBox.py @@ -0,0 +1,141 @@ +import direct +import direct.showbase +import direct.showbase.ShowBaseGlobal +from panda3d.core import ( + Geom, + GeomLines, + GeomNode, + GeomVertexData, + GeomVertexFormat, + GeomVertexWriter, + LColor, + LPoint3, + NodePath +) +import panda3d.core as p3d + +class CornerBBox: + def __init__( + self, + target: NodePath, + color: tuple = (0.5, 0, 0.5, 1), + corner_offset: float = 0.52, + stub_scale: float = 0.075, + line_thickness: float = 2.0, + parent: NodePath | None = None + ) -> None: + """ + 创建一个“角点风格”的包围盒可视化框。 + + :param target: 要描框的 NodePath + :param color: 线颜色 (r, g, b, a) + :param corner_offset: 角点在包围盒外扩的偏移,决定框外伸出的长度 + :param stub_scale: 每个角三条小线的比例(实际使用两段:stub 和 3*stub + stub) + :param line_thickness: 线粗细 + :param parent: 框的挂载节点,默认与 target 同级父节点 + """ + self.world = direct.showbase.ShowBaseGlobal.base + self.target = target + self.parent = parent or target + self.color = LColor(*color) + self.corner_offset = corner_offset + self.stub_scale = stub_scale + self.line_thickness = line_thickness + self.np = self._build_geom() + self.update() # 初始化尺寸/位置 + + def _build_geom(self) -> NodePath: + """构造“八角+三向短线”几何体""" + fmt = GeomVertexFormat.get_v3c4() + vdata = GeomVertexData("corner_bbox", fmt, Geom.UH_static) + pos_w = GeomVertexWriter(vdata, "vertex") + col_w = GeomVertexWriter(vdata, "color") + lines = GeomLines(Geom.UH_static) + + # 定义 8 个角(基于偏移量 m) + m = self.corner_offset + corners = [(x, y, z) for x in (-m, m) for y in (-m, m) for z in (-m, m)] + + for corner in corners: + cx, cy, cz = corner + for axis_idx, coord in enumerate((cx, cy, cz)): + sign = -1.0 if coord > 0 else 1.0 + # 两段短线:长度分别为 stub_scale 和 3 * stub_scale + offset1 = self.stub_scale * sign + offset2 = (3.0 * self.stub_scale + self.stub_scale) * sign + + base = list(corner) + + # 第一段线:从角点到第一个 stub + p1 = LPoint3(*base) + pos_w.add_data3(p1) + col_w.add_data4(self.color) + + base[axis_idx] = coord + offset1 + p2 = LPoint3(*base) + pos_w.add_data3(p2) + col_w.add_data4(self.color) + lines.add_next_vertices(2) + + # 第二段线:从第一个 stub 到更远的 stub + base[axis_idx] = coord + offset2 + p3 = LPoint3(*base) + pos_w.add_data3(p2) # 重复起点 + col_w.add_data4(self.color) + pos_w.add_data3(p3) + col_w.add_data4(self.color) + lines.add_next_vertices(2) + + geom = Geom(vdata) + geom.add_primitive(lines) + node = GeomNode("corner_bbox") + node.add_geom(geom) + np = self.parent.attach_new_node(node) + + # 渲染设置 + np.set_light_off() + np.set_texture_off() + np.set_color_off(False) # 保留顶点色 + np.set_render_mode_thickness(self.line_thickness) + + mat = p3d.Material('unlit') + np.setMaterial(mat) + + return np + + def update(self) -> None: + """根据 target 的 tight bounds 更新包围框的位置/缩放。""" + if not self.world or self.target.is_empty() or self.np is None: + return + + render = self.world.render + + # 统一在 render 坐标系下保存/恢复 + last_hpr = self.target.getHpr(render) + + try: + # 暂时归零朝向 + self.target.setHpr(render, 0, 0, 0) + + bmin, bmax = self.target.get_tight_bounds(render) + if not bmin or not bmax: + return + + size = bmax - bmin + center = (bmin + bmax) * 0.5 + + # bbox 挂在 parent 下,但变换以 render 为参照设置,避免坐标系错乱 + self.np.set_pos(render, center) + self.np.set_scale(render, size) + + finally: + # 无论成功与否都必须恢复 target 姿态 + self.target.setHpr(render, last_hpr) + + + def remove(self) -> None: + """从场景图中移除该包围框。""" + if self.np is None: + return + self.np.detach_node() + self.np = None \ No newline at end of file diff --git a/classes/gameobject.py b/classes/gameobject.py new file mode 100644 index 0000000..be080ad --- /dev/null +++ b/classes/gameobject.py @@ -0,0 +1,90 @@ +import direct +import direct.showbase +import direct.showbase.ShowBaseGlobal +import panda3d.core as p3d +from direct.showbase.ShowBase import ShowBase +from panda3d.core import NodePath + +class GameObject(NodePath): + def __init__(self, model: NodePath): + self = model + self.gameobject = self + self.self_active = self.is_hidden() + + def set_active(self, active: bool): + if active:self.show() + else:self.hide() + + @classmethod + def create_panel(self) -> NodePath: + base = direct.showbase.ShowBaseGlobal.base + if not base or not base.render: + raise Exception("base or base.render is None") + from panda3d.core import CardMaker + cm = CardMaker("ground") + cm.set_frame(-10, 10, -10, 10) # (left, right, bottom, top) + plane_np = base.render.attach_new_node(cm.generate()) + plane_np.set_hpr(0, -90, 0) # 躺平(默认是 XY 平面,朝 +Z) + plane_np.setTwoSided(True) + mat = p3d.Material('unlit') + plane_np.set_material(mat) + return plane_np + + @classmethod + def set_model_auto_scale(self, model: NodePath,debug_info = False): + base = direct.showbase.ShowBaseGlobal.base + if not base or not base.render: + raise Exception("base or base.render is None") + + if not model or model.is_empty(): + return + + bmin, bmax = model.get_tight_bounds(base.render) + if bmin is None or bmax is None: + return + + size = bmax - bmin + max_size = max(size.x, size.y, size.z) + + if max_size <= 0: + return + + # 目标:让最大边缩放到略小于 10,比如 9.9 + target_max = 3 + scale_factor = target_max / max_size + + model.set_scale(scale_factor) + + if debug_info: + print(f"自动缩放:原最大尺寸={max_size:.3f} → 缩放因子={scale_factor:.6f}") + + @classmethod + def get_node_type(self,np: NodePath) -> str: + node = np.node() + + if isinstance(node, p3d.GeomNode): + return "mesh(GeomNode)" + if isinstance(node, p3d.CollisionNode): + return "collision(CollisionNode)" + if isinstance(node, p3d.Camera): + return "camera" + if isinstance(node, p3d.Light): + return "light" + if isinstance(node, p3d.TextNode): + return "text" + + # 不同节点可能是模型根、LOD根等,但核心是:是否包含 Geom/Collision + if not np.find("**/+GeomNode").isEmpty(): + return "empty*" + if not np.find("**/+CollisionNode").isEmpty(): + return "collision_parent*" + return "empty" + + @classmethod + def get_child_name(self,node:NodePath): + if not node or node.isEmpty() or node.getNumChildren() == 0:return + for n in node.getChildren(): + print(f"{n.getName()} -> {GameObject.get_node_type(n)}") + GameObject.get_child_name(n) + + return f"empty/transform({node.getType().getName()})" \ No newline at end of file diff --git a/classes/json_scene_tree.py b/classes/json_scene_tree.py new file mode 100644 index 0000000..eed9865 --- /dev/null +++ b/classes/json_scene_tree.py @@ -0,0 +1,51 @@ +import json +import panda3d.core as p3d +from typing import List + +class TreeInfo: + def __init__(self, root: p3d.NodePath): + self.name = root.getName() + self.root = root + self.type = self.classify_np(root) + self.childs: List[TreeInfo] = [] + self._build_children() + + def classify_np(self,np: p3d.NodePath) -> str: + node = np.node() + + if isinstance(node, p3d.GeomNode): + return "mesh(GeomNode)" + if isinstance(node, p3d.CollisionNode): + return "collision(CollisionNode)" + if isinstance(node, p3d.Camera): + return "camera" + if isinstance(node, p3d.Light): + return "light" + if isinstance(node, p3d.TextNode): + return "text" + + # 不同节点可能是模型根、LOD根等,但核心是:是否包含 Geom/Collision + if not np.find("**/+GeomNode").isEmpty(): + return "model(has GeomNode children)" + if not np.find("**/+CollisionNode").isEmpty(): + return "collision_parent(has CollisionNode children)" + + def _build_children(self): + if not self.root or self.root.isEmpty(): + return + for child in self.root.getChildren(): + child_info = TreeInfo(child) # 递归构建子树 + self.childs.append(child_info) + + def to_dict(self): + return { + "name": self.name, + "type": self.type or "", + "children": [child.to_dict() for child in self.childs], + } + + def save_tree_json(self,path: str): + """保存树的 name/type 结构为 JSON。""" + data = self.to_dict() + with open(path, "w", encoding="utf-8") as f: + json.dump(data, f, ensure_ascii=False, indent=2) \ No newline at end of file diff --git a/classes/lights.py b/classes/lights.py new file mode 100644 index 0000000..40bab19 --- /dev/null +++ b/classes/lights.py @@ -0,0 +1,22 @@ +class Lights(): + def __init__(self): + pass + # self.ambient = self.render.attach_new_node(p3d.AmbientLight('ambient')) + # self.ambient.node().set_color((.2, .2, .2,.2)) + # self.render.set_light(self.ambient) + + # point = p3d.PointLight('lamp') + # point.set_color((1, 0.9, 0.7, 1)) + # point.set_attenuation((1, 0.1, 0.01)) # 常数/线性/二次衰减 + # point_np = self.render.attach_new_node(point) + # point_np.set_pos(0, 0, 0) + # self.render.set_light(point_np) + # self.gizmo.attach(point_np) + + # sun = p3d.DirectionalLight('sun') + # sun.set_color((1.0, 0.95, 0.9, 1)) + # sun.set_shadow_caster(True, 2048, 2048) # 阴影,可调分辨率 + # self.sun_np = self.render.attach_new_node(sun) + # self.render.set_light(self.sun_np) + # self.set_frame_rate_meter(True) + # self.gizmo.attach(self.sun_np) \ No newline at end of file diff --git a/classes/point_marker.py b/classes/point_marker.py new file mode 100644 index 0000000..6b1e19f --- /dev/null +++ b/classes/point_marker.py @@ -0,0 +1,37 @@ +import panda3d.core as p3d + +class PointMarker(): + def __init__(self,default_disable = False): + self.disable = default_disable + from direct.showbase import ShowBaseGlobal + self.base = ShowBaseGlobal.base + self.marker = ShowBaseGlobal.base.loader.loadModel("models/misc/sphere") + mat = p3d.Material('unlit') + mat.base_color = p3d.Vec4(1,1,1,1) * 0.1 + mat.setEmission((1,0,1,1)) + self.marker.setMaterial(mat) + self.marker.reparentTo(ShowBaseGlobal.base.render) + self.marker.hide() + + def set_disable(self,state:bool): + self.disable = state + if not state: + self.marker.hide() + + def update_point(self,point:p3d.LPoint3f): + if self.disable: + return + + self.marker.show() + self.marker.setPos(point) + scale_factor = p3d.LPoint3f(self.base.cam.getPos() - point).length() + self.marker.setScale(scale_factor * 0.02) + + def show(self): + if self.disable: + return + + self.marker.show() + + def hide(self): + self.marker.hide() \ No newline at end of file diff --git a/config/daytime.yaml b/config/daytime.yaml new file mode 100644 index 0000000..d2e6a6f --- /dev/null +++ b/config/daytime.yaml @@ -0,0 +1,863 @@ +# Render Pipeline Time Of Day Configuration +# Instead of editing this file, prefer to use the Time Of Day Editor +# Any formatting and comments will be lost +# 渲染管线昼夜配置,建议使用 Time Of Day 编辑器修改,工具保存会丢失格式和注释。 + +control_points: + env_probes: + ambient_scale: + [ + [ + [0.4961464355, 0.3175487465], + [0.1368015414, 0.3621169916], + [0.8420038536, 0.3983286908], + ], + ] + sky_ambient_scale: + [ + [ + [0.4836223507, 0.0974930362], + [0.8497109827, 0.0000000000], + [0.0867052023, 0.0027855153], + ], + ] + sun_ambient_scale: + [ + [ + [0.4913294797, 0.0584958217], + [0.8612716763, 0.0306406685], + [0.1425818882, 0.0445682451], + ], + ] + color_correction: + camera_iso: [[[0.4438274549, 0.2674094708]]] + camera_shutter: [[[0.5211132438, 0.0190100061]]] + camera_aperture: [[[0.5057581574, 0.3577712610]]] + scattering: + sun_intensity: + [ + [ + [0.0000000000, 0.0000000000], + [0.0041666667, 0.0000000000], + [0.0083333333, 0.0000000000], + [0.0125000000, 0.0000000000], + [0.0166666667, 0.0000000000], + [0.0208333333, 0.0000000000], + [0.0250000000, 0.0000000000], + [0.0291666667, 0.0000000000], + [0.0333333333, 0.0000000000], + [0.0375000000, 0.0000000000], + [0.0416666667, 0.0000000000], + [0.0458333333, 0.0000000000], + [0.0500000000, 0.0000000000], + [0.0541666667, 0.0000000000], + [0.0583333333, 0.0000000000], + [0.0625000000, 0.0000000000], + [0.0666666667, 0.0000000000], + [0.0708333333, 0.0000000000], + [0.0750000000, 0.0000000000], + [0.0791666667, 0.0000000000], + [0.0833333333, 0.0000000000], + [0.0875000000, 0.0000000000], + [0.0916666667, 0.0000000000], + [0.0958333333, 0.0000000000], + [0.1000000000, 0.0000000000], + [0.1041666667, 0.0000000000], + [0.1083333333, 0.0000000000], + [0.1125000000, 0.0000000000], + [0.1166666667, 0.0000000000], + [0.1208333333, 0.0000000000], + [0.1250000000, 0.0000000000], + [0.1291666667, 0.0000000000], + [0.1333333333, 0.0000000000], + [0.1375000000, 0.0000000000], + [0.1416666667, 0.0000000000], + [0.1458333333, 0.0000000000], + [0.1500000000, 0.0000000000], + [0.1541666667, 0.0000000000], + [0.1583333333, 0.0000028805], + [0.1625000000, 0.0003577724], + [0.1666666667, 0.0013331400], + [0.1708333333, 0.0029671803], + [0.1750000000, 0.0052963381], + [0.1791666667, 0.0083550556], + [0.1833333333, 0.0121755589], + [0.1875000000, 0.0167876159], + [0.1916666667, 0.0222183530], + [0.1958333333, 0.0284919947], + [0.2000000000, 0.0356297193], + [0.2041666667, 0.0436494349], + [0.2083333333, 0.0525656099], + [0.2125000000, 0.0623891610], + [0.2166666667, 0.0731272461], + [0.2208333333, 0.0847831708], + [0.2250000000, 0.0973563167], + [0.2291666667, 0.1108419698], + [0.2333333333, 0.1252313631], + [0.2375000000, 0.1405115250], + [0.2416666667, 0.1566653434], + [0.2458333333, 0.1736715009], + [0.2500000000, 0.1915046014], + [0.2541666667, 0.2101350464], + [0.2583333333, 0.2295292930], + [0.2625000000, 0.2496498145], + [0.2666666667, 0.2704552670], + [0.2708333333, 0.2919006662], + [0.2750000000, 0.3139375192], + [0.2791666667, 0.3365139497], + [0.2833333333, 0.3595750662], + [0.2875000000, 0.3830630359], + [0.2916666667, 0.4069173972], + [0.2958333333, 0.4310753462], + [0.3000000000, 0.4554720417], + [0.3041666667, 0.4800408236], + [0.3083333333, 0.5047136020], + [0.3125000000, 0.5294212108], + [0.3166666667, 0.5540936424], + [0.3208333333, 0.5786605298], + [0.3250000000, 0.6030514553], + [0.3291666667, 0.6271963182], + [0.3333333333, 0.6510256858], + [0.3375000000, 0.6744711982], + [0.3416666667, 0.6974659988], + [0.3458333333, 0.7199450163], + [0.3500000000, 0.7418453485], + [0.3541666667, 0.7631067095], + [0.3583333333, 0.7836717291], + [0.3625000000, 0.8034862953], + [0.3666666667, 0.8224999302], + [0.3708333333, 0.8406661079], + [0.3750000000, 0.8579425235], + [0.3791666667, 0.8742914270], + [0.3833333333, 0.8896799131], + [0.3875000000, 0.9040801386], + [0.3916666667, 0.9174695289], + [0.3958333333, 0.9298310650], + [0.4000000000, 0.9411533765], + [0.4041666667, 0.9514309312], + [0.4083333333, 0.9606641691], + [0.4125000000, 0.9688595571], + [0.4166666667, 0.9760296330], + [0.4208333333, 0.9821930708], + [0.4250000000, 0.9873746114], + [0.4291666667, 0.9916050060], + [0.4333333333, 0.9949209310], + [0.4375000000, 0.9973647924], + [0.4416666667, 0.9989845508], + [0.4458333333, 0.9998334497], + [0.4500000000, 0.9999696949], + [0.4541666667, 0.9994560801], + [0.4583333333, 0.9983595429], + [0.4625000000, 0.9967506613], + [0.4666666667, 0.9947030614], + [0.4708333333, 0.9922927758], + [0.4750000000, 0.9895975125], + [0.4791666667, 0.9866958610], + [0.4833333333, 0.9836664262], + [0.4875000000, 0.9805868867], + [0.4916666667, 0.9775330316], + [0.4958333333, 0.9745777179], + [0.5000000000, 0.9717898417], + [0.5041666667, 0.9692332877], + [0.5083333333, 0.9669658924], + [0.5125000000, 0.9650384806], + [0.5166666667, 0.9634939916], + [0.5208333333, 0.9623666659], + [0.5250000000, 0.9616814371], + [0.5291666667, 0.9614534423], + [0.5333333333, 0.9616877089], + [0.5375000000, 0.9623790807], + [0.5416666667, 0.9635123329], + [0.5458333333, 0.9650624244], + [0.5500000000, 0.9669949804], + [0.5541666667, 0.9692669864], + [0.5583333333, 0.9718275065], + [0.5625000000, 0.9746185969], + [0.5666666667, 0.9775762863], + [0.5708333333, 0.9806315864], + [0.5750000000, 0.9837115661], + [0.5791666667, 0.9867403433], + [0.5833333333, 0.9896401655], + [0.5875000000, 0.9923323562], + [0.5916666667, 0.9947382579], + [0.5958333333, 0.9967800977], + [0.6000000000, 0.9983817820], + [0.6041666667, 0.9994696263], + [0.6083333333, 0.9999730028], + [0.6125000000, 0.9998249266], + [0.6166666667, 0.9989625601], + [0.6208333333, 0.9973276624], + [0.6250000000, 0.9948669567], + [0.6291666667, 0.9915324664], + [0.6333333333, 0.9872817545], + [0.6375000000, 0.9820781426], + [0.6416666667, 0.9758908775], + [0.6458333333, 0.9686952146], + [0.6500000000, 0.9604725211], + [0.6541666667, 0.9512102537], + [0.6583333333, 0.9409019858], + [0.6625000000, 0.9295473441], + [0.6666666667, 0.9171518878], + [0.6708333333, 0.9037270619], + [0.6750000000, 0.8892899902], + [0.6791666667, 0.8738633008], + [0.6833333333, 0.8574749656], + [0.6875000000, 0.8401579787], + [0.6916666667, 0.8219502453], + [0.6958333333, 0.8028941798], + [0.7000000000, 0.7830364456], + [0.7041666667, 0.7624277344], + [0.7083333333, 0.7411222520], + [0.7125000000, 0.7191776044], + [0.7166666667, 0.6966542563], + [0.7208333333, 0.6736152714], + [0.7250000000, 0.6501259629], + [0.7291666667, 0.6262533880], + [0.7333333333, 0.6020661121], + [0.7375000000, 0.5776338043], + [0.7416666667, 0.5530267796], + [0.7458333333, 0.5283156992], + [0.7500000000, 0.5035711751], + [0.7541666667, 0.4788634341], + [0.7583333333, 0.4542618347], + [0.7625000000, 0.4298347613], + [0.7666666667, 0.4056490351], + [0.7708333333, 0.3817697830], + [0.7750000000, 0.3582600107], + [0.7791666667, 0.3351803495], + [0.7833333333, 0.3125888445], + [0.7875000000, 0.2905406366], + [0.7916666667, 0.2690876955], + [0.7958333333, 0.2482787388], + [0.8000000000, 0.2281588906], + [0.8041666667, 0.2087696425], + [0.8083333333, 0.1901486315], + [0.8125000000, 0.1723295359], + [0.8166666667, 0.1553419918], + [0.8208333333, 0.1392115328], + [0.8250000000, 0.1239595144], + [0.8291666667, 0.1096030703], + [0.8333333333, 0.0961551918], + [0.8375000000, 0.0836246599], + [0.8416666667, 0.0720161369], + [0.8458333333, 0.0613302273], + [0.8500000000, 0.0515635598], + [0.8541666667, 0.0427088803], + [0.8583333333, 0.0347551990], + [0.8625000000, 0.0276878920], + [0.8666666667, 0.0214889271], + [0.8708333333, 0.0161369711], + [0.8750000000, 0.0116076130], + [0.8791666667, 0.0078735477], + [0.8833333333, 0.0049047927], + [0.8875000000, 0.0026688977], + [0.8916666667, 0.0011311782], + [0.8958333333, 0.0002549473], + [0.9000000000, 0.0000000000], + [0.9041666667, 0.0000000000], + [0.9083333333, 0.0000000000], + [0.9125000000, 0.0000000000], + [0.9166666667, 0.0000000000], + [0.9208333333, 0.0000000000], + [0.9250000000, 0.0000000000], + [0.9291666667, 0.0000000000], + [0.9333333333, 0.0000000000], + [0.9375000000, 0.0000000000], + [0.9416666667, 0.0000000000], + [0.9458333333, 0.0000000000], + [0.9500000000, 0.0000000000], + [0.9541666667, 0.0000000000], + [0.9583333333, 0.0000000000], + [0.9625000000, 0.0000000000], + [0.9666666667, 0.0000000000], + [0.9708333333, 0.0000000000], + [0.9750000000, 0.0000000000], + [0.9791666667, 0.0000000000], + [0.9833333333, 0.0000000000], + [0.9875000000, 0.0000000000], + [0.9916666667, 0.0000000000], + [0.9958333333, 0.0000000000], + ], + ] + sun_color: + [ + [ + [0.4971900000, 0.5763000000], + [0.0433100000, 0.8999700000], + [0.8635787716, 0.9130000000], + [0.1785000000, 0.8973600000], + [0.8099800000, 0.8651100000], + [0.2360800000, 0.7712700000], + [0.6583432177, 0.8485126184], + [0.1266806142, 0.9648102053], + [0.9558541267, 0.9090909091], + [0.5568400771, 0.7353760446], + ], + [ + [0.5001318426, 0.5160300000], + [0.0572700000, 0.6541600000], + [0.2395000000, 0.5976800000], + [0.8104600000, 0.6009000000], + [0.6967400000, 0.5483900000], + ], + [ + [0.0862400000, 0.4257800000], + [0.4955600000, 0.4033000000], + [0.8234200000, 0.4340200000], + ], + ] + sun_azimuth: + [ + [ + [0.0000000000, 0.9712048444], + [0.0041666667, 0.9752899861], + [0.0083333333, 0.9793860750], + [0.0125000000, 0.9834913806], + [0.0166666667, 0.9876041361], + [0.0208333333, 0.9917225333], + [0.0250000000, 0.9958447417], + [0.0291666667, 0.9999689083], + [0.0333333333, 0.0040931694], + [0.0375000000, 0.0082156694], + [0.0416666667, 0.0123345500], + [0.0458333333, 0.0164479833], + [0.0500000000, 0.0205541528], + [0.0541666667, 0.0246512917], + [0.0583333333, 0.0287376667], + [0.0625000000, 0.0328116028], + [0.0666666667, 0.0368714722], + [0.0708333333, 0.0409157278], + [0.0750000000, 0.0449428778], + [0.0791666667, 0.0489515194], + [0.0833333333, 0.0529403222], + [0.0875000000, 0.0569080472], + [0.0916666667, 0.0608535417], + [0.0958333333, 0.0647757500], + [0.1000000000, 0.0686737000], + [0.1041666667, 0.0725465278], + [0.1083333333, 0.0763934556], + [0.1125000000, 0.0802138056], + [0.1166666667, 0.0840069972], + [0.1208333333, 0.0877725472], + [0.1250000000, 0.0915100639], + [0.1291666667, 0.0952192472], + [0.1333333333, 0.0988998889], + [0.1375000000, 0.1025518722], + [0.1416666667, 0.1061751639], + [0.1458333333, 0.1097698111], + [0.1500000000, 0.1133359472], + [0.1541666667, 0.1168737750], + [0.1583333333, 0.1203835778], + [0.1625000000, 0.1238657083], + [0.1666666667, 0.1273205833], + [0.1708333333, 0.1307486917], + [0.1750000000, 0.1341505750], + [0.1791666667, 0.1375268417], + [0.1833333333, 0.1408781500], + [0.1875000000, 0.1442052111], + [0.1916666667, 0.1475087917], + [0.1958333333, 0.1507897056], + [0.2000000000, 0.1540488056], + [0.2041666667, 0.1572870000], + [0.2083333333, 0.1605052250], + [0.2125000000, 0.1637044694], + [0.2166666667, 0.1668857556], + [0.2208333333, 0.1700501444], + [0.2250000000, 0.1731987333], + [0.2291666667, 0.1763326528], + [0.2333333333, 0.1794530750], + [0.2375000000, 0.1825612000], + [0.2416666667, 0.1856582667], + [0.2458333333, 0.1887455500], + [0.2500000000, 0.1918243556], + [0.2541666667, 0.1948960250], + [0.2583333333, 0.1979619444], + [0.2625000000, 0.2010235250], + [0.2666666667, 0.2040822250], + [0.2708333333, 0.2071395417], + [0.2750000000, 0.2101970083], + [0.2791666667, 0.2132562056], + [0.2833333333, 0.2163187583], + [0.2875000000, 0.2193863444], + [0.2916666667, 0.2224606833], + [0.2958333333, 0.2255435528], + [0.3000000000, 0.2286367806], + [0.3041666667, 0.2317422667], + [0.3083333333, 0.2348619583], + [0.3125000000, 0.2379978778], + [0.3166666667, 0.2411521139], + [0.3208333333, 0.2443268361], + [0.3250000000, 0.2475242861], + [0.3291666667, 0.2507467917], + [0.3333333333, 0.2539967694], + [0.3375000000, 0.2572767278], + [0.3416666667, 0.2605892750], + [0.3458333333, 0.2639371222], + [0.3500000000, 0.2673230944], + [0.3541666667, 0.2707501250], + [0.3583333333, 0.2742212694], + [0.3625000000, 0.2777397167], + [0.3666666667, 0.2813087750], + [0.3708333333, 0.2849318944], + [0.3750000000, 0.2886126722], + [0.3791666667, 0.2923548361], + [0.3833333333, 0.2961622694], + [0.3875000000, 0.3000390083], + [0.3916666667, 0.3039892333], + [0.3958333333, 0.3080172722], + [0.4000000000, 0.3121276028], + [0.4041666667, 0.3163248417], + [0.4083333333, 0.3206137361], + [0.4125000000, 0.3249991444], + [0.4166666667, 0.3294860333], + [0.4208333333, 0.3340794444], + [0.4250000000, 0.3387844583], + [0.4291666667, 0.3436061833], + [0.4333333333, 0.3485496806], + [0.4375000000, 0.3536199333], + [0.4416666667, 0.3588217694], + [0.4458333333, 0.3641597972], + [0.4500000000, 0.3696383139], + [0.4541666667, 0.3752612083], + [0.4583333333, 0.3810318500], + [0.4625000000, 0.3869529694], + [0.4666666667, 0.3930265278], + [0.4708333333, 0.3992535694], + [0.4750000000, 0.4056340889], + [0.4791666667, 0.4121668750], + [0.4833333333, 0.4188493722], + [0.4875000000, 0.4256775556], + [0.4916666667, 0.4326458139], + [0.4958333333, 0.4397468583], + [0.5000000000, 0.4469716889], + [0.5041666667, 0.4543095722], + [0.5083333333, 0.4617480944], + [0.5125000000, 0.4692732500], + [0.5166666667, 0.4768695944], + [0.5208333333, 0.4845204611], + [0.5250000000, 0.4922082083], + [0.5291666667, 0.4999145222], + [0.5333333333, 0.5076207528], + [0.5375000000, 0.5153082417], + [0.5416666667, 0.5229586861], + [0.5458333333, 0.5305544472], + [0.5500000000, 0.5380788667], + [0.5541666667, 0.5455165139], + [0.5583333333, 0.5528533917], + [0.5625000000, 0.5600771000], + [0.5666666667, 0.5671769194], + [0.5708333333, 0.5741438583], + [0.5750000000, 0.5809706444], + [0.5791666667, 0.5876516833], + [0.5833333333, 0.5941829556], + [0.5875000000, 0.6005619194], + [0.5916666667, 0.6067873722], + [0.5958333333, 0.6128593167], + [0.6000000000, 0.6187788083], + [0.6041666667, 0.6245478111], + [0.6083333333, 0.6301690611], + [0.6125000000, 0.6356459333], + [0.6166666667, 0.6409823222], + [0.6208333333, 0.6461825222], + [0.6250000000, 0.6512511500], + [0.6291666667, 0.6561930306], + [0.6333333333, 0.6610131500], + [0.6375000000, 0.6657165722], + [0.6416666667, 0.6703083972], + [0.6458333333, 0.6747937167], + [0.6500000000, 0.6791775667], + [0.6541666667, 0.6834649111], + [0.6583333333, 0.6876606111], + [0.6625000000, 0.6917694111], + [0.6666666667, 0.6957959306], + [0.6708333333, 0.6997446417], + [0.6750000000, 0.7036198722], + [0.6791666667, 0.7074258083], + [0.6833333333, 0.7111664778], + [0.6875000000, 0.7148457639], + [0.6916666667, 0.7184673972], + [0.6958333333, 0.7220349750], + [0.7000000000, 0.7255519417], + [0.7041666667, 0.7290216111], + [0.7083333333, 0.7324471667], + [0.7125000000, 0.7358316639], + [0.7166666667, 0.7391780417], + [0.7208333333, 0.7424891222], + [0.7250000000, 0.7457676139], + [0.7291666667, 0.7490161278], + [0.7333333333, 0.7522371750], + [0.7375000000, 0.7554331694], + [0.7416666667, 0.7586064389], + [0.7458333333, 0.7617592306], + [0.7500000000, 0.7648937083], + [0.7541666667, 0.7680119667], + [0.7583333333, 0.7711160278], + [0.7625000000, 0.7742078444], + [0.7666666667, 0.7772893111], + [0.7708333333, 0.7803622611], + [0.7750000000, 0.7834284722], + [0.7791666667, 0.7864896722], + [0.7833333333, 0.7895475361], + [0.7875000000, 0.7926036889], + [0.7916666667, 0.7956597194], + [0.7958333333, 0.7987171639], + [0.8000000000, 0.8017775194], + [0.8041666667, 0.8048422500], + [0.8083333333, 0.8079127722], + [0.8125000000, 0.8109904750], + [0.8166666667, 0.8140767000], + [0.8208333333, 0.8171727639], + [0.8250000000, 0.8202799444], + [0.8291666667, 0.8233994833], + [0.8333333333, 0.8265325917], + [0.8375000000, 0.8296804389], + [0.8416666667, 0.8328441694], + [0.8458333333, 0.8360248861], + [0.8500000000, 0.8392236528], + [0.8541666667, 0.8424415028], + [0.8583333333, 0.8456794278], + [0.8625000000, 0.8489383750], + [0.8666666667, 0.8522192611], + [0.8708333333, 0.8555229444], + [0.8750000000, 0.8588502528], + [0.8791666667, 0.8622019556], + [0.8833333333, 0.8655787722], + [0.8875000000, 0.8689813778], + [0.8916666667, 0.8724103833], + [0.8958333333, 0.8758663472], + [0.9000000000, 0.8793497583], + [0.9041666667, 0.8828610500], + [0.9083333333, 0.8864005861], + [0.9125000000, 0.8899686500], + [0.9166666667, 0.8935654667], + [0.9208333333, 0.8971911694], + [0.9250000000, 0.9008458222], + [0.9291666667, 0.9045293972], + [0.9333333333, 0.9082417861], + [0.9375000000, 0.9119827889], + [0.9416666667, 0.9157521139], + [0.9458333333, 0.9195493806], + [0.9500000000, 0.9233741083], + [0.9541666667, 0.9272257222], + [0.9583333333, 0.9311035472], + [0.9625000000, 0.9350068194], + [0.9666666667, 0.9389346667], + [0.9708333333, 0.9428861278], + [0.9750000000, 0.9468601417], + [0.9791666667, 0.9508555611], + [0.9833333333, 0.9548711389], + [0.9875000000, 0.9589055500], + [0.9916666667, 0.9629573778], + [0.9958333333, 0.9670251389], + ], + ] + sun_altitude: + [ + [ + [0.0000000000, 0.3483996917], + [0.0041666667, 0.3470706833], + [0.0083333333, 0.3459423667], + [0.0125000000, 0.3450159667], + [0.0166666667, 0.3442925167], + [0.0208333333, 0.3437728167], + [0.0250000000, 0.3434574417], + [0.0291666667, 0.3433467500], + [0.0333333333, 0.3434408667], + [0.0375000000, 0.3437396833], + [0.0416666667, 0.3442428667], + [0.0458333333, 0.3449498417], + [0.0500000000, 0.3458598250], + [0.0541666667, 0.3469718083], + [0.0583333333, 0.3482845667], + [0.0625000000, 0.3497966583], + [0.0666666667, 0.3515064500], + [0.0708333333, 0.3534121083], + [0.0750000000, 0.3555116167], + [0.0791666667, 0.3578027667], + [0.0833333333, 0.3602831917], + [0.0875000000, 0.3629503750], + [0.0916666667, 0.3658016417], + [0.0958333333, 0.3688341750], + [0.1000000000, 0.3720450583], + [0.1041666667, 0.3754312333], + [0.1083333333, 0.3789895417], + [0.1125000000, 0.3827167583], + [0.1166666667, 0.3866095417], + [0.1208333333, 0.3906645000], + [0.1250000000, 0.3948781667], + [0.1291666667, 0.3992470500], + [0.1333333333, 0.4037675833], + [0.1375000000, 0.4084361917], + [0.1416666667, 0.4132492667], + [0.1458333333, 0.4182031750], + [0.1500000000, 0.4232942833], + [0.1541666667, 0.4285189583], + [0.1583333333, 0.4338735667], + [0.1625000000, 0.4393544833], + [0.1666666667, 0.4449581083], + [0.1708333333, 0.4506808417], + [0.1750000000, 0.4565191333], + [0.1791666667, 0.4624694333], + [0.1833333333, 0.4685282417], + [0.1875000000, 0.4746920750], + [0.1916666667, 0.4809575167], + [0.1958333333, 0.4873211500], + [0.2000000000, 0.4937796250], + [0.2041666667, 0.5003296167], + [0.2083333333, 0.5069678333], + [0.2125000000, 0.5136910500], + [0.2166666667, 0.5204960583], + [0.2208333333, 0.5273796917], + [0.2250000000, 0.5343388417], + [0.2291666667, 0.5413704083], + [0.2333333333, 0.5484713583], + [0.2375000000, 0.5556386667], + [0.2416666667, 0.5628693583], + [0.2458333333, 0.5701604750], + [0.2500000000, 0.5775091167], + [0.2541666667, 0.5849123667], + [0.2583333333, 0.5923673667], + [0.2625000000, 0.5998712583], + [0.2666666667, 0.6074212000], + [0.2708333333, 0.6150143750], + [0.2750000000, 0.6226479750], + [0.2791666667, 0.6303191750], + [0.2833333333, 0.6380251833], + [0.2875000000, 0.6457631833], + [0.2916666667, 0.6535303500], + [0.2958333333, 0.6613238500], + [0.3000000000, 0.6691408417], + [0.3041666667, 0.6769784417], + [0.3083333333, 0.6848337417], + [0.3125000000, 0.6927038083], + [0.3166666667, 0.7005856417], + [0.3208333333, 0.7084762083], + [0.3250000000, 0.7163724167], + [0.3291666667, 0.7242711083], + [0.3333333333, 0.7321690417], + [0.3375000000, 0.7400628917], + [0.3416666667, 0.7479492583], + [0.3458333333, 0.7558246250], + [0.3500000000, 0.7636853500], + [0.3541666667, 0.7715276833], + [0.3583333333, 0.7793477333], + [0.3625000000, 0.7871414500], + [0.3666666667, 0.7949046250], + [0.3708333333, 0.8026328750], + [0.3750000000, 0.8103216083], + [0.3791666667, 0.8179660250], + [0.3833333333, 0.8255611083], + [0.3875000000, 0.8331015917], + [0.3916666667, 0.8405819250], + [0.3958333333, 0.8479963000], + [0.4000000000, 0.8553385833], + [0.4041666667, 0.8626023167], + [0.4083333333, 0.8697807083], + [0.4125000000, 0.8768665917], + [0.4166666667, 0.8838523917], + [0.4208333333, 0.8907301500], + [0.4250000000, 0.8974914667], + [0.4291666667, 0.9041274833], + [0.4333333333, 0.9106289083], + [0.4375000000, 0.9169859417], + [0.4416666667, 0.9231883167], + [0.4458333333, 0.9292252917], + [0.4500000000, 0.9350856417], + [0.4541666667, 0.9407576583], + [0.4583333333, 0.9462292250], + [0.4625000000, 0.9514877833], + [0.4666666667, 0.9565204500], + [0.4708333333, 0.9613140333], + [0.4750000000, 0.9658551333], + [0.4791666667, 0.9701302333], + [0.4833333333, 0.9741258167], + [0.4875000000, 0.9778285167], + [0.4916666667, 0.9812252417], + [0.4958333333, 0.9843033667], + [0.5000000000, 0.9870508917], + [0.5041666667, 0.9894566333], + [0.5083333333, 0.9915104250], + [0.5125000000, 0.9932032917], + [0.5166666667, 0.9945276083], + [0.5208333333, 0.9954772833], + [0.5250000000, 0.9960478583], + [0.5291666667, 0.9962366167], + [0.5333333333, 0.9960426583], + [0.5375000000, 0.9954669000], + [0.5416666667, 0.9945120417], + [0.5458333333, 0.9931825417], + [0.5500000000, 0.9914845167], + [0.5541666667, 0.9894255667], + [0.5583333333, 0.9870146750], + [0.5625000000, 0.9842620167], + [0.5666666667, 0.9811787667], + [0.5708333333, 0.9777769250], + [0.5750000000, 0.9740691000], + [0.5791666667, 0.9700683917], + [0.5833333333, 0.9657881583], + [0.5875000000, 0.9612419083], + [0.5916666667, 0.9564431500], + [0.5958333333, 0.9514052750], + [0.6000000000, 0.9461414667], + [0.6041666667, 0.9406646083], + [0.6083333333, 0.9349872417], + [0.6125000000, 0.9291214833], + [0.6166666667, 0.9230790167], + [0.6208333333, 0.9168710750], + [0.6250000000, 0.9105083833], + [0.6291666667, 0.9040012167], + [0.6333333333, 0.8973593417], + [0.6375000000, 0.8905920583], + [0.6416666667, 0.8837082167], + [0.6458333333, 0.8767162000], + [0.6500000000, 0.8696239833], + [0.6541666667, 0.8624391083], + [0.6583333333, 0.8551687417], + [0.6625000000, 0.8478196833], + [0.6666666667, 0.8403983667], + [0.6708333333, 0.8329109250], + [0.6750000000, 0.8253631750], + [0.6791666667, 0.8177606417], + [0.6833333333, 0.8101086000], + [0.6875000000, 0.8024120500], + [0.6916666667, 0.7946758000], + [0.6958333333, 0.7869044250], + [0.7000000000, 0.7791023000], + [0.7041666667, 0.7712736500], + [0.7083333333, 0.7634224917], + [0.7125000000, 0.7555527333], + [0.7166666667, 0.7476681167], + [0.7208333333, 0.7397722667], + [0.7250000000, 0.7318687083], + [0.7291666667, 0.7239608333], + [0.7333333333, 0.7160519583], + [0.7375000000, 0.7081453250], + [0.7416666667, 0.7002440833], + [0.7458333333, 0.6923513250], + [0.7500000000, 0.6844700833], + [0.7541666667, 0.6766033500], + [0.7583333333, 0.6687540417], + [0.7625000000, 0.6609250833], + [0.7666666667, 0.6531193333], + [0.7708333333, 0.6453396500], + [0.7750000000, 0.6375888583], + [0.7791666667, 0.6298697667], + [0.7833333333, 0.6221851917], + [0.7875000000, 0.6145379417], + [0.7916666667, 0.6069308083], + [0.7958333333, 0.5993666167], + [0.8000000000, 0.5918481750], + [0.8041666667, 0.5843783250], + [0.8083333333, 0.5769599167], + [0.8125000000, 0.5695958167], + [0.8166666667, 0.5622889167], + [0.8208333333, 0.5550421417], + [0.8250000000, 0.5478584417], + [0.8291666667, 0.5407407833], + [0.8333333333, 0.5336921917], + [0.8375000000, 0.5267157083], + [0.8416666667, 0.5198144167], + [0.8458333333, 0.5129914417], + [0.8500000000, 0.5062499500], + [0.8541666667, 0.4995931417], + [0.8583333333, 0.4930242667], + [0.8625000000, 0.4865465917], + [0.8666666667, 0.4801634583], + [0.8708333333, 0.4738782250], + [0.8750000000, 0.4676943000], + [0.8791666667, 0.4616151250], + [0.8833333333, 0.4556441833], + [0.8875000000, 0.4497849833], + [0.8916666667, 0.4440410667], + [0.8958333333, 0.4384160250], + [0.9000000000, 0.4329134417], + [0.9041666667, 0.4275369500], + [0.9083333333, 0.4222901667], + [0.9125000000, 0.4171767583], + [0.9166666667, 0.4122003667], + [0.9208333333, 0.4073646417], + [0.9250000000, 0.4026732417], + [0.9291666667, 0.3981297750], + [0.9333333333, 0.3937378500], + [0.9375000000, 0.3895010500], + [0.9416666667, 0.3854229000], + [0.9458333333, 0.3815068833], + [0.9500000000, 0.3777564167], + [0.9541666667, 0.3741748500], + [0.9583333333, 0.3707654667], + [0.9625000000, 0.3675314333], + [0.9666666667, 0.3644758250], + [0.9708333333, 0.3616016083], + [0.9750000000, 0.3589116167], + [0.9791666667, 0.3564085583], + [0.9833333333, 0.3540949750], + [0.9875000000, 0.3519732750], + [0.9916666667, 0.3500456750], + [0.9958333333, 0.3483142333], + ], + ] + extinction: [[[0.4913294798, 0.6378830084]]] + volumetrics: + fog_ramp_size: [[[0.5510597303, 0.7409470752]]] + fog_color: + [ + [ + [0.5827924660, 0.6183844011], + [0.7616411304, 0.9173984431], + [0.1996161228, 0.4985337243], + [0.6696215593, 0.5832754719], + [0.5183044316, 0.6629526462], + ], + [ + [0.4922410956, 0.5637316326], + [0.8541266795, 0.4985337243], + [0.2168905950, 0.4809384164], + [0.3666026871, 0.5571847507], + [0.7552986513, 0.5738161560], + [0.5838150289, 0.6880222841], + ], + [ + [0.5250555661, 0.9247910863], + [0.8598848369, 0.5249266862], + [0.2168905950, 0.5278592375], + [0.3666026871, 0.7008797654], + [0.7620183506, 0.4861173510], + [0.5741811175, 0.9972144846], + ], + ] + fog_brightness: + [ + [ + [0.6637912862, 0.3537604457], + [0.0000000000, 0.0000000000], + [1.0000000000, 0.0000000000], + [0.2708922740, 0.3198196359], + [0.1727447217, 0.1026392962], + [0.1401151631, 0.0000000000], + [0.8984426717, 0.1352486133], + [0.9232245681, 0.0000000000], + [0.7071290944, 0.2228412257], + [0.5491329479, 0.3231197772], + ], + ] + fog_intensity: [[[0.5317919075, 0.0083565460]]] + clouds: + cloud_brightness: + [ + [ + [0.4558541267, 0.9574780059], + [0.2744727256, 0.8944309678], + [0.1938559693, 0.5249266862], + [0.8905932438, 0.2375366569], + [0.6429901728, 0.9589492375], + [0.7581600000, 0.8914912023], + [0.2226478119, 0.7859268915], + [0.8406909789, 0.4897360704], + [0.5451055662, 0.9618768328], + [0.9462571977, 0.0000000000], + [1.0000000000, 0.0000000000], + [0.3646833013, 0.9472140762], + [0.3186180422, 0.9325513197], + [0.1362763916, 0.0000000000], + ], + ] diff --git a/config/debugging.yaml b/config/debugging.yaml new file mode 100644 index 0000000..3ab0cee --- /dev/null +++ b/config/debugging.yaml @@ -0,0 +1,33 @@ + +# This file contains all available debug modes. +# You can add or remove debug modes here, aswell as +# disable or enable them, whatever fits to you. +# 此文件列出所有可用调试模式,可按需增删或启用/禁用。 + +# NOTICE: This file only has effect if debugging is enabled +# in the pipeline.yaml (settings.pipeline.display_debuger == True) +# 注意:仅当 pipeline.yaml 中开启调试(settings.pipeline.display_debugger == True)时此文件才生效。 + +# Usually you don't have to touch this file, except when developing +# new plugins or adding new features. +# 一般无需修改,除非开发新插件或功能时需要新增调试模式。 + +render_modes: + - { name: "Shading Model", key: "SHADING_MODEL" } + - { name: "Diffuse", key: "DIFFUSE" } + - { name: "Roughness", key: "ROUGHNESS" } + - { name: "Specular", key: "SPECULAR" } + - { name: "Normal", key: "NORMAL" } + - { name: "Metallic", key: "METALLIC" } + - { name: "Translucency", key: "TRANSLUCENCY" } + - { name: "PSSM Splits", key: "PSSM_SPLITS", requires: "pssm", cxx_only: true } + - { name: "Ambient Occlusion", key: "OCCLUSION", requires: "ao" } + - { name: "Sky AO", key: "SKY_AO", requires: "sky_ao" } + - { name: "Scattering", key: "SCATTERING", requires: "scattering" } + - { name: "Velocity", key: "VELOCITY" } + - { name: "Diffuse Ambient", key: "DIFFUSE_AMBIENT" } + - { name: "Specular Ambient", key: "SPECULAR_AMBIENT" } + - { name: "Luminance", key: "LUMINANCE", special: true } + - { name: "Probe Count", key: "ENVPROBE_COUNT", requires: "env_probes" } + - { name: "Light Count", key: "LIGHT_COUNT" } + - { name: "Light Tiles", key: "LIGHT_TILES", special: true } diff --git a/config/panda3d-config.prc b/config/panda3d-config.prc new file mode 100644 index 0000000..6c08c12 --- /dev/null +++ b/config/panda3d-config.prc @@ -0,0 +1,216 @@ + + +# This is the config file used to configure basic settings for Panda3D. +# The pipeline loads it at startup to ensure the environment is setup properly. +# Panda3D 基础设置文件,管线启动时会加载以确保环境配置正确。 + +# -------------- Development options -------------- +# 开发环境选项 + +pstats-gpu-timing #t +gl-debug #t +gl-debug-object-labels #t + +# -------------- Production options --------------- +# 生产环境选项(发布可用) + +# pstats-gpu-timing #f +# gl-debug #f +# gl-debug-object-labels #f + +# ----------------- Misc Settings ----------------- +# 杂项设置 + +# Disable V-Sync +# 关闭垂直同步 +sync-video #f + +# Limit the pstats-rate. This causes huge lag on windows 10. +# 限制 pstats 速率,避免 Win10 上的巨大卡顿 +pstats-max-rate 200 + +# No stack trace on assertion, set this to true to make panda crash on assertions +# (which will allow to debug it) +# 断言时不打印堆栈;设为 true 会在断言时直接崩溃便于调试 +# assert-abort #t +# show-dll-error-dialog #f + +# File system should be case sensitive +# NOTICE: Set this to #f if you are using tempfile, since it returns +# wrong cased directory paths +# 文件系统区分大小写;若使用 tempfile 目录大小写错误则改为 #f +vfs-case-sensitive #t + +# Enable state cache, this seems to actually help the performance by a lot +# 启用状态缓存,通常能显著提升性能 +state-cache #t +transform-cache #t + +# Hide frame rate meter (we have our own) +# 隐藏 Panda3D 自带帧率计数(管线有自定义) +show-frame-rate-meter #f + +# Set text settings +# 文本相关设置 +text-minfilter linear +text-magfilter linear +text-page-size 512 512 +text-rwap-mode WM_border_clor + +# Better text performance since rdb's patch +# 配合 rdb 补丁的文本性能设置 +text-flatten 0 +text-dynamic-merge 1 + +# For smoother animations +# even-animation #t +# 更平滑的动画(需要时启用 even-animation) + +# Threading, really buggy! +#threading-model App/Cull/Draw +# 多线程模式,存在问题慎用 + +# Disable stencil, not supported/required +# 关闭模板缓冲,未使用也不需要 +support-stencil #f +framebuffer-stencil #f + +# Don't use srgb correction, we do that in the final shader +# 不使用内置 sRGB 校正,最终着色器中处理 +framebuffer-srgb #f + +# Don't use multisamples +# 不启用多重采样 +framebuffer-multisample #f +multisamples 0 + +# Don't rescale textures which are no power-of-2 +# 非 2 次幂纹理不缩放 +textures-power-2 none + +# Set default texture filters +# 默认纹理过滤器 +texture-anisotropic-degree 16 +texture-magfilter linear +texture-minfilter linear +texture-quality-level fastest + +# Enable seamless cubemap filtering, important for environment filtering +# 启用无缝立方体贴图过滤,对环境滤波很关键 +gl-cube-map-seamless #t + +# Disable caching of textures +# 关闭纹理缓存 +model-cache-textures #f + +# Disable the annoying SRGB warning from pnmimage +# 关闭 pnmimage 的 SRGB 警告 +notify-level-pnmimage error + +# Disable the buffer viewer, we have our own +# 关闭内置缓冲查看器(管线自带) +show-buffers #f + +# Use the default coordinate system, this makes our matrix transformations +# faster because we don't have have to transform them to a different coordinate +# system before +# 使用默认坐标系,避免矩阵转换到其他坐标系的额外开销 +gl-coordinate-system default + +# This makes animations smoother, especially if they were exported at 30 FPS +# and are played at 60 FPS +# 让动画更平滑,特别是 30FPS 输出播放到 60FPS 时 +interpolate-frames #t + +# Disable workarround in panda which causes our shadow atlas to take twice +# the amount of vram it should, due to an intel driver bug. +# 关闭 Intel 驱动相关的临时修复,避免阴影图集显存翻倍 +gl-force-fbo-color #f + +# ----------- OpenGL / Performance Settings ------------ +# OpenGL 与性能相关设置 + +# Require OpenGL 4.3 at least, necessary for Intel drivers on Linux +# 至少需要 OpenGL 4.3(Linux Intel 驱动需要) +gl-version 4 3 + +# Animations on the gpu. The default shader has to get adjusted to support this +# feature before this option can be turned on. +# hardware-animated-vertices #t +# GPU 动画,开启需修改默认着色器以支持 + +# Try this options for performance +# uniquify-matrix #t +# uniquify-transforms #t +# uniquify-states #t +# uniquify-attribs #f +# 可尝试的性能优化选项 + +# Enable garbarge collection +# 启用状态垃圾回收 +garbage-collect-states #t +# garbage-collect-states-rate 0.2 + +# Compress textures on the drivers? +# driver-compress-textures #t +# 是否让驱动压缩纹理 + +# Faster animations? (Have to test) +# matrix-palette #t +# display-list-animation #t +# 可能加速动画的选项(需测试) + +# Better GL performance by not using gl-finish and so on +# 通过关闭 gl-finish 等获取更好 GL 性能 +gl-finish #f +gl-force-no-error #t +gl-check-errors #f +gl-force-no-flush #t +gl-force-no-scissor #t + +# Eventually disable memory barriers, have to check if this is faster +# 如需可禁用内存屏障,需测试是否更快 +gl-enable-memory-barriers #f + +# Disable threading +# 禁用线程化 +lock-to-one-cpu #t +support-threads #f + +# Let the driver generate the mipmaps +# 由驱动生成 mipmap +driver-generate-mipmaps #t + +# Use immutable texture storage, it is *supposed* to be faster, but might not be +# XXX: Seems to produce an GL_INVALID_VALUE when disabled +# 使用不可变纹理存储,理论更快;禁用时可能出现 GL_INVALID_VALUE +gl-immutable-texture-storage #t + +# Default window settings +# depth-bits 0 +color-bits 0 +framebuffer-depth #f +# 默认窗口设置(深度位、颜色位等) + +# Small performance gain by specifying fixed vertex attribute locations. +# Might cause issues with some (incorrectly converted/loaded) meshes though +# 固定顶点属性位置可略增性能,但可能与部分模型不兼容 +gl-fixed-vertex-attrib-locations #f + +# Disable the fragment shader performance warning +# 关闭片段着色器性能警告/重复编译提示 +gl-validate-shaders #f +gl-skip-shader-recompilation-warnings #t + +alpha-scale-via-texture #f +pstats-name Render Pipeline Stats +rescale-normals #f +screenshot-extension png + +# Required for correct velocity +# 正确计算速度所需 +always-store-prev-transform #t +allow-incomplete-render #t + + +no-singular-invert #f diff --git a/config/pipeline.yaml b/config/pipeline.yaml new file mode 100644 index 0000000..27fad9c --- /dev/null +++ b/config/pipeline.yaml @@ -0,0 +1,94 @@ +# This file stores internal settings of the pipeline. It does not contain the +# plugin settings, but just the basic settings of the internal pipeline components. +# 此文件仅存储渲染管线的内部基础设置,不包含各插件的独立配置。 +pipeline: + # This controls whether to show or hide the onscreen debugger. Not showing + # it will also disable the hotkeys, and give a small performance boost. + # Most likely you also don't want to show it in your own game, so set + # it to false in that case. + # 控制是否显示屏幕调试器;隐藏会禁用热键并略微提升性能,正式项目通常建议关闭。 + display_debugger: false + + # Affects which debugging information is displayed. If this is set to false, + # only frame time is displayed, otherwise much more information is visible. + # Has no effect when display_debugger is set to false. + # 影响调试器展示的信息范围;false 只显示帧时间,true 显示更多细节(仅在开启调试器时生效)。 + advanced_debugging_info: false + + # Whether to use the GL_R11F_G11F_B10F texture format to save memory + # and bandwidth. Usually you want to enable this, however it can + # cause banding sometimes, in which case you can disable this setting. + # 是否使用 GL_R11F_G11F_B10F 纹理格式以节省显存/带宽;可能引入色带时可关闭。 + use_r11_g11_b10: false + + # Enables to render at a higher or lower resolution than the window size. + # A value of 2.0 for example renders at twice the resolution (supoersampling) + # whereas a value of 0.5 would render at half resolution. + # 允许以不同于窗口分辨率的比例渲染:2.0 为超采样两倍分辨率,0.5 为半分辨率渲染。 + resolution_scale: 1.0 + + # Whether to render in a special reference mode, which displays the + # environment map as a background, and disable special effects like color + # grading and so on. This is used by the pathtracing reference. + # 是否启用参考模式:用环境贴图作为背景并关闭色调映射等特效,供路径追踪参考使用。 + reference_mode: false + +# This are the settings affecting the lighting part of the pipeline, +# including builtin shadows and lights. +# 以下为光照部分的设置,包含内置阴影与光源处理。 +lighting: + # The pipeline uses clustered deferred shading, this means that the + # screen gets divided into tiles, and for each tile, the lights affecting + # that tile are accumulated. You can adjust the tile size here (in pixels), + # optimal is a tile size which is not too big (to avoid unecessary shading), + # but also not too small (to avoid excessive culling). + # 采用聚类延迟着色,屏幕分片后对每片累积灯光;可调分片像素尺寸,过大浪费着色,过小增加裁剪开销。 + culling_grid_size_x: 24 + culling_grid_size_y: 16 + + # The view frustum is additionally divived into slices, to be able to do + # better culling. If you use a higher amount of slices, the culling will + # get more exact, but also more expensive. You have to find the optimal + # size depending on your scene. + # 视锥进一步分层以改进裁剪;层数多精度高但开销大,需按场景权衡。 + culling_grid_slices: 32 + + # This controls the maximum culling distance in world space. After this + # distance, no lights are rendered anymore. If you choose a lower + # distance, this *can* positively impact performance, but you should not + # set it too low, to avoid getting artifacts. + # 控制光源裁剪的最大世界距离,超过即不渲染;降低可提速但过低会带来缺失伪影。 + culling_max_distance: 500.0 + + # Controls the size of a slice in culling. Lower values might produce + # better performance for less amount of lights, but higher values should + # be used when using many lights, e.g. > 1024, to get better coherency. + # 控制裁剪 slice 的宽度;灯光少可用小值提升性能,灯光多(>1024)用大值提升一致性。 + culling_slice_width: 2048 + + # Controls the maximum amount of lights for each cell. If this value + # is set too low, you might get artifacts when having many lights. + # In general, try to set this value as low as possible without getting + # artifacts + # 每个 cell 允许的最大灯光数量,过低会在灯光密集时出伪影;尽量低但避免出现缺失。 + max_lights_per_cell: 64 + +shadows: + # The size of the global shadow atlas, used for point and spot light + # shadows. This should be a power of 2. + # 全局阴影图集尺寸(点光/聚光阴影),应为 2 的幂。 + atlas_size: 4096 + + # Maximum of shadow updates which may occur at one time. All updates + # which are beyond that count will get delayed to the next frame. + # If you set this too low, artifacts may occur because of shadows not + # getting updated fast enough. However, this also affects the performance + # quite a bit, since for every shadow map a part of the scene has + # to get re-rendered. + # 单帧内允许的阴影更新最大数量,超出推迟到下一帧;过低会更新不及时产生伪影,但过高会拖慢渲染。 + max_updates: 8 + + # Sets the maximum distance until which shadows are updated. If a shadow + # source is further away, it will no longer recieve updates + # 阴影更新的最远距离,超过距离的阴影源不再更新。 + max_update_distance: 150.0 diff --git a/config/plugins.yaml b/config/plugins.yaml new file mode 100644 index 0000000..f782b09 --- /dev/null +++ b/config/plugins.yaml @@ -0,0 +1,198 @@ +# Render Pipeline Plugin Configuration +# Instead of editing this file, prefer to use the Plugin Configurator +# Any formatting and comments will be lost +# 渲染管线插件配置;建议用插件配置器修改,此文件的格式和注释会在工具写回时丢失。 + +enabled: + - ao # 屏幕空间环境光遮蔽 + - bloom # 泛光 + - color_correction # 曝光/色调/色差/锐化 + - env_probes # 环境探针反射/IBL + - forward_shading # 前向通道(透明/特殊材质) + # - motion_blur # 动态模糊 + - pssm # 阴影(PSSM) + - scattering # 大气散射/天空 + # - clouds # 体积云 + - skin_shading # 皮肤次表面 + - sky_ao # 天空方向的环境遮蔽 + - smaa # SMAA 抗锯齿 + - ssr # 屏幕空间反射 + # - dof # 景深 + # - fxaa # FXAA 抗锯齿 + # - volumetrics # 体积光 + # - vxgi # 体素 GI + +overrides: + ao: + blur_quality: MEDIUM # 模糊质量 + blur_normal_factor: 2.97 # 模糊时法线权重 + blur_depth_factor: 0.88158 # 模糊时深度权重 + occlusion_strength: 2.19 # AO 强度 + clip_length: 4 # 采样裁剪长度 + technique: SSAO # AO 算法(SSAO/HBAO/SSVO/UE4AO/Alchemy) + ssao_sample_radius: 95.29 # SSAO 半径 + ssao_sequence: halton_3D_8 # SSAO 采样序列 + ssao_bias: 0.0143 # SSAO 自遮挡偏移 + ssao_max_distance: 7.5 # SSAO 最大距离 + hbao_sample_radius: 255.0 # HBAO 半径 + hbao_ray_count: 4 # HBAO 射线数量 + hbao_ray_steps: 3 # HBAO 射线步数 + hbao_tangent_bias: 0.64997 # HBAO 切线偏移 + hbao_max_distance: 11.5 # HBAO 最大距离 + ssvo_sequence: halton_2D_8 # SSVO 序列 + ssvo_sphere_radius: 18.0 # SSVO 球半径 + ssvo_max_distance: 3.19 # SSVO 最大距离 + alchemy_sample_radius: 38.86 # Alchemy 半径 + alchemy_sequence: halton_2D_8 # Alchemy 序列 + alchemy_max_distance: 5.86 # Alchemy 最大距离 + ue4ao_sample_radius: 50.14286 # UE4AO 半径 + ue4ao_sample_sequence: halton_2D_8 # UE4AO 序列 + ue4ao_max_distance: 1.47 # UE4AO 最大距离 + + bloom: + num_mipmaps: 6 # 采样层数 + bloom_strength: 0.8003 # 泛光强度 + remove_fireflies: False # 去除亮点噪声 + lens_dirt_factor: 0.0 # 镜头污渍混合 + + clouds: + raymarch_steps: 160 # 云体积采样步数 + + color_correction: + tonemap_operator: optimized # 色调映射算子 + reinhard_version: rgb # Reinhard 版本 + exponential_factor: 1.23 # 指数算子强度 + uc2t_shoulder_strength: 0.3352 # UC2T 肩部 + uc2t_linear_strength: 0.5339 # UC2T 线性段强度 + uc2t_linear_angle: 0.1797 # UC2T 线性段角度 + uc2t_toe_strength: 0.3919 # UC2T 暗部压缩 + uc2t_toe_numerator: 0.0029 # UC2T 暗部分子 + uc2t_toe_denumerator: 0.2787 # UC2T 暗部分母 + uc2t_reference_white: 10.05 # UC2T 参考白 + vignette_strength: 0.1286 # 暗角强度 + film_grain_strength: 0.1286 # 胶片颗粒 + color_lut: film_luts/default_lut.png # LUT 路径 + use_chromatic_aberration: True # 色差开关 + chromatic_aberration_strength: 0.019 # 色差强度 + chromatic_aberration_samples: 2 # 色差采样数 + manual_camera_parameters: False # False=自动曝光 + min_exposure_value: 0.01 # 最小曝光 + max_exposure_value: 1.0 # 最大曝光 + exposure_scale: 1.0 # 曝光缩放 + brightness_adaption_rate: 3.6 # 变亮响应 + darkness_adaption_rate: 0.7 # 变暗响应 + use_sharpen: True # 锐化开关 + sharpen_strength: 0.5 # 锐化强度 + sharpen_twice: False # 是否二次锐化 + + dof: + focal_point: 1000.0 # 焦点距离 + focal_size: 994.0 # 焦平面厚度 + blur_strength: 0.0 # 远景模糊强度 + near_blur_strength: 0.4286 # 近景模糊强度 + + env_probes: + probe_resolution: 128 # 反射探针分辨率 + diffuse_probe_resolution: 2 # 漫反射探针分辨率 + max_probes: 16 # 最大探针数 + max_probes_per_cell: 3 # 每单元最大探针 + + forward_shading: + # 无额外参数 + + fxaa: + quality: ultra # 质量档位 + subpixel_quality: 0.5 # 次像素质量 + edge_threshold: 0.166 # 边缘阈值 + min_threshold: 0.833 # 最小阈值 + + motion_blur: + num_camera_samples: 6 # 相机采样数 + camera_blur_factor: 0.4 # 相机模糊权重 + enable_object_blur: False # 启用物体模糊 + blur_factor: 0.5 # 物体模糊权重 + tile_size: 32 # 速度图 tile 大小 + max_blur_radius: 10.0 # 最大模糊半径 + num_samples: 12 # 模糊采样数 + + pssm: + max_distance: 50.0 # 阴影覆盖距离 + logarithmic_factor: 3.0 # 分割对数因子 + sun_distance: 100.0 # 太阳虚拟距离 + split_count: 4 # 分割数 + resolution: 1024 # 主阴影分辨率 + border_bias: 0.058 # 边界偏移 + use_pcf: True # 启用 PCF + filter_sequence: halton_2D_32 # PCF 序列 + filter_radius: 0.7 # PCF 半径 + fixed_bias: 0.11429 # 固定偏移 + slope_bias: 0.0 # 斜率偏移 + normal_bias: 0.67 # 法线偏移 + use_pcss: False # 启用 PCSS + pcss_sequence: halton_2D_16 # PCSS 序列 + pcss_penumbra_size: 2.38 # 半影尺寸 + pcss_min_penumbra_size: 7.0 # 半影最小尺寸 + use_distant_shadows: True # 远景阴影 + dist_shadow_resolution: 4096 # 远景阴影分辨率 + dist_shadow_clipsize: 400.0 # 远景裁剪体大小 + dist_shadow_sundist: 300.0 # 远景光源距离 + scene_shadow_resolution: 512 # 近景阴影分辨率 + scene_shadow_sundist: 300.0 # 近景光源距离 + + scattering: + scattering_method: eric_bruneton # 大气模型 + ground_reflectance: 0.1231 # 地表反照率 + rayleigh_factor: 0.5 # 瑞利散射系数 + rayleigh_height_scale: 8.0 # 瑞利高度尺度 + mie_height_scale: 1.3 # 米氏高度尺度 + mie_phase_factor: 0.3 # 米氏相函数偏前向 + beta_mie_scattering: 4.0 # 米氏散射强度 + enable_godrays: False # 光束/耶稣光 + atmosphere_start: 549.61 # 大气起始高度 + + skin_shading: + quality: medium # 质量档 + blur_scale: 0.43 # 次表面模糊尺度 + + sky_ao: + sample_radius: 17.17 # 采样半径 + max_radius: 500.0 # 最大距离 + resolution: 1024 # 贴图分辨率 + sample_sequence: poisson_2D_32 # 采样序列 + ao_multiplier: 0.83 # AO 强度 + ao_bias: 0.0 # AO 偏移 + blend_factor: 0.01 # 混合因子 + capture_height: 568.75 # 捕捉高度 + + smaa: + use_reprojection: True # 是否使用历史重投影 + smaa_quality: ultra # 质量档位 + jitter_pattern: halton8 # 抖动序列 + history_length: 8 # 历史帧长度 + jitter_amount: 0.16143 # 抖动幅度 + + ssr: + effect_scale: 1.0 # 效果强度缩放 + trace_steps: 64 # 追踪步数 + history_length: 16 # 历史长度 + abort_on_object_infront: True # 前方遮挡终止 + intial_bias: 0.1 # 初始偏移 + hit_tolerance: 0.1 # 命中容差 + roughness_fade: 0.72 # 粗糙度衰减 + skip_invalid_samples: False # 跳过无效样本 + border_fade: 0.005 # 边缘淡出 + + volumetrics: + enable_volumetric_shadows: True # 体积阴影开关 + volumetric_shadow_intensity: 8.31 # 阴影强度 + volumetric_shadow_brightness: 1.66 # 阴影亮度 + volumetric_shadow_pow: 1.15999 # 阴影幂次 + volumetric_max_distance: 79.41429 # 体积最大距离 + volumetric_shadow_fadein_distance: 9.61 # 阴影淡入 + volumetric_num_steps: 128 # 体积步数 + + vxgi: + grid_resolution: 256 # 体素网格分辨率 + grid_ws_size: 100.0 # 网格世界尺寸 + diffuse_cone_steps: 32 # 漫反射锥步数 + specular_cone_steps: 150 # 高光锥步数 diff --git a/config/stages.yaml b/config/stages.yaml new file mode 100644 index 0000000..651c9dc --- /dev/null +++ b/config/stages.yaml @@ -0,0 +1,74 @@ +# This file controls the order of all render stages. +# 控制所有渲染阶段的执行顺序。 + +# Usually you do not have to modify this, except if you are adding new plugins. +# If you move stages, you should know what you do. +# 通常无需修改,只有添加新插件时才调整;移动阶段需明确其作用与依赖。 + +# Commenting out a stage won't disable it, but instead produce an error when +# it is created. +# 将阶段注释掉并不会禁用,而是在创建时抛出错误。 + +global_stage_order: + # Shadows, Environment and Voxelization + # 阴影、环境与体素化阶段 + - PSSMShadowStage + - PSSMDistShadowStage + - PSSMSceneShadowStage + - ScatteringEnvmapStage + - SkyAOCaptureStage + - EnvironmentCaptureStage + - VoxelizationStage + + # Main scene + # 主场景阶段 + - GBufferStage + - ShadowStage + - DownscaleZStage + - CombineVelocityStage + + # Light(-culling) + # 灯光及灯光裁剪阶段 + - FlagUsedCellsStage + - CollectUsedCellsStage + - CullLightsStage + - CullProbesStage + + # Plugins + # 插件阶段 + - CloudVoxelStage + - AOStage + - SkyAOStage + - ApplyLightsStage + - PSSMStage + - ScatteringStage + - ApplyEnvprobesStage + - VXGIStage + - SSRStage + + - AmbientStage + - ForwardStage + + - ApplyCloudsStage + - GodrayStage + - VolumetricsStage + - AutoExposureStage + - ManualExposureStage + + # Post AA & Effects + # 抗锯齿与后期效果 + - BloomStage + - TonemappingStage + - SMAAStage + - FXAAStage + - DoFStage + - MotionBlurStage + - SkinShadingStage + - SharpenStage + - ColorCorrectionStage + + # Finishing stages, do not insert anything below + # 收尾阶段,下面不要插入新阶段 + - UpscaleStage + - FinalStage + - UpdatePreviousPipesStage diff --git a/config/task-scheduler.yaml b/config/task-scheduler.yaml new file mode 100644 index 0000000..9e0ea75 --- /dev/null +++ b/config/task-scheduler.yaml @@ -0,0 +1,34 @@ + +# This file controls which tasks are allowed to run each frame. +# Usually you do not have to edit this file, except when developing plugins. +# 控制每帧允许运行的任务列表,除非开发插件一般无需修改。 + +frame_cycles: !!omap + + - frame1: + - envprobes_select_and_cull + - pssm_scene_shadows + + - frame2: + - envprobes_capture_envmap_face0 + - pssm_distant_shadows + + - frame3: + - envprobes_capture_envmap_face1 + - pssm_convert_distant_to_esm + + - frame4: + - envprobes_capture_envmap_face2 + - pssm_blur_distant_vert + + - frame5: + - pssm_blur_distant_horiz + - envprobes_capture_envmap_face3 + - envprobes_capture_envmap_face4 + + - frame6: + - envprobes_capture_envmap_face5 + - scattering_update_envmap + + - frame7: + - envprobes_filter_and_store_envmap diff --git a/data/builtin_models/skybox/SOURCE.txt b/data/builtin_models/skybox/SOURCE.txt new file mode 100644 index 0000000..68971e9 --- /dev/null +++ b/data/builtin_models/skybox/SOURCE.txt @@ -0,0 +1,16 @@ + +The skydomes for the skybox were taken from: + + +Skybox.jpg: + +http://www.gravis.com.ua/gal/content/photoprint/sky/sk_21.jpg + + +Skybox2.jpg: + +http://www.artist-reference.com/wp-content/gallery/marlin-studios-gallery/sky-dome-panorma.jpg + + + +I couldn't find a direct license for those photos. If there is one, please contact me. diff --git a/data/builtin_models/skybox/skybox-2.jpg b/data/builtin_models/skybox/skybox-2.jpg new file mode 100644 index 0000000..fa0b417 Binary files /dev/null and b/data/builtin_models/skybox/skybox-2.jpg differ diff --git a/data/builtin_models/skybox/skybox-blend.zip b/data/builtin_models/skybox/skybox-blend.zip new file mode 100644 index 0000000..c5738d2 Binary files /dev/null and b/data/builtin_models/skybox/skybox-blend.zip differ diff --git a/data/builtin_models/skybox/skybox.bam b/data/builtin_models/skybox/skybox.bam new file mode 100644 index 0000000..f4ecd3b Binary files /dev/null and b/data/builtin_models/skybox/skybox.bam differ diff --git a/data/builtin_models/skybox/skybox.jpg b/data/builtin_models/skybox/skybox.jpg new file mode 100644 index 0000000..bace855 Binary files /dev/null and b/data/builtin_models/skybox/skybox.jpg differ diff --git a/data/default_cubemap/filter.compute.glsl b/data/default_cubemap/filter.compute.glsl new file mode 100644 index 0000000..892e8b6 --- /dev/null +++ b/data/default_cubemap/filter.compute.glsl @@ -0,0 +1,116 @@ +#version 430 + +// Shader to pre-filter the cubemap using importance sampling + +layout (local_size_x = 16, local_size_y = 16, local_size_z = 1) in; + + +#define M_PI 3.1415926535897932384626433 + +vec3 get_transformed_coord(vec2 coord, uint face) { + float f = 1.0; + switch (face) { + case 1: return vec3(-f, coord); + case 2: return vec3(coord, -f); + case 0: return vec3(f, -coord.x, coord.y); + case 3: return vec3(coord.xy * vec2(1, -1), f); + case 4: return vec3(coord.x, f, coord.y); + case 5: return vec3(-coord.x, -f, coord.y); + } + return vec3(0); +} + +// From: +// http://www.trentreed.net/blog/physically-based-shading-and-image-based-lighting/ +vec2 hammersley(uint i, uint N) +{ + return vec2(float(i) / float(N), float(bitfieldReverse(i)) * 2.3283064365386963e-10); +} + +// From: +// http://www.gamedev.net/topic/655431-ibl-problem-with-consistency-using-ggx-anisotropy/ +vec3 importance_sample_ggx(vec2 xi, float roughness) +{ + float r_square = roughness * roughness; + float phi = 2 * M_PI * xi.x; + float cos_theta = sqrt((1 - xi.y) / (1 + (r_square * r_square - 1) * xi.y)); + float sin_theta = sqrt(1 - cos_theta * cos_theta); + + return vec3(sin_theta * cos(phi), sin_theta * sin(phi), cos_theta); +} + +// Converts a normalized spherical coordinate (r = 1) to cartesian coordinates +vec3 spherical_to_vector(float theta, float phi) { + float sin_theta = sin(theta); + return normalize(vec3( + sin_theta * cos(phi), + sin_theta * sin(phi), + cos(theta) + )); +} + +float brdf_distribution_ggx(float NxH, float roughness) { + float nxh_sq = NxH * NxH; + float tan_sq = (1 - nxh_sq) / nxh_sq; + float f = roughness / max(1e-10, nxh_sq * (roughness * roughness + tan_sq)); + return f * f / M_PI; +} + +// Finds a tangent and bitangent vector based on a given normal +void find_arbitrary_tangent(vec3 normal, out vec3 tangent, out vec3 bitangent) { + vec3 v0 = abs(normal.z) < 0.999 ? vec3(0, 0, 1) : vec3(0, 1, 0); + tangent = normalize(cross(v0, normal)); + bitangent = normalize(cross(tangent, normal)); +} + +vec3 transform_cubemap_coordinates(vec3 coord) { + return normalize(coord.xyz * vec3(1, -1, 1)); +} + +uniform samplerCube SourceTex; +uniform int currentSize; +uniform int currentMip; +uniform int currentFace; +layout(rgba16f) uniform imageCube DestTex; + +void main() { + ivec2 coord = ivec2(gl_GlobalInvocationID.xy); + + vec2 texcoord = vec2(coord + 0.5) / float(currentSize); + texcoord = texcoord * 2.0 - 1.0; + + vec3 n = get_transformed_coord(texcoord, currentFace); + n = normalize(n); + n = transform_cubemap_coordinates(n); + float roughness = clamp(float(currentMip) / 7.0, 0.001, 1.0); + // roughness *= roughness; + + vec3 tangent, binormal; + find_arbitrary_tangent(n, tangent, binormal); + + vec4 accum = vec4(0); + const uint num_samples = 512; + + // Ultra high quality, might cause TDR on low-end systems + // const uint num_samples = 4096; + for (uint i = 0; i < num_samples; ++i) { + vec2 xi = hammersley(i, num_samples); + vec3 r = importance_sample_ggx(xi, roughness); + vec3 h = normalize(r.x * tangent + r.y * binormal + r.z * n); + vec3 l = 2.0 * dot(n, h) * h - n; + + float NxL = clamp(dot(n, l), 0.0, 1.0); + float NxH = clamp(dot(n, h), 0.0, 1.0); + + vec3 sampled = textureLod(SourceTex, l, 0).rgb; + + float weight = 1; + weight = clamp(weight, 0.0, 1.0); + accum += vec4(sampled, 1) * weight; + } + + accum /= max(0.1, accum.w); + accum.xyz = pow(accum.xyz, vec3(2.2)); + + imageStore(DestTex, ivec3(coord, currentFace), vec4(accum.xyz, 1.0)); +} diff --git a/data/default_cubemap/filter.py b/data/default_cubemap/filter.py new file mode 100644 index 0000000..3794acc --- /dev/null +++ b/data/default_cubemap/filter.py @@ -0,0 +1,105 @@ +""" + +RenderPipeline + +Copyright (c) 2014-2016 tobspr + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. + +""" + +from __future__ import print_function, division + +import os +import shutil +from os.path import dirname, realpath +from panda3d.core import * +from direct.stdpy.file import isdir, isfile, join +from direct.showbase.ShowBase import ShowBase + +class Application(ShowBase): + def __init__(self): + load_prc_file_data("", """ + textures-power-2 none + window-type offscreen + win-size 100 100 + gl-coordinate-system default + notify-level-display error + print-pipe-types #f + gl-version 4 3 + """) + + ShowBase.__init__(self) + + base_path = realpath(dirname(__file__)) + os.chdir(base_path) + filter_dir = join(base_path, "tmp/") + if isdir(filter_dir): + shutil.rmtree(filter_dir) + os.makedirs(filter_dir) + + source_path = join(base_path, "source") + print(source_path) + extension = ".jpg" + if isfile(join(source_path, "1.png")): + extension = ".png" + + cubemap = self.loader.loadCubeMap(Filename.from_os_specific(join(source_path, "#" + extension))) + mipmap, size = -1, 1024 + + cshader = Shader.load_compute(Shader.SL_GLSL, "filter.compute.glsl") + + while size > 1: + size = size // 2 + mipmap += 1 + print("Filtering mipmap", mipmap) + + dest_cubemap = Texture("Dest") + dest_cubemap.setup_cube_map(size, Texture.T_float, Texture.F_rgba16) + node = NodePath("") + + for i in range(6): + node.set_shader(cshader) + node.set_shader_inputs( + SourceTex=cubemap, + DestTex=dest_cubemap, + currentSize=size, + currentMip=mipmap, + currentFace=i) + attr = node.get_attrib(ShaderAttrib) + self.graphicsEngine.dispatch_compute(( (size + 15) // 16, (size+15) // 16, 1), attr, self.win.gsg) + + print(" Extracting data ..") + + self.graphicsEngine.extract_texture_data(dest_cubemap, self.win.gsg) + + print(" Writing data ..") + dest_cubemap.write(join(filter_dir, "{}-#.png".format(mipmap)), 0, 0, True, False) + + + print("Reading in data back in ..") + tex = self.loader.loadCubeMap(Filename.from_os_specific(join(base_path, "tmp/#-#.png")), readMipmaps="True") + + print("Writing txo ..") + tex.write("data/default_cubemap/" + "cubemap.txo.pz") + + shutil.rmtree(join(base_path, "tmp")) + + +Application() diff --git a/data/default_cubemap/source/0.png b/data/default_cubemap/source/0.png new file mode 100644 index 0000000..4d80497 Binary files /dev/null and b/data/default_cubemap/source/0.png differ diff --git a/data/default_cubemap/source/1.png b/data/default_cubemap/source/1.png new file mode 100644 index 0000000..ac61fcc Binary files /dev/null and b/data/default_cubemap/source/1.png differ diff --git a/data/default_cubemap/source/2.png b/data/default_cubemap/source/2.png new file mode 100644 index 0000000..bf7d53e Binary files /dev/null and b/data/default_cubemap/source/2.png differ diff --git a/data/default_cubemap/source/3.png b/data/default_cubemap/source/3.png new file mode 100644 index 0000000..9e3a1c3 Binary files /dev/null and b/data/default_cubemap/source/3.png differ diff --git a/data/default_cubemap/source/4.png b/data/default_cubemap/source/4.png new file mode 100644 index 0000000..5f3dc99 Binary files /dev/null and b/data/default_cubemap/source/4.png differ diff --git a/data/default_cubemap/source/5.png b/data/default_cubemap/source/5.png new file mode 100644 index 0000000..53b1189 Binary files /dev/null and b/data/default_cubemap/source/5.png differ diff --git a/data/default_cubemap/source_2/0.jpg b/data/default_cubemap/source_2/0.jpg new file mode 100644 index 0000000..4167546 Binary files /dev/null and b/data/default_cubemap/source_2/0.jpg differ diff --git a/data/default_cubemap/source_2/1.jpg b/data/default_cubemap/source_2/1.jpg new file mode 100644 index 0000000..8235d6a Binary files /dev/null and b/data/default_cubemap/source_2/1.jpg differ diff --git a/data/default_cubemap/source_2/2.jpg b/data/default_cubemap/source_2/2.jpg new file mode 100644 index 0000000..38f8501 Binary files /dev/null and b/data/default_cubemap/source_2/2.jpg differ diff --git a/data/default_cubemap/source_2/3.jpg b/data/default_cubemap/source_2/3.jpg new file mode 100644 index 0000000..837448d Binary files /dev/null and b/data/default_cubemap/source_2/3.jpg differ diff --git a/data/default_cubemap/source_2/4.jpg b/data/default_cubemap/source_2/4.jpg new file mode 100644 index 0000000..550fd0c Binary files /dev/null and b/data/default_cubemap/source_2/4.jpg differ diff --git a/data/default_cubemap/source_2/5.jpg b/data/default_cubemap/source_2/5.jpg new file mode 100644 index 0000000..9db7093 Binary files /dev/null and b/data/default_cubemap/source_2/5.jpg differ diff --git a/data/default_cubemap/source_3/0.png b/data/default_cubemap/source_3/0.png new file mode 100644 index 0000000..e4d6ae3 Binary files /dev/null and b/data/default_cubemap/source_3/0.png differ diff --git a/data/default_cubemap/source_3/1.png b/data/default_cubemap/source_3/1.png new file mode 100644 index 0000000..d0fdb05 Binary files /dev/null and b/data/default_cubemap/source_3/1.png differ diff --git a/data/default_cubemap/source_3/2.png b/data/default_cubemap/source_3/2.png new file mode 100644 index 0000000..8d62293 Binary files /dev/null and b/data/default_cubemap/source_3/2.png differ diff --git a/data/default_cubemap/source_3/3.png b/data/default_cubemap/source_3/3.png new file mode 100644 index 0000000..b8174e4 Binary files /dev/null and b/data/default_cubemap/source_3/3.png differ diff --git a/data/default_cubemap/source_3/4.png b/data/default_cubemap/source_3/4.png new file mode 100644 index 0000000..8f149e6 Binary files /dev/null and b/data/default_cubemap/source_3/4.png differ diff --git a/data/default_cubemap/source_3/5.png b/data/default_cubemap/source_3/5.png new file mode 100644 index 0000000..9148feb Binary files /dev/null and b/data/default_cubemap/source_3/5.png differ diff --git a/data/empty_textures/README.md b/data/empty_textures/README.md new file mode 100644 index 0000000..2b68381 --- /dev/null +++ b/data/empty_textures/README.md @@ -0,0 +1,7 @@ + +### Empty textures + +This are the empty textures you can use in your models in case you don't have +a detailmap for example. + +See the wiki for further information. diff --git a/data/empty_textures/empty_basecolor.png b/data/empty_textures/empty_basecolor.png new file mode 100644 index 0000000..437c244 Binary files /dev/null and b/data/empty_textures/empty_basecolor.png differ diff --git a/data/empty_textures/empty_normal.png b/data/empty_textures/empty_normal.png new file mode 100644 index 0000000..863dc2e Binary files /dev/null and b/data/empty_textures/empty_normal.png differ diff --git a/data/empty_textures/empty_roughness.png b/data/empty_textures/empty_roughness.png new file mode 100644 index 0000000..437c244 Binary files /dev/null and b/data/empty_textures/empty_roughness.png differ diff --git a/data/empty_textures/empty_specular.png b/data/empty_textures/empty_specular.png new file mode 100644 index 0000000..437c244 Binary files /dev/null and b/data/empty_textures/empty_specular.png differ diff --git a/data/environment_brdf/generate_reference.py b/data/environment_brdf/generate_reference.py new file mode 100644 index 0000000..a13bcd0 --- /dev/null +++ b/data/environment_brdf/generate_reference.py @@ -0,0 +1,120 @@ +""" + +Uses mitsuba to generate the environment brdf + +""" + +from __future__ import print_function + +import os +import sys +import math +from panda3d.core import PNMImage, load_prc_file_data, Vec3 + +load_prc_file_data("", "notify-level error") +load_prc_file_data("", "notify-level-pnmimage error") + +configs = { + "normal": { + "out_dir": "slices", + "out_name": "env_brdf_{}.png", + "template_suffix": "", + "sequence": xrange(7), + "samples": 32, + }, + "metallic": { + "out_dir": "slices_metal", + "out_name": "env_brdf.png", + "template_suffix": "-metal", + "sequence": [1], + "samples": 32, + }, + "clearcoat": { + "out_dir": "slices_coat", + "out_name": "env_brdf.png", + "template_suffix": "-coat", + "sequence": [1], + "samples": 2048, + } +} + +# configs_to_run = ["normal", "metallic", "clearcoat"] +configs_to_run = ["clearcoat"] + +for config_name in configs_to_run: + + config = configs[config_name] + + if not os.path.isdir(config["out_dir"]): + os.makedirs(config["out_dir"]) + + + for pass_index in config["sequence"]: + + ior = 1.01 + 0.2 * pass_index + + dest_size = 512 + dest_h = 32 + dest = PNMImage(dest_size, dest_h) + + # run mitsuba + print("Running mitsuba for ior =", ior, "( index =", pass_index,")") + with open("res/scene" + config["template_suffix"] + ".templ.xml", "r") as handle: + content = handle.read() + + content = content.replace("%IOR%", str(ior)) + content = content.replace("%SAMPLES%", str(config["samples"])) + + with open("res/scene.xml", "w") as handle: + handle.write(content) + + os.system("run_mitsuba.bat") + + img = PNMImage("scene.png") + source_w = img.get_x_size() + + print("Converting ..") + + indices = [] + nxv_values = [] + + # Generate nonlinear NxV sequence + for i in xrange(source_w): + v = 1 - i / float(source_w) + NxV = math.sqrt(1 - v*v) + nxv_values.append(NxV) + + # Generate lerp indices and weights + for x in xrange(dest_size): + NxV = (x) / float(dest_size) + index = 0 + for i, s_nxv in enumerate(reversed(nxv_values)): + if NxV >= s_nxv: + index = i + break + index = len(nxv_values) - index - 1 + next_index = index + 1 if index < dest_size - 1 else index + + curr_nxv = nxv_values[index] + next_nxv = nxv_values[next_index] + + lerp_factor = (NxV - curr_nxv) / max(1e-10, abs(next_nxv - curr_nxv)) + lerp_factor = max(0.0, min(1.0, lerp_factor)) + indices.append((index, next_index, lerp_factor)) + + # Generate the final linear lut using the lerp weights + for y in xrange(dest_h): + for x in xrange(dest_size): + curr_i, next_i, lerp = indices[x] + curr_v = img.get_xel(curr_i, y) + next_v = img.get_xel(next_i, y) + dest.set_xel(x, y, curr_v * (1 - lerp) + next_v * lerp) + + + out_name = config["out_name"].replace("{}", str(pass_index)) + dest.write(config["out_dir"] + "/" + out_name) + +try: + os.remove("scene.png") +except: + pass diff --git a/data/environment_brdf/res/environment.png b/data/environment_brdf/res/environment.png new file mode 100644 index 0000000..33b80f8 Binary files /dev/null and b/data/environment_brdf/res/environment.png differ diff --git a/data/environment_brdf/res/roughness.png b/data/environment_brdf/res/roughness.png new file mode 100644 index 0000000..6351314 Binary files /dev/null and b/data/environment_brdf/res/roughness.png differ diff --git a/data/environment_brdf/res/scene-coat.templ.xml b/data/environment_brdf/res/scene-coat.templ.xml new file mode 100644 index 0000000..0906e4d --- /dev/null +++ b/data/environment_brdf/res/scene-coat.templ.xml @@ -0,0 +1,68 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/data/environment_brdf/res/scene-metal.templ.xml b/data/environment_brdf/res/scene-metal.templ.xml new file mode 100644 index 0000000..4b0c191 --- /dev/null +++ b/data/environment_brdf/res/scene-metal.templ.xml @@ -0,0 +1,56 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/data/environment_brdf/res/scene.templ.xml b/data/environment_brdf/res/scene.templ.xml new file mode 100644 index 0000000..8f4a970 --- /dev/null +++ b/data/environment_brdf/res/scene.templ.xml @@ -0,0 +1,62 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/data/environment_brdf/res/scene.xml b/data/environment_brdf/res/scene.xml new file mode 100644 index 0000000..32e22b2 --- /dev/null +++ b/data/environment_brdf/res/scene.xml @@ -0,0 +1,68 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/data/environment_brdf/run_mitsuba.bat b/data/environment_brdf/run_mitsuba.bat new file mode 100644 index 0000000..00a6e43 --- /dev/null +++ b/data/environment_brdf/run_mitsuba.bat @@ -0,0 +1,10 @@ +@echo off + +"C:/mitsuba/mitsuba" -p 6 res/scene.xml +echo "" +echo Rendering done +echo "" +echo "" +echo "" +"C:/mitsuba/mtsutil" tonemap -g 2.0 res/scene.exr +copy res\scene.png scene.png diff --git a/data/environment_brdf/slices/env_brdf_0.png b/data/environment_brdf/slices/env_brdf_0.png new file mode 100644 index 0000000..c38078c Binary files /dev/null and b/data/environment_brdf/slices/env_brdf_0.png differ diff --git a/data/environment_brdf/slices/env_brdf_1.png b/data/environment_brdf/slices/env_brdf_1.png new file mode 100644 index 0000000..88478f1 Binary files /dev/null and b/data/environment_brdf/slices/env_brdf_1.png differ diff --git a/data/environment_brdf/slices/env_brdf_10.png b/data/environment_brdf/slices/env_brdf_10.png new file mode 100644 index 0000000..2af90cc Binary files /dev/null and b/data/environment_brdf/slices/env_brdf_10.png differ diff --git a/data/environment_brdf/slices/env_brdf_11.png b/data/environment_brdf/slices/env_brdf_11.png new file mode 100644 index 0000000..730a052 Binary files /dev/null and b/data/environment_brdf/slices/env_brdf_11.png differ diff --git a/data/environment_brdf/slices/env_brdf_12.png b/data/environment_brdf/slices/env_brdf_12.png new file mode 100644 index 0000000..a1a1391 Binary files /dev/null and b/data/environment_brdf/slices/env_brdf_12.png differ diff --git a/data/environment_brdf/slices/env_brdf_13.png b/data/environment_brdf/slices/env_brdf_13.png new file mode 100644 index 0000000..2aa6940 Binary files /dev/null and b/data/environment_brdf/slices/env_brdf_13.png differ diff --git a/data/environment_brdf/slices/env_brdf_14.png b/data/environment_brdf/slices/env_brdf_14.png new file mode 100644 index 0000000..954fd84 Binary files /dev/null and b/data/environment_brdf/slices/env_brdf_14.png differ diff --git a/data/environment_brdf/slices/env_brdf_2.png b/data/environment_brdf/slices/env_brdf_2.png new file mode 100644 index 0000000..73c3f03 Binary files /dev/null and b/data/environment_brdf/slices/env_brdf_2.png differ diff --git a/data/environment_brdf/slices/env_brdf_3.png b/data/environment_brdf/slices/env_brdf_3.png new file mode 100644 index 0000000..fcff569 Binary files /dev/null and b/data/environment_brdf/slices/env_brdf_3.png differ diff --git a/data/environment_brdf/slices/env_brdf_4.png b/data/environment_brdf/slices/env_brdf_4.png new file mode 100644 index 0000000..b00ab37 Binary files /dev/null and b/data/environment_brdf/slices/env_brdf_4.png differ diff --git a/data/environment_brdf/slices/env_brdf_5.png b/data/environment_brdf/slices/env_brdf_5.png new file mode 100644 index 0000000..53ca700 Binary files /dev/null and b/data/environment_brdf/slices/env_brdf_5.png differ diff --git a/data/environment_brdf/slices/env_brdf_6.png b/data/environment_brdf/slices/env_brdf_6.png new file mode 100644 index 0000000..0ea35e5 Binary files /dev/null and b/data/environment_brdf/slices/env_brdf_6.png differ diff --git a/data/environment_brdf/slices/env_brdf_7.png b/data/environment_brdf/slices/env_brdf_7.png new file mode 100644 index 0000000..d5aaebb Binary files /dev/null and b/data/environment_brdf/slices/env_brdf_7.png differ diff --git a/data/environment_brdf/slices/env_brdf_8.png b/data/environment_brdf/slices/env_brdf_8.png new file mode 100644 index 0000000..c426f22 Binary files /dev/null and b/data/environment_brdf/slices/env_brdf_8.png differ diff --git a/data/environment_brdf/slices/env_brdf_9.png b/data/environment_brdf/slices/env_brdf_9.png new file mode 100644 index 0000000..0a35d21 Binary files /dev/null and b/data/environment_brdf/slices/env_brdf_9.png differ diff --git a/data/environment_brdf/slices_coat/env_brdf.png b/data/environment_brdf/slices_coat/env_brdf.png new file mode 100644 index 0000000..5267681 Binary files /dev/null and b/data/environment_brdf/slices_coat/env_brdf.png differ diff --git a/data/environment_brdf/slices_metal/env_brdf.png b/data/environment_brdf/slices_metal/env_brdf.png new file mode 100644 index 0000000..6be5eb0 Binary files /dev/null and b/data/environment_brdf/slices_metal/env_brdf.png differ diff --git a/data/film_grain/generate.py b/data/film_grain/generate.py new file mode 100644 index 0000000..c0f1f71 --- /dev/null +++ b/data/film_grain/generate.py @@ -0,0 +1,77 @@ +""" + +RenderPipeline + +Copyright (c) 2014-2016 tobspr + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. + +""" + +# This script precomputes the noise for the film grain to improve performance + +import os +curr_dir = os.path.dirname(os.path.realpath(__file__)) +os.chdir(curr_dir) + +import sys +sys.path.insert(0, "../../rpcore") +sys.path.insert(0, "../../") + +from panda3d.core import load_prc_file_data, NodePath, Shader, Texture, ShaderAttrib +from panda3d.core import PNMImage + +from direct.showbase.ShowBase import ShowBase + +class Application(ShowBase): + def __init__(self): + load_prc_file_data("", """ + textures-power-2 none + window-type offscreen + win-size 100 100 + gl-coordinate-system default + notify-level-display error + print-pipe-types #f + gl-version 4 3 + """) + + ShowBase.__init__(self) + + dest_tex = Texture() + dest_tex.setup_2d_texture(2048, 2048, Texture.T_unsigned_byte, Texture.F_rgba8) + cshader = Shader.load_compute(Shader.SL_GLSL, "grain.compute.glsl") + node = NodePath("") + node.set_shader(cshader) + node.set_shader_input("DestTex", dest_tex) + attr = node.get_attrib(ShaderAttrib) + self.graphicsEngine.dispatch_compute( + (2048 // 16, 2048 // 16, 1), attr, self.win.gsg) + + base.graphicsEngine.extract_texture_data(dest_tex, base.win.gsg) + + # Convert to single channel + img = PNMImage(2048, 2048, 1, 255) + dest_tex.store(img) + img.set_num_channels(1) + + tex = Texture() + tex.load(img) + tex.write("grain.txo.pz") + +Application() diff --git a/data/film_grain/grain.compute.glsl b/data/film_grain/grain.compute.glsl new file mode 100644 index 0000000..5d6d101 --- /dev/null +++ b/data/film_grain/grain.compute.glsl @@ -0,0 +1,25 @@ +#version 430 + +// Precomputes the film grain + +layout (local_size_x = 16, local_size_y = 16, local_size_z = 1) in; + +#define ASPECT_RATIO 1 +#define SCREEN_SIZE vec2(2048, 2048) +#define gl_FragCoord vec4(0) +#pragma include "../../rpcore/shader/includes/noise.inc.glsl" + +layout(rgba8) uniform image2D DestTex; + +float generate_grain(vec2 texCoord, vec2 resolution, float frame, float multiplier) { + vec2 mult = texCoord * resolution; + float offset = snoise3D(vec3(mult / multiplier, frame)); + float n1 = pnoise3D(vec3(mult, offset), vec3(1.0 / texCoord * resolution, 1.0)); + return n1 * 0.5 + 0.5; +} + +void main() { + vec2 texcoord = vec2(ivec2(gl_GlobalInvocationID.xy) + 0.5) / 2048.0; + vec4 result = vec4(generate_grain(texcoord * 2048.0, vec2(4096.0), 0.0, 4.634523)); + imageStore(DestTex, ivec2(gl_GlobalInvocationID.xy), result); +} diff --git a/data/font/Roboto-Black.ttf b/data/font/Roboto-Black.ttf new file mode 100644 index 0000000..86ec2b2 Binary files /dev/null and b/data/font/Roboto-Black.ttf differ diff --git a/data/font/Roboto-BlackItalic.ttf b/data/font/Roboto-BlackItalic.ttf new file mode 100644 index 0000000..1904c99 Binary files /dev/null and b/data/font/Roboto-BlackItalic.ttf differ diff --git a/data/font/Roboto-Bold.ttf b/data/font/Roboto-Bold.ttf new file mode 100644 index 0000000..91ec212 Binary files /dev/null and b/data/font/Roboto-Bold.ttf differ diff --git a/data/font/Roboto-BoldCondensed.ttf b/data/font/Roboto-BoldCondensed.ttf new file mode 100644 index 0000000..d7ea883 Binary files /dev/null and b/data/font/Roboto-BoldCondensed.ttf differ diff --git a/data/font/Roboto-BoldCondensedItalic.ttf b/data/font/Roboto-BoldCondensedItalic.ttf new file mode 100644 index 0000000..3c9635a Binary files /dev/null and b/data/font/Roboto-BoldCondensedItalic.ttf differ diff --git a/data/font/Roboto-BoldItalic.ttf b/data/font/Roboto-BoldItalic.ttf new file mode 100644 index 0000000..4013bf8 Binary files /dev/null and b/data/font/Roboto-BoldItalic.ttf differ diff --git a/data/font/Roboto-Condensed.ttf b/data/font/Roboto-Condensed.ttf new file mode 100644 index 0000000..6e7575a Binary files /dev/null and b/data/font/Roboto-Condensed.ttf differ diff --git a/data/font/Roboto-CondensedItalic.ttf b/data/font/Roboto-CondensedItalic.ttf new file mode 100644 index 0000000..5ed712c Binary files /dev/null and b/data/font/Roboto-CondensedItalic.ttf differ diff --git a/data/font/Roboto-Italic.ttf b/data/font/Roboto-Italic.ttf new file mode 100644 index 0000000..9f49ffd Binary files /dev/null and b/data/font/Roboto-Italic.ttf differ diff --git a/data/font/Roboto-Light.ttf b/data/font/Roboto-Light.ttf new file mode 100644 index 0000000..d43e943 Binary files /dev/null and b/data/font/Roboto-Light.ttf differ diff --git a/data/font/Roboto-LightItalic.ttf b/data/font/Roboto-LightItalic.ttf new file mode 100644 index 0000000..c11442c Binary files /dev/null and b/data/font/Roboto-LightItalic.ttf differ diff --git a/data/font/Roboto-Medium.ttf b/data/font/Roboto-Medium.ttf new file mode 100644 index 0000000..8798341 Binary files /dev/null and b/data/font/Roboto-Medium.ttf differ diff --git a/data/font/Roboto-MediumItalic.ttf b/data/font/Roboto-MediumItalic.ttf new file mode 100644 index 0000000..5e86637 Binary files /dev/null and b/data/font/Roboto-MediumItalic.ttf differ diff --git a/data/font/Roboto-Regular.ttf b/data/font/Roboto-Regular.ttf new file mode 100644 index 0000000..7d9a6c4 Binary files /dev/null and b/data/font/Roboto-Regular.ttf differ diff --git a/data/font/Roboto-Thin.ttf b/data/font/Roboto-Thin.ttf new file mode 100644 index 0000000..861d63a Binary files /dev/null and b/data/font/Roboto-Thin.ttf differ diff --git a/data/font/Roboto-ThinItalic.ttf b/data/font/Roboto-ThinItalic.ttf new file mode 100644 index 0000000..e65145f Binary files /dev/null and b/data/font/Roboto-ThinItalic.ttf differ diff --git a/data/font/roboto-LICENSE.txt b/data/font/roboto-LICENSE.txt new file mode 100644 index 0000000..817dcac --- /dev/null +++ b/data/font/roboto-LICENSE.txt @@ -0,0 +1,178 @@ +Font data copyright Google 2012 + + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + “License” shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + “Licensor” shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + “Legal Entity” shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + “control” means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + “You” (or “Your”) shall mean an individual or Legal Entity + exercising permissions granted by this License. + + “Source” form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + “Object” form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + “Work” shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + “Derivative Works” shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + “Contribution” shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, “submitted” + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as “Not a Contribution.” + + “Contributor” shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a “NOTICE” text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an “AS IS” BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS diff --git a/data/generate_txo_files.py b/data/generate_txo_files.py new file mode 100644 index 0000000..6e83e69 --- /dev/null +++ b/data/generate_txo_files.py @@ -0,0 +1,37 @@ +""" + +Converts pipeline resources to TXO files to speed up loading. +This is called during the setup. + +""" + +from __future__ import print_function + +import os + +from panda3d.core import Filename, Texture, load_prc_file_data +load_prc_file_data("", "window-type none") +load_prc_file_data("", "notify-level-pnmimage error") +load_prc_file_data("", "textures-power-2 none") + +files_to_convert = [ + "data/gui/loading_screen_bg.png", + "rpplugins/bloom/resources/lens_dirt.png", + "data/builtin_models/skybox/skybox.jpg" +] + +this_dir = os.path.realpath(os.path.dirname(__file__)) +os.chdir(this_dir) + +pipeline_dir = "../" + +import direct.directbase.DirectStart + +for filename in files_to_convert: + src_path = os.path.abspath(os.path.join(pipeline_dir, filename)) + fullpath = Filename.from_os_specific(src_path).get_fullpath() + dest_path = fullpath.replace(".png", ".txo.pz") + dest_path = dest_path.replace(".jpg", ".txo.pz") + + print(src_path, "->", dest_path) + loader.load_texture(fullpath).write(dest_path) diff --git a/data/gui/checkbox_checked.png b/data/gui/checkbox_checked.png new file mode 100644 index 0000000..d1d21d7 Binary files /dev/null and b/data/gui/checkbox_checked.png differ diff --git a/data/gui/checkbox_default.png b/data/gui/checkbox_default.png new file mode 100644 index 0000000..5816c16 Binary files /dev/null and b/data/gui/checkbox_default.png differ diff --git a/data/gui/close_window.png b/data/gui/close_window.png new file mode 100644 index 0000000..9500f90 Binary files /dev/null and b/data/gui/close_window.png differ diff --git a/data/gui/close_window_hover.png b/data/gui/close_window_hover.png new file mode 100644 index 0000000..47ade9d Binary files /dev/null and b/data/gui/close_window_hover.png differ diff --git a/data/gui/icon.ico b/data/gui/icon.ico new file mode 100644 index 0000000..8ce6d56 Binary files /dev/null and b/data/gui/icon.ico differ diff --git a/data/gui/icon.png b/data/gui/icon.png new file mode 100644 index 0000000..74d8e82 Binary files /dev/null and b/data/gui/icon.png differ diff --git a/data/gui/icon_buffer_texture.png b/data/gui/icon_buffer_texture.png new file mode 100644 index 0000000..0b1baef Binary files /dev/null and b/data/gui/icon_buffer_texture.png differ diff --git a/data/gui/icon_pipe.png b/data/gui/icon_pipe.png new file mode 100644 index 0000000..204b195 Binary files /dev/null and b/data/gui/icon_pipe.png differ diff --git a/data/gui/icon_texture.png b/data/gui/icon_texture.png new file mode 100644 index 0000000..a302815 Binary files /dev/null and b/data/gui/icon_texture.png differ diff --git a/data/gui/icon_ubo.png b/data/gui/icon_ubo.png new file mode 100644 index 0000000..4a4b9d0 Binary files /dev/null and b/data/gui/icon_ubo.png differ diff --git a/data/gui/keybindings.png b/data/gui/keybindings.png new file mode 100644 index 0000000..d06d291 Binary files /dev/null and b/data/gui/keybindings.png differ diff --git a/data/gui/loading_screen_bg.png b/data/gui/loading_screen_bg.png new file mode 100644 index 0000000..8c11f74 Binary files /dev/null and b/data/gui/loading_screen_bg.png differ diff --git a/data/gui/meta_core.png b/data/gui/meta_core.png new file mode 100644 index 0000000..3d68d2f Binary files /dev/null and b/data/gui/meta_core.png differ diff --git a/data/gui/pipeline_logo.png b/data/gui/pipeline_logo.png new file mode 100644 index 0000000..f6c7ec2 Binary files /dev/null and b/data/gui/pipeline_logo.png differ diff --git a/data/gui/pipeline_logo_text.png b/data/gui/pipeline_logo_text.png new file mode 100644 index 0000000..e4cf49b Binary files /dev/null and b/data/gui/pipeline_logo_text.png differ diff --git a/data/gui/python_warning.png b/data/gui/python_warning.png new file mode 100644 index 0000000..6c183a7 Binary files /dev/null and b/data/gui/python_warning.png differ diff --git a/data/gui/radiobox_checked.png b/data/gui/radiobox_checked.png new file mode 100644 index 0000000..778b160 Binary files /dev/null and b/data/gui/radiobox_checked.png differ diff --git a/data/gui/radiobox_default.png b/data/gui/radiobox_default.png new file mode 100644 index 0000000..93f7c50 Binary files /dev/null and b/data/gui/radiobox_default.png differ diff --git a/data/gui/radiobox_disabled.png b/data/gui/radiobox_disabled.png new file mode 100644 index 0000000..8c59a2b Binary files /dev/null and b/data/gui/radiobox_disabled.png differ diff --git a/data/gui/shader_reload_hint.png b/data/gui/shader_reload_hint.png new file mode 100644 index 0000000..b8dbd15 Binary files /dev/null and b/data/gui/shader_reload_hint.png differ diff --git a/data/ies_profiles/PREVIEWS.jpg b/data/ies_profiles/PREVIEWS.jpg new file mode 100644 index 0000000..2499928 Binary files /dev/null and b/data/ies_profiles/PREVIEWS.jpg differ diff --git a/data/ies_profiles/README.md b/data/ies_profiles/README.md new file mode 100644 index 0000000..673600b --- /dev/null +++ b/data/ies_profiles/README.md @@ -0,0 +1,25 @@ + +# IES Profiles + + +### Source + +This files were aqcuired from: +http://www.derekjenson.com/3d-blog/ies-light-profiles + +### Finding new IES Profiles + +You can download IES profile files from the vendors directly. +Here are some links to start with: + +- http://www.colorkinetics.com/support/ies/ +- http://www.seleconlight.com/index.php?option=com_content&view=article&id=475 +- http://www.lithonia.com/photometrics.aspx + + +### Previewing IES Profiles + +You can preview the profiles with a viewer like this: + +http://www.photometricviewer.com + diff --git a/data/ies_profiles/area_light.ies b/data/ies_profiles/area_light.ies new file mode 100644 index 0000000..0981e5e --- /dev/null +++ b/data/ies_profiles/area_light.ies @@ -0,0 +1,83 @@ +IESNA:LM-63-1995 +[ISSUEDATE] 07-16-2008 +[TEST] S0710292-R1 +[MANUFAC] QSSI +[LUMCAT] KH40A-Type III +[LUMINAIRE] KH40 with Adjustable Reflector in Type III position +[LAMP] 400W Venture Uni-Form Pulse Start Lamp, Rated at 41,000 Lumens +[SKTPOSITION] Horizontal Socket Position 5, Street Side Lamp Holder +TILT=NONE +1 41000 1.27 35 35 1 1 1.25 1.25 0 +1 1 433.62 +0 5 10 15 20 25 30 35 40 45 50 55 60 62.5 65 67.5 70 72.5 75 77.5 80 82.5 85 87.5 90 95 105 115 125 135 145 155 165 175 180 +0 5 15 25 35 45 47.5 50 52.5 55 57.5 60 62.5 65 67.5 70 72.5 75 77.5 80 82.5 85 87.5 90 92.5 95 105 115 125 135 145 155 165 175 180 +7417.00 7382.00 7263.00 7121.00 6990.00 6758.00 6434.00 6118.00 5692.00 4547.00 3496.00 4195.00 4796.00 5633.00 5783.00 5751.00 +4859.00 3975.00 2344.00 1366.00 160.00 72.00 39.00 24.00 21.00 20.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 +7417.00 7405.00 7283.00 7135.00 7003.00 6820.00 6491.00 6141.00 5694.00 4606.00 3541.00 4075.00 4778.00 5313.00 5496.00 5075.00 +4280.00 3598.00 1962.00 1151.00 141.00 67.00 40.00 23.00 21.00 19.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 +7417.00 7383.00 7267.00 7116.00 6985.00 6824.00 6642.00 6130.00 5292.00 4304.00 3494.00 3652.00 4934.00 5076.00 4892.00 4279.00 +2986.00 2173.00 1626.00 732.00 190.00 67.00 42.00 23.00 21.00 19.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 +7417.00 7338.00 7186.00 7004.00 6792.00 6636.00 6374.00 5738.00 4946.00 4762.00 4024.00 3997.00 5536.00 5402.00 5123.00 4709.00 +3693.00 2178.00 1438.00 685.00 161.00 72.00 39.00 23.00 20.00 19.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 +7417.00 7324.00 7066.00 6717.00 6486.00 6325.00 5900.00 5379.00 5421.00 4917.00 4550.00 4575.00 5901.00 8328.00 7841.00 6686.00 +5417.00 2837.00 1896.00 1123.00 177.00 71.00 41.00 24.00 21.00 20.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 +7417.00 7284.00 6859.00 6523.00 6335.00 6048.00 5654.00 5112.00 5736.00 5706.00 5144.00 5769.00 10385.00 10952.00 10744.00 9057.00 +6083.00 3307.00 2350.00 1042.00 167.00 76.00 41.00 26.00 22.00 21.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 +7417.00 7272.00 6802.00 6505.00 6253.00 5947.00 5546.00 5083.00 5713.00 5777.00 5236.00 7030.00 10955.00 11004.00 11331.00 9180.00 +5616.00 3669.00 2326.00 700.00 150.00 76.00 42.00 26.00 23.00 21.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 +7417.00 7271.00 6780.00 6512.00 6255.00 5925.00 5422.00 5108.00 5698.00 5856.00 5267.00 7787.00 11280.00 11056.00 11588.00 8604.00 +5357.00 4075.00 2388.00 624.00 150.00 77.00 44.00 26.00 23.00 21.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 +7417.00 7283.00 6781.00 6529.00 6229.00 5824.00 5318.00 5151.00 5653.00 5917.00 5389.00 7867.00 11388.00 11116.00 10907.00 7978.00 +5353.00 4324.00 2291.00 595.00 163.00 89.00 43.00 26.00 23.00 21.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 +7417.00 7252.00 6706.00 6496.00 6161.00 5735.00 5214.00 5111.00 5586.00 5951.00 5500.00 8022.00 11522.00 11494.00 9242.00 7462.00 +5174.00 4516.00 2094.00 594.00 191.00 87.00 43.00 26.00 23.00 21.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 +7417.00 7224.00 6669.00 6459.00 6086.00 5610.00 5150.00 5099.00 5499.00 5899.00 5565.00 7933.00 11560.00 11858.00 8529.00 7029.00 +4917.00 4292.00 2027.00 619.00 209.00 88.00 42.00 26.00 23.00 21.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 +7417.00 7219.00 6654.00 6449.00 6073.00 5494.00 5090.00 5076.00 5442.00 5831.00 5637.00 7786.00 11528.00 11335.00 8436.00 6553.00 +4715.00 3972.00 1899.00 626.00 241.00 94.00 42.00 26.00 22.00 21.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 +7417.00 7225.00 6658.00 6469.00 6030.00 5441.00 5046.00 5116.00 5435.00 5771.00 5787.00 7685.00 11568.00 10502.00 8333.00 6219.00 +4476.00 3582.00 1644.00 641.00 253.00 90.00 43.00 26.00 22.00 21.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 +7417.00 7287.00 6700.00 6520.00 6031.00 5380.00 5032.00 5191.00 5403.00 5729.00 5891.00 7489.00 11227.00 9688.00 8036.00 5924.00 +4353.00 3030.00 1294.00 604.00 257.00 87.00 49.00 26.00 22.00 21.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 +7417.00 7238.00 6625.00 6449.00 5934.00 5232.00 4936.00 5183.00 5393.00 5653.00 5980.00 7355.00 10352.00 8867.00 7433.00 5389.00 +4232.00 2454.00 1000.00 488.00 280.00 78.00 45.00 26.00 22.00 21.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 +7417.00 7215.00 6607.00 6445.00 5862.00 5161.00 4900.00 5195.00 5390.00 5590.00 6054.00 7236.00 9281.00 8026.00 6696.00 5128.00 +4013.00 2035.00 778.00 409.00 215.00 79.00 41.00 25.00 22.00 21.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 +7417.00 7202.00 6596.00 6417.00 5833.00 5078.00 4804.00 5214.00 5410.00 5505.00 6057.00 7124.00 8613.00 7409.00 6003.00 5068.00 +4005.00 1857.00 568.00 257.00 131.00 69.00 38.00 25.00 22.00 20.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 +7417.00 7198.00 6559.00 6398.00 5781.00 5001.00 4741.00 5227.00 5452.00 5376.00 6037.00 6982.00 7652.00 6384.00 5441.00 4949.00 +4260.00 1950.00 441.00 169.00 109.00 64.00 35.00 25.00 22.00 20.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 +7417.00 7209.00 6581.00 6423.00 5768.00 4945.00 4717.00 5255.00 5458.00 5273.00 6009.00 6841.00 6818.00 5427.00 5345.00 5378.00 +5257.00 2594.00 517.00 194.00 158.00 67.00 34.00 25.00 22.00 20.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 +7417.00 7249.00 6627.00 6441.00 5774.00 4912.00 4687.00 5213.00 5383.00 5201.00 5955.00 6672.00 6098.00 5163.00 5212.00 5595.00 +5994.00 3246.00 995.00 262.00 147.00 74.00 36.00 25.00 22.00 21.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 +7417.00 7220.00 6574.00 6416.00 5722.00 4852.00 4628.00 5136.00 5255.00 5090.00 5723.00 6408.00 5524.00 5543.00 5326.00 5697.00 +5900.00 2620.00 1258.00 332.00 134.00 72.00 33.00 24.00 22.00 21.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 +7417.00 7204.00 6563.00 6422.00 5659.00 4808.00 4586.00 5061.00 5175.00 5011.00 5620.00 6185.00 5303.00 5609.00 5550.00 6641.00 +6023.00 2144.00 1230.00 275.00 129.00 70.00 33.00 24.00 21.00 21.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 +7417.00 7213.00 6587.00 6404.00 5652.00 4780.00 4572.00 4995.00 5118.00 4963.00 5582.00 5940.00 5607.00 5486.00 5667.00 7137.00 +5903.00 2045.00 900.00 218.00 113.00 66.00 34.00 24.00 21.00 21.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 +7417.00 7206.00 6542.00 6407.00 5637.00 4739.00 4549.00 4938.00 5067.00 4970.00 5547.00 5724.00 5658.00 5314.00 6006.00 7655.00 +5363.00 1908.00 642.00 179.00 91.00 58.00 32.00 24.00 21.00 21.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 +7417.00 7217.00 6564.00 6406.00 5634.00 4719.00 4566.00 4855.00 5050.00 5103.00 5396.00 5597.00 5391.00 5163.00 6692.00 8064.00 +5238.00 1781.00 490.00 167.00 95.00 53.00 31.00 24.00 22.00 21.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 +7417.00 7286.00 6641.00 6476.00 5639.00 4713.00 4554.00 4773.00 5052.00 5127.00 5168.00 5272.00 5191.00 5129.00 7315.00 7707.00 +5151.00 1457.00 411.00 163.00 91.00 54.00 31.00 24.00 22.00 21.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 +7417.00 7243.00 6589.00 6437.00 5748.00 4721.00 4489.00 4610.00 5047.00 4800.00 4975.00 5468.00 5017.00 5275.00 5262.00 4489.00 +3129.00 839.00 279.00 151.00 101.00 90.00 30.00 23.00 22.00 22.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 +7417.00 7268.00 6633.00 6416.00 5949.00 4866.00 4390.00 4377.00 4763.00 4275.00 4100.00 4194.00 3792.00 3797.00 3409.00 3078.00 +2472.00 738.00 230.00 137.00 129.00 69.00 28.00 22.00 22.00 23.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 +7417.00 7292.00 6733.00 6404.00 6097.00 5175.00 4364.00 4151.00 4142.00 3841.00 3661.00 3526.00 3221.00 3089.00 2900.00 2676.00 +2374.00 1206.00 314.00 138.00 77.00 54.00 26.00 22.00 22.00 23.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 +7417.00 7297.00 6902.00 6409.00 6182.00 5542.00 4511.00 4002.00 3796.00 3539.00 3411.00 3264.00 2961.00 2817.00 2632.00 2439.00 +2127.00 1415.00 388.00 129.00 157.00 47.00 25.00 21.00 21.00 22.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 +7417.00 7310.00 7105.00 6591.00 6171.00 5732.00 4813.00 4065.00 3605.00 3299.00 3404.00 3190.00 2840.00 2596.00 2425.00 2177.00 +1837.00 994.00 356.00 153.00 78.00 42.00 24.00 21.00 21.00 21.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 +7417.00 7332.00 7219.00 6927.00 6432.00 5846.00 5194.00 4422.00 3788.00 3171.00 3017.00 2873.00 2689.00 2478.00 2121.00 1807.00 +1441.00 740.00 332.00 169.00 93.00 49.00 24.00 20.00 20.00 20.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 +7417.00 7319.00 7224.00 7077.00 6815.00 6270.00 5499.00 4735.00 3994.00 3098.00 2739.00 2489.00 2235.00 1983.00 1672.00 1383.00 +1057.00 553.00 272.00 168.00 89.00 44.00 23.00 20.00 19.00 20.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 +7417.00 7337.00 7218.00 7041.00 6856.00 6402.00 5656.00 4670.00 3658.00 2889.00 2547.00 2219.00 1898.00 1632.00 1349.00 1086.00 +792.00 492.00 283.00 213.00 136.00 56.00 23.00 19.00 19.00 20.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 +7417.00 7348.00 7218.00 7033.00 6787.00 6357.00 5609.00 4578.00 3463.00 2809.00 2508.00 2217.00 1920.00 1583.00 1285.00 987.00 +694.00 490.00 238.00 142.00 86.00 44.00 22.00 19.00 20.00 20.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 diff --git a/data/ies_profiles/bollard.ies b/data/ies_profiles/bollard.ies new file mode 100644 index 0000000..a98b594 --- /dev/null +++ b/data/ies_profiles/bollard.ies @@ -0,0 +1,16 @@ +IESNA:LM-63-2002 +[TEST]BALLABS TEST NO. 14397.0 +[TESTLAB] BUILDING ACOUSTICS & LIGHTING LABORATORIES, INC +[ISSUEDATE] 03-DEC-2008 +[MANUFAC] H.E. WILLIAMS, INC - CARTHAGE, MISSOURI +[LUMINAIRE] 1/100W CLEAR ED17 LAMP 6"DIA 38.25"TALL WHITE BOLLARD +[MORE] 4.5"DIA SPECULAR CONE REFLECTOR w/5.875"TALL ACRYLIC +[MORE] CYLINDER LENS +[LUMCAT] OSA6R-100PSMH120-AC +[LAMPCAT] M90 MH100W/U/PS +TILT=NONE +1 9000 1 35 1 1 1 -0.49 -0.49 0.406 +1 1 100 +0 5 10 15 20 25 30 35 40 45 50 55 60 62.5 65 67.5 70 72.5 75 77.5 80 82.5 85 87.5 90 95 105 115 125 135 145 155 165 175 180 +0 +0.00 12.00 87.00 182.00 167.00 300.00 655.00 944.00 822.00 703.00 614.00 565.00 487.00 438.00 372.00 309.00 262.00 216.00 182.00 142.00 111.00 83.00 61.00 42.00 25.00 19.00 14.00 14.00 15.00 20.00 33.00 36.00 27.00 4.00 0.00 diff --git a/data/ies_profiles/comet.ies b/data/ies_profiles/comet.ies new file mode 100644 index 0000000..8ae2f26 --- /dev/null +++ b/data/ies_profiles/comet.ies @@ -0,0 +1,13 @@ +IESNA:LM-63-1995 +[TEST] INFINITY LIGHTING PHOTOMETRIC REPORT NO. W00006 +[LUMINAIRE] ICEAL8-2X150-FL-CG1 +TILT=NONE +2 11000 1 19 5 1 1 1.375 1.04167 0 +1 1 314 +0 5 10 15 20 25 30 35 40 45 50 55 60 65 70 75 80 85 90 +0 22.5 45 67.5 90 +9085.62 9033.58 8923.24 8687.43 8145.53 7454.18 6336.9 5050.9 3180.16 2162.21 1292.02 677.24 243.87 48.44 16.1 6.48 6.25 6.99 3.31 +9085.62 8902.2 8825.21 8578.38 8462.81 7787.37 6902.89 5633.64 3822.33 2423.91 1614.81 927.01 382.27 72.18 18.92 8.91 6.41 5.19 2.16 +9085.62 9029.2 9168.27 8989.93 8818.57 8434.18 7791.45 6806.71 5489.39 3939.15 2518.39 1573.92 770.93 308.04 81.18 28.92 14.71 8.88 4.75 +9085.62 9404.94 9244.69 9202.21 9146.45 8779.2 8121.15 7346.47 6513.38 5407.45 3976.98 2453.4 1106.06 428.6 117.57 35.96 12.34 7.19 1.55 +9085.62 9315.27 9317.59 9459.68 9433.84 9128.13 8380.85 7752.85 6655.4 5439.5 3990.21 2472.54 1140.85 377.1 65.79 17.41 9 4.71 2.77 diff --git a/data/ies_profiles/cylinder_narrow.ies b/data/ies_profiles/cylinder_narrow.ies new file mode 100644 index 0000000..7d9efdc --- /dev/null +++ b/data/ies_profiles/cylinder_narrow.ies @@ -0,0 +1,16 @@ + IESNA:LM-63-1995 + [TEST]BALLABS TEST NO. 10974.0 + [MANUFAC] INFINITY LIGHTING INC - CARTHAGE, MISSOURI + [LUMINAIRE] 1/250W HALOGEN CLEAR MINICAN 7.5"DIA RECESSED LUMINAIRE + [LUMINAIRE] FACETED HYDROFORMED SEMI-SPECULAR REFLECTOR + [LUMINAIRE] CLEAR GLASS LENS w/4"DEEPSPUN SPECULAR ALUMINUM CONE +[LUMCAT]CATALOG NO. : TH75-250-T4 NARROW w/SPACER I +[LAMPCAT]LAMP CODE : 250Q/CL/MC (EHT) +TILT=NONE + 1 5000. 1.000000 19 1 1 1 .625 .625 .000 + 1.0000 1.0000 247.0000 + .0 5.0 10.0 15.0 20.0 25.0 30.0 35.0 40.0 45.0 + 50.0 55.0 60.0 65.0 70.0 75.0 80.0 85.0 90.0 + .0 + 8183. 6729. 4775. 3866. 2714. 1600. 992. 715. 373. 119. + 46. 20. 8. 4. 0. 0. 0. 0. 0. diff --git a/data/ies_profiles/cylinder_wide.ies b/data/ies_profiles/cylinder_wide.ies new file mode 100644 index 0000000..8bf4be0 --- /dev/null +++ b/data/ies_profiles/cylinder_wide.ies @@ -0,0 +1,16 @@ + IESNA:LM-63-1995 + [TEST]BALLABS TEST NO. 10979.0 + [MANUFAC] INFINITY LIGHTING INC - CARTHAGE, MISSOURI + [LUMINAIRE] 1/500W HALOGEN CLEAR MINICAN 7.5"DIA RECESSED LUMINAIRE + [LUMINAIRE] FACETED HYDROFORMED SEMI-SPECULAR REFLECTOR + [LUMINAIRE] CLEAR GLASS LENS w/4"DEEP SPUN SPECULAR ALUMINUM CONE +[LUMCAT]CATALOG NO. : TH75-500-T4 WIDE w/SPACER D +[LAMPCAT]LAMP CODE : 500Q/CL/MC (EVR) +TILT=NONE + 1 10450. 1.000000 19 1 1 1 .625 .625 .000 + 1.0000 1.0000 503.0000 + .0 5.0 10.0 15.0 20.0 25.0 30.0 35.0 40.0 45.0 + 50.0 55.0 60.0 65.0 70.0 75.0 80.0 85.0 90.0 + .0 + 4612. 5322. 6414. 6917. 6708. 5675. 4019. 2703. 1870. 872. + 169. 42. 9. 0. 0. 0. 0. 0. 0. diff --git a/data/ies_profiles/defined.ies b/data/ies_profiles/defined.ies new file mode 100644 index 0000000..c40a941 --- /dev/null +++ b/data/ies_profiles/defined.ies @@ -0,0 +1,16 @@ +IESNA91 +[TEST] Test unknown +[MANUFAC] Manufacturing company unknown +TILT=NONE +1 13172.61 1 +37 1 +1 +2 +0 0 0 +1 1 0 + 0.00 2.50 5.00 7.50 9.11 10.00 10.80 12.50 15.83 22.50 25.00 27.50 32.50 34.28 35.00 42.50 47.02 47.50 47.81 50.00 50.78 52.50 + 55.00 57.50 60.00 62.50 65.00 67.50 70.00 72.50 75.00 77.50 80.00 82.50 85.00 87.50 90.00 + 0.00 + 8379.00 8409.00 8528.00 8126.65 8500.00 8564.00 8301.00 8158.61 8411.98 8036.59 7865.61 7283.76 5209.38 6038.93 4533.49 3091.00 + 3665.38 2996.97 3625.45 2194.62 3170.85 1115.28 651.00 450.00 244.00 102.00 80.00 43.00 5.00 2.00 0.00 0.00 0.00 0.00 0.00 0.00 + 0.00 diff --git a/data/ies_profiles/defined_diffuse.ies b/data/ies_profiles/defined_diffuse.ies new file mode 100644 index 0000000..60738a5 --- /dev/null +++ b/data/ies_profiles/defined_diffuse.ies @@ -0,0 +1,64 @@ +ERCO Leuchten GmbH +3399_0 - IES format +ERCO 89064 +ERCO Double Focus Downlight +DL40-QT12-2HA-SI-DOUBLE +1*QT-ax12 100W/12V +light output ratio: 0.5912 +ident no. for symmetry: 1 +D694 +TILT=NONE + 1 + 2200 + 2.2 + 19 + 1 + 1 + 2 + 0 + 0 + 0 + 1 + 1 + 100 + 0 + 5 + 10 + 15 + 20 + 25 + 30 + 35 + 40 + 45 + 50 + 55 + 60 + 65 + 70 + 75 + 80 + 85 + 90 + 0 + 681.879276637 + 557.110079287 + 490.896871945 + 628.387368307 + 682.069349408 + 430.426577604 + 286.398935592 + 254.901162159 + 76.9183773216 + 18.9393939394 + 11.0377973281 + .488758553275 + .00678831323993 + 0 + 0 + 0 + 0 + 0 + 0 +END + \ No newline at end of file diff --git a/data/ies_profiles/defined_diffuse_spot.ies b/data/ies_profiles/defined_diffuse_spot.ies new file mode 100644 index 0000000..f3cb4c3 --- /dev/null +++ b/data/ies_profiles/defined_diffuse_spot.ies @@ -0,0 +1,29 @@ +ERCO Leuchten GmbH BY: ERCO/LUM650/8701 +74216023+Q50MR16/C/CG55-FNV.IES +- +- +- +- +- +- +TILT=NONE +1 825 .825 73 2 1 2 -.2 0 0 +1.00 1.00 50 +0 1.25 2.5 3.75 5 6.25 7.5 8.75 10 11.25 12.5 13.75 15 16.25 17.5 18.75 20 +21.25 22.5 23.75 25 26.25 27.5 28.75 30 31.25 32.5 33.75 35 36.25 37.5 38.75 +40 41.25 42.5 43.75 45 46.25 47.5 48.75 50 51.25 52.5 53.75 55 56.25 57.5 +58.75 60 61.25 62.5 63.75 65 66.25 67.5 68.75 70 71.25 72.5 73.75 75 76.25 +77.5 78.75 80 81.25 82.5 83.75 85 86.25 87.5 88.75 90 +0 90 +1091 1113 1132 1160 1183 1206 1219 1223 1217 1207 1190 1162 1120 1063 995.2 +919 837.6 753.2 666.7 579.4 495.8 418.3 338.2 250.3 175.8 135.5 123.9 128.9 +138.2 142.1 140.9 137.1 133.3 131.4 129.6 125.5 116.4 100.9 81.69 62.57 47.27 +38.54 35 34.26 33.94 32.17 29.22 25.91 23.03 21.2 20.24 19.77 19.39 18.83 +18.14 17.47 16.97 16.74 16.74 16.85 16.97 17.03 17.03 17 16.97 16.95 16.95 +16.96 16.97 16.97 16.97 16.97 16.97 +1091 1113 1132 1160 1183 1206 1219 1223 1217 1207 1190 1162 1120 1063 995.2 +919 837.6 753.2 666.7 579.4 495.8 418.3 338.2 250.3 175.8 135.5 123.9 128.9 +138.2 142.1 140.9 137.1 133.3 131.4 129.6 125.5 116.4 100.9 81.69 62.57 47.27 +38.54 35 34.26 33.94 32.17 29.22 25.91 23.03 21.2 20.24 19.77 19.39 18.83 +18.14 17.47 16.97 16.74 16.74 16.85 16.97 17.03 17.03 17 16.97 16.95 16.95 +16.96 16.97 16.97 16.97 16.97 16.97 diff --git a/data/ies_profiles/defined_spot.ies b/data/ies_profiles/defined_spot.ies new file mode 100644 index 0000000..4bfcc86 --- /dev/null +++ b/data/ies_profiles/defined_spot.ies @@ -0,0 +1,14 @@ +IESNA:LM-63-1995 +[TEST] 100068_0 BY: ERCO / LUM650 +[DATE]02.12.2004 +[MANUFAC] ERCO Leuchten GmbH +[LUMCAT] 22619000_83670000 +[LUMINAIRE] Lightcast Downlight +[LAMPCAT] HIPAR-L30 35W 30 +TILT=NONE +1 2200 1 19 1 1 2 -.097 0 0 +1.00 1.00 35 +0 5 10 15 20 25 30 35 40 45 50 55 60 65 70 75 80 85 90 +0 +7399.9 7219.5 6097.7 3707.0 836.0 281.6 239.8 145.2 90.2 46.2 33.0 17.6 12.1 +11.0 9.9 9.0 0.0 0.0 0.0 diff --git a/data/ies_profiles/display.ies b/data/ies_profiles/display.ies new file mode 100644 index 0000000..0f819b3 --- /dev/null +++ b/data/ies_profiles/display.ies @@ -0,0 +1,29 @@ +ERCO Leuchten GmbH BY: ERCO/LUM650/8701 +73011023+CHM70/U/PAR38/12.IES +- +- +- +- +- +- +TILT=NONE +1 4100 4.1 73 2 1 2 -.12 0 0 +1.00 1.00 92 +0 1.25 2.5 3.75 5 6.25 7.5 8.75 10 11.25 12.5 13.75 15 16.25 17.5 18.75 20 +21.25 22.5 23.75 25 26.25 27.5 28.75 30 31.25 32.5 33.75 35 36.25 37.5 38.75 +40 41.25 42.5 43.75 45 46.25 47.5 48.75 50 51.25 52.5 53.75 55 56.25 57.5 +58.75 60 61.25 62.5 63.75 65 66.25 67.5 68.75 70 71.25 72.5 73.75 75 76.25 +77.5 78.75 80 81.25 82.5 83.75 85 86.25 87.5 88.75 90 +0 90 +13800 13140 11450 9275 7132 5238 3687 2529 1731 1206 867.8 644.4 493.7 385.4 +306.8 250.1 211 186.1 170.7 160.7 153.9 149.1 145.6 142.8 140 136.7 134.3 +134.7 139.8 150.2 162.8 173.3 177.3 171.9 159.2 142.4 124.9 109.4 96.15 84.85 +75.12 66.63 59 51.87 44.88 37.79 30.91 24.68 19.51 15.73 13.11 11.31 10 8.932 +8.275 8.298 9.268 11.25 13.52 15.12 15.12 12.93 9.3 5.354 2.195 .6462 .3783 +.7748 1.22 1.234 .8939 .4114 0 +13800 13140 11450 9275 7132 5238 3687 2529 1731 1206 867.8 644.4 493.7 385.4 +306.8 250.1 211 186.1 170.7 160.7 153.9 149.1 145.6 142.8 140 136.7 134.3 +134.7 139.8 150.2 162.8 173.3 177.3 171.9 159.2 142.4 124.9 109.4 96.15 84.85 +75.12 66.63 59 51.87 44.88 37.79 30.91 24.68 19.51 15.73 13.11 11.31 10 8.932 +8.275 8.298 9.268 11.25 13.52 15.12 15.12 12.93 9.3 5.354 2.195 .6462 .3783 +.7748 1.22 1.234 .8939 .4114 0 diff --git a/data/ies_profiles/jelly_fish.ies b/data/ies_profiles/jelly_fish.ies new file mode 100644 index 0000000..1edf650 --- /dev/null +++ b/data/ies_profiles/jelly_fish.ies @@ -0,0 +1,80 @@ +IESNA:LM-63-1995 +[TEST]BALLABS TEST NO. 12788.0 +[MANUFAC] INFINITY LIGHTING INC - CARTHAGE, MISSOURI +[LUMINAIRE] 1/100W ICETRON INDUCTION 20x15"DIRECT AREALIGHT LUMINAIRE +[LUMINAIRE] MIRO4 SPEC ALUM TYPE II OPTICS & CLEAR FLAT GLASS LENS +[LUMINAIRE] BLACK PANEL STREET SIDE SYLVANIA # QT 1x150 ICE/UNV-T +[LUMCAT] ICEAL2-150S-TYPE2/CG1-277 +[LAMPCAT] ICE100/QT150 2PIN +TILT=NONE + 1 11000. 1.000000 25 21 1 1 .938 1.266 .000 + 1.0000 1.0000 140.0000 + .0 5.0 10.0 15.0 20.0 25.0 30.0 35.0 40.0 45.0 + 50.0 55.0 60.0 62.5 65.0 67.5 70.0 72.5 75.0 77.5 + 80.0 82.5 85.0 87.5 90.0 + .0 5.0 15.0 25.0 35.0 45.0 55.0 65.0 75.0 85.0 + 90.0 95.0 105.0 115.0 125.0 135.0 145.0 155.0 165.0 175.0 + 180.0 + 1789. 1841. 1911. 1979. 2023. 2025. 1994. 1867. 1718. 1551. + 1374. 1208. 990. 808. 637. 469. 347. 202. 89. 18. + 9. 7. 7. 6. 0. + 1789. 1831. 1908. 1969. 2013. 2018. 1983. 1865. 1701. 1548. + 1353. 1193. 981. 842. 661. 503. 352. 172. 68. 19. + 8. 6. 6. 5. 0. + 1789. 1828. 1891. 1939. 1958. 1939. 1908. 1808. 1668. 1559. + 1428. 1300. 1222. 1161. 999. 778. 580. 318. 129. 39. + 10. 7. 7. 4. 0. + 1789. 1818. 1865. 1891. 1942. 1959. 1927. 1843. 1761. 1714. + 1673. 1599. 1445. 1325. 1165. 948. 668. 400. 186. 75. + 30. 9. 7. 2. 0. + 1789. 1811. 1821. 1891. 1941. 1974. 1980. 1943. 1993. 2082. + 1963. 1808. 1621. 1601. 1424. 1166. 829. 487. 279. 152. + 65. 15. 8. 2. 0. + 1789. 1794. 1804. 1893. 1935. 1995. 2020. 2145. 2342. 2221. + 2063. 2135. 2157. 1694. 948. 340. 101. 8. 0. 185. + 94. 32. 9. 0. 0. + 1789. 1775. 1803. 1868. 1931. 1992. 2076. 2357. 2333. 2285. + 2254. 2608. 2375. 2010. 1722. 1448. 981. 661. 376. 244. + 122. 38. 8. 0. 0. + 1789. 1763. 1798. 1839. 1918. 1961. 2151. 2291. 2310. 2263. + 2575. 2700. 2380. 2075. 1792. 1483. 1102. 702. 430. 298. + 192. 67. 11. 2. 0. + 1789. 1746. 1801. 1827. 1871. 1923. 2176. 2119. 2124. 2062. + 2553. 2596. 2201. 1907. 1678. 1368. 1015. 673. 440. 303. + 178. 63. 10. 1. 0. + 1789. 1738. 1788. 1808. 1830. 1895. 2081. 2024. 1953. 1883. + 2313. 2285. 1854. 1661. 1400. 1139. 833. 577. 404. 267. + 157. 54. 12. 1. 0. + 1789. 1735. 1783. 1797. 1812. 1868. 2046. 1983. 1911. 1805. + 2191. 2151. 1759. 1513. 1288. 1033. 802. 568. 386. 243. + 134. 56. 10. 3. 0. + 1789. 1734. 1778. 1786. 1797. 1838. 2016. 1951. 1871. 1766. + 2128. 2078. 1681. 1474. 1248. 1009. 739. 523. 349. 228. + 144. 52. 13. 2. 0. + 1789. 1733. 1774. 1773. 1771. 1777. 1959. 1895. 1811. 1647. + 2034. 1957. 1595. 1293. 1118. 925. 717. 481. 319. 208. + 125. 51. 7. 1. 0. + 1789. 1738. 1763. 1755. 1744. 1704. 1880. 1794. 1752. 1541. + 1772. 1720. 1427. 1191. 1003. 795. 588. 427. 274. 166. + 98. 39. 8. 3. 0. + 1789. 1734. 1744. 1732. 1708. 1647. 1674. 1703. 1620. 1413. + 1325. 1423. 1205. 983. 808. 642. 464. 312. 192. 107. + 57. 18. 8. 3. 0. + 1789. 1735. 1714. 1725. 1673. 1590. 1481. 1511. 1373. 1230. + 982. 993. 902. 771. 626. 456. 300. 187. 112. 60. + 31. 14. 8. 4. 0. + 1789. 1736. 1681. 1700. 1617. 1511. 1381. 1252. 1210. 1043. + 875. 657. 554. 487. 398. 294. 195. 122. 70. 40. + 19. 11. 8. 3. 0. + 1789. 1737. 1666. 1641. 1577. 1471. 1333. 1172. 1015. 890. + 728. 574. 409. 326. 243. 181. 114. 72. 40. 24. + 14. 9. 7. 4. 0. + 1789. 1740. 1679. 1601. 1493. 1388. 1268. 1114. 956. 769. + 624. 481. 347. 267. 201. 141. 85. 41. 25. 16. + 10. 7. 6. 3. 0. + 1789. 1737. 1693. 1616. 1479. 1340. 1187. 1041. 896. 724. + 572. 431. 303. 233. 167. 117. 62. 29. 18. 12. + 9. 6. 6. 4. 1. + 1789. 1742. 1698. 1623. 1491. 1354. 1196. 1040. 894. 722. + 565. 421. 302. 227. 159. 108. 57. 20. 14. 10. + 8. 6. 6. 5. 0. diff --git a/data/ies_profiles/medium_scatter.ies b/data/ies_profiles/medium_scatter.ies new file mode 100644 index 0000000..7684592 --- /dev/null +++ b/data/ies_profiles/medium_scatter.ies @@ -0,0 +1,385 @@ +IESNA:LM-63-2002 +[TEST] 5890_0 +[TESTLAB] ERCO GmbH +[ISSUEDATE] 02-12-2008 +[MANUFAC] ERCO GmbH +[LUMCAT] 33519000 +[LUMINAIRE] Kubus Floor washlight +[LAMP] HIT-TC-CE 20W +TILT=NONE +1 1615 1 37 73 1 2 0.103 0.059 0 +1.0 1.0 24 +0 2.5 5 7.5 10 12.5 15 17.5 20 22.5 25 27.5 30 +32.5 35 37.5 40 42.5 45 47.5 50 52.5 55 57.5 60 62.5 +65 67.5 70 72.5 75 77.5 80 82.5 85 87.5 90 +0 2.5 5 7.5 10 12.5 15 17.5 20 22.5 25 27.5 30 +32.5 35 37.5 40 42.5 45 47.5 50 52.5 55 57.5 60 62.5 +65 67.5 70 72.5 75 77.5 80 82.5 85 87.5 90 92.5 95 +97.5 100 102.5 105 107.5 110 112.5 115 117.5 120 122.5 125 127.5 +130 132.5 135 137.5 140 142.5 145 147.5 150 152.5 155 157.5 160 +162.5 165 167.5 170 172.5 175 177.5 180 +174.408695 186.514735 207.74714 232.0109 259.393225 290.905105 329.41801 371.299805 413.25912 +451.245535 487.59757 510.86326 514.272525 504.50339 491.06659 481.24739 473.75702 470.79188 +471.491175 465.94688 448.826265 421.89291 385.692685 336.53693 275.843615 220.833485 172.667725 +138.452335 109.86845 87.28106 67.431095 50.761065 36.44086 23.40458 12.382205 3.77264 +0 +174.408695 186.24503 208.21226 231.893005 258.99432 290.456135 328.705795 370.82015 411.190305 +451.636365 486.478375 509.308015 514.198235 503.661975 490.829185 481.08266 472.12264 470.44627 +469.93593 463.828 448.5824 424.378395 389.798015 336.6629 278.547125 220.067975 173.953265 +138.071195 110.2722 87.81078 67.763785 50.964555 36.345575 23.34321 12.27077 3.75649 +0 +174.408695 186.0157 207.63086 230.823875 258.333785 290.4416 328.276205 369.71872 411.584365 +449.65153 484.175385 507.77215 512.935305 503.86708 488.84435 479.21249 469.905245 467.854195 +466.145525 462.72011 447.43575 420.92068 387.178485 339.510145 278.682785 222.855465 176.492045 +140.47916 111.16368 87.650895 68.65688 51.0017 36.442475 23.260845 12.34506 3.72096 +0 +174.408695 185.77345 207.59856 230.94177 258.35478 288.73293 327.291055 368.62052 409.81917 +449.25424 483.86692 504.188465 511.136195 501.5544 486.959645 476.44115 467.35193 462.392265 +461.99982 458.337 441.14371 417.88771 386.903935 340.17714 282.22448 226.653945 178.465575 +140.67942 111.313875 88.38249 68.78285 51.319855 36.348805 23.29153 12.31599 3.74357 +0 +174.408695 185.81867 206.934795 230.462115 258.078615 287.920585 325.67121 366.390205 407.695445 +447.705455 480.947 502.689745 508.27926 499.385455 486.3088 474.42886 464.59028 457.1419 +454.82276 449.010375 435.418535 415.26818 383.87258 338.59121 284.75034 231.444035 182.480465 +144.773445 114.2774 89.45808 68.965345 51.22134 36.58298 23.16556 12.336985 3.74034 +0 +174.408695 185.96079 206.6231 229.86618 257.293725 285.88084 323.179265 363.877265 405.780055 +444.85175 477.25511 499.88772 505.199455 498.019165 484.188305 472.73311 459.288235 450.66575 +446.08238 437.337155 424.565735 406.19834 378.51401 336.5983 285.727415 230.462115 184.02602 +145.044765 114.05776 89.47746 68.874905 51.26979 36.290665 23.170405 12.16418 3.741955 +0 +174.408695 185.080615 205.778455 229.060295 256.58797 284.425725 320.876275 361.193135 402.785845 +439.17018 474.37718 496.98718 502.315065 496.097315 482.618525 467.20335 455.396085 444.68379 +436.20181 425.79475 415.253645 395.80743 367.84209 328.870525 279.27226 228.09291 181.41941 +142.81122 111.34133 88.20161 67.660425 50.496205 35.347505 22.71013 11.8541 3.64667 +0 +174.408695 185.16944 205.778455 228.01862 254.89545 283.282305 317.630125 357.39304 399.119795 +435.883655 468.8991 491.830485 500.61447 494.71003 479.5581 463.735945 448.241635 437.19019 +426.04023 416.629625 404.18282 382.9488 355.27093 319.555205 273.821635 224.84676 178.866095 +142.686865 109.811925 86.98713 66.442715 49.49329 34.44472 22.05767 11.51172 3.596605 +0 +174.408695 184.83352 204.96934 227.102915 252.97683 281.0746 314.581005 353.40722 394.09553 +431.413335 463.55668 487.50713 496.41224 491.533325 477.0064 460.560855 444.61273 429.75796 +418.42389 407.062365 392.67433 372.40285 342.278255 310.327095 271.008305 225.303805 181.03181 +143.474985 111.09908 86.539775 65.80479 49.13476 34.26384 21.964 11.471345 3.561075 +0 +174.408695 184.61388 204.66895 225.662335 251.44581 279.35301 311.732145 348.838385 389.20854 +425.237575 458.577635 478.813585 491.26685 487.78168 473.40172 459.32861 439.76773 423.69848 +410.85277 395.89464 383.12968 362.301025 335.831175 306.092565 270.66108 227.96371 185.74438 +147.867785 115.01707 90.105695 67.922055 50.4203 35.024505 22.307995 11.5957 3.632135 +0 +174.408695 184.3684 203.498075 224.45916 249.356 276.85622 307.88683 344.129045 382.67102 +419.811175 451.79302 472.605525 485.17184 485.580435 472.779945 456.84797 436.20504 418.64999 +402.03487 388.609375 373.25557 354.79612 330.240045 302.678455 272.830025 233.504775 195.090385 +156.071985 121.898585 94.663225 71.05677 52.58117 36.04034 22.97499 11.89609 3.72419 +0 +174.408695 183.685255 202.709955 222.878075 247.94126 274.57907 304.72466 339.216215 376.800495 +412.563055 445.169905 466.672015 479.269015 481.484795 470.04575 454.24782 433.264125 412.986185 +393.296105 376.638995 363.499355 346.72112 324.616615 300.136445 272.33422 237.707005 202.08495 +163.588195 129.40995 100.606425 75.519015 54.960065 37.72317 23.732425 12.249775 3.79525 +0 +174.408695 183.698175 202.34981 221.40681 245.207065 271.96923 300.452985 332.875725 368.97582 +404.827205 436.15659 459.50949 472.34551 475.85652 467.62002 451.28914 430.344205 407.524255 +386.422665 368.55915 352.41238 336.667745 315.92307 294.106035 269.95048 238.42245 206.09338 +169.021055 135.04307 105.23986 79.136615 58.03664 39.594955 24.95175 12.727815 3.94706 +0 +174.408695 183.362255 201.279065 219.593165 242.287145 267.93496 295.45133 326.92445 361.6631 +395.453745 426.23726 450.832095 464.575745 468.219185 463.316045 447.524575 426.09191 402.365945 +381.08832 361.018715 341.90519 325.356285 307.681725 286.76263 266.65265 238.2125 207.50812 +172.196145 141.26728 110.629115 84.08013 61.09545 42.08367 26.23729 13.39481 4.119865 +0 +174.408695 182.945585 200.197015 218.37707 239.758055 264.564455 290.078225 319.84106 353.27156 +386.06898 417.316 440.39112 455.34279 459.488495 455.677095 442.967045 422.369335 397.143035 +372.546585 352.20243 332.633475 315.611375 297.135775 279.874655 259.251105 234.095865 206.73615 +174.828595 144.48113 114.372685 88.81208 64.07997 44.720965 27.60681 14.17001 4.349195 +0 +174.408695 182.40133 199.173105 216.615105 237.471215 259.97624 284.44995 313.453735 345.023755 +376.21748 405.19381 429.769265 445.040705 449.74197 448.03653 438.248015 419.145795 394.97409 +368.08757 345.46465 323.909245 306.0425 286.615665 269.506355 251.515255 229.3946 204.609195 +175.930025 147.56255 118.830085 93.23718 67.569985 48.015565 29.31548 15.28113 4.665735 +0 +174.408695 182.451395 198.15081 214.48169 234.806465 255.9452 279.306175 306.43979 336.45941 +365.60047 394.78998 418.26885 432.44209 438.041295 439.065205 430.508935 413.95034 390.747635 +363.189275 340.133535 317.4444 296.87253 277.213135 258.398385 241.721895 219.583475 196.73607 +172.06856 147.98568 120.060715 95.751735 70.318715 50.02301 30.76898 16.00465 4.92898 +0 +174.408695 182.04603 197.529035 213.217145 232.16594 252.60861 274.01382 299.32733 327.76425 +354.45051 382.578965 404.51228 419.220085 425.17782 426.267945 419.220085 406.04976 384.66716 +358.06488 332.93871 309.041555 288.10631 267.28573 249.26233 230.17626 210.71551 190.364895 +168.20871 144.069305 119.61013 96.11188 71.200505 51.47974 31.6217 16.671645 5.033955 +0 +174.408695 181.676195 196.29679 211.09342 228.63555 248.30625 269.251185 291.64316 317.42825 +343.00016 369.3505 390.43271 404.33786 411.280745 412.42901 407.16734 397.54517 377.446495 +351.0364 325.69705 300.985935 277.3924 255.271745 236.02902 217.516275 197.474125 178.68037 +159.589455 138.03082 116.139495 93.6054 70.66917 51.45713 31.87364 16.852525 5.10986 +0 +174.408695 181.203 194.80453 209.263625 225.701095 244.48516 263.230465 284.5953 308.511835 +332.18612 356.661445 376.949075 388.55931 395.143665 397.201175 392.65172 384.181045 365.81688 +343.747905 317.0568 290.56111 265.281515 241.55878 221.750805 201.70381 181.824775 166.181885 +148.051895 130.196455 109.337115 89.80692 68.093245 49.762995 30.883645 16.37287 4.90314 +0 +174.408695 180.62483 193.659495 207.1076 223.297975 239.993845 257.35671 277.717015 299.85059 +321.383385 343.19719 361.583965 373.266875 379.119635 380.686185 377.17679 368.61083 353.34908 +333.124435 307.584825 281.76259 254.60152 229.619085 208.191265 186.960475 167.83403 150.002815 +133.833435 116.81941 99.475925 82.00324 62.52634 45.954825 28.67594 15.095405 4.54138 +0 +174.408695 180.374505 192.331965 205.481295 219.609315 235.145615 251.65576 271.001845 290.536885 +308.931735 328.68803 345.282155 357.617525 362.75807 362.74838 358.896605 350.485685 338.001735 +321.325245 297.13739 273.072275 245.37664 218.78728 195.72508 173.753005 154.392385 136.343145 +120.936045 104.64231 88.135395 71.281255 56.19877 40.44929 25.74633 13.377045 4.058495 +0 +174.408695 179.880315 191.446945 203.469005 216.81698 231.182405 246.211595 263.30637 280.77744 +297.23752 315.824555 329.794305 340.80699 345.07382 344.1565 340.139995 332.29917 320.785835 +303.54571 282.390825 260.29278 235.429855 208.775895 184.379705 161.83269 142.74985 124.689305 +109.673035 93.229105 78.34365 62.783125 49.036245 35.114945 22.36452 11.571475 3.490015 +0 +174.408695 179.17456 190.038665 201.33236 213.33181 226.71047 240.778735 255.6222 271.670455 +285.772635 302.394215 315.40627 325.062355 328.29397 326.34305 322.249025 313.67822 302.148735 +286.48808 267.7347 245.39602 222.196545 197.21088 173.517215 152.102315 131.985875 113.29548 +97.783405 82.02585 68.332265 54.188095 42.4422 29.99055 19.28956 9.824045 2.989365 +0 +174.408695 178.988835 188.701445 198.966385 210.274615 222.206235 234.903365 248.827895 262.73466 +274.713115 289.40154 300.36416 308.708865 311.65624 308.628115 304.15618 295.365735 283.45188 +267.303495 250.55433 230.18272 207.64055 184.24243 161.705105 141.608045 121.21867 103.57964 +88.16931 72.57164 60.15875 47.1903 36.6605 25.64297 16.55052 8.299485 2.57108 +0 +174.408695 178.69652 187.04284 196.76837 207.15928 217.98301 229.467275 241.17764 253.42257 +263.81348 275.950205 285.804935 291.993615 295.246225 291.547875 285.05719 276.234445 263.970135 +248.47421 231.321295 211.831475 192.180155 170.95421 150.42756 130.877985 111.446305 94.93293 +79.66795 65.967905 54.149335 42.66507 32.902395 22.72951 14.704575 7.33533 0 +0 +174.408695 178.239475 186.19658 194.864285 204.22321 213.691955 223.51923 233.569375 244.72418 +253.19324 263.492095 271.65269 277.710555 277.952805 274.50478 266.75601 256.42324 244.98904 +228.485355 213.30274 193.830685 176.185195 156.010615 137.987215 119.747405 102.363545 86.54785 +72.43275 60.16521 49.04432 38.231895 29.352625 20.40714 13.041125 6.49876 0 +0 +174.408695 177.793735 184.86259 192.27221 200.81556 208.96162 217.803745 225.99018 235.68664 +243.634055 251.5847 258.98463 262.4052 263.482405 259.29148 250.31531 239.044225 227.254725 +210.89639 196.811975 177.61447 159.721885 141.88744 125.748745 109.088405 93.76367 79.11885 +66.058345 54.20909 44.43834 34.35751 26.322885 18.131605 11.510105 5.75909 0 +0 +174.408695 177.590245 183.833835 190.342285 197.826195 204.557515 212.002665 218.966545 228.04123 +234.221835 240.33784 246.4167 249.464205 248.98778 244.144395 236.51675 223.514385 211.553695 +195.529665 180.51178 162.489995 146.727595 129.301745 114.02223 98.658735 85.464185 71.749605 +60.57542 49.116995 40.008395 30.8465 23.545085 16.2469 10.22618 5.11309 0 +0 +174.408695 177.154195 182.46916 188.09905 194.67533 200.503865 206.673165 213.485235 219.71752 +225.174605 229.85972 234.325195 236.8236 236.45215 231.15818 224.464005 210.445805 197.648545 +182.80831 167.0556 149.79448 134.86542 118.41826 104.31608 90.525595 78.009345 66.00505 +55.564075 45.39765 36.684725 28.412695 21.406825 14.77725 9.226495 4.626975 0 +0 +174.408695 176.256255 181.094795 186.272485 191.61006 196.479285 201.770025 207.416065 212.11733 +216.90096 220.187485 223.614515 225.177835 224.51084 220.113195 212.525925 200.513555 186.007625 +172.38833 157.23317 140.03019 126.4222 110.454695 97.357045 84.34499 72.57164 61.1116 +51.357 42.08367 34.126565 26.351955 19.610945 13.566 8.45937 4.23776 0 +0 +174.408695 175.73138 179.76242 184.66233 188.632 192.645275 196.97832 201.495475 204.793305 +209.286235 211.834705 213.62574 214.19422 213.265595 210.22778 203.685415 192.11071 177.603165 +163.5026 151.472465 134.812125 121.074935 105.02345 92.340855 79.721245 69.084855 57.55537 +48.4177 39.81298 32.178875 24.714345 18.496595 12.67775 7.94903 3.96321 0 +0 +174.408695 175.613485 178.6836 182.267285 185.820285 189.315145 192.125245 195.97702 199.305535 +202.393415 204.48807 205.019405 205.41508 205.3634 202.38857 196.944405 185.96402 173.59958 +160.138555 148.16979 132.954875 119.311355 103.600635 90.74685 77.9399 66.67689 55.974285 +46.920595 37.860445 30.55903 23.590305 17.731085 12.2417 7.621185 3.806555 0 +0 +174.408695 175.10799 177.76305 180.836395 183.66103 186.15136 188.46081 191.488935 194.10685 +197.357845 198.94539 199.118195 199.760965 199.518715 196.76514 191.34843 182.335115 171.995885 +160.36627 147.55286 134.4326 120.79231 105.412665 92.05177 79.175375 67.402025 56.626745 +46.99327 38.238355 30.328085 23.34321 17.3451 11.91224 7.437075 3.70804 0 +0 +174.408695 174.828595 176.863495 179.45557 181.78763 183.617425 185.55704 188.145885 190.55708 +193.097475 195.229275 195.63141 196.17405 195.445685 192.54353 189.00022 180.035355 172.041105 +161.233525 149.59099 136.47719 124.091755 109.01896 96.05374 82.159895 70.493135 59.00564 +48.887665 38.78261 31.019305 23.80187 17.391935 12.139955 7.395085 3.74357 0 +0 +174.408695 174.440995 175.96394 178.01822 179.80118 181.82639 183.8839 185.306715 187.88587 +190.261535 193.25413 193.7354 195.287415 193.26059 191.921755 188.149115 180.84447 173.081165 +162.91474 152.118465 140.422635 127.951605 114.760285 101.18621 88.103095 76.126255 62.618395 +51.65093 40.43314 32.382365 23.92784 17.72624 11.936465 7.340175 3.68543 0 +0 +174.408695 174.024325 175.10476 176.50981 178.92585 180.594145 182.984345 184.35871 187.919785 +189.289305 192.222145 193.940505 195.41177 192.7018 192.68888 188.04091 183.685255 172.364105 +164.502285 153.76738 145.487275 132.864435 119.589135 106.14426 95.835715 81.85143 68.9282 +55.98559 43.85694 34.32844 25.424945 18.163905 12.030135 7.330485 3.606295 0 +0 +174.408695 173.61896 174.54274 176.065685 178.006915 179.854475 183.016645 185.05962 188.413975 +189.49764 192.212455 194.786765 194.56874 191.93629 189.91431 183.37356 177.880945 166.09629 +158.64468 150.2596 143.726925 132.08439 121.730625 108.846155 99.198145 83.61501 71.50251 +56.894835 47.311425 35.25868 26.67657 18.37547 12.275615 7.330485 3.61114 0 +0 +174.408695 173.756235 174.45553 175.49882 177.14612 180.154865 183.8839 185.736305 190.18563 +191.53577 191.908835 191.818395 188.56094 185.60872 178.313765 171.340195 161.23837 153.355555 +145.84096 137.832175 129.3292 118.24707 110.286735 99.595435 90.012025 75.26546 66.239225 +53.54371 45.03589 34.38658 26.439165 18.10738 12.74558 7.40962 3.75649 0 +0 +174.408695 173.585045 173.95811 174.99171 177.44005 181.33543 185.490825 187.7922 191.614905 +192.083255 188.82903 186.149745 178.67391 172.028185 160.942825 150.82485 141.67103 133.22135 +124.178965 116.11527 106.610995 96.239465 88.77009 81.032625 71.487975 62.754055 53.984605 +45.586605 38.183445 29.691775 23.7405 17.04794 12.198095 7.2352 3.70804 0 +0 +174.408695 173.265275 173.491375 174.689705 177.935855 182.661345 187.66623 189.744735 192.267365 +190.04674 180.955905 174.47168 164.38762 153.798065 141.520835 131.0411 121.204135 113.80259 +102.489515 94.524335 86.759415 76.943445 68.85391 63.267625 54.02175 49.41577 41.85111 +36.145315 29.59326 24.6126 19.604485 14.759485 10.36184 6.42124 3.254225 0 +0 +174.408695 173.236205 173.774 175.20812 178.942 184.40393 189.163335 190.901075 189.825485 +182.373875 171.369265 160.85723 148.17302 135.180345 123.28264 112.244115 103.4892 95.092815 +85.105655 77.379495 68.810305 63.206255 55.62383 50.347625 43.370825 38.852055 32.621385 +28.745385 23.52086 19.62548 15.68165 12.06728 8.328555 5.35211 2.73258 0 +0 +174.408695 173.239435 173.891895 175.91226 179.90454 185.797675 190.46987 190.14041 185.81544 +173.213595 160.513235 146.33515 132.166755 120.306195 107.38458 97.973975 89.366025 80.89858 +72.179195 66.06642 57.84607 52.87833 46.54107 42.19026 36.4021 32.27416 27.53575 +23.8374 19.94202 16.781465 13.02336 10.105055 7.106 4.59629 0 0 +0 +174.408695 173.20552 173.711015 176.71653 181.104485 187.09452 190.474715 187.0816 178.90647 +164.02909 146.5774 131.882515 118.54423 107.00021 95.40774 86.281375 77.637895 70.993785 +62.77828 57.305045 50.88542 45.589835 40.631785 36.048415 31.555485 27.818375 23.79218 +20.70107 17.61965 14.63836 11.52787 8.880885 6.29204 4.06011 0 0 +0 +174.408695 173.065015 173.988795 177.33023 182.373875 187.4369 188.785425 182.138085 170.57953 +152.97926 133.791445 118.523235 106.14749 95.951995 85.415735 76.97736 69.25443 62.770205 +55.66259 50.52689 44.59661 39.808135 35.03258 31.59263 27.611655 24.178165 20.91748 +18.173595 15.224605 12.766575 10.14543 7.844055 5.5879 3.635365 0 0 +0 +174.408695 172.98911 174.14545 178.15388 182.761475 187.45305 186.065765 176.462975 160.29521 +141.369025 122.00033 107.53639 95.81795 86.152175 77.279365 70.12976 62.579635 56.000125 +49.375395 44.746805 39.41246 35.19731 31.025765 27.695635 24.036045 21.284085 18.52082 +16.057945 13.57246 11.274315 8.977785 6.984875 5.001655 3.33336 0 0 +0 +174.408695 172.806615 174.45876 178.895165 183.724015 187.5984 182.0751 169.398965 150.803855 +130.74071 112.386235 98.88322 87.615365 78.43409 70.72731 64.033135 56.70588 50.386385 +44.19609 39.87435 35.063265 31.368145 27.682715 24.426875 21.60224 19.40907 16.75401 +14.69973 12.391895 10.50719 8.43676 6.535905 4.743255 3.17509 0 0 +0 +174.408695 172.53045 174.86897 179.73335 184.53636 185.84774 177.2947 161.223835 140.929745 +120.923125 103.36 91.22166 80.073315 72.41014 64.588695 58.03018 50.86927 45.45902 +39.9228 35.454095 31.28901 28.050935 24.86131 22.349985 20.00339 18.15906 15.883525 +13.86962 11.888015 9.911255 8.076615 6.232285 4.55753 3.050735 0 0 +0 +174.408695 172.59505 175.206505 180.846085 184.73985 182.926205 171.92967 152.75962 130.564675 +111.436615 95.987525 83.76682 74.78419 67.043495 58.480765 52.46489 45.98874 41.200265 +35.935365 32.256395 28.645255 25.93367 23.283455 21.15973 19.152285 17.159375 15.273055 +13.322135 11.371215 9.52204 7.74554 6.00457 4.429945 2.96837 0 0 +0 +174.408695 172.65319 175.79921 181.81347 184.10354 179.8787 166.0866 144.311555 121.771 +103.31155 89.721325 78.138545 70.134605 61.927175 54.165485 48.031715 41.86403 37.450235 +33.034825 29.79998 26.809 24.56092 22.301535 20.47497 18.580575 16.62158 14.68358 +12.834405 10.964235 9.239415 7.521055 5.8463 4.300745 2.91669 0 0 +0 +174.408695 172.54983 176.288555 182.402945 183.501145 176.62932 159.27776 135.890945 113.87365 +96.914535 83.396985 73.513185 65.93399 57.41325 49.785605 43.77942 38.499985 34.433415 +30.7819 28.15914 25.65266 23.68236 21.48596 19.64809 17.85544 15.990115 14.139325 +12.404815 10.615395 8.90834 7.24166 5.676725 4.207075 2.866625 0 0 +0 +174.408695 172.6112 176.75206 182.687185 182.399715 172.335035 152.725705 128.623445 106.87747 +91.30887 77.97543 69.29642 61.817355 53.01722 45.56561 40.444445 35.609135 32.146575 +29.349395 27.07709 24.817705 22.78119 20.77213 19.09576 17.25466 15.450705 13.606375 +11.907395 10.25848 8.680625 7.12861 5.586285 4.168315 2.84563 0 0 +0 +174.408695 172.65319 177.25271 182.793775 180.37289 168.55432 146.091285 121.685405 100.83414 +86.28945 74.537095 66.0212 57.721715 49.23812 42.501955 37.76193 33.60492 30.625245 +28.325485 26.255055 24.032815 22.38713 20.347385 18.635485 16.61835 14.885455 13.263995 +11.68291 10.13897 8.580495 7.085005 5.54591 4.148935 2.83917 0 0 +0 +174.408695 172.829225 177.63385 182.6565 177.72106 163.88374 140.047955 115.761585 95.45942 +81.27972 71.46698 62.38745 53.858635 46.13732 39.93572 35.57845 32.14173 29.65463 +27.70694 25.53638 23.709815 21.804115 19.872575 18.01694 16.24367 14.659355 13.131565 +11.59893 10.0776 8.538505 7.04786 5.531375 4.148935 2.85855 0 0 +0 +174.408695 172.39802 178.06021 182.82123 175.63448 159.2067 134.075685 110.622655 91.1506 +77.954435 68.312885 58.95719 50.370235 43.374055 37.750625 33.890775 31.080675 29.097455 +26.881675 24.97436 23.196245 21.27924 19.355775 17.68102 16.07248 14.55438 13.054045 +11.542405 10.050145 8.50459 7.03171 5.51361 4.14732 2.86178 0 0 +0 +174.408695 172.6758 178.2637 181.937825 173.00526 154.634635 128.86408 106.006985 87.4684 +75.36236 65.722425 56.02112 47.76201 41.135665 36.129165 32.883015 30.466975 28.41431 +26.435935 24.55446 22.48726 20.64939 19.05054 17.49368 15.99173 14.44456 13.02013 +11.51495 10.02915 8.490055 7.03171 5.51361 4.148935 2.86178 0 0 +0 +174.408695 172.515915 178.862865 181.262755 170.42772 149.673355 123.88019 101.937185 84.398285 +73.20472 63.22402 53.49849 45.563995 39.003865 34.850085 32.140115 29.83228 28.13007 +25.880375 24.04412 21.968845 20.298935 18.78245 17.330565 15.93036 14.43487 13.0492 +11.53433 10.04207 8.49813 7.039785 5.534605 4.15701 2.882775 0 0 +0 +174.408695 172.59182 179.02598 180.31475 167.93739 145.270865 119.443785 98.58606 82.00001 +71.45083 60.47529 51.22457 43.32076 37.60043 33.96345 31.77674 29.41238 27.715015 +25.70111 23.40781 21.67976 20.166505 18.69847 17.31603 15.977195 14.468785 13.070195 +11.55694 10.069525 8.53689 7.065625 5.56529 4.19577 2.908615 0 0 +0 +174.408695 172.767855 179.47818 179.489485 165.471285 141.220445 115.71152 95.709745 79.947345 +69.614575 58.067325 49.042705 41.78974 36.591055 33.50156 31.28578 29.220195 27.495375 +25.211765 23.141335 21.545715 20.10675 18.75338 17.35156 16.03372 14.51562 13.118645 +11.60539 10.11636 8.599875 7.130225 5.625045 4.232915 2.934455 0 0 +0 +174.408695 172.909975 179.447495 178.6513 163.139225 137.88547 112.179515 93.27917 78.199915 +67.78155 56.080875 47.405095 40.680235 35.912755 33.0752 30.867495 28.96341 27.091625 +24.859695 22.966915 21.46335 20.143895 18.813135 17.47753 16.15646 14.64805 13.24623 +11.67968 10.21972 8.680625 7.18029 5.67834 4.278135 2.969985 0 0 +0 +174.408695 173.139305 179.970755 177.85026 160.4341 135.02692 109.924975 91.110225 77.014505 +65.945295 54.485255 46.096945 39.66117 35.463785 32.82972 30.54611 28.787375 26.823535 +24.42526 22.831255 21.458505 20.237565 18.890655 17.64872 16.264665 14.79986 13.338285 +11.797575 10.29401 8.751685 7.23843 5.73325 4.307205 2.995825 0 0 +0 +174.408695 173.071475 180.19847 176.521115 158.25385 132.2362 107.44918 89.33857 75.993825 +64.449805 52.99784 44.927685 38.7923 35.16824 32.744125 30.6527 28.819675 26.41817 +24.320285 22.85548 21.52472 20.32316 19.0247 17.766615 16.35672 14.91291 13.409345 +11.894475 10.373145 8.825975 7.307875 5.76878 4.33466 3.01682 0 0 +0 +174.408695 172.867985 180.46333 175.94456 156.314235 129.686115 105.2657 87.72357 75.150795 +63.254705 51.894795 44.181555 38.31103 35.29098 32.602005 30.88526 28.729235 26.054795 +24.36066 22.966915 21.642615 20.437825 19.152285 17.882895 16.41163 15.00012 13.4691 +11.99622 10.42321 8.88573 7.34502 5.815615 4.36696 3.03297 0 0 +0 +174.408695 172.968115 180.125795 174.931955 154.44568 127.386355 103.58287 86.03751 74.07359 +62.411675 51.384455 43.42735 38.13338 35.23607 32.63592 30.9111 28.44015 26.038645 +24.47371 23.067045 21.771815 20.567025 19.29925 17.957185 16.54406 15.085715 13.56277 +12.09312 10.51042 8.96971 7.391855 5.860835 4.394415 3.05235 0 0 +0 +174.408695 173.28627 180.15971 173.8063 152.98249 125.438665 102.208505 85.024905 73.51157 +61.80282 51.17612 43.06236 38.105925 35.16501 32.92339 30.83035 28.319025 25.980505 +24.517315 23.154255 21.952695 20.641315 19.400995 18.008865 16.661955 15.13901 13.658055 +12.17064 10.60086 9.044 7.472605 5.902825 4.426715 3.07496 0 0 +0 +174.408695 173.00526 180.31475 173.14738 151.5516 123.797825 101.15068 84.252935 72.912405 +61.75114 50.996855 42.608545 37.8233 34.969595 32.74897 30.73668 28.134915 25.88845 +24.568995 23.21724 22.05121 20.757595 19.48659 18.08477 16.72817 15.23591 13.780795 +12.22232 10.670305 9.090835 7.537205 5.93674 4.47032 3.086265 0 0 +0 +174.408695 173.44131 179.99821 172.276895 149.95275 122.51713 100.154225 83.836265 72.550645 +61.232725 50.61087 42.136965 37.55844 34.940525 32.602005 30.79159 28.012175 25.941745 +24.656205 23.286685 22.16426 20.83027 19.578645 18.13322 16.823455 15.31343 13.884155 +12.285305 10.757515 9.161895 7.60665 5.9755 4.488085 3.09757 0 0 +0 +174.408695 173.22813 180.219465 171.378955 148.47341 121.071705 99.278895 83.151505 72.38107 +61.003395 50.43645 41.927015 37.398555 34.830705 32.640765 30.69469 27.97826 25.86261 +24.649745 23.341595 22.18364 20.951395 19.62548 18.26565 16.849295 15.399025 13.9213 +12.36444 10.812425 9.21519 7.634105 6.01103 4.51231 3.11049 0 0 +0 +174.408695 173.55113 180.193625 170.946135 147.2557 119.82331 98.89614 82.822045 71.756065 +60.55281 50.08115 41.755825 37.556825 34.884 32.91047 30.521885 27.805455 25.896525 +24.48986 23.396505 22.188485 21.035375 19.659395 18.28503 16.87998 15.44586 13.96329 +12.39351 10.81404 9.249105 7.653485 6.03364 4.51231 3.12018 0 0 +0 +174.408695 173.139305 180.642595 170.65382 146.259245 118.99643 98.4827 82.53619 71.355545 +60.18136 50.01655 41.97385 37.679565 35.10687 33.060665 30.431445 27.847445 25.91752 +24.43818 23.41427 22.236935 21.05637 19.71592 18.318945 16.942965 15.44909 13.964905 +12.427425 10.835035 9.255565 7.66479 6.038485 4.522 3.121795 0 0 +0 +174.408695 173.50591 180.703965 170.3179 145.79574 118.22123 98.6119 82.14536 70.777375 +59.55151 50.024625 42.02553 37.640805 34.969595 32.83941 30.499275 27.695635 25.873915 +24.50278 23.377125 22.356445 21.09836 19.762755 18.34963 16.942965 15.470085 14.003665 +12.443575 10.86249 9.27656 7.679325 6.06917 4.53815 3.12664 0 0 +0 +174.408695 173.89351 180.962365 169.941605 145.24018 117.70443 98.65389 81.82882 70.26865 +59.369015 50.176435 42.107895 37.73609 34.80325 32.844255 30.525115 27.50668 25.780245 +24.48017 23.40135 22.40651 21.103205 19.80959 18.357705 16.99626 15.50077 14.029505 +12.44842 10.886715 9.30563 7.70678 6.07886 4.54138 3.131485 0 0 +0 +174.408695 173.807915 180.787945 170.032045 145.329005 117.612375 98.72172 81.55104 70.476985 +59.446535 50.31371 41.962545 37.8233 34.859775 32.76512 30.418525 27.43239 25.70434 +24.40911 23.42396 22.333835 21.112895 19.76437 18.377085 17.01887 15.518535 14.00851 +12.462955 10.87541 9.310475 7.705165 6.06917 4.54784 3.131485 0 0 +0 diff --git a/data/ies_profiles/overhead.ies b/data/ies_profiles/overhead.ies new file mode 100644 index 0000000..80f4fa5 --- /dev/null +++ b/data/ies_profiles/overhead.ies @@ -0,0 +1,24 @@ +IESNA:LM-63-1995 +[TEST]BALLABS TEST NO. 14061.0 +[MANUFAC] H.E. WILLIAMS, INC - CARTHAGE, MISSOURI +[LUMINAIRE] 8/54W T5HO LAMP 25x48"CABLE MOUNT LUMINAIRE +[MORE] MIRO4 SPECULAR REFLECTOR w/OPEN BOTTOM +[MORE] 2 UNIVERSAL BALLAST #B454PUNV-E WATTS=432 +[LUMCAT] HL-4-854T5H-MD-EB4/4-BD-UNV +[LAMPCAT] FP54T5HO/835 +TILT=NONE + 8 5000. 1.000000 19 5 1 1 2.083 4.000 .000 + 1.0000 1.0000 432.0000 + .0 5.0 10.0 15.0 20.0 25.0 30.0 35.0 40.0 45.0 + 50.0 55.0 60.0 65.0 70.0 75.0 80.0 85.0 90.0 + .0 22.5 45.0 67.5 90.0 + 19229. 19192. 19185. 18789. 18134. 17000. 15662. 14433. 13163. 11892. + 10500. 8916. 7319. 5817. 4110. 2580. 1269. 327. 0. + 19229. 19239. 19253. 18898. 18188. 16905. 15184. 13505. 11443. 9375. + 7606. 5721. 4260. 3031. 2007. 1447. 1037. 396. 0. + 19229. 19140. 19267. 18557. 17041. 14788. 12139. 10050. 8097. 6603. + 5311. 4123. 3523. 3004. 2621. 1925. 1106. 368. 0. + 19229. 19168. 19090. 17820. 15280. 12808. 10091. 8466. 6854. 5739. + 4833. 4192. 3919. 3577. 2826. 1898. 1078. 300. 0. + 19229. 19182. 18980. 17451. 14652. 12139. 9613. 8042. 6513. 5624. + 4861. 4328. 4096. 3686. 2812. 1884. 1065. 259. 0. diff --git a/data/ies_profiles/parallel_beam.ies b/data/ies_profiles/parallel_beam.ies new file mode 100644 index 0000000..5a521c0 --- /dev/null +++ b/data/ies_profiles/parallel_beam.ies @@ -0,0 +1,35 @@ +IESNA:LM-63-2002 +[TEST] 3907_1 +[TESTLAB] ERCO GmbH +[ISSUEDATE] 02-12-2008 +[MANUFAC] ERCO GmbH +[LUMCAT] 81051000 +[LUMINAIRE] Lightcast Directional luminaire +[LAMP] HIT-CE 70W +TILT=NONE +1 6600 1 19 7 1 2 -0.127 -0.127 0 +1.0 1.0 79 +0 5 10 15 20 25 30 35 40 45 50 55 60 +65 70 75 80 85 90 +0 15 30 45 60 75 90 +11501.82 8886.24 4579.74 2596.836 1430.154 810.546 487.8588 266.8446 163.6338 +108.933 71.247 41.349 20.0178 10.2234 0 0 0 0 +0 +11501.82 8992.5 4689.564 2685.144 1510.806 853.512 524.139 292.0962 171.7056 +113.3682 72.9366 43.0452 20.4006 10.0782 0 0 0 0 +0 +11501.82 9288.84 5057.58 2943.864 1719.432 987.162 595.7424 347.8464 193.71 +120.1464 74.7186 45.5994 22.1232 9.8736 0 0 0 0 +0 +11501.82 9724.44 5794.14 3453.186 2080.782 1230.108 722.238 427.614 235.719 +138.6726 83.4702 49.1502 24.0768 9.207 0 0 0 0 +0 +11501.82 10198.32 7048.8 4538.688 2758.668 1656.402 938.916 532.158 289.707 +157.3836 89.9844 53.1366 24.783 8.1642 0 0 0 0 +0 +11501.82 10580.46 8413.02 6409.458 4582.182 2761.044 1490.742 710.754 335.8674 +173.3754 96.4194 55.9944 26.4858 8.4678 0 0 0 0 +0 +11501.82 10746.12 9057.18 7549.74 6203.736 3923.898 1914.198 784.278 360.2148 +177.9558 99.2772 57.8556 27.5748 8.976 0 0 0 0 +0 diff --git a/data/ies_profiles/pear.ies b/data/ies_profiles/pear.ies new file mode 100644 index 0000000..3c8ad63 --- /dev/null +++ b/data/ies_profiles/pear.ies @@ -0,0 +1,24 @@ +IESNA:LM-63-1995 +[TEST]BALLABS TEST NO. 10495.0 +[MANUFAC] H.E. WILLIAMS, INC - CARTHAGE, MISSOURI +[LUMINAIRE] 1/150W ICETRON LAMP 2x2 DIRECT RECESSED LUMINAIRE +[LUMINAIRE] SPECULAR REFLECTOR w/PRISMATIC ACRYLIC PAT-12 LENS +[LUMINAIRE] SYLVANIA BALLAST #QT1x150/120-240 ICE WATTS=155 +[LUMCAT]CATALOG NO. : MPG-S22-1/150I LER +[LAMPCAT]LAMP CODE : ICE150/835 +TILT=NONE + 1 12000. 1.000000 19 5 1 1 1.688 1.677 .000 + 1.0000 1.0000 155.0000 + .0 5.0 10.0 15.0 20.0 25.0 30.0 35.0 40.0 45.0 + 50.0 55.0 60.0 65.0 70.0 75.0 80.0 85.0 90.0 + .0 22.5 45.0 67.5 90.0 + 3962. 3933. 3802. 3619. 3384. 3120. 2804. 2463. 2013. 1517. + 1089. 770. 568. 415. 333. 270. 189. 79. 0. + 3962. 3912. 3776. 3603. 3409. 3178. 2885. 2522. 2071. 1569. + 1115. 784. 573. 429. 343. 266. 185. 73. 0. + 3962. 3918. 3798. 3612. 3402. 3195. 2919. 2615. 2199. 1693. + 1203. 843. 601. 449. 337. 265. 179. 85. 0. + 3962. 3901. 3765. 3603. 3418. 3210. 2932. 2592. 2147. 1660. + 1183. 818. 577. 428. 333. 261. 179. 69. 0. + 3962. 3920. 3792. 3613. 3430. 3266. 3056. 2776. 2335. 1816. + 1338. 927. 640. 453. 342. 271. 182. 68. 0. diff --git a/data/ies_profiles/scatter_light.ies b/data/ies_profiles/scatter_light.ies new file mode 100644 index 0000000..338da4e --- /dev/null +++ b/data/ies_profiles/scatter_light.ies @@ -0,0 +1,36 @@ +IESNA:LM-63-2002 +[TEST]BALLABS TEST NO. 14353.0 +[TESTLAB] BUILDING ACOUSTICS & LIGHTING LABORATORIES, INC +[ISSUEDATE] 29-DEC-2008 +[MANUFAC] H.E. WILLIAMS, INC - CARTHAGE, MISSOURI +[LUMINAIRE] 1/250W ED28 PS MH LAMP 17x17x10"SQ AREA LUMINAIRE +[MORE] MIRO4 SPECULAR FORWARD THROW DISTRIBUTION REFLECTOR +[MORE] CLEAR FLAT GLASS LENS +[LUMCAT] OER1717-250PSMH120-TFT +[LAMPCAT] M153/E MH250W/H75/P +TILT=NONE +1 22000 1 25 21 1 1 1.11 1.11 0 +1 1 250 +0 5 10 15 20 25 30 35 40 45 50 55 60 62.5 65 67.5 70 72.5 75 77.5 80 82.5 85 87.5 90 +0 5 15 25 35 45 55 65 75 85 90 95 105 115 125 135 145 155 165 175 180 +2698.00 3943.00 5458.00 6672.00 6831.00 7214.00 7080.00 5916.00 5057.00 5401.00 5200.00 3823.00 4642.00 4546.00 3326.00 4307.00 4716.00 3352.00 2186.00 1024.00 164.00 33.00 1.00 0.00 0.00 +2698.00 3973.00 5563.00 7147.00 7067.00 7341.00 7279.00 6574.00 5462.00 5861.00 5381.00 3878.00 4745.00 4638.00 3478.00 4444.00 4903.00 3779.00 2312.00 1321.00 268.00 34.00 0.00 0.00 0.00 +2698.00 4247.00 5895.00 7809.00 7305.00 7481.00 7591.00 7469.00 5914.00 5507.00 5457.00 3972.00 4789.00 4514.00 3983.00 4291.00 4333.00 4226.00 3418.00 1555.00 301.00 33.00 0.00 0.00 0.00 +2698.00 3962.00 5992.00 8215.00 7325.00 7430.00 7666.00 6840.00 5236.00 4909.00 5078.00 4158.00 4647.00 4356.00 4229.00 3282.00 4660.00 3998.00 3538.00 1950.00 464.00 38.00 0.00 0.00 0.00 +2698.00 3718.00 5991.00 8093.00 7644.00 7666.00 7065.00 6385.00 6315.00 4905.00 5666.00 4104.00 4832.00 6475.00 4871.00 2674.00 5890.00 4150.00 5346.00 2833.00 702.00 47.00 1.00 0.00 0.00 +2698.00 3315.00 5882.00 7298.00 8906.00 7613.00 6407.00 6351.00 7849.00 5321.00 7181.00 4739.00 5685.00 4241.00 3129.00 2071.00 3098.00 3571.00 3435.00 2095.00 1203.00 271.00 0.00 0.00 0.00 +2698.00 3110.00 4667.00 6205.00 7897.00 8795.00 6483.00 7120.00 6544.00 5762.00 10333.00 2340.00 3481.00 3706.00 3439.00 2736.00 1690.00 2207.00 2514.00 1436.00 644.00 109.00 0.00 0.00 0.00 +2698.00 2701.00 3758.00 4788.00 6029.00 7687.00 8309.00 7108.00 5106.00 7821.00 3277.00 2142.00 2247.00 2162.00 2026.00 1480.00 1290.00 1412.00 387.00 543.00 182.00 117.00 0.00 0.00 0.00 +2698.00 2771.00 2944.00 4037.00 4601.00 4975.00 5264.00 3669.00 4336.00 7602.00 3156.00 3270.00 2701.00 2160.00 2660.00 1389.00 1533.00 1199.00 1021.00 224.00 180.00 54.00 0.00 0.00 0.00 +2698.00 2732.00 3015.00 3506.00 4038.00 3169.00 3471.00 2415.00 3423.00 7272.00 2935.00 1882.00 1764.00 1895.00 2225.00 1567.00 1584.00 1262.00 703.00 192.00 346.00 47.00 0.00 0.00 0.00 +2698.00 2743.00 3286.00 4036.00 4457.00 3456.00 2094.00 2262.00 4356.00 7484.00 3955.00 1670.00 1163.00 1062.00 943.00 857.00 701.00 465.00 189.00 78.00 56.00 6.00 0.00 0.00 0.00 +2698.00 2918.00 4025.00 5141.00 5140.00 3749.00 2006.00 1904.00 2552.00 2538.00 1859.00 1553.00 1125.00 1073.00 958.00 1141.00 672.00 478.00 182.00 64.00 25.00 0.00 0.00 0.00 0.00 +2698.00 3464.00 4778.00 5035.00 4629.00 3210.00 2471.00 2042.00 3098.00 2579.00 1434.00 1252.00 1146.00 1423.00 982.00 1008.00 1184.00 353.00 97.00 35.00 5.00 0.00 0.00 0.00 0.00 +2698.00 4025.00 4809.00 4376.00 3673.00 2601.00 1992.00 2043.00 1859.00 1968.00 2114.00 1492.00 1216.00 1066.00 686.00 354.00 220.00 95.00 53.00 17.00 4.00 0.00 0.00 0.00 0.00 +2698.00 4236.00 4435.00 3765.00 2559.00 2564.00 1816.00 1794.00 1815.00 1890.00 1660.00 1338.00 687.00 351.00 558.00 101.00 59.00 55.00 61.00 41.00 10.00 0.00 0.00 0.00 0.00 +2698.00 4418.00 4174.00 2760.00 2602.00 2238.00 1959.00 1846.00 1693.00 1664.00 1665.00 796.00 306.00 125.00 94.00 86.00 76.00 72.00 71.00 59.00 36.00 17.00 0.00 0.00 0.00 +2698.00 4391.00 3812.00 2473.00 2438.00 2231.00 2219.00 1983.00 1899.00 1760.00 889.00 331.00 130.00 166.00 309.00 301.00 94.00 58.00 47.00 34.00 21.00 7.00 0.00 0.00 0.00 +2698.00 4257.00 3531.00 2438.00 2319.00 2044.00 2167.00 2131.00 1947.00 1503.00 668.00 224.00 285.00 212.00 105.00 80.00 70.00 65.00 53.00 38.00 25.00 11.00 0.00 0.00 0.00 +2698.00 4110.00 3488.00 2406.00 2227.00 2084.00 2068.00 2015.00 1882.00 1212.00 589.00 195.00 283.00 276.00 162.00 109.00 105.00 90.00 82.00 50.00 35.00 19.00 5.00 0.00 0.00 +2698.00 4024.00 3228.00 2390.00 2172.00 2042.00 2014.00 1959.00 1846.00 1134.00 463.00 188.00 265.00 235.00 153.00 108.00 110.00 90.00 76.00 53.00 38.00 23.00 8.00 0.00 0.00 +2698.00 3931.00 3193.00 2575.00 2140.00 2066.00 1998.00 1956.00 1841.00 1186.00 544.00 205.00 274.00 230.00 167.00 112.00 115.00 93.00 76.00 56.00 41.00 25.00 9.00 0.00 0.00 diff --git a/data/ies_profiles/soft_arrow.ies b/data/ies_profiles/soft_arrow.ies new file mode 100644 index 0000000..ea0c47c --- /dev/null +++ b/data/ies_profiles/soft_arrow.ies @@ -0,0 +1,14 @@ +IESNA91 +[MANUFAC] Halo,Recessed +[LUMCAT] H7t-301 +[LUMINAIRE] Open Trim (75W R-30 Flood) +[LAMP] +[REPORT] +TILT=NONE +1 900.0 1.0 36 1 1 1 0.0 -0.32 0.0 +1.0 1.0 75.0 +0.0 1.0 2.0 3.0 4.0 5.0 6.0 7.0 8.0 9.0 10.0 11.0 12.0 13.0 14.0 15.0 17.5 20.0 22.5 25.0 27.5 30.0 32.5 35.0 37.5 40.0 45.0 +50.0 55.0 60.0 65.0 70.0 75.0 80.0 85.0 90.0 +0.0 +1512.0 1516.0 1508.0 1487.0 1453.0 1409.0 1357.0 1294.0 1229.0 1158.0 1085.0 1008.0 934.0 862.0 795.0 727.0 578.0 459.0 368.0 +304.0 256.0 222.0 197.0 177.0 163.0 153.0 141.0 124.0 73.0 28.0 23.0 18.0 13.0 9.0 4.0 1.0 diff --git a/data/ies_profiles/soft_display.ies b/data/ies_profiles/soft_display.ies new file mode 100644 index 0000000..f3cb4c3 --- /dev/null +++ b/data/ies_profiles/soft_display.ies @@ -0,0 +1,29 @@ +ERCO Leuchten GmbH BY: ERCO/LUM650/8701 +74216023+Q50MR16/C/CG55-FNV.IES +- +- +- +- +- +- +TILT=NONE +1 825 .825 73 2 1 2 -.2 0 0 +1.00 1.00 50 +0 1.25 2.5 3.75 5 6.25 7.5 8.75 10 11.25 12.5 13.75 15 16.25 17.5 18.75 20 +21.25 22.5 23.75 25 26.25 27.5 28.75 30 31.25 32.5 33.75 35 36.25 37.5 38.75 +40 41.25 42.5 43.75 45 46.25 47.5 48.75 50 51.25 52.5 53.75 55 56.25 57.5 +58.75 60 61.25 62.5 63.75 65 66.25 67.5 68.75 70 71.25 72.5 73.75 75 76.25 +77.5 78.75 80 81.25 82.5 83.75 85 86.25 87.5 88.75 90 +0 90 +1091 1113 1132 1160 1183 1206 1219 1223 1217 1207 1190 1162 1120 1063 995.2 +919 837.6 753.2 666.7 579.4 495.8 418.3 338.2 250.3 175.8 135.5 123.9 128.9 +138.2 142.1 140.9 137.1 133.3 131.4 129.6 125.5 116.4 100.9 81.69 62.57 47.27 +38.54 35 34.26 33.94 32.17 29.22 25.91 23.03 21.2 20.24 19.77 19.39 18.83 +18.14 17.47 16.97 16.74 16.74 16.85 16.97 17.03 17.03 17 16.97 16.95 16.95 +16.96 16.97 16.97 16.97 16.97 16.97 +1091 1113 1132 1160 1183 1206 1219 1223 1217 1207 1190 1162 1120 1063 995.2 +919 837.6 753.2 666.7 579.4 495.8 418.3 338.2 250.3 175.8 135.5 123.9 128.9 +138.2 142.1 140.9 137.1 133.3 131.4 129.6 125.5 116.4 100.9 81.69 62.57 47.27 +38.54 35 34.26 33.94 32.17 29.22 25.91 23.03 21.2 20.24 19.77 19.39 18.83 +18.14 17.47 16.97 16.74 16.74 16.85 16.97 17.03 17.03 17 16.97 16.95 16.95 +16.96 16.97 16.97 16.97 16.97 16.97 diff --git a/data/ies_profiles/star_focused.ies b/data/ies_profiles/star_focused.ies new file mode 100644 index 0000000..d2decb0 --- /dev/null +++ b/data/ies_profiles/star_focused.ies @@ -0,0 +1,48 @@ +IESNA91 +[TEST] NO. 12296 +[MANUFAC]LITHONIA - ESG MODEL HQM LAMPHEAD +[LUMCAT]ELA CDS N0606 +[LUMINAIRE]SPECULAR REFLECTOR WITH TRANSLUCENT PLASTIC LENS +[LAMP]ONE GE#939 INCANDESCENT WEDGE MINIATURE LAMP.. LUMEN RATING = 68 LMS. +[MORE]6 VOLTS DC OPERATING AT .9 AMPS AND 5.4 WATTS +[OTHER]LITHONIA- ESG LIGHTING +[MORE]DECATUR, GA +[OTHER]Version: 4/1/97 - 12:00:00 +TILT=NONE +1 +68 +1 +37 +5 +1 +1 +.33 +.33 +.00 +1 +1 +5.4000 +0,2.5,5,7.5,10,12.5,15,17.5,20,22.5,25,27.5,30,32.5,35,37.5 +40,42.5,45,47.5,50,52.5,55,57.5,60,62.5,65,67.5,70,72.5,75 +77.5,80,82.5,85,87.5,90 +0,22.5,45,67.5,90 +166,160,125,88,53,40,27,19,14,11 +9,7,7,6,6,5,5,5,5,4 +4,4,3,3,3,3,3,2,2,1 +1,1,1,1,0,0,0 +166,158,124,89,59,40,26,18,13,10 +8,7,6,6,5,5,5,5,4,4 +4,4,4,3,3,2,2,2,1,1 +1,1,1,0,0,0,0 +166,153,120,85,56,37,24,17,12,9 +8,7,6,5,5,5,5,4,4,4 +4,4,3,3,3,2,2,2,1,1 +1,1,1,0,0,0,0 +166,148,114,80,52,34,22,15,11,9 +7,6,6,6,5,5,5,4,4,4 +4,4,3,3,3,2,2,2,1,1 +1,1,1,0,0,0,0 +166,142,108,75,49,32,21,15,11,9 +7,6,6,6,5,5,5,5,4,4 +4,4,3,3,3,2,2,2,1,1 +1,1,1,0,0,0,0 diff --git a/data/ies_profiles/three_lobe_umbrella.ies b/data/ies_profiles/three_lobe_umbrella.ies new file mode 100644 index 0000000..cf7881b --- /dev/null +++ b/data/ies_profiles/three_lobe_umbrella.ies @@ -0,0 +1,16 @@ +IESNA:LM-63-1995 +[TEST] 100071_0 BY: ERCO / LUM650 +[DATE]02.12.2004 +[MANUFAC] ERCO Leuchten GmbH +[LUMCAT] 22625000 +[LUMINAIRE] Lightcast Directional luminaire +[LAMPCAT] QPAR30 75W 30 +TILT=NONE +1 1234 1 37 1 1 2 -.097 0 0 +1.00 1.00 75 +0 5 10 15 20 25 30 35 40 45 50 55 60 65 70 75 80 85 90 95 100 105 110 115 120 +125 130 135 140 145 150 155 160 165 170 175 180 +0 +2400.1 2237.2 1869.5 1201.9 501.0 362.8 273.9 155.5 125.9 108.6 100.0 86.4 +50.6 28.4 18.5 11.1 10.4 4.9 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 +0.0 0.0 0.0 0.0 0.0 0.0 0.0 diff --git a/data/ies_profiles/three_lobe_vee.ies b/data/ies_profiles/three_lobe_vee.ies new file mode 100644 index 0000000..a07a027 --- /dev/null +++ b/data/ies_profiles/three_lobe_vee.ies @@ -0,0 +1,13 @@ +IESNA:LM-63-1995 +[TEST] 100069_0 BY: ERCO / LUM650 +[DATE]02.12.2004 +[MANUFAC] ERCO Leuchten GmbH +[LUMCAT] 22619000_83671000 +[LUMINAIRE] Lightcast Downlight +[LAMPCAT] HIPAR-L30 70W 10 +TILT=NONE +1 4850 1 19 1 1 2 -.097 0 0 +1.00 1.00 70 +0 5 10 15 20 25 30 35 40 45 50 55 60 65 70 75 80 85 90 +0 +68000 34008 6853 3982 936 582 543 514 349 189 92 58 44 34 0 0 0 0 0 diff --git a/data/ies_profiles/tight_focused.ies b/data/ies_profiles/tight_focused.ies new file mode 100644 index 0000000..d89c1f3 --- /dev/null +++ b/data/ies_profiles/tight_focused.ies @@ -0,0 +1,32 @@ +IESNA:LM-63-1995 +[TEST]BALLABS TEST NO. 13700.0 +[MANUFAC] INFINITY LIGHTING INC - CARTHAGE, MISSOURI +[LUMINAIRE] 1/175W CLEAR ED17 MH LAMP 16x16"DIRECT WALL MNT LUMINAIRE +[MORE] SEMI-SPECULAR REFLECTOR SYSTEMS w/BLACK BLADE BAFFLES +[MORE] .1875"THICK CLEAR TEMPERED GLASS LENS +[LUMCAT] WPSQ-MH-175-MED-120 +[LAMPCAT] M57 (M175/U/MED) +TILT=NONE + 1 12800. 1.000000 19 9 1 1 .943 .917 .000 + 1.0000 1.0000 175.0000 + .0 5.0 10.0 15.0 20.0 25.0 30.0 35.0 40.0 45.0 + 50.0 55.0 60.0 65.0 70.0 75.0 80.0 85.0 90.0 + .0 22.5 45.0 67.5 90.0 112.5 135.0 157.5 180.0 + 25790. 25293. 19946. 12741. 6548. 3620. 2037. 1395. 1016. 765. + 587. 461. 338. 221. 19. 4. 0. 0. 0. + 25790. 24593. 19253. 12080. 6261. 3230. 1942. 1387. 1049. 590. + 231. 107. 49. 29. 9. 0. 0. 0. 0. + 25790. 24242. 18086. 10203. 4745. 2374. 1247. 460. 193. 91. + 54. 35. 10. 3. 2. 0. 0. 0. 0. + 25790. 23677. 17161. 9024. 3716. 1603. 608. 256. 142. 94. + 38. 10. 4. 6. 1. 0. 0. 0. 0. + 25790. 23467. 16339. 7925. 3242. 1304. 490. 249. 131. 90. + 29. 7. 4. 2. 1. 0. 0. 0. 0. + 25790. 22684. 15653. 7409. 3273. 1538. 520. 213. 113. 83. + 31. 7. 3. 4. 0. 0. 0. 0. 0. + 25790. 22633. 16005. 7769. 3449. 2045. 1312. 474. 147. 72. + 54. 45. 8. 2. 2. 0. 0. 0. 0. + 25790. 22392. 15298. 8244. 3996. 2118. 1372. 1090. 986. 833. + 486. 178. 62. 60. 7. 0. 0. 0. 0. + 25790. 23109. 15969. 8525. 3888. 2119. 1337. 1025. 835. 699. + 578. 473. 373. 251. 23. 7. 0. 0. 0. diff --git a/data/ies_profiles/top_post.ies b/data/ies_profiles/top_post.ies new file mode 100644 index 0000000..bfd1343 --- /dev/null +++ b/data/ies_profiles/top_post.ies @@ -0,0 +1,16 @@ +IESNA:LM-63-2002 +[TEST]BALLABS TEST NO. 14501.0 +[TESTLAB] BUILDING ACOUSTICS & LIGHTING LABORATORIES, INC +[ISSUEDATE] 04-MAR-2009 +[MANUFAC] H.E. WILLIAMS, INC - CARTHAGE, MISSOURI +[LUMINAIRE] 1/100W CLEAR ED17PS MH HORIZ LAMP LS SERIES POST LUMINAIRE +[MORE] WHITE TOP REFLECTOR w/FROSTED GLASS CHIMNEY +[MORE] CLEAR ACRYLIC PANELS +[LUMCAT] HLSC15-100PSMH120-BLK +[LAMPCAT] M90 +TILT=NONE +1 9000 1 35 1 1 1 0.885 0.885 0.781 +1 1 100 +0 5 10 15 20 25 30 35 40 45 50 55 60 62.5 65 67.5 70 72.5 75 77.5 80 82.5 85 87.5 90 95 105 115 125 135 145 155 165 175 180 +0 +67.00 113.00 238.00 460.00 973.00 1277.00 1388.00 1425.00 1408.00 1338.00 1199.00 1018.00 700.00 430.00 320.00 335.00 227.00 209.00 154.00 137.00 125.00 109.00 91.00 65.00 46.00 38.00 25.00 18.00 10.00 5.00 3.00 3.00 0.00 0.00 0.00 diff --git a/data/ies_profiles/trapezoid.ies b/data/ies_profiles/trapezoid.ies new file mode 100644 index 0000000..48cfa70 --- /dev/null +++ b/data/ies_profiles/trapezoid.ies @@ -0,0 +1,36 @@ +IESNA:LM-63-2002 +[TEST]BALLABS TEST NO. 14477.0 +[TESTLAB] BUILDING ACOUSTICS & LIGHTING LABORATORIES, INC +[ISSUEDATE] 11-FEB-2009 +[MANUFAC] H.E. WILLIAMS, INC - CARTHAGE, MISSOURI +[LUMINAIRE] 1/400W CLEAR ED37 PS MH 18x17x9"WALL PACK AREA LUMINAIRE +[MORE] HAMMERTONE REFLECTOR w/FLAT CLEAR GLASS LENS +[MORE] +[LUMCAT] WPTZ3-PSMH-400-MED-FD-120 +[LAMPCAT] M155/E MH400W/H75/P +TILT=NONE +1 40000 1 25 21 1 1 1.25 0.687 0 +1 1 400 +0 5 10 15 20 25 30 35 40 45 50 55 60 62.5 65 67.5 70 72.5 75 77.5 80 82.5 85 87.5 90 +0 5 15 25 35 45 55 65 75 85 90 95 105 115 125 135 145 155 165 175 180 +9079.00 7777.00 6697.00 6001.00 5457.00 5017.00 5081.00 5849.00 6929.00 7921.00 7361.00 6753.00 4769.00 2896.00 2672.00 2472.00 2192.00 1720.00 1336.00 960.00 568.00 152.00 0.00 0.00 0.00 +9079.00 7769.00 6681.00 6025.00 5425.00 5001.00 5057.00 5785.00 7089.00 8033.00 7569.00 6929.00 5697.00 3056.00 2712.00 2528.00 2224.00 1728.00 1400.00 1000.00 592.00 184.00 0.00 0.00 0.00 +9079.00 7833.00 6849.00 6121.00 5481.00 4977.00 4889.00 5633.00 6945.00 8305.00 7953.00 7009.00 6313.00 3784.00 2840.00 2576.00 2328.00 1888.00 1504.00 1056.00 648.00 224.00 0.00 0.00 0.00 +9079.00 7985.00 7001.00 6209.00 5465.00 4945.00 4680.00 5177.00 6281.00 7705.00 8033.00 6609.00 5681.00 4624.00 2296.00 1904.00 1616.00 1248.00 888.00 544.00 336.00 80.00 0.00 0.00 0.00 +9079.00 8129.00 7257.00 6329.00 5489.00 4793.00 4368.00 4456.00 4985.00 5345.00 4905.00 3936.00 3416.00 3248.00 2616.00 696.00 536.00 400.00 264.00 152.00 64.00 8.00 0.00 0.00 0.00 +9079.00 8281.00 7465.00 6505.00 5505.00 4737.00 4168.00 3896.00 3832.00 3744.00 3384.00 3136.00 2880.00 2176.00 1272.00 680.00 616.00 544.00 408.00 232.00 104.00 24.00 0.00 0.00 0.00 +9079.00 8529.00 7793.00 6825.00 5745.00 4753.00 4016.00 3528.00 3224.00 3048.00 3088.00 3184.00 2536.00 1624.00 1064.00 832.00 712.00 616.00 528.00 320.00 144.00 32.00 0.00 0.00 0.00 +9079.00 8689.00 8121.00 7353.00 6057.00 4969.00 4000.00 3456.00 3080.00 2864.00 2800.00 2800.00 2008.00 1512.00 1392.00 1200.00 928.00 616.00 440.00 272.00 136.00 40.00 0.00 0.00 0.00 +9079.00 8961.00 8577.00 7841.00 6721.00 5553.00 4352.00 3560.00 3096.00 2872.00 2688.00 2464.00 1360.00 1128.00 1120.00 1072.00 976.00 824.00 640.00 392.00 200.00 64.00 0.00 0.00 0.00 +9079.00 9089.00 8817.00 8161.00 7185.00 5953.00 4576.00 3664.00 3208.00 2992.00 2792.00 2472.00 1352.00 1048.00 1024.00 944.00 856.00 720.00 608.00 424.00 200.00 56.00 0.00 0.00 0.00 +9079.00 9297.00 9121.00 8609.00 7737.00 6641.00 5129.00 3840.00 3344.00 3168.00 2976.00 2544.00 1368.00 1032.00 936.00 808.00 712.00 608.00 472.00 328.00 176.00 48.00 0.00 0.00 0.00 +9079.00 9466.00 9401.00 8977.00 8161.00 7297.00 5513.00 3968.00 3448.00 3240.00 2848.00 2080.00 1224.00 1016.00 872.00 736.00 600.00 448.00 336.00 208.00 104.00 32.00 0.00 0.00 0.00 +9079.00 9666.00 9706.00 9313.00 8473.00 7369.00 5313.00 2864.00 1744.00 1352.00 1344.00 1264.00 1016.00 856.00 752.00 584.00 472.00 320.00 224.00 128.00 64.00 16.00 0.00 0.00 0.00 +9079.00 9874.00 10034.00 9642.00 8233.00 5769.00 3600.00 2352.00 1592.00 1256.00 1208.00 1240.00 904.00 696.00 536.00 384.00 272.00 168.00 104.00 56.00 24.00 0.00 0.00 0.00 0.00 +9079.00 10002.00 10210.00 9225.00 6513.00 4504.00 3880.00 3464.00 2496.00 1456.00 984.00 792.00 504.00 360.00 272.00 200.00 160.00 104.00 80.00 32.00 16.00 0.00 0.00 0.00 0.00 +9079.00 10162.00 10338.00 8361.00 5553.00 4721.00 4440.00 4256.00 3624.00 2056.00 768.00 456.00 280.00 200.00 160.00 120.00 96.00 56.00 40.00 16.00 8.00 0.00 0.00 0.00 0.00 +9079.00 10242.00 10226.00 7433.00 5529.00 5033.00 4897.00 4560.00 3376.00 1536.00 568.00 312.00 200.00 152.00 120.00 88.00 80.00 40.00 32.00 16.00 8.00 0.00 0.00 0.00 0.00 +9079.00 10330.00 9938.00 6873.00 5721.00 5409.00 5177.00 4352.00 2552.00 1032.00 544.00 360.00 248.00 176.00 136.00 96.00 72.00 40.00 32.00 24.00 8.00 0.00 0.00 0.00 0.00 +9079.00 10234.00 9794.00 6873.00 5913.00 5641.00 5273.00 4016.00 2120.00 1120.00 736.00 552.00 384.00 280.00 184.00 112.00 80.00 48.00 40.00 24.00 8.00 0.00 0.00 0.00 0.00 +9079.00 10242.00 9794.00 6825.00 5985.00 5777.00 5313.00 4000.00 2104.00 1160.00 840.00 640.00 456.00 320.00 232.00 152.00 104.00 56.00 48.00 24.00 16.00 0.00 0.00 0.00 0.00 +9079.00 10298.00 9666.00 6905.00 6097.00 5849.00 5401.00 4152.00 2128.00 1248.00 904.00 720.00 488.00 352.00 248.00 168.00 120.00 64.00 48.00 32.00 24.00 8.00 0.00 0.00 0.00 diff --git a/data/ies_profiles/umbrella.ies b/data/ies_profiles/umbrella.ies new file mode 100644 index 0000000..f3fa89c --- /dev/null +++ b/data/ies_profiles/umbrella.ies @@ -0,0 +1,24 @@ +IESNA:LM-63-1995 +[TEST]BALLABS TEST NO. 12447.0 +[MANUFAC] INFINITY LIGHTING INC - CARTHAGE, MISSOURI +[LUMINAIRE] 1/100W ICETRON INDUCTION LAMP 20x15"AREALIGHT LUMINAIRE +[LUMINAIRE] MIRO4 HIGHLY SPEC FLOOD OPTICS w/CLEAR GLASS LENS +[LUMINAIRE] SYLVANIA BALLAST #QT1x150 ICE/UNV-T WATTS=145 +[LUMCAT] ICE DC-150W/41K-FL/CGI-MTV @277VOLTS +[LAMPCAT] ICETRON100/QT150 +TILT=NONE + 1 11000. 1.000000 19 5 1 1 .938 1.266 .000 + 1.0000 1.0000 145.0000 + .0 5.0 10.0 15.0 20.0 25.0 30.0 35.0 40.0 45.0 + 50.0 55.0 60.0 65.0 70.0 75.0 80.0 85.0 90.0 + .0 22.5 45.0 67.5 90.0 + 5122. 5161. 5246. 5337. 5360. 5211. 4910. 4510. 3890. 3056. + 1952. 1153. 451. 139. 30. 15. 3. 0. 0. + 5122. 5138. 5234. 5291. 5289. 5129. 4754. 4318. 3676. 2838. + 2069. 1240. 482. 172. 37. 11. 6. 1. 0. + 5122. 5134. 5160. 5118. 4967. 4781. 4477. 3831. 2940. 1851. + 1139. 685. 306. 85. 25. 13. 7. 1. 0. + 5122. 5119. 5076. 4880. 4697. 4385. 3786. 2876. 1738. 1121. + 711. 388. 120. 30. 11. 6. 4. 1. 0. + 5122. 5113. 5032. 4843. 4615. 4130. 3464. 2374. 1519. 1017. + 589. 293. 73. 27. 11. 6. 3. 1. 0. diff --git a/data/ies_profiles/vee.ies b/data/ies_profiles/vee.ies new file mode 100644 index 0000000..6786cab --- /dev/null +++ b/data/ies_profiles/vee.ies @@ -0,0 +1,15 @@ +ERCO Leuchten GmbH BY: ERCO/LUM650/8701 +73608023+Q100T3/12V/CL 70.IES +- +- +- +- +- +- +TILT=NONE +1 2350 2.35 19 1 1 2 -.09 0 0 +1.00 1.00 100 +0 5 10 15 20 25 30 35 40 45 50 55 60 65 70 75 80 85 90 +0 +270.9 258 264.8 271.4 288.6 330.7 402.9 109.6 6.511 5.297 3.399 1.846 1.063 +.5676 .4306 .03262 0 0 0 diff --git a/data/ies_profiles/x_arrow.ies b/data/ies_profiles/x_arrow.ies new file mode 100644 index 0000000..81a5e6e --- /dev/null +++ b/data/ies_profiles/x_arrow.ies @@ -0,0 +1,13 @@ +IESNA:LM-63-1995 +[TEST] BE1680 +[DATE] 12-FEB-96 +[MANUFAC] BEGA +[LUMCAT] 6340 +[LUMINAIRE] SURFACE MOUNTED WALL LUMINAIRE +[LAMP] (1) 100W A-19 INC +TILT=NONE + 1 1750 1.75 73 1 1 2 -.1 0 .05 + 1 1 100 + 0 2.5 5 7.5 10 12.5 15 17.5 20 22.5 25 27.5 30 32.5 35 37.5 40 42.5 45 47.5 50 52.5 55 57.5 60 62.5 65 67.5 70 72.5 75 77.5 80 82.5 85 87.5 90 92.5 95 97.5 100 102.5 105 107.5 110 112.5 115 117.5 120 122.5 125 127.5 130 132.5 135 137.5 140 142.5 145 147.5 150 152.5 155 157.5 160 162.5 165 167.5 170 172.5 175 177.5 180 + 0 + 167.3 168.9 173 179.9 179.2 151.2 119.4 95.63 81.03 71.95 66.46 62.67 60.25 57.67 52.18 46.62 48.91 63.15 83.15 95.41 97.4 87.75 62.6 43.08 39.26 47.36 52.89 45.74 31.45 18.17 10.5 7.888 8.112 7.592 3.665 .6467 .498 .4252 .3735 .3185 .2765 .2279 .2199 .2021 .1746 .1407 .1358 .1277 .1326 .1342 .1406 .1374 .1358 .1375 .1488 .1488 .1536 .1925 .2183 .2328 .2345 .249 .2765 .3023 .3266 .3476 .3557 .3638 .3541 .3573 .3638 .3719 .3816 diff --git a/data/ies_profiles/x_arrow_diffuse.ies b/data/ies_profiles/x_arrow_diffuse.ies new file mode 100644 index 0000000..77a91bb --- /dev/null +++ b/data/ies_profiles/x_arrow_diffuse.ies @@ -0,0 +1,13 @@ +IESNA:LM-63-1995 +[TEST] BE1396 +[DATE] 22-SEPT-96 +[MANUFAC] BEGA +[LUMCAT] 6690 +[LUMINAIRE] SURFACE MOUNTED WALL LUMINAIRE +[LAMP] (1) 100W A-19 INC +TILT=NONE + 1 1750 1.75 37 1 1 2 -.12 0 0 + 1 1 100 + 0 2.5 5 7.5 10 12.5 15 17.5 20 22.5 25 27.5 30 32.5 35 37.5 40 42.5 45 47.5 50 52.5 55 57.5 60 62.5 65 67.5 70 72.5 75 77.5 80 82.5 85 87.5 90 + 0 + 283.4 280.7 270 250.8 228 207.8 185.8 160.1 140.4 133 131.4 131.4 130.9 127.9 120.7 109.3 99.46 95.13 98.4 106.8 116 122.2 124.1 119.1 97.99 57.94 26.92 11.71 4.582 1.544 .9573 .6497 .4341 .2616 .1724 .04603 .005727 diff --git a/data/ies_profiles/x_arrow_soft.ies b/data/ies_profiles/x_arrow_soft.ies new file mode 100644 index 0000000..c3905c0 --- /dev/null +++ b/data/ies_profiles/x_arrow_soft.ies @@ -0,0 +1,13 @@ +IESNA:LM-63-1995 +[TEST] BE1667 +[DATE] 12-FEB-96 +[MANUFAC] BEGA +[LUMCAT] 6339 +[LUMINAIRE] SURFACE MOUNTED WALL LUMINAIRE +[LAMP] (1) 60W A-19 INC +TILT=NONE + 1 890 .89 73 1 1 2 -.1 0 0 + 1 1 60 + 0 2.5 5 7.5 10 12.5 15 17.5 20 22.5 25 27.5 30 32.5 35 37.5 40 42.5 45 47.5 50 52.5 55 57.5 60 62.5 65 67.5 70 72.5 75 77.5 80 82.5 85 87.5 90 92.5 95 97.5 100 102.5 105 107.5 110 112.5 115 117.5 120 122.5 125 127.5 130 132.5 135 137.5 140 142.5 145 147.5 150 152.5 155 157.5 160 162.5 165 167.5 170 172.5 175 177.5 180 + 0 + 178.4 176.7 170.8 160.9 147 133 114.6 96.13 80.57 67.13 56.54 47.61 40.87 36.97 36.86 39.76 45.47 54.35 66.39 75.84 79.96 73.53 62.87 52.35 44.33 39.14 36.31 33.87 29.1 22.59 15.67 9.13 5.317 2.654 1.382 .3416 .2 .09695 .2025 .175 .1518 .1455 .1328 .1307 .1139 .1097 .097 .1075 .1076 .07175 .1243 .1073 .1328 .1349 .1391 .1307 .1412 .1475 .156 .1813 .1876 .2087 .2466 .2466 .2782 .2993 .3035 .3035 .3035 .2993 .2993 .3035 .3035 diff --git a/data/panda3d_patches/README.md b/data/panda3d_patches/README.md new file mode 100644 index 0000000..db5a669 --- /dev/null +++ b/data/panda3d_patches/README.md @@ -0,0 +1,16 @@ + +## Patches for Panda3D + +This folder contains patches for the Panda3D Engine which have not yet made +it to the Panda3D-Repository, but are used by some render pipeline features. + +**IMPORTANT**: After you applied a patch, delete it, so the render pipeline +knows the patch is available. + +## List of patches + +#### prev-model-view-matrix.diff + +This patch adds the p3d_PrevModelViewMatrix to add support for per object +velocities. When this patch is enabled, moving objects recieve motion blur (per +object motion blur). Also don't forget to apply the second part of the patch, too. diff --git a/data/panda3d_patches/prev-model-view-matrix-part2.diff b/data/panda3d_patches/prev-model-view-matrix-part2.diff new file mode 100644 index 0000000..3472914 --- /dev/null +++ b/data/panda3d_patches/prev-model-view-matrix-part2.diff @@ -0,0 +1,609 @@ +From 098218a265d582bec22c0398ca9901fa770235ae Mon Sep 17 00:00:00 2001 +From: tobspr +Date: Thu, 3 Mar 2016 10:10:24 +0100 +Subject: [PATCH] Add PrevModelMatrix - Part2 + +--- + panda/src/collide/collisionVisualizer.cxx | 4 ++-- + panda/src/display/callbackGraphicsWindow.cxx | 2 +- + panda/src/display/graphicsEngine.cxx | 4 ---- + panda/src/display/graphicsStateGuardian.I | 4 ++-- + panda/src/display/graphicsStateGuardian.cxx | 12 ++++++------ + panda/src/display/graphicsStateGuardian.h | 8 ++++---- + panda/src/dxgsg9/dxGraphicsStateGuardian9.cxx | 4 ++-- + panda/src/glstuff/glGraphicsStateGuardian_src.cxx | 6 +++--- + panda/src/glstuff/glShaderContext_src.cxx | 6 +++--- + panda/src/gobj/shader.cxx | 4 ++-- + panda/src/gobj/shader.h | 4 ++-- + panda/src/parametrics/ropeNode.cxx | 8 ++++---- + panda/src/parametrics/sheetNode.cxx | 2 +- + panda/src/pgraph/cullTraverserData.I | 8 -------- + panda/src/pgraph/cullTraverserData.cxx | 4 ---- + panda/src/pgraph/cullTraverserData.h | 1 - + panda/src/pgraph/cullableObject.I | 14 +++++++------- + panda/src/pgraph/cullableObject.h | 4 ++-- + panda/src/pgraph/geomNode.cxx | 2 +- + panda/src/pgraph/occluderNode.cxx | 4 ++-- + panda/src/pgraph/planeNode.cxx | 2 +- + panda/src/pgraph/sceneSetup.I | 18 ------------------ + panda/src/pgraph/sceneSetup.h | 3 --- + panda/src/pgraphnodes/callbackNode.cxx | 2 +- + panda/src/pgraphnodes/computeNode.cxx | 2 +- + panda/src/pgraphnodes/nodeCullCallbackData.cxx | 2 +- + panda/src/tinydisplay/tinyGraphicsStateGuardian.cxx | 4 ++-- + 27 files changed, 50 insertions(+), 88 deletions(-) + +diff --git a/panda/src/collide/collisionVisualizer.cxx b/panda/src/collide/collisionVisualizer.cxx +index cceb6c5..da34f7f 100644 +--- a/panda/src/collide/collisionVisualizer.cxx ++++ b/panda/src/collide/collisionVisualizer.cxx +@@ -189,7 +189,7 @@ cull_callback(CullTraverser *trav, CullTraverserData &data) { + CullableObject *object = + new CullableObject(geom, point_state, + xform_data.get_internal_transform(trav), +- xform_data.get_prev_internal_transform(trav)); ++ xform_data.get_prev_net_transform(trav)); + + trav->get_cull_handler()->record_object(object, trav); + } +@@ -219,7 +219,7 @@ cull_callback(CullTraverser *trav, CullTraverserData &data) { + CullableObject *object = + new CullableObject(geom, empty_state, + xform_data.get_internal_transform(trav), +- xform_data.get_prev_internal_transform(trav)); ++ xform_data.get_prev_net_transform(trav)); + + trav->get_cull_handler()->record_object(object, trav); + } +diff --git a/panda/src/display/callbackGraphicsWindow.cxx b/panda/src/display/callbackGraphicsWindow.cxx +index ebd5b37..69dd9fb 100644 +--- a/panda/src/display/callbackGraphicsWindow.cxx ++++ b/panda/src/display/callbackGraphicsWindow.cxx +@@ -109,7 +109,7 @@ end_frame(FrameMode mode, Thread *current_thread) { + // In case the callback or the application hosting the OpenGL context + // wants to do more rendering, let's give it a blank slate. + _gsg->set_state_and_transform(RenderState::make_empty(), _gsg->get_internal_transform(), +- _gsg->get_prev_internal_transform()); ++ _gsg->get_prev_net_transform()); + _gsg->clear_before_callback(); + + RenderCallbackData data(this, RCT_end_frame, mode); +diff --git a/panda/src/display/graphicsEngine.cxx b/panda/src/display/graphicsEngine.cxx +index 5578121..42ae88c 100644 +--- a/panda/src/display/graphicsEngine.cxx ++++ b/panda/src/display/graphicsEngine.cxx +@@ -1806,7 +1806,6 @@ do_setup_scene(GraphicsStateGuardian *gsg, DisplayRegionPipelineReader *dr) { + NodePath scene_parent = scene_root.get_parent(current_thread); + CPT(TransformState) camera_transform = camera.get_transform(scene_parent, current_thread); + CPT(TransformState) world_transform = scene_parent.get_transform(camera, current_thread); +- CPT(TransformState) prev_world_transform = scene_parent.get_prev_transform(camera, current_thread); + + if (camera_transform->is_invalid()) { + // There must be a singular transform over the scene. +@@ -1859,9 +1858,6 @@ do_setup_scene(GraphicsStateGuardian *gsg, DisplayRegionPipelineReader *dr) { + CPT(TransformState) cs_world_transform = cs_transform->compose(world_transform); + scene_setup->set_cs_world_transform(cs_world_transform); + +- CPT(TransformState) prev_cs_world_transform = cs_transform->compose(prev_world_transform); +- scene_setup->set_prev_cs_world_transform(prev_cs_world_transform); +- + // Make sure that the GSG has a ShaderGenerator for the munger to use. We + // have to do this here because the ShaderGenerator needs a host window + // pointer. Hopefully we'll be able to eliminate that requirement in the +diff --git a/panda/src/display/graphicsStateGuardian.I b/panda/src/display/graphicsStateGuardian.I +index d330100..9fa45c6 100644 +--- a/panda/src/display/graphicsStateGuardian.I ++++ b/panda/src/display/graphicsStateGuardian.I +@@ -852,8 +852,8 @@ get_internal_transform() const { + * function is typically only meaningful during the geometry rendering process. + */ + INLINE CPT(TransformState) GraphicsStateGuardian:: +-get_prev_internal_transform() const { +- return _prev_internal_transform; ++get_prev_net_transform() const { ++ return _prev_net_transform; + } + + /** +diff --git a/panda/src/display/graphicsStateGuardian.cxx b/panda/src/display/graphicsStateGuardian.cxx +index 8d3fbae..8663288 100644 +--- a/panda/src/display/graphicsStateGuardian.cxx ++++ b/panda/src/display/graphicsStateGuardian.cxx +@@ -146,7 +146,7 @@ GraphicsStateGuardian(CoordinateSystem internal_coordinate_system, + { + _coordinate_system = CS_invalid; + _internal_transform = TransformState::make_identity(); +- _prev_internal_transform = _prev_internal_transform; ++ _prev_net_transform = _prev_net_transform; + + set_coordinate_system(get_default_coordinate_system()); + +@@ -1208,9 +1208,6 @@ fetch_specified_part(Shader::ShaderMatInput part, InternalName *name, + case Shader::SMO_model_to_apiview: { + return &(get_internal_transform()->get_mat()); + } +- case Shader::SMO_prev_model_to_apiview: { +- return &(get_prev_internal_transform()->get_mat()); +- } + case Shader::SMO_view_to_model: { + t = get_external_transform()->get_inverse()->get_mat(); + return &t; +@@ -1219,8 +1216,11 @@ fetch_specified_part(Shader::ShaderMatInput part, InternalName *name, + t = get_internal_transform()->get_inverse()->get_mat(); + return &t; + } +- case Shader::SMO_prev_apiview_to_model: { +- t = get_prev_internal_transform()->get_inverse()->get_mat(); ++ case Shader::SMO_prev_net_transform: { ++ return &(get_prev_net_transform()->get_mat()); ++ } ++ case Shader::SMO_prev_inv_net_transform: { ++ t = get_prev_net_transform()->get_inverse()->get_mat(); + return &t; + } + case Shader::SMO_apiview_to_view: { +diff --git a/panda/src/display/graphicsStateGuardian.h b/panda/src/display/graphicsStateGuardian.h +index a1cc245..7233075 100644 +--- a/panda/src/display/graphicsStateGuardian.h ++++ b/panda/src/display/graphicsStateGuardian.h +@@ -389,7 +389,7 @@ public: + + INLINE CPT(TransformState) get_external_transform() const; + INLINE CPT(TransformState) get_internal_transform() const; +- INLINE CPT(TransformState) get_prev_internal_transform() const; ++ INLINE CPT(TransformState) get_prev_net_transform() const; + + RenderBuffer get_render_buffer(int buffer_type, const FrameBufferProperties &prop); + +@@ -479,9 +479,9 @@ protected: + // The current transform, as of the last call to set_state_and_transform(). + CPT(TransformState) _internal_transform; + +- // The previous transform, as of the last call to the 3 parameter overload of +- // set_state_and_transform() +- CPT(TransformState) _prev_internal_transform; ++ // The previous net transform, as of the last call to the 3 parameter overload ++ // of set_state_and_transform() ++ CPT(TransformState) _prev_net_transform; + + // The current TextureAttrib is a special case; we may further restrict it + // (according to graphics cards limits) or extend it (according to +diff --git a/panda/src/dxgsg9/dxGraphicsStateGuardian9.cxx b/panda/src/dxgsg9/dxGraphicsStateGuardian9.cxx +index 66d007d..7609cae 100644 +--- a/panda/src/dxgsg9/dxGraphicsStateGuardian9.cxx ++++ b/panda/src/dxgsg9/dxGraphicsStateGuardian9.cxx +@@ -758,7 +758,7 @@ clear(DrawableRegion *clearable) { + return; + } + +- set_state_and_transform(RenderState::make_empty(), _internal_transform, _prev_internal_transform); ++ set_state_and_transform(RenderState::make_empty(), _internal_transform, _prev_net_transform); + + D3DCOLOR color_clear_value = LColor_to_D3DCOLOR(clearable->get_clear_color()); + PN_stdfloat depth_clear_value = clearable->get_clear_depth(); +@@ -3037,7 +3037,7 @@ set_state_and_transform(const RenderState *target, + #endif + _state_pcollector.add_level(1); + PStatTimer timer1(_draw_set_state_pcollector); +- _prev_internal_transform = prev_transform; ++ _prev_net_transform = prev_transform; + + if (transform != _internal_transform) { + // PStatTimer timer(_draw_set_state_transform_pcollector); +diff --git a/panda/src/glstuff/glGraphicsStateGuardian_src.cxx b/panda/src/glstuff/glGraphicsStateGuardian_src.cxx +index 3dca96f..b7ca084 100644 +--- a/panda/src/glstuff/glGraphicsStateGuardian_src.cxx ++++ b/panda/src/glstuff/glGraphicsStateGuardian_src.cxx +@@ -2875,7 +2875,7 @@ clear(DrawableRegion *clearable) { + // XXX rdb: Is this line really necessary? Could we perhaps just reset the + // color write mask and other relevant attributes? + set_state_and_transform(RenderState::make_empty(), _internal_transform, +- _prev_internal_transform); ++ _prev_net_transform); + + int mask = 0; + +@@ -5897,7 +5897,7 @@ framebuffer_copy_to_ram(Texture *tex, int view, int z, + // glReadPixels() to work NOTE: reading the depth buffer is *much* slower + // than reading the color buffer + set_state_and_transform(RenderState::make_empty(), _internal_transform, +- _prev_internal_transform); ++ _prev_net_transform); + + int xo, yo, w, h; + dr->get_region_pixels(xo, yo, w, h); +@@ -9522,7 +9522,7 @@ set_state_and_transform(const RenderState *target, + _state_pcollector.add_level(1); + PStatGPUTimer timer1(this, _draw_set_state_pcollector); + +- _prev_internal_transform = prev_transform; ++ _prev_net_transform = prev_transform; + + if (transform != _internal_transform) { + // PStatGPUTimer timer(this, _draw_set_state_transform_pcollector); +diff --git a/panda/src/glstuff/glShaderContext_src.cxx b/panda/src/glstuff/glShaderContext_src.cxx +index a7759af..a7466bb 100644 +--- a/panda/src/glstuff/glShaderContext_src.cxx ++++ b/panda/src/glstuff/glShaderContext_src.cxx +@@ -769,10 +769,10 @@ reflect_uniform(int i, char *name_buffer, GLsizei name_buflen) { + : Shader::SMO_model_to_apiview; + bind._part[1] = Shader::SMO_identity; + +- } else if (matrix_name == "PrevModelViewMatrix") { ++ } else if (matrix_name == "PrevModelMatrix") { + bind._func = Shader::SMF_first; +- bind._part[0] = inverse ? Shader::SMO_prev_apiview_to_model +- : Shader::SMO_prev_model_to_apiview; ++ bind._part[0] = inverse ? Shader::SMO_prev_inv_net_transform ++ : Shader::SMO_prev_net_transform; + bind._part[1] = Shader::SMO_identity; + + } else if (matrix_name == "ProjectionMatrix") { +diff --git a/panda/src/gobj/shader.cxx b/panda/src/gobj/shader.cxx +index 552f665..95bc136a 100644 +--- a/panda/src/gobj/shader.cxx ++++ b/panda/src/gobj/shader.cxx +@@ -390,8 +390,8 @@ cp_dependency(ShaderMatInput inp) { + (inp == SMO_view_to_model) || + (inp == SMO_model_to_apiview) || + (inp == SMO_apiview_to_model) || +- (inp == SMO_prev_model_to_apiview) || +- (inp == SMO_prev_apiview_to_model) || ++ (inp == SMO_prev_net_transform) || ++ (inp == SMO_prev_inv_net_transform) || + (inp == SMO_view_to_world) || + (inp == SMO_world_to_view) || + (inp == SMO_view_x_to_view) || +diff --git a/panda/src/gobj/shader.h b/panda/src/gobj/shader.h +index f517565..e5d244d 100644 +--- a/panda/src/gobj/shader.h ++++ b/panda/src/gobj/shader.h +@@ -202,8 +202,8 @@ public: + SMO_tex_is_alpha_i, + + // Previous frame transform +- SMO_prev_apiview_to_model, +- SMO_prev_model_to_apiview, ++ SMO_prev_net_transform, ++ SMO_prev_inv_net_transform, + + SMO_INVALID + }; +diff --git a/panda/src/parametrics/ropeNode.cxx b/panda/src/parametrics/ropeNode.cxx +index 6705f66..28160b9 100644 +--- a/panda/src/parametrics/ropeNode.cxx ++++ b/panda/src/parametrics/ropeNode.cxx +@@ -335,7 +335,7 @@ render_thread(CullTraverser *trav, CullTraverserData &data, + CullableObject *object = + new CullableObject(geom, state, + data.get_internal_transform(trav), +- data.get_prev_internal_transform(trav)); ++ data.get_prev_net_transform(trav)); + trav->get_cull_handler()->record_object(object, trav); + } + +@@ -382,7 +382,7 @@ render_tape(CullTraverser *trav, CullTraverserData &data, + CullableObject *object = + new CullableObject(geom, state, + data.get_internal_transform(trav), +- data.get_prev_internal_transform(trav)); ++ data.get_prev_net_transform(trav)); + trav->get_cull_handler()->record_object(object, trav); + } + +@@ -436,7 +436,7 @@ render_billboard(CullTraverser *trav, CullTraverserData &data, + CullableObject *object = + new CullableObject(geom, state, + data.get_internal_transform(trav), +- data.get_prev_internal_transform(trav)); ++ data.get_prev_net_transform(trav)); + trav->get_cull_handler()->record_object(object, trav); + } + +@@ -498,7 +498,7 @@ render_tube(CullTraverser *trav, CullTraverserData &data, + CullableObject *object = + new CullableObject(geom, state, + data.get_internal_transform(trav), +- data.get_prev_internal_transform(trav)); ++ data.get_prev_net_transform(trav)); + trav->get_cull_handler()->record_object(object, trav); + } + +diff --git a/panda/src/parametrics/sheetNode.cxx b/panda/src/parametrics/sheetNode.cxx +index f745d6e..b950105 100644 +--- a/panda/src/parametrics/sheetNode.cxx ++++ b/panda/src/parametrics/sheetNode.cxx +@@ -332,7 +332,7 @@ render_sheet(CullTraverser *trav, CullTraverserData &data, + CullableObject *object = + new CullableObject(geom, state, + data.get_internal_transform(trav), +- data.get_prev_internal_transform(trav)); ++ data.get_prev_net_transform(trav)); + trav->get_cull_handler()->record_object(object, trav); + } + +diff --git a/panda/src/pgraph/cullTraverserData.I b/panda/src/pgraph/cullTraverserData.I +index 7c1a79f..3ec4380 100644 +--- a/panda/src/pgraph/cullTraverserData.I ++++ b/panda/src/pgraph/cullTraverserData.I +@@ -139,14 +139,6 @@ INLINE CPT(TransformState) CullTraverserData:: + get_internal_transform(const CullTraverser *trav) const { + return trav->get_scene()->get_cs_world_transform()->compose(_net_transform); + } +-/** +- * Returns the previous internal transform: the modelview transform in the GSG's +- * internal coordinate system in the last frame. +- */ +-INLINE CPT(TransformState) CullTraverserData:: +-get_prev_internal_transform(const CullTraverser *trav) const { +- return trav->get_scene()->get_prev_cs_world_transform()->compose(_prev_net_transform); +-} + + /** + * Returns the net transform: the relative transform from root of the scene +diff --git a/panda/src/pgraph/cullTraverserData.cxx b/panda/src/pgraph/cullTraverserData.cxx +index e84a3d8..95b9013 100644 +--- a/panda/src/pgraph/cullTraverserData.cxx ++++ b/panda/src/pgraph/cullTraverserData.cxx +@@ -47,12 +47,8 @@ apply_transform_and_state(CullTraverser *trav) { + _node_reader.compose_draw_mask(_draw_mask); + + apply_transform_and_state(trav, _node_reader.get_transform(), +-<<<<<<< HEAD + _node_reader.get_prev_transform(), +- node_state, _node_reader.get_effects(), +-======= + MOVE(node_state), _node_reader.get_effects(), +->>>>>>> 2bf886fc5b086e92ef86b25c652f7257521365d7 + _node_reader.get_off_clip_planes()); + } + +diff --git a/panda/src/pgraph/cullTraverserData.h b/panda/src/pgraph/cullTraverserData.h +index 30b8d68..cb1e147 100644 +--- a/panda/src/pgraph/cullTraverserData.h ++++ b/panda/src/pgraph/cullTraverserData.h +@@ -61,7 +61,6 @@ public: + PUBLISHED: + INLINE CPT(TransformState) get_modelview_transform(const CullTraverser *trav) const; + INLINE CPT(TransformState) get_internal_transform(const CullTraverser *trav) const; +- INLINE CPT(TransformState) get_prev_internal_transform(const CullTraverser *trav) const; + INLINE const TransformState *get_net_transform(const CullTraverser *trav) const; + INLINE const TransformState *get_prev_net_transform(const CullTraverser *trav) const; + +diff --git a/panda/src/pgraph/cullableObject.I b/panda/src/pgraph/cullableObject.I +index 5fbe70c..7481f12 100644 +--- a/panda/src/pgraph/cullableObject.I ++++ b/panda/src/pgraph/cullableObject.I +@@ -28,11 +28,11 @@ CullableObject() { + INLINE CullableObject:: + CullableObject(const Geom *geom, const RenderState *state, + const TransformState *internal_transform, +- const TransformState *prev_internal_transform) : ++ const TransformState *prev_net_transform) : + _geom(geom), + _state(state), + _internal_transform(internal_transform), +- _prev_internal_transform(prev_internal_transform) ++ _prev_net_transform(prev_net_transform) + { + #ifdef DO_MEMORY_USAGE + MemoryUsage::update_type(this, get_class_type()); +@@ -49,7 +49,7 @@ CullableObject(const Geom *geom, const RenderState *state, + _geom(geom), + _state(state), + _internal_transform(internal_transform), +- _prev_internal_transform(internal_transform) ++ _prev_net_transform(internal_transform) + { + #ifdef DO_MEMORY_USAGE + MemoryUsage::update_type(this, get_class_type()); +@@ -66,7 +66,7 @@ CullableObject(const CullableObject ©) : + _munged_data(copy._munged_data), + _state(copy._state), + _internal_transform(copy._internal_transform), +- _prev_internal_transform(copy._prev_internal_transform) ++ _prev_net_transform(copy._prev_net_transform) + { + #ifdef DO_MEMORY_USAGE + MemoryUsage::update_type(this, get_class_type()); +@@ -83,7 +83,7 @@ operator = (const CullableObject ©) { + _munged_data = copy._munged_data; + _state = copy._state; + _internal_transform = copy._internal_transform; +- _prev_internal_transform = copy._prev_internal_transform; ++ _prev_net_transform = copy._prev_net_transform; + _draw_callback = copy._draw_callback; + } + +@@ -96,7 +96,7 @@ draw(GraphicsStateGuardianBase *gsg, bool force, Thread *current_thread) { + if (_draw_callback != (CallbackObject *)NULL) { + // It has a callback associated. + gsg->clear_before_callback(); +- gsg->set_state_and_transform(_state, _internal_transform, _prev_internal_transform); ++ gsg->set_state_and_transform(_state, _internal_transform, _prev_net_transform); + GeomDrawCallbackData cbdata(this, gsg, force); + _draw_callback->do_callback(&cbdata); + if (cbdata.get_lost_state()) { +@@ -106,7 +106,7 @@ draw(GraphicsStateGuardianBase *gsg, bool force, Thread *current_thread) { + // Now the callback has taken care of drawing. + } else { + nassertv(_geom != (Geom *)NULL); +- gsg->set_state_and_transform(_state, _internal_transform, _prev_internal_transform); ++ gsg->set_state_and_transform(_state, _internal_transform, _prev_net_transform); + draw_inline(gsg, force, current_thread); + } + } +diff --git a/panda/src/pgraph/cullableObject.h b/panda/src/pgraph/cullableObject.h +index f450cbc..5887ac9 100644 +--- a/panda/src/pgraph/cullableObject.h ++++ b/panda/src/pgraph/cullableObject.h +@@ -51,7 +51,7 @@ public: + + INLINE CullableObject(const Geom *geom, const RenderState *state, + const TransformState *internal_transform, +- const TransformState *prev_internal_transform); ++ const TransformState *prev_net_transform); + + INLINE CullableObject(const CullableObject ©); + INLINE void operator = (const CullableObject ©); +@@ -78,7 +78,7 @@ public: + CPT(GeomVertexData) _munged_data; + CPT(RenderState) _state; + CPT(TransformState) _internal_transform; +- CPT(TransformState) _prev_internal_transform; ++ CPT(TransformState) _prev_net_transform; + PT(CallbackObject) _draw_callback; + + private: +diff --git a/panda/src/pgraph/geomNode.cxx b/panda/src/pgraph/geomNode.cxx +index 5ea321e..1813431 100644 +--- a/panda/src/pgraph/geomNode.cxx ++++ b/panda/src/pgraph/geomNode.cxx +@@ -559,7 +559,7 @@ add_for_draw(CullTraverser *trav, CullTraverserData &data) { + CullableObject *object = + new CullableObject(geom, state, + data.get_internal_transform(trav), +- data.get_prev_internal_transform(trav)); ++ data.get_prev_net_transform(trav)); + trav->get_cull_handler()->record_object(object, trav); + } + } +diff --git a/panda/src/pgraph/occluderNode.cxx b/panda/src/pgraph/occluderNode.cxx +index 83695fb..f41a220 100644 +--- a/panda/src/pgraph/occluderNode.cxx ++++ b/panda/src/pgraph/occluderNode.cxx +@@ -143,7 +143,7 @@ cull_callback(CullTraverser *trav, CullTraverserData &data) { + CullableObject *occluder_viz = + new CullableObject(get_occluder_viz(trav, data), get_occluder_viz_state(trav, data), + data.get_internal_transform(trav), +- data.get_prev_internal_transform(trav)); ++ data.get_prev_net_transform(trav)); + trav->get_cull_handler()->record_object(occluder_viz, trav); + + // Also get the frame. +@@ -151,7 +151,7 @@ cull_callback(CullTraverser *trav, CullTraverserData &data) { + CullableObject *frame_viz = + new CullableObject(_frame_viz, get_frame_viz_state(trav, data), + data.get_internal_transform(trav), +- data.get_prev_internal_transform(trav)); ++ data.get_prev_net_transform(trav)); + trav->get_cull_handler()->record_object(frame_viz, trav); + + // Now carry on to render our child nodes. +diff --git a/panda/src/pgraph/planeNode.cxx b/panda/src/pgraph/planeNode.cxx +index a643862..cfc098b 100644 +--- a/panda/src/pgraph/planeNode.cxx ++++ b/panda/src/pgraph/planeNode.cxx +@@ -142,7 +142,7 @@ cull_callback(CullTraverser *trav, CullTraverserData &data) { + CullableObject *plane_viz = + new CullableObject(get_viz(trav, data), data._state, + data.get_internal_transform(trav), +- data.get_prev_internal_transform(trav)); ++ data.get_prev_net_transform(trav)); + trav->get_cull_handler()->record_object(plane_viz, trav); + + // Now carry on to render our child nodes. +diff --git a/panda/src/pgraph/sceneSetup.I b/panda/src/pgraph/sceneSetup.I +index 1b150ff..4a29d5a 100644 +--- a/panda/src/pgraph/sceneSetup.I ++++ b/panda/src/pgraph/sceneSetup.I +@@ -269,21 +269,3 @@ INLINE const TransformState *SceneSetup:: + get_cs_world_transform() const { + return _cs_world_transform; + } +- +-/** +- * Specifies the position from the starting node relative to the camera, in +- * the GSG's internal coordinate system. +- */ +-INLINE void SceneSetup:: +-set_prev_cs_world_transform(const TransformState *prev_cs_world_transform) { +- _prev_cs_world_transform = prev_cs_world_transform; +-} +- +-/** +- * Returns the position from the starting node relative to the camera, in the +- * GSG's internal coordinate system. +- */ +-INLINE const TransformState *SceneSetup:: +-get_prev_cs_world_transform() const { +- return _prev_cs_world_transform; +-} +diff --git a/panda/src/pgraph/sceneSetup.h b/panda/src/pgraph/sceneSetup.h +index 72c0599..180f4ba 100644 +--- a/panda/src/pgraph/sceneSetup.h ++++ b/panda/src/pgraph/sceneSetup.h +@@ -74,9 +74,6 @@ PUBLISHED: + INLINE void set_cs_world_transform(const TransformState *cs_world_transform); + INLINE const TransformState *get_cs_world_transform() const; + +- INLINE void set_prev_cs_world_transform(const TransformState *prev_cs_world_transform); +- INLINE const TransformState *get_prev_cs_world_transform() const; +- + private: + DisplayRegion *_display_region; + int _viewport_width; +diff --git a/panda/src/pgraphnodes/callbackNode.cxx b/panda/src/pgraphnodes/callbackNode.cxx +index 2ced441..c6b3d9b 100644 +--- a/panda/src/pgraphnodes/callbackNode.cxx ++++ b/panda/src/pgraphnodes/callbackNode.cxx +@@ -134,7 +134,7 @@ add_for_draw(CullTraverser *trav, CullTraverserData &data) { + CullableObject *object = + new CullableObject(NULL, data._state, + data.get_internal_transform(trav), +- data.get_prev_internal_transform(trav)); ++ data.get_prev_net_transform(trav)); + object->set_draw_callback(cbobj); + trav->get_cull_handler()->record_object(object, trav); + } +diff --git a/panda/src/pgraphnodes/computeNode.cxx b/panda/src/pgraphnodes/computeNode.cxx +index 2f40dd6..b5efe4a 100644 +--- a/panda/src/pgraphnodes/computeNode.cxx ++++ b/panda/src/pgraphnodes/computeNode.cxx +@@ -95,7 +95,7 @@ add_for_draw(CullTraverser *trav, CullTraverserData &data) { + CullableObject *object = + new CullableObject(NULL, data._state, + data.get_internal_transform(trav), +- data.get_prev_internal_transform(trav)); ++ data.get_prev_net_transform(trav)); + object->set_draw_callback(_dispatcher); + trav->get_cull_handler()->record_object(object, trav); + } +diff --git a/panda/src/pgraphnodes/nodeCullCallbackData.cxx b/panda/src/pgraphnodes/nodeCullCallbackData.cxx +index b89ac5f..8542712 100644 +--- a/panda/src/pgraphnodes/nodeCullCallbackData.cxx ++++ b/panda/src/pgraphnodes/nodeCullCallbackData.cxx +@@ -51,7 +51,7 @@ upcall() { + CullableObject *object = + new CullableObject(NULL, _data._state, + _data.get_internal_transform(_trav), +- _data.get_prev_internal_transform(_trav)); ++ _data.get_prev_net_transform(_trav)); + object->set_draw_callback(cbobj); + _trav->get_cull_handler()->record_object(object, _trav); + } +diff --git a/panda/src/tinydisplay/tinyGraphicsStateGuardian.cxx b/panda/src/tinydisplay/tinyGraphicsStateGuardian.cxx +index ef6fcb7..fdfad22 100644 +--- a/panda/src/tinydisplay/tinyGraphicsStateGuardian.cxx ++++ b/panda/src/tinydisplay/tinyGraphicsStateGuardian.cxx +@@ -206,7 +206,7 @@ clear(DrawableRegion *clearable) { + return; + } + +- set_state_and_transform(RenderState::make_empty(), _internal_transform, _prev_internal_transform); ++ set_state_and_transform(RenderState::make_empty(), _internal_transform, _prev_net_transform); + + bool clear_color = false; + PIXEL color = 0; +@@ -1496,7 +1496,7 @@ set_state_and_transform(const RenderState *target, + _state_pcollector.add_level(1); + PStatTimer timer1(_draw_set_state_pcollector); + +- _prev_internal_transform = prev_transform; ++ _prev_net_transform = prev_transform; + + if (transform != _internal_transform) { + PStatTimer timer(_draw_set_state_transform_pcollector); +-- +1.9.5.msysgit.0 + diff --git a/data/panda3d_patches/prev-model-view-matrix.diff b/data/panda3d_patches/prev-model-view-matrix.diff new file mode 100644 index 0000000..76b8916 --- /dev/null +++ b/data/panda3d_patches/prev-model-view-matrix.diff @@ -0,0 +1,1452 @@ +From 47c83fce1f4a96954a5db33c6be875e17a4675cc Mon Sep 17 00:00:00 2001 +From: tobspr +Date: Sat, 27 Feb 2016 17:35:53 +0100 +Subject: [PATCH] Support for p3d_PrevModelViewMatrix, populate previous + transform during cull stage + +--- + panda/src/collide/collisionVisualizer.cxx | 7 +- + panda/src/display/callbackGraphicsWindow.cxx | 3 +- + panda/src/display/graphicsEngine.cxx | 4 ++ + panda/src/display/graphicsStateGuardian.I | 9 +++ + panda/src/display/graphicsStateGuardian.cxx | 21 +++++- + panda/src/display/graphicsStateGuardian.h | 9 +++ + panda/src/dxgsg9/dxGraphicsStateGuardian9.cxx | 8 ++- + panda/src/dxgsg9/dxGraphicsStateGuardian9.h | 4 +- + panda/src/glstuff/glCgShaderContext_src.cxx | 8 +++ + panda/src/glstuff/glCgShaderContext_src.h | 2 + + panda/src/glstuff/glGraphicsStateGuardian_src.cxx | 13 ++-- + panda/src/glstuff/glGraphicsStateGuardian_src.h | 3 +- + panda/src/glstuff/glShaderContext_src.cxx | 12 ++++ + panda/src/glstuff/glShaderContext_src.h | 2 + + panda/src/gobj/shader.cxx | 2 + + panda/src/gobj/shader.h | 4 ++ + panda/src/gobj/shaderContext.h | 2 +- + panda/src/gsgbase/graphicsStateGuardianBase.h | 4 ++ + panda/src/parametrics/ropeNode.cxx | 12 ++-- + panda/src/parametrics/sheetNode.cxx | 3 +- + panda/src/pgraph/config_pgraph.cxx | 7 ++ + panda/src/pgraph/config_pgraph.h | 1 + + panda/src/pgraph/cullTraverser.I | 3 + + panda/src/pgraph/cullTraverser.cxx | 10 ++- + panda/src/pgraph/cullTraverserData.I | 22 ++++++ + panda/src/pgraph/cullTraverserData.cxx | 8 +++ + panda/src/pgraph/cullTraverserData.h | 5 ++ + panda/src/pgraph/cullableObject.I | 29 ++++++-- + panda/src/pgraph/cullableObject.h | 5 ++ + panda/src/pgraph/geomNode.cxx | 5 +- + panda/src/pgraph/nodePath.cxx | 66 +++++++++++++----- + panda/src/pgraph/nodePath.h | 81 ++++++++++++++-------- + panda/src/pgraph/occluderNode.cxx | 6 +- + panda/src/pgraph/planeNode.cxx | 3 +- + panda/src/pgraph/portalNode.cxx | 2 + + panda/src/pgraph/sceneSetup.I | 19 +++++ + panda/src/pgraph/sceneSetup.h | 4 ++ + panda/src/pgraphnodes/callbackNode.cxx | 3 +- + panda/src/pgraphnodes/computeNode.cxx | 3 +- + panda/src/pgraphnodes/lodNode.cxx | 2 + + panda/src/pgraphnodes/nodeCullCallbackData.cxx | 3 +- + .../src/tinydisplay/tinyGraphicsStateGuardian.cxx | 7 +- + panda/src/tinydisplay/tinyGraphicsStateGuardian.h | 3 +- + 43 files changed, 349 insertions(+), 80 deletions(-) + +diff --git a/panda/src/collide/collisionVisualizer.cxx b/panda/src/collide/collisionVisualizer.cxx +index 19699b9..cceb6c5 100644 +--- a/panda/src/collide/collisionVisualizer.cxx ++++ b/panda/src/collide/collisionVisualizer.cxx +@@ -112,6 +112,7 @@ cull_callback(CullTraverser *trav, CullTraverserData &data) { + xform_data._net_transform = TransformState::make_identity(); + xform_data._view_frustum = trav->get_view_frustum(); + xform_data.apply_transform_and_state(trav, net_transform, ++ TransformState::make_identity(), + RenderState::make_empty(), + RenderEffects::make_empty(), + ClipPlaneAttrib::make()); +@@ -187,7 +188,8 @@ cull_callback(CullTraverser *trav, CullTraverserData &data) { + + CullableObject *object = + new CullableObject(geom, point_state, +- xform_data.get_internal_transform(trav)); ++ xform_data.get_internal_transform(trav), ++ xform_data.get_prev_internal_transform(trav)); + + trav->get_cull_handler()->record_object(object, trav); + } +@@ -216,7 +218,8 @@ cull_callback(CullTraverser *trav, CullTraverserData &data) { + + CullableObject *object = + new CullableObject(geom, empty_state, +- xform_data.get_internal_transform(trav)); ++ xform_data.get_internal_transform(trav), ++ xform_data.get_prev_internal_transform(trav)); + + trav->get_cull_handler()->record_object(object, trav); + } +diff --git a/panda/src/display/callbackGraphicsWindow.cxx b/panda/src/display/callbackGraphicsWindow.cxx +index f9c2362..ebd5b37 100644 +--- a/panda/src/display/callbackGraphicsWindow.cxx ++++ b/panda/src/display/callbackGraphicsWindow.cxx +@@ -108,7 +108,8 @@ end_frame(FrameMode mode, Thread *current_thread) { + if (_render_callback != NULL) { + // In case the callback or the application hosting the OpenGL context + // wants to do more rendering, let's give it a blank slate. +- _gsg->set_state_and_transform(RenderState::make_empty(), _gsg->get_internal_transform()); ++ _gsg->set_state_and_transform(RenderState::make_empty(), _gsg->get_internal_transform(), ++ _gsg->get_prev_internal_transform()); + _gsg->clear_before_callback(); + + RenderCallbackData data(this, RCT_end_frame, mode); +diff --git a/panda/src/display/graphicsEngine.cxx b/panda/src/display/graphicsEngine.cxx +index 41f6df5..7eed22f 100644 +--- a/panda/src/display/graphicsEngine.cxx ++++ b/panda/src/display/graphicsEngine.cxx +@@ -1805,6 +1805,7 @@ setup_scene(GraphicsStateGuardian *gsg, DisplayRegionPipelineReader *dr) { + NodePath scene_parent = scene_root.get_parent(current_thread); + CPT(TransformState) camera_transform = camera.get_transform(scene_parent, current_thread); + CPT(TransformState) world_transform = scene_parent.get_transform(camera, current_thread); ++ CPT(TransformState) prev_world_transform = scene_parent.get_prev_transform(camera, current_thread); + + if (camera_transform->is_invalid()) { + // There must be a singular transform over the scene. +@@ -1857,6 +1858,9 @@ setup_scene(GraphicsStateGuardian *gsg, DisplayRegionPipelineReader *dr) { + CPT(TransformState) cs_world_transform = cs_transform->compose(world_transform); + scene_setup->set_cs_world_transform(cs_world_transform); + ++ CPT(TransformState) prev_cs_world_transform = cs_transform->compose(prev_world_transform); ++ scene_setup->set_prev_cs_world_transform(prev_cs_world_transform); ++ + // Make sure that the GSG has a ShaderGenerator for the munger to use. We + // have to do this here because the ShaderGenerator needs a host window + // pointer. Hopefully we'll be able to eliminate that requirement in the +diff --git a/panda/src/display/graphicsStateGuardian.I b/panda/src/display/graphicsStateGuardian.I +index db8e1f1..d330100 100644 +--- a/panda/src/display/graphicsStateGuardian.I ++++ b/panda/src/display/graphicsStateGuardian.I +@@ -846,6 +846,15 @@ INLINE CPT(TransformState) GraphicsStateGuardian:: + get_internal_transform() const { + return _internal_transform; + } ++/** ++ * Fetches the previous external net transform. This transform is generally ++ * only set when geometry is about to be rendered. Therefore, this "get" ++ * function is typically only meaningful during the geometry rendering process. ++ */ ++INLINE CPT(TransformState) GraphicsStateGuardian:: ++get_prev_internal_transform() const { ++ return _prev_internal_transform; ++} + + /** + * Returns the current display region being rendered to, as set by the last +diff --git a/panda/src/display/graphicsStateGuardian.cxx b/panda/src/display/graphicsStateGuardian.cxx +index 6f5e873..c0b1cab 100644 +--- a/panda/src/display/graphicsStateGuardian.cxx ++++ b/panda/src/display/graphicsStateGuardian.cxx +@@ -146,6 +146,7 @@ GraphicsStateGuardian(CoordinateSystem internal_coordinate_system, + { + _coordinate_system = CS_invalid; + _internal_transform = TransformState::make_identity(); ++ _prev_internal_transform = _prev_internal_transform; + + set_coordinate_system(get_default_coordinate_system()); + +@@ -1189,6 +1190,9 @@ fetch_specified_part(Shader::ShaderMatInput part, InternalName *name, + case Shader::SMO_model_to_apiview: { + return &(get_internal_transform()->get_mat()); + } ++ case Shader::SMO_prev_model_to_apiview: { ++ return &(get_prev_internal_transform()->get_mat()); ++ } + case Shader::SMO_view_to_model: { + t = get_external_transform()->get_inverse()->get_mat(); + return &t; +@@ -1197,6 +1201,10 @@ fetch_specified_part(Shader::ShaderMatInput part, InternalName *name, + t = get_internal_transform()->get_inverse()->get_mat(); + return &t; + } ++ case Shader::SMO_prev_apiview_to_model: { ++ t = get_prev_internal_transform()->get_inverse()->get_mat(); ++ return &t; ++ } + case Shader::SMO_apiview_to_view: { + return &(_inv_cs_transform->get_mat()); + } +@@ -2308,6 +2316,15 @@ reset() { + } + + /** ++ * @see set_state_and_transform(const RenderState*, const TransformState*, const TransformState*) ++ */ ++void GraphicsStateGuardian:: ++set_state_and_transform(const RenderState *state, ++ const TransformState *trans) { ++ set_state_and_transform(state, trans, trans); ++} ++ ++/** + * Simultaneously resets the render state and the transform state. + * + * This transform specified is the "internal" net transform, already converted +@@ -2321,9 +2338,11 @@ reset() { + */ + void GraphicsStateGuardian:: + set_state_and_transform(const RenderState *state, +- const TransformState *trans) { ++ const TransformState *trans, ++ const TransformState *prev_transform) { + } + ++ + /** + * Clears the framebuffer within the current DisplayRegion, according to the + * flags indicated by the given DrawableRegion object. +diff --git a/panda/src/display/graphicsStateGuardian.h b/panda/src/display/graphicsStateGuardian.h +index 401c538..ad81f17 100644 +--- a/panda/src/display/graphicsStateGuardian.h ++++ b/panda/src/display/graphicsStateGuardian.h +@@ -320,6 +320,10 @@ public: + virtual void set_state_and_transform(const RenderState *state, + const TransformState *transform); + ++ virtual void set_state_and_transform(const RenderState *state, ++ const TransformState *transform, ++ const TransformState *prev_transform); ++ + virtual PN_stdfloat compute_distance_to(const LPoint3 &point) const; + + virtual void clear(DrawableRegion *clearable); +@@ -384,6 +388,7 @@ public: + + INLINE CPT(TransformState) get_external_transform() const; + INLINE CPT(TransformState) get_internal_transform() const; ++ INLINE CPT(TransformState) get_prev_internal_transform() const; + + RenderBuffer get_render_buffer(int buffer_type, const FrameBufferProperties &prop); + +@@ -473,6 +478,10 @@ protected: + // The current transform, as of the last call to set_state_and_transform(). + CPT(TransformState) _internal_transform; + ++ // The previous transform, as of the last call to the 3 parameter overload of ++ // set_state_and_transform() ++ CPT(TransformState) _prev_internal_transform; ++ + // The current TextureAttrib is a special case; we may further restrict it + // (according to graphics cards limits) or extend it (according to + // ColorScaleAttribs in effect) beyond what is specifically requested in the +diff --git a/panda/src/dxgsg9/dxGraphicsStateGuardian9.cxx b/panda/src/dxgsg9/dxGraphicsStateGuardian9.cxx +index 5cc7d8d..da726f6 100644 +--- a/panda/src/dxgsg9/dxGraphicsStateGuardian9.cxx ++++ b/panda/src/dxgsg9/dxGraphicsStateGuardian9.cxx +@@ -758,7 +758,7 @@ clear(DrawableRegion *clearable) { + return; + } + +- set_state_and_transform(RenderState::make_empty(), _internal_transform); ++ set_state_and_transform(RenderState::make_empty(), _internal_transform, _prev_internal_transform); + + D3DCOLOR color_clear_value = LColor_to_D3DCOLOR(clearable->get_clear_color()); + PN_stdfloat depth_clear_value = clearable->get_clear_depth(); +@@ -3027,7 +3027,8 @@ do_issue_shade_model() { + */ + void DXGraphicsStateGuardian9:: + set_state_and_transform(const RenderState *target, +- const TransformState *transform) { ++ const TransformState *transform, ++ const TransformState *prev_transform) { + #ifndef NDEBUG + if (gsg_cat.is_spam()) { + gsg_cat.spam() << "Setting GSG state to " << (void *)target << ":\n"; +@@ -3036,6 +3037,7 @@ set_state_and_transform(const RenderState *target, + #endif + _state_pcollector.add_level(1); + PStatTimer timer1(_draw_set_state_pcollector); ++ _prev_internal_transform = prev_transform; + + if (transform != _internal_transform) { + // PStatTimer timer(_draw_set_state_transform_pcollector); +@@ -3044,6 +3046,7 @@ set_state_and_transform(const RenderState *target, + do_issue_transform(); + } + ++ + if (target == _state_rs && (_state_mask | _inv_state_mask).is_all_on()) { + return; + } +@@ -3233,6 +3236,7 @@ set_state_and_transform(const RenderState *target, + _state_rs = _target_rs; + } + ++ + /** + * Called the first time a particular light has been bound to a given id + * within a frame, this should set up the associated hardware light with the +diff --git a/panda/src/dxgsg9/dxGraphicsStateGuardian9.h b/panda/src/dxgsg9/dxGraphicsStateGuardian9.h +index 4a51d21..b6afb00 100644 +--- a/panda/src/dxgsg9/dxGraphicsStateGuardian9.h ++++ b/panda/src/dxgsg9/dxGraphicsStateGuardian9.h +@@ -150,7 +150,9 @@ public: + INLINE static DWORD LColor_to_D3DCOLOR(const LColor &cLColor); + + virtual void set_state_and_transform(const RenderState *state, +- const TransformState *transform); ++ const TransformState *transform, ++ const TransformState *prev_transform); ++ + + bool check_dx_allocation (HRESULT result, int allocation_size, int attempts); + +diff --git a/panda/src/glstuff/glCgShaderContext_src.cxx b/panda/src/glstuff/glCgShaderContext_src.cxx +index c857948..5a0aa4e 100644 +--- a/panda/src/glstuff/glCgShaderContext_src.cxx ++++ b/panda/src/glstuff/glCgShaderContext_src.cxx +@@ -384,6 +384,7 @@ unbind() { + } + + /** ++ * + * This function gets called whenever the RenderState or TransformState has + * changed, but the Shader itself has not changed. It loads new values into + * the shader's parameters. +@@ -391,6 +392,7 @@ unbind() { + void CLP(CgShaderContext):: + set_state_and_transform(const RenderState *target_rs, + const TransformState *modelview_transform, ++ const TransformState *prev_modelview_transform, + const TransformState *projection_transform) { + + if (!valid()) { +@@ -404,6 +406,12 @@ set_state_and_transform(const RenderState *target_rs, + _modelview_transform = modelview_transform; + altered |= Shader::SSD_transform; + } ++ ++ if (_prev_modelview_transform != prev_modelview_transform) { ++ _prev_modelview_transform = prev_modelview_transform; ++ altered |= Shader::SSD_transform; ++ } ++ + if (_projection_transform != projection_transform) { + _projection_transform = projection_transform; + altered |= Shader::SSD_projection; +diff --git a/panda/src/glstuff/glCgShaderContext_src.h b/panda/src/glstuff/glCgShaderContext_src.h +index ae76989..c229444 100644 +--- a/panda/src/glstuff/glCgShaderContext_src.h ++++ b/panda/src/glstuff/glCgShaderContext_src.h +@@ -39,6 +39,7 @@ public: + + void set_state_and_transform(const RenderState *state, + const TransformState *modelview_transform, ++ const TransformState *prev_modelview_transform, + const TransformState *projection_transform); + + void issue_parameters(int altered) OVERRIDE; +@@ -77,6 +78,7 @@ private: + + WCPT(RenderState) _state_rs; + CPT(TransformState) _modelview_transform; ++ CPT(TransformState) _prev_modelview_transform; + CPT(TransformState) _projection_transform; + GLint _frame_number; + +diff --git a/panda/src/glstuff/glGraphicsStateGuardian_src.cxx b/panda/src/glstuff/glGraphicsStateGuardian_src.cxx +index 2a9ace7..1fb4fcd 100644 +--- a/panda/src/glstuff/glGraphicsStateGuardian_src.cxx ++++ b/panda/src/glstuff/glGraphicsStateGuardian_src.cxx +@@ -2869,7 +2869,8 @@ clear(DrawableRegion *clearable) { + + // XXX rdb: Is this line really necessary? Could we perhaps just reset the + // color write mask and other relevant attributes? +- set_state_and_transform(RenderState::make_empty(), _internal_transform); ++ set_state_and_transform(RenderState::make_empty(), _internal_transform, ++ _prev_internal_transform); + + int mask = 0; + +@@ -5889,7 +5890,8 @@ framebuffer_copy_to_ram(Texture *tex, int view, int z, + // Bug fix for RE, RE2, and VTX - need to disable texturing in order for + // glReadPixels() to work NOTE: reading the depth buffer is *much* slower + // than reading the color buffer +- set_state_and_transform(RenderState::make_empty(), _internal_transform); ++ set_state_and_transform(RenderState::make_empty(), _internal_transform, ++ _prev_internal_transform); + + int xo, yo, w, h; + dr->get_region_pixels(xo, yo, w, h); +@@ -9486,7 +9488,8 @@ end_bind_clip_planes() { + */ + void CLP(GraphicsStateGuardian):: + set_state_and_transform(const RenderState *target, +- const TransformState *transform) { ++ const TransformState *transform, ++ const TransformState *prev_transform) { + report_my_gl_errors(); + #ifndef NDEBUG + if (gsg_cat.is_spam()) { +@@ -9498,6 +9501,8 @@ set_state_and_transform(const RenderState *target, + _state_pcollector.add_level(1); + PStatGPUTimer timer1(this, _draw_set_state_pcollector); + ++ _prev_internal_transform = prev_transform; ++ + if (transform != _internal_transform) { + // PStatGPUTimer timer(this, _draw_set_state_transform_pcollector); + _transform_state_pcollector.add_level(1); +@@ -9529,7 +9534,7 @@ set_state_and_transform(const RenderState *target, + #endif + + if (_current_shader_context != NULL) { +- _current_shader_context->set_state_and_transform(target, transform, _projection_mat); ++ _current_shader_context->set_state_and_transform(target, transform, prev_transform, _projection_mat); + } + #endif + +diff --git a/panda/src/glstuff/glGraphicsStateGuardian_src.h b/panda/src/glstuff/glGraphicsStateGuardian_src.h +index c2909e3..b1267ba 100644 +--- a/panda/src/glstuff/glGraphicsStateGuardian_src.h ++++ b/panda/src/glstuff/glGraphicsStateGuardian_src.h +@@ -375,7 +375,8 @@ public: + INLINE int get_gl_version_minor() const; + + virtual void set_state_and_transform(const RenderState *state, +- const TransformState *transform); ++ const TransformState *transform, ++ const TransformState *prev_transform); + + void bind_fbo(GLuint fbo); + virtual bool get_supports_cg_profile(const string &name) const; +diff --git a/panda/src/glstuff/glShaderContext_src.cxx b/panda/src/glstuff/glShaderContext_src.cxx +index 708347a..a7759af 100644 +--- a/panda/src/glstuff/glShaderContext_src.cxx ++++ b/panda/src/glstuff/glShaderContext_src.cxx +@@ -769,6 +769,12 @@ reflect_uniform(int i, char *name_buffer, GLsizei name_buflen) { + : Shader::SMO_model_to_apiview; + bind._part[1] = Shader::SMO_identity; + ++ } else if (matrix_name == "PrevModelViewMatrix") { ++ bind._func = Shader::SMF_first; ++ bind._part[0] = inverse ? Shader::SMO_prev_apiview_to_model ++ : Shader::SMO_prev_model_to_apiview; ++ bind._part[1] = Shader::SMO_identity; ++ + } else if (matrix_name == "ProjectionMatrix") { + bind._func = Shader::SMF_first; + bind._part[0] = inverse ? Shader::SMO_apiclip_to_apiview +@@ -1789,6 +1795,7 @@ unbind() { + void CLP(ShaderContext):: + set_state_and_transform(const RenderState *target_rs, + const TransformState *modelview_transform, ++ const TransformState *prev_modelview_transform, + const TransformState *projection_transform) { + + // Find out which state properties have changed. +@@ -1798,6 +1805,11 @@ set_state_and_transform(const RenderState *target_rs, + _modelview_transform = modelview_transform; + altered |= Shader::SSD_transform; + } ++ if (_prev_modelview_transform != prev_modelview_transform) { ++ _prev_modelview_transform = prev_modelview_transform; ++ altered |= Shader::SSD_transform; ++ } ++ + if (_projection_transform != projection_transform) { + _projection_transform = projection_transform; + altered |= Shader::SSD_projection; +diff --git a/panda/src/glstuff/glShaderContext_src.h b/panda/src/glstuff/glShaderContext_src.h +index 4209ec6..b260f1c 100644 +--- a/panda/src/glstuff/glShaderContext_src.h ++++ b/panda/src/glstuff/glShaderContext_src.h +@@ -48,6 +48,7 @@ public: + + void set_state_and_transform(const RenderState *state, + const TransformState *modelview_transform, ++ const TransformState *prev_modelview_transform, + const TransformState *projection_transform); + + void issue_parameters(int altered); +@@ -69,6 +70,7 @@ private: + + WCPT(RenderState) _state_rs; + CPT(TransformState) _modelview_transform; ++ CPT(TransformState) _prev_modelview_transform; + CPT(TransformState) _projection_transform; + + /* +diff --git a/panda/src/gobj/shader.cxx b/panda/src/gobj/shader.cxx +index 2905d54..552f665 100644 +--- a/panda/src/gobj/shader.cxx ++++ b/panda/src/gobj/shader.cxx +@@ -390,6 +390,8 @@ cp_dependency(ShaderMatInput inp) { + (inp == SMO_view_to_model) || + (inp == SMO_model_to_apiview) || + (inp == SMO_apiview_to_model) || ++ (inp == SMO_prev_model_to_apiview) || ++ (inp == SMO_prev_apiview_to_model) || + (inp == SMO_view_to_world) || + (inp == SMO_world_to_view) || + (inp == SMO_view_x_to_view) || +diff --git a/panda/src/gobj/shader.h b/panda/src/gobj/shader.h +index dbdde6f..f517565 100644 +--- a/panda/src/gobj/shader.h ++++ b/panda/src/gobj/shader.h +@@ -201,6 +201,10 @@ public: + // Hack for text rendering. Don't use in user shaders. + SMO_tex_is_alpha_i, + ++ // Previous frame transform ++ SMO_prev_apiview_to_model, ++ SMO_prev_model_to_apiview, ++ + SMO_INVALID + }; + +diff --git a/panda/src/gobj/shaderContext.h b/panda/src/gobj/shaderContext.h +index 2b356ce..af2c81d 100644 +--- a/panda/src/gobj/shaderContext.h ++++ b/panda/src/gobj/shaderContext.h +@@ -32,7 +32,7 @@ class EXPCL_PANDA_GOBJ ShaderContext: public SavedContext { + public: + INLINE ShaderContext(Shader *se); + +- INLINE virtual void set_state_and_transform(const RenderState *, const TransformState *, const TransformState*) {}; ++ INLINE virtual void set_state_and_transform(const RenderState *, const TransformState *, const TransformState *, const TransformState *) {}; + + INLINE virtual bool valid() { return false; } + INLINE virtual void bind() {}; +diff --git a/panda/src/gsgbase/graphicsStateGuardianBase.h b/panda/src/gsgbase/graphicsStateGuardianBase.h +index 2fecf30..ace7f38 100644 +--- a/panda/src/gsgbase/graphicsStateGuardianBase.h ++++ b/panda/src/gsgbase/graphicsStateGuardianBase.h +@@ -170,6 +170,10 @@ public: + virtual void set_state_and_transform(const RenderState *state, + const TransformState *transform)=0; + ++ virtual void set_state_and_transform(const RenderState *state, ++ const TransformState *transform, ++ const TransformState *prev_transform)=0; ++ + // This function may only be called during a render traversal; it will + // compute the distance to the indicated point, assumed to be in eye + // coordinates, from the camera plane. This is a virtual function because +diff --git a/panda/src/parametrics/ropeNode.cxx b/panda/src/parametrics/ropeNode.cxx +index c799595..6705f66 100644 +--- a/panda/src/parametrics/ropeNode.cxx ++++ b/panda/src/parametrics/ropeNode.cxx +@@ -334,7 +334,8 @@ render_thread(CullTraverser *trav, CullTraverserData &data, + + CullableObject *object = + new CullableObject(geom, state, +- data.get_internal_transform(trav)); ++ data.get_internal_transform(trav), ++ data.get_prev_internal_transform(trav)); + trav->get_cull_handler()->record_object(object, trav); + } + +@@ -380,7 +381,8 @@ render_tape(CullTraverser *trav, CullTraverserData &data, + + CullableObject *object = + new CullableObject(geom, state, +- data.get_internal_transform(trav)); ++ data.get_internal_transform(trav), ++ data.get_prev_internal_transform(trav)); + trav->get_cull_handler()->record_object(object, trav); + } + +@@ -433,7 +435,8 @@ render_billboard(CullTraverser *trav, CullTraverserData &data, + + CullableObject *object = + new CullableObject(geom, state, +- data.get_internal_transform(trav)); ++ data.get_internal_transform(trav), ++ data.get_prev_internal_transform(trav)); + trav->get_cull_handler()->record_object(object, trav); + } + +@@ -494,7 +497,8 @@ render_tube(CullTraverser *trav, CullTraverserData &data, + + CullableObject *object = + new CullableObject(geom, state, +- data.get_internal_transform(trav)); ++ data.get_internal_transform(trav), ++ data.get_prev_internal_transform(trav)); + trav->get_cull_handler()->record_object(object, trav); + } + +diff --git a/panda/src/parametrics/sheetNode.cxx b/panda/src/parametrics/sheetNode.cxx +index 34496bc..f745d6e 100644 +--- a/panda/src/parametrics/sheetNode.cxx ++++ b/panda/src/parametrics/sheetNode.cxx +@@ -331,7 +331,8 @@ render_sheet(CullTraverser *trav, CullTraverserData &data, + + CullableObject *object = + new CullableObject(geom, state, +- data.get_internal_transform(trav)); ++ data.get_internal_transform(trav), ++ data.get_prev_internal_transform(trav)); + trav->get_cull_handler()->record_object(object, trav); + } + +diff --git a/panda/src/pgraph/config_pgraph.cxx b/panda/src/pgraph/config_pgraph.cxx +index d5427a6..1360bbf 100644 +--- a/panda/src/pgraph/config_pgraph.cxx ++++ b/panda/src/pgraph/config_pgraph.cxx +@@ -369,6 +369,13 @@ ConfigVariableBool allow_live_flatten + "only has an effect when Panda is not compiled for a release " + "build.")); + ++ ++ConfigVariableBool always_store_prev_transform ++("always-store-prev-transform", false, ++ PRC_DESC("When setting this to true, the previous transform is kept on " ++ "nodes. This makes NodePath::set_pos and all other transform changes " ++ "behave like their fluid variants, e.g. set_fluid_pos.")); ++ + /** + * Initializes the library. This must be called at least once before any of + * the functions or classes in this library can be used. Normally it will be +diff --git a/panda/src/pgraph/config_pgraph.h b/panda/src/pgraph/config_pgraph.h +index 988c9b1..4ba1ad5 100644 +--- a/panda/src/pgraph/config_pgraph.h ++++ b/panda/src/pgraph/config_pgraph.h +@@ -72,6 +72,7 @@ extern ConfigVariableList load_file_type; + extern ConfigVariableString default_model_extension; + + extern ConfigVariableBool allow_live_flatten; ++extern ConfigVariableBool always_store_prev_transform; + + extern EXPCL_PANDA_PGRAPH void init_libpgraph(); + +diff --git a/panda/src/pgraph/cullTraverser.I b/panda/src/pgraph/cullTraverser.I +index 180b94b..8441ba0 100644 +--- a/panda/src/pgraph/cullTraverser.I ++++ b/panda/src/pgraph/cullTraverser.I +@@ -227,6 +227,8 @@ do_traverse(CullTraverserData &data) { + + data.apply_transform_and_state(this); + ++#if defined(HAVE_CG) || defined(SUPPORT_FIXED_FUNCTION) ++ // Fog is only supported with the shader generator or the FFP. + const FogAttrib *fog = (const FogAttrib *) + node_reader->get_state()->get_attrib(FogAttrib::get_class_slot()); + +@@ -237,6 +239,7 @@ do_traverse(CullTraverserData &data) { + // it. + fog->get_fog()->adjust_to_camera(get_camera_transform()); + } ++#endif + + if (fancy_bits & PandaNode::FB_cull_callback) { + PandaNode *node = data.node(); +diff --git a/panda/src/pgraph/cullTraverser.cxx b/panda/src/pgraph/cullTraverser.cxx +index 5d08b4e..df8ae99 100644 +--- a/panda/src/pgraph/cullTraverser.cxx ++++ b/panda/src/pgraph/cullTraverser.cxx +@@ -128,7 +128,9 @@ traverse(const NodePath &root) { + // Store this pointer in this + set_portal_clipper(&portal_viewer); + +- CullTraverserData data(root, TransformState::make_identity(), ++ CullTraverserData data(root, ++ TransformState::make_identity(), ++ TransformState::make_identity(), + _initial_state, _view_frustum, + _current_thread); + +@@ -142,13 +144,17 @@ traverse(const NodePath &root) { + // Render the frustum relative to the cull center. + NodePath cull_center = _scene_setup->get_cull_center(); + CPT(TransformState) transform = cull_center.get_transform(root); ++ CPT(TransformState) prev_transform = cull_center.get_prev_transform(root); + + CullTraverserData my_data(data, portal_viewer._previous); + my_data._net_transform = my_data._net_transform->compose(transform); ++ my_data._prev_net_transform = my_data._prev_net_transform->compose(prev_transform); + traverse(my_data); + + } else { +- CullTraverserData data(root, TransformState::make_identity(), ++ CullTraverserData data(root, ++ TransformState::make_identity(), ++ TransformState::make_identity(), + _initial_state, _view_frustum, + _current_thread); + +diff --git a/panda/src/pgraph/cullTraverserData.I b/panda/src/pgraph/cullTraverserData.I +index 4367d16..7c1a79f 100644 +--- a/panda/src/pgraph/cullTraverserData.I ++++ b/panda/src/pgraph/cullTraverserData.I +@@ -17,12 +17,14 @@ + INLINE CullTraverserData:: + CullTraverserData(const NodePath &start, + const TransformState *net_transform, ++ const TransformState *prev_net_transform, + const RenderState *state, + GeometricBoundingVolume *view_frustum, + Thread *current_thread) : + _node_path(start), + _node_reader(start.node(), current_thread), + _net_transform(net_transform), ++ _prev_net_transform(prev_net_transform), + _state(state), + _view_frustum(view_frustum), + _cull_planes(CullPlanes::make_empty()), +@@ -42,6 +44,7 @@ CullTraverserData(const CullTraverserData ©) : + _node_path(copy._node_path), + _node_reader(copy._node_reader), + _net_transform(copy._net_transform), ++ _prev_net_transform(copy._prev_net_transform), + _state(copy._state), + _view_frustum(copy._view_frustum), + _cull_planes(copy._cull_planes), +@@ -58,6 +61,7 @@ operator = (const CullTraverserData ©) { + _node_path = copy._node_path; + _node_reader = copy._node_reader; + _net_transform = copy._net_transform; ++ _prev_net_transform = copy._prev_net_transform; + _state = copy._state; + _view_frustum = copy._view_frustum; + _cull_planes = copy._cull_planes; +@@ -74,6 +78,7 @@ CullTraverserData(const CullTraverserData &parent, PandaNode *child) : + _node_path(parent._node_path, child), + _node_reader(child, parent._node_reader.get_current_thread()), + _net_transform(parent._net_transform), ++ _prev_net_transform(parent._prev_net_transform), + _state(parent._state), + _view_frustum(parent._view_frustum), + _cull_planes(parent._cull_planes), +@@ -134,6 +139,14 @@ INLINE CPT(TransformState) CullTraverserData:: + get_internal_transform(const CullTraverser *trav) const { + return trav->get_scene()->get_cs_world_transform()->compose(_net_transform); + } ++/** ++ * Returns the previous internal transform: the modelview transform in the GSG's ++ * internal coordinate system in the last frame. ++ */ ++INLINE CPT(TransformState) CullTraverserData:: ++get_prev_internal_transform(const CullTraverser *trav) const { ++ return trav->get_scene()->get_prev_cs_world_transform()->compose(_prev_net_transform); ++} + + /** + * Returns the net transform: the relative transform from root of the scene +@@ -145,6 +158,15 @@ get_net_transform(const CullTraverser *) const { + } + + /** ++ * Returns the previous net transform: the relative transform from root of the scene ++ * graph to the current node in the last frame. ++ */ ++INLINE const TransformState *CullTraverserData:: ++get_prev_net_transform(const CullTraverser *) const { ++ return _prev_net_transform; ++} ++ ++/** + * Returns true if the current node is within the view frustum, false + * otherwise. If the node's bounding volume falls completely within the view + * frustum, this will also reset the view frustum pointer, saving some work +diff --git a/panda/src/pgraph/cullTraverserData.cxx b/panda/src/pgraph/cullTraverserData.cxx +index 186869c..e67d45d 100644 +--- a/panda/src/pgraph/cullTraverserData.cxx ++++ b/panda/src/pgraph/cullTraverserData.cxx +@@ -47,6 +47,7 @@ apply_transform_and_state(CullTraverser *trav) { + _node_reader.compose_draw_mask(_draw_mask); + + apply_transform_and_state(trav, _node_reader.get_transform(), ++ _node_reader.get_prev_transform(), + node_state, _node_reader.get_effects(), + _node_reader.get_off_clip_planes()); + } +@@ -58,6 +59,7 @@ apply_transform_and_state(CullTraverser *trav) { + void CullTraverserData:: + apply_transform_and_state(CullTraverser *trav, + CPT(TransformState) node_transform, ++ CPT(TransformState) prev_node_transform, + CPT(RenderState) node_state, + CPT(RenderEffects) node_effects, + const RenderAttrib *off_clip_planes) { +@@ -96,6 +98,12 @@ apply_transform_and_state(CullTraverser *trav, + } + } + ++ if (_net_transform == _prev_net_transform && node_transform == prev_node_transform) { ++ _prev_net_transform = _net_transform; ++ } else if (!prev_node_transform->is_identity()) { ++ _prev_net_transform = _prev_net_transform->compose(prev_node_transform); ++ } ++ + _state = _state->compose(node_state); + + if (clip_plane_cull) { +diff --git a/panda/src/pgraph/cullTraverserData.h b/panda/src/pgraph/cullTraverserData.h +index 80d523f..30b8d68 100644 +--- a/panda/src/pgraph/cullTraverserData.h ++++ b/panda/src/pgraph/cullTraverserData.h +@@ -41,6 +41,7 @@ class EXPCL_PANDA_PGRAPH CullTraverserData { + public: + INLINE CullTraverserData(const NodePath &start, + const TransformState *net_transform, ++ const TransformState *prev_net_transform, + const RenderState *state, + GeometricBoundingVolume *view_frustum, + Thread *current_thread); +@@ -60,7 +61,9 @@ public: + PUBLISHED: + INLINE CPT(TransformState) get_modelview_transform(const CullTraverser *trav) const; + INLINE CPT(TransformState) get_internal_transform(const CullTraverser *trav) const; ++ INLINE CPT(TransformState) get_prev_internal_transform(const CullTraverser *trav) const; + INLINE const TransformState *get_net_transform(const CullTraverser *trav) const; ++ INLINE const TransformState *get_prev_net_transform(const CullTraverser *trav) const; + + INLINE bool is_in_view(const DrawMask &camera_mask); + INLINE bool is_this_node_hidden(const DrawMask &camera_mask) const; +@@ -68,6 +71,7 @@ PUBLISHED: + void apply_transform_and_state(CullTraverser *trav); + void apply_transform_and_state(CullTraverser *trav, + CPT(TransformState) node_transform, ++ CPT(TransformState) prev_node_transform, + CPT(RenderState) node_state, + CPT(RenderEffects) node_effects, + const RenderAttrib *off_clip_planes); +@@ -76,6 +80,7 @@ public: + WorkingNodePath _node_path; + PandaNodePipelineReader _node_reader; + CPT(TransformState) _net_transform; ++ CPT(TransformState) _prev_net_transform; + CPT(RenderState) _state; + PT(GeometricBoundingVolume) _view_frustum; + CPT(CullPlanes) _cull_planes; +diff --git a/panda/src/pgraph/cullableObject.I b/panda/src/pgraph/cullableObject.I +index 2424965..5fbe70c 100644 +--- a/panda/src/pgraph/cullableObject.I ++++ b/panda/src/pgraph/cullableObject.I +@@ -23,6 +23,24 @@ CullableObject() { + + /** + * Creates a CullableObject based the indicated geom, with the indicated ++ * render state, transform and previous transform. ++ */ ++INLINE CullableObject:: ++CullableObject(const Geom *geom, const RenderState *state, ++ const TransformState *internal_transform, ++ const TransformState *prev_internal_transform) : ++ _geom(geom), ++ _state(state), ++ _internal_transform(internal_transform), ++ _prev_internal_transform(prev_internal_transform) ++{ ++#ifdef DO_MEMORY_USAGE ++ MemoryUsage::update_type(this, get_class_type()); ++#endif ++} ++ ++/** ++ * Creates a CullableObject based the indicated geom, with the indicated + * render state and transform. + */ + INLINE CullableObject:: +@@ -30,7 +48,8 @@ CullableObject(const Geom *geom, const RenderState *state, + const TransformState *internal_transform) : + _geom(geom), + _state(state), +- _internal_transform(internal_transform) ++ _internal_transform(internal_transform), ++ _prev_internal_transform(internal_transform) + { + #ifdef DO_MEMORY_USAGE + MemoryUsage::update_type(this, get_class_type()); +@@ -46,7 +65,8 @@ CullableObject(const CullableObject ©) : + _munger(copy._munger), + _munged_data(copy._munged_data), + _state(copy._state), +- _internal_transform(copy._internal_transform) ++ _internal_transform(copy._internal_transform), ++ _prev_internal_transform(copy._prev_internal_transform) + { + #ifdef DO_MEMORY_USAGE + MemoryUsage::update_type(this, get_class_type()); +@@ -63,6 +83,7 @@ operator = (const CullableObject ©) { + _munged_data = copy._munged_data; + _state = copy._state; + _internal_transform = copy._internal_transform; ++ _prev_internal_transform = copy._prev_internal_transform; + _draw_callback = copy._draw_callback; + } + +@@ -75,7 +96,7 @@ draw(GraphicsStateGuardianBase *gsg, bool force, Thread *current_thread) { + if (_draw_callback != (CallbackObject *)NULL) { + // It has a callback associated. + gsg->clear_before_callback(); +- gsg->set_state_and_transform(_state, _internal_transform); ++ gsg->set_state_and_transform(_state, _internal_transform, _prev_internal_transform); + GeomDrawCallbackData cbdata(this, gsg, force); + _draw_callback->do_callback(&cbdata); + if (cbdata.get_lost_state()) { +@@ -85,7 +106,7 @@ draw(GraphicsStateGuardianBase *gsg, bool force, Thread *current_thread) { + // Now the callback has taken care of drawing. + } else { + nassertv(_geom != (Geom *)NULL); +- gsg->set_state_and_transform(_state, _internal_transform); ++ gsg->set_state_and_transform(_state, _internal_transform, _prev_internal_transform); + draw_inline(gsg, force, current_thread); + } + } +diff --git a/panda/src/pgraph/cullableObject.h b/panda/src/pgraph/cullableObject.h +index 82fd0df..f450cbc 100644 +--- a/panda/src/pgraph/cullableObject.h ++++ b/panda/src/pgraph/cullableObject.h +@@ -49,6 +49,10 @@ public: + INLINE CullableObject(const Geom *geom, const RenderState *state, + const TransformState *internal_transform); + ++ INLINE CullableObject(const Geom *geom, const RenderState *state, ++ const TransformState *internal_transform, ++ const TransformState *prev_internal_transform); ++ + INLINE CullableObject(const CullableObject ©); + INLINE void operator = (const CullableObject ©); + +@@ -74,6 +78,7 @@ public: + CPT(GeomVertexData) _munged_data; + CPT(RenderState) _state; + CPT(TransformState) _internal_transform; ++ CPT(TransformState) _prev_internal_transform; + PT(CallbackObject) _draw_callback; + + private: +diff --git a/panda/src/pgraph/geomNode.cxx b/panda/src/pgraph/geomNode.cxx +index bfbd24f..5ea321e 100644 +--- a/panda/src/pgraph/geomNode.cxx ++++ b/panda/src/pgraph/geomNode.cxx +@@ -512,7 +512,6 @@ add_for_draw(CullTraverser *trav, CullTraverserData &data) { + Geoms geoms = get_geoms(trav->get_current_thread()); + int num_geoms = geoms.get_num_geoms(); + trav->_geoms_pcollector.add_level(num_geoms); +- CPT(TransformState) internal_transform = data.get_internal_transform(trav); + + for (int i = 0; i < num_geoms; i++) { + const Geom *geom = geoms.get_geom(i); +@@ -558,7 +557,9 @@ add_for_draw(CullTraverser *trav, CullTraverserData &data) { + } + + CullableObject *object = +- new CullableObject(geom, state, internal_transform); ++ new CullableObject(geom, state, ++ data.get_internal_transform(trav), ++ data.get_prev_internal_transform(trav)); + trav->get_cull_handler()->record_object(object, trav); + } + } +diff --git a/panda/src/pgraph/nodePath.cxx b/panda/src/pgraph/nodePath.cxx +index c6bfff1..ecb8936 100644 +--- a/panda/src/pgraph/nodePath.cxx ++++ b/panda/src/pgraph/nodePath.cxx +@@ -906,7 +906,9 @@ void NodePath:: + set_pos(const LVecBase3 &pos) { + nassertv_always(!is_empty()); + set_transform(get_transform()->set_pos(pos)); +- node()->reset_prev_transform(); ++ if (!always_store_prev_transform) { ++ node()->reset_prev_transform(); ++ } + } + + void NodePath:: +@@ -1173,7 +1175,10 @@ set_pos_hpr(const LVecBase3 &pos, const LVecBase3 &hpr) { + transform = TransformState::make_pos_hpr_scale_shear + (pos, hpr, transform->get_scale(), transform->get_shear()); + set_transform(transform); +- node()->reset_prev_transform(); ++ ++ if (!always_store_prev_transform) { ++ node()->reset_prev_transform(); ++ } + } + + /** +@@ -1187,7 +1192,10 @@ set_pos_quat(const LVecBase3 &pos, const LQuaternion &quat) { + transform = TransformState::make_pos_quat_scale_shear + (pos, quat, transform->get_scale(), transform->get_shear()); + set_transform(transform); +- node()->reset_prev_transform(); ++ ++ if (!always_store_prev_transform) { ++ node()->reset_prev_transform(); ++ } + } + + /** +@@ -1226,7 +1234,9 @@ set_pos_hpr_scale(const LVecBase3 &pos, const LVecBase3 &hpr, + nassertv_always(!is_empty()); + set_transform(TransformState::make_pos_hpr_scale + (pos, hpr, scale)); +- node()->reset_prev_transform(); ++ if (!always_store_prev_transform) { ++ node()->reset_prev_transform(); ++ } + } + + /** +@@ -1239,7 +1249,9 @@ set_pos_quat_scale(const LVecBase3 &pos, const LQuaternion &quat, + nassertv_always(!is_empty()); + set_transform(TransformState::make_pos_quat_scale + (pos, quat, scale)); +- node()->reset_prev_transform(); ++ if (!always_store_prev_transform) { ++ node()->reset_prev_transform(); ++ } + } + + /** +@@ -1252,7 +1264,9 @@ set_pos_hpr_scale_shear(const LVecBase3 &pos, const LVecBase3 &hpr, + nassertv_always(!is_empty()); + set_transform(TransformState::make_pos_hpr_scale_shear + (pos, hpr, scale, shear)); +- node()->reset_prev_transform(); ++ if (!always_store_prev_transform) { ++ node()->reset_prev_transform(); ++ } + } + + /** +@@ -1265,7 +1279,9 @@ set_pos_quat_scale_shear(const LVecBase3 &pos, const LQuaternion &quat, + nassertv_always(!is_empty()); + set_transform(TransformState::make_pos_quat_scale_shear + (pos, quat, scale, shear)); +- node()->reset_prev_transform(); ++ if (!always_store_prev_transform) { ++ node()->reset_prev_transform(); ++ } + } + + /** +@@ -1275,7 +1291,9 @@ void NodePath:: + set_mat(const LMatrix4 &mat) { + nassertv_always(!is_empty()); + set_transform(TransformState::make_mat(mat)); +- node()->reset_prev_transform(); ++ if (!always_store_prev_transform) { ++ node()->reset_prev_transform(); ++ } + } + + /** +@@ -1334,7 +1352,9 @@ set_pos(const NodePath &other, const LVecBase3 &pos) { + // If we didn't have a componentwise transform already, never mind. + set_transform(other, rel_transform->set_pos(pos)); + } +- node()->reset_prev_transform(); ++ if (!always_store_prev_transform) { ++ node()->reset_prev_transform(); ++ } + } + + void NodePath:: +@@ -1712,7 +1732,9 @@ set_pos_hpr(const NodePath &other, const LVecBase3 &pos, + // If we didn't have a componentwise transform already, never mind. + set_transform(other, TransformState::make_pos_hpr_scale_shear + (pos, hpr, rel_transform->get_scale(), rel_transform->get_shear())); +- node()->reset_prev_transform(); ++ if (!always_store_prev_transform) { ++ node()->reset_prev_transform(); ++ } + } + } + +@@ -1747,7 +1769,9 @@ set_pos_quat(const NodePath &other, const LVecBase3 &pos, + // If we didn't have a componentwise transform already, never mind. + set_transform(other, TransformState::make_pos_quat_scale_shear + (pos, quat, rel_transform->get_scale(), rel_transform->get_shear())); +- node()->reset_prev_transform(); ++ if (!always_store_prev_transform) { ++ node()->reset_prev_transform(); ++ } + } + } + +@@ -1797,7 +1821,9 @@ set_pos_hpr_scale(const NodePath &other, + nassertv_always(!is_empty()); + set_transform(other, TransformState::make_pos_hpr_scale + (pos, hpr, scale)); +- node()->reset_prev_transform(); ++ if (!always_store_prev_transform) { ++ node()->reset_prev_transform(); ++ } + } + + /** +@@ -1811,7 +1837,9 @@ set_pos_quat_scale(const NodePath &other, + nassertv_always(!is_empty()); + set_transform(other, TransformState::make_pos_quat_scale + (pos, quat, scale)); +- node()->reset_prev_transform(); ++ if (!always_store_prev_transform) { ++ node()->reset_prev_transform(); ++ } + } + + /** +@@ -1825,7 +1853,9 @@ set_pos_hpr_scale_shear(const NodePath &other, + nassertv_always(!is_empty()); + set_transform(other, TransformState::make_pos_hpr_scale_shear + (pos, hpr, scale, shear)); +- node()->reset_prev_transform(); ++ if (!always_store_prev_transform) { ++ node()->reset_prev_transform(); ++ } + } + + /** +@@ -1839,7 +1869,9 @@ set_pos_quat_scale_shear(const NodePath &other, + nassertv_always(!is_empty()); + set_transform(other, TransformState::make_pos_quat_scale_shear + (pos, quat, scale, shear)); +- node()->reset_prev_transform(); ++ if (!always_store_prev_transform) { ++ node()->reset_prev_transform(); ++ } + } + + /** +@@ -1864,7 +1896,9 @@ void NodePath:: + set_mat(const NodePath &other, const LMatrix4 &mat) { + nassertv_always(!is_empty()); + set_transform(other, TransformState::make_mat(mat)); +- node()->reset_prev_transform(); ++ if (!always_store_prev_transform) { ++ node()->reset_prev_transform(); ++ } + } + + /** +diff --git a/panda/src/pgraph/nodePath.h b/panda/src/pgraph/nodePath.h +index 729bcf3..a9a8233 100644 +--- a/panda/src/pgraph/nodePath.h ++++ b/panda/src/pgraph/nodePath.h +@@ -66,50 +66,73 @@ class ShaderInput; + * A NodePath is the fundamental unit of high-level interaction with the scene + * graph. It encapsulates the complete path down to a node from some other + * node, usually the root of the scene graph. This is used to resolve +- * ambiguities associated with instancing. NodePath also contains a number of +- * handy high-level methods for common scene-graph manipulations, such as +- * reparenting, and common state changes, such as repositioning. There are +- * also a number of NodePath methods for finding nodes deep within the tree by +- * name or by type. These take a path string, which at its simplest consists +- * of a series of node names separated by slashes, like a directory pathname. ++ * ambiguities associated with instancing. ++ * ++ * NodePath also contains a number of handy high-level methods for common ++ * scene-graph manipulations, such as reparenting, and common state changes, ++ * such as repositioning. There are also a number of NodePath methods for ++ * finding nodes deep within the tree by name or by type. These take a path ++ * string, which at its simplest consists of a series of node names separated ++ * by slashes, like a directory pathname. ++ * + * Each component of the path string may optionally consist of one of the +- * following special names, instead of a node name: * -- matches +- * exactly one node, with any name. ** -- matches any sequence of +- * zero or more nodes. +typename -- matches any node that is or derives from +- * the given type. -typename -- matches any node that is the given type +- * exactly. =tag -- matches any node that has the indicated tag. +- * =tag=value -- matches any node whose tag matches the indicated value. ++ * following special names, instead of a node name: ++ * ++ * * -- matches exactly one node, with any name. ++ * ** -- matches any sequence of zero or more nodes. ++ * +typename -- matches any node that is or derives from the given type. ++ * -typename -- matches any node that is the given type exactly. ++ * =tag -- matches any node that has the indicated tag. ++ * =tag=value -- matches any node whose tag matches the indicated value. ++ * + * Furthermore, a node name may itself contain standard filename globbing + * characters, like *, ?, and [a-z], that will be accepted as a partial match. + * (In fact, the '*' special name may be seen as just a special case of this.) + * The globbing characters may not be used with the typename matches or with + * tag matches, but they may be used to match a tag's value in the =tag=value +- * syntax. The special characters "@@", appearing at the beginning of a node ++ * syntax. ++ * ++ * The special characters "@@", appearing at the beginning of a node + * name, indicate a stashed node. Normally, stashed nodes are not returned by + * a find (but see the special flags, below), but a stashed node may be found + * if it is explicitly named with its leading @@ characters. By extension, +- * "@@*" may be used to identify any stashed node. Examples: "roomgraph" will +- * look for a node named "graph", which is a child of an unnamed node, which +- * is a child of a node named "room", which is a child of the starting path. +- * "**red*" will look for any node anywhere in the tree (below the starting +- * path) with a name that begins with "red". "**+PartBundleNode**head" will +- * look for a node named "head", somewhere below a PartBundleNode anywhere in +- * the tree. The search is always potentially ambiguous, even if the special ++ * "@@*" may be used to identify any stashed node. ++ * ++ * Examples: ++ * ++ * "roomgraph" will look for a node named "graph", which is a child ++ * of an unnamed node, which is a child of a node named "room", which is a ++ * child of the starting path. ++ * ++ * "**red*" will look for any node anywhere in the tree (below the starting ++ * path) with a name that begins with "red". ++ * ++ * "**+PartBundleNode**head" will look for a node named "head", somewhere ++ * below a PartBundleNode anywhere in the tree. ++ * ++ * The search is always potentially ambiguous, even if the special + * wildcard operators are not used, because there may be multiple nodes in the + * tree with the same name. In general, in the case of an ambiguity, the + * shortest path is preferred; when a method (such as extend_by) must choose + * only only one of several possible paths, it will choose the shortest + * available; on the other hand, when a method (such as find_all_matches) is + * to return all of the matching paths, it will sort them so that the shortest +- * paths appear first in the output. Special flags. The entire string may +- * optionally be followed by the ";" character, followed by one or more of the +- * following special control flags, with no intervening spaces or punctuation: +- * -h Do not return hidden nodes. +h Do return hidden nodes. -s Do +- * not return stashed nodes unless explicitly referenced with @@. +s Return +- * stashed nodes even without any explicit @@ characters. -i Node name +- * comparisons are not case insensitive: case must match exactly. +i Node +- * name comparisons are case insensitive: case is not important. This affects +- * matches against the node name only; node type and tag strings are always ++ * paths appear first in the output. ++ * ++ * Special flags: ++ * ++ * The entire string may optionally be followed by the ";" character, followed ++ * by one or more of the following special control flags, with no intervening ++ * spaces or punctuation: ++ * ++ * -h Do not return hidden nodes. ++ * +h Do return hidden nodes. ++ * -s Do not return stashed nodes unless explicitly referenced with @@. ++ * +s Return stashed nodes even without any explicit @@ characters. ++ * -i Node name comparisons are not case insensitive: case must match exactly. ++ * +i Node name comparisons are case insensitive: case is not important. ++ * ++ * This affects matches against the node name only; node type and tag strings are always + * case sensitive. The default flags are +h-s-i. + */ + +diff --git a/panda/src/pgraph/occluderNode.cxx b/panda/src/pgraph/occluderNode.cxx +index c1a4c4d..83695fb 100644 +--- a/panda/src/pgraph/occluderNode.cxx ++++ b/panda/src/pgraph/occluderNode.cxx +@@ -142,14 +142,16 @@ cull_callback(CullTraverser *trav, CullTraverserData &data) { + // draw a visualization, a checkerboard-textured polygon. + CullableObject *occluder_viz = + new CullableObject(get_occluder_viz(trav, data), get_occluder_viz_state(trav, data), +- data.get_internal_transform(trav)); ++ data.get_internal_transform(trav), ++ data.get_prev_internal_transform(trav)); + trav->get_cull_handler()->record_object(occluder_viz, trav); + + // Also get the frame. + nassertr(_frame_viz != (Geom *)NULL, false); + CullableObject *frame_viz = + new CullableObject(_frame_viz, get_frame_viz_state(trav, data), +- data.get_internal_transform(trav)); ++ data.get_internal_transform(trav), ++ data.get_prev_internal_transform(trav)); + trav->get_cull_handler()->record_object(frame_viz, trav); + + // Now carry on to render our child nodes. +diff --git a/panda/src/pgraph/planeNode.cxx b/panda/src/pgraph/planeNode.cxx +index c096eae..a643862 100644 +--- a/panda/src/pgraph/planeNode.cxx ++++ b/panda/src/pgraph/planeNode.cxx +@@ -141,7 +141,8 @@ cull_callback(CullTraverser *trav, CullTraverserData &data) { + + CullableObject *plane_viz = + new CullableObject(get_viz(trav, data), data._state, +- data.get_internal_transform(trav)); ++ data.get_internal_transform(trav), ++ data.get_prev_internal_transform(trav)); + trav->get_cull_handler()->record_object(plane_viz, trav); + + // Now carry on to render our child nodes. +diff --git a/panda/src/pgraph/portalNode.cxx b/panda/src/pgraph/portalNode.cxx +index d70eacd..3e360fd 100644 +--- a/panda/src/pgraph/portalNode.cxx ++++ b/panda/src/pgraph/portalNode.cxx +@@ -228,6 +228,7 @@ cull_callback(CullTraverser *trav, CullTraverserData &data) { + + // Get the net trasform of the _cell_out as seen from the camera. + CPT(TransformState) cell_transform = _cell_out.get_net_transform(); ++ CPT(TransformState) prev_cell_transform = _cell_out.get_net_prev_transform(); + CPT(TransformState) frustum_transform = cell_transform ->invert_compose(portal_viewer->_scene_setup->get_cull_center().get_net_transform()); + + // transform to _cell_out space +@@ -283,6 +284,7 @@ cull_callback(CullTraverser *trav, CullTraverserData &data) { + + CullTraverserData next_data(_cell_out, + cell_transform, ++ prev_cell_transform, + next_state, new_bh, + current_thread); + next_data._portal_depth = data._portal_depth + 1; +diff --git a/panda/src/pgraph/sceneSetup.I b/panda/src/pgraph/sceneSetup.I +index 425c538..1b150ff 100644 +--- a/panda/src/pgraph/sceneSetup.I ++++ b/panda/src/pgraph/sceneSetup.I +@@ -25,6 +25,7 @@ SceneSetup() { + _world_transform = TransformState::make_identity(); + _cs_transform = TransformState::make_identity(); + _cs_world_transform = TransformState::make_identity(); ++ _prev_cs_world_transform = TransformState::make_identity(); + } + + /** +@@ -268,3 +269,21 @@ INLINE const TransformState *SceneSetup:: + get_cs_world_transform() const { + return _cs_world_transform; + } ++ ++/** ++ * Specifies the position from the starting node relative to the camera, in ++ * the GSG's internal coordinate system. ++ */ ++INLINE void SceneSetup:: ++set_prev_cs_world_transform(const TransformState *prev_cs_world_transform) { ++ _prev_cs_world_transform = prev_cs_world_transform; ++} ++ ++/** ++ * Returns the position from the starting node relative to the camera, in the ++ * GSG's internal coordinate system. ++ */ ++INLINE const TransformState *SceneSetup:: ++get_prev_cs_world_transform() const { ++ return _prev_cs_world_transform; ++} +diff --git a/panda/src/pgraph/sceneSetup.h b/panda/src/pgraph/sceneSetup.h +index d2ad0c0..72c0599 100644 +--- a/panda/src/pgraph/sceneSetup.h ++++ b/panda/src/pgraph/sceneSetup.h +@@ -74,6 +74,9 @@ PUBLISHED: + INLINE void set_cs_world_transform(const TransformState *cs_world_transform); + INLINE const TransformState *get_cs_world_transform() const; + ++ INLINE void set_prev_cs_world_transform(const TransformState *prev_cs_world_transform); ++ INLINE const TransformState *get_prev_cs_world_transform() const; ++ + private: + DisplayRegion *_display_region; + int _viewport_width; +@@ -88,6 +91,7 @@ private: + CPT(TransformState) _world_transform; + CPT(TransformState) _cs_transform; + CPT(TransformState) _cs_world_transform; ++ CPT(TransformState) _prev_cs_world_transform; + + public: + static TypeHandle get_class_type() { +diff --git a/panda/src/pgraphnodes/callbackNode.cxx b/panda/src/pgraphnodes/callbackNode.cxx +index 17424d5..2ced441 100644 +--- a/panda/src/pgraphnodes/callbackNode.cxx ++++ b/panda/src/pgraphnodes/callbackNode.cxx +@@ -133,7 +133,8 @@ add_for_draw(CullTraverser *trav, CullTraverserData &data) { + if (cbobj != (CallbackObject *)NULL) { + CullableObject *object = + new CullableObject(NULL, data._state, +- data.get_internal_transform(trav)); ++ data.get_internal_transform(trav), ++ data.get_prev_internal_transform(trav)); + object->set_draw_callback(cbobj); + trav->get_cull_handler()->record_object(object, trav); + } +diff --git a/panda/src/pgraphnodes/computeNode.cxx b/panda/src/pgraphnodes/computeNode.cxx +index 7962378..2f40dd6 100644 +--- a/panda/src/pgraphnodes/computeNode.cxx ++++ b/panda/src/pgraphnodes/computeNode.cxx +@@ -94,7 +94,8 @@ add_for_draw(CullTraverser *trav, CullTraverserData &data) { + // however. + CullableObject *object = + new CullableObject(NULL, data._state, +- data.get_internal_transform(trav)); ++ data.get_internal_transform(trav), ++ data.get_prev_internal_transform(trav)); + object->set_draw_callback(_dispatcher); + trav->get_cull_handler()->record_object(object, trav); + } +diff --git a/panda/src/pgraphnodes/lodNode.cxx b/panda/src/pgraphnodes/lodNode.cxx +index 5936b06..2d52b41 100644 +--- a/panda/src/pgraphnodes/lodNode.cxx ++++ b/panda/src/pgraphnodes/lodNode.cxx +@@ -394,6 +394,7 @@ show_switches_cull_callback(CullTraverser *trav, CullTraverserData &data) { + // And draw the spindle in this color. + CullTraverserData next_data2(data, sw.get_spindle_viz()); + next_data2.apply_transform_and_state(trav, viz_transform, ++ TransformState::make_identity(), + RenderState::make_empty(), + RenderEffects::make_empty(), + ClipPlaneAttrib::make()); +@@ -404,6 +405,7 @@ show_switches_cull_callback(CullTraverser *trav, CullTraverserData &data) { + // the geometry and the spindle. + CullTraverserData next_data(data, sw.get_ring_viz()); + next_data.apply_transform_and_state(trav, viz_transform, ++ TransformState::make_identity(), + RenderState::make_empty(), + RenderEffects::make_empty(), + ClipPlaneAttrib::make()); +diff --git a/panda/src/pgraphnodes/nodeCullCallbackData.cxx b/panda/src/pgraphnodes/nodeCullCallbackData.cxx +index d0bf763..b89ac5f 100644 +--- a/panda/src/pgraphnodes/nodeCullCallbackData.cxx ++++ b/panda/src/pgraphnodes/nodeCullCallbackData.cxx +@@ -50,7 +50,8 @@ upcall() { + if (cbobj != (CallbackObject *)NULL) { + CullableObject *object = + new CullableObject(NULL, _data._state, +- _data.get_internal_transform(_trav)); ++ _data.get_internal_transform(_trav), ++ _data.get_prev_internal_transform(_trav)); + object->set_draw_callback(cbobj); + _trav->get_cull_handler()->record_object(object, _trav); + } +diff --git a/panda/src/tinydisplay/tinyGraphicsStateGuardian.cxx b/panda/src/tinydisplay/tinyGraphicsStateGuardian.cxx +index ba33377..af0a608 100644 +--- a/panda/src/tinydisplay/tinyGraphicsStateGuardian.cxx ++++ b/panda/src/tinydisplay/tinyGraphicsStateGuardian.cxx +@@ -206,7 +206,7 @@ clear(DrawableRegion *clearable) { + return; + } + +- set_state_and_transform(RenderState::make_empty(), _internal_transform); ++ set_state_and_transform(RenderState::make_empty(), _internal_transform, _prev_internal_transform); + + bool clear_color = false; + PIXEL color = 0; +@@ -1467,7 +1467,8 @@ framebuffer_copy_to_ram(Texture *tex, int view, int z, + */ + void TinyGraphicsStateGuardian:: + set_state_and_transform(const RenderState *target, +- const TransformState *transform) { ++ const TransformState *transform, ++ const TransformState *prev_transform) { + #ifndef NDEBUG + if (tinydisplay_cat.is_spam()) { + tinydisplay_cat.spam() +@@ -1480,6 +1481,8 @@ set_state_and_transform(const RenderState *target, + _state_pcollector.add_level(1); + PStatTimer timer1(_draw_set_state_pcollector); + ++ _prev_internal_transform = prev_transform; ++ + if (transform != _internal_transform) { + PStatTimer timer(_draw_set_state_transform_pcollector); + _state_pcollector.add_level(1); +diff --git a/panda/src/tinydisplay/tinyGraphicsStateGuardian.h b/panda/src/tinydisplay/tinyGraphicsStateGuardian.h +index 65e01d7..69f4ed9 100644 +--- a/panda/src/tinydisplay/tinyGraphicsStateGuardian.h ++++ b/panda/src/tinydisplay/tinyGraphicsStateGuardian.h +@@ -82,7 +82,8 @@ public: + (Texture *tex, int view, int z, const DisplayRegion *dr, const RenderBuffer &rb); + + virtual void set_state_and_transform(const RenderState *state, +- const TransformState *transform); ++ const TransformState *transform, ++ const TransformState *prev_transform); + + virtual TextureContext *prepare_texture(Texture *tex, int view); + virtual bool update_texture(TextureContext *tc, bool force); +-- +1.9.5.msysgit.0 + diff --git a/data/setup/check_requirements.py b/data/setup/check_requirements.py new file mode 100644 index 0000000..c0c93ea --- /dev/null +++ b/data/setup/check_requirements.py @@ -0,0 +1,58 @@ +""" + +RenderPipeline + +Copyright (c) 2014-2016 tobspr + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. + +""" + +from __future__ import print_function, division + +import os +import sys +from panda3d.core import * +from direct.showbase.ShowBase import ShowBase + +def _error(msg): + print("\n" * 4, file=sys.stderr) + print("ERROR:", msg, file=sys.stderr) + print("\n" * 4, file=sys.stderr) + sys.exit(1) + +class Application(ShowBase): + def __init__(self): + load_prc_file_data("", """ + window-type offscreen + win-size 100 100 + color-bits 0 + depth-bits 0 + back-buffers 0 + print-pipe-types #f + """) + ShowBase.__init__(self) + + if not self.win.gsg.supports_compute_shaders: + _error("Compute shaders not supported! Please update your driver, or get a newer gpu.") + + + print("All checks passed successfully") + +Application() diff --git a/effects/basic_instancing.yaml b/effects/basic_instancing.yaml new file mode 100644 index 0000000..650edee --- /dev/null +++ b/effects/basic_instancing.yaml @@ -0,0 +1,28 @@ + +# Terrain effect +# This effect uses prodecural shader splatting, you most likely want to modify +# it with your own texture-map generation code. + +vertex: + inout: | + uniform samplerBuffer InstancingData; + + + transform: | + + int data_index = gl_InstanceID * 4; + + vec4 data_0 = texelFetch(InstancingData, data_index); + vec4 data_1 = texelFetch(InstancingData, data_index + 1); + vec4 data_2 = texelFetch(InstancingData, data_index + 2); + vec4 data_3 = texelFetch(InstancingData, data_index + 3); + + mat4 transform_mat = mat4(data_0, data_1, data_2, data_3); + + vOutput.position = (transform_mat * p3d_Vertex).xyz; + // Also transform normal, not 100% correct but works out nicely + vOutput.normal = mat3(transform_mat) * vOutput.normal; + + +fragment: + diff --git a/effects/default.yaml b/effects/default.yaml new file mode 100644 index 0000000..9884cd1 --- /dev/null +++ b/effects/default.yaml @@ -0,0 +1,3 @@ + +# Default effect file, used for all objects if not overridden. +# This file actually contains no content, since no templates are overriden. diff --git a/effects/material_blend4.yaml b/effects/material_blend4.yaml new file mode 100644 index 0000000..fe9fe08 --- /dev/null +++ b/effects/material_blend4.yaml @@ -0,0 +1,89 @@ + + +# This effect blends 4 materials based on a material map +# The textures should be setup like in the 04-Material-Blending sample. + +# The last material is the base material and thus has no blending. It will +# be wherever no other material is. + +vertex: + +fragment: + inout: | + uniform sampler2D p3d_Texture0; // Alpha - Map + + uniform sampler2D p3d_Texture1; // M1 - Diffuse + uniform sampler2D p3d_Texture2; // M1 - Normal + uniform sampler2D p3d_Texture3; // M1 - Specular + uniform sampler2D p3d_Texture4; // M1 - Blendmap + + uniform sampler2D p3d_Texture5; // M2 - Diffuse + uniform sampler2D p3d_Texture6; // M2 - Normal + uniform sampler2D p3d_Texture7; // M2 - Specular + uniform sampler2D p3d_Texture8; // M2 - Blendmap + + uniform sampler2D p3d_Texture9; // M3 - Diffuse + uniform sampler2D p3d_Texture10; // M3 - Normal + uniform sampler2D p3d_Texture11; // M3 - Specular + uniform sampler2D p3d_Texture12; // M3 - Blendmap + + uniform sampler2D p3d_Texture13; // M4 - Diffuse + uniform sampler2D p3d_Texture14; // M4 - Normal + uniform sampler2D p3d_Texture15; // M4 - Specular + uniform sampler2D p3d_Texture16; // M4 - Blendmap + + uniform float detail_scale_factor; + + uniform float material_0_pow; + uniform float material_0_add; + uniform float material_1_pow; + uniform float material_1_add; + uniform float material_2_pow; + uniform float material_2_add; + + defines: | + #define DONT_FETCH_DEFAULT_TEXTURES 1 + #define DONT_SET_MATERIAL_PROPERTIES 1 + + material: | + + // Get detail coordinate + vec2 detail_coord = texcoord * detail_scale_factor; + vec4 layers = texture(p3d_Texture0, texcoord); + layers.xyz *= layers.w; + + // Blend all materials + layers.x = blend_material(layers.x, texture(p3d_Texture4, detail_coord).x, material_0_add, material_0_pow); + layers.y = blend_material(layers.y, texture(p3d_Texture8, detail_coord).x, material_1_add, material_1_pow); + layers.z = blend_material(layers.z, texture(p3d_Texture12, detail_coord).x, material_2_add, material_2_pow); + layers.w = saturate(1.0 - dot(layers.xyz, vec3(1))); // More inituitive + + // Diffuse + vec3 m_base = vec3(0); + m_base = texture(p3d_Texture1, detail_coord).xyz * layers.x; + m_base += texture(p3d_Texture5, detail_coord).xyz * layers.y; + m_base += texture(p3d_Texture9, detail_coord).xyz * layers.z; + m_base += texture(p3d_Texture13, detail_coord).xyz * layers.w; + + // Normal + vec3 m_nrm = vec3(0); + m_nrm += unpack_texture_normal(texture(p3d_Texture2, detail_coord).xyz) * layers.x; + m_nrm += unpack_texture_normal(texture(p3d_Texture6, detail_coord).xyz) * layers.y; + m_nrm += unpack_texture_normal(texture(p3d_Texture10, detail_coord).xyz) * layers.z; + m_nrm += unpack_texture_normal(texture(p3d_Texture14, detail_coord).xyz) * layers.w; + + // Specular + float spec = 0.0; + spec = texture(p3d_Texture3, detail_coord).x * layers.x; + spec += texture(p3d_Texture7, detail_coord).x * layers.y; + spec += texture(p3d_Texture11, detail_coord).x * layers.z; + spec += texture(p3d_Texture15, detail_coord).x * layers.w; + + // Material properties + m.shading_model = mInput.shading_model; + m.basecolor = m_base * mInput.color; + m.normal = apply_normal_map(vOutput.normal, m_nrm, mInput.normalfactor); + m.specular_ior = blend_ior(mInput.specular_ior, spec); + m.roughness = mInput.roughness; + m.metallic = mInput.metallic; + m.shading_model_param0 = mInput.arbitrary0; diff --git a/effects/skybox.yaml b/effects/skybox.yaml new file mode 100644 index 0000000..27d6667 --- /dev/null +++ b/effects/skybox.yaml @@ -0,0 +1,20 @@ + +# Skybox effect + +vertex: + transform: | + // vOutput.position.xy += MainSceneData.camera_pos.xy; + +fragment: + defines: | + #define DONT_FETCH_DEFAULT_TEXTURES 1 + #define DONT_SET_MATERIAL_PROPERTIES 1 + + material: | + m.basecolor = vec3(0); + m.shading_model = SHADING_MODEL_EMISSIVE; + m.specular_ior = 1.0; + m.metallic = 0.0; + m.roughness = 1.0; + m.shading_model_param0 = 0.0; + m.normal = vOutput.normal; diff --git a/effects/terrain-effect.yaml b/effects/terrain-effect.yaml new file mode 100644 index 0000000..f319755 --- /dev/null +++ b/effects/terrain-effect.yaml @@ -0,0 +1,142 @@ + +# Terrain effect +# This effect uses prodecural shader splatting, you most likely want to modify +# it with your own texture-map generation code. + +vertex: + inout: | + uniform struct { + sampler2D data_texture; + sampler2D heightfield; + int view_index; + int terrain_size; + int chunk_size; + } ShaderTerrainMesh; + out vec2 terrain_uv; + + transform: | + // Terrain data has the layout: + // x: x-pos, y: y-pos, z: size, w: clod + vec4 terrain_data = texelFetch(ShaderTerrainMesh.data_texture, + ivec2(gl_InstanceID, ShaderTerrainMesh.view_index), 0); + + // Get initial chunk position in the (0, 0, 0), (1, 1, 0) range + vec3 chunk_position = p3d_Vertex.xyz; + + // CLOD implementation + float clod_factor = smoothstep(0, 1, terrain_data.w); + chunk_position.xy -= clod_factor * fract(chunk_position.xy * ShaderTerrainMesh.chunk_size / 2.0) + * 2.0 / ShaderTerrainMesh.chunk_size; + + // Scale the chunk + chunk_position *= terrain_data.z * float(ShaderTerrainMesh.chunk_size) + / float(ShaderTerrainMesh.terrain_size); + chunk_position.z *= ShaderTerrainMesh.chunk_size; + + // Offset the chunk, it is important that this happens after the scale + chunk_position.xy += terrain_data.xy / float(ShaderTerrainMesh.terrain_size); + + // Compute the terrain UV coordinates + terrain_uv = chunk_position.xy; + + // Sample the heightfield and offset the terrain - we do not need to multiply + // the height with anything since the terrain transform is included in the + // model view projection matrix. + chunk_position.z += texture(ShaderTerrainMesh.heightfield, terrain_uv).x; + + // Lower the terrain on the borders - this ensures the shadow map is generated + // correctly. + if ( min(terrain_uv.x, terrain_uv.y) < 8.0 / ShaderTerrainMesh.terrain_size || + max(terrain_uv.x, terrain_uv.y) > 1 - 9.0 / ShaderTerrainMesh.terrain_size) { + chunk_position.z = 0; + } + + vOutput.position = (p3d_ModelMatrix * vec4(chunk_position, 1)).xyz; + +fragment: + defines: | + #define DONT_FETCH_DEFAULT_TEXTURES 1 + #define DONT_SET_MATERIAL_PROPERTIES 1 + + inout: | + layout(location=4) in vec2 terrain_uv; + layout(location=5) uniform struct { + sampler2D data_texture; + sampler2D heightfield; + int view_index; + int terrain_size; + int chunk_size; + } ShaderTerrainMesh; + + material: | + + // Compute terrain normal + const float terrain_height = 1000.0; + vec3 pixel_size = vec3(1.0, -1.0, 0) / textureSize(ShaderTerrainMesh.heightfield, 0).xxx; + float h_u0 = texture(ShaderTerrainMesh.heightfield, terrain_uv + pixel_size.yz).x * terrain_height; + float h_u1 = texture(ShaderTerrainMesh.heightfield, terrain_uv + pixel_size.xz).x * terrain_height; + float h_v0 = texture(ShaderTerrainMesh.heightfield, terrain_uv + pixel_size.zy).x * terrain_height; + float h_v1 = texture(ShaderTerrainMesh.heightfield, terrain_uv + pixel_size.zx).x * terrain_height; + vec3 tangent = normalize(vec3(1, 0, h_u1 - h_u0)); + vec3 binormal = normalize(vec3(0, 1, h_v1 - h_v0)); + vec3 normal = normalize(cross(tangent, binormal)); + + normal.x *= -1; + // normal.y *= -1; + + // Material splatting + float height = (h_u0 + h_u1 + h_v0 + h_v1) / (4.0 * terrain_height); // xxx + float slope = 1.0 - normal.z; + float grass = 0.0; + float rock = 0.0; + float snow = 0.0; + + { // Snow + snow = saturate(4.0 * (height-0.49)); + snow *= saturate(pow(saturate(1.0 - slope), 2.0)) * 12.0; + + //snow -= 0.6; + //snow *= 0.5; + snow = saturate(snow); + snow = pow(snow, 2.0); + } + + { // Rock + rock = saturate((pow(slope, 1.2) * 12.0 - 0.02) * 4.5); + } + + { // Grass + grass = 1.0 - saturate(rock + snow); + } + + + // Material definitions + + MaterialShaderOutput grass_mat = make_default_material_output(); + grass_mat.basecolor = vec3(0.1, 0.2, 0.1); + grass_mat.roughness = 0.8; + + MaterialShaderOutput rock_mat = make_default_material_output(); + rock_mat.basecolor = vec3(0.13); + rock_mat.roughness = 0.8; + rock_mat.specular_ior = 1.4; + + MaterialShaderOutput snow_mat = make_default_material_output(); + snow_mat.basecolor = vec3(0.6, 0.6, 0.9); + snow_mat.roughness = 0.5; + snow_mat.specular_ior = 1.7; + + m.basecolor = vec3(0); + m.shading_model = SHADING_MODEL_DEFAULT; + m.specular_ior = 0.0; + m.metallic = 0.0; + m.roughness = 0.0; + m.shading_model_param0 = 0.0; + m.normal = vec3(0); + + merge_material_output(m, grass_mat, grass); + merge_material_output(m, rock_mat, rock); + merge_material_output(m, snow_mat, snow); + + m.normal = normal; + diff --git a/fonts/monaco.ttf b/fonts/monaco.ttf new file mode 100644 index 0000000..57217b3 Binary files /dev/null and b/fonts/monaco.ttf differ diff --git a/fonts/msyh.ttc b/fonts/msyh.ttc new file mode 100644 index 0000000..ea174b2 Binary files /dev/null and b/fonts/msyh.ttc differ diff --git a/imgui.ini b/imgui.ini new file mode 100644 index 0000000..3962323 --- /dev/null +++ b/imgui.ini @@ -0,0 +1,10 @@ +[Window][Debug##Default] +Pos=9,11 +Size=400,400 +Collapsed=0 + +[Window][Hierarchy] +Pos=0,0 +Size=300,720 +Collapsed=0 + diff --git a/lui.pyd b/lui.pyd new file mode 100644 index 0000000..0c4dd5d Binary files /dev/null and b/lui.pyd differ diff --git a/main.py b/main.py new file mode 100644 index 0000000..486479c --- /dev/null +++ b/main.py @@ -0,0 +1,294 @@ +from panda3d.core import ConfigVariableString, NodePath,Filename,Material +from direct.showbase.ShowBase import ShowBase +import simplepbr +from rpcore.render_pipeline import RenderPipeline +import os,sys +import p3dimgui # Panda3D 的 ImGui 后端 +from imgui_bundle import ImVec2, imgui # ImGui API +from tools.picker_ray import PickerRay +import panda3d.core as p3d +from pathlib import Path + +sys.path.insert(0,os.path.dirname(__file__)) +sys.path.insert(0, str(Path(__file__).resolve().parent / "Builtin")) +from TransformGizmo.transform_gizmo import TransformGizmo +from tools.camera_orbit_controller import CameraOrbitController +from classes.cornerBBox import CornerBBox +from classes.colors import Color +from rpcore.rpobject import RPObject +from classes.gameobject import GameObject +from classes.point_marker import PointMarker + +import panda3d +import lui +panda3d.lui = lui +sys.modules["panda3d.lui"] = lui +from Builtin.LUIRegion import LUIRegion +from Builtin.LUIInputHandler import LUIInputHandler +from Builtin.LUIButton import LUIButton +from Builtin.LUISkin import LUIDefaultSkin + +class MainApp(ShowBase): + def __init__(self): + ConfigVariableString('win-size').set_value('1280 720') + # super().__init__() + + RPObject._OUTPUT_LEVEL = 1 + + self.render_pipeline = RenderPipeline() + self.render_pipeline.create(self) + + self.setFrameRateMeter(True) + + # 关闭窗口时确保主循环退出 + if self.win: + self.win.setCloseRequestEvent("app-exit") + self.accept("app-exit", self.on_exit) + + # 初始化 ImGui:挂在 pixel2d 上并注册渲染回调 + p3dimgui.init(window=self.win, parent=self.pixel2d, style='dark') + self.accept("imgui-new-frame", self.draw_imgui) + + self.font_en = None + self.font_cn = None + self.node_icon = None + self.node_icon_size = ImVec2(16, 16) + self._init_imgui_fonts() + self._load_node_icon() + + self.controller = CameraOrbitController(self) + self.gizmo = TransformGizmo(self) + + self.models_root = self.render.attach_new_node("models_root") + self.picker = PickerRay(self,self.models_root) + model_path = "assets/Fox.glb" + infile = Filename.from_os_specific(os.path.abspath(model_path)) + if os.path.exists(infile): + model: NodePath = self.loader.load_model(infile,noCache = True) + model.reparent_to(self.models_root) + GameObject.set_model_auto_scale(model) + mat = Material('unlit') + model.set_material(mat) + + self.controller.set_target(model) + + else: + print(f"模型路径不存在 -> {model_path}") + + self.accept("mouse1", self.picker_evt) + + self.corner_box:CornerBBox = None + + panel:NodePath = GameObject.create_panel() + panel.wrtReparentTo(self.models_root) + + self.marker = PointMarker(default_disable=True) + self._init_lui_button() + + # region_width = 1.0 + # region_height = (self.win.getYSize() - 48) / self.win.getYSize() + # dr = self.camNode.getDisplayRegion(0) + # dr.setDimensions(0, region_width, 0, region_height) + # # 鼠标坐标系跟随显示区域,否则拾取会偏移 + # self.mouseWatcherNode.setDisplayRegion(dr) + # self._apply_region_aspect(dr) + # # 窗口变化时同步刷新镜头纵横比,避免再次挤压/拉伸 + # self.accept("window-event", lambda win: self._apply_region_aspect(dr)) + + self.selected_node = None + self.hierarchy_size = ImVec2(300,0) + self.last_mouse_cursor = imgui.get_mouse_cursor() + + # props = p3d.WindowProperties() + # props.setCursorHidden(True) + # self.win.requestProperties(props) + # imgui.get_io().mouse_draw_cursor = True + + def _init_imgui_fonts(self): + # 为 ImGui 加载中英文字体,避免中文显示为方块 + io = imgui.get_io() + + # 英文字体:优先项目内提供,其次默认 + font_en_path = Path("fonts/monaco.ttf") + if font_en_path.exists(): + self.font_en = io.fonts.add_font_from_file_ttf(str(font_en_path), 18) + else: + self.font_en = io.fonts.add_font_default() + print(f'找不到英文字体文件 -> {font_en_path},已使用默认字体') + + # 中文字体:尝试多个常见路径,选第一个可用的 + candidate_cn_fonts = [ + Path("fonts/msyh.ttc"), + Path("fonts/SourceHanSansCN-Regular.otf"), + Path("fonts/SourceHanSansSC-Regular.otf"), + Path("fonts/simhei.ttf"), + Path("fonts/simsun.ttc"), + Path("C:/Windows/Fonts/msyh.ttc"), + Path("C:/Windows/Fonts/SimHei.ttf"), + Path("C:/Windows/Fonts/simsun.ttc"), + ] + cn_path = next((p for p in candidate_cn_fonts if p.exists()), None) + if cn_path: + cfg = imgui.ImFontConfig() + cfg.oversample_h = 2 + cfg.oversample_v = 2 + self.font_cn = io.fonts.add_font_from_file_ttf(str(cn_path), 18, cfg) + else: + self.font_cn = None + print("未找到可用的中文字体(尝试了项目 fonts/ 下和系统字体),中文可能显示为方框,请放入中文字体到 fonts/ 并重启程序。") + + def _init_lui_button(self): + """在右上角添加一个 LUI 按钮,演示 LUI 与现有管线共存。""" + # 创建 LUI 区域和输入处理 + self.lui_region = LUIRegion.make("LUI", self.win) + self.lui_handler = LUIInputHandler() + self.mouseWatcher.attach_new_node(self.lui_handler) + self.lui_region.set_input_handler(self.lui_handler) + # 提高显示区域排序,确保覆盖在 RenderPipeline 的最终合成之上 + self.lui_region.set_sort(8) + # 加载默认皮肤,保证按钮资源可用 + self.lui_skin = LUIDefaultSkin() + self.lui_skin.load() + # 在右上角放置按钮 + self.lui_button = LUIButton(parent=self.lui_region.root, text="LUI按钮", template="ButtonGreen") + self.lui_button.top = 20 + self.lui_button.right = 20 + self.lui_button.bind("click", lambda event: print("按钮被点击了", event)) + + def _load_node_icon(self): + icon_path = Path("assets/icons/model-color.png") + if not icon_path.exists(): + print(f"找不到层级树图标 -> {icon_path}") + return + + try: + self.node_icon = base.imgui.loadTexture(str(icon_path)) + except Exception as exc: + self.node_icon = None + print(f"加载层级树图标失败 -> {icon_path}: {exc}") + + def _apply_region_aspect(self, dr:p3d.DisplayRegion): + """根据显示区域的实际宽高比调整镜头,保持 3D 画面比例不变。""" + if not self.win or not dr: + return + win_w = self.win.getXSize() + win_h = self.win.getYSize() + if win_h == 0: + return + region_w = dr.getRight() - dr.getLeft() + region_h = dr.getTop() - dr.getBottom() + if region_h == 0: + return + region_aspect = (win_w / win_h) * (region_w / region_h) + self.camLens.setAspectRatio(region_aspect) + + def picker_evt(self): + # 如果 ImGui 捕获鼠标,则不执行 3D 拾取,避免 UI 上点击触发场景操作 + try: + if base.imgui.isMouseCaptured(): + # print("ImGui 捕获鼠标,不执行 3D 拾取") + return + except AttributeError: + pass + + if self.gizmo.is_hovering: + return + + if self.corner_box: + self.corner_box.remove() + + node,point = self.picker.pick_object() + self.controller.set_target(node) + + if node: + self.corner_box = CornerBBox(node) + self.gizmo.attach(node) + else: + self.gizmo.detach() + + if point: + self.marker.update_point(point) + else: + self.marker.hide() + + def draw_imgui(self): + io = imgui.get_io() + display_w, display_h = io.display_size + imgui.set_next_window_pos((0, 0), imgui.Cond_.always) + imgui.set_next_window_size((min(500,self.hierarchy_size.x), display_h), imgui.Cond_.always) + imgui.set_next_window_bg_alpha(1.0) + imgui.begin("Hierarchy", flags=imgui.WindowFlags_.no_collapse | imgui.WindowFlags_.no_move) + + imgui.push_style_var(imgui.StyleVar_.item_spacing, (4, 2)) # item之间间距 + imgui.push_style_var(imgui.StyleVar_.frame_padding, (0, 0)) # item内部padding + imgui.push_style_var(imgui.StyleVar_.indent_spacing, 10) # 缩进更紧 + imgui.push_font(self.font_cn,16) + self.draw_tree_node(self.render) + imgui.pop_font() + imgui.pop_style_var(3) + + self.hierarchy_size = imgui.get_window_size() + # if imgui.get_mouse_cursor() != self.last_mouse_cursor: + # self.last_mouse_cursor = imgui.get_mouse_cursor() + # print(f"设置鼠标光标 -> {self.last_mouse_cursor}") + imgui.end() + + def draw_tree_node(self, node: NodePath): + children = node.getChildren() + has_children = len(children) > 0 + + # --- 图标 --- + if self.node_icon: + imgui.image(self.node_icon, self.node_icon_size, (1, 1), (0, 0)) + imgui.same_line() + + label = f'{node.getName()} [{GameObject.get_node_type(node)}]' + + # ✅ 叶子节点:不用 tree_node_ex,完全无占位 + if not has_children: + clicked, _ = imgui.selectable( + label, + p_selected=(node == self.selected_node), + flags=imgui.SelectableFlags_.span_all_columns | + imgui.SelectableFlags_.allow_double_click + ) + if clicked: + self.selected_node = node + if imgui.is_mouse_double_clicked(imgui.MouseButton_.left): + # print(f"双击了节点 -> {node.getName()}") + pass + return + + # --- 有子节点的才使用 tree node --- + flags = ( + imgui.TreeNodeFlags_.open_on_arrow | + imgui.TreeNodeFlags_.span_avail_width | + imgui.TreeNodeFlags_.open_on_double_click + ) + + if node == self.selected_node: + flags |= imgui.TreeNodeFlags_.selected + + if node.getName() == 'render': + imgui.set_next_item_open(True, imgui.Cond_.first_use_ever) + + opened = imgui.tree_node_ex(label, flags) + + if imgui.is_item_clicked(imgui.MouseButton_.left): + self.selected_node = node + + if opened: + for child in children: + self.draw_tree_node(child) + imgui.tree_pop() + + + def on_exit(self): + """关闭窗口时清理 ImGui 上下文并退出应用。""" + try: + self.imgui.cleanup() + except Exception: + pass + self.userExit() + +MainApp().run() diff --git a/rpcore/__init__.py b/rpcore/__init__.py new file mode 100644 index 0000000..a10088a --- /dev/null +++ b/rpcore/__init__.py @@ -0,0 +1,47 @@ +""" + +RenderPipeline + +Copyright (c) 2014-2016 tobspr + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. + +""" + +# flake8: noqa + +__all__ = ("RenderPipeline", "SpotLight", "PointLight") + +# This file includes all classes from the pipeline which are exposed +from rpcore.render_pipeline import RenderPipeline +from rpcore.native import SpotLight, PointLight + +# Polyfill a set_shader_inputs function for older versions of Panda. +from panda3d.core import NodePath +from direct.extensions_native.extension_native_helpers import Dtool_funcToMethod +from rplibs.six import iteritems + +if not hasattr(NodePath, 'set_shader_inputs'): + def set_shader_inputs(self, **inputs): + set_shader_input = self.set_shader_input + for args in iteritems(inputs): + set_shader_input(*args) + + Dtool_funcToMethod(set_shader_inputs, NodePath) + del set_shader_inputs diff --git a/rpcore/common_resources.py b/rpcore/common_resources.py new file mode 100644 index 0000000..94b9fce --- /dev/null +++ b/rpcore/common_resources.py @@ -0,0 +1,245 @@ +""" + +RenderPipeline + +Copyright (c) 2014-2016 tobspr + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. + +""" + +from __future__ import division + +from panda3d.core import CS_yup_right, CS_zup_right, invert, Vec3, Mat4, Vec4 +from panda3d.core import SamplerState +from direct.stdpy.file import open + +from rpcore.globals import Globals +from rpcore.rpobject import RPObject +from rpcore.loader import RPLoader + +from rpcore.util.shader_input_blocks import GroupedInputBlock + + +class CommonResources(RPObject): + + """ This class manages the loading and binding of commonly used resources, + such as textures, models, but also shader inputs """ + + def __init__(self, pipeline): + RPObject.__init__(self) + self._pipeline = pipeline + self._showbase = Globals.base + self._ptas = {} + self._load_fonts() + self._load_textures() + self._setup_inputs() + + def _load_fonts(self): + """ Loads the default font used for rendering and assigns it to + Globals.font for further usage """ + font = RPLoader.load_font("/$$rp/data/font/Roboto-Medium.ttf") + font.set_pixels_per_unit(35) + font.set_poly_margin(0.0) + font.set_texture_margin(1) + font.set_bg(Vec4(1, 1, 1, 0)) + font.set_fg(Vec4(1, 1, 1, 1)) + Globals.font = font + + def _setup_inputs(self): + """ Creates commonly used shader inputs such as the current mvp and + registers them to the stage manager so they can be used for rendering """ + + self._input_ubo = GroupedInputBlock("MainSceneData") + inputs = ( + ("camera_pos", "vec3"), + ("view_proj_mat_no_jitter", "mat4"), + ("last_view_proj_mat_no_jitter", "mat4"), + ("last_inv_view_proj_mat_no_jitter", "mat4"), + ("view_mat_z_up", "mat4"), + ("proj_mat", "mat4"), + ("inv_proj_mat", "mat4"), + ("view_mat_billboard", "mat4"), + ("frame_delta", "float"), + ("smooth_frame_delta", "float"), + ("frame_time", "float"), + ("current_film_offset", "vec2"), + ("frame_index", "int"), + ("screen_size", "ivec2"), + ("native_screen_size", "ivec2"), + ("lc_tile_count", "ivec2"), + ("ws_frustum_directions", "mat4"), + ("vs_frustum_directions", "mat4"), + ) + for name, ipt_type in inputs: + self._input_ubo.register_pta(name, ipt_type) + + self._pipeline.stage_mgr.input_blocks.append(self._input_ubo) + + # Main camera and main render have to be regular inputs, since they are + # used in the shaders by that name. + self._pipeline.stage_mgr.inputs["mainCam"] = self._showbase.cam + self._pipeline.stage_mgr.inputs["mainRender"] = self._showbase.render + + # Set the correct frame rate interval + Globals.clock.set_average_frame_rate_interval(3.0) + + # Set initial value for view_proj_mat_no_jitter + view_mat = Globals.render.get_transform(self._showbase.cam).get_mat() + proj_mat = Mat4(self._showbase.camLens.get_projection_mat()) + proj_mat.set_cell(1, 0, 0.0) + proj_mat.set_cell(1, 1, 0.0) + self._input_ubo.update_input("view_proj_mat_no_jitter", view_mat * proj_mat) + + def write_config(self): + """ Generates the shader configuration for the common inputs """ + content = self._input_ubo.generate_shader_code() + try: + # Try to write the temporary file + with open("/$$rptemp/$$main_scene_data.inc.glsl", "w") as handle: + handle.write(content) + except IOError as msg: + self.error("Failed to write common resources shader configuration!", msg) + + def _load_textures(self): + """ Loads commonly used textures and makes them available via the + stage manager """ + self._load_environment_cubemap() + self._load_prefilter_brdf() + self._load_skydome() + + def _load_environment_cubemap(self): + """ Loads the default cubemap used for the environment, which is used + when no other environment data is available """ + envmap = RPLoader.load_cube_map("/$$rp/data/default_cubemap/cubemap1.txo", read_mipmaps=True) + envmap.set_minfilter(SamplerState.FT_linear_mipmap_linear) + # envmap.set_format(Image.F_rgba16) + envmap.set_magfilter(SamplerState.FT_linear) + envmap.set_wrap_u(SamplerState.WM_repeat) + envmap.set_wrap_v(SamplerState.WM_repeat) + envmap.set_wrap_w(SamplerState.WM_repeat) + self._pipeline.stage_mgr.inputs["DefaultEnvmap"] = envmap + + def _load_prefilter_brdf(self): + """ Loads the prefiltered brdf """ + luts = [ + {"src": "slices/env_brdf_#.png", "input": "PrefilteredBRDF"}, + {"src": "slices_metal/env_brdf.png", "input": "PrefilteredMetalBRDF"}, + {"src": "slices_coat/env_brdf.png", "input": "PrefilteredCoatBRDF"}, + ] + + for config in luts: + loader_method = RPLoader.load_texture + if "#" in config["src"]: + loader_method = RPLoader.load_3d_texture + + brdf_tex = loader_method("/$$rp/data/environment_brdf/{}".format(config["src"])) + brdf_tex.set_minfilter(SamplerState.FT_linear) + brdf_tex.set_magfilter(SamplerState.FT_linear) + brdf_tex.set_wrap_u(SamplerState.WM_clamp) + brdf_tex.set_wrap_v(SamplerState.WM_clamp) + brdf_tex.set_wrap_w(SamplerState.WM_clamp) + brdf_tex.set_anisotropic_degree(0) + self._pipeline.stage_mgr.inputs[config["input"]] = brdf_tex + + def _load_skydome(self): + """ Loads the skydome """ + skydome = RPLoader.load_texture("/$$rp/data/builtin_models/skybox/skybox.txo") + skydome.set_wrap_u(SamplerState.WM_clamp) + skydome.set_wrap_v(SamplerState.WM_clamp) + self._pipeline.stage_mgr.inputs["DefaultSkydome"] = skydome + + def load_default_skybox(self): + skybox = RPLoader.load_model("/$$rp/data/builtin_models/skybox/skybox.bam") + return skybox + + def update(self): + """ Updates the commonly used resources, mostly the shader inputs """ + update = self._input_ubo.update_input + + # Get the current transform matrix of the camera + view_mat = Globals.render.get_transform(self._showbase.cam).get_mat() + + # Compute the view matrix, but with a z-up coordinate system + zup_conversion = Mat4.convert_mat(CS_zup_right, CS_yup_right) + update("view_mat_z_up", view_mat * zup_conversion) + + # Compute the view matrix without the camera rotation + view_mat_billboard = Mat4(view_mat) + view_mat_billboard.set_row(0, Vec3(1, 0, 0)) + view_mat_billboard.set_row(1, Vec3(0, 1, 0)) + view_mat_billboard.set_row(2, Vec3(0, 0, 1)) + update("view_mat_billboard", view_mat_billboard) + + update("camera_pos", self._showbase.camera.get_pos(Globals.render)) + + # Compute last view projection mat + curr_vp = self._input_ubo.get_input("view_proj_mat_no_jitter") + update("last_view_proj_mat_no_jitter", curr_vp) + curr_vp = Mat4(curr_vp) + curr_vp.invert_in_place() + curr_inv_vp = curr_vp + update("last_inv_view_proj_mat_no_jitter", curr_inv_vp) + + proj_mat = Mat4(self._showbase.camLens.get_projection_mat()) + + # Set the projection matrix as an input, but convert it to the correct + # coordinate system before. + proj_mat_zup = Mat4.convert_mat(CS_yup_right, CS_zup_right) * proj_mat + update("proj_mat", proj_mat_zup) + + # Set the inverse projection matrix + update("inv_proj_mat", invert(proj_mat_zup)) + + # Remove jitter and set the new view projection mat + proj_mat.set_cell(1, 0, 0.0) + proj_mat.set_cell(1, 1, 0.0) + update("view_proj_mat_no_jitter", view_mat * proj_mat) + + # Store the frame delta + update("frame_delta", Globals.clock.get_dt()) + update("smooth_frame_delta", 1.0 / max(1e-5, Globals.clock.get_average_frame_rate())) + update("frame_time", Globals.clock.get_frame_time()) + + # Store the current film offset, we use this to compute the pixel-perfect + # velocity, which is otherwise not possible. Usually this is always 0 + # except when SMAA and reprojection is enabled + update("current_film_offset", self._showbase.camLens.get_film_offset()) + update("frame_index", Globals.clock.get_frame_count()) + + # Compute frustum corners in the order BL, BR, TL, TR + ws_frustum_directions = Mat4() + vs_frustum_directions = Mat4() + inv_proj_mat = Globals.base.camLens.get_projection_mat_inv() + view_mat_inv = Mat4(view_mat) + view_mat_inv.invert_in_place() + + for i, point in enumerate(((-1, -1), (1, -1), (-1, 1), (1, 1))): + result = inv_proj_mat.xform(Vec4(point[0], point[1], 1.0, 1.0)) + vs_dir = (zup_conversion.xform(result)).xyz.normalized() + vs_frustum_directions.set_row(i, Vec4(vs_dir, 1)) + ws_dir = view_mat_inv.xform(Vec4(result.xyz, 0)) + ws_frustum_directions.set_row(i, ws_dir) + + update("vs_frustum_directions", vs_frustum_directions) + update("ws_frustum_directions", ws_frustum_directions) + + update("screen_size", Globals.resolution) + update("native_screen_size", Globals.native_resolution) + update("lc_tile_count", self._pipeline.light_mgr.num_tiles) diff --git a/rpcore/effect.py b/rpcore/effect.py new file mode 100644 index 0000000..a84e3eb --- /dev/null +++ b/rpcore/effect.py @@ -0,0 +1,307 @@ +""" + +RenderPipeline + +Copyright (c) 2014-2016 tobspr + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. + +""" + +from rplibs.six import iteritems, iterkeys +from rplibs.yaml import load_yaml_file + +from panda3d.core import Filename +from direct.stdpy.file import open + +from rpcore.rpobject import RPObject +from rpcore.loader import RPLoader + + +class Effect(RPObject): + + """ This class represents an instance of a compiled effect. It can be loaded + from a file. """ + + # Configuration options which can be set per effect instance. These control + # which features are available in the effect, and which passes to render. + _DEFAULT_OPTIONS = { + "render_gbuffer": True, + "render_shadow": True, + "render_voxelize": True, + "render_envmap": True, + "render_forward": False, + "alpha_testing": True, + "normal_mapping": True, + "parallax_mapping": False, + } + + # All supported render passes, should match the available passes in the + # TagStateManager class. + _PASSES = ("gbuffer", "shadow", "voxelize", "envmap", "forward") + + # Effects are cached based on their source filename and options, this is + # the cache where compiled are effects stored. + _GLOBAL_CACHE = {} + + # Global counter to store the amount of generated effects, used to create + # a unique id used for writing temporary files. + _EFFECT_ID = 0 + + @classmethod + def load(cls, filename, options): + """ Loads an effect from a given filename with the specified options. + This lookups in the global effect cache, and checks if a similar effect + (i.e. with the same hash) was already loaded, and in that case returns it. + Otherwise a new effect with the given options is created. """ + effect_hash = cls._generate_hash(filename, options) + if effect_hash in cls._GLOBAL_CACHE: + return cls._GLOBAL_CACHE[effect_hash] + effect = cls() + effect.set_options(options) + if not effect.do_load(filename): + RPObject.global_error("Effect", "Could not load effect!") + return None + return effect + + @classmethod + def _generate_hash(cls, filename, options): + """ Generates an unique hash for the effect. The effect hash is based + on the filename and the configured options, and is ensured to make the + effect unique. This is important to make sure the caching works as + intended. All options not present in options are set to the default value""" + + # Set all options which are not present in the dict to its defaults + options = {k: options.get(k, v) for k, v in iteritems(cls._DEFAULT_OPTIONS)} + + # Hash filename, make sure it has the right format and also resolve + # it to an absolute path, to make sure that relative paths are cached + # correctly (otherwise, specifying a different path to the same file + # will cause a cache miss) + filename = Filename(filename) + filename.make_absolute() + file_hash = str(hash(filename.to_os_generic())) + + # Hash the options, that is, sort the keys to make sure the values + # are always in the same order, and then convert the flags to strings using + # '1' for a set flag, and '0' for a unset flag + options_hash = "".join(["1" if options[key] else "0" for key in sorted(iterkeys(options))]) + return file_hash + "-" + options_hash + + def __init__(self): + """ Constructs a new empty effect, this is a private constructor and + should not be called. Instead, use Effect.load() """ + RPObject.__init__(self) + self.effect_id = Effect._EFFECT_ID + Effect._EFFECT_ID += 1 + self.filename = None + self._options = self._DEFAULT_OPTIONS.copy() + self._generated_shader_paths = {} + self._shader_objs = {} + + def get_option(self, name): + """ Returns a given option value by name """ + return self._options[name] + + def set_options(self, options): + """ Sets the effect options, overriding the default options """ + for key, val in iteritems(options): + if key not in self._options: + self.error("Unkown option:", key) + continue + self._options[key] = val + + def do_load(self, filename): + """ Internal method to load the effect from the given filename, do + not use this directly, instead use load(). """ + self.filename = filename + self.effect_name = self._convert_filename_to_name(filename) + self.effect_hash = self._generate_hash(filename, self._options) + + # Load the YAML file + parsed_yaml = load_yaml_file(filename) or {} + self._parse_content(parsed_yaml) + + # Construct a shader object for each pass + for pass_id in self._PASSES: + vertex_src = self._generated_shader_paths["vertex-" + pass_id] + fragment_src = self._generated_shader_paths["fragment-" + pass_id] + self._shader_objs[pass_id] = RPLoader.load_shader(vertex_src, fragment_src) + return True + + def get_shader_obj(self, pass_id): + """ Returns a handle to the compiled shader object for a given render + pass. """ + if pass_id not in self._shader_objs: + self.warn("Pass '" + pass_id + "' not found!") + return False + return self._shader_objs[pass_id] + + def _convert_filename_to_name(self, filename): + """ Constructs an effect name from a filename, this is used for writing + out temporary files """ + return filename.replace(".yaml", "").replace("effects/", "")\ + .replace("/", "_").replace("\\", "_").replace(".", "-") + + def _parse_content(self, parsed_yaml): + """ Internal method to construct the effect from a yaml object """ + vtx_data = parsed_yaml.get("vertex", None) or {} + frag_data = parsed_yaml.get("fragment", None) or {} + + for pass_id in self._PASSES: + self._parse_shader_template(pass_id, "vertex", vtx_data) + self._parse_shader_template(pass_id, "fragment", frag_data) + + def _parse_shader_template(self, pass_id, stage, data): + """ Parses a fragment template. This just finds the default template + for the shader, and redirects that to construct_shader_from_data """ + if stage == "fragment": + shader_ext = {"vertex": "vert", "fragment": "frag"}[stage] + template_src = "/$$rp/shader/templates/{}.{}.glsl".format(pass_id, shader_ext) + elif stage == "vertex": + # Using a shared vertex shader + template_src = "/$$rp/shader/templates/vertex.vert.glsl" + + shader_path = self._construct_shader_from_data(pass_id, stage, template_src, data) + self._generated_shader_paths[stage + "-" + pass_id] = shader_path + + def _construct_shader_from_data(self, pass_id, stage, template_src, data): # noqa # pylint: disable=too-many-branches + """ Constructs a shader from a given dataset """ + injects = {"defines": []} + + for key, val in iteritems(self._options): + if isinstance(val, bool): + val_str = "1" if val else "0" + else: + val_str = str(val) + injects["defines"].append("#define OPT_{} {}".format(key.upper(), val_str)) + + injects["defines"].append("#define IN_" + stage.upper() + "_SHADER 1") + injects["defines"].append("#define IN_" + pass_id.upper() + "_SHADER 1") + injects["defines"].append("#define IN_RENDERING_PASS 1") + + # Parse dependencies + if "dependencies" in data: + injects["includes"] = [] + for dependency in data["dependencies"]: + include_str = "#pragma include \"{}\"".format(dependency) + injects["includes"].append(include_str) + del data["dependencies"] + + # Append aditional injects + for key, val in iteritems(data): + if val is None: + self.warn("Empty insertion: '" + key + "'") + continue + + if isinstance(val, (list, tuple)): + self.warn("Invalid syntax, you used a list but you should have used a string:") + self.warn(val) + continue + injects[key] = injects.get(key, []) + [i for i in val.split("\n")] + + cache_key = self.effect_name + "@" + stage + "-" + pass_id + "@" + self.effect_hash + return self._process_shader_template(template_src, cache_key, injects) + + def _process_shader_template(self, template_src, cache_key, injections): # noqa # pylint: disable=too-many-branches + """ Generates a compiled shader object from a given shader + source location and code injection definitions. """ + with open(template_src, "r") as handle: + shader_lines = handle.readlines() + + parsed_lines = ["\n\n"] + addline = parsed_lines.append + + addline("/* Compiled Shader Template") + addline(" * generated from: '" + template_src + "'") + addline(" * cache key: '" + cache_key + "'") + addline(" *") + addline(" * !!! Autogenerated, do not edit! Your changes will be lost. !!!") + addline(" */\n\n") + + # Store whether we are in the main function already - we need this + # to properly insert scoped code blocks + in_main = False + + for line in shader_lines: # pylint: disable=too-many-nested-blocks + stripped_line = line.strip().lower() + + # Check if we are already in the main function + if "void main()" in stripped_line: + in_main = True + + # Check if the current line is a hook + if stripped_line.startswith("%") and stripped_line.endswith("%"): + + # If the line is a hook, get the hook name and save the + # indent so we can indent all injected lines properly. + hook_name = stripped_line[1:-1] + indent = " " * (len(line) - len(line.lstrip())) + + # Inject all registered template values into the hook + if hook_name in injections: + + # Directly remove the value from the list so we can check which + # hooks were not found in the template + insertions = injections.pop(hook_name) + + if len(insertions) > 0: + + # When we are in the main function, we have to make sure we + # use a seperate scope, so there are no conflicts with variable + # declarations + header = indent + "/* Hook: " + hook_name + " */" + (" {" if in_main else "") # noqa # pylint: disable=line-too-long + addline(header) + + for line_to_insert in insertions: + if line_to_insert is None: + self.warn("Empty insertion '" + hook_name + "'") + continue + + if not isinstance(line_to_insert, str): + self.warn("Invalid line type: ", line_to_insert) + continue + + # Dont indent defines and pragmas + if line_to_insert.startswith("#"): + addline(line_to_insert) + else: + addline(indent + line_to_insert) + + if in_main: + addline(indent + "}") + + else: + addline(line.rstrip()) + + # Add a closing newline to the file + addline("") + + # Warn the user about all unused hooks + for key in injections: + self.warn("Hook '" + key + "' not found in template '" + template_src + "'!") + + # Write the constructed shader and load it back + shader_content = "\n".join(parsed_lines) + temp_path = "/$$rptemp/$$effect-" + cache_key + ".glsl" + + with open(temp_path, "w") as handle: + handle.write(shader_content) + + return temp_path diff --git a/rpcore/globals.py b/rpcore/globals.py new file mode 100644 index 0000000..11b4a75 --- /dev/null +++ b/rpcore/globals.py @@ -0,0 +1,47 @@ +""" + +RenderPipeline + +Copyright (c) 2014-2016 tobspr + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. + +""" + +__all__ = ("Globals",) + + +class Globals(object): # pylint: disable=too-few-public-methods + + """ This class is a singleton to store globals widely used by the application. + This is a wrapper around Panda3D's globals since ShowBase writes to __builtins__ + which is bad practice. This class also attempts to help IDEs to figure out + where the variables come from and where they are defined. """ + + __init__ = None + + @staticmethod + def load(showbase): + """ Loads the globals from a given showbase """ + Globals.base = showbase + Globals.render = showbase.render + Globals.clock = showbase.taskMgr.globalClock + Globals.font = None + Globals.resolution = None + Globals.native_resolution = None diff --git a/rpcore/gpu_command_queue.py b/rpcore/gpu_command_queue.py new file mode 100644 index 0000000..9bfe17a --- /dev/null +++ b/rpcore/gpu_command_queue.py @@ -0,0 +1,117 @@ +""" + +RenderPipeline + +Copyright (c) 2014-2016 tobspr + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. + +""" + +from panda3d.core import PTAInt + +from rpcore.image import Image +from rpcore.rpobject import RPObject +from rpcore.loader import RPLoader +from rpcore.render_target import RenderTarget + +from rpcore.native import GPUCommand, GPUCommandList + + +class GPUCommandQueue(RPObject): + + """ This class offers an interface to the gpu, allowing commands to be + pushed to a queue which then get executed on the gpu """ + + def __init__(self, pipeline): + RPObject.__init__(self) + self._pipeline = pipeline + self._commands_per_frame = 1024 + self._command_list = GPUCommandList() + self._pta_num_commands = PTAInt.empty_array(1) + self._create_data_storage() + self._create_command_target() + self._commands = [] + self._register_defines() + + def clear_queue(self): + """ Clears all commands currently being in the queue """ + raise NotImplementedError() + + @property + def command_list(self): + """ Returns a handle to the command list """ + return self._command_list + + @property + def num_queued_commands(self): + """ Returns the amount of queued commands, which are waiting to get + executed on the gpu. This might be zero a lot of the time, because the + GPUCommandList clears the queue after executing, so you have to call + this after work was submitted. """ + return self._command_list.num_commands + + @property + def num_processed_commands(self): + """ Returns the amount of commands processed the last time when the + command queue was updated """ + return self._pta_num_commands[0] + + def process_queue(self): + """ Processes the n first commands of the queue """ + pointer = self._data_texture.modify_ram_image() + num_commands_exec = self._command_list.write_commands_to( + pointer, self._commands_per_frame) + self._pta_num_commands[0] = num_commands_exec + + def reload_shaders(self): + """ Reloads the command shader """ + shader = RPLoader.load_shader( + "/$$rp/shader/default_post_process.vert.glsl", + "/$$rp/shader/process_command_queue.frag.glsl") + self._command_target.shader = shader + + def register_input(self, key, val): + """ Registers an new shader input to the command target """ + self._command_target.set_shader_input(key, val) + + def _register_defines(self): + """ Registers all the command types as defines so they can be used + in a shader later on """ + for attr in dir(GPUCommand): + if attr.startswith("CMD_"): + attr_val = getattr(GPUCommand, attr) + self._pipeline.stage_mgr.defines[attr] = attr_val + self._pipeline.stage_mgr.defines["GPU_CMD_INT_AS_FLOAT"] = \ + GPUCommand.get_uses_integer_packing() + + def _create_data_storage(self): + """ Creates the buffer used to transfer commands """ + command_buffer_size = self._commands_per_frame * 32 + self.debug("Allocating command buffer of size", command_buffer_size) + self._data_texture = Image.create_buffer("CommandQueue", command_buffer_size, "R32") + + def _create_command_target(self): + """ Creates the target which processes the commands """ + self._command_target = RenderTarget("ExecCommandTarget") + self._command_target.size = 1, 1 + self._command_target.prepare_buffer() + self._command_target.set_shader_inputs( + CommandQueue=self._data_texture, + commandCount=self._pta_num_commands) diff --git a/rpcore/gui/README.md b/rpcore/gui/README.md new file mode 100644 index 0000000..acbc2eb --- /dev/null +++ b/rpcore/gui/README.md @@ -0,0 +1,6 @@ + +## rp-gui + +This folder only contains helper classes for the pipeline gui. +It is not really part of the pipeline, and thus also does not follow the +pipeline code conventions. diff --git a/rpcore/gui/__init__.py b/rpcore/gui/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/rpcore/gui/buffer_viewer.py b/rpcore/gui/buffer_viewer.py new file mode 100644 index 0000000..5dc59a9 --- /dev/null +++ b/rpcore/gui/buffer_viewer.py @@ -0,0 +1,255 @@ +""" + +RenderPipeline + +Copyright (c) 2014-2016 tobspr + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. + +""" + +from __future__ import division +from functools import partial + +from panda3d.core import Texture, Vec3 + +from direct.gui.DirectFrame import DirectFrame +from direct.gui.DirectGui import DGG +from direct.gui.DirectScrolledFrame import DirectScrolledFrame + +from rplibs.six import itervalues + +from rpcore.image import Image +from rpcore.util.display_shader_builder import DisplayShaderBuilder +from rpcore.globals import Globals +from rpcore.render_target import RenderTarget +from rpcore.gui.texture_preview import TexturePreview +from rpcore.gui.sprite import Sprite +from rpcore.gui.labeled_checkbox import LabeledCheckbox +from rpcore.gui.text import Text +from rpcore.gui.draggable_window import DraggableWindow + + +class BufferViewer(DraggableWindow): + + """ This class provides a view into the buffers to inspect them """ + + def __init__(self, pipeline, parent): + """ Constructs the buffer viewer """ + DraggableWindow.__init__(self, width=1400, height=800, parent=parent, + title="Buffer- and Image-Browser") + self._pipeline = pipeline + self._scroll_height = 3000 + self._display_images = False + self._stages = [] + self._create_components() + self._tex_preview = TexturePreview(self._pipeline, parent) + self._tex_preview.hide() + self.hide() + + def toggle(self): + """ Updates all the buffers and then toggles the buffer viewer """ + if self._visible: + self._remove_components() + self.hide() + else: + self._perform_update() + self.show() + + @property + def entries(self): + """ Returns a list of all registered entries """ + return RenderTarget.REGISTERED_TARGETS + Image.REGISTERED_IMAGES + + @property + def stage_information(self): + """ Returns the amount of attached stages, and also the memory consumed + in MiB in a tuple. """ + count, memory = 0, 0 + for entry in self.entries: + if isinstance(entry, Texture): + memory += entry.estimate_texture_memory() + count += 1 + elif entry.__class__.__name__ == "RenderTarget": + for target in itervalues(entry.targets): + memory += target.estimate_texture_memory() + count += 1 + else: + self.warn("Unkown type:", entry.__class__.__name__) + return memory, count + + def _create_components(self): + """ Creates the window components """ + DraggableWindow._create_components(self) + + self._content_frame = DirectScrolledFrame( + frameSize=(0, self._width - 15, 0, self._height - 70), + canvasSize=(0, self._width - 80, 0, self._scroll_height), + autoHideScrollBars=False, + scrollBarWidth=12.0, + frameColor=(0, 0, 0, 0), + verticalScroll_relief=DGG.FLAT, + verticalScroll_incButton_relief=DGG.FLAT, + verticalScroll_decButton_relief=DGG.FLAT, + verticalScroll_thumb_relief=DGG.FLAT, + verticalScroll_frameColor=(0.05, 0.05, 0.05, 1), + verticalScroll_thumb_frameColor=(0.8, 0.8, 0.8, 1), + verticalScroll_incButton_frameColor=(0.6, 0.6, 0.6, 1), + verticalScroll_decButton_frameColor=(0.6, 0.6, 0.6, 1), + horizontalScroll_frameColor=(0, 0, 0, 0), + horizontalScroll_relief=False, + horizontalScroll_thumb_relief=False, + horizontalScroll_incButton_relief=False, + horizontalScroll_decButton_relief=False, + parent=self._node, + pos=(0, 1, -self._height)) + self._content_node = self._content_frame.getCanvas().attach_new_node( + "BufferComponents") + self._content_node.set_scale(1, 1, -1) + self._content_node.set_z(self._scroll_height) + self._chb_show_images = LabeledCheckbox( + parent=self._node, x=10, y=43, chb_callback=self._set_show_images, + chb_checked=False, text="Display image resources", + text_color=Vec3(0.4), expand_width=330) + + def _set_show_images(self, arg): + """ Sets whether images and textures will be shown """ + self._display_images = arg + self._perform_update() + + def _set_scroll_height(self, height): + """ Sets the maximum scroll height in the content frame """ + self._scroll_height = height + self._content_frame["canvasSize"] = (0, self._width - 80, 0, self._scroll_height) + self._content_node.set_z(self._scroll_height) + + def _remove_components(self): + """ Removes all components of the buffer viewer """ + self._content_node.node().remove_all_children() + self._tex_preview.hide() + + def _perform_update(self): + """ Collects all entries, extracts their images and re-renders the + window """ + + # Collect texture stages + self._stages = [] + for entry in sorted(self.entries, key=lambda entry: entry.sort): + if isinstance(entry, Texture): + if self._display_images: + self._stages.append(entry) + # Can not use isinstance or we get circular import references + elif entry.__class__.__name__ == "RenderTarget": + for target in itervalues(entry.targets): + self._stages.append(target) + else: + self.warn("Unrecognized instance!", entry.__class__) + + self._render_stages() + + def _on_texture_hovered(self, hover_frame, evt=None): # pylint: disable=unused-argument + """ Internal method when a texture is hovered """ + hover_frame["frameColor"] = (0, 0, 0, 0.1) + + def _on_texture_blurred(self, hover_frame, evt=None): # pylint: disable=unused-argument + """ Internal method when a texture is blurred """ + hover_frame["frameColor"] = (0, 0, 0, 0) + + def _on_texture_clicked(self, tex_handle, evt=None): # pylint: disable=unused-argument + """ Internal method when a texture is blurred """ + self._tex_preview.present(tex_handle) + + def _render_stages(self): + """ Renders the stages to the window """ + + self._remove_components() + entries_per_row = 6 + aspect = Globals.native_resolution.y / Globals.native_resolution.x + entry_width = 235 + entry_height = (entry_width - 20) * aspect + 55 + + # Store already processed images + processed = set() + index = -1 + # Iterate over all stages + for stage_tex in self._stages: + if stage_tex in processed: + continue + processed.add(stage_tex) + index += 1 + stage_name = stage_tex.get_name() + + xoffs = index % entries_per_row + yoffs = index // entries_per_row + node = self._content_node.attach_new_node("Preview") + node.set_sz(-1) + node.set_pos(10 + xoffs * (entry_width - 14), 1, yoffs * (entry_height - 14 + 10)) + + r, g, b = 0.2, 0.2, 0.2 + if isinstance(stage_tex, Image): + r, g, b = 0.2, 0.4, 0.6 + + stage_name = stage_name.replace("render_pipeline_internal:", "") + parts = stage_name.split(":") + stage_name = parts[-1] + DirectFrame( + parent=node, frameSize=(7, entry_width - 17, -7, -entry_height + 17), + frameColor=(r, g, b, 1.0), pos=(0, 0, 0)) + + frame_hover = DirectFrame( + parent=node, frameSize=(0, entry_width - 10, 0, -entry_height + 10), + frameColor=(0, 0, 0, 0), pos=(0, 0, 0), state=DGG.NORMAL) + frame_hover.bind( + DGG.ENTER, partial(self._on_texture_hovered, frame_hover)) + frame_hover.bind( + DGG.EXIT, partial(self._on_texture_blurred, frame_hover)) + frame_hover.bind( + DGG.B1PRESS, partial(self._on_texture_clicked, stage_tex)) + + Text(text=stage_name, x=15, y=29, parent=node, size=12, color=Vec3(0.8)) + + # Scale image so it always fits + w, h = stage_tex.get_x_size(), stage_tex.get_y_size() + padd_x, padd_y = 24, 57 + scale_x = (entry_width - padd_x) / max(1, w) + scale_y = (entry_height - padd_y) / max(1, h) + scale_factor = min(scale_x, scale_y) + + if stage_tex.get_texture_type() == Image.TT_buffer_texture: + scale_factor = 1 + w = entry_width - padd_x + h = entry_height - padd_y + + preview = Sprite( + image=stage_tex, w=scale_factor * w, h=scale_factor * h, + any_filter=False, parent=node, x=7, y=40, transparent=False) + + preview.set_shader_inputs( + mipmap=0, + slice=0, + brightness=1, + tonemap=False) + + preview_shader = DisplayShaderBuilder.build( + stage_tex, scale_factor * w, scale_factor * h) + preview.set_shader(preview_shader) + + num_rows = (index + entries_per_row) // entries_per_row + + self._set_scroll_height(50 + (entry_height - 14 + 10) * num_rows) diff --git a/rpcore/gui/checkbox.py b/rpcore/gui/checkbox.py new file mode 100644 index 0000000..a61aec9 --- /dev/null +++ b/rpcore/gui/checkbox.py @@ -0,0 +1,130 @@ +""" + +RenderPipeline + +Copyright (c) 2014-2016 tobspr + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. + +""" + +from panda3d.core import TransparencyAttrib, SamplerState +from direct.gui.DirectCheckBox import DirectCheckBox +import direct.gui.DirectGuiGlobals as DGG + +from rpcore.rpobject import RPObject +from rpcore.loader import RPLoader + + +class Checkbox(RPObject): + + """ This is a wrapper around DirectCheckBox, providing a simpler interface + and better visuals """ + + def __init__(self, parent=None, x=0, y=0, callback=None, extra_args=None, + radio=False, expand_width=100, checked=False, enabled=True): + RPObject.__init__(self) + + prefix = "checkbox" if not radio else "radiobox" + + if enabled: + checked_img = RPLoader.load_texture( + "/$$rp/data/gui/" + prefix + "_checked.png") + unchecked_img = RPLoader.load_texture( + "/$$rp/data/gui/" + prefix + "_default.png") + else: + checked_img = RPLoader.load_texture( + "/$$rp/data/gui/" + prefix + "_disabled.png") + unchecked_img = checked_img + + # Set near filter, otherwise textures look like crap + for tex in [checked_img, unchecked_img]: + tex.set_minfilter(SamplerState.FT_linear) + tex.set_magfilter(SamplerState.FT_linear) + tex.set_wrap_u(SamplerState.WM_clamp) + tex.set_wrap_v(SamplerState.WM_clamp) + tex.set_anisotropic_degree(0) + + self._node = DirectCheckBox( + parent=parent, pos=(x + 11, 1, -y - 8), scale=(10 / 2.0, 1, 10 / 2.0), + checkedImage=checked_img, uncheckedImage=unchecked_img, + image=unchecked_img, extraArgs=extra_args, state=DGG.NORMAL, + relief=DGG.FLAT, command=self._update_status) + + self._node["frameColor"] = (0, 0, 0, 0) + self._node["frameSize"] = (-2.6, 2 + expand_width / 7.5, -2.35, 2.5) + self._node.set_transparency(TransparencyAttrib.M_alpha) + + self._callback = callback + self._extra_args = extra_args + self._collection = None + + if checked: + self.set_checked(True, False) + + @property + def collection(self): + """ Returns a handle to the assigned checkbox collection, or None + if no collection was assigned """ + return self._collection + + @collection.setter + def collection(self, coll): + """ Internal method to add a checkbox to a checkbox collection, this + is used for radio-buttons """ + self._collection = coll + + @property + def checked(self): + """ Returns whether the node is currently checked """ + return self._node["isChecked"] + + @property + def node(self): + """ Returns a handle to the internally used node """ + return self._node + + def _update_status(self, status): + """ Internal method when another checkbox in the same radio group + changed it's value """ + + if not status and self._collection: + self._node.commandFunc(None) + return + + if self._collection: + if status: + self._collection.on_checkbox_changed(self) + # A radio box can't be unchecked + # self._node["state"] = DGG.DISABLED + + if self._callback is not None: + self._callback(*([status] + self._extra_args)) + + def set_checked(self, val, do_callback=True): + """ Internal method to check/uncheck the checkbox """ + self._node["isChecked"] = val + + if val: + self._node["image"] = self._node["checkedImage"] + else: + self._node["image"] = self._node["uncheckedImage"] + + if do_callback and self._callback is not None: + self._callback(*([val] + self._extra_args)) diff --git a/rpcore/gui/checkbox_collection.py b/rpcore/gui/checkbox_collection.py new file mode 100644 index 0000000..4d8b390 --- /dev/null +++ b/rpcore/gui/checkbox_collection.py @@ -0,0 +1,67 @@ +""" + +RenderPipeline + +Copyright (c) 2014-2016 tobspr + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. + +""" + +from rpcore.rpobject import RPObject + +import direct.gui.DirectGuiGlobals as DGG + + +class CheckboxCollection(RPObject): + + """ This is a container for multiple Checkboxes, controlling that + only one checkbox of this collection is checked at one time + (like a radio-button) """ + + def __init__(self): + RPObject.__init__(self) + self._items = [] + + def add(self, chb): + """ Adds a Checkbox to this collection """ + if chb.collection is not None: + self.error( + "Can't add checkbox as it already belongs " + "to another collection!") + return + chb.collection = self + self._items.append(chb) + + def remove(self, chb): + """ Removes a checkbox from this collection """ + if chb.collection is not self: + self.error( + "Can't remove the checkbox from this collection as it is not " + "attached to this collection!") + return + chb.collection = None + self._items.remove(chb) + + def on_checkbox_changed(self, chb): + """ Internal callback when a checkbox got changed """ + for item in self._items: + if item is not chb: + item.set_checked(False) + item.node["state"] = DGG.NORMAL diff --git a/rpcore/gui/debugger.py b/rpcore/gui/debugger.py new file mode 100644 index 0000000..889d822 --- /dev/null +++ b/rpcore/gui/debugger.py @@ -0,0 +1,330 @@ +""" + +RenderPipeline + +Copyright (c) 2014-2016 tobspr + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. + +""" + +from __future__ import division + +import os +import sys +import subprocess + +from rplibs.six.moves import range # pylint: disable=import-error + +from panda3d.core import Vec4, Vec3, Vec2, RenderState, TransformState +from panda3d.core import TexturePool, SceneGraphAnalyzer +from direct.interval.IntervalGlobal import Sequence + +from rpcore.gui.sprite import Sprite +from rpcore.gui.buffer_viewer import BufferViewer +from rpcore.gui.pipe_viewer import PipeViewer +from rpcore.gui.render_mode_selector import RenderModeSelector + +from rpcore.gui.text_node import TextNode +from rpcore.gui.error_message_display import ErrorMessageDisplay +from rpcore.gui.exposure_widget import ExposureWidget +from rpcore.gui.fps_chart import FPSChart +from rpcore.gui.pixel_inspector import PixelInspector + +from rpcore.globals import Globals +from rpcore.rpobject import RPObject + +from rpcore.native import NATIVE_CXX_LOADED +from rpcore.render_target import RenderTarget +from rpcore.image import Image + + +class Debugger(RPObject): + + """ This class manages the onscreen control, and displays statistics. """ + + def __init__(self, pipeline): + RPObject.__init__(self) + self.debug("Creating debugger") + self.pipeline = pipeline + self.analyzer = SceneGraphAnalyzer() + + self.fullscreen_node = Globals.base.pixel2d.attach_new_node("rp_debugger") + self.create_components() + self.init_keybindings() + + if self.advanced_info: + Globals.base.doMethodLater( + 0.5, lambda task: self.collect_scene_data(), "RPDebugger_collectSceneData_initial") + + Globals.base.doMethodLater(0.1, self.update_stats, "RPDebugger_updateStats") + + @property + def advanced_info(self): + return self.pipeline.settings["pipeline.advanced_debugging_info"] + + def create_components(self): + """ Creates the gui components """ + + self.debugger_width = 460 + self.debugger_visible = False + self.debugger_interval = None + + self.create_stats() + self.create_hints() + + self.pipeline_logo = Sprite( + image="/$$rp/data/gui/pipeline_logo_text.png", x=30, y=30, + parent=self.fullscreen_node) + + if self.advanced_info: + self.exposure_node = self.fullscreen_node.attach_new_node("ExposureWidget") + self.exposure_widget = ExposureWidget(self.pipeline, self.exposure_node) + + self.fps_node = self.fullscreen_node.attach_new_node("FPSChart") + self.fps_node.set_pos(Vec3(21, 1, -108 - 40)) + self.fps_widget = FPSChart(self.pipeline, self.fps_node) + + self.pixel_widget = PixelInspector(self.pipeline) + self.buffer_viewer = BufferViewer(self.pipeline, self.fullscreen_node) + self.pipe_viewer = PipeViewer(self.pipeline, self.fullscreen_node) + self.rm_selector = RenderModeSelector(self.pipeline, self.fullscreen_node) + self.error_msg_handler = ErrorMessageDisplay() + + self.handle_window_resize() + + def update(self): + """ Updates the gui """ + self.error_msg_handler.update() + self.pixel_widget.update() + + def collect_scene_data(self, task=None): + """ Analyzes the scene graph to provide useful information """ + self.analyzer.clear() + for geom_node in Globals.base.render.find_all_matches("**/+GeomNode"): + self.analyzer.add_node(geom_node.node()) + if task: + return task.again + + def create_stats(self): + """ Creates the stats overlay """ + self.overlay_node = Globals.base.aspect2d.attach_new_node("Overlay") + self.debug_lines = [] + + num_lines = 6 if self.advanced_info else 1 + for i in range(num_lines): + self.debug_lines.append(TextNode( + pos=Vec2(0, -i * 0.046), parent=self.overlay_node, align="right", color=Vec3(0.7, 1, 1))) + self.debug_lines[0].color = Vec4(1, 1, 0, 1) + + def create_hints(self): + """ Creates the hints like keybindings and when reloading shaders """ + self.hint_reloading = Sprite( + image="/$$rp/data/gui/shader_reload_hint.png", + parent=self.fullscreen_node) + self.set_reload_hint_visible(False) + + self.python_warning = None + if not NATIVE_CXX_LOADED: + # Warning when using the python version + self.python_warning = Sprite( + image="/$$rp/data/gui/python_warning.png", + parent=self.fullscreen_node) + Sequence( + self.python_warning.color_scale_interval( + 0.7, Vec4(0.3, 1, 1, 0.7), blendType="easeOut"), + self.python_warning.color_scale_interval( + 0.7, Vec4(1, 1, 1, 1.0), blendType="easeOut"), + ).loop() + + # Keybinding hints + self.keybinding_instructions = Sprite( + image="/$$rp/data/gui/keybindings.png", + parent=self.fullscreen_node, any_filter=False) + + def set_reload_hint_visible(self, flag): + """ Sets whether the shader reload hint is visible """ + if flag: + self.hint_reloading.show() + else: + self.hint_reloading.hide() + + def handle_window_resize(self): + """ Handles the window resize, repositions the GUI elements to fit on + screen. """ + # When using small resolutions, scale the GUI so its still useable, + # otherwise the sub-windows are bigger than the main window + self.gui_scale = max(0.65, min(1.0, Globals.native_resolution.x / 1920.0)) + self.fullscreen_node.set_scale(self.gui_scale) + + if self.advanced_info: + self.exposure_node.set_pos( + Globals.native_resolution.x // self.gui_scale - 200, + 1, -Globals.native_resolution.y // self.gui_scale + 120) + self.hint_reloading.set_pos( + float((Globals.native_resolution.x) // 2) / self.gui_scale - 465 // 2, 220) + self.keybinding_instructions.set_pos( + 30, Globals.native_resolution.y // self.gui_scale - 510.0,) + self.overlay_node.set_pos(Globals.base.get_aspect_ratio() - 0.07, 1, 1.0 - 0.07) + if self.python_warning: + self.python_warning.set_pos( + (Globals.native_resolution.x // self.gui_scale - 1054) // 2, + (Globals.native_resolution.y // self.gui_scale - 118 - 40)) + + for text in self.debug_lines: + text.set_pixel_size(16 * max(0.8, self.gui_scale)) + + self.buffer_viewer.center_on_screen() + self.pipe_viewer.center_on_screen() + self.rm_selector.center_on_screen() + + def init_keybindings(self): + """ Inits the debugger keybindings """ + Globals.base.accept("v", self.buffer_viewer.toggle) + Globals.base.accept("c", self.pipe_viewer.toggle) + Globals.base.accept("z", self.rm_selector.toggle) + Globals.base.accept("f5", self.toggle_gui_visible) + Globals.base.accept("f6", self.toggle_keybindings_visible) + # Globals.base.accept("r", self.pipeline.reload_shaders) + Globals.base.accept("m", self.start_material_editor) + + def start_material_editor(self): + """ Starts the material editor """ + self.debug("Starting material editor") + pth = sys.executable + editor = os.path.dirname(os.path.realpath(__file__)) + editor = os.path.join(editor, "..", "..", "toolkit", "material_editor", "main.py") + subprocess.Popen([pth, editor], shell=True) + + def toggle_gui_visible(self): + """ Shows / Hides the gui """ + + if not self.fullscreen_node.is_hidden(): + self.fullscreen_node.hide() + self.overlay_node.hide() + self.error_msg_handler.hide() + else: + self.fullscreen_node.show() + self.overlay_node.show() + self.error_msg_handler.show() + + def toggle_keybindings_visible(self): + """ Shows / Hides the FPS graph """ + if not self.keybinding_instructions.is_hidden(): + self.keybinding_instructions.hide() + else: + self.keybinding_instructions.show() + + def update_stats(self, task=None): + """ Updates the stats overlay """ + clock = Globals.clock + self.debug_lines[0].text = "{:3.0f} fps | {:3.1f} ms | {:3.1f} ms max".format( + clock.get_average_frame_rate(), + 1000.0 / max(0.001, clock.get_average_frame_rate()), + clock.get_max_frame_duration() * 1000.0) + + if not self.advanced_info: + return task.again if task else None + + text = "{:4d} states | {:4d} transforms " + text += "| {:4d} cmds | {:4d} lights | {:4d} shadows " + text += "| {:5.1f}% atlas usage" + self.debug_lines[1].text = text.format( + RenderState.get_num_states(), TransformState.get_num_states(), + self.pipeline.light_mgr.cmd_queue.num_processed_commands, + self.pipeline.light_mgr.num_lights, + self.pipeline.light_mgr.num_shadow_sources, + self.pipeline.light_mgr.shadow_atlas_coverage) + + text = "Internal: {:3.0f} MB VRAM | {:5d} img | {:5d} tex | " + text += "{:5d} fbos | {:3d} plugins | {:2d} views ({:2d} active)" + tex_memory, tex_count = self.buffer_viewer.stage_information + + views, active_views = 0, 0 + for target in RenderTarget.REGISTERED_TARGETS: + if not target.create_default_region: + num_regions = target.internal_buffer.get_num_display_regions() + for i, region in enumerate(target.internal_buffer.get_display_regions()): + # Skip overlay display region + if i == 0 and num_regions > 1: + continue + views += 1 + active_views += 1 if target.active and region.active else 0 + + self.debug_lines[2].text = text.format( + tex_memory / (1024**2), len(Image.REGISTERED_IMAGES), tex_count, + RenderTarget.NUM_ALLOCATED_BUFFERS, + len(self.pipeline.plugin_mgr.enabled_plugins), + views, active_views) + + text = "Scene: {:4.0f} MB VRAM | {:3d} tex | {:4d} geoms " + text += "| {:4d} nodes | {:7,.0f} vertices" + scene_tex_size = 0 + for tex in TexturePool.find_all_textures(): + scene_tex_size += tex.estimate_texture_memory() + + self.debug_lines[3].text = text.format( + scene_tex_size / (1024**2), + len(TexturePool.find_all_textures()), + self.analyzer.get_num_geoms(), + self.analyzer.get_num_nodes(), + self.analyzer.get_num_vertices(), + ) + + sun_vector = Vec3(0) + if self.pipeline.plugin_mgr.is_plugin_enabled("scattering"): + sun_vector = self.pipeline.plugin_mgr.instances["scattering"].sun_vector + + text = "Time: {} ({:1.3f}) | Sun {:0.2f} {:0.2f} {:0.2f}" + text += " | X {:3.1f} Y {:3.1f} Z {:3.1f}" + text += " | {:2d} tasks | scheduled: {:2d}" + self.debug_lines[4].text = text.format( + self.pipeline.daytime_mgr.formatted_time, + self.pipeline.daytime_mgr.time, + sun_vector.x, sun_vector.y, sun_vector.z, + Globals.base.camera.get_x(Globals.base.render), + Globals.base.camera.get_y(Globals.base.render), + Globals.base.camera.get_z(Globals.base.render), + self.pipeline.task_scheduler.num_tasks, + self.pipeline.task_scheduler.num_scheduled_tasks,) + + text = "Scene shadows: " + if "pssm" in self.pipeline.plugin_mgr.enabled_plugins: + focus = self.pipeline.plugin_mgr.instances["pssm"].scene_shadow_stage.last_focus + if focus is not None: + text += "{:3.1f} {:3.1f} {:3.1f} r {:3.1f}".format( + focus[0].x, focus[0].y, focus[0].z, focus[1]) + else: + text += "none" + else: + text += "inactive" + + text += " | HPR ({:3.1f}, {:3.1f}, {:3.1f}) | {:4d} x {:4d} pixels @ {:3.1f} %" + text += " | {:3d} x {:3d} tiles" + self.debug_lines[5].text = text.format( + Globals.base.camera.get_h(Globals.base.render), + Globals.base.camera.get_p(Globals.base.render), + Globals.base.camera.get_r(Globals.base.render), + Globals.native_resolution.x, + Globals.native_resolution.y, + self.pipeline.settings["pipeline.resolution_scale"] * 100.0, + self.pipeline.light_mgr.num_tiles.x, + self.pipeline.light_mgr.num_tiles.y,) + if task: + return task.again diff --git a/rpcore/gui/draggable_window.py b/rpcore/gui/draggable_window.py new file mode 100644 index 0000000..01e83d1 --- /dev/null +++ b/rpcore/gui/draggable_window.py @@ -0,0 +1,166 @@ +""" + +RenderPipeline + +Copyright (c) 2014-2016 tobspr + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. + +""" + +from panda3d.core import Vec2, TransparencyAttrib, Vec3 +from direct.gui.DirectFrame import DirectFrame +from direct.gui.DirectButton import DirectButton +from direct.gui.DirectGui import DGG + +from rpcore.rpobject import RPObject +from rpcore.globals import Globals +from rpcore.gui.text import Text + + +class DraggableWindow(RPObject): + + """ This is a simple draggable but not resizeable window """ + + def __init__(self, width=800, height=500, title="Window", parent=None): + """ Constructs a new window with the given dimensions and title """ + RPObject.__init__(self, "Window-" + title) + self._width = width + self._height = height + self._title = title + self._visible = True + self._parent = parent if parent else Globals.base.pixel2d + self._dragging = False + self._drag_offset = Vec2(0) + self._pos = Vec2(0) + + def center_on_screen(self): + """ Centers the window on screen """ + self._context_scale = 1.0 / self._parent.get_sx() + self._context_width = Globals.native_resolution.x * self._context_scale + self._context_height = Globals.native_resolution.y * self._context_scale + self._set_pos(Vec2((self._context_width - self._width) / 2, + (self._context_height - self._height) / 2)) + + def set_title(self, title): + """ Sets the window title """ + self._title = title + self._window_title.set_text(title) + + def show(self): + """ Shows the window """ + self._visible = True + self.center_on_screen() + self._node.show() + + def hide(self): + """ Hides the window """ + self._visible = False + self._stop_drag() + self._node.hide() + + def remove(self): + """ Removes the window from the scene graph. You should still delete the + instance """ + self._stop_drag() + self._node.remove_node() + + def _create_components(self): + """ Creates the window components """ + self._node = self._parent.attach_new_node("Window") + self._node.set_pos(self._pos.x, 1, -self._pos.y) + border_px = 1 + border_frame_size = (-border_px, self._width + border_px, + border_px, -self._height - border_px) + self._border_frame = DirectFrame( + pos=(0, 1, 0), frameSize=border_frame_size, + frameColor=(24 / 255.0, 131 / 255.0, 215 / 255.0, 1), + parent=self._node, state=DGG.NORMAL) + self._background = DirectFrame( + pos=(0, 1, 0), frameSize=(0, self._width, 0, -self._height), + frameColor=(0.1, 0.1, 0.1, 1.0), parent=self._node) + self._title_bar = DirectFrame( + pos=(0, 1, 0), frameSize=(0, self._width, 0, -25), + # frameColor=(0.058, 0.058, 0.058, 1), + frameColor=(1, 1, 1, 1), + parent=self._node, + state=DGG.NORMAL) + self._window_title = Text( + parent=self._node, x=8, y=17, text=self._title, size=13, + color=Vec3(0.15), may_change=True) + self._btn_close = DirectButton( + relief=DGG.FLAT, pressEffect=1, pos=(self._width - 22, 1, -12), + frameColor=(1.0, 0.2, 0.2, 0.5), parent=self._node, + scale=(45 / 2, 1, 24 / 2), + image="/$$rp/data/gui/close_window.png") + + # Init bindings + self._btn_close.set_transparency(TransparencyAttrib.M_alpha) + self._btn_close.bind(DGG.B1CLICK, self._request_close) + self._btn_close.bind(DGG.WITHIN, self._on_close_btn_hover) + self._btn_close.bind(DGG.WITHOUT, self._on_close_btn_out) + self._title_bar.bind(DGG.B1PRESS, self._start_drag) + self._title_bar.bind(DGG.B1RELEASE, self._stop_drag) + + def _start_drag(self, evt=None): # pylint: disable=unused-argument + """ Gets called when the user starts dragging the window """ + self._dragging = True + self._node.detach_node() + self._node.reparent_to(self._parent) + Globals.base.taskMgr.add(self._on_tick, "UIWindowDrag", + uponDeath=self._stop_drag) + self._drag_offset = self._pos - self._get_mouse_pos() + + def _on_close_btn_hover(self, evt=None): # pylint: disable=unused-argument + """ Internal method when the close button got hovered """ + self._btn_close["image"] = "/$$rp/data/gui/close_window_hover.png" + + def _on_close_btn_out(self, evt=None): # pylint: disable=unused-argument + """ Internal method when the close button is no longer hovered """ + self._btn_close["image"] = "/$$rp/data/gui/close_window.png" + + def _request_close(self, evt=None): # pylint: disable=unused-argument + """ This method gets called when the close button gets clicked """ + self.hide() + + def _stop_drag(self, evt=None): # pylint: disable=unused-argument + """ Gets called when the user stops dragging the window """ + Globals.base.taskMgr.remove("UIWindowDrag") + self._dragging = False + + def _get_mouse_pos(self): + """ Internal helper function to get the mouse position, scaled by + the context scale """ + mouse_x, mouse_y = (Globals.base.win.get_pointer(0).x, + Globals.base.win.get_pointer(0).y) + return Vec2(mouse_x, mouse_y) * self._context_scale + + def _set_pos(self, pos): + """ Moves the window to the specified position """ + self._pos = pos + self._pos.x = max(self._pos.x, -self._width + 100) + self._pos.y = max(self._pos.y, 25) + self._pos.x = min(self._pos.x, self._context_width - 100) + self._pos.y = min(self._pos.y, self._context_height - 50) + self._node.set_pos(self._pos.x, 1, -self._pos.y) + + def _on_tick(self, task): + """ Task which updates the window while being dragged """ + self._set_pos(self._get_mouse_pos() + self._drag_offset) + return task.cont diff --git a/rpcore/gui/error_message_display.py b/rpcore/gui/error_message_display.py new file mode 100644 index 0000000..b4ffac3 --- /dev/null +++ b/rpcore/gui/error_message_display.py @@ -0,0 +1,101 @@ +""" + +RenderPipeline + +Copyright (c) 2014-2016 tobspr + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. + +""" + +from __future__ import print_function + +from panda3d.core import Notify, LineStream, Vec3 + +from rpcore.globals import Globals +from rpcore.rpobject import RPObject + +from rpcore.gui.text import Text + + +class ErrorMessageDisplay(RPObject): + + """ This is a gui element which listens to the panda output stream + and shows errors """ + + def __init__(self): + RPObject.__init__(self) + self._num_errors = 0 + self._error_node = Globals.base.pixel2d.attach_new_node("ErrorDisplay") + self._error_node.set_z(-180) + self._notify_stream = None + + def _init_notify(self): + """ Internal method to init the stream to catch all notify messages """ + self._notify_stream = LineStream() + Notify.ptr().set_ostream_ptr(self._notify_stream, False) + + def update(self): + """ Updates the error display, fetching all new messages from the notify + stream """ + + if not self._notify_stream: + self._init_notify() + + while self._notify_stream.is_text_available(): + line = self._notify_stream.get_line().strip() + if "warning" in line: + RPObject.global_warn("Panda3D", line) + # self.add_warning(line) + elif "error" in line: + RPObject.global_error("Panda3D", line) + self.add_error(line) + else: + RPObject.global_debug("Panda3D", line) + + def add_error(self, msg): + """ Adds a new error message """ + self.add_text(msg, Vec3(1, 0.2, 0.2)) + + def add_warning(self, msg): + """ Adds a new warning message """ + self.add_text(msg, Vec3(1, 1, 0.2)) + + def add_text(self, text, color): + """ Internal method to add a new text to the output """ + Text( + x=Globals.native_resolution.x - 30, y=self._num_errors * 23, + align="right", text=text, size=12, parent=self._error_node, color=color) + + self._num_errors += 1 + + if self._num_errors > 30: + self.clear_messages() + self.add_error("Error count exceeded. Cleared errors ..") + + def clear_messages(self): + """ Clears all messages / removes them """ + self._error_node.node().remove_all_children() + self._num_errors = 0 + + def show(self): + self._error_node.show() + + def hide(self): + self._error_node.hide() diff --git a/rpcore/gui/exposure_widget.py b/rpcore/gui/exposure_widget.py new file mode 100644 index 0000000..1945492 --- /dev/null +++ b/rpcore/gui/exposure_widget.py @@ -0,0 +1,101 @@ +""" + +RenderPipeline + +Copyright (c) 2014-2016 tobspr + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. + +""" +from __future__ import division + +from panda3d.core import ComputeNode, Vec4, Vec3 +from direct.gui.DirectFrame import DirectFrame + +from rpcore.gui.sprite import Sprite +from rpcore.gui.text import Text + +from rpcore.rpobject import RPObject +from rpcore.image import Image +from rpcore.globals import Globals +from rpcore.loader import RPLoader + + +class ExposureWidget(RPObject): + + """ Widget to show the current exposure """ + + def __init__(self, pipeline, parent): + """ Inits the widget """ + RPObject.__init__(self) + self._pipeline = pipeline + self._parent = parent + self._node = self._parent.attach_new_node("ExposureWidgetNode") + self._create_components() + + def _create_components(self): + """ Internal method to init the widgets components """ + + self._node.hide() + + # Create the texture where the gui component is rendered inside + self._storage_tex = Image.create_2d("ExposureDisplay", 140, 20, "RGBA8") + self._storage_tex.set_clear_color(Vec4(0.2, 0.6, 1.0, 1.0)) + self._storage_tex.clear_image() + + self._bg_frame = DirectFrame( + parent=self._node, frameColor=(0.1, 0.1, 0.1, 1.0), + frameSize=(200, 0, -10, -85), pos=(0, 0, 0)) + + self._display_img = Sprite( + image=self._storage_tex, parent=self._node, w=140, h=20, x=20, y=50) + + self._display_txt = Text( + text="Current Exposure".upper(), parent=self._node, x=160, y=40, + size=13, color=Vec3(0.8), align="right") + + # Create the shader which generates the visualization texture + self._cshader_node = ComputeNode("ExposureWidget") + self._cshader_node.add_dispatch(140 // 10, 20 // 4, 1) + + self._cshader_np = self._node.attach_new_node(self._cshader_node) + + # Defer the further loading + Globals.base.taskMgr.doMethodLater(1.0, self._late_init, "ExposureLateInit") + + def _late_init(self, task): + """ Gets called after the pipeline initialized, this extracts the + exposure texture from the stage manager """ + stage_mgr = self._pipeline.stage_mgr + + if "Exposure" not in stage_mgr.pipes: + self.debug("Disabling exposure widget, could not find the exposure data.") + self._node.remove_node() + return + + self._node.show() + + exposure_tex = stage_mgr.pipes["Exposure"] + self._cshader = RPLoader.load_shader("/$$rp/shader/visualize_exposure.compute.glsl") + self._cshader_np.set_shader(self._cshader) + self._cshader_np.set_shader_inputs( + DestTex=self._storage_tex, + ExposureTex=exposure_tex) + + return task.done diff --git a/rpcore/gui/fps_chart.py b/rpcore/gui/fps_chart.py new file mode 100644 index 0000000..8670462 --- /dev/null +++ b/rpcore/gui/fps_chart.py @@ -0,0 +1,133 @@ +""" + +RenderPipeline + +Copyright (c) 2014-2016 tobspr + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. + +""" +from __future__ import division + +from panda3d.core import ComputeNode, Vec4, Vec3, PTAInt, PTAFloat + +from rpcore.gui.sprite import Sprite +from rpcore.gui.text import Text + +from rpcore.rpobject import RPObject +from rpcore.image import Image +from rpcore.globals import Globals +from rpcore.loader import RPLoader + + +class FPSChart(RPObject): + + """ Widget to show the FPS as a chart """ + + def __init__(self, pipeline, parent): + """ Inits the widget """ + RPObject.__init__(self) + self._pipeline = pipeline + self._parent = parent + self._node = self._parent.attach_new_node("FPSChartNode") + self._create_components() + + def _create_components(self): + """ Internal method to init the widgets components """ + + # Create the buffer which stores the last FPS values + self._storage_buffer = Image.create_buffer("FPSValues", 250, "R16") + self._storage_buffer.set_clear_color(Vec4(0)) + self._storage_buffer.clear_image() + + self._store_index = PTAInt.empty_array(1) + self._store_index[0] = 0 + + self._current_ftime = PTAFloat.empty_array(1) + self._current_ftime[0] = 16.0 + + self._chart_ms_max = PTAFloat.empty_array(1) + self._chart_ms_max[0] = 40 + + # Create the texture where the gui component is rendered inside + self._display_tex = Image.create_2d("FPSChartRender", 250, 120, "RGBA8") + self._display_tex.set_clear_color(Vec4(0)) + self._display_tex.clear_image() + self._display_img = Sprite( + image=self._display_tex, parent=self._node, w=250, h=120, x=10, y=10) + + # Defer the further loading + Globals.base.taskMgr.doMethodLater(0.3, self._late_init, "FPSChartInit") + + def _late_init(self, task): + """ Gets called after the pipeline was initialized """ + self._display_txt = Text( + text="40 ms", parent=self._node, x=20, y=25, + size=13, color=Vec3(1), may_change=True) + self._display_txt_bottom = Text( + text="0 ms", parent=self._node, x=20, y=120, + size=13, color=Vec3(1), may_change=True) + + # Create the shader which generates the visualization texture + self._cshader_node = ComputeNode("FPSChartUpdateChart") + self._cshader_node.add_dispatch(250 // 10, 120 // 4, 1) + self._cshader_np = self._node.attach_new_node(self._cshader_node) + + self._cshader = RPLoader.load_shader("/$$rp/shader/fps_chart.compute.glsl") + self._cshader_np.set_shader(self._cshader) + self._cshader_np.set_shader_inputs( + DestTex=self._display_tex, + FPSValues=self._storage_buffer, + index=self._store_index, + maxMs=self._chart_ms_max) + + self._update_shader_node = ComputeNode("FPSChartUpdateValues") + self._update_shader_node.add_dispatch(1, 1, 1) + self._update_shader_np = self._node.attach_new_node(self._update_shader_node) + self._ushader = RPLoader.load_shader("/$$rp/shader/fps_chart_update.compute.glsl") + self._update_shader_np.set_shader(self._ushader) + self._update_shader_np.set_shader_inputs( + DestTex=self._storage_buffer, + index=self._store_index, + currentData=self._current_ftime) + + Globals.base.addTask(self._update, "UpdateFPSChart", sort=-50) + + return task.done + + def _update(self, task): + """ Updates the widget """ + self._store_index[0] = (self._store_index[0] + 1) % 250 + self._current_ftime[0] = Globals.clock.get_dt() * 1000.0 + + avg_fps = Globals.clock.get_average_frame_rate() + if avg_fps > 122: + self._chart_ms_max[0] = 10.0 + elif avg_fps > 62: + self._chart_ms_max[0] = 20.0 + elif avg_fps > 32: + self._chart_ms_max[0] = 40.0 + elif avg_fps > 15: + self._chart_ms_max[0] = 70.0 + else: + self._chart_ms_max[0] = 200.0 + + self._display_txt.set_text(str(int(self._chart_ms_max[0])) + " ms") + + return task.cont diff --git a/rpcore/gui/labeled_checkbox.py b/rpcore/gui/labeled_checkbox.py new file mode 100644 index 0000000..d6889e6 --- /dev/null +++ b/rpcore/gui/labeled_checkbox.py @@ -0,0 +1,86 @@ +""" + +RenderPipeline + +Copyright (c) 2014-2016 tobspr + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. + +""" + +from panda3d.core import Vec3 +import direct.gui.DirectGuiGlobals as DGG + +from rpcore.rpobject import RPObject +from rpcore.gui.checkbox import Checkbox +from rpcore.gui.text import Text + + +class LabeledCheckbox(RPObject): + + """ This is a checkbox, combined with a label. The arguments are + equal to the Checkbox and OnscreenText arguments. """ + + def __init__(self, parent=None, x=0, y=0, chb_callback=None, + chb_args=None, chb_checked=True, text="", text_size=16, + radio=False, text_color=None, expand_width=100, enabled=True): + """ Constructs a new checkbox, forwarding most of the elements to the + underlying Checkbox and Text. """ + RPObject.__init__(self) + if chb_args is None: + chb_args = [] + + if text_color is None: + text_color = Vec3(1) + + if not enabled: + text_color = Vec3(1.0, 0, 0.28) + + self.text_color = text_color + + self._checkbox = Checkbox( + parent=parent, x=x, y=y, enabled=enabled, callback=chb_callback, + extra_args=chb_args, checked=chb_checked, radio=radio, + expand_width=expand_width) + self._text = Text( + x=x + 26, y=y + 9 + text_size // 4, text=text, align="left", + parent=parent, size=text_size, color=text_color, may_change=True) + + if enabled: + self._checkbox.node.bind(DGG.WITHIN, self._on_node_enter) + self._checkbox.node.bind(DGG.WITHOUT, self._on_node_leave) + + def _on_node_enter(self, *args): # pylint: disable=unused-argument + """ Internal callback when the node gets hovered """ + self._text.node["fg"] = (self.text_color.x + 0.1, self.text_color.y + 0.1, + self.text_color.z + 0.1, 1.0) + + def _on_node_leave(self, *args): # pylint: disable=unused-argument + """ Internal callback when the node gets no longer hovered """ + self._text.node["fg"] = (self.text_color.x, self.text_color.y, self.text_color.z, 1.0) + + @property + def checkbox(self): + """ Returns a handle to the checkbox """ + return self._checkbox + + @property + def label(self): + """ Returns a handle to the label """ + return self._text diff --git a/rpcore/gui/loading_screen.py b/rpcore/gui/loading_screen.py new file mode 100644 index 0000000..c886448 --- /dev/null +++ b/rpcore/gui/loading_screen.py @@ -0,0 +1,70 @@ +""" + +RenderPipeline + +Copyright (c) 2014-2016 tobspr + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. + +""" +from __future__ import division + +from rplibs.six.moves import range # pylint: disable=import-error + +from rpcore.gui.sprite import Sprite +from rpcore.rpobject import RPObject +from rpcore.globals import Globals + + +class LoadingScreen(RPObject): + + """ This is the default loading screen used by the pipeline. It provides + the ability to display a simple image during loading. The image should be + in the format 16:9 and not too small, to avoid being blurred out. """ + + def __init__(self, pipeline, image_source="/$$rp/data/gui/loading_screen_bg.txo"): + """ Inits the loading screen with a given image source. By default, + this is the pipeline loading screen, but it can be overridden. """ + RPObject.__init__(self) + self.pipeline = pipeline + self.image_source = image_source + + def create(self): + """ Creates the gui components """ + screen_w, screen_h = Globals.native_resolution.x, Globals.native_resolution.y + self.fullscreen_node = Globals.base.pixel2dp.attach_new_node("LoadingScreen") + self.fullscreen_node.set_bin("fixed", 10) + self.fullscreen_node.set_depth_test(False) + + scale_w = screen_w / 1920.0 + scale_h = screen_h / 1080.0 + scale = max(scale_w, scale_h) + + self.fullscreen_bg = Sprite( + image=self.image_source, x=(screen_w - 1920.0 * scale) // 2, + y=(screen_h - 1080.0 * scale) // 2, w=int(1920 * scale), + h=int(1080 * scale), parent=self.fullscreen_node, near_filter=False) + + for _ in range(2): + Globals.base.graphicsEngine.render_frame() + + def remove(self): + """ Removes the loading screen """ + self.fullscreen_bg.node["image"].get_texture().release_all() + self.fullscreen_node.remove_node() diff --git a/rpcore/gui/pipe_viewer.py b/rpcore/gui/pipe_viewer.py new file mode 100644 index 0000000..10b4487 --- /dev/null +++ b/rpcore/gui/pipe_viewer.py @@ -0,0 +1,217 @@ +""" + +RenderPipeline + +Copyright (c) 2014-2016 tobspr + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. + +""" + +from rplibs.six import iteritems + +from panda3d.core import Texture, Vec3 + +from direct.gui.DirectScrolledFrame import DirectScrolledFrame +from direct.gui.DirectFrame import DirectFrame + +from rpcore.globals import Globals +from rpcore.util.generic import rgb_from_string +from rpcore.util.display_shader_builder import DisplayShaderBuilder +from rpcore.util.shader_input_blocks import SimpleInputBlock, GroupedInputBlock + +from rpcore.gui.draggable_window import DraggableWindow +from rpcore.gui.text import Text +from rpcore.gui.sprite import Sprite + + +class PipeViewer(DraggableWindow): + + """ Small tool which displays the order of the graphic pipes """ + + _STAGE_MGR = None + + @classmethod + def register_stage_mgr(cls, mgr): + """ Sets the stage manager, this is a workaround to prevent + circular imports, since the pipe viewer is already included + from the StageManager """ + cls._STAGE_MGR = mgr + + def __init__(self, pipeline, parent): + """ Constructs the pipe viewer """ + DraggableWindow.__init__(self, width=1300, height=900, parent=parent, + title="Pipeline Visualizer") + self._pipeline = pipeline + self._scroll_width = 8000 + self._scroll_height = 3000 + self._created = False + self._create_components() + self.hide() + + def toggle(self): + """ Toggles the pipe viewer """ + if self._visible: + Globals.base.taskMgr.remove("RP_GUI_UpdatePipeViewer") + self.hide() + else: + Globals.base.taskMgr.add(self._update_task, "RP_GUI_UpdatePipeViewer") + if not self._created: + self._populate_content() + self.show() + + def _update_task(self, task=None): + """ Updates the viewer """ + scroll_value = self._content_frame.horizontalScroll["value"] + scroll_value *= 2.45 + self._pipe_descriptions.set_x(scroll_value * 2759.0) + return task.cont + + def _populate_content(self): # pylint: disable=too-many-branches,too-many-statements + """ Reads the pipes and stages from the stage manager and renders those + into the window """ + self._created = True + self._pipe_node = self._content_node.attach_new_node("pipes") + self._pipe_node.set_scale(1, 1, -1) + self._stage_node = self._content_node.attach_new_node("stages") + current_pipes = [] + pipe_pixel_size = 3 + pipe_height = 100 + + # Generate stages + for offs, stage in enumerate(self._STAGE_MGR.stages): + node = self._content_node.attach_new_node("stage") + node.set_pos(220 + offs * 200.0, 0, 20) + node.set_scale(1, 1, -1) + DirectFrame(parent=node, frameSize=(10, 150, 0, -3600), + frameColor=(0.2, 0.2, 0.2, 1)) + Text(text=str(stage.debug_name.replace("Stage", "")), + parent=node, x=20, y=25, size=15) + + for output_pipe, pipe_tex in iteritems(stage.produced_pipes): + pipe_idx = 0 + r, g, b = rgb_from_string(output_pipe) + if output_pipe in current_pipes: + pipe_idx = current_pipes.index(output_pipe) + else: + current_pipes.append(output_pipe) + pipe_idx = len(current_pipes) - 1 + DirectFrame(parent=node, + frameSize=(0, 8000, pipe_pixel_size / 2, + -pipe_pixel_size / 2), + frameColor=(r, g, b, 1), + pos=(10, 1, -95 - pipe_idx * pipe_height)) + w = 160 + h = Globals.native_resolution.y /\ + float(Globals.native_resolution.x) * w + DirectFrame(parent=node, + frameSize=(-pipe_pixel_size, w + pipe_pixel_size, + h / 2 + pipe_pixel_size, + -h / 2 - pipe_pixel_size), + frameColor=(r, g, b, 1), + pos=(0, 1, -95 - pipe_idx * pipe_height)) + + if isinstance(pipe_tex, (list, tuple)): + pipe_tex = pipe_tex[0] + + if isinstance(pipe_tex, (SimpleInputBlock, GroupedInputBlock)): + icon_file = "/$$rp/data/gui/icon_ubo.png" + elif pipe_tex.get_z_size() > 1: + icon_file = "/$$rp/data/gui/icon_texture.png" + elif pipe_tex.get_texture_type() == Texture.TT_buffer_texture: + icon_file = "/$$rp/data/gui/icon_buffer_texture.png" + else: + icon_file = None + preview = Sprite( + image=pipe_tex, parent=node, x=0, + y=50 + pipe_idx * pipe_height, w=w, h=h, any_filter=False, + transparent=False) + + preview_shader = DisplayShaderBuilder.build(pipe_tex, int(w), int(h)) + preview.set_shader(preview_shader) + + preview.set_shader_inputs( + mipmap=0, + slice=0, + brightness=1, + tonemap=False) + + if icon_file: + Sprite(image=icon_file, parent=node, + x=55, y=65 + pipe_idx * pipe_height, + w=48, h=48, near_filter=False, + transparent=True) + + if isinstance(pipe_tex, (SimpleInputBlock, GroupedInputBlock)): + tex_desc = "UBO" + else: + tex_desc = pipe_tex.format_texture_type(pipe_tex.get_texture_type()) + tex_desc += " - " + pipe_tex.format_format(pipe_tex.get_format()).upper() + + Text(text=tex_desc, parent=node, x=55 + 48 / 2, + y=130 + pipe_idx * pipe_height, color=Vec3(0.2), + size=12, align="center") + + for input_pipe in stage.required_pipes: + if input_pipe not in current_pipes: + self.warn("Pipe not found:", input_pipe) + continue + idx = current_pipes.index(input_pipe) + r, g, b = rgb_from_string(input_pipe) + DirectFrame(parent=node, frameSize=(0, 10, 40, -40), + frameColor=(r, g, b, 1), + pos=(5, 1, -95 - idx * pipe_height)) + + self._pipe_descriptions = self._content_node.attach_new_node( + "PipeDescriptions") + self._pipe_descriptions.set_scale(1, 1, -1) + + DirectFrame(parent=self._pipe_descriptions, frameSize=(0, 190, 0, -5000), + frameColor=(0.1, 0.1, 0.1, 1.0)) + + # Generate the pipe descriptions + for idx, pipe in enumerate(current_pipes): + r, g, b = rgb_from_string(pipe) + DirectFrame(parent=self._pipe_descriptions, + frameSize=(0, 180, -95, -135), + frameColor=(r, g, b, 1.0), pos=(0, 1, -idx * pipe_height)) + Text(parent=self._pipe_descriptions, text=pipe, + x=42, y=121 + idx * pipe_height, size=15, + color=Vec3(0.1)) + Sprite(parent=self._pipe_descriptions, x=9, y=103 + idx * pipe_height, + image="/$$rp/data/gui/icon_pipe.png", + transparent=True, near_filter=False) + + def _create_components(self): + """ Internal method to create the window components """ + DraggableWindow._create_components(self) + + self._content_frame = DirectScrolledFrame( + frameSize=(0, self._width - 40, 0, self._height - 80), + canvasSize=(0, self._scroll_width, 0, self._scroll_height), + autoHideScrollBars=False, + scrollBarWidth=20.0, + frameColor=(0, 0, 0, 0), + verticalScroll_relief=False, + horizontalScroll_relief=False, + parent=self._node, + pos=(20, 1, -self._height + 20)) + self._content_node = self._content_frame.getCanvas().attach_new_node("PipeComponents") + self._content_node.set_scale(1, 1, -1) + self._content_node.set_z(self._scroll_height) diff --git a/rpcore/gui/pixel_inspector.py b/rpcore/gui/pixel_inspector.py new file mode 100644 index 0000000..42595ab --- /dev/null +++ b/rpcore/gui/pixel_inspector.py @@ -0,0 +1,81 @@ +""" + +RenderPipeline + +Copyright (c) 2014-2016 tobspr + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. + +""" + +from panda3d.core import CardMaker, Vec2, GraphicsWindow +from rpcore.rpobject import RPObject +from rpcore.globals import Globals +from rpcore.loader import RPLoader + + +class PixelInspector(RPObject): + + """ Widget to analyze the rendered pixels, by zooming in """ + + def __init__(self, pipeline): + RPObject.__init__(self) + self._pipeline = pipeline + self._node = Globals.base.pixel2d.attach_new_node("ExposureWidgetNode") + self._create_components() + self.hide() + + def _create_components(self): + """ Internal method to init the widgets components """ + card_maker = CardMaker("PixelInspector") + card_maker.set_frame(-200, 200, -150, 150) + self._zoomer = self._node.attach_new_node(card_maker.generate()) + + # Defer the further loading + Globals.base.taskMgr.doMethodLater( + 1.0, self._late_init, "PixelInspectorLateInit") + Globals.base.accept("q", self.show) + Globals.base.accept("q-up", self.hide) + + def show(self): + """ Shows the inspector """ + self._node.show() + + def hide(self): + """ Shows the inspector """ + self._node.hide() + + def _late_init(self, task): + """ Gets called after the pipeline got initialized """ + scene_tex = self._pipeline.stage_mgr.pipes["ShadedScene"] + self._zoomer.set_shader(RPLoader.load_shader( + "/$$rp/shader/default_gui_shader.vert.glsl", + "/$$rp/shader/pixel_inspector.frag.glsl")) + self._zoomer.set_shader_input("SceneTex", scene_tex) + return task.done + + def update(self): + """ Updates the pixel preview """ + if isinstance(Globals.base.win, GraphicsWindow): + mouse = Globals.base.win.get_pointer(0) + if mouse.get_in_window(): + pos = mouse.get_x(), 1, -mouse.get_y() + rel_mouse_pos = Vec2(mouse.get_x(), Globals.native_resolution.y - mouse.get_y()) + self._node.set_pos(pos) + self._zoomer.set_shader_input("mousePos", rel_mouse_pos) diff --git a/rpcore/gui/render_mode_selector.py b/rpcore/gui/render_mode_selector.py new file mode 100644 index 0000000..0eec713 --- /dev/null +++ b/rpcore/gui/render_mode_selector.py @@ -0,0 +1,132 @@ +""" + +RenderPipeline + +Copyright (c) 2014-2016 tobspr + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. + +""" + +from __future__ import division +from functools import partial + +from panda3d.core import Vec3 + +from rplibs.yaml import load_yaml_file + +from rpcore.native import NATIVE_CXX_LOADED +from rpcore.gui.draggable_window import DraggableWindow +from rpcore.gui.labeled_checkbox import LabeledCheckbox +from rpcore.gui.checkbox_collection import CheckboxCollection + + +class RenderModeSelector(DraggableWindow): + + """ Window which offers the user to select a render mode to apply """ + + def __init__(self, pipeline, parent): + DraggableWindow.__init__(self, width=690, height=340, parent=parent, + title="Select render mode") + self._pipeline = pipeline + self._selected_mode = "" + self._create_components() + self.hide() + + def _create_components(self): + """ Internal method to init the components """ + DraggableWindow._create_components(self) + self._content_node = self._node.attach_new_node("content") + self._populate_content() + + def _populate_content(self): + """ Populates the windows content """ + self._content_node.node().remove_all_children() + + # Reload config each time the window is opened so its easy to add new + # render modes + config = load_yaml_file("/$$rpconfig/debugging.yaml") + + debugger_content = self._content_node.attach_new_node("RenderModes") + debugger_content.set_z(-20) + debugger_content.set_x(20) + + render_modes = [("Default", "", False, "", False)] + + # Read modes from configuration + for mode in config["render_modes"]: + data = [mode["name"], mode["key"]] + data.append(mode.get("cxx_only", False)) + data.append(mode.get("requires", "")) + data.append(mode.get("special", False)) + render_modes.append(data) + + collection = CheckboxCollection() + + max_column_height = 9 + + for idx, (mode, mode_id, requires_cxx, requires_plugin, special) in enumerate(render_modes): + offs_y = (idx % max_column_height) * 24 + 35 + offs_x = (idx // max_column_height) * 220 + enabled = True + if requires_cxx and not NATIVE_CXX_LOADED: + enabled = False + + if requires_plugin: + if not self._pipeline.plugin_mgr.is_plugin_enabled(requires_plugin): + enabled = False + + box = LabeledCheckbox( + parent=debugger_content, x=offs_x, y=offs_y, text=mode.upper(), + text_color=Vec3(0.4), radio=True, chb_checked=(mode_id == self._selected_mode), + chb_callback=partial(self._set_render_mode, mode_id, special), + text_size=14, expand_width=230, enabled=enabled) + collection.add(box.checkbox) + + def _set_render_mode(self, mode_id, special, value): + """ Callback which gets called when a render mode got selected """ + if not value: + return + + to_remove = [] + for define in self._pipeline.stage_mgr.defines: + if define.startswith("_RM_"): + to_remove.append(define) + for define in to_remove: + del self._pipeline.stage_mgr.defines[define] + + if mode_id == "": + self._pipeline.stage_mgr.defines["ANY_DEBUG_MODE"] = 0 + else: + # Don't activate the generic debugging mode for special modes. This + # is for modes like luminance which expect the scene to be rendered + # unaltered. + self._pipeline.stage_mgr.defines["ANY_DEBUG_MODE"] = 0 if special else 1 + self._pipeline.stage_mgr.defines["_RM_" + mode_id] = 1 + + self._selected_mode = mode_id + self._pipeline.reload_shaders() + + def toggle(self): + """ Toggles the visibility of this windows """ + if self._visible: + self.hide() + else: + self._populate_content() + self.show() diff --git a/rpcore/gui/slider.py b/rpcore/gui/slider.py new file mode 100644 index 0000000..14226da --- /dev/null +++ b/rpcore/gui/slider.py @@ -0,0 +1,68 @@ +""" + +RenderPipeline + +Copyright (c) 2014-2016 tobspr + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. + +""" + +import direct.gui.DirectGuiGlobals as DGG +from direct.gui.DirectSlider import DirectSlider + +from rpcore.rpobject import RPObject + + +class Slider(RPObject): + + """ This is a simple wrapper around DirectSlider, providing a simpler + interface """ + + def __init__(self, x=0, y=0, parent=None, size=100, min_value=0, + max_value=100, value=50, page_size=1, callback=None, + extra_args=None): + """ Inits the slider """ + RPObject.__init__(self) + if extra_args is None: + extra_args = [] + + # Scale has to be 2.0, otherwise there will be an error. + self._node = DirectSlider( + pos=(size * 0.5 + x, 1, -y), parent=parent, range=(min_value, max_value), + value=value, pageSize=page_size, scale=2.0, command=callback, + extraArgs=extra_args, frameColor=(0.0, 0.0, 0.0, 1), + frameSize=(-size * 0.25, size * 0.25, -5, 5), relief=DGG.FLAT, + thumb_frameColor=(0.35, 0.53, 0.2, 1.0), thumb_relief=DGG.FLAT, + thumb_frameSize=(-2.5, 2.5, -5.0, 5.0),) + + @property + def value(self): + """ Returns the currently assigned value """ + return self._node["value"] + + @value.setter + def value(self, value): + """ Sets the value of the slider """ + self._node["value"] = value + + @property + def node(self): + """ Returns a handle to the internally used node """ + return self._node diff --git a/rpcore/gui/sprite.py b/rpcore/gui/sprite.py new file mode 100644 index 0000000..a505d61 --- /dev/null +++ b/rpcore/gui/sprite.py @@ -0,0 +1,153 @@ +""" + +RenderPipeline + +Copyright (c) 2014-2016 tobspr + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. + +""" + +from panda3d.core import TransparencyAttrib, Vec3, Texture, SamplerState +from direct.gui.OnscreenImage import OnscreenImage + +from rpcore.rpobject import RPObject +from rpcore.loader import RPLoader + + +class Sprite(RPObject): + + """ Simple wrapper arround OnscreenImage, providing a simpler interface """ + + def __init__(self, image=None, parent=None, x=0, y=0, w=None, h=None, + transparent=True, near_filter=True, any_filter=True): + """ Creates a new image, taking (x,y) as topleft coordinates. + + When near_filter is set to true, a near filter will be set to the + texture passed. This provides sharper images. + + When any_filter is set to false, the passed image won't be modified at + all. This enables you to display existing textures, otherwise the + texture would get a near filter in the 3D View, too. """ + + RPObject.__init__(self) + + if not isinstance(image, Texture): + if not isinstance(image, str): + self.warn("Invalid argument to image parameter:", image) + return + image = RPLoader.load_texture(image) + + if w is None or h is None: + w, h = image.get_x_size(), image.get_y_size() + else: + if w is None or h is None: + w = 10 + h = 10 + + self._width, self._height = w, h + self._initial_pos = self._translate_pos(x, y) + + self.node = OnscreenImage( + image=image, parent=parent, pos=self._initial_pos, + scale=(self._width / 2.0, 1, self._height / 2.0)) + + if transparent: + self.node.set_transparency(TransparencyAttrib.M_alpha) + + tex = self.node.get_texture() + + # Apply a near filter, but only if the parent has no scale, otherwise + # it will look weird + if near_filter and any_filter and parent.get_sx() == 1.0: + tex.set_minfilter(SamplerState.FT_nearest) + tex.set_magfilter(SamplerState.FT_nearest) + + if any_filter: + tex.set_anisotropic_degree(8) + tex.set_wrap_u(SamplerState.WM_clamp) + tex.set_wrap_v(SamplerState.WM_clamp) + + def get_initial_pos(self): + """ Returns the initial position of the image. This can be used for + animations """ + return self._initial_pos + + def pos_interval(self, *args, **kwargs): + """ Returns a pos interval, this is a wrapper around + NodePath.posInterval """ + return self.node.posInterval(*args, **kwargs) + + def hpr_interval(self, *args, **kwargs): + """ Returns a hpr interval, this is a wrapper around + NodePath.hprInterval """ + return self.node.hprInterval(*args, **kwargs) + + def color_scale_interval(self, *args, **kwargs): + """ Returns a color scale interval, this is a wrapper around + NodePath.colorScaleInterval """ + return self.node.colorScaleInterval(*args, **kwargs) + + def set_image(self, img): + """ Sets the current image """ + self.node.set_image(img) + + def get_width(self): + """ Returns the width of the image in pixels """ + return self._width + + def get_height(self): + """ Returns the height of the image in pixels """ + return self._height + + def set_pos(self, x, y): + """ Sets the position """ + self.node.set_pos(self._translate_pos(x, y)) + + def _translate_pos(self, x, y): + """ Converts 2d coordinates to pandas coordinate system """ + return Vec3(x + self._width / 2.0, 1, -y - self._height / 2.0) + + def set_shader(self, shader): + """ Sets a shader to be used for rendering the image """ + self.node.set_shader(shader) + + def set_shader_input(self, *args): + """ Sets a shader input on the image """ + self.node.set_shader_input(*args) + + def set_shader_inputs(self, **kwargs): + """ Sets multiple shader inputs on the image """ + self.node.set_shader_inputs(**kwargs) + + def remove(self): + """ Removes the image """ + self.node.remove() + + def hide(self): + """ Hides the image """ + self.node.hide() + + def show(self): + """ Shows the image if it was previously hidden """ + self.node.show() + + def is_hidden(self): + """ Returns whether the image is hidden """ + return self.node.is_hidden() diff --git a/rpcore/gui/text.py b/rpcore/gui/text.py new file mode 100644 index 0000000..a41a706 --- /dev/null +++ b/rpcore/gui/text.py @@ -0,0 +1,83 @@ +""" + +RenderPipeline + +Copyright (c) 2014-2016 tobspr + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. + +""" + +from panda3d.core import Vec2, Vec3, TextNode, Vec4 +from direct.gui.OnscreenText import OnscreenText + +from rpcore.globals import Globals +from rpcore.rpobject import RPObject + + +class Text(RPObject): + + """ Simple wrapper around OnscreenText, providing a simpler interface """ + + def __init__(self, text="", parent=None, x=0, y=0, size=10, align="left", + color=None, may_change=False, font=None): + """ Constructs a new text. The parameters are almost equal to the + parameters of OnscreenText """ + RPObject.__init__(self) + + if color is None: + color = Vec3(1) + + align_mode = TextNode.A_left + + if align == "center": + align_mode = TextNode.A_center + elif align == "right": + align_mode = TextNode.A_right + + if font is None: + font = Globals.font + # Should always have a global font. Never use the default panda font! + assert font + + self._initial_pos = Vec2(x, -y) + self._node = OnscreenText( + text=text, parent=parent, pos=self._initial_pos, scale=size, + align=align_mode, fg=Vec4(color.x, color.y, color.z, 1.0), + font=font, mayChange=may_change) + + @property + def node(self): + """ Returns a handle to the internlally used node """ + return self._node + + def set_text(self, text): + """ Changes the text, remember to pass may_change to the constructor, + otherwise this method does not work. """ + self._node["text"] = text + + def get_initial_pos(self): + """ Returns the initial position of the text. This can be used for + animations """ + return self._initial_pos + + def pos_interval(self, *args, **kwargs): + """ Returns a pos interval, this is a wrapper around + NodePath.pos_interval """ + return self._node.pos_interval(*args, **kwargs) diff --git a/rpcore/gui/text_node.py b/rpcore/gui/text_node.py new file mode 100644 index 0000000..caae482 --- /dev/null +++ b/rpcore/gui/text_node.py @@ -0,0 +1,87 @@ +""" + +RenderPipeline + +Copyright (c) 2014-2016 tobspr + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. + +""" + + +from panda3d.core import Vec2, Vec3, Vec4 +from panda3d.core import TextNode as TextNodeImpl + +from rpcore.globals import Globals +from rpcore.rpobject import RPObject +from rpcore.loader import RPLoader + + +class TextNode(RPObject): + + """ Interface for the Panda3D TextNode. """ + + def __init__(self, font="/$$rp/data/font/Roboto-Bold.ttf", pixel_size=16, align="left", + pos=Vec2(0), color=Vec3(1), parent=None): + """ Constructs a new text node, forwaring the parameters to the internal + panda3d implementation """ + RPObject.__init__(self) + self._node = TextNodeImpl('FTN') + self._node.set_text("") + self._node.set_align(getattr(TextNodeImpl, "A_" + align)) + self._node.set_text_color(color.x, color.y, color.z, 1) + + if parent is None: + parent = Globals.base.aspect2d + + self._nodepath = parent.attach_new_node(self._node) + self._nodepath.set_pos(pos.x, 0, pos.y) + + font = RPLoader.load_font(font) + # font.set_outline(Vec4(0, 0, 0, 0.78), 1.6, 0.37) + font.set_outline(Vec4(0, 0, 0, 1), 1.6, 0.37) + font.set_scale_factor(1.0) + font.set_texture_margin(int(pixel_size / 4.0 * 2.0)) + font.set_bg(Vec4(0, 0, 0, 0)) + self._node.set_font(font) + self.set_pixel_size(pixel_size) + + @property + def text(self): + """ Returns the current text """ + return self._node.get_text() + + @text.setter + def text(self, text): + """ Sets the current text """ + self._node.set_text(text) + + @property + def color(self): + """ Returns the current text color """ + return self._node.get_text_color() + + @color.setter + def color(self, val): + """ Sets the current text color """ + self._node.set_text_color(val) + + def set_pixel_size(self, size): + """ Sets the text size in pixels """ + self._nodepath.set_scale(size * 2.0 / float(Globals.native_resolution.y)) diff --git a/rpcore/gui/texture_preview.py b/rpcore/gui/texture_preview.py new file mode 100644 index 0000000..52013e9 --- /dev/null +++ b/rpcore/gui/texture_preview.py @@ -0,0 +1,182 @@ +""" + +RenderPipeline + +Copyright (c) 2014-2016 tobspr + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. + +""" + +from panda3d.core import Vec3 + +from rpcore.image import Image +from rpcore.gui.draggable_window import DraggableWindow +from rpcore.gui.sprite import Sprite +from rpcore.gui.text import Text +from rpcore.gui.slider import Slider +from rpcore.gui.labeled_checkbox import LabeledCheckbox + +from rpcore.util.display_shader_builder import DisplayShaderBuilder + + +class TexturePreview(DraggableWindow): + + """ Small window which provides a preview of a texture """ + def __init__(self, pipeline, parent): + DraggableWindow.__init__(self, width=1600, height=900, parent=parent, + title="Texture Viewer") + self._pipeline = pipeline + self._current_tex = None + self._mip_slider = None + self._mip_text = None + self._slice_slider = None + self._slice_text = None + self._preview_image = None + self._create_components() + + def present(self, tex): + """ "Presents" a given texture and shows the window """ + self._current_tex = tex + + self.set_title(tex.get_name()) + + # tex.write(tex.get_name() + ".png") + + # Remove old content + self._content_node.node().remove_all_children() + + w, h = tex.get_x_size(), tex.get_y_size() + if h > 1: + scale_x = (self._width - 40.0) / w + scale_y = (self._height - 110.0) / h + scale_f = min(scale_x, scale_y) + display_w = scale_f * w + display_h = scale_f * h + + else: + display_w = self._width - 40 + display_h = self._height - 110 + + image = Sprite( + image=tex, parent=self._content_node, x=20, y=90, w=display_w, + h=display_h, any_filter=False, transparent=False) + description = "" + + # Image size + description += "{:d} x {:d} x {:d}".format( + tex.get_x_size(), tex.get_y_size(), tex.get_z_size()) + + # Image type + description += ", {:s}, {:s}".format( + Image.format_format(tex.get_format()).upper(), + Image.format_component_type(tex.get_component_type()).upper()) + + Text(text=description, parent=self._content_node, x=17, y=70, + size=16, color=Vec3(0.6, 0.6, 0.6)) + + estimated_bytes = tex.estimate_texture_memory() + size_desc = "Estimated memory: {:2.2f} MB".format( + estimated_bytes / (1024.0 ** 2)) + + Text(text=size_desc, parent=self._content_node, x=self._width - 20.0, + y=70, size=18, color=Vec3(0.34, 0.564, 0.192), align="right") + + x_pos = len(size_desc) * 9 + 140 + + # Slider for viewing different mipmaps + if tex.uses_mipmaps(): + max_mips = tex.get_expected_num_mipmap_levels() - 1 + self._mip_slider = Slider( + parent=self._content_node, size=140, min_value=0, max_value=max_mips, + callback=self._set_mip, x=x_pos, y=65, value=0) + x_pos += 140 + 5 + + self._mip_text = Text( + text="MIP: 5", parent=self._content_node, x=x_pos, y=72, size=18, + color=Vec3(1, 0.4, 0.4), may_change=1) + x_pos += 50 + 30 + + # Slider for viewing different Z-layers + if tex.get_z_size() > 1: + self._slice_slider = Slider( + parent=self._content_node, size=250, min_value=0, + max_value=tex.get_z_size() - 1, callback=self._set_slice, x=x_pos, + y=65, value=0) + x_pos += 250 + 5 + + self._slice_text = Text( + text="Z: 5", parent=self._content_node, x=x_pos, y=72, size=18, + color=Vec3(0.4, 1, 0.4), may_change=1) + + x_pos += 50 + 30 + + # Slider to adjust brightness + self._bright_slider = Slider( + parent=self._content_node, size=140, min_value=-14, max_value=14, + callback=self._set_brightness, x=x_pos, y=65, value=0) + x_pos += 140 + 5 + self._bright_text = Text( + text="Bright: 1", parent=self._content_node, x=x_pos, y=72, size=18, + color=Vec3(0.4, 0.4, 1), may_change=1) + x_pos += 100 + 30 + + # Slider to enable reinhard tonemapping + self._tonemap_box = LabeledCheckbox( + parent=self._content_node, x=x_pos, y=60, text="Tonemap", + text_color=Vec3(1, 0.4, 0.4), chb_checked=False, + chb_callback=self._set_enable_tonemap, + text_size=18, expand_width=90) + x_pos += 90 + 30 + + image.set_shader_inputs( + slice=0, + mipmap=0, + brightness=1, + tonemap=False) + + preview_shader = DisplayShaderBuilder.build(tex, display_w, display_h) + image.set_shader(preview_shader) + + self._preview_image = image + self.show() + + def _set_slice(self): + idx = int(self._slice_slider.value) + self._preview_image.set_shader_input("slice", idx) + self._slice_text.set_text("Z: " + str(idx)) + + def _set_mip(self): + idx = int(self._mip_slider.value) + self._preview_image.set_shader_input("mipmap", idx) + self._mip_text.set_text("MIP " + str(idx)) + + def _set_brightness(self): + val = self._bright_slider.value + scale = 2 ** val + self._bright_text.set_text("Bright: " + str(round(scale, 3))) + self._preview_image.set_shader_input("brightness", scale) + + def _set_enable_tonemap(self, enable_tonemap): + self._preview_image.set_shader_input("tonemap", enable_tonemap) + + def _create_components(self): + """ Internal method to init the components """ + DraggableWindow._create_components(self) + self._content_node = self._node.attach_new_node("content") diff --git a/rpcore/image.py b/rpcore/image.py new file mode 100644 index 0000000..5910fc0 --- /dev/null +++ b/rpcore/image.py @@ -0,0 +1,158 @@ +""" + +RenderPipeline + +Copyright (c) 2014-2016 tobspr + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. + +""" + +from panda3d.core import Texture, GeomEnums + +from rpcore.rpobject import RPObject +from rpcore.globals import Globals +from rpcore.render_target import RenderTarget + + +class ImageFormatTypes(object): # pylint: disable=too-few-public-methods + + """ This is a small helper class to prevent pylint errors about the Image + class not defining the enums. This class just copies the enum properties + from panda3d's builtin Texture class. """ + + T_float = Texture.T_float + T_unsigned_byte = Texture.T_unsigned_byte + T_int = Texture.T_int + T_unsigned_short = Texture.T_unsigned_short + T_unsigned_int_24_8 = Texture.T_unsigned_int_24_8 + + TT_buffer_texture = Texture.TT_buffer_texture + TT_2d_texture = Texture.TT_2d_texture + TT_3d_texture = Texture.TT_3d_texture + TT_cube_map = Texture.TT_cube_map + TT_cube_map_array = Texture.TT_cube_map_array + TT_2d_texture_array = Texture.TT_2d_texture_array + + format_format = Texture.format_format + format_component_type = Texture.format_component_type + + +class Image(RPObject, Texture, ImageFormatTypes): + + """ This is a wrapper arround the Texture class from Panda3D, which keeps + track of all images and registers / unregisters them aswell as counting + the memory used. This is used by all classes instead of pandas builtin + Texture class. """ + + # All registered images + REGISTERED_IMAGES = [] + + # String formats + FORMAT_MAPPINGS = { + "R11G11B10": (Texture.T_float, Texture.F_r11_g11_b10), + "RGBA8": (Texture.T_unsigned_byte, Texture.F_rgba8), + "RGBA16": (Texture.T_float, Texture.F_rgba16), + "RGBA32": (Texture.T_float, Texture.F_rgba32), + "R8": (Texture.T_unsigned_byte, Texture.F_red), + "R8UI": (Texture.T_unsigned_byte, Texture.F_red), + "R16": (Texture.T_float, Texture.F_r16), + "R16UI": (Texture.T_unsigned_short, Texture.F_r16i), + "R32": (Texture.T_float, Texture.F_r32), + "R32I": (Texture.T_int, Texture.F_r32i), + } + + @classmethod + def create_buffer(cls, name, size, component_format): + """ Creates a new buffer texture """ + img = cls("ImgBuffer-" + name) + comp_type, comp_format = cls.convert_texture_format(component_format) + img.setup_buffer_texture(size, comp_type, comp_format, GeomEnums.UH_static) + return img + + @classmethod + def create_counter(cls, name): + """ Creates a new 1x1 R32I texture to be used as an atomic counter """ + return cls.create_buffer(name, 1, "R32I") + + @classmethod + def create_2d(cls, name, w, h, component_format): + """ Creates a new 2D texture """ + img = cls("Img2D-" + name) + comp_type, comp_format = cls.convert_texture_format(component_format) + img.setup_2d_texture(w, h, comp_type, comp_format) + return img + + @classmethod + def create_2d_array(cls, name, w, h, slices, component_format): + """ Creates a new 2D-array texture """ + img = cls("Img2DArr-" + name) + comp_type, comp_format = cls.convert_texture_format(component_format) + img.setup_2d_texture_array(w, h, slices, comp_type, comp_format) + return img + + @classmethod + def create_3d(cls, name, w, h, slices, component_format): + """ Creates a new 3D texture """ + img = cls("Img3D-" + name) + comp_type, comp_format = cls.convert_texture_format(component_format) + img.setup_3d_texture(w, h, slices, comp_type, comp_format) + return img + + @classmethod + def create_cube(cls, name, size, component_format): + """ Creates a new cubemap """ + img = cls("ImgCube-" + name) + comp_type, comp_format = cls.convert_texture_format(component_format) + img.setup_cube_map(size, comp_type, comp_format) + return img + + @classmethod + def create_cube_array(cls, name, size, num_cubemaps, component_format): + """ Creates a new cubemap """ + img = cls("ImgCubeArr-" + name) + comp_type, comp_format = cls.convert_texture_format(component_format) + img.setup_cube_map_array(size, num_cubemaps, comp_type, comp_format) + return img + + @classmethod + def convert_texture_format(cls, comp_type): + """ Converts a string like 'RGBA8' to a texture type and format """ + return cls.FORMAT_MAPPINGS[comp_type] + + def __init__(self, name): + """ Internal method to create a new image """ + RPObject.__init__(self, name) + Texture.__init__(self, name) + Image.REGISTERED_IMAGES.append(self) + self.set_clear_color(0) + self.clear_image() + self.sort = RenderTarget.CURRENT_SORT + + def __del__(self): + """ Destroys the image """ + self.warn("Image destructor not implemented yet") + + def write(self, pth): + """ Writes the image to disk """ + Globals.base.graphicsEngine.extract_texture_data(self, Globals.base.win.gsg) + if self.get_texture_type() in [Texture.TT_3d_texture, Texture.TT_cube_map]: + Texture.write(self, "#_" + pth, 0, 0, True, False) + else: + Texture.write(self, pth) diff --git a/rpcore/light_manager.py b/rpcore/light_manager.py new file mode 100644 index 0000000..b24ec00 --- /dev/null +++ b/rpcore/light_manager.py @@ -0,0 +1,207 @@ +""" + +RenderPipeline + +Copyright (c) 2014-2016 tobspr + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. + +""" + +import math + +from panda3d.core import LVecBase2i, PTAInt + +from rpcore.globals import Globals +from rpcore.gpu_command_queue import GPUCommandQueue +from rpcore.image import Image +from rpcore.native import InternalLightManager, PointLight, ShadowManager +from rpcore.rpobject import RPObject + +from rpcore.stages.apply_lights_stage import ApplyLightsStage +from rpcore.stages.collect_used_cells_stage import CollectUsedCellsStage +from rpcore.stages.cull_lights_stage import CullLightsStage +from rpcore.stages.flag_used_cells_stage import FlagUsedCellsStage +from rpcore.stages.shadow_stage import ShadowStage + + +class LightManager(RPObject): + + """ This class is a wrapper around the InternalLightManager, and provides + additional functionality like setting up all required stages and defines.""" + + # Maximum amount of lights, has to match the definitions in the native code + MAX_LIGHTS = 65535 + + # Maximum amount of shadow sources + MAX_SOURCES = 2048 + + def __init__(self, pipeline): + """ Constructs the light manager """ + RPObject.__init__(self) + self.pipeline = pipeline + self.compute_tile_size() + self.init_internal_manager() + self.init_command_queue() + self.init_shadow_manager() + self.init_stages() + + @property + def total_tiles(self): + """ Returns the total amount of tiles """ + return self.num_tiles.x * self.num_tiles.y * \ + self.pipeline.settings["lighting.culling_grid_slices"] + + @property + def num_lights(self): + """ Returns the amount of stored lights """ + return self.internal_mgr.num_lights + + @property + def num_shadow_sources(self): + """ Returns the amount of stored shadow sources """ + return self.internal_mgr.num_shadow_sources + + @property + def shadow_atlas_coverage(self): + """ Returns the shadow atlas coverage in percentage """ + return self.internal_mgr.shadow_manager.atlas.coverage * 100.0 + + def add_light(self, light): + """ Adds a new light """ + self.internal_mgr.add_light(light) + self.pta_max_light_index[0] = self.internal_mgr.max_light_index + + def remove_light(self, light): + """ Removes a light """ + self.internal_mgr.remove_light(light) + self.pta_max_light_index[0] = self.internal_mgr.max_light_index + + def update(self): + """ Main update method to process the GPU commands """ + self.internal_mgr.set_camera_pos( + Globals.base.camera.get_pos(Globals.base.render)) + self.internal_mgr.update() + self.shadow_manager.update() + self.cmd_queue.process_queue() + + def reload_shaders(self): + """ Reloads all assigned shaders """ + self.cmd_queue.reload_shaders() + + def compute_tile_size(self): + """ Computes how many tiles there are on screen """ + self.tile_size = LVecBase2i( + self.pipeline.settings["lighting.culling_grid_size_x"], + self.pipeline.settings["lighting.culling_grid_size_y"]) + num_tiles_x = int(math.ceil(Globals.resolution.x / float(self.tile_size.x))) + num_tiles_y = int(math.ceil(Globals.resolution.y / float(self.tile_size.y))) + self.debug("Tile size =", self.tile_size.x, "x", self.tile_size.y, + ", Num tiles =", num_tiles_x, "x", num_tiles_y) + self.num_tiles = LVecBase2i(num_tiles_x, num_tiles_y) + + def init_command_queue(self): + """ Inits the command queue """ + self.cmd_queue = GPUCommandQueue(self.pipeline) + self.cmd_queue.register_input("LightData", self.img_light_data) + self.cmd_queue.register_input("SourceData", self.img_source_data) + self.internal_mgr.set_command_list(self.cmd_queue.command_list) + + def init_shadow_manager(self): + """ Inits the shadow manager """ + self.shadow_manager = ShadowManager() + self.shadow_manager.set_max_updates(self.pipeline.settings["shadows.max_updates"]) + self.shadow_manager.set_scene(Globals.base.render) + self.shadow_manager.set_tag_state_manager(self.pipeline.tag_mgr) + self.shadow_manager.atlas_size = self.pipeline.settings["shadows.atlas_size"] + self.internal_mgr.shadow_manager = self.shadow_manager + + def init_shadows(self): + """ Inits the shadows, this has to get called after the stages were + created, because we need the GraphicsOutput of the shadow atlas, which + is not available earlier """ + self.shadow_manager.set_atlas_graphics_output(self.shadow_stage.atlas_buffer) + self.shadow_manager.init() + + def init_internal_manager(self): + """ Creates the light storage manager and the buffer to store the light data """ + self.internal_mgr = InternalLightManager() + self.internal_mgr.set_shadow_update_distance( + self.pipeline.settings["shadows.max_update_distance"]) + + # Storage for the Lights + per_light_vec4s = 4 + self.img_light_data = Image.create_buffer( + "LightData", self.MAX_LIGHTS * per_light_vec4s, "RGBA16") + self.img_light_data.clear_image() + + self.pta_max_light_index = PTAInt.empty_array(1) + self.pta_max_light_index[0] = 0 + + # Storage for the shadow sources + per_source_vec4s = 5 + + # IMPORTANT: RGBA32 is really required here. Otherwise artifacts and bad + # shadow filtering occur due to precision issues + self.img_source_data = Image.create_buffer( + "ShadowSourceData", self.MAX_SOURCES * per_source_vec4s, "RGBA32") + self.img_light_data.clear_image() + + # Register the buffer + inputs = self.pipeline.stage_mgr.inputs + inputs["AllLightsData"] = self.img_light_data + inputs["ShadowSourceData"] = self.img_source_data + inputs["maxLightIndex"] = self.pta_max_light_index + + def init_stages(self): + """ Inits all required stages for the lighting """ + + add_stage = self.pipeline.stage_mgr.add_stage + + self.flag_cells_stage = FlagUsedCellsStage(self.pipeline) + add_stage(self.flag_cells_stage) + + self.collect_cells_stage = CollectUsedCellsStage(self.pipeline) + add_stage(self.collect_cells_stage) + + self.cull_lights_stage = CullLightsStage(self.pipeline) + add_stage(self.cull_lights_stage) + + self.apply_lights_stage = ApplyLightsStage(self.pipeline) + add_stage(self.apply_lights_stage) + + self.shadow_stage = ShadowStage(self.pipeline) + self.shadow_stage.size = self.shadow_manager.get_atlas_size() + add_stage(self.shadow_stage) + + def init_defines(self): + """ Inits the common defines """ + defines = self.pipeline.stage_mgr.defines + defines["LC_TILE_SIZE_X"] = self.tile_size.x + defines["LC_TILE_SIZE_Y"] = self.tile_size.y + defines["LC_TILE_SLICES"] = self.pipeline.settings["lighting.culling_grid_slices"] + defines["LC_MAX_DISTANCE"] = self.pipeline.settings["lighting.culling_max_distance"] + defines["LC_CULLING_SLICE_WIDTH"] = self.pipeline.settings["lighting.culling_slice_width"] + defines["LC_MAX_LIGHTS_PER_CELL"] = self.pipeline.settings["lighting.max_lights_per_cell"] + defines["SHADOW_ATLAS_SIZE"] = self.pipeline.settings["shadows.atlas_size"] + + # Register all light types as defines + for attr in dir(PointLight): + if attr.startswith("LT_"): + defines[attr.upper()] = getattr(PointLight, attr) diff --git a/rpcore/loader.py b/rpcore/loader.py new file mode 100644 index 0000000..082c0df --- /dev/null +++ b/rpcore/loader.py @@ -0,0 +1,145 @@ +""" + +RenderPipeline + +Copyright (c) 2014-2016 tobspr + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. + +""" + +from __future__ import print_function + +import time + +from panda3d.core import PNMImage, VirtualFileSystem, VirtualFileMountRamdisk +from panda3d.core import Shader + +from rpcore.globals import Globals +from rpcore.rpobject import RPObject + +__all__ = ("RPLoader",) + + +class timed_loading_operation(object): # noqa # pylint: disable=invalid-name,too-few-public-methods + + """ Context manager for a synchronous loading operation, keeping track + on how much time elapsed during the loading process, and warning about + long loading times. """ + + WARNING_COUNT = 0 + + def __init__(self, resource): + self.resource = resource + if isinstance(self.resource, (list, tuple)): + self.resource = ', '.join(self.resource) + + def __enter__(self): + self.start_time = time.process_time() + + def __exit__(self, *args): + duration = (time.process_time() - self.start_time) * 1000.0 + if duration > 200.0 and timed_loading_operation.WARNING_COUNT < 5: + RPObject.global_warn("RPLoader", "Loading '" + self.resource + "' took", round(duration, 2), "ms") + timed_loading_operation.WARNING_COUNT += 1 + if timed_loading_operation.WARNING_COUNT == 5: + RPObject.global_warn("RPLoader", "Skipping further loading warnings (max warning count reached)") + + +class RPLoader(RPObject): + + """ Generic loader class used by the pipeline. All loading of assets happens + here, which enables us to keep track of used resources """ + + @classmethod + def load_texture(cls, filename): + """ Loads a 2D-texture from disk """ + with timed_loading_operation(filename): + return Globals.base.loader.load_texture(filename) + + @classmethod + def load_cube_map(cls, filename, read_mipmaps=False): + """ Loads a cube map from disk """ + with timed_loading_operation(filename): + return Globals.base.loader.load_cube_map(filename, readMipmaps=read_mipmaps) + + @classmethod + def load_3d_texture(cls, filename): + """ Loads a 3D-texture from disk """ + with timed_loading_operation(filename): + return Globals.base.loader.load_3d_texture(filename) + + @classmethod + def load_font(cls, filename): + """ Loads a font from disk """ + with timed_loading_operation(filename): + return Globals.base.loader.load_font(filename) + + @classmethod + def load_shader(cls, *args): + """ Loads a shader from disk """ + with timed_loading_operation(args): + if len(args) == 1: + return Shader.load_compute(Shader.SL_GLSL, args[0]) + return Shader.load(Shader.SL_GLSL, *args) + + @classmethod + def load_model(cls, filename): + """ Loads a model from disk """ + with timed_loading_operation(filename): + return Globals.base.loader.load_model(filename) + + @classmethod + def load_sliced_3d_texture(cls, fname, tile_size_x, tile_size_y=None, num_tiles=None): + """ Loads a texture from the given filename and dimensions. If only + one dimensions is specified, the other dimensions are assumed to be + equal. This internally loads the texture into ram, splits it into smaller + sub-images, and then calls the load_3d_texture from the Panda loader """ + + tempfile_name = "/$$slice_loader_temp-" + str(time.time()) + "/" + tile_size_y = tile_size_x if tile_size_y is None else tile_size_y + num_tiles = tile_size_x if num_tiles is None else num_tiles + + # Load sliced image from disk + tex_handle = cls.load_texture(fname) + source = PNMImage() + tex_handle.store(source) + width = source.get_x_size() + + # Find slice properties + num_cols = width // tile_size_x + temp_img = PNMImage(tile_size_x, tile_size_y, source.get_num_channels(), source.get_maxval()) + + # Construct a ramdisk to write the files to + vfs = VirtualFileSystem.get_global_ptr() + ramdisk = VirtualFileMountRamdisk() + vfs.mount(ramdisk, tempfile_name, 0) + + # Extract all slices and write them to the virtual disk + for z_slice in range(num_tiles): + slice_x = (z_slice % num_cols) * tile_size_x + slice_y = (z_slice // num_cols) * tile_size_y + temp_img.copy_sub_image(source, 0, 0, slice_x, slice_y, tile_size_x, tile_size_y) + temp_img.write(tempfile_name + str(z_slice) + ".png") + + # Load the de-sliced texture from the ramdisk + texture_handle = cls.load_3d_texture(tempfile_name + "/#.png") + vfs.unmount(ramdisk) + + return texture_handle diff --git a/rpcore/mount_manager.py b/rpcore/mount_manager.py new file mode 100644 index 0000000..5deaef4 --- /dev/null +++ b/rpcore/mount_manager.py @@ -0,0 +1,316 @@ +""" + +RenderPipeline + +Copyright (c) 2014-2016 tobspr + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. + +""" + +import os +import atexit + +from panda3d.core import Filename, VirtualFileSystem, get_model_path +from panda3d.core import VirtualFileMountRamdisk +from direct.stdpy.file import join, isdir, isfile + +from rpcore.rpobject import RPObject + + +class MountManager(RPObject): + + """ This classes mounts the required directories for the pipeline to run. + This is important if the pipeline is in a subdirectory for example. The + mount manager also handles the lock, storing the current PID into a file + named instance.pid and ensuring that there is only 1 instance of the + pipeline running at one time. """ + + def __init__(self, pipeline): + """ Creates a new mount manager """ + RPObject.__init__(self) + self._pipeline = pipeline + self._base_path = self._find_basepath() + self._lock_file = "instance.pid" + self._model_paths = [] + self._write_path = None + self._mounted = False + self._do_cleanup = True + self._config_dir = None + + self.debug("Auto-Detected base path to", self._base_path) + atexit.register(self._on_exit_cleanup) + + @property + def write_path(self): + """ Returns the write path previously set with set_write_path, or None + if no write path has been set yet. """ + return self._write_path + + @write_path.setter + def write_path(self, pth): + """ Set a writable directory for generated files. This can be a string + path name or a multifile with openReadWrite(). If no pathname is set + then the root directory is used. + + This feature is usually only used for debugging, the pipeline will dump + all generated shaders and other temporary files to that directory. + If you don't need this, you can use set_virtual_write_path(), which + will create the temporary path in the VirtualFileSystem, thus not + writing any files to disk. """ + if pth is None: + self._write_path = None + self._lock_file = "instance.pid" + else: + self._write_path = Filename.from_os_specific(pth).get_fullpath() + self._lock_file = join(self._write_path, "instance.pid") + + @property + def base_path(self): + """ Returns the base path of the pipeline. This returns the path previously + set with set_base_path, or the auto detected base path if no path was + set yet """ + return self._base_path + + @base_path.setter + def base_path(self, pth): + """ Sets the path where the base shaders and models on are contained. This + is usually the root of the rendering pipeline folder """ + self.debug("Set base path to '" + pth + "'") + self._base_path = Filename.from_os_specific(pth).get_fullpath() + + @property + def config_dir(self): + """ Returns the config directory previously set with set_config_dir, or + None if no directory was set yet """ + + @config_dir.setter + def config_dir(self, pth): + """ Sets the path to the config directory. Usually this is the config/ + directory located in the pipeline root directory. However, if you want + to load your own configuration files, you can specify a custom config + directory here. Your configuration directory should contain the + pipeline.yaml, plugins.yaml, daytime.yaml and configuration.prc. + + It is highly recommended you use the pipeline provided config files, modify + them to your needs, and as soon as you think they are in a final version, + copy them over. Please also notice that you should keep your config files + up-to-date, e.g. when new configuration variables are added. + + Also, specifying a custom configuration_dir disables the functionality + of the PluginConfigurator and DayTime editor, since they operate on the + pipelines default config files. + + Set the directory to None to use the default directory. """ + self._config_dir = Filename.from_os_specific(pth).get_fullpath() + + @property + def do_cleanup(self): + """ Returns whether the mount manager will attempt to cleanup the + generated files after the application stopped running """ + return self._do_cleanup + + @do_cleanup.setter + def do_cleanup(self, cleanup): + """ Sets whether to cleanup the tempfolder after the application stopped. + This is mostly useful for debugging, to analyze the generated tempfiles + even after the pipeline stopped running """ + self._do_cleanup = cleanup + + def get_lock(self): + """ Checks if we are the only instance running. If there is no instance + running, write the current PID to the instance.pid file. If the + instance file exists, checks if the specified process still runs. This + way only 1 instance of the pipeline can be run at one time. """ + + # Check if there is a lockfile at all + if isfile(self._lock_file): + # Read process id from lockfile + try: + with open(self._lock_file, "r") as handle: + pid = int(handle.readline()) + except IOError as msg: + self.error("Failed to read lockfile:", msg) + return False + + # Check if the process is still running + if self._is_pid_running(pid): + self.error("Found running instance") + return False + + # Process is not running anymore, we can write the lockfile + self._write_lock() + return True + + else: + # When there is no lockfile, just create it and continue + self._write_lock() + return True + + def _find_basepath(self): + """ Attempts to find the pipeline base path by looking at the location + of this file """ + pth = os.path.abspath(join(os.path.dirname(os.path.realpath(__file__)), "..")) + return Filename.from_os_specific(pth).get_fullpath() + + def _is_pid_running(self, pid): + """ Checks if a pid is still running """ + + # Code snippet from: + # http://stackoverflow.com/questions/568271/how-to-check-if-there-exists-a-process-with-a-given-pid + + if os.name == 'posix': + import errno + if pid < 0: + return False + try: + os.kill(pid, 0) + except OSError as err: + return err.errno == errno.EPERM + else: + return True + else: + import ctypes + kernel32 = ctypes.windll.kernel32 + process = kernel32.OpenProcess(0x100000, 0, pid) + if process != 0: + kernel32.CloseHandle(process) + return True + else: + return False + + def _write_lock(self): + """ Internal method to write the current process id to the instance.pid + lockfile. This is used to ensure no second instance of the pipeline is + running. """ + + with open(self._lock_file, "w") as handle: + handle.write(str(os.getpid())) + + def _try_remove(self, fname): + """ Tries to remove the specified filename, returns either True or False + depending if we had success or not """ + try: + os.remove(fname) + return True + except (IOError, OSError): + pass + return False + + def _on_exit_cleanup(self): + """ Gets called when the application exists """ + + if self._do_cleanup: + self.debug("Cleaning up ..") + + if self._write_path is not None: + + # Try removing the lockfile + self._try_remove(self._lock_file) + + # Check for further tempfiles in the write path + # We explicitely use os.listdir here instead of pandas listdir, + # to work with actual paths + for fname in os.listdir(self._write_path): + pth = join(self._write_path, fname) + + # Tempfiles from the pipeline start with "$$" to distinguish + # them from user created files + if isfile(pth) and fname.startswith("$$"): + self._try_remove(pth) + + # Delete the write path if no files are left + if len(os.listdir(self._write_path)) < 1: + try: + os.removedirs(self._write_path) + except IOError: + pass + + @property + def is_mounted(self): + """ Returns whether the MountManager was already mounted by calling + mount() """ + return self._mounted + + def mount(self): + """ Inits the VFS Mounts. This creates the following virtual directory + structure, from which all files can be located: + + /$$rp/ (Mounted from the render pipeline base directory) + + rpcore/ + + shader/ + + ... + + /$rpconfig/ (Mounted from config/, may be set by user) + + pipeline.yaml + + ... + + /$$rptemp/ (Either ramdisk or user specified) + + day_time_config + + shader_auto_config + + ... + + /$$rpshader/ (Link to /$$rp/rpcore/shader) + + """ + self.debug("Setting up virtual filesystem") + self._mounted = True + + def convert_path(pth): + return Filename.from_os_specific(pth).get_fullpath() + vfs = VirtualFileSystem.get_global_ptr() + + # Mount config dir as $$rpconf + if self._config_dir is None: + config_dir = convert_path(join(self._base_path, "config/")) + self.debug("Mounting auto-detected config dir:", config_dir) + vfs.mount(config_dir, "/$$rpconfig", 0) + else: + self.debug("Mounting custom config dir:", self._config_dir) + vfs.mount(convert_path(self._config_dir), "/$$rpconfig", 0) + + # Mount directory structure + vfs.mount(convert_path(self._base_path), "/$$rp", 0) + vfs.mount(convert_path(join(self._base_path, "rpcore/shader")), "/$$rp/shader", 0) + vfs.mount(convert_path(join(self._base_path, "effects")), "effects", 0) + + # Mount the pipeline temp path: + # If no write path is specified, use a virtual ramdisk + if self._write_path is None: + self.debug("Mounting ramdisk as /$$rptemp") + vfs.mount(VirtualFileMountRamdisk(), "/$$rptemp", 0) + else: + # In case an actual write path is specified: + # Ensure the pipeline write path exists, and if not, create it + if not isdir(self._write_path): + self.debug("Creating temporary path, since it does not exist yet") + try: + os.makedirs(self._write_path) + except IOError as msg: + self.fatal("Failed to create temporary path:", msg) + self.debug("Mounting", self._write_path, "as /$$rptemp") + vfs.mount(convert_path(self._write_path), '/$$rptemp', 0) + + get_model_path().prepend_directory("/$$rp") + get_model_path().prepend_directory("/$$rp/shader") + get_model_path().prepend_directory("/$$rptemp") + + def unmount(self): + """ Unmounts the VFS """ + raise NotImplementedError("TODO") diff --git a/rpcore/native/.gitignore b/rpcore/native/.gitignore new file mode 100644 index 0000000..a2c9784 --- /dev/null +++ b/rpcore/native/.gitignore @@ -0,0 +1,19 @@ + +# Prefab gitignore which can be used by the user to ignore the files generated +# by the module builder + +*.pyd +*.pyc +*.so +*.pdb + +# Various output names +win_*/ +linux_*/ +source/interrogate* + +# Source and script files +scripts/ +CMakeLists.txt +build.py +LICENSE diff --git a/rpcore/native/__init__.py b/rpcore/native/__init__.py new file mode 100644 index 0000000..3ba9d57 --- /dev/null +++ b/rpcore/native/__init__.py @@ -0,0 +1,95 @@ +""" + +RenderPipeline + +Copyright (c) 2014-2016 tobspr + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. + +""" + +# pylint: disable=invalid-name + +# This file includes all modules from the native module. + +from __future__ import print_function +import sys +from os.path import dirname, realpath + +from direct.stdpy.file import join, isfile +from rpcore.rpobject import RPObject + +# Store a global flag, indicating whether the C++ modules were loaded or the python +# implemetation of them +NATIVE_CXX_LOADED = False + +# Read the configuration from the flag-file +current_path = dirname(realpath(__file__)) +cxx_flag_path = join(current_path, "use_cxx.flag") +if not isfile(cxx_flag_path): + RPObject.global_error("CORE", "Could not find cxx flag, please run the setup.py!") + sys.exit(1) +else: + with open(join(current_path, "use_cxx.flag"), "r") as handle: + NATIVE_CXX_LOADED = handle.read().strip() == "1" + +# The native module should only be imported once, and that by the internal pipeline code +assert __package__ == "rpcore.native", "You have included the pipeline in the wrong way!" + +# Classes which should get imported +classes_to_import = [ + "GPUCommand", + "GPUCommandList", + "ShadowManager", + "InternalLightManager", + "PSSMCameraRig", + "IESDataset", + "TagStateManager", +] + +# Classes which should get imported and renamed +classes_to_import_and_rename = { + "RPPointLight": "PointLight", + "RPSpotLight": "SpotLight" +} + +native_module = None + +# If the module was built, use it, otherwise use the python wrappers +if NATIVE_CXX_LOADED: + try: + from panda3d import _rplight as _native_module # pylint: disable=wrong-import-position + RPObject.global_debug("CORE", "Using panda3d-supplied core module") + except ImportError: + RPObject.global_debug("CORE", "Using native core module") + from rpcore.native import native_ as _native_module # pylint: disable=wrong-import-position +else: + from rpcore import pynative as _native_module # pylint: disable=wrong-import-position + RPObject.global_debug("CORE", "Using simulated python-wrapper module") + +# Import all classes +for v in classes_to_import + list(classes_to_import_and_rename.keys()): + if hasattr(_native_module, v): + v_name = classes_to_import_and_rename[v] if v in classes_to_import_and_rename else v + globals()[v_name] = getattr(_native_module, v) + else: + print("ERROR: could not import class", v, "from", _native_module.__name__) + +# Don't export all variables, only the required ones +__all__ = classes_to_import + list(classes_to_import_and_rename.values()) + ["NATIVE_CXX_LOADED"] diff --git a/rpcore/native/config.ini b/rpcore/native/config.ini new file mode 100644 index 0000000..72d084a --- /dev/null +++ b/rpcore/native/config.ini @@ -0,0 +1,2 @@ +generate_pdb=1 +module_name=native_ diff --git a/rpcore/native/source/README.md b/rpcore/native/source/README.md new file mode 100644 index 0000000..2f342f3 --- /dev/null +++ b/rpcore/native/source/README.md @@ -0,0 +1,7 @@ +## Render Pipeline Native + +This contains the source code of the native C++ modules +of the RenderPipeline. + +The documentation of the +modules can be found here. diff --git a/rpcore/native/source/config_rsnative.N b/rpcore/native/source/config_rsnative.N new file mode 100644 index 0000000..d2e84d1 --- /dev/null +++ b/rpcore/native/source/config_rsnative.N @@ -0,0 +1,5 @@ +forcetype GPUCommandList +forcetype GPUCommand +forcetype RPLight +forcetype ShadowManager +forcetype TagStateManager diff --git a/rpcore/native/source/config_rsnative.cpp b/rpcore/native/source/config_rsnative.cpp new file mode 100644 index 0000000..fb481f7 --- /dev/null +++ b/rpcore/native/source/config_rsnative.cpp @@ -0,0 +1,52 @@ +/** + * + * RenderPipeline + * + * Copyright (c) 2014-2016 tobspr + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + */ + +#include "config_rsnative.h" + +#include "rp_light.h" +#include "rp_point_light.h" + +#include "dconfig.h" + +Configure(config_rsnative); +NotifyCategoryDef(rsnative, ""); + +ConfigureFn(config_rsnative) { + init_librsnative(); +} + +void +init_librsnative() { + static bool initialized = false; + if (initialized) { + return; + } + initialized = true; + + // RPLight::init_type(); + // RPPointLight::init_type(); +} + diff --git a/rpcore/native/source/config_rsnative.h b/rpcore/native/source/config_rsnative.h new file mode 100644 index 0000000..3d4f287 --- /dev/null +++ b/rpcore/native/source/config_rsnative.h @@ -0,0 +1,37 @@ +/** + * + * RenderPipeline + * + * Copyright (c) 2014-2016 tobspr + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + */ + +#pragma once + +#include "pandabase.h" +#include "notifyCategoryProxy.h" +#include "configVariableDouble.h" +#include "configVariableString.h" +#include "configVariableInt.h" + +NotifyCategoryDecl(rsnative, EXPORT_CLASS, EXPORT_TEMPL); + +extern void init_librsnative(); diff --git a/rpcore/native/source/gpu_command.I b/rpcore/native/source/gpu_command.I new file mode 100644 index 0000000..4fdc2aa --- /dev/null +++ b/rpcore/native/source/gpu_command.I @@ -0,0 +1,185 @@ +/** + * + * RenderPipeline + * + * Copyright (c) 2014-2016 tobspr + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + */ + +#include "stdint.h" + +/** + * @brief Appends an integer to the GPUCommand. + * @details This adds an integer to the back of the GPUCommand. Depending on the + * setting in convert_int_to_float, this will either just convert the int to a + * float by casting it, or just do a bitwise copy. + * + * @param v The integer to append. + */ +inline void GPUCommand::push_int(int v) { + push_float(convert_int_to_float(v)); +} + +/** + * @brief Internal method to convert an integer to float + * @details This methods gets called by the GPUCommand::push_int, and manages + * storing an integer in a floating point variable. There are two options, + * which are documented inside of the method. + * + * @param v Integer to convert + * @return Float-representation of that integer, either casted or binary converted.s + */ +inline float GPUCommand::convert_int_to_float(int v) const { + + #if !PACK_INT_AS_FLOAT + // Just round to float, can cause rounding issues tho + return (float)v; + + #else + assert(sizeof(float) == 4); // We really need this for packing! Better + // throw an error if the compiler uses more + // than 4 bytes. + // Simple binary conversion, assuming sizeof(int) == sizeof(float) + union { int32_t _int; float _float; } converter = { (int32_t)v }; + return converter._float; + #endif +} + +/** + * @brief Appends a float to the GPUCommand. + * @details This adds an integer to the back of the GPUCommand. Its used by all + * other push_xxx methods, and simply stores the value, then increments the write + * pointer. When the amount of floats exceeds the capacity of the GPUCommand, + * an error will be printed, and the method returns without doing anything else. + * + * @param v The float to append. + */ +inline void GPUCommand::push_float(float v) { + if (_current_index >= GPU_COMMAND_ENTRIES) { + gpucommand_cat.error() << "Out of bounds! Exceeded command size of " << GPU_COMMAND_ENTRIES << endl; + return; + } + _data[_current_index++] = v; +} + +/** + * @brief Appends a 3-component floating point vector to the GPUCommand. + * @details This appends a 3-component floating point vector to the command. + * It basically just calls push_float() for every component, in the order + * x, y, z, which causes the vector to occupy the space of 3 floats. + * + * @param v Int-Vector to append. + */ +inline void GPUCommand::push_vec3(const LVecBase3f &v) { + push_float(v.get_x()); + push_float(v.get_y()); + push_float(v.get_z()); +} + + +/** + * @brief Appends a 3-component integer vector to the GPUCommand. + * @details This appends a 3-component integer vector to the command. + * It basically just calls push_int() for every component, in the order + * x, y, z, which causes the vector to occupy the space of 3 floats. + * + * @param v Int-Vector to append. + */ +inline void GPUCommand::push_vec3(const LVecBase3i &v) { + push_int(v.get_x()); + push_int(v.get_y()); + push_int(v.get_z()); +} + +/** + * @brief Appends a 4-component floating point vector to the GPUCommand. + * @details This appends a 4-component floating point vector to the command. + * It basically just calls push_float() for every component, in the order + * x, y, z, which causes the vector to occupy the space of 3 floats. + * + * @param v Int-Vector to append. + */ +inline void GPUCommand::push_vec4(const LVecBase4f &v) { + push_float(v.get_x()); + push_float(v.get_y()); + push_float(v.get_z()); + push_float(v.get_w()); +} + +/** + * @brief Appends a 4-component integer vector to the GPUCommand. + * @details This appends a 4-component integer vector to the command. + * It basically just calls push_int() for every component, in the order + * x, y, z, w, which causes the vector to occupy the space of 4 floats. + * + * @param v Int-Vector to append. + */ +inline void GPUCommand::push_vec4(const LVecBase4i &v) { + push_int(v.get_x()); + push_int(v.get_y()); + push_int(v.get_z()); + push_int(v.get_w()); +} + +/** + * @brief Appends a floating point 3x3 matrix to the GPUCommand. + * @details This appends a floating point 3x3 matrix to the GPUCommand, by + * pushing all components in row-order to the command. This occupies a space of + * 9 floats. + * + * @param v Matrix to append + */ +inline void GPUCommand::push_mat3(const LMatrix3f &v) { + for (size_t i = 0; i < 3; ++i) { + for (size_t j = 0; j < 3; ++j) { + push_float(v.get_cell(i, j)); + } + } +} + +/** + * @brief Appends a floating point 4x4 matrix to the GPUCommand. + * @details This appends a floating point 4x4 matrix to the GPUCommand, by + * pushing all components in row-order to the command. This occupies a space of + * 16 floats. + * + * @param v Matrix to append + */ +inline void GPUCommand::push_mat4(const LMatrix4f &v) { + for (size_t i = 0; i < 4; ++i) { + for (size_t j = 0; j < 4; ++j) { + push_float(v.get_cell(i, j)); + } + } +} + +/** + * @brief Returns whether integers are packed as floats. + * @details This returns how integer are packed into the data stream. If the + * returned value is true, then integers are packed using their binary + * representation converted to floating point format. If the returned value + * is false, then integers are packed by simply casting them to float, + * e.g. val = (float)i; + * @return The integer representation flag + */ +inline bool GPUCommand::get_uses_integer_packing() { + return PACK_INT_AS_FLOAT; +} diff --git a/rpcore/native/source/gpu_command.cpp b/rpcore/native/source/gpu_command.cpp new file mode 100644 index 0000000..d93f3a3 --- /dev/null +++ b/rpcore/native/source/gpu_command.cpp @@ -0,0 +1,87 @@ +/** + * + * RenderPipeline + * + * Copyright (c) 2014-2016 tobspr + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + */ + +#include "gpu_command.h" + +#include +#include +#include + + +NotifyCategoryDef(gpucommand, ""); + +/** + * @brief Constructs a new GPUCommand with the given command type. + * @details This will construct a new GPUCommand of the given command type. + * The command type should be of GPUCommand::CommandType, and determines + * what data the GPUCommand contains, and how it will be handled. + * + * @param command_type The type of the GPUCommand + */ +GPUCommand::GPUCommand(CommandType command_type) { + _command_type = command_type; + _current_index = 0; + memset(_data, 0x0, sizeof(float) * GPU_COMMAND_ENTRIES); + + // Store the command type as the first entry + push_int(command_type); +} + +/** + * @brief Prints out the GPUCommand to the console + * @details This method prints the type, size, and data of the GPUCommand to the + * console. This helps for debugging the contents of the GPUCommand. Keep + * in mind that integers might be shown in their binary float representation, + * depending on the setting in the GPUCommand::convert_int_to_float method. + */ +void GPUCommand::write(ostream &out) const { + out << "GPUCommand(type=" << _command_type << ", size=" << _current_index << ", data = {" << endl; + for (size_t k = 0; k < GPU_COMMAND_ENTRIES; ++k) { + out << std::setw(12) << std::fixed << std::setprecision(5) << _data[k] << " "; + if (k % 6 == 5 || k == GPU_COMMAND_ENTRIES - 1) out << endl; + } + out << "})" << endl; +} + +/** + * @brief Writes the GPU command to a given target. + * @details This method writes all the data of the GPU command to a given target. + * The target should be a pointer to memory being big enough to hold the + * data. Presumably #dest will be a handle to texture memory. + * The command_index controls the offset where the data will be written + * to. + * + * @param dest Handle to the memory to write the command to + * @param command_index Offset to write the command to. The command will write + * its data to command_index * GPU_COMMAND_ENTRIES. When writing + * the GPUCommand in a GPUCommandList, the command_index will + * most likely be the index of the command in the list. + */ +void GPUCommand::write_to(const PTA_uchar &dest, size_t command_index) { + size_t command_size = GPU_COMMAND_ENTRIES * sizeof(float); + size_t offset = command_index * command_size; + memcpy(dest.p() + offset, &_data, command_size); +} diff --git a/rpcore/native/source/gpu_command.h b/rpcore/native/source/gpu_command.h new file mode 100644 index 0000000..4275e4f --- /dev/null +++ b/rpcore/native/source/gpu_command.h @@ -0,0 +1,92 @@ +/** + * + * RenderPipeline + * + * Copyright (c) 2014-2016 tobspr + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + */ + +#ifndef RP_GPU_COMMAND_H +#define RP_GPU_COMMAND_H + +#include "pandabase.h" +#include "luse.h" + +NotifyCategoryDecl(gpucommand, EXPORT_CLASS, EXPORT_TEMPL); + +#define GPU_COMMAND_ENTRIES 32 + +// Packs integers by storing their binary representation in floats +// This only works if the command and light buffer is 32bit floating point. +#define PACK_INT_AS_FLOAT 0 + + +/** + * @brief Class for storing data to be transferred to the GPU. + * @details This class can be seen like a packet, to be transferred to the GPU. + * It has a command type, which tells the GPU what to do once it recieved this + * "packet". It stores a limited amount of floating point components. + */ +class GPUCommand { + + PUBLISHED: + + /** + * The different types of GPUCommands. Each type has a special case in + * the command queue processor. When adding new types, those need to + * be handled in the command target, too. + */ + enum CommandType { + CMD_invalid = 0, + CMD_store_light = 1, + CMD_remove_light = 2, + CMD_store_source = 3, + CMD_remove_sources = 4, + }; + + GPUCommand(CommandType command_type); + + inline void push_int(int v); + inline void push_float(float v); + inline void push_vec3(const LVecBase3f &v); + inline void push_vec3(const LVecBase3i &v); + inline void push_vec4(const LVecBase4f &v); + inline void push_vec4(const LVecBase4i &v); + inline void push_mat3(const LMatrix3f &v); + inline void push_mat4(const LMatrix4f &v); + + inline static bool get_uses_integer_packing(); + + void write_to(const PTA_uchar &dest, size_t command_index); + void write(ostream &out) const; + + private: + + inline float convert_int_to_float(int v) const; + + CommandType _command_type; + size_t _current_index; + float _data[GPU_COMMAND_ENTRIES]; +}; + +#include "gpu_command.I" + +#endif // RP_GPU_COMMAND_H diff --git a/rpcore/native/source/gpu_command_list.cpp b/rpcore/native/source/gpu_command_list.cpp new file mode 100644 index 0000000..bf8e683 --- /dev/null +++ b/rpcore/native/source/gpu_command_list.cpp @@ -0,0 +1,82 @@ +/** + * + * RenderPipeline + * + * Copyright (c) 2014-2016 tobspr + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + */ + +#include "gpu_command_list.h" + + +/** + * @brief Constructs a new GPUCommandList + * @details This constructs a new GPUCommandList. By default, there are no commands + * in the list. + */ +GPUCommandList::GPUCommandList() { +} + +/** + * @brief Pushes a GPUCommand to the command list. + * @details This adds a new GPUCommand to the list of commands to be processed. + * + * @param cmd The command to add + */ +void GPUCommandList::add_command(const GPUCommand& cmd) { + _commands.push(cmd); +} + +/** + * @brief Returns the number of commands in this list. + * @details This returns the amount of commands which are currently stored in this + * list, and are waiting to get processed. + * @return Amount of commands + */ +size_t GPUCommandList::get_num_commands() { + return _commands.size(); +} + +/** + * @brief Writes the first n-commands to a destination. + * @details This takes the first #limit commands, and writes them to the + * destination using GPUCommand::write_to. See GPUCommand::write_to for + * further information about #dest. The limit controls after how much + * commands the processing will be stopped. All commands which got processed + * will get removed from the list. + * + * @param dest Destination to write to, see GPUCommand::write_to + * @param limit Maximum amount of commands to process + * + * @return Amount of commands processed, between 0 and #limit. + */ +size_t GPUCommandList::write_commands_to(const PTA_uchar &dest, size_t limit) { + size_t num_commands_written = 0; + + while (num_commands_written < limit && !_commands.empty()) { + // Write the first command to the stream, and delete it afterwards + _commands.front().write_to(dest, num_commands_written); + _commands.pop(); + num_commands_written ++; + } + + return num_commands_written; +} diff --git a/rpcore/native/source/gpu_command_list.h b/rpcore/native/source/gpu_command_list.h new file mode 100644 index 0000000..1851904 --- /dev/null +++ b/rpcore/native/source/gpu_command_list.h @@ -0,0 +1,55 @@ +/** + * + * RenderPipeline + * + * Copyright (c) 2014-2016 tobspr + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + */ + +#ifndef RP_GPU_COMMAND_LIST_H +#define RP_GPU_COMMAND_LIST_H + +#include "pandabase.h" +#include "gpu_command.h" + +#include + +/** + * @brief Class to store a list of commands. + * @details This is a class to store a list of GPUCommands. It provides + * functionality to only provide the a given amount of commands at one time. + */ +class GPUCommandList { + + PUBLISHED: + GPUCommandList(); + + void add_command(const GPUCommand& cmd); + size_t get_num_commands(); + size_t write_commands_to(const PTA_uchar &dest, size_t limit = 32); + + MAKE_PROPERTY(num_commands, get_num_commands); + + protected: + queue _commands; +}; + +#endif // RP_GPU_COMMAND_LIST_H diff --git a/rpcore/native/source/ies_dataset.cpp b/rpcore/native/source/ies_dataset.cpp new file mode 100644 index 0000000..c658cb5 --- /dev/null +++ b/rpcore/native/source/ies_dataset.cpp @@ -0,0 +1,233 @@ +/** + * + * RenderPipeline + * + * Copyright (c) 2014-2016 tobspr + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + */ + + +#include "ies_dataset.h" + +#define _USE_MATH_DEFINES +#include + +NotifyCategoryDef(iesdataset, "") + +/** + * @brief Constructs a new empty dataset. + * @details This constructs a new IESDataset with no data set. + */ +IESDataset::IESDataset() { +} + +/** + * @brief Sets the vertical angles of the dataset. + * @details This sets the list of vertical angles of the dataset. + * + * @param vertical_angles Vector of all vertical angles. + */ +void IESDataset::set_vertical_angles(const PTA_float &vertical_angles) { + nassertv(vertical_angles.size() > 0); + _vertical_angles = vertical_angles; +} + +/** + * @brief Sets the horizontal angles of the dataset. + * @details This sets the list of horizontal angles of the dataset. + * + * @param horizontal_angles Vector of all horizontal angles. + */ +void IESDataset::set_horizontal_angles(const PTA_float &horizontal_angles) { + nassertv(horizontal_angles.size() > 0); + _horizontal_angles = horizontal_angles; +} + +/** + * @brief Sets the candela values. + * @details This sets the candela values of the dataset. They should be an + * interleaved 2D array with the dimensions vertical_angles x horizontal_angles. + * They also should be normalized by dividing by the maximum entry. + * @param candela_values Interleaved 2D-vector of candela values. + */ +void IESDataset::set_candela_values(const PTA_float &candela_values) { + nassertv(candela_values.size() == _horizontal_angles.size() * _vertical_angles.size()); + _candela_values = candela_values; +} + +/** + * @brief Internal method to access the candela data. + * @details This lookups a candela value in the candela values. It converts a + * two dimensional index to a onedimensional index and then returns the candela + * value at that position. + * + * @param vertical_angle_idx Index of the vertical angle + * @param horizontal_angle_idx Index of the horizontal angle + * + * @return Candela value between 0 .. 1 + */ +float IESDataset::get_candela_value_from_index(size_t vertical_angle_idx, size_t horizontal_angle_idx) const { + size_t index = vertical_angle_idx + horizontal_angle_idx * _vertical_angles.size(); + nassertr(index >= 0 && index < _candela_values.size(), 0.0); + return _candela_values[index]; +} + +/** + * @brief Samples the dataset at the given position + * @details This looks up a value in the dataset, by specifying a horizontal and + * vertical angle. This is used for generating the LUT. The vertical and horizontal + * angle should be inside of the bounds of the vertical and horizontal angle arrays. + * + * @param vertical_angle Vertical angle, from 0 .. 90 or 0 .. 180 depending on the dataset + * @param horizontal_angle Horizontal angle, from 0 .. 180 or 0 .. 360 depending on the dataset. + * + * @return Candela value between 0 .. 1 + */ +float IESDataset::get_candela_value(float vertical_angle, float horizontal_angle) const { + + // Special case for datasets without horizontal angles + if (_horizontal_angles.size() == 1) { + return get_vertical_candela_value(0, vertical_angle); + } + + float max_angle = _horizontal_angles[_horizontal_angles.size() - 1]; + + // Wrap angle to fit from 0 .. 360 degree. Most profiles only distribute + // candela values from 0 .. 180 or even 0 .. 90. We have to mirror the + // values at those borders (so 2 times for 180 degree and 4 times for 90 degree) + horizontal_angle = fmod(horizontal_angle, 2.0f * max_angle); + if (horizontal_angle > max_angle) { + horizontal_angle = 2.0 * max_angle - horizontal_angle; + } + + // Simlar to the vertical step, we now try interpolating a horizontal angle, + // but we need to evaluate the vertical value for each row instead of fetching + // the value directly + for (size_t horizontal_index = 1; horizontal_index < _horizontal_angles.size(); ++horizontal_index) { + float curr_angle = _horizontal_angles[horizontal_index]; + + if (curr_angle >= horizontal_angle) { + + // Get previous angle data + float prev_angle = _horizontal_angles[horizontal_index - 1]; + float prev_value = get_vertical_candela_value(horizontal_index - 1, vertical_angle); + float curr_value = get_vertical_candela_value(horizontal_index, vertical_angle); + + // Interpolate lineary + float lerp = (horizontal_angle - prev_angle) / (curr_angle - prev_angle); + + // Should never occur, but to be safe: + if (lerp < 0.0 || lerp > 1.0) { + iesdataset_cat.error() << "Invalid horizontal lerp: " << lerp + << ", requested angle was " << horizontal_angle + << ", prev = " << prev_angle << ", cur = " << curr_angle + << endl; + } + + return curr_value * lerp + prev_value * (1-lerp); + } + } + + return 0.0; +} + +/** + * @brief Fetches a vertical candela value + * @details Fetches a vertical candela value, using a given horizontal position. + * This does an 1D interpolation in the candela values array. + * + * @param horizontal_angle_idx The index of the horizontal angle in the horizontal + * angle array. + * @param vertical_angle The vertical angle. Interpolation will be done if the + * vertical angle is not in the vertical angles array. + * + * @return Candela value between 0 .. 1 + */ +float IESDataset::get_vertical_candela_value(size_t horizontal_angle_idx, float vertical_angle) const { + nassertr(horizontal_angle_idx >= 0 && horizontal_angle_idx < _horizontal_angles.size(), 0.0); + + // Lower bound + if (vertical_angle < 0.0) return 0.0; + + // Upper bound + if (vertical_angle > _vertical_angles[_vertical_angles.size() - 1] ) return 0.0; + + // Find lowest enclosing angle + for (size_t vertical_index = 1; vertical_index < _vertical_angles.size(); ++vertical_index) { + float curr_angle = _vertical_angles[vertical_index]; + + // Found value + if (curr_angle > vertical_angle) { + + // Get previous angle data + float prev_angle = _vertical_angles[vertical_index - 1]; + float prev_value = get_candela_value_from_index(vertical_index - 1, horizontal_angle_idx); + float curr_value = get_candela_value_from_index(vertical_index, horizontal_angle_idx); + + // Interpolate lineary + float lerp = (vertical_angle - prev_angle) / (curr_angle - prev_angle); + + // Should never occur, but to be safe: + if (lerp < 0.0 || lerp > 1.0) { + iesdataset_cat.error() << "ERROR: Invalid vertical lerp: " << lerp + << ", requested angle was " << vertical_angle + << ", prev = " << prev_angle << ", cur = " << curr_angle + << endl; + } + + return curr_value * lerp + prev_value * (1-lerp); + } + } + return 0.0; +} + +/** + * @brief Generates the IES LUT + * @details This generates the LUT into a given dataset texture. The x-axis + * referes to the vertical_angle, whereas the y-axis refers to the + * horizontal angle. + * + * @param dest_tex Texture to write the LUT into + * @param z Layer to write the LUT into, in case the texture is a 3D Texture or + * 2D Texture Array. + */ +void IESDataset::generate_dataset_texture_into(Texture* dest_tex, size_t z) const { + + size_t resolution_vertical = dest_tex->get_y_size(); + size_t resolution_horizontal = dest_tex->get_x_size(); + + // Candla values are stored flippped - vertical angles in the x - Axis + // and horizontal angles in the y - Axis + PNMImage dest = PNMImage(resolution_vertical, resolution_horizontal, 1, 65535); + + for (size_t vert = 0; vert < resolution_vertical; ++vert) { + for (size_t horiz = 0; horiz < resolution_horizontal; ++horiz) { + float vert_angle = (float)vert / (float)(resolution_vertical-1); + vert_angle = cos(vert_angle * M_PI) * 90.0 + 90.0; + float horiz_angle = (float)horiz / (float)(resolution_horizontal-1) * 360.0; + float candela = get_candela_value(vert_angle, horiz_angle); + dest.set_xel(vert, horiz, candela); + } + } + + + dest_tex->load(dest, z, 0); +} diff --git a/rpcore/native/source/ies_dataset.h b/rpcore/native/source/ies_dataset.h new file mode 100644 index 0000000..36a11ee --- /dev/null +++ b/rpcore/native/source/ies_dataset.h @@ -0,0 +1,66 @@ +/** + * + * RenderPipeline + * + * Copyright (c) 2014-2016 tobspr + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + */ + +#pragma once + +#include "pandabase.h" +#include "pta_float.h" +#include "pointerToArray.h" +#include "texture.h" +#include "pnmImage.h" + +NotifyCategoryDecl(iesdataset, EXPORT_CLASS, EXPORT_TEMPL); + + +/** + * @brief This class generates a LUT from IES data. + * @details This class is used by the IESLoader to generate a LUT texture which + * is used in the shaders to perform IES lighting. It takes a set of vertical + * and horizontal angles, as well as a set of candela values, which then are + * lineary interpolated onto a 2D LUT Texture. + */ +class IESDataset { + + PUBLISHED: + IESDataset(); + + void set_vertical_angles(const PTA_float &vertical_angles); + void set_horizontal_angles(const PTA_float &horizontal_angles); + void set_candela_values(const PTA_float &candela_values); + + void generate_dataset_texture_into(Texture* dest_tex, size_t z) const; + + public: + + float get_candela_value(float vertical_angle, float horizontal_angle) const; + float get_candela_value_from_index(size_t vertical_angle_idx, size_t horizontal_angle_idx) const; + float get_vertical_candela_value(size_t horizontal_angle_idx, float vertical_angle) const; + + private: + PTA_float _vertical_angles; + PTA_float _horizontal_angles; + PTA_float _candela_values; +}; diff --git a/rpcore/native/source/internal_light_manager.I b/rpcore/native/source/internal_light_manager.I new file mode 100644 index 0000000..5d9f7ee --- /dev/null +++ b/rpcore/native/source/internal_light_manager.I @@ -0,0 +1,140 @@ +/** + * + * RenderPipeline + * + * Copyright (c) 2014-2016 tobspr + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + */ + + +/** + * @brief Returns the maximum light index + * @details This returns the maximum light index (also called slot). Any lights + * after that slot are guaranteed to be zero-lights. This is useful when + * iterating over the list of lights, because iteration can be stopped when + * the maximum light index is reached. + * + * The maximum light index points to the last slot which is used. If no lights + * are attached, -1 is returned. If one light is attached at slot 0, the index + * is 0, if two are attached at the slots 0 and 1, the index is 1, and so on. + * + * If, for example, two lights are attached at the slots 2 and 5, then the + * index will be 5. Keep in mind that the max-index is not an indicator for + * how many lights are attached. Also, zero lights still may occur when iterating + * over the light lists + * + * @return Maximum light index + */ +inline int InternalLightManager::get_max_light_index() const { + return _lights.get_max_index(); +} + +/** + * @brief Returns the amount of stored lights. + * @details This returns the amount of stored lights. This behaves unlike + * InternalLightManager::get_max_light_index, and instead returns the true + * amount of lights, which is completely unrelated to the amount of used slots. + * + * @return Amount of stored lights + */ +inline size_t InternalLightManager::get_num_lights() const { + return _lights.get_num_entries(); +} + +/** + * @brief Returns the amount of shadow sources. + * @details This returns the total amount of stored shadow sources. This does + * not denote the amount of updated sources, but instead takes into account + * all sources, even those out of frustum. + * @return Amount of shadow sources. + */ +inline size_t InternalLightManager::get_num_shadow_sources() const { + return _shadow_sources.get_num_entries(); +} + +/** + * @brief Sets the handle to the shadow manager + * @details This sets the handle to the global shadow manager. It is usually + * constructed on the python side, so we need to get a handle to it. + * + * The manager should be a handle to a ShadowManager instance, and will be + * stored somewhere on the python side most likely. The light manager does not + * keep a reference to it, so the python side should make sure to keep one. + * + * Be sure to call this before the InternalLightManager::update() method is + * called, otherwise an assertion will get triggered. + * + * @param mgr The ShadowManager instance + */ +inline void InternalLightManager::set_shadow_manager(ShadowManager* mgr) { + _shadow_manager = mgr; +} + +/** + * @brief Sets a handle to the command list + * @details This sets a handle to the global GPUCommandList. This is required to + * emit GPUCommands, which are used for attaching and detaching lights, as well + * as shadow source updates. + * + * The cmd_list should be a handle to a GPUCommandList handle, and will be + * stored somewhere on the python side most likely. The light manager does not + * keep a reference to it, so the python side should make sure to keep one. + * + * Be sure to call this before the InternalLightManager::update() method is + * called, otherwise an assertion will get triggered. + * + * @param cmd_list The GPUCommandList instance + */ +inline void InternalLightManager::set_command_list(GPUCommandList *cmd_list) { + _cmd_list = cmd_list; +} + +/** + * @brief Sets the camera position + * @details This sets the camera position, which will be used to determine which + * shadow sources have to get updated + * + * @param mat View projection mat + */ +inline void InternalLightManager::set_camera_pos(const LPoint3f& pos) { + _camera_pos = pos; +} + +/** + * @brief Sets the maximum shadow update distance + * @details This controls the maximum distance until which shadows are updated. + * If a shadow source is past that distance, it is ignored and no longer recieves + * updates until it is in range again + * + * @param dist Distance in world space units + */ +inline void InternalLightManager::set_shadow_update_distance(float dist) { + _shadow_update_distance = dist; +} + +/** + * @brief Returns the internal used ShadowManager + * @details This returns a handle to the internally used shadow manager + * @return Shadow manager + */ +inline ShadowManager* InternalLightManager::get_shadow_manager() const { + return _shadow_manager; +} diff --git a/rpcore/native/source/internal_light_manager.cpp b/rpcore/native/source/internal_light_manager.cpp new file mode 100644 index 0000000..53e39c3 --- /dev/null +++ b/rpcore/native/source/internal_light_manager.cpp @@ -0,0 +1,441 @@ +/** + * + * RenderPipeline + * + * Copyright (c) 2014-2016 tobspr + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + */ + + +#include "internal_light_manager.h" + +#include + +NotifyCategoryDef(lightmgr, ""); + + +/** + * @brief Constructs the light manager + * @details This constructs the light manager, initializing the light and shadow + * storage. You should set a command list and shadow manager before calling + * InternalLightManager::update. s + */ +InternalLightManager::InternalLightManager() { + _shadow_update_distance = 100.0f; + _cmd_list = NULL; + _shadow_manager = NULL; +} + +/** + * @brief Adds a new light. + * @details This adds a new light to the list of lights. This will throw an + * error and return if the light is already attached. You may only call + * this after the ShadowManager was already set. + * + * While the light is attached, the light manager keeps a reference to it, so + * the light does not get destructed. + * + * This also setups the shadows on the light, in case shadows are enabled. + * While a light is attached, you can not change whether it casts shadows or not. + * To do so, detach the light, change the setting, and re-add the light. + * + * In case no free light slot is available, an error will be printed and no + * action will be performed. + * + * If no shadow manager was set, an assertion will be triggered. + * + * @param light The light to add. + */ +void InternalLightManager::add_light(PT(RPLight) light) { + nassertv(_shadow_manager != NULL); // Shadow manager not set yet! + + // Don't attach the light in case its already attached + if (light->has_slot()) { + lightmgr_cat.error() << "could not add light because it already is attached! " + << "Detach the light first, then try it again." << endl; + return; + } + + // Find a free slot + size_t slot; + if (!_lights.find_slot(slot)) { + lightmgr_cat.error() << "Light limit of " << MAX_LIGHT_COUNT << " reached, " + << "all light slots used!" << endl; + return; + } + + // Reference the light because we store it, to avoid it getting destructed + // on the python side while we still work with it. The reference will be + // removed when the light gets detached. + light->ref(); + + // Reserve the slot + light->assign_slot(slot); + _lights.reserve_slot(slot, light); + + // Setup the shadows in case the light uses them + if (light->get_casts_shadows()) { + setup_shadows(light); + } + + // Store the light on the gpu, to make sure the GPU directly knows about it. + // We could wait until the next update cycle, but then we might be one frame + // too late already. + gpu_update_light(light); +} + +/** + * @brief Internal method to setup shadows for a light + * @details This method gets called by the InternalLightManager::add_light method + * to setup a lights shadow sources, in case shadows are enabled on that light. + * + * It finds a slot for all shadow sources of the ilhgt, and inits the shadow + * sources as well. If no slot could be found, an error is printed an nothing + * happens. + * + * @param light The light to init the shadow sources for + */ +void InternalLightManager::setup_shadows(RPLight* light) { + + // Init the lights shadow sources, and also call update once to make sure + // the sources are properly initialized + light->init_shadow_sources(); + light->update_shadow_sources(); + + // Find consecutive slots, this is important for PointLights so we can just + // store the first index of the source, and get the other slots by doing + // first_index + 1, +2 and so on. + size_t base_slot; + size_t num_sources = light->get_num_shadow_sources(); + if (!_shadow_sources.find_consecutive_slots(base_slot, num_sources)) { + lightmgr_cat.error() << "Failed to find slot for shadow sources! " + << "Shadow-Source limit of " << MAX_SHADOW_SOURCES + << " reached!" << endl; + return; + } + + // Init all sources + for (int i = 0; i < num_sources; ++i) { + ShadowSource* source = light->get_shadow_source(i); + + // Set the source as dirty, so it gets updated in the beginning + source->set_needs_update(true); + + // Assign the slot to the source. Since we got consecutive slots, we can + // just do base_slot + N. + size_t slot = base_slot + i; + _shadow_sources.reserve_slot(slot, source); + source->set_slot(slot); + } +} + +/** + * @brief Removes a light + * @details This detaches a light. This prevents it from being rendered, and also + * cleans up all resources used by that light. If no reference is kept on the + * python side, the light will also get destructed. + * + * If the light was not previously attached with InternalLightManager::add_light, + * an error will be triggered and nothing happens. + * + * In case the light was set to cast shadows, all shadow sources are cleaned + * up, and their regions in the shadow atlas are freed. + * + * All resources used by the light in the light and shadow storage are also + * cleaned up, by emitting cleanup GPUCommands. + * + * If no shadow manager was set, an assertion will be triggered. + * + * @param light [description] + */ +void InternalLightManager::remove_light(PT(RPLight) light) { + nassertv(_shadow_manager != NULL); + + if (!light->has_slot()) { + lightmgr_cat.error() << "Could not detach light, light was not attached!" << endl; + return; + } + + // Free the lights slot in the light storage + _lights.free_slot(light->get_slot()); + + // Tell the GPU we no longer need the lights data + gpu_remove_light(light); + + // Mark the light as detached. After this call, we can not call get_slot + // anymore, so its important we do this after we unregistered the light + // from everywhere. + light->remove_slot(); + + // Clear shadow related stuff, in case the light casts shadows + if (light->get_casts_shadows()) { + + // Free the slots of all sources, and also unregister their regions from + // the shadow atlas. + for (size_t i = 0; i < light->get_num_shadow_sources(); ++i) { + ShadowSource* source = light->get_shadow_source(i); + if (source->has_slot()) { + _shadow_sources.free_slot(source->get_slot()); + } + if (source->has_region()) { + _shadow_manager->get_atlas()->free_region(source->get_region()); + source->clear_region(); + } + } + + // Remove all sources of the light by emitting a consecutive remove command + gpu_remove_consecutive_sources(light->get_shadow_source(0), + light->get_num_shadow_sources()); + + // Finally remove all shadow sources. This is important in case the light + // will be re-attached. Otherwise an assertion will get triggered. + light->clear_shadow_sources(); + } + + // Since we referenced the light when we stored it, we have to decrease + // the reference now. In case no reference was kept on the python side, + // the light will get destructed soon. + light->unref(); +} + +/** + * @brief Internal method to remove consecutive sources from the GPU. + * @details This emits a GPUCommand to consecutively remove shadow sources from + * the GPU. This is called when a light gets removed, to free the space its + * shadow sources took. Its not really required, because as long as the light + * is not used, there is no reference to the sources. However, it can't hurt to + * cleanup the memory. + * + * All sources starting at first_source->get_slot() until + * first_source->get_slot() + num_sources will get cleaned up. + * + * @param first_source First source of the light + * @param num_sources Amount of consecutive sources to clear + */ +void InternalLightManager::gpu_remove_consecutive_sources(ShadowSource *first_source, + size_t num_sources) { + nassertv(_cmd_list != NULL); // No command list set yet + nassertv(first_source->has_slot()); // Source has no slot! + GPUCommand cmd_remove(GPUCommand::CMD_remove_sources); + cmd_remove.push_int(first_source->get_slot()); + cmd_remove.push_int(num_sources); + _cmd_list->add_command(cmd_remove); +} + +/** + * @brief Internal method to remove a light from the GPU. + * @details This emits a GPUCommand to clear a lights data. This sets the data + * to all zeros, marking that no light is stored anymore. + * + * This throws an assertion in case the light is not currently attached. Be + * sure to call this before detaching the light. + * + * @param light The light to remove, must be attached. + */ +void InternalLightManager::gpu_remove_light(RPLight* light) { + nassertv(_cmd_list != NULL); // No command list set yet + nassertv(light->has_slot()); // Light has no slot! + GPUCommand cmd_remove(GPUCommand::CMD_remove_light); + cmd_remove.push_int(light->get_slot()); + _cmd_list->add_command(cmd_remove); +} + +/** + * @brief Updates a lights data on the GPU + * @details This method emits a GPUCommand to update a lights data. This can + * be used to initially store the lights data, or to update the data whenever + * the light changed. + * + * This throws an assertion in case the light is not currently attached. Be + * sure to call this after attaching the light. + * + * @param light The light to update + */ +void InternalLightManager::gpu_update_light(RPLight* light) { + nassertv(_cmd_list != NULL); // No command list set yet + nassertv(light->has_slot()); // Light has no slot! + GPUCommand cmd_update(GPUCommand::CMD_store_light); + cmd_update.push_int(light->get_slot()); + light->write_to_command(cmd_update); + light->set_needs_update(false); + _cmd_list->add_command(cmd_update); +} + +/** + * @brief Updates a shadow source data on the GPU + * @details This emits a GPUCommand to update a given shadow source, storing all + * data of the source on the GPU. This can also be used to initially store a + * ShadowSource, since all data will be overridden. + * + * This throws an assertion if the source has no slot yet. + * + * @param source The source to update + */ +void InternalLightManager::gpu_update_source(ShadowSource* source) { + nassertv(_cmd_list != NULL); // No command list set yet + nassertv(source->has_slot()); // Source has no slot! + GPUCommand cmd_update(GPUCommand::CMD_store_source); + cmd_update.push_int(source->get_slot()); + source->write_to_command(cmd_update); + _cmd_list->add_command(cmd_update); +} + +/** + * @brief Internal method to update all lights + * @details This is called by the main update method, and iterates over the list + * of lights. If a light is marked as dirty, it will recieve an update of its + * data and its shadow sources. + */ +void InternalLightManager::update_lights() { + for (auto iter = _lights.begin(); iter != _lights.end(); ++iter) { + RPLight* light = *iter; + if (light && light->get_needs_update()) { + if (light->get_casts_shadows()) { + light->update_shadow_sources(); + } + gpu_update_light(light); + } + } +} + +/** + * @brief Compares shadow sources by their priority + * @details Returns if a has a greater priority than b. This depends on the + * resolution of the source, and also if the source has a region or not. + * This method can be passed to std::sort. + * + * @param a First source + * @param b Second source + * + * @return true if a is more important than b, else false + */ +bool InternalLightManager::compare_shadow_sources(const ShadowSource* a, const ShadowSource* b) const { + + // Make sure that sources which already have a region (but maybe outdated) + // come after sources which have no region at all. + if (a->has_region() != b->has_region()) { + return b->has_region(); + } + + // Compare sources based on their distance to the camera + float dist_a = (_camera_pos - a->get_bounds().get_center()).length_squared(); + float dist_b = (_camera_pos - a->get_bounds().get_center()).length_squared(); + + // XXX: Should also compare based on source size, so that huge sources recieve + // more updates + + return dist_b > dist_a; +} + +/** + * @brief Internal method to update all shadow sources + * @details This updates all shadow sources which are marked dirty. It will sort + * the list of all dirty shadow sources by their resolution, take the first + * n entries, and update them. The amount of sources processed depends on the + * max_updates of the ShadowManager. + */ +void InternalLightManager::update_shadow_sources() { + + // Find all dirty shadow sources and make a list of them + vector sources_to_update; + for (auto iter = _shadow_sources.begin(); iter != _shadow_sources.end(); ++iter) { + ShadowSource* source = *iter; + if (source) { + const BoundingSphere& bounds = source->get_bounds(); + + // Check if source is in range + float distance_to_camera = (_camera_pos - bounds.get_center()).length() - bounds.get_radius(); + if (distance_to_camera < _shadow_update_distance) { + if (source->get_needs_update()) { + sources_to_update.push_back(source); + } + } else { + + // Free regions of sources which are out of the update radius, + // to make space for other regions + if (source->has_region()) { + _shadow_manager->get_atlas()->free_region(source->get_region()); + source->clear_region(); + } + } + } + + } + + // Sort the sources based on their importance, so that sources with a bigger + // priority come first. This helps to get a better packing on the shadow atlas. + // However, we also need to prioritize sources which have no current region, + // because no shadows are worse than outdated-shadows. + std::sort(sources_to_update.begin(), sources_to_update.end(), [this](const ShadowSource* a, const ShadowSource* b) { + return this->compare_shadow_sources(a, b); + }); + + // Get a handle to the atlas, will be frequently used + ShadowAtlas *atlas = _shadow_manager->get_atlas(); + + // Free the regions of all sources which will get updated. We have to take into + // account that only a limited amount of sources can get updated per frame. + size_t update_slots = min(sources_to_update.size(), + _shadow_manager->get_num_update_slots_left()); + for(size_t i = 0; i < update_slots; ++i) { + if (sources_to_update[i]->has_region()) { + atlas->free_region(sources_to_update[i]->get_region()); + } + } + + // Find an atlas spot for all regions which are supposed to get an update + for (size_t i = 0; i < update_slots; ++i) { + ShadowSource *source = sources_to_update[i]; + + if(!_shadow_manager->add_update(source)) { + // In case the ShadowManager lied about the number of updates left + lightmgr_cat.error() << "ShadowManager ensured update slot, but slot is taken!" << endl; + break; + } + + // We have an update slot, and are guaranteed to get updated as soon + // as possible, so we can start getting a new atlas position. + size_t region_size = atlas->get_required_tiles(source->get_resolution()); + LVecBase4i new_region = atlas->find_and_reserve_region(region_size, region_size); + LVecBase4f new_uv_region = atlas->region_to_uv(new_region); + source->set_region(new_region, new_uv_region); + + // Mark the source as updated + source->set_needs_update(false); + gpu_update_source(source); + } +} + +/** + * @brief Main update method + * @details This is the main update method of the InternalLightManager. It + * processes all lights and shadow sources, updates them, and notifies the + * GPU about it. This should be called on a per-frame basis. + * + * If the InternalLightManager was not initialized yet, an assertion is thrown. + */ +void InternalLightManager::update() { + nassertv(_shadow_manager != NULL); // Not initialized yet! + nassertv(_cmd_list != NULL); // Not initialized yet! + + update_lights(); + update_shadow_sources(); +} diff --git a/rpcore/native/source/internal_light_manager.h b/rpcore/native/source/internal_light_manager.h new file mode 100644 index 0000000..d5c8a4b --- /dev/null +++ b/rpcore/native/source/internal_light_manager.h @@ -0,0 +1,104 @@ +/** + * + * RenderPipeline + * + * Copyright (c) 2014-2016 tobspr + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + */ + +#ifndef RP_INTERNAL_LIGHT_MANAGER_H +#define RP_INTERNAL_LIGHT_MANAGER_H + +#include "referenceCount.h" +#include "rp_light.h" +#include "shadow_source.h" +#include "shadow_atlas.h" +#include "shadow_manager.h" +#include "pointer_slot_storage.h" +#include "gpu_command_list.h" + +#define MAX_LIGHT_COUNT 65535 +#define MAX_SHADOW_SOURCES 2048 + +NotifyCategoryDecl(lightmgr, EXPORT_CLASS, EXPORT_TEMPL); + +/** + * @brief Internal class used for handling lights and shadows. + * @details This is the internal class used by the pipeline to handle all + * lights and shadows. It stores references to the lights, manages handling + * the light and shadow slots, and also communicates with the GPU with the + * GPUCommandQueue to store light and shadow source data. + */ +class InternalLightManager { + + PUBLISHED: + InternalLightManager(); + + + void add_light(PT(RPLight) light); + void remove_light(PT(RPLight) light); + + void update(); + inline void set_camera_pos(const LPoint3f& pos); + inline void set_shadow_update_distance(float dist); + + inline int get_max_light_index() const; + MAKE_PROPERTY(max_light_index, get_max_light_index); + + inline size_t get_num_lights() const; + MAKE_PROPERTY(num_lights, get_num_lights); + + inline size_t get_num_shadow_sources() const; + MAKE_PROPERTY(num_shadow_sources, get_num_shadow_sources); + + inline void set_shadow_manager(ShadowManager* mgr); + inline ShadowManager* get_shadow_manager() const; + MAKE_PROPERTY(shadow_manager, get_shadow_manager, set_shadow_manager); + + inline void set_command_list(GPUCommandList *cmd_list); + + protected: + + void gpu_update_light(RPLight* light); + void gpu_update_source(ShadowSource* source); + void gpu_remove_light(RPLight* light); + void gpu_remove_consecutive_sources(ShadowSource *first_source, size_t num_sources); + + void setup_shadows(RPLight* light); + bool compare_shadow_sources(const ShadowSource* a, const ShadowSource* b) const; + + void update_lights(); + void update_shadow_sources(); + + GPUCommandList* _cmd_list; + ShadowManager* _shadow_manager; + + PointerSlotStorage _lights; + PointerSlotStorage _shadow_sources; + + LPoint3f _camera_pos; + float _shadow_update_distance; + +}; + +#include "internal_light_manager.I" + +#endif // RP_INTERNAL_LIGHT_MANAGER_H diff --git a/rpcore/native/source/pointer_slot_storage.h b/rpcore/native/source/pointer_slot_storage.h new file mode 100644 index 0000000..979732e --- /dev/null +++ b/rpcore/native/source/pointer_slot_storage.h @@ -0,0 +1,230 @@ +/** + * + * RenderPipeline + * + * Copyright (c) 2014-2016 tobspr + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + */ + +#ifndef RP_POINTER_SLOT_STORAGE +#define RP_POINTER_SLOT_STORAGE + + +#ifdef CPPPARSER + +// Dummy implementation for interrogate +template < typename T, int SIZE > +class PointerSlotStorage {}; + +#else // CPPPARSER + + +#include "pandabase.h" +#include + +/** + * @brief Class to keep a list of pointers and nullpointers. + * @details This class stores a fixed size list of pointers, whereas pointers + * may be a nullptr as well. It provides functionality to find free slots, + * and also to find free consecutive slots, as well as taking care of reserving slots. + * + * @tparam T* Pointer-Type + * @tparam SIZE Size of the storage + */ +template < typename T, int SIZE > +class PointerSlotStorage { + +public: + + /** + * @brief Constructs a new PointerSlotStorage + * @details This constructs a new PointerSlotStorage, with all slots + * initialized to a nullptr. + */ + PointerSlotStorage() { + _data.fill(NULL); + _max_index = 0; + _num_entries = 0; + } + + /** + * @brief Returns the maximum index of the container + * @details This returns the greatest index of any element which is not zero. + * This can be useful for iterating the container, since all elements + * coming after the returned index are guaranteed to be a nullptr. + * + * If no elements are in this container, -1 is returned. + * @return Maximum index of the container + */ + int get_max_index() const { + return _max_index; + } + + /** + * @brief Returns the amount of elements of the container + * @details This returns the amount of elements in the container which are + * no nullptr. + * @return Amount of elements + */ + size_t get_num_entries() const { + return _num_entries; + } + + /** + * @brief Finds a free slot + * @details This finds the first slot which is a nullptr and returns it. + * This is most likely useful in combination with reserve_slot. + * + * When no slot found was found, slot will be undefined, and false will + * be returned. + * + * @param slot Output-Variable, slot will be stored there + * @return true if a slot was found, otherwise false + */ + bool find_slot(size_t &slot) const { + for (size_t i = 0; i < SIZE; ++i) { + if (_data[i] == NULL) { + slot = i; + return true; + } + } + return false; + } + + /** + * @brief Finds free consecutive slots + * @details This behaves like find_slot, but it tries to find a slot + * after which free slots follow as well. + * + * When no slot found was found, slot will be undefined, and false will + * be returned. + * + * @param slot Output-Variable, index of the first slot of the consecutive + * slots will be stored there. + * @param num_consecutive Amount of consecutive slots to find, including the + * first slot. + * + * @return true if consecutive slots were found, otherwise false. + */ + bool find_consecutive_slots(size_t &slot, size_t num_consecutive) const { + nassertr(num_consecutive > 0, false); + + // Fall back to default search algorithm in case the parameters are equal + if (num_consecutive == 1) { + return find_slot(slot); + } + + // Try to find consecutive slots otherwise + for (size_t i = 0; i < SIZE; ++i) { + bool any_taken = false; + for (size_t k = 0; !any_taken && k < num_consecutive; ++k) { + any_taken = _data[i + k] != NULL; + } + if (!any_taken) { + slot = i; + return true; + } + } + return false; + } + + /** + * @brief Frees an allocated slot + * @details This frees an allocated slot. If the slot was already freed + * before, this method throws an assertion. + * + * @param slot Slot to free + */ + void free_slot(size_t slot) { + nassertv(slot >= 0 && slot < SIZE); + nassertv(_data[slot] != NULL); // Slot was already empty! + _data[slot] = NULL; + _num_entries--; + + // Update maximum index + if (slot == _max_index) { + while (_max_index >= 0 && !_data[_max_index--]); + } + } + + /** + * @brief Frees consecutive allocated slots + * @details This behaves like PointerSlotStorage::free_slot, but deletes + * consecutive slots. + * + * @param slot Start of the consecutive slots to free + * @param num_consecutive Number of consecutive slots + */ + void free_consecutive_slots(size_t slot, size_t num_consecutive) { + for (size_t i = slot; i < slot + num_consecutive; ++i) { + free_slot(i); + } + } + + /** + * @brief Reserves a slot + * @details This reserves a slot by storing a pointer in it. If the slot + * was already taken, throws an assertion. + * If the ptr is a nullptr, also throws an assertion. + * If the slot was out of bounds, also throws an assertion. + * + * @param slot Slot to reserve + * @param ptr Pointer to store + */ + void reserve_slot(size_t slot, T ptr) { + nassertv(slot >= 0 && slot < SIZE); + nassertv(_data[slot] == NULL); // Slot already taken! + nassertv(ptr != NULL); // nullptr passed as argument! + _max_index = max(_max_index, (int)slot); + _data[slot] = ptr; + _num_entries++; + } + + typedef array InternalContainer; + + /** + * @brief Returns an iterator to the begin of the container + * @details This returns an iterator to the beginning of the container + * @return Begin-Iterator + */ + typename InternalContainer::iterator begin() { + return _data.begin(); + } + + /** + * @brief Returns an iterator to the end of the container + * @details This returns an iterator to the end of the iterator. This only + * iterates to PointerSlotStorage::get_max_index() + * @return [description] + */ + typename InternalContainer::iterator end() { + return _data.begin() + _max_index + 1; + } + +private: + int _max_index; + size_t _num_entries; + InternalContainer _data; +}; + +#endif // CPPPARSER + +#endif // RP_POINTER_SLOT_STORAGE diff --git a/rpcore/native/source/pssm_camera_rig.I b/rpcore/native/source/pssm_camera_rig.I new file mode 100644 index 0000000..c9bf1fb --- /dev/null +++ b/rpcore/native/source/pssm_camera_rig.I @@ -0,0 +1,243 @@ +/** + * + * RenderPipeline + * + * Copyright (c) 2014-2016 tobspr + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + */ + + +/** + * @brief Sets the maximum pssm distance. + * @details This sets the maximum distance in world space until which shadows + * are rendered. After this distance, no shadows will be rendered. + * + * If the distance is below zero, an assertion is triggered. + * + * @param distance Maximum distance in world space + */ +inline void PSSMCameraRig::set_pssm_distance(float distance) { + nassertv(distance > 0.0 && distance < 100000.0); + _pssm_distance = distance; +} + +/** + * @brief Sets the suns distance + * @details This sets the distance the cameras will have from the cameras frustum. + * This prevents far objects from having no shadows, which can occur when these + * objects are between the cameras frustum and the sun, but not inside of the + * cameras frustum. Setting the sun distance high enough will move the cameras + * away from the camera frustum, being able to cover those distant objects too. + * + * If the sun distance is set too high, artifacts will occur due to the reduced + * range of depth. If a value below zero is passed, an assertion will get + * triggered. + * + * @param distance The sun distance + */ +inline void PSSMCameraRig::set_sun_distance(float distance) { + nassertv(distance > 0.0 && distance < 100000.0); + _sun_distance = distance; +} + +/** + * @brief Sets the logarithmic factor + * @details This sets the logarithmic factor, which is the core of the algorithm. + * PSSM splits the camera frustum based on a linear and a logarithmic factor. + * While a linear factor provides a good distribution, it often is not applicable + * for wider distances. A logarithmic distribution provides a better distribution + * at distance, but suffers from splitting in the near areas. + * + * The logarithmic factor mixes the logarithmic and linear split distribution, + * to get the best of both. A greater factor will make the distribution more + * logarithmic, while a smaller factor will make it more linear. + * + * If the factor is below zero, an ssertion is triggered. + * + * @param factor The logarithmic factor + */ +inline void PSSMCameraRig::set_logarithmic_factor(float factor) { + nassertv(factor > 0.0); + _logarithmic_factor = factor; +} + +/** + * @brief Sets whether to use a fixed film size + * @details This controls if a fixed film size should be used. This will cause + * the camera rig to cache the current film size, and only change it in case + * it gets too small. This provides less flickering when moving, because the + * film size will stay roughly constant. However, to prevent the cached film + * size getting too big, one should call PSSMCameraRig::reset_film_size + * once in a while, otherwise there might be a lot of wasted space. + * + * @param flag Whether to use a fixed film size + */ +inline void PSSMCameraRig::set_use_fixed_film_size(bool flag) { + _use_fixed_film_size = flag; +} + +/** + * @brief Sets the resolution of each split + * @details This sets the resolution of each split. Currently it is equal for + * each split. This is required when using PSSMCameraRig::set_use_stable_csm, + * to compute how bix a texel is. + * + * It has to match the y-resolution of the pssm shadow map. If an invalid + * resolution is triggered, an assertion is thrown. + * + * @param resolution The resolution of each split. + */ +inline void PSSMCameraRig::set_resolution(size_t resolution) { + nassertv(resolution >= 0 && resolution < 65535); + _resolution = resolution; +} + +/** + * @brief Sets whether to use stable CSM snapping. + * @details This option controls if stable CSM snapping should be used. When the + * option is enabled, all splits will snap to their texels, so that when moving, + * no flickering will occur. However, this only works when the splits do not + * change their film size, rotation and angle. + * + * @param flag Whether to use stable CSM snapping + */ +inline void PSSMCameraRig::set_use_stable_csm(bool flag) { + _use_stable_csm = flag; +} + +/** + * @brief Sets the border bias for each split + * @details This sets the border bias for every split. This increases each + * splits frustum by multiplying it by (1 + bias), and helps reducing artifacts + * at the borders of the splits. Artifacts can occur when the bias is too low, + * because then the filtering will go over the bounds of the split, producing + * invalid results. + * + * If the bias is below zero, an assertion is thrown. + * + * @param bias Border bias + */ +inline void PSSMCameraRig::set_border_bias(float bias) { + nassertv(bias >= 0.0); + _border_bias = bias; +} + +/** + * @brief Resets the film size cache + * @details In case PSSMCameraRig::set_use_fixed_film_size is used, this resets + * the film size cache. This might lead to a small "jump" in the shadows, + * because the film size changes, however it leads to a better shadow distribution. + * + * This is the case because when using a fixed film size, the cache will get + * bigger and bigger, whenever the camera moves to a grazing angle. However, + * when moving back to a normal angle, the film size cache still stores this + * big angle, and thus the splits will have a much bigger film size than actualy + * required. To prevent this, call this method once in a while, so an optimal + * distribution is ensured. + */ +inline void PSSMCameraRig::reset_film_size_cache() { + for (size_t i = 0; i < _max_film_sizes.size(); ++i) { + _max_film_sizes[i].fill(0); + } +} + +/** + * @brief Returns the n-th camera + * @details This returns the n-th camera of the camera rig, which can be used + * for various stuff like showing its frustum, passing it as a shader input, + * and so on. + * + * The first camera is the camera which is the camera of the first split, + * which is the split closest to the camera. All cameras follow in descending + * order until to the last camera, which is the split furthest away from the + * camera. + * + * If an invalid index is passed, an assertion is thrown. + * + * @param index Index of the camera. + * @return [description] + */ +inline NodePath PSSMCameraRig::get_camera(size_t index) { + nassertr(index >= 0 && index < _cam_nodes.size(), NodePath()); + return _cam_nodes[index]; +} + +/** + * @brief Internal method to compute the distance of a split + * @details This is the internal method to perform the weighting of the + * logarithmic and linear distribution. It computes the distance to the + * camera from which a given split starts, by weighting the logarithmic and + * linear factor. + * + * The return value is a value ranging from 0 .. 1. To get the distance in + * world space, the value has to get multiplied with the maximum shadow distance. + * + * @param split_index The index of the split + * @return Distance of the split, ranging from 0 .. 1 + */ +inline float PSSMCameraRig::get_split_start(size_t split_index) { + float x = (float)split_index / (float)_cam_nodes.size(); + return (exp(_logarithmic_factor*x)-1) / (exp(_logarithmic_factor)-1); +} + +/** + * @brief Internal method for interpolating a point along the camera frustum + * @details This method takes a given distance in the 0 .. 1 range, whereas + * 0 denotes the camera near plane, and 1 denotes the camera far plane, + * and lineary interpolates between them. + * + * @param origin Edge of the frustum + * @param depth Distance in the 0 .. 1 range + * + * @return interpolated point in world space + */ +inline LPoint3f PSSMCameraRig::get_interpolated_point(CoordinateOrigin origin, float depth) { + nassertr(depth >= 0.0 && depth <= 1.0, LPoint3f()); + return _curr_near_points[origin] * (1.0 - depth) + _curr_far_points[origin] * depth; +} + +/** + * @brief Returns a handle to the MVP array + * @details This returns a handle to the array of view-projection matrices + * of the different splits. This can be used for computing shadows. The array + * is a PTALMatrix4f and thus can be directly bound to a shader. + * + * @return view-projection matrix array + */ +inline const PTA_LMatrix4f &PSSMCameraRig::get_mvp_array() { + return _camera_mvps; +} + +/** + * @brief Returns a handle to the near and far planes array + * @details This returns a handle to the near and far plane array. Each split + * has an entry in the array, whereas the x component of the vecto denotes the + * near plane, and the y component denotes the far plane of the split. + * + * This is required because the near and far planes of the splits change + * constantly. To access them in a shader, the shader needs access to the + * array. + * + * @return Array of near and far planes + */ +inline const PTA_LVecBase2f &PSSMCameraRig::get_nearfar_array() { + return _camera_nearfar; +} diff --git a/rpcore/native/source/pssm_camera_rig.cpp b/rpcore/native/source/pssm_camera_rig.cpp new file mode 100644 index 0000000..ee93b66 --- /dev/null +++ b/rpcore/native/source/pssm_camera_rig.cpp @@ -0,0 +1,396 @@ +/** + * + * RenderPipeline + * + * Copyright (c) 2014-2016 tobspr + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + */ + + +#include "pssm_camera_rig.h" + +#define _USE_MATH_DEFINES +#include +#include "orthographicLens.h" + + +PStatCollector PSSMCameraRig::_update_collector("App:Show code:RP_PSSM_update"); + +/** + * @brief Constructs a new PSSM camera rig + * @details This constructs a new camera rig, with a given amount of splits. + * The splits can not be changed later on. Splits are also called Cascades. + * + * An assertion will be triggered if the splits are below zero. + * + * @param num_splits Amount of PSSM splits + */ +PSSMCameraRig::PSSMCameraRig(size_t num_splits) { + nassertv(num_splits > 0); + _num_splits = num_splits; + _pssm_distance = 100.0; + _sun_distance = 500.0; + _use_fixed_film_size = false; + _use_stable_csm = true; + _logarithmic_factor = 1.0; + _resolution = 512; + _border_bias = 0.1; + _camera_mvps = PTA_LMatrix4f::empty_array(num_splits); + _camera_nearfar = PTA_LVecBase2f::empty_array(num_splits); + init_cam_nodes(); +} + +/** + * @brief Destructs the camera rig + * @details This destructs the camera rig, cleaning up all used resources. + */ +PSSMCameraRig::~PSSMCameraRig() { + // TODO: Detach all cameras and call remove_node. Most likely this is not + // an issue tho, because the camera rig will never get destructed. +} + +/** + * @brief Internal method to init the cameras + * @details This method constructs all cameras and their required lens nodes + * for all splits. It also resets the film size array. + */ +void PSSMCameraRig::init_cam_nodes() { + _cam_nodes.reserve(_num_splits); + _max_film_sizes.resize(_num_splits); + _cameras.resize(_num_splits); + for (size_t i = 0; i < _num_splits; ++i) + { + // Construct a new lens + Lens *lens = new OrthographicLens(); + lens->set_film_size(1, 1); + lens->set_near_far(1, 1000); + + // Construct a new camera + _cameras[i] = new Camera("pssm-cam-" + to_string(((long long)i)), lens); + _cam_nodes.push_back(NodePath(_cameras[i])); + _max_film_sizes[i].fill(0); + } +} + +/** + * @brief Reparents the camera rig + * @details This reparents all cameras to the given parent. Usually the parent + * will be ShowBase.render. The parent should be the same node where the + * main camera is located in, too. + * + * If an empty parrent is passed, an assertion will get triggered. + * + * @param parent Parent node path + */ +void PSSMCameraRig::reparent_to(NodePath parent) { + nassertv(!parent.is_empty()); + for (size_t i = 0; i < _num_splits; ++i) { + _cam_nodes[i].reparent_to(parent); + } + _parent = parent; +} + +/** + * @brief Internal method to compute the view-projection matrix of a camera + * @details This returns the view-projection matrix of the given split. No bounds + * checking is done. If an invalid index is passed, undefined behaviour occurs. + * + * @param split_index Index of the split + * @return view-projection matrix of the split + */ +LMatrix4f PSSMCameraRig::compute_mvp(size_t split_index) { + LMatrix4f transform = _parent.get_transform(_cam_nodes[split_index])->get_mat(); + return transform * _cameras[split_index]->get_lens()->get_projection_mat(); +} + +/** + * @brief Internal method used for stable CSM + * @details This method is used when stable CSM is enabled. It ensures that each + * source only moves in texel-steps, thus preventing flickering. This works by + * projecting the point (0, 0, 0) to NDC space, making sure that it gets projected + * to a texel center, and then projecting that texel back. + * + * This only works if the camera does not rotate, change its film size, or change + * its angle. + * + * @param mat view-projection matrix of the camera + * @param resolution resolution of the split + * + * @return Offset to add to the camera position to achieve stable snapping + */ +LVecBase3f PSSMCameraRig::get_snap_offset(const LMatrix4f& mat, size_t resolution) { + // Transform origin to camera space + LPoint4f base_point = mat.get_row(3) * 0.5 + 0.5; + + // Compute the snap offset + float texel_size = 1.0 / (float)(resolution); + float offset_x = fmod(base_point.get_x(), texel_size); + float offset_y = fmod(base_point.get_y(), texel_size); + + // Reproject the offset back, for that we need the inverse MVP + LMatrix4f inv_mat(mat); + inv_mat.invert_in_place(); + LVecBase3f new_base_point = inv_mat.xform_point(LVecBase3f( + (base_point.get_x() - offset_x) * 2.0 - 1.0, + (base_point.get_y() - offset_y) * 2.0 - 1.0, + base_point.get_z() * 2.0 - 1.0 + )); + return -new_base_point; +} + +/** + * @brief Computes the average of a list of points + * @details This computes the average over a given set of points in 3D space. + * It returns the average of those points, namely sum_of_points / num_points. + * + * It is designed to work with a frustum, which is why it takes two arrays + * with a dimension of 4. Usually the first array are the camera near points, + * and the second array are the camera far points. + * + * @param starts First array of points + * @param ends Second array of points + * @return Average of points + */ +LPoint3f get_average_of_points(LVecBase3f const (&starts)[4], LVecBase3f const (&ends)[4]) { + LPoint3f mid_point(0, 0, 0); + for (size_t k = 0; k < 4; ++k) { + mid_point += starts[k]; + mid_point += ends[k]; + } + return mid_point / 8.0; +} + +/** + * @brief Finds the minimum and maximum extends of the given projection + * @details This projects each point of the given array of points using the + * cameras view-projection matrix, and computes the minimum and maximum + * of the projected points. + * + * @param min_extent Will store the minimum extent of the projected points in NDC space + * @param max_extent Will store the maximum extent of the projected points in NDC space + * @param transform The transformation matrix of the camera + * @param proj_points The array of points to project + * @param cam The camera to be used to project the points + */ +void find_min_max_extents(LVecBase3f &min_extent, LVecBase3f &max_extent, const LMatrix4f &transform, LVecBase3f const (&proj_points)[8], Camera *cam) { + + min_extent.fill(1e10); + max_extent.fill(-1e10); + LPoint2f screen_points[8]; + + // Now project all points to the screen space of the current camera and also + // find the minimum and maximum extents + for (size_t k = 0; k < 8; ++k) { + LVecBase4f point(proj_points[k], 1); + LPoint4f proj_point = transform.xform(point); + LPoint3f proj_point_3d(proj_point.get_x(), proj_point.get_y(), proj_point.get_z()); + cam->get_lens()->project(proj_point_3d, screen_points[k]); + + // Find min / max extents + if (screen_points[k].get_x() > max_extent.get_x()) max_extent.set_x(screen_points[k].get_x()); + if (screen_points[k].get_y() > max_extent.get_y()) max_extent.set_y(screen_points[k].get_y()); + + if (screen_points[k].get_x() < min_extent.get_x()) min_extent.set_x(screen_points[k].get_x()); + if (screen_points[k].get_y() < min_extent.get_y()) min_extent.set_y(screen_points[k].get_y()); + + // Find min / max projected depth to adjust far plane + if (proj_point.get_y() > max_extent.get_z()) max_extent.set_z(proj_point.get_y()); + if (proj_point.get_y() < min_extent.get_z()) min_extent.set_z(proj_point.get_y()); + } +} + +/** + * @brief Computes a film size from a given minimum and maximum extend + * @details This takes a minimum and maximum extent in NDC space and computes + * the film size and film offset needed to cover that extent. + * + * @param film_size Output film size, can be used for Lens::set_film_size + * @param film_offset Output film offset, can be used for Lens::set_film_offset + * @param min_extent Minimum extent + * @param max_extent Maximum extent + */ +inline void get_film_properties(LVecBase2f &film_size, LVecBase2f &film_offset, const LVecBase3f &min_extent, const LVecBase3f &max_extent) { + float x_center = (min_extent.get_x() + max_extent.get_x()) * 0.5; + float y_center = (min_extent.get_y() + max_extent.get_y()) * 0.5; + float x_size = max_extent.get_x() - x_center; + float y_size = max_extent.get_y() - y_center; + film_size.set(x_size, y_size); + film_offset.set(x_center * 0.5, y_center * 0.5); +} + +/** + * @brief Merges two arrays + * @details This takes two arrays which each 4 members and produces an array + * with both arrays contained. + * + * @param dest Destination array + * @param array1 First array + * @param array2 Second array + */ +inline void merge_points_interleaved(LVecBase3f (&dest)[8], LVecBase3f const (&array1)[4], LVecBase3f const (&array2)[4]) { + for (size_t k = 0; k < 4; ++k) { + dest[k] = array1[k]; + dest[k+4] = array2[k]; + } +} + + +/** + * @brief Internal method to compute the splits + * @details This is the internal update method to update the PSSM splits. + * It distributes the camera splits over the frustum, and updates the + * MVP array aswell as the nearfar array. + * + * @param transform Main camera transform + * @param max_distance Maximum pssm distance, relative to the camera far plane + * @param light_vector Sun-Vector + */ +void PSSMCameraRig::compute_pssm_splits(const LMatrix4f& transform, float max_distance, const LVecBase3f& light_vector) { + nassertv(!_parent.is_empty()); + + // PSSM Distance should never be smaller than camera far plane. + nassertv(max_distance <= 1.0); + + float filmsize_bias = 1.0 + _border_bias; + + // Compute the positions of all cameras + for (size_t i = 0; i < _cam_nodes.size(); ++i) { + float split_start = get_split_start(i) * max_distance; + float split_end = get_split_start(i + 1) * max_distance; + + LVecBase3f start_points[4]; + LVecBase3f end_points[4]; + LVecBase3f proj_points[8]; + + // Get split bounding box, and collect all points which define the frustum + for (size_t k = 0; k < 4; ++k) { + start_points[k] = get_interpolated_point((CoordinateOrigin)k, split_start); + end_points[k] = get_interpolated_point((CoordinateOrigin)k, split_end); + proj_points[k] = start_points[k]; + proj_points[k + 4] = end_points[k]; + } + + // Compute approximate split mid point + LPoint3f split_mid = get_average_of_points(start_points, end_points); + LPoint3f cam_start = split_mid + light_vector * _sun_distance; + + // Reset the film size, offset and far-plane + Camera* cam = DCAST(Camera, _cam_nodes[i].node()); + cam->get_lens()->set_film_size(1, 1); + cam->get_lens()->set_film_offset(0, 0); + cam->get_lens()->set_near_far(1, 100); + + // Find a good initial position + _cam_nodes[i].set_pos(cam_start); + _cam_nodes[i].look_at(split_mid); + + LVecBase3f best_min_extent, best_max_extent; + + // Find minimum and maximum extents of the points + LMatrix4f merged_transform = _parent.get_transform(_cam_nodes[i])->get_mat(); + find_min_max_extents(best_min_extent, best_max_extent, merged_transform, proj_points, cam); + + // Find the film size to cover all points + LVecBase2f film_size, film_offset; + get_film_properties(film_size, film_offset, best_min_extent, best_max_extent); + + if (_use_fixed_film_size) { + // In case we use a fixed film size, store the maximum film size, and + // only change the film size if a new maximum is there + if (_max_film_sizes[i].get_x() < film_size.get_x()) _max_film_sizes[i].set_x(film_size.get_x()); + if (_max_film_sizes[i].get_y() < film_size.get_y()) _max_film_sizes[i].set_y(film_size.get_y()); + + cam->get_lens()->set_film_size(_max_film_sizes[i] * filmsize_bias); + } else { + // If we don't use a fixed film size, we can just set the film size + // on the lens. + cam->get_lens()->set_film_size(film_size * filmsize_bias); + } + + // Compute new film offset + cam->get_lens()->set_film_offset(film_offset); + cam->get_lens()->set_near_far(10, best_max_extent.get_z()); + _camera_nearfar[i] = LVecBase2f(10, best_max_extent.get_z()); + + // Compute the camera MVP + LMatrix4f mvp = compute_mvp(i); + + // Stable CSM Snapping + if (_use_stable_csm) { + LPoint3f snap_offset = get_snap_offset(mvp, _resolution); + _cam_nodes[i].set_pos(_cam_nodes[i].get_pos() + snap_offset); + + // Compute the new mvp, since we changed the snap offset + mvp = compute_mvp(i); + } + + _camera_mvps.set_element(i, mvp); + } +} + + +/** + * @brief Updates the PSSM camera rig + * @details This updates the rig with an updated camera position, and a given + * light vector. This should be called on a per-frame basis. It will reposition + * all camera sources to fit the frustum based on the pssm distribution. + * + * The light vector should be the vector from the light source, not the + * vector to the light source. + * + * @param cam_node Target camera node + * @param light_vector The vector from the light to any point + */ +void PSSMCameraRig::update(NodePath cam_node, const LVecBase3f &light_vector) { + nassertv(!cam_node.is_empty()); + _update_collector.start(); + + // Get camera node transform + LMatrix4f transform = cam_node.get_transform()->get_mat(); + + // Get Camera and Lens pointers + Camera* cam = DCAST(Camera, cam_node.get_child(0).node()); + nassertv(cam != NULL); + Lens* lens = cam->get_lens(); + + // Extract near and far points: + lens->extrude(LPoint2f(-1, 1), _curr_near_points[UpperLeft], _curr_far_points[UpperLeft]); + lens->extrude(LPoint2f(1, 1), _curr_near_points[UpperRight], _curr_far_points[UpperRight]); + lens->extrude(LPoint2f(-1, -1), _curr_near_points[LowerLeft], _curr_far_points[LowerLeft]); + lens->extrude(LPoint2f(1, -1), _curr_near_points[LowerRight], _curr_far_points[LowerRight]); + + // Construct MVP to project points to world space + LMatrix4f mvp = transform * lens->get_view_mat(); + + // Project all points to world space + for (size_t i = 0; i < 4; ++i) { + LPoint4f ws_near = mvp.xform(_curr_near_points[i]); + LPoint4f ws_far = mvp.xform(_curr_far_points[i]); + _curr_near_points[i].set(ws_near.get_x(), ws_near.get_y(), ws_near.get_z()); + _curr_far_points[i].set(ws_far.get_x(), ws_far.get_y(), ws_far.get_z()); + } + + // Do the actual PSSM + compute_pssm_splits( transform, _pssm_distance / lens->get_far(), light_vector ); + + _update_collector.stop(); +} + diff --git a/rpcore/native/source/pssm_camera_rig.h b/rpcore/native/source/pssm_camera_rig.h new file mode 100644 index 0000000..b192eb3 --- /dev/null +++ b/rpcore/native/source/pssm_camera_rig.h @@ -0,0 +1,129 @@ +/** + * + * RenderPipeline + * + * Copyright (c) 2014-2016 tobspr + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + */ + +#ifndef PSSM_CAMERA_RIG_H +#define PSSM_CAMERA_RIG_H + +#include "pandabase.h" +#include "luse.h" +#include "camera.h" +#include "nodePath.h" +#include "pStatCollector.h" + +#include + +/** + * @brief Main class used for handling PSSM + * @details This is the main class for supporting PSSM, it is used by the PSSM + * plugin to compute the position of the splits. + * + * It supports handling a varying amount of cameras, and fitting those cameras + * into the main camera frustum, to render distant shadows. It also supports + * various optimizations for fitting the frustum, e.g. rotating the sources + * to get a better coverage. + * + * It also provides methods to get arrays of data about the used cameras + * view-projection matrices and their near and far plane, which is required for + * processing the data in the shadow sampling shader. + * + * In this class, there is often referred to "Splits" or also called "Cascades". + * These denote the different cameras which are used to split the frustum, + * and are a common term related to the PSSM algorithm. + * + * To understand the functionality of this class, a detailed knowledge of the + * PSSM algorithm is helpful. + */ +class PSSMCameraRig { + + PUBLISHED: + PSSMCameraRig(size_t num_splits); + ~PSSMCameraRig(); + + inline void set_pssm_distance(float distance); + inline void set_sun_distance(float distance); + inline void set_use_fixed_film_size(bool flag); + inline void set_resolution(size_t resolution); + inline void set_use_stable_csm(bool flag); + inline void set_logarithmic_factor(float factor); + inline void set_border_bias(float bias); + + void update(NodePath cam_node, const LVecBase3f &light_vector); + inline void reset_film_size_cache(); + + inline NodePath get_camera(size_t index); + + void reparent_to(NodePath parent); + inline const PTA_LMatrix4f &get_mvp_array(); + inline const PTA_LVecBase2f &get_nearfar_array(); + + public: + + // Used to access the near and far points in the array + enum CoordinateOrigin { + UpperLeft = 0, + UpperRight, + LowerLeft, + LowerRight + }; + + protected: + + void init_cam_nodes(); + void compute_pssm_splits(const LMatrix4f& transform, float max_distance, + const LVecBase3f &light_vector); + inline float get_split_start(size_t split_index); + LMatrix4f compute_mvp(size_t cam_index); + inline LPoint3f get_interpolated_point(CoordinateOrigin origin, float depth); + LVecBase3f get_snap_offset(const LMatrix4f& mat, size_t resolution); + + vector _cam_nodes; + vector _cameras; + vector _max_film_sizes; + + // Current near and far points + // Order: UL, UR, LL, LR (See CoordinateOrigin) + LPoint3f _curr_near_points[4]; + LPoint3f _curr_far_points[4]; + float _pssm_distance; + float _sun_distance; + float _logarithmic_factor; + float _border_bias; + bool _use_fixed_film_size; + bool _use_stable_csm; + size_t _resolution; + size_t _num_splits; + NodePath _parent; + + PTA_LMatrix4f _camera_mvps; + PTA_LVecBase2f _camera_nearfar; + + static PStatCollector _update_collector; + +}; + +#include "pssm_camera_rig.I" + +#endif // PSSM_CAMERA_RIG_H diff --git a/rpcore/native/source/pssm_helper.cpp b/rpcore/native/source/pssm_helper.cpp new file mode 100644 index 0000000..df0ea35 --- /dev/null +++ b/rpcore/native/source/pssm_helper.cpp @@ -0,0 +1,116 @@ +/** + * + * RenderPipeline + * + * Copyright (c) 2014-2016 tobspr + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + */ + +// Only include the pssm helper if actually required +#ifdef RP_REQ_PSSM_HELPER + +#include "pssm_helper.h" + +#include + +/** + * @brief Internal method to generate a set of equations + * @details This generates a set of equations into a given equation system. + * Based on a given start point and end point, it inserts an equation to the + * system which will, when solved, solve the following equation: + * vec * = expected + * + * @param eq_system The equation system + * @param eq_results The target result vector of the equation system + * @param vec The actual vector to be transformed + * @param expected The expected output of the transformation + * @param offset The index of the equation + */ +void generate_equations(Eigen::MatrixXf &eq_system, Eigen::VectorXf &eq_results, const LVector4f &vec, LVector4f expected, size_t offset) { + size_t write_offset = offset * 4; + for (size_t row = 0; row < 4; ++row) { + float expected_coeff = expected.get_cell(row); + size_t col_offset = row * 4; + for (size_t col = 0; col < 4; ++col) { + eq_system(write_offset, col_offset + col) = vec.get_cell(col); + } + eq_results(write_offset++) = expected_coeff; + } +} +/** + * @brief Finds a projection mat arround the given set of points. + * @details This methods finds a projection matrix which projects the given set + * of frustum points to a unit cube, which can be used as a camera matrix. + * The eight points should determine the frustum uniquely. + * + * @param near_ul The Upper-Left point of the frustum on the near plane + * @param near_ur The Upper-Right point of the frustum on the near plane + * @param near_ll The Lower-Left point of the frustum on the near plane + * @param near_lr The Lower-Right point of the frustum on the near plane + * @param far_ul The Upper-Left point of the frustum on the far plane + * @param far_ur The Upper-Right point of the frustum on the far plane + * @param far_ll The Lower-Left point of the frustum on the far plane + * @param far_lr The Lower-Right point of the frustum on the far plane + * + */ +LMatrix4f PSSMHelper::find_projection_mat( + const LVector4f &near_ul, + const LVector4f &near_ur, + const LVector4f &near_ll, + const LVector4f &near_lr, + + const LVector4f &far_ul, + const LVector4f &far_ur, + const LVector4f &far_ll, + const LVector4f &far_lr) { + + // We have 8*4 = 32 equations, which require 16 coefficients each + Eigen::MatrixXf equation_system(32, 16); + Eigen::VectorXf equation_results(32); + equation_system.fill(0); + + // Generate the equations + size_t offset = 0; + generate_equations(equation_system, equation_results, near_ul, LVector4f(-1, 1, 0, 1), offset++); + generate_equations(equation_system, equation_results, near_ur, LVector4f( 1, 1, 0, 1), offset++); + generate_equations(equation_system, equation_results, near_ll, LVector4f(-1, -1, 0, 1), offset++); + generate_equations(equation_system, equation_results, near_lr, LVector4f( 1, -1, 0, 1), offset++); + + generate_equations(equation_system, equation_results, far_ul, LVector4f(-1, 1, 1, 1), offset++); + generate_equations(equation_system, equation_results, far_ur, LVector4f( 1, 1, 1, 1), offset++); + generate_equations(equation_system, equation_results, far_ll, LVector4f(-1, -1, 1, 1), offset++); + generate_equations(equation_system, equation_results, far_lr, LVector4f( 1, -1, 1, 1), offset++); + + // Solve the equation system + Eigen::VectorXf solved_system = equation_system.colPivHouseholderQr().solve(equation_results); + + // Construct result matrix and return it. We also need to transpose the matrix. + LMatrix4f result( + solved_system(0), solved_system(4), solved_system(8), solved_system(12), + solved_system(1), solved_system(5), solved_system(9), solved_system(13), + solved_system(2), solved_system(6), solved_system(10), solved_system(14), + solved_system(3), solved_system(7), solved_system(11), solved_system(15) + ); + return result; +} + + +#endif // RP_REQ_PSSM_HELPER diff --git a/rpcore/native/source/pssm_helper.h b/rpcore/native/source/pssm_helper.h new file mode 100644 index 0000000..a2bb305 --- /dev/null +++ b/rpcore/native/source/pssm_helper.h @@ -0,0 +1,57 @@ +/** + * + * RenderPipeline + * + * Copyright (c) 2014-2016 tobspr + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + */ + +#ifndef RP_PSSM_HELPER_H +#define RP_PSSM_HELPER_H + +// Only include the pssm helper if actually required +#ifdef RP_REQ_PSSM_HELPER + +#include "pandabase.h" +#include "luse.h" + +/** + * @brief Class to generate projection matrices. + */ +class PSSMHelper { + + PUBLISHED: + static LMatrix4f find_projection_mat( + const LVector4f &near_ul, + const LVector4f &near_ur, + const LVector4f &near_ll, + const LVector4f &near_lr, + + const LVector4f &far_ul, + const LVector4f &far_ur, + const LVector4f &far_ll, + const LVector4f &far_lr); + +}; + +#endif // RP_REQ_PSSM_HELPER + +#endif // RP_PSSM_HELPER_H diff --git a/rpcore/native/source/rp_light.I b/rpcore/native/source/rp_light.I new file mode 100644 index 0000000..756af2c --- /dev/null +++ b/rpcore/native/source/rp_light.I @@ -0,0 +1,406 @@ +/** + * + * RenderPipeline + * + * Copyright (c) 2014-2016 tobspr + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + */ + + +/** + * @brief Returns the amount of shadow sources + * @details This returns the amount of shadow sources attached to this light. + * In case the light has no shadows enabled, or the light was not attached + * yet, this returns 0. + * + * @return Amount of shadow sources + */ +inline int RPLight::get_num_shadow_sources() const { + return _shadow_sources.size(); +} + +/** + * @brief Returns the n-th shadow source + * @details This returns the n-th attached shadow source. This ranges from + * 0 .. RPLight::get_num_shadow_sources(). If an invalid index is passed, + * an assertion is thrown. + * + * @param index Index of the source + * @return Handle to the shadow source + */ +inline ShadowSource* RPLight::get_shadow_source(size_t index) const { + nassertr(index < _shadow_sources.size(), NULL); // Invalid shadow source index + return _shadow_sources[index]; +} + +/** + * @brief Clears all shadow source + * @details This removes and destructs all shadow sources attached to this light. + * This usually gets called when the light gets detached or destructed. + * All shadows sources are freed, and then removed from the shadow source list. + */ +inline void RPLight::clear_shadow_sources() { + for (size_t i = 0; i < _shadow_sources.size(); ++i) { + delete _shadow_sources[i]; + } + _shadow_sources.clear(); +} + +/** + * @brief Sets whether the light needs an update + * @details This controls whether the light needs to get an update. This is the + * case when a property of the light changed, e.g. position or color. It does + * not affect the shadows (For that use RPLight::invalidate_shadows()). + * When this flag is set to true, the light will get resubmitted to the GPU + * in the next update cycle. + * + * You should usually never set the flag to false manually. The + * InternalLightManager will do this when the data got sucessfully updated. + * + * @param flag Update-Flag + */ +inline void RPLight::set_needs_update(bool flag) { + _needs_update = flag; +} + +/** + * @brief Returns whether the light needs an update + * @details This returns whether the light needs an update. This might be the + * case when a property of the light was changed, e.g. position or color. + * It does not affect the shadows, you have to query the update flag of each + * individual source for that. + * The return value is the value previously set with RPLight::set_needs_update. + * + * @return Update-flag + */ +inline bool RPLight::get_needs_update() const { + return _needs_update; +} + +/** + * @brief Returns whether the light has a slot + * @details This returns wheter the light currently is attached, and thus has + * a slot in the InternalLightManagers light list. When the light is attached, + * this returns true, otherwise it will return false. + * + * @return true if the light has a slot, false otherwise + */ +inline bool RPLight::has_slot() const { + return _slot >= 0; +} + +/** + * @brief Returns the slot of the light + * @details This returns the slot of the light. This is the space on the GPU + * where the light is stored. If the light is not attached yet, this will + * return -1, otherwise the index of the light. + * + * @return Light-Slot + */ +inline int RPLight::get_slot() const { + return _slot; +} + +/** + * @brief Removes the light slot + * @details This is an internal method to remove the slot of the light. It gets + * called by the InternalLightManager when a light gets detached. It internally + * sets the slot to -1 to indicate the light is no longer attached. + */ +inline void RPLight::remove_slot() { + _slot = -1; +} + +/** + * @brief Assigns a slot to the light + * @details This assigns a slot to the light, marking it as attached. The slot + * relates to the index in the GPU's storage of lights. This is an internal + * method called by the InternalLightManager when the light got attached. + * + * @param slot Slot of the light + */ +inline void RPLight::assign_slot(int slot) { + _slot = slot; +} + +/** + * @brief Invalidates the shadows + * @details This invalidates all shadows of the light, causing them to get + * regenerated. This might be the case when the lights position or similar + * changed. This will cause all shadow sources to be updated, emitting a + * shadow update. Be careful when calling this method if you don't want all + * sources to get updated. If you only have to invalidate a single shadow source, + * use get_shadow_source(n)->set_needs_update(true). + */ +inline void RPLight::invalidate_shadows() { + for (size_t i = 0; i < _shadow_sources.size(); ++i) { + _shadow_sources[i]->set_needs_update(true); + } +} + +/** + * @brief Sets the position of the light + * @details This sets the position of the light in world space. It will cause + * the light to get invalidated, and resubmitted to the GPU. + * + * @param pos Position in world space + */ +inline void RPLight::set_pos(const LVecBase3f &pos) { + set_pos(pos.get_x(), pos.get_y(), pos.get_z()); +} + +/** + * @brief Sets the position of the light + * @details @copydetails RPLight::set_pos(const LVecBase3f &pos) + * + * @param x X-component of the position + * @param y Y-component of the position + * @param z Z-component of the position + */ +inline void RPLight::set_pos(float x, float y, float z) { + _position.set(x, y, z); + set_needs_update(true); + invalidate_shadows(); +} + +/** + * @brief Returns the position of the light + * @details This returns the position of the light previously set with + * RPLight::set_pos(). The returned position is in world space. + * @return Light-position + */ +inline const LVecBase3f& RPLight::get_pos() const { + return _position; +} + +/** + * @brief Sets the lights color + * @details This sets the lights color. The color should not include the brightness + * of the light, you should control that with the energy. The color specifies + * the lights "tint" and will get multiplied with its specular and diffuse + * contribution. + * + * The color will be normalized by dividing by the colors luminance. Setting + * higher values than 1.0 will have no effect. + * + * @param color Light color + */ +inline void RPLight::set_color(const LVecBase3f &color) { + _color = color; + _color /= 0.2126 * color.get_x() + 0.7152 * color.get_y() + 0.0722 * color.get_z(); + set_needs_update(true); +} + +/** + * @brief Sets the lights color + * @details @copydetails RPLight::set_color(const LVecBase3f &color) + * + * @param r Red-component of the color + * @param g Green-component of the color + * @param b Blue-component of the color + */ +inline void RPLight::set_color(float r, float g, float b) { + set_color(LVecBase3f(r, g, b)); +} + +/** + * @brief Returns the lights color + * @details This returns the light color, previously set with RPLight::set_color. + * This does not include the energy of the light. It might differ from what + * was set with set_color, because the color is normalized by dividing it + * by its luminance. + * @return Light-color + */ +inline const LVecBase3f& RPLight::get_color() const { + return _color; +} + +/** + * @brief Sets the energy of the light + * @details This sets the energy of the light, which can be seen as the brightness + * of the light. It will get multiplied with the normalized color. + * + * @param energy energy of the light + */ +inline void RPLight::set_energy(float energy) { + _energy = energy; + set_needs_update(true); +} + +/** + * @brief Returns the energy of the light + * @details This returns the energy of the light, previously set with + * RPLight::set_energy. + * + * @return energy of the light + */ +inline float RPLight::get_energy() const { + return _energy; +} + +/** + * @brief Returns the type of the light + * @details This returns the internal type of the light, which was specified + * in the lights constructor. This can be used to distinguish between light + * types. + * @return Type of the light + */ +inline RPLight::LightType RPLight::get_light_type() const { + return _light_type; +} + +/** + * @brief Controls whether the light casts shadows + * @details This sets whether the light casts shadows. You can not change this + * while the light is attached. When flag is set to true, the light will be + * setup to cast shadows, spawning shadow sources based on the lights type. + * If the flag is set to false, the light will be inddicated to cast no shadows. + * + * @param flag Whether the light casts shadows + */ +inline void RPLight::set_casts_shadows(bool flag) { + if (has_slot()) { + cerr << "Light is already attached, can not call set_casts_shadows!" << endl; + return; + } + _casts_shadows = flag; +} + +/** + * @brief Returns whether the light casts shadows + * @details This returns whether the light casts shadows, the returned value + * is the one previously set with RPLight::set_casts_shadows. + * + * @return true if the light casts shadows, false otherwise + */ +inline bool RPLight::get_casts_shadows() const { + return _casts_shadows; +} + +/** + * @brief Sets the lights shadow map resolution + * @details This sets the lights shadow map resolution. This has no effect + * when the light is not told to cast shadows (Use RPLight::set_casts_shadows). + * + * When calling this on a light with multiple shadow sources (e.g. PointLight), + * this controls the resolution of each source. If the light has 6 shadow sources, + * and you use a resolution of 512x512, the lights shadow map will occur a + * space of 6 * 512x512 maps in the shadow atlas. + * + * @param resolution Resolution of the shadow map in pixels + */ +inline void RPLight::set_shadow_map_resolution(size_t resolution) { + nassertv(resolution >= 32 && resolution <= 16384); + _source_resolution = resolution; + invalidate_shadows(); +} + +/** + * @brief Returns the shadow map resolution + * @details This returns the shadow map resolution of each source of the light. + * If the light is not setup to cast shadows, this value is meaningless. + * The returned value is the one previously set with RPLight::set_shadow_map_resolution. + * + * @return Shadow map resolution in pixels + */ +inline size_t RPLight::get_shadow_map_resolution() const { + return _source_resolution; +} + +/** + * @brief Sets the ies profile + * @details This sets the ies profile of the light. The parameter should be a + * handle previously returned by RenderPipeline.load_ies_profile. Using a + * value of -1 indicates no ies profile. + * + * Notice that for ies profiles which cover a whole range, you should use + * PointLights, whereas for ies profiles which only cover the lower hemisphere + * you should use SpotLights for the best performance. + * + * @param profile IES Profile handle + */ +inline void RPLight::set_ies_profile(int profile) { + _ies_profile = profile; + set_needs_update(true); +} + +/** + * @brief Returns the lights ies profile + * @details This returns the ies profile of a light, previously set with + * RPLight::set_ies_profile. In case no ies profile was set, returns -1. + * + * @return IES Profile handle + */ +inline int RPLight::get_ies_profile() const { + return _ies_profile; +} + +/** + * @brief Returns whether the light has an ies profile assigned + * @details This returns whether the light has an ies profile assigned, + * previously done with RPLight::set_ies_profile. + * + * @return true if the light has an ies profile assigned, false otherwise + */ +inline bool RPLight::has_ies_profile() const { + return _ies_profile >= 0; +} + +/** + * @brief Clears the ies profile + * @details This clears the ies profile of the light, telling it to no longer + * use an ies profile, and instead use the default attenuation. + */ +inline void RPLight::clear_ies_profile() { + set_ies_profile(-1); +} + +/** + * @brief Sets the near plane of the light + * @details This sets the near plane of all shadow sources of the light. It has + * no effects if the light does not cast shadows. This prevents artifacts from + * objects near to the light. It behaves like Lens::set_near_plane. + * + * It can also help increasing shadow map precision, low near planes will + * cause the precision to suffer. Try setting the near plane as big as possible. + * + * If a negative or zero near plane is passed, an assertion is thrown. + * + * @param near_plane Near-plane + */ +inline void RPLight::set_near_plane(float near_plane) { + nassertv(near_plane > 0.00001); + _near_plane = near_plane; + invalidate_shadows(); +} + +/** + * @brief Returns the near plane of the light + * @details This returns the lights near plane, previously set with + * RPLight::set_near_plane. If the light does not cast shadows, this value + * is meaningless. + * + * @return Near-plane + */ +inline float RPLight::get_near_plane() const { + return _near_plane; +} + diff --git a/rpcore/native/source/rp_light.cpp b/rpcore/native/source/rp_light.cpp new file mode 100644 index 0000000..24a84b4 --- /dev/null +++ b/rpcore/native/source/rp_light.cpp @@ -0,0 +1,137 @@ +/** + * + * RenderPipeline + * + * Copyright (c) 2014-2016 tobspr + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + */ + + +#include "rp_light.h" + + +/** + * @brief Constructs a new light with the given type + * @details This constructs a new base light with the given light type. + * Sub-Classes should call this to initialize all properties. + * + * @param light_type Type of the light + */ +RPLight::RPLight(LightType light_type) { + _light_type = light_type; + _needs_update = false; + _casts_shadows = false; + _slot = -1; + _position.fill(0); + _color.fill(1); + _ies_profile = -1; + _source_resolution = 512; + _near_plane = 0.5; + _energy = 20.0; +} + +/** + * @brief Writes the light to a GPUCommand + * @details This writes all of the lights data to the given GPUCommand handle. + * Subclasses should first call this method, and then append their own + * data. This makes sure that for unpacking a light, no information about + * the type of the light is required. + * + * @param cmd The GPUCommand to write to + */ +void RPLight::write_to_command(GPUCommand &cmd) { + cmd.push_int(_light_type); + cmd.push_int(_ies_profile); + + if (_casts_shadows) { + // If we casts shadows, write the index of the first source, we expect + // them to be consecutive + nassertv(_shadow_sources.size() >= 0); + nassertv(_shadow_sources[0]->has_slot()); + cmd.push_int(_shadow_sources[0]->get_slot()); + } else { + // If we cast no shadows, just push a negative number + cmd.push_int(-1); + } + + cmd.push_vec3(_position); + + // Get the lights color by multiplying color with energy. Divide by + // 100, since 16bit floating point buffers only go up to 65000.0, which + // prevents very bright lights + cmd.push_vec3(_color * _energy / 100.0); +} + +/** + * @brief Light destructor + * @details This destructs the light, cleaning up all resourced used. The light + * should be detached at this point, because while the Light is attached, + * the InternalLightManager holds a reference to prevent it from being + * destructed. + */ +RPLight::~RPLight() { + nassertv(!has_slot()); // Light still attached - should never happen + clear_shadow_sources(); +} + +/** + * @brief Sets the lights color from a given color temperature + * @details This sets the lights color, given a temperature. This is more + * physically based than setting a user defined color. The color will be + * computed from the given temperature. + * + * @param temperature Light temperature + */ +void RPLight::set_color_from_temperature(float temperature) { + + // Thanks to rdb for this conversion script + float mm = 1000.0 / temperature; + float mm2 = mm * mm; + float mm3 = mm2 * mm; + float x, y; + + if (temperature < 4000) { + x = -0.2661239 * mm3 - 0.2343580 * mm2 + 0.8776956 * mm + 0.179910; + } else { + x = -3.0258469 * mm3 + 2.1070379 * mm2 + 0.2226347 * mm + 0.240390; + } + + float x2 = x * x; + float x3 = x2 * x; + if (temperature < 2222) { + y = -1.1063814 * x3 - 1.34811020 * x2 + 2.18555832 * x - 0.20219683; + } else if (temperature < 4000) { + y = -0.9549476 * x3 - 1.37418593 * x2 + 2.09137015 * x - 0.16748867; + } else { + y = 3.0817580 * x3 - 5.87338670 * x2 + 3.75112997 * x - 0.37001483; + } + + // xyY to XYZ, assuming Y=1. + LVecBase3 xyz(x / y, 1, (1 - x - y) / y); + + // Convert XYZ to linearized sRGB. + const static LMatrix3 xyz_to_rgb( + 3.2406, -0.9689, 0.0557, + -1.5372, 1.8758, -0.2050, + -0.4986, 0.0415, 1.0570); + + set_color(xyz_to_rgb.xform(xyz)); +} diff --git a/rpcore/native/source/rp_light.h b/rpcore/native/source/rp_light.h new file mode 100644 index 0000000..2fbc07e --- /dev/null +++ b/rpcore/native/source/rp_light.h @@ -0,0 +1,135 @@ +/** + * + * RenderPipeline + * + * Copyright (c) 2014-2016 tobspr + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + */ + +#ifndef RP_LIGHT_H +#define RP_LIGHT_H + +#include "referenceCount.h" +#include "luse.h" +#include "gpu_command.h" +#include "shadow_source.h" + +/** + * @brief Base class for Lights + * @details This is the base class for all lights in the render pipeline. It + * stores common properties, and provides methods to modify these. + * It also defines some interface functions which subclasses have to implement. + */ +class RPLight : public ReferenceCount { + + PUBLISHED: + + /** + * Different types of light. + */ + enum LightType { + LT_empty = 0, + LT_point_light = 1, + LT_spot_light = 2, + }; + + public: + RPLight(LightType light_type); + virtual ~RPLight(); + + virtual void init_shadow_sources() = 0; + virtual void update_shadow_sources() = 0; + virtual void write_to_command(GPUCommand &cmd); + + inline int get_num_shadow_sources() const; + inline ShadowSource* get_shadow_source(size_t index) const; + inline void clear_shadow_sources(); + + inline void set_needs_update(bool flag); + inline bool get_needs_update() const; + + inline bool has_slot() const; + inline int get_slot() const; + inline void remove_slot(); + inline void assign_slot(int slot); + + + PUBLISHED: + + inline void invalidate_shadows(); + + inline void set_pos(const LVecBase3f &pos); + inline void set_pos(float x, float y, float z); + inline const LVecBase3f& get_pos() const; + MAKE_PROPERTY(pos, get_pos, set_pos); + + inline void set_color(const LVecBase3f &color); + inline void set_color(float r, float g, float b); + inline const LVecBase3f& get_color() const; + MAKE_PROPERTY(color, get_color, set_color); + + void set_color_from_temperature(float temperature); + + inline void set_energy(float energy); + inline float get_energy() const; + MAKE_PROPERTY(energy, get_energy, set_energy); + + inline LightType get_light_type() const; + MAKE_PROPERTY(light_type, get_light_type); + + inline void set_casts_shadows(bool flag = true); + inline bool get_casts_shadows() const; + MAKE_PROPERTY(casts_shadows, get_casts_shadows, set_casts_shadows); + + inline void set_shadow_map_resolution(size_t resolution); + inline size_t get_shadow_map_resolution() const; + MAKE_PROPERTY(shadow_map_resolution, get_shadow_map_resolution, set_shadow_map_resolution); + + inline void set_ies_profile(int profile); + inline int get_ies_profile() const; + inline bool has_ies_profile() const; + inline void clear_ies_profile(); + MAKE_PROPERTY2(ies_profile, has_ies_profile, get_ies_profile, + set_ies_profile, clear_ies_profile); + + inline void set_near_plane(float near_plane); + inline float get_near_plane() const; + MAKE_PROPERTY(near_plane, get_near_plane, set_near_plane); + + protected: + + int _slot; + int _ies_profile; + size_t _source_resolution; + bool _needs_update; + bool _casts_shadows; + LVecBase3f _position; + LVecBase3f _color; + float _energy; + LightType _light_type; + float _near_plane; + + vector _shadow_sources; +}; + +#include "rp_light.I" + +#endif // RP_LIGHT_H diff --git a/rpcore/native/source/rp_point_light.I b/rpcore/native/source/rp_point_light.I new file mode 100644 index 0000000..ab85c40 --- /dev/null +++ b/rpcore/native/source/rp_point_light.I @@ -0,0 +1,82 @@ +/** + * + * RenderPipeline + * + * Copyright (c) 2014-2016 tobspr + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + */ + + +/** + * @brief Sets the radius of the light + * @details This sets the radius of the light. It controls the lights + * influence. After a distance greater than this radius, the light influence + * is zero. + * + * @param radius Light radius in world space + */ +inline void RPPointLight::set_radius(float radius) { + nassertv(radius > 0); // Invalid light radius + _radius = radius; + set_needs_update(true); + invalidate_shadows(); +} + +/** + * @brief Returns the lights radius + * @details This returns the lights radius previously set with + * RPPointLight::set_radius + * @return Light radius in world space + */ +inline float RPPointLight::get_radius() const { + return _radius; +} + +/** + * @brief Sets the inner radius of the light + * @details This sets the inner radius of the light. Anything greater than + * zero causes the light to get an area light. This has influence on the + * specular highlights of the light aswell as the shadows. + * + * The inner radius controls the size of the lights sphere size in world + * space units. A radius of 0 means the light has no inner radius, and the + * light will be have like an infinite small point light source. + * A radius greater than zero will cause the light to behave like it would be + * an emissive sphere with the given inner radius emitting light. This is + * more physically correct. + * + * @param inner_radius Inner-radius in world space + */ +inline void RPPointLight::set_inner_radius(float inner_radius) { + nassertv(inner_radius >= 0.01); // Invalid inner radius + _inner_radius = inner_radius; + set_needs_update(true); +} + +/** + * @brief Returns the inner radius of the light + * @details This returns the inner radius of the light, previously set with + * RPPointLight::get_inner_radius. + * @return [description] + */ +inline float RPPointLight::get_inner_radius() const { + return _inner_radius; +} diff --git a/rpcore/native/source/rp_point_light.cpp b/rpcore/native/source/rp_point_light.cpp new file mode 100644 index 0000000..8fb5ba7 --- /dev/null +++ b/rpcore/native/source/rp_point_light.cpp @@ -0,0 +1,90 @@ +/** + * + * RenderPipeline + * + * Copyright (c) 2014-2016 tobspr + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + */ + + +#include "rp_point_light.h" + + +/** + * @brief Constructs a new point light + * @details This contructs a new point light with default settings. By default + * the light is set to be an infinitely small point light source. You can + * change this with RPPointLight::set_inner_radius. + */ +RPPointLight::RPPointLight() : RPLight(RPLight::LT_point_light) { + _radius = 10.0; + _inner_radius = 0.01; +} + +/** + * @brief Writes the light to a GPUCommand + * @details This writes the point light data to a GPUCommand. + * @see RPLight::write_to_command + * + * @param cmd The target GPUCommand + */ +void RPPointLight::write_to_command(GPUCommand &cmd) { + RPLight::write_to_command(cmd); + cmd.push_float(_radius); + cmd.push_float(_inner_radius); +} + +/** + * @brief Inits the shadow sources of the light + * @details This inits all required shadow sources for the point light. + * @see RPLight::init_shadow_sources + */ +void RPPointLight::init_shadow_sources() { + nassertv(_shadow_sources.size() == 0); + // Create 6 shadow sources, one for each direction + for(size_t i = 0; i < 6; ++i) { + _shadow_sources.push_back(new ShadowSource()); + } +} + +/** + * @brief Updates the shadow sources + * @details This updates all shadow sources of the light. + * @see RPLight::update_shadow_sources + */ +void RPPointLight::update_shadow_sources() { + LVecBase3f directions[6] = { + LVecBase3f( 1, 0, 0), + LVecBase3f(-1, 0, 0), + LVecBase3f( 0, 1, 0), + LVecBase3f( 0, -1, 0), + LVecBase3f( 0, 0, 1), + LVecBase3f( 0, 0, -1) + }; + + // Increase fov to prevent artifacts at the shadow map transitions + const float fov = 90.0f + 3.0f; + for (size_t i = 0; i < _shadow_sources.size(); ++i) { + _shadow_sources[i]->set_resolution(get_shadow_map_resolution()); + _shadow_sources[i]->set_perspective_lens(fov, _near_plane, _radius, + _position, directions[i]); + } +} diff --git a/rpcore/native/source/rp_point_light.h b/rpcore/native/source/rp_point_light.h new file mode 100644 index 0000000..cca9ea1 --- /dev/null +++ b/rpcore/native/source/rp_point_light.h @@ -0,0 +1,66 @@ +/** + * + * RenderPipeline + * + * Copyright (c) 2014-2016 tobspr + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + */ + +#ifndef RP_POINT_LIGHT_H +#define RP_POINT_LIGHT_H + +#include "pandabase.h" +#include "rp_light.h" + +/** + * @brief PointLight class + * @details This represents a point light, a light which has a position and + * radius. Checkout the RenderPipeline documentation for more information + * about this type of light. + */ +class RPPointLight : public RPLight { + + PUBLISHED: + RPPointLight(); + + inline void set_radius(float radius); + inline float get_radius() const; + MAKE_PROPERTY(radius, get_radius, set_radius); + + inline void set_inner_radius(float inner_radius); + inline float get_inner_radius() const; + MAKE_PROPERTY(inner_radius, get_inner_radius, set_inner_radius); + + public: + virtual void write_to_command(GPUCommand &cmd); + virtual void update_shadow_sources(); + virtual void init_shadow_sources(); + + protected: + + float _radius; + float _inner_radius; + +}; + +#include "rp_point_light.I" + +#endif // RP_POINT_LIGHT_H diff --git a/rpcore/native/source/rp_spot_light.I b/rpcore/native/source/rp_spot_light.I new file mode 100644 index 0000000..ba6b7d4 --- /dev/null +++ b/rpcore/native/source/rp_spot_light.I @@ -0,0 +1,74 @@ +/** + * + * RenderPipeline + * + * Copyright (c) 2014-2016 tobspr + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + */ + + + +inline void RPSpotLight::set_radius(float radius) { + _radius = radius; + set_needs_update(true); + invalidate_shadows(); +} + +inline float RPSpotLight::get_radius() const { + return _radius; +} + + +inline void RPSpotLight::set_fov(float fov) { + _fov = fov; + set_needs_update(true); + invalidate_shadows(); +} + +inline float RPSpotLight::get_fov() const { + return _fov; +} + +inline void RPSpotLight::set_direction(LVecBase3f direction) { + _direction = direction; + _direction.normalize(); + set_needs_update(true); + invalidate_shadows(); +} + +inline void RPSpotLight::set_direction(float dx, float dy, float dz) { + _direction.set(dx, dy, dz); + _direction.normalize(); + set_needs_update(true); + invalidate_shadows(); +} + +inline const LVecBase3f& RPSpotLight::get_direction() const { + return _direction; +} + +inline void RPSpotLight::look_at(LVecBase3f point) { + set_direction(point - _position); +} + +inline void RPSpotLight::look_at(float x, float y, float z) { + set_direction(LVecBase3f(x, y, z) - _position); +} diff --git a/rpcore/native/source/rp_spot_light.cpp b/rpcore/native/source/rp_spot_light.cpp new file mode 100644 index 0000000..2dbcf22 --- /dev/null +++ b/rpcore/native/source/rp_spot_light.cpp @@ -0,0 +1,80 @@ +/** + * + * RenderPipeline + * + * Copyright (c) 2014-2016 tobspr + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + */ + + +#include "rp_spot_light.h" + +#define _USE_MATH_DEFINES +#include + + +/** + * @brief Creates a new spot light + * @details This creates a new spot light with default properties set. You should + * set at least a direction, fov, radius and position to make the light useful. + */ +RPSpotLight::RPSpotLight() : RPLight(RPLight::LT_spot_light) { + _radius = 10.0; + _fov = 45.0; + _direction.set(0, 0, -1); +} + +/** + * @brief Writes the light to a GPUCommand + * @details This writes the spot light data to a GPUCommand. + * @see RPLight::write_to_command + * + * @param cmd The target GPUCommand + */ +void RPSpotLight::write_to_command(GPUCommand &cmd) { + RPLight::write_to_command(cmd); + cmd.push_float(_radius); + + // Encode FOV as cos(fov) + cmd.push_float(cos(_fov / 360.0 * M_PI)); + cmd.push_vec3(_direction); +} + +/** + * @brief Inits the shadow sources of the light + * @details This inits all required shadow sources for the spot light. + * @see RPLight::init_shadow_sources + */ +void RPSpotLight::init_shadow_sources() { + nassertv(_shadow_sources.size() == 0); + _shadow_sources.push_back(new ShadowSource()); +} + +/** + * @brief Updates the shadow sources + * @details This updates all shadow sources of the light. + * @see RPLight::update_shadow_sources + */ +void RPSpotLight::update_shadow_sources() { + _shadow_sources[0]->set_resolution(get_shadow_map_resolution()); + _shadow_sources[0]->set_perspective_lens(_fov, _near_plane, _radius, _position, _direction); +} + diff --git a/rpcore/native/source/rp_spot_light.h b/rpcore/native/source/rp_spot_light.h new file mode 100644 index 0000000..aade599 --- /dev/null +++ b/rpcore/native/source/rp_spot_light.h @@ -0,0 +1,72 @@ +/** + * + * RenderPipeline + * + * Copyright (c) 2014-2016 tobspr + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + */ + +#ifndef RP_SPOT_LIGHT_H +#define RP_SPOT_LIGHT_H + +#include "pandabase.h" +#include "rp_light.h" + +/** + * @brief SpotLight class + * @details This represents a spot light, a light which has a position, radius, + * direction and FoV. Checkout the RenderPipeline documentation for more + * information about this type of light. + */ +class RPSpotLight : public RPLight { + + PUBLISHED: + RPSpotLight(); + + inline void set_radius(float radius); + inline float get_radius() const; + MAKE_PROPERTY(radius, get_radius, set_radius); + + inline void set_fov(float fov); + inline float get_fov() const; + MAKE_PROPERTY(fov, get_fov, set_fov); + + inline void set_direction(LVecBase3f direction); + inline void set_direction(float dx, float dy, float dz); + inline const LVecBase3f& get_direction() const; + inline void look_at(LVecBase3f point); + inline void look_at(float x, float y, float z); + MAKE_PROPERTY(direction, get_direction, set_direction); + + public: + virtual void write_to_command(GPUCommand &cmd); + virtual void init_shadow_sources(); + virtual void update_shadow_sources(); + + protected: + float _radius; + float _fov; + LVecBase3f _direction; +}; + +#include "rp_spot_light.I" + +#endif // RP_SPOT_LIGHT_H diff --git a/rpcore/native/source/shadow_atlas.I b/rpcore/native/source/shadow_atlas.I new file mode 100644 index 0000000..2bb93c6 --- /dev/null +++ b/rpcore/native/source/shadow_atlas.I @@ -0,0 +1,159 @@ +/** + * + * RenderPipeline + * + * Copyright (c) 2014-2016 tobspr + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + */ + + +/** + * @brief Returns the tile size of the atlas. + * @details This returns the tile size of the atlas, which was set in the + * constructor. This is the smalles unit of the atlas, and every resolution + * has to be a multiple of the tile size. + * @return Tile size in pixels + */ +inline int ShadowAtlas::get_tile_size() const { + return _tile_size; +} + +/** + * @brief Sets a specific tile status. + * @details This marks a tile to either reserved or free, depending on the flag. + * If flag is true, the tile gets marked as reserved. If flag is false, the + * tile gets marked as free. + * + * No bounds checking is done for performance reasons. Passing an invalid tile + * index causes a crash. The coordinates are expected to be in tile space. + * + * @param x x-position of the tile + * @param y y-position of the tile + * @param flag Flag to set the tile to + */ +inline void ShadowAtlas::set_tile(size_t x, size_t y, bool flag) { + _flags[x + y * _num_tiles] = flag; +} + +/** + * @brief Returns the status of a given tile. + * @details This returns the value of a tile. If the tile is true, this means + * the tile is already reserved. If the tile is false, the tile can be + * used, and is not reserved. + * + * No bounds checking is done for performance reasons. Passing an invalid tile + * index causes a crash. The coordinates are expected to be in tile space. + * + * @param x x-position of the tile + * @param y y-position of the tile + * + * @return Tile-Status + */ +inline bool ShadowAtlas::get_tile(size_t x, size_t y) const { + return _flags[x + y * _num_tiles]; +} + +/** + * @brief Checks wheter a given region is free. + * @details This checks whether a given region in the atlas is still free. This + * is true if *all* tiles in that region are false, and thus are not taken yet. + * The coordinates are expected to be in tile space. + * + * Passing an invalid region, causes an assertion, in case those are enabled. + * If assertions are optimized out, this method will crash when passing invalid + * bounds. + * + * @param x x- start position of the region + * @param y y- start position of the region + * @param w width of the region + * @param h height of the region + * @return true if the region is completely free, else false + */ +inline bool ShadowAtlas::region_is_free(size_t x, size_t y, size_t w, size_t h) const { + // Check if we are out of bounds, this should be disabled for performance + // reasons at some point. + nassertr(x >= 0 && y >= 0 && x + w <= _num_tiles && y + h <= _num_tiles, false); + + // Iterate over every tile in that region and check if it is still free. + for (size_t cx = 0; cx < w; ++cx) { + for (size_t cy = 0; cy < h; ++cy) { + if (get_tile(cx + x, cy + y)) return false; + } + } + return true; +} + +/** + * @brief Returns the amount of tiles required to store a resolution. + * @details Returns the amount of tiles which would be required to store a + * given resolution. This basically just returns resolution / tile_size. + * + * When an invalid resolution is passed (not a multiple of the tile size), + * an error is printed and 1 is returned. + * When a negative or zero resolution is passed, undefined behaviour occurs. + * + * @param resolution The resolution to compute the amount of tiles for + * @return Amount of tiles to store the resolution + */ +inline int ShadowAtlas::get_required_tiles(size_t resolution) const { + nassertr(resolution > 0, -1); + + if (resolution % _tile_size != 0) { + shadowatlas_cat.error() << "Resolution " << resolution << " is not a multiple " + << "of the shadow atlas tile size (" << _tile_size << ")!" << endl; + return 1; + } + return resolution / _tile_size; +} + +/** + * @brief Converts a tile-space region to uv space. + * @details This converts a region (presumably from ShadowAtlas::find_and_reserve_region) + * to uv space (0 .. 1 range). This can be used in shaders, since they expect + * floating point coordinates instead of integer coordinates. + * + * @param region tile-space region + * @return uv-space region + */ +inline LVecBase4f ShadowAtlas::region_to_uv(const LVecBase4i& region) { + LVecBase4f flt = LVecBase4f(region.get_x(), region.get_y(), region.get_z(), region.get_w()); + return flt * ((float)_tile_size / (float)_size); +} + +/** + * @brief Returns the amount of used tiles + * @details Returns the amount of used tiles in the atlas + * @return Amount of used tiles + */ +inline int ShadowAtlas::get_num_used_tiles() const { + return _num_used_tiles; +} + +/** + * @brief Returns the amount of used tiles in percentage + * @details This returns in percentage from 0 to 1 how much space of the atlas + * is used right now. A value of 1 means the atlas is completely full, whereas + * a value of 0 means the atlas is completely free. + * @return Atlas usage in percentage + */ +inline float ShadowAtlas::get_coverage() const { + return float(_num_used_tiles) / float(_num_tiles * _num_tiles); +} diff --git a/rpcore/native/source/shadow_atlas.cpp b/rpcore/native/source/shadow_atlas.cpp new file mode 100644 index 0000000..d27bc67 --- /dev/null +++ b/rpcore/native/source/shadow_atlas.cpp @@ -0,0 +1,186 @@ +/** + * + * RenderPipeline + * + * Copyright (c) 2014-2016 tobspr + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + */ + + +#include "shadow_atlas.h" +#include + +NotifyCategoryDef(shadowatlas, ""); + +/** + * @brief Constructs a new shadow atlas. + * @details This constructs a new shadow atlas with the given size and tile size. + * + * The size determines the total size of the atlas in pixels. It should be a + * power-of-two to favour the GPU. + * + * The tile_size determines the smallest unit of tiles the atlas can store. + * If, for example, a tile_size of 32 is used, then every entry stored must + * have a resolution of 32 or greater, and the resolution must be a multiple + * of 32. This is to optimize the search in the atlas, so the atlas does not + * have to check every pixel, and instead can just check whole tiles. + * + * If you want to disable the use of tiles, set the tile_size to 1, which + * will make the shadow atlas use pixels instead of tiles. + * + * @param size Atlas-size in pixels + * @param tile_size tile-size in pixels, or 1 to use no tiles. + */ +ShadowAtlas::ShadowAtlas(size_t size, size_t tile_size) { + nassertv(size > 1 && tile_size >= 1); + nassertv(tile_size < size && size % tile_size == 0); + _size = size; + _tile_size = tile_size; + _num_used_tiles = 0; + init_tiles(); +} + +/** + * @brief Destructs the shadow atlas. + * @details This destructs the shadow atlas, freeing all used resources. + */ +ShadowAtlas::~ShadowAtlas() { + delete [] _flags; +} + +/** + * @brief Internal method to init the storage. + * @details This method setups the storage used for storing the tile flags. + */ +void ShadowAtlas::init_tiles() { + _num_tiles = _size / _tile_size; + _flags = new bool[_num_tiles * _num_tiles]; + memset(_flags, 0x0, sizeof(bool) * _num_tiles * _num_tiles); +} + +/** + * @brief Internal method to reserve a region in the atlas. + * @details This reserves a given region in the shadow atlas. The region should + * be in tile space.This is called by the ShadowAtlas::find_and_reserve_region. + * It sets all flags in that region to true, indicating that those are used. + * When an invalid region is passed, an assertion is triggered. If assertions + * are optimized out, undefined behaviour occurs. + * + * @param x x- start positition of the region + * @param y y- start position of the region + * @param w width of the region + * @param h height of the region + */ +void ShadowAtlas::reserve_region(size_t x, size_t y, size_t w, size_t h) { + // Check if we are out of bounds, this should be disabled for performance + // reasons at some point. + nassertv(x >= 0 && y >= 0 && x + w <= _num_tiles && y + h <= _num_tiles); + + _num_used_tiles += w * h; + + // Iterate over every tile in the region and mark it as used + for (size_t cx = 0; cx < w; ++cx) { + for (size_t cy = 0; cy < h; ++cy) { + set_tile(cx + x, cy + y, true); + } + } +} + +/** + * @brief Finds space for a map of the given size in the atlas. + * @details This methods searches for a space to store a region of the given + * size in the atlas. tile_width and tile_height should be already in tile + * space. They can be converted using ShadowAtlas::get_required_tiles. + * + * If no region is found, or an invalid size is passed, an integer vector with + * all components set to -1 is returned. + * + * If a region is found, an integer vector with the given layout is returned: + * x: x- Start of the region + * y: y- Start of the region + * z: width of the region + * w: height of the region + * + * The layout is in tile space, and can get converted to uv space using + * ShadowAtlas::region_to_uv. + * + * @param tile_width Width of the region in tile space + * @param tile_height Height of the region in tile space + * + * @return Region, see description, or -1 when no region is found. + */ +LVecBase4i ShadowAtlas::find_and_reserve_region(size_t tile_width, size_t tile_height) { + + // Check for empty region + if (tile_width < 1 || tile_height < 1) { + shadowatlas_cat.error() << "Called find_and_reserve_region with null-region!" << endl; + return LVecBase4i(-1); + } + + // Check for region bigger than the shadow atlas + if (tile_width > _num_tiles || tile_height > _num_tiles) { + shadowatlas_cat.error() << "Requested region exceeds shadow atlas size!" << endl; + return LVecBase4i(-1); + } + + // Iterate over every possible region and check if its still free + for (size_t x = 0; x <= _num_tiles - tile_width; ++x) { + for (size_t y = 0; y <= _num_tiles - tile_height; ++y) { + if (region_is_free(x, y, tile_width, tile_height)) { + // Found free region, now reserve it + reserve_region(x, y, tile_width, tile_height); + return LVecBase4i(x, y, tile_width, tile_height); + } + } + } + + // When we reached this part, we couldn't find a free region, so the atlas + // seems to be full. + shadowatlas_cat.error() << "Failed to find a free region of size " << tile_width + << " x " << tile_height << "!" << endl; + return LVecBase4i(-1); +} + +/** + * @brief Frees a given region + * @details This frees a given region, marking it as free so that other shadow + * maps can use the space again. The region should be the same as returned + * by ShadowAtlas::find_and_reserve_region. + * + * If an invalid region is passed, an assertion is triggered. If assertions + * are compiled out, undefined behaviour will occur. + * + * @param region Region to free + */ +void ShadowAtlas::free_region(const LVecBase4i& region) { + // Out of bounds check, can't hurt + nassertv(region.get_x() >= 0 && region.get_y() >= 0); + nassertv(region.get_x() + region.get_z() <= _num_tiles && region.get_y() + region.get_w() <= _num_tiles); + + _num_used_tiles -= region.get_z() * region.get_w(); + + for (size_t x = 0; x < region.get_z(); ++x) { + for (size_t y = 0; y < region.get_w(); ++y) { + // Could do an assert here, that the tile should have been used (=true) before + set_tile(region.get_x() + x, region.get_y() + y, false); + } + } +} diff --git a/rpcore/native/source/shadow_atlas.h b/rpcore/native/source/shadow_atlas.h new file mode 100644 index 0000000..822e983 --- /dev/null +++ b/rpcore/native/source/shadow_atlas.h @@ -0,0 +1,82 @@ +/** + * + * RenderPipeline + * + * Copyright (c) 2014-2016 tobspr + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + */ + +#ifndef RP_SHADOW_ATLAS_H +#define RP_SHADOW_ATLAS_H + +#include "pandabase.h" +#include "lvecBase4.h" + +NotifyCategoryDecl(shadowatlas, EXPORT_CLASS, EXPORT_TEMPL); + + +/** + * @brief Class which manages distributing shadow maps in an atlas. + * @details This class manages the shadow atlas. It handles finding and reserving + * space for new shadow maps. + */ +class ShadowAtlas { + +PUBLISHED: + ShadowAtlas(size_t size, size_t tile_size = 32); + ~ShadowAtlas(); + + inline int get_num_used_tiles() const; + inline float get_coverage() const; + + MAKE_PROPERTY(num_used_tiles, get_num_used_tiles); + MAKE_PROPERTY(coverage, get_coverage); + +public: + + LVecBase4i find_and_reserve_region(size_t tile_width, size_t tile_height); + void free_region(const LVecBase4i& region); + inline LVecBase4f region_to_uv(const LVecBase4i& region); + + inline int get_tile_size() const; + inline int get_required_tiles(size_t resolution) const; + +protected: + + void init_tiles(); + + inline void set_tile(size_t x, size_t y, bool flag); + inline bool get_tile(size_t x, size_t y) const; + + inline bool region_is_free(size_t x, size_t y, size_t w, size_t h) const; + void reserve_region(size_t x, size_t y, size_t w, size_t h); + + size_t _size; + size_t _num_tiles; + size_t _tile_size; + size_t _num_used_tiles; + bool* _flags; +}; + +#include "shadow_atlas.I" + + +#endif // RP_SHADOW_ATLAS_H diff --git a/rpcore/native/source/shadow_manager.I b/rpcore/native/source/shadow_manager.I new file mode 100644 index 0000000..b5039b3 --- /dev/null +++ b/rpcore/native/source/shadow_manager.I @@ -0,0 +1,192 @@ +/** + * + * RenderPipeline + * + * Copyright (c) 2014-2016 tobspr + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + */ + + +/** + * @brief Sets the maximum amount of updates per frame. + * @details This controls the maximum amount of updated ShadowSources per frame. + * The ShadowManager will take the first ShadowSources, and + * generate shadow maps for them every frame. If there are more ShadowSources + * waiting to get updated than available updates, the sources are sorted by + * priority, and the update of the less important sources is delayed to the + * next frame. + * + * If the update count is set too low, and there are a lot of ShadowSources + * waiting to get updated, artifacts will occur, and there might be ShadowSources + * which never get updated, due to low priority. + * + * If an update count of 0 is passed, no updates will happen. This also means + * that there are no shadows. This is not recommended. + * + * If an update count < 0 is passed, undefined behaviour occurs. + * + * This method has to get called before ShadowManager::init, otherwise an + * assertion will get triggered. + * + * @param max_updates Maximum amoumt of updates + */ +inline void ShadowManager::set_max_updates(size_t max_updates) { + nassertv(max_updates >= 0); + nassertv(_atlas == NULL); // ShadowManager was already initialized + if (max_updates == 0) { + shadowmanager_cat.warning() << "max_updates set to 0, no shadows will be updated." << endl; + } + _max_updates = max_updates; +} + +/** + * @brief Sets the shadow atlas size + * @details This sets the desired shadow atlas size. It should be big enough + * to store all important shadow sources, with some buffer, because the shadow + * maps usually won't be fitted perfectly, so gaps can occur. + * + * This has to get called before calling ShadowManager::init. When calling this + * method after initialization, an assertion will get triggered. + * + * @param atlas_size Size of the shadow atlas in pixels + */ +inline void ShadowManager::set_atlas_size(size_t atlas_size) { + nassertv(atlas_size >= 16 && atlas_size <= 16384); + nassertv(_atlas == NULL); // ShadowManager was already initialized + _atlas_size = atlas_size; +} + +/** + * @brief Returns the shadow atlas size. + * @details This returns the shadow atlas size previously set with + * ShadowManager::set_atlas_size. + * @return Shadow atlas size in pixels + */ +inline size_t ShadowManager::get_atlas_size() const { + return _atlas_size; +} + + +/** + * @brief Returns a handle to the shadow atlas. + * @details This returns a handle to the internal shadow atlas instance. This + * is only valid after calling ShadowManager::init. Calling this earlier will + * trigger an assertion and undefined behaviour. + * @return The internal ShadowAtlas instance + */ +inline ShadowAtlas* ShadowManager::get_atlas() const { + nassertr(_atlas != NULL, NULL); // Can't hurt to check + return _atlas; +} + +/** + * @brief Sets the target scene + * @details This sets the target scene for rendering shadows. All shadow cameras + * will be parented to this scene to render shadows. + * + * Usually the scene will be ShowBase.render. If the scene is an empty or + * invalid NodePath, an assertion will be triggered. + * + * This method has to get called before calling ShadowManager::init, or an + * assertion will get triggered. + * + * @param scene_parent The target scene + */ +inline void ShadowManager::set_scene(NodePath scene_parent) { + nassertv(!scene_parent.is_empty()); + nassertv(_atlas == NULL); // ShadowManager was already initialized + _scene_parent = scene_parent; +} + +/** + * @brief Sets the handle to the TagStageManager. + * @details This sets the handle to the TagStateManager used by the pipeline. + * Usually this is RenderPipeline.get_tag_mgr(). + * + * This has to get called before ShadowManager::init, otherwise an assertion + * will get triggered. + * + * @param tag_mgr [description] + */ +inline void ShadowManager::set_tag_state_manager(TagStateManager* tag_mgr) { + nassertv(tag_mgr != NULL); + nassertv(_atlas == NULL); // ShadowManager was already initialized + _tag_state_mgr = tag_mgr; +} + +/** + * @brief Sets the handle to the Shadow targets output + * @details This sets the handle to the GraphicsOutput of the shadow atlas. + * Usually this is RenderTarget.get_internal_buffer(), whereas the RenderTarget + * is the target of the ShadowStage. + * + * This is used for creating display regions and attaching cameras to them, + * for performing shadow updates. + * + * This has to get called before ShadowManager::init, otherwise an assertion + * will be triggered. + * + * @param graphics_output [description] + */ +inline void ShadowManager::set_atlas_graphics_output(GraphicsOutput* graphics_output) { + nassertv(graphics_output != NULL); + nassertv(_atlas == NULL); // ShadowManager was already initialized + _atlas_graphics_output = graphics_output; +} + + +/** + * @brief Adds a new shadow update + * @details This adds a new update to the update queue. When the queue is already + * full, this method returns false, otherwise it returns true. The next time + * the manager is updated, the shadow source will recieve an update of its + * shadow map. + * + * @param source The shadow source to update + * + * @return Whether the shadow source udpate was sucessfully queued. + */ +inline bool ShadowManager::add_update(const ShadowSource* source) { + nassertr(_atlas != NULL, false); // ShadowManager::init not called yet. + nassertr(source != NULL, false); // NULL-Pointer passed + + if (_queued_updates.size() >= _max_updates) { + if (shadowmanager_cat.is_debug()) { + shadowmanager_cat.debug() << "cannot update source, out of update slots" << endl; + } + return false; + } + + // Add the update to the queue + _queued_updates.push_back(source); + return true; +} + +/** + * @brief Returns how many update slots are left. + * @details This returns how many update slots are left. You can assume the + * next n calls to add_update will succeed, whereas n is the value returned + * by this function. + * @return Number of update slots left. + */ +inline size_t ShadowManager::get_num_update_slots_left() const { + return _max_updates - _queued_updates.size(); +} diff --git a/rpcore/native/source/shadow_manager.cpp b/rpcore/native/source/shadow_manager.cpp new file mode 100644 index 0000000..fb62271 --- /dev/null +++ b/rpcore/native/source/shadow_manager.cpp @@ -0,0 +1,157 @@ +/** + * + * RenderPipeline + * + * Copyright (c) 2014-2016 tobspr + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + */ + + +#include "shadow_manager.h" + +NotifyCategoryDef(shadowmanager, ""); + +/** + * @brief Constructs a new shadow atlas + * @details This constructs a new shadow atlas. There are a set of properties + * which should be set before calling ShadowManager::init, see the set-Methods. + * After all properties are set, ShadowManager::init should get called. + * ShadowManager::update should get called on a per frame basis. + */ +ShadowManager::ShadowManager() { + _max_updates = 10; + _atlas = NULL; + _atlas_size = 4096; + _tag_state_mgr = NULL; + _atlas_graphics_output = NULL; +} + +/** + * @brief Destructs the ShadowManager + * @details This destructs the shadow manager, clearing all resources used + */ +ShadowManager::~ShadowManager() { + delete _atlas; + + // Todo: Could eventually unregister all shadow cameras. Since the tag state + // manager does this on cleanup already, and we get destructed at the same + // time (if at all), this is not really necessary +} + + +/** + * @brief Initializes the ShadowManager. + * @details This initializes the ShadowManager. All properties should have + * been set before calling this, otherwise assertions will get triggered. + * + * This setups everything required for rendering shadows, including the + * shadow atlas and the various shadow cameras. After calling this method, + * no properties can be changed anymore. + */ +void ShadowManager::init() { + nassertv(!_scene_parent.is_empty()); // Scene parent not set, call set_scene_parent before init! + nassertv(_tag_state_mgr != NULL); // TagStateManager not set, call set_tag_state_mgr before init! + nassertv(_atlas_graphics_output != NULL); // AtlasGraphicsOutput not set, call set_atlas_graphics_output before init! + + _cameras.resize(_max_updates); + _display_regions.resize(_max_updates); + _camera_nps.reserve(_max_updates); + + // Create the cameras and regions + for(size_t i = 0; i < _max_updates; ++i) { + + // Create the camera + PT(Camera) camera = new Camera("ShadowCam-" + to_string((long long)i)); + camera->set_lens(new MatrixLens()); + camera->set_active(false); + camera->set_scene(_scene_parent); + _tag_state_mgr->register_camera("shadow", camera); + _camera_nps.push_back(_scene_parent.attach_new_node(camera)); + _cameras[i] = camera; + + // Create the display region + PT(DisplayRegion) region = _atlas_graphics_output->make_display_region(); + region->set_sort(1000); + region->set_clear_depth_active(true); + region->set_clear_depth(1.0); + region->set_clear_color_active(false); + region->set_camera(_camera_nps[i]); + region->set_active(false); + _display_regions[i] = region; + } + + // Create the atlas + _atlas = new ShadowAtlas(_atlas_size); + + // Reserve enough space for the updates + _queued_updates.reserve(_max_updates); +} + + +/** + * @brief Updates the ShadowManager + * @details This updates the ShadowManager, processing all shadow sources which + * need to get updated. + * + * This first collects all sources which require an update, sorts them by priority, + * and then processes the first ShadowSources. + * + * This may not get called before ShadowManager::init, or an assertion will be + * thrown. + */ +void ShadowManager::update() { + nassertv(_atlas != NULL); // ShadowManager::init not called yet + nassertv(_queued_updates.size() <= _max_updates); // Internal error, should not happen + + // Disable all cameras and regions which will not be used + for (size_t i = _queued_updates.size(); i < _max_updates; ++i) { + _cameras[i]->set_active(false); + _display_regions[i]->set_active(false); + } + + // Iterate over all queued updates + for (size_t i = 0; i < _queued_updates.size(); ++i) { + const ShadowSource* source = _queued_updates[i]; + + // Enable the camera and display region, so they perform a render + _cameras[i]->set_active(true); + _display_regions[i]->set_active(true); + + // Set the view projection matrix + DCAST(MatrixLens, _cameras[i]->get_lens())->set_user_mat(source->get_mvp()); + + // Optional: Show the camera frustum for debugging + // _cameras[i]->show_frustum(); + + // Set the correct dimensions on the display region + const LVecBase4f& uv = source->get_uv_region(); + _display_regions[i]->set_dimensions( + uv.get_x(), // left + uv.get_x() + uv.get_z(), // right + uv.get_y(), // bottom + uv.get_y() + uv.get_w() // top + ); + } + + // Clear the update list + _queued_updates.clear(); + _queued_updates.reserve(_max_updates); +} diff --git a/rpcore/native/source/shadow_manager.h b/rpcore/native/source/shadow_manager.h new file mode 100644 index 0000000..b6e7366 --- /dev/null +++ b/rpcore/native/source/shadow_manager.h @@ -0,0 +1,92 @@ +/** + * + * RenderPipeline + * + * Copyright (c) 2014-2016 tobspr + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + */ + +#ifndef RP_SHADOW_MANAGER_H +#define RP_SHADOW_MANAGER_H + +#include "pandabase.h" +#include "camera.h" +#include "luse.h" +#include "matrixLens.h" +#include "referenceCount.h" +#include "nodePath.h" +#include "displayRegion.h" +#include "graphicsOutput.h" + +#include "tag_state_manager.h" +#include "shadow_source.h" +#include "shadow_atlas.h" + +NotifyCategoryDecl(shadowmanager, EXPORT_CLASS, EXPORT_TEMPL); + + +class ShadowManager : public ReferenceCount { + + PUBLISHED: + ShadowManager(); + ~ShadowManager(); + + inline void set_max_updates(size_t max_updates); + inline void set_scene(NodePath scene_parent); + inline void set_tag_state_manager(TagStateManager* tag_mgr); + inline void set_atlas_graphics_output(GraphicsOutput* graphics_output); + + inline void set_atlas_size(size_t atlas_size); + inline size_t get_atlas_size() const; + MAKE_PROPERTY(atlas_size, get_atlas_size, set_atlas_size); + + inline size_t get_num_update_slots_left() const; + MAKE_PROPERTY(num_update_slots_left, get_num_update_slots_left); + + inline ShadowAtlas* get_atlas() const; + MAKE_PROPERTY(atlas, get_atlas); + + void init(); + void update(); + + public: + inline bool add_update(const ShadowSource* source); + + private: + size_t _max_updates; + size_t _atlas_size; + NodePath _scene_parent; + + pvector _cameras; + pvector _camera_nps; + pvector _display_regions; + + ShadowAtlas* _atlas; + TagStateManager* _tag_state_mgr; + GraphicsOutput* _atlas_graphics_output; + + typedef pvector UpdateQueue; + UpdateQueue _queued_updates; +}; + +#include "shadow_manager.I" + +#endif // RP_SHADOW_MANAGER_H diff --git a/rpcore/native/source/shadow_source.I b/rpcore/native/source/shadow_source.I new file mode 100644 index 0000000..2c898ff --- /dev/null +++ b/rpcore/native/source/shadow_source.I @@ -0,0 +1,261 @@ +/** + * + * RenderPipeline + * + * Copyright (c) 2014-2016 tobspr + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + */ + + + +/** + * @brief Returns whether the shadow source needs an update. + * @details This returns the update flag, which was previously set with + * ShadowSource::set_needs_update. If the value is true, it means that the + * ShadowSource is invalid and should be regenerated. This can either be the + * case because the scene changed and affected the shadow source, or the light + * moved. + * @return Update-Flag + */ +inline bool ShadowSource::get_needs_update() const { + return !has_region() || _needs_update; +} + +/** + * @brief Returns the slot of the shadow source. + * @details This returns the assigned slot of the ShadowSource, or -1 if no slot + * was assigned yet. You can check if a slot exists with ShadowSource::has_slot. + * The slot is the index of the ShadowSource in the global source buffer. + * @return Slot, or -1 to indicate no slot. + */ +inline int ShadowSource::get_slot() const { + return _slot; +} + +/** + * @brief Returns whether the source has a slot. + * @details This returns whether the ShadowSource currently has an assigned slot. + * If the source has a slot assigned, this returns true, otherwise false. Cases + * where the source has no slot might be when the source just got attached, but + * never got rendered yet. + * @return [description] + */ +inline bool ShadowSource::has_slot() const { + return _slot >= 0; +} + +/** + * @brief Assigns the source a slot + * @details This assigns a slot to the ShadowSource. This is called from the + * ShadowManager, when the source gets attached first time. This should not + * get called by the user. + * + * @param slot Slot of the source, or -1 to indicate no slot. + */ +inline void ShadowSource::set_slot(int slot) { + _slot = slot; +} + +/** + * @brief Setups a perspective lens for the source. + * @details This makes the shadow source behave like a perspective lens. The + * parameters are similar to the ones of a PerspectiveLens. + * + * @param fov FoV of the lens + * @param near_plane The near plane of the lens, to avoid artifacts at low distance + * @param far_plane The far plane of the lens + * @param pos Position of the lens, in world space + * @param direction Direction (Orientation) of the lens + */ +inline void ShadowSource::set_perspective_lens(float fov, float near_plane, + float far_plane, LVecBase3f pos, + LVecBase3f direction) { + // Construct the transformation matrix + LMatrix4f transform_mat = LMatrix4f::translate_mat(-pos); + + // Construct a temporary lens to generate the lens matrix + PerspectiveLens temp_lens = PerspectiveLens(fov, fov); + temp_lens.set_film_offset(0, 0); + temp_lens.set_near_far(near_plane, far_plane); + temp_lens.set_view_vector(direction, LVector3::up()); + set_matrix_lens(transform_mat * temp_lens.get_projection_mat()); + + // Set new bounds, approximate with sphere + CPT(BoundingHexahedron) hexahedron = DCAST(BoundingHexahedron, temp_lens.make_bounds()); + LPoint3 center = (hexahedron->get_min() + hexahedron->get_max()) * 0.5f; + _bounds = BoundingSphere(pos + center, (hexahedron->get_max() - center).length()); +} + +/** + * @brief Sets a custom matrix for the source. + * @details This tells the source to use a custom matrix for rendering, just like + * the matrix lens. The matrix should include all transformations, rotations and + * scales. No other matrices will be used for rendering this shadow source (not + * even a coordinate system conversion). + * + * @param mvp Custom View-Projection matrix + */ +inline void ShadowSource::set_matrix_lens(const LMatrix4f& mvp) { + _mvp = mvp; + set_needs_update(true); +} + +/** + * @brief Sets the update flag of the source. + * @details Sets whether the source is still valid, or needs to get regenerated. + * Usually you only want to flag the shadow source as invalid, by passing + * true as the flag. However, the ShadowManager will set the flag to false + * after updating the source. + * + * @param flag The update flag + */ +inline void ShadowSource::set_needs_update(bool flag) { + _needs_update = flag; +} + +/** + * @brief Returns whether the source has a valid region. + * @details This returns whether the ShadowSource has a valid shadow atlas region + * assigned. This might be not the case when the source never was rendered yet, + * or is about to get updated. + * @return true if the source has a valid region, else false. + */ +inline bool ShadowSource::has_region() const { + return _region.get_x() >= 0 && _region.get_y() >= 0 && _region.get_z() >= 0 && _region.get_w() >= 0; +} + +/** + * @brief Returns the resolution of the source. + * @details Returns the shadow map resolution of source, in pixels. This is the + * space the source takes in the shadow atlas, in pixels. + * @return Resolution in pixels + */ +inline size_t ShadowSource::get_resolution() const { + return _resolution; +} + +/** + * @brief Returns the assigned region of the source in atlas space. + * @details This returns the region of the source, in atlas space. This is the + * region set by ShadowSource::set_region. If no region was set yet, returns + * a 4-component integer vector with all components set to -1. To check this, + * you should call ShadowSource::has_region() first. + * + * @return [description] + */ +inline const LVecBase4i& ShadowSource::get_region() const { + return _region; +} + +/** + * @brief Returns the assigned region of the source in UV space. + * @details This returns the region of the source, in UV space. This is the + * region set by ShadowSource::set_region. If no region was set yet, returns + * a 4-component integer vector with all components set to -1. To check this, + * you should call ShadowSource::has_region() first. + * + * @return [description] + */ +inline const LVecBase4f& ShadowSource::get_uv_region() const { + return _region_uv; +} + +/** + * @brief Sets the assigned region of the source in atlas and uv space. + * @details This sets the assigned region of the ShadowSource. The region in + * atlas space should be the region returned from the + * ShadowAtlas::find_and_reserve_region. The uv-region should be the same region, + * but in the 0 .. 1 range (can be converted with ShadowAtlas::region_to_uv). + * This is required for the shaders, because they expect coordinates in the + * 0 .. 1 range for sampling. + * + * @param region Atlas-Space region + * @param region_uv UV-Space region + */ +inline void ShadowSource::set_region(const LVecBase4i& region, const LVecBase4f& region_uv) { + _region = region; + _region_uv = region_uv; +} + +/** + * @brief Returns the View-Projection matrix of the source. + * @details This returns the current view-projection matrix of the ShadowSource. + * If no matrix was set yet, returns a matrix with all components zero. + * If a matrix was set with ShadowSource::set_matrix_lens, returns the matrix + * set by that function call. + * + * If a matrix was set with ShadowSource::set_perspective_lens, returns a + * perspective view-projection matrix setup by those parameters. + * + * The matrix returned is the matrix used for rendering the shadow map, and + * includes the camera transform as well as the projection matrix. + * + * @return View-Projection matrix. + */ +inline const LMatrix4f& ShadowSource::get_mvp() const { + return _mvp; +} + +/** + * @brief Writes the source to a GPUCommand. + * @details This writes the ShadowSource to a GPUCommand. This stores the + * mvp and the uv-region in the command. + * + * @param cmd GPUCommand to write to. + */ +inline void ShadowSource::write_to_command(GPUCommand &cmd) const { + // When storing on the gpu, we should already have a valid slot + nassertv(_slot >= 0); + cmd.push_mat4(_mvp); + cmd.push_vec4(_region_uv); +} + +/** + * @brief Sets the resolution of the source. + * @details This sets the resolution of the ShadowSource, in pixels. It should be + * a multiple of the tile size of the ShadowAtlas, and greater than zero. + * + * @param resolution [description] + */ +inline void ShadowSource::set_resolution(size_t resolution) { + nassertv(resolution > 0); + _resolution = resolution; + set_needs_update(true); +} + +/** + * @brief Returns the shadow sources bounds + * @details This returns the bounds of the shadow source, approximated as a sphere + * @return Bounds as a BoundingSphere + */ +inline const BoundingSphere& ShadowSource::get_bounds() const { + return _bounds; +} + +/** + * @brief Clears the assigned region of the source + * @details This unassigns any shadow atlas region from the source, previously + * set with set_region + */ +inline void ShadowSource::clear_region() { + _region.fill(-1); + _region_uv.fill(0); +} diff --git a/rpcore/native/source/shadow_source.cpp b/rpcore/native/source/shadow_source.cpp new file mode 100644 index 0000000..335d928 --- /dev/null +++ b/rpcore/native/source/shadow_source.cpp @@ -0,0 +1,41 @@ +/** + * + * RenderPipeline + * + * Copyright (c) 2014-2016 tobspr + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + */ + +#include "shadow_source.h" + +/** + * @brief Constructs a new shadow source + * @details This constructs a new shadow source, with no projection setup, + * and no slot assigned. + */ +ShadowSource::ShadowSource() { + _slot = -1; + _needs_update = true; + _resolution = 512; + _mvp.fill(0.0); + _region.fill(-1); + _region_uv.fill(0); +} diff --git a/rpcore/native/source/shadow_source.h b/rpcore/native/source/shadow_source.h new file mode 100644 index 0000000..4b9c4cf --- /dev/null +++ b/rpcore/native/source/shadow_source.h @@ -0,0 +1,93 @@ +/** + * + * RenderPipeline + * + * Copyright (c) 2014-2016 tobspr + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + */ + + +#ifndef RP_SHADOW_SOURCE_H +#define RP_SHADOW_SOURCE_H + +#include "pandabase.h" +#include "luse.h" +#include "transformState.h" +#include "look_at.h" +#include "compose_matrix.h" +#include "perspectiveLens.h" +#include "boundingVolume.h" +#include "boundingSphere.h" +#include "boundingHexahedron.h" +#include "geometricBoundingVolume.h" + +#include "gpu_command.h" + +/** + * @brief This class represents a single shadow source. + * @details The ShadowSource can be seen as a Camera. It is used by the Lights + * to render their shadows. Each ShadowSource has a position in the atlas, + * and a view-projection matrix. The shadow manager regenerates the shadow maps + * using the data from the shadow sources. + */ +class ShadowSource { + +public: + ShadowSource(); + + inline void write_to_command(GPUCommand &cmd) const; + + inline void set_needs_update(bool flag); + inline void set_slot(int slot); + inline void set_region(const LVecBase4i& region, const LVecBase4f& region_uv); + inline void set_resolution(size_t resolution); + inline void set_perspective_lens(float fov, float near_plane, + float far_plane, LVecBase3f pos, LVecBase3f direction); + inline void set_matrix_lens(const LMatrix4f& mvp); + + inline bool has_region() const; + inline bool has_slot() const; + + inline void clear_region(); + + inline int get_slot() const; + inline bool get_needs_update() const; + inline size_t get_resolution() const; + inline const LMatrix4f& get_mvp() const; + inline const LVecBase4i& get_region() const; + inline const LVecBase4f& get_uv_region() const; + + inline const BoundingSphere& get_bounds() const; + +private: + int _slot; + bool _needs_update; + size_t _resolution; + LMatrix4f _mvp; + LVecBase4i _region; + LVecBase4f _region_uv; + + BoundingSphere _bounds; +}; + +#include "shadow_source.I" + +#endif // RP_SHADOW_SOURCE_H diff --git a/rpcore/native/source/tag_state_manager.I b/rpcore/native/source/tag_state_manager.I new file mode 100644 index 0000000..d448b6d --- /dev/null +++ b/rpcore/native/source/tag_state_manager.I @@ -0,0 +1,88 @@ +/** + * + * RenderPipeline + * + * Copyright (c) 2014-2016 tobspr + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + */ + +/** + * @brief Registers a new camera which renders a certain pass + * @details This registers a new camera which will be used to render the given + * pass. The TagStateManager will keep track of the camera and + * applies all registered states onto the camera with Camera::set_tag_state. + * It also applies the appropriate camera mask to the camera, + * and sets an initial state to disable color write depending on the pass. + * + * @param source Camera which will be used to render shadows + */ +inline void TagStateManager::register_camera(const string& name, Camera* source) { + ContainerList::iterator entry = _containers.find(name); + nassertv(entry != _containers.end()); + register_camera(entry->second, source); +} + +/** + * @brief Unregisters a camera from the list of shadow cameras + * @details This unregisters a camera from the list of shadows cameras. It also + * resets all tag states of the camera, and also its initial state. + * + * @param source Camera to unregister + */ +inline void TagStateManager::unregister_camera(const string& name, Camera* source) { + ContainerList::iterator entry = _containers.find(name); + nassertv(entry != _containers.end()); + unregister_camera(entry->second, source); +} + +/** + * @brief Applies a given state for a pass to a NodePath + * @details This applies a shader to the given NodePath which is used when the + * NodePath is rendered by any registered camera for that pass. + * It also disables color write depending on the pass. + * + * @param np The nodepath to apply the shader to + * @param shader A handle to the shader to apply + * @param name Name of the state, should be a unique identifier + * @param sort Determines the sort with which the shader will be applied. + */ +inline void TagStateManager::apply_state(const string& state, NodePath np, Shader* shader, + const string &name, int sort) { + ContainerList::iterator entry = _containers.find(state); + nassertv(entry != _containers.end()); + apply_state(entry->second, np, shader, name, sort); +} + +/** + * @brief Returns the render mask for the given state + * @details This returns the mask of a given render pass, which can be used + * to either show or hide objects from this pass. + * + * @param container_name Name of the render-pass + * @return Bit mask of the render pass + */ +inline BitMask32 TagStateManager::get_mask(const string &container_name) { + if (container_name == "gbuffer") + return BitMask32::bit(1); + ContainerList::iterator entry = _containers.find(container_name); + nassertr(entry != _containers.end(), BitMask32()); + return entry->second.mask; +} diff --git a/rpcore/native/source/tag_state_manager.cpp b/rpcore/native/source/tag_state_manager.cpp new file mode 100644 index 0000000..296a632 --- /dev/null +++ b/rpcore/native/source/tag_state_manager.cpp @@ -0,0 +1,195 @@ +/** + * + * RenderPipeline + * + * Copyright (c) 2014-2016 tobspr + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + */ + + +#include "tag_state_manager.h" + + +NotifyCategoryDef(tagstatemgr, ""); + +/** + * @brief Constructs a new TagStateManager + * @details This constructs a new TagStateManager. The #main_cam_node should + * refer to the main scene camera, and will most likely be base.cam. + * It is necessary to pass the camera because the C++ code does not have + * access to the showbase. + * + * @param main_cam_node The main scene camera + */ +TagStateManager::TagStateManager(NodePath main_cam_node) { + nassertv(!main_cam_node.is_empty()); + nassertv(DCAST(Camera, main_cam_node.node()) != NULL); + _main_cam_node = main_cam_node; + + // Set default camera mask + DCAST(Camera, _main_cam_node.node())->set_camera_mask(BitMask32::bit(1)); + + // Init containers + _containers["shadow"] = StateContainer("Shadows", 2, false); + _containers["voxelize"] = StateContainer("Voxelize", 3, false); + _containers["envmap"] = StateContainer("Envmap", 4, true); + _containers["forward"] = StateContainer("Forward", 5, true); +} + +/** + * @brief Destructs the TagStateManager + * @details This destructs the TagStateManager, and cleans up all resources used. + */ +TagStateManager::~TagStateManager() { + cleanup_states(); +} + +/** + * @brief Applies a given state to a NodePath + * @details This applies a shader to the given NodePath which is used when the + * NodePath is rendered by any registered camera of the container. + * + * @param container The container which is used to store the state + * @param np The nodepath to apply the shader to + * @param shader A handle to the shader to apply + * @param name Name of the state, should be a unique identifier + * @param sort Changes the sort with which the shader will be applied. + */ +void TagStateManager::apply_state(StateContainer& container, NodePath np, Shader* shader, + const string &name, int sort) { + if (tagstatemgr_cat.is_spam()) { + tagstatemgr_cat.spam() << "Constructing new state " << name + << " with shader " << shader << endl; + } + + // Construct the render state + CPT(RenderState) state = RenderState::make_empty(); + + // Disable color write for all stages except the environment container + if (!container.write_color) { + state = state->set_attrib(ColorWriteAttrib::make(ColorWriteAttrib::C_off), 10000); + } + state = state->set_attrib(ShaderAttrib::make(shader, sort), sort); + + // Emit a warning if we override an existing state + if (container.tag_states.count(name) != 0) { + tagstatemgr_cat.warning() << "Overriding existing state " << name << endl; + } + + // Store the state, this is required whenever we attach a new camera, so + // it can also track the existing states + container.tag_states[name] = state; + + // Save the tag on the node path + np.set_tag(container.tag_name, name); + + // Apply the state on all cameras which are attached so far + for (size_t i = 0; i < container.cameras.size(); ++i) { + container.cameras[i]->set_tag_state(name, state); + } +} + +/** + * @brief Cleans up all registered states. + * @details This cleans up all states which were registered to the TagStateManager. + * It also calls Camera::clear_tag_states() on the main_cam_node and all attached + * cameras. + */ +void TagStateManager::cleanup_states() { + if (tagstatemgr_cat.is_info()) { + tagstatemgr_cat.info() << "cleaning up states" << endl; + } + + // Clear all tag states of the main camera + DCAST(Camera, _main_cam_node.node())->clear_tag_states(); + + // Clear the containers + // XXX: Just iterate over the _container map + cleanup_container_states(_containers["shadow"]); + cleanup_container_states(_containers["voxelize"]); + cleanup_container_states(_containers["envmap"]); + cleanup_container_states(_containers["forward"]); +} + +/** + * @brief Cleans up the states of a given container + * @details This cleans all tag states of the given container, + * and also calls Camera::clear_tag_states on every assigned camera. + * + * @param container Container to clear + */ +void TagStateManager::cleanup_container_states(StateContainer& container) { + for (size_t i = 0; i < container.cameras.size(); ++i) { + container.cameras[i]->clear_tag_states(); + } + container.tag_states.clear(); +} + +/** + * @brief Registers a new camera to a given container + * @details This registers a new camera to a container, and sets its initial + * state as well as the camera mask. + * + * @param container The container to add the camera to + * @param source The camera to add + */ +void TagStateManager::register_camera(StateContainer& container, Camera* source) { + source->set_tag_state_key(container.tag_name); + source->set_camera_mask(container.mask); + + // Construct an initial state which also disables color write, additionally + // to the ColorWriteAttrib on each unique state. + CPT(RenderState) state = RenderState::make_empty(); + + if (!container.write_color) { + state = state->set_attrib(ColorWriteAttrib::make(ColorWriteAttrib::C_off), 10000); + } + source->set_initial_state(state); + + // Store the camera so we can keep track of it + container.cameras.push_back(source); +} + +/** + * @brief Unregisters a camera from a container + * @details This unregisters a camera from the list of cameras of a given + * container. It also resets all tag states of the camera, and also its initial + * state. + * + * @param source Camera to unregister + */ +void TagStateManager::unregister_camera(StateContainer& container, Camera* source) { + CameraList& cameras = container.cameras; + + // Make sure the camera was attached so far + if (std::find(cameras.begin(), cameras.end(), source) == cameras.end()) { + tagstatemgr_cat.error() + << "Called unregister_camera but camera was never registered!" << endl; + return; + } + + // Remove the camera from the list of attached cameras + cameras.erase(std::remove(cameras.begin(), cameras.end(), source), cameras.end()); + + // Reset the camera + source->clear_tag_states(); + source->set_initial_state(RenderState::make_empty()); +} diff --git a/rpcore/native/source/tag_state_manager.h b/rpcore/native/source/tag_state_manager.h new file mode 100644 index 0000000..4b9f75d --- /dev/null +++ b/rpcore/native/source/tag_state_manager.h @@ -0,0 +1,95 @@ +/** + * + * RenderPipeline + * + * Copyright (c) 2014-2016 tobspr + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + */ + +#ifndef TAG_STATE_MANAGER_H +#define TAG_STATE_MANAGER_H + +#include "pandabase.h" +#include "bitMask.h" +#include "camera.h" +#include "nodePath.h" +#include "shader.h" +#include "renderState.h" +#include "shaderAttrib.h" +#include "colorWriteAttrib.h" + +NotifyCategoryDecl(tagstatemgr, EXPORT_CLASS, EXPORT_TEMPL); + +/** + * @brief This class handles all different tag states + * @details The TagStateManager stores a list of RenderStates assigned to different + * steps in the pipeline. For example, there are a list of shadow states, which + * are applied whenever objects are rendered from a shadow camera. + * + * The Manager also stores a list of all cameras used in the different stages, + * to keep track of the states used and to be able to attach new states. + */ +class TagStateManager { + + PUBLISHED: + TagStateManager(NodePath main_cam_node); + ~TagStateManager(); + + inline void apply_state(const string& state, NodePath np, Shader* shader, const string &name, int sort); + void cleanup_states(); + + inline void register_camera(const string& state, Camera* source); + inline void unregister_camera(const string& state, Camera* source); + inline BitMask32 get_mask(const string &container_name); + + private: + + typedef vector CameraList; + typedef pmap TagStateList; + + struct StateContainer { + CameraList cameras; + TagStateList tag_states; + string tag_name; + BitMask32 mask; + bool write_color; + + StateContainer() {}; + StateContainer(const string &tag_name, size_t mask, bool write_color) + : tag_name(tag_name), mask(BitMask32::bit(mask)), write_color(write_color) {}; + }; + + void apply_state(StateContainer& container, NodePath np, Shader* shader, + const string& name, int sort); + void cleanup_container_states(StateContainer& container); + void register_camera(StateContainer &container, Camera* source); + void unregister_camera(StateContainer &container, Camera* source); + + typedef pmap ContainerList; + ContainerList _containers; + + NodePath _main_cam_node; +}; + + +#include "tag_state_manager.I" + +#endif // TAG_STATE_MANAGER_H diff --git a/rpcore/native/update_module_builder.py b/rpcore/native/update_module_builder.py new file mode 100644 index 0000000..a4b0ee9 --- /dev/null +++ b/rpcore/native/update_module_builder.py @@ -0,0 +1,57 @@ +""" + +RenderPipeline + +Copyright (c) 2014-2016 tobspr + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. + +""" + +# This script downloads and updates the module builder. + +# pylint: skip-file + +if __name__ == "__main__": + import os + import sys + from os.path import dirname, realpath, isfile + + # Files which are skipped from the downloaded zip + files_to_ignore = "__init__.py LICENSE README.md config.ini config_module".split() + + current_dir = dirname(realpath(__file__)) + os.chdir(current_dir) + + # Import thirdparty packages + sys.path.insert(0, "../../rpcore/util") + sys.path.insert(0, "../../") + + # Download the module + from submodule_downloader import download_submodule + download_submodule("tobspr", "P3DModuleBuilder", current_dir, files_to_ignore) + + # Make an init script so we can import the code + with open("scripts/__init__.py", "w") as handle: + handle.write("") + + # Update the gitignore using the suggested version from the module builder + if isfile(".gitignore"): + os.remove(".gitignore") + os.rename("prefab.gitignore", ".gitignore") diff --git a/rpcore/pluginbase/__init__.py b/rpcore/pluginbase/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/rpcore/pluginbase/base_plugin.py b/rpcore/pluginbase/base_plugin.py new file mode 100644 index 0000000..3489a67 --- /dev/null +++ b/rpcore/pluginbase/base_plugin.py @@ -0,0 +1,101 @@ +""" + +RenderPipeline + +Copyright (c) 2014-2016 tobspr + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. + +""" + +from direct.stdpy.file import join + +from rpcore.rpobject import RPObject + + +class BasePlugin(RPObject): + + """ This is the base class for all plugins. All plugin classes derive from + this class. Additionally there are a lot of helpful functions provided, + such as creating render stages. """ + + # Plugins can set this to indicate they have some C++ code, so they cannot + # be used with the python version. + native_only = False + + # Plugins can set this to require other plugins + required_plugins = tuple() + + def __init__(self, pipeline): + """ Inits the plugin """ + self._pipeline = pipeline + self._assigned_stages = [] + self.plugin_id = str(self.__class__.__module__).split(".")[-2] + RPObject.__init__(self, "plugin:" + self.plugin_id) + self._set_debug_color("magenta", "bright") + + @property + def base_path(self): + """ Returns the path to the root directory of the plugin """ + return "/$$rp/rpplugins/{}/".format(self.plugin_id) + + def get_resource(self, pth): + """ Converts a local path from the plugins resource directory into + an absolute path """ + return join(self.base_path, "resources", pth) + + def get_shader_resource(self, pth): + """ Converts a local path from the plugins shader directory into + an absolute path """ + return join(self.base_path, "shader", pth) + + def create_stage(self, stage_type): + """ Shortcut to create a new render stage from a given class type. It + also registers the stage to the stage manager, and links the stage + to the current plugin instance. """ + stage_handle = stage_type(self._pipeline) + self._pipeline.stage_mgr.add_stage(stage_handle) + self._assigned_stages.append(stage_handle) + return stage_handle + + def get_setting(self, setting_id, plugin_id=None): + """ Returns the value of a setting given by its setting id. If plugin_id + is set, returns the setting of the given plugin """ + return self._pipeline.plugin_mgr.settings[plugin_id or self.plugin_id][setting_id].value + + def get_daytime_setting(self, setting_id, plugin_id=None): + """ Returns the value of a time of day setting given by its setting + id. If plugin_id is set, returns the setting of a gien plugin """ + handle = self._pipeline.plugin_mgr.day_settings[plugin_id or self.plugin_id][setting_id] + return handle.get_scaled_value_at(self._pipeline.daytime_mgr.time) + + def get_plugin_instance(self, plugin_id): + """ Returns the instance of a different plugin, given by its id. + This should be only used to access plugins which are also in the + current plugins requirements """ + return self._pipeline.plugin_mgr.instances[plugin_id] + + def is_plugin_enabled(self, plugin_id): + """ Returns whether a plugin is enabled and loaded, given is plugin id """ + return self._pipeline.plugin_mgr.is_plugin_enabled(plugin_id) + + def reload_shaders(self): + """ Reloads all shaders of the plugin """ + for stage in self._assigned_stages: + stage.reload_shaders() diff --git a/rpcore/pluginbase/day_manager.py b/rpcore/pluginbase/day_manager.py new file mode 100644 index 0000000..681965e --- /dev/null +++ b/rpcore/pluginbase/day_manager.py @@ -0,0 +1,99 @@ +""" + +RenderPipeline + +Copyright (c) 2014-2016 tobspr + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. + +""" + +from __future__ import division + +from rplibs.six import iteritems +from direct.stdpy.file import open + +from rpcore.rpobject import RPObject +from rpcore.util.shader_input_blocks import GroupedInputBlock +from rpcore.pluginbase.day_setting_types import ColorType + + +class DayTimeManager(RPObject): + + """ This manager handles all time of day settings, provides them as + a input to all shaders, and stores which time it currently is """ + + def __init__(self, pipeline): + RPObject.__init__(self) + self._pipeline = pipeline + self._input_ubo = GroupedInputBlock("TimeOfDay") + self._time = 0.5 + self._setting_handles = {} + + @property + def time(self): + """ Returns the current time of day as floating point number + from 0 to 1, whereas 0 means 00:00 and 1 means 24:00 (=00:00) """ + return self._time + + @time.setter + def time(self, day_time): + """ Sets the current time of day as floating point number from + 0 to 1, whereas 0 means 00:00 and 1 means 24:00 (=00:00). Any + number greater than 1 will be reduced to fit the 0 .. 1 range by + doing time modulo 1. + + Alternatively a string in the format 'hh:mm' can be passed. """ + if isinstance(day_time, float): + self._time = day_time % 1.0 + elif isinstance(day_time, str): + parts = [int(i) for i in day_time.split(":")] + self._time = (parts[0] * 60 + parts[1]) / (24 * 60) + + @property + def formatted_time(self): + """ Returns the current time as formatted string, e.g. 12:34 """ + total_minutes = int(self._time * 24 * 60) + return "{:02d}:{:02d}".format(total_minutes // 60, total_minutes % 60) + + def load_settings(self): + """ Loads all day time settings from the plugin manager and registers + them to the used input buffer """ + for plugin_id, settings in iteritems(self._pipeline.plugin_mgr.day_settings): + for setting, handle in iteritems(settings): + setting_id = "{}.{}".format(plugin_id, setting) + self._input_ubo.register_pta(setting_id, handle.glsl_type) + self._setting_handles[setting_id] = handle + self._pipeline.stage_mgr.input_blocks.append(self._input_ubo) + + # Generate UBO shader code + shader_code = self._input_ubo.generate_shader_code() + with open("/$$rptemp/$$daytime_config.inc.glsl", "w") as handle: + handle.write(shader_code) + + def update(self): + """ Internal update method which updates all day time settings """ + for setting_id, handle in iteritems(self._setting_handles): + # XXX: Find a better interface for this. Without this fix, colors + # are in the range 0 .. 255 in the shader. + if isinstance(handle, ColorType): + value = handle.get_value_at(self._time) + else: + value = handle.get_scaled_value_at(self._time) + self._input_ubo.update_input(setting_id, value) diff --git a/rpcore/pluginbase/day_setting_types.py b/rpcore/pluginbase/day_setting_types.py new file mode 100644 index 0000000..2141f54 --- /dev/null +++ b/rpcore/pluginbase/day_setting_types.py @@ -0,0 +1,159 @@ +""" + +RenderPipeline + +Copyright (c) 2014-2016 tobspr + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. + +""" + +from __future__ import division, print_function +from math import exp, log + +from panda3d.core import PTAFloat, PTALVecBase3f + +from rpcore.rpobject import RPObject +from rpcore.util.smooth_connected_curve import SmoothConnectedCurve +from rpcore.pluginbase.setting_types import make_setting_from_factory + +__all__ = ["make_daysetting_from_data"] + + +def make_daysetting_from_data(data): + """ Constructs a new setting from a given dataset. This method will automatically + instantiate a new class matching the type of the given dataset. It will fill + all values provided by the dataset and then return the created instance """ + factory = { + "color": ColorType, + "scalar": ScalarType + } + return make_setting_from_factory(data, factory) + + +class BaseType(RPObject): + """ Base setting type for all setting types """ + + def __init__(self, data): + self.type = data.pop("type") + self.label = data.pop("label").strip() + self.description = data.pop("description").strip() + self.curves = [] + + RPObject.__init__(self, "dsetting:{}".format(self.label)) + + def get_value_at(self, offset): + """ Returns the unscaled value at the given day time offset """ + if len(self.curves) == 1: + return self.curves[0].get_value(offset) + return tuple(curve.get_value(offset) for curve in self.curves) + + def get_scaled_value_at(self, offset): + """ Returns the scaled value at a given day time offset """ + return self.get_scaled_value(self.get_value_at(offset)) + + def get_scaled_value(self, value): + """ Returns the scaled value from a given normalized value """ + raise NotImplementedError() + + def set_control_points(self, control_points): + """ Sets the control points on the curves. """ + for curve_index, points in enumerate(control_points): + self.curves[curve_index].control_points = points + + def serialize(self): + """ Serializes the setting to a yaml string """ + values = ','.join(i.serialize() for i in self.curves) + return "[{}]".format(values) + + +class ScalarType(BaseType): + """ Setting type storing a single scalar """ + + glsl_type = "float" + pta_type = PTAFloat + + def __init__(self, data): + BaseType.__init__(self, data) + self.unit = data.pop("unit", "none") + self.minvalue, self.maxvalue = data.pop("range") + self.logarithmic_factor = data.pop("logarithmic_factor", 1.0) + if self.unit not in ("degree", "meter", "percent", "klux", "none"): + raise Exception("Invalid unit type: {}".format(self.unit)) + + self.default = self.get_linear_value(data.pop("default")) + + self.curves.append(SmoothConnectedCurve()) + self.curves[0].set_single_value(self.default) + + def format(self, value): + """ Formats a given value, attaching the appropriate metric unit """ + metric = { + "degree": u'\N{DEGREE SIGN}', + "percent": u'%', + "meter": u'm', + "klux": u' L', + "none": '' + }[self.unit] + if self.unit == "percent": + value *= 100.0 + return u"{:3.1f}{}".format(value, metric) + + def get_scaled_value(self, value): + """ Scales a linear value """ + if self.logarithmic_factor != 1.0: + exp_mult = exp(self.logarithmic_factor * value * 4.0) - 1 + exp_div = exp(self.logarithmic_factor * 4.0) - 1 + return exp_mult / exp_div * (self.maxvalue - self.minvalue) + self.minvalue + else: + return value * (self.maxvalue - self.minvalue) + self.minvalue + + def get_linear_value(self, scaled_value): + """ Linearizes a scaled value """ + result = (scaled_value - self.minvalue) / (self.maxvalue - self.minvalue) + if self.logarithmic_factor != 1.0: + result *= exp(self.logarithmic_factor * 4.0) - 1 + result = log(result + 1.0) / (4.0 * self.logarithmic_factor) + return result + + +class ColorType(BaseType): + """ Setting type storing a RGB color triple """ + + glsl_type = "vec3" + pta_type = PTALVecBase3f + + def __init__(self, data): + BaseType.__init__(self, data) + self.default = self.get_linear_value(data.pop("default")) + colors = ((255, 0, 0), (0, 255, 0), (0, 0, 255)) + for i in range(3): + curve = SmoothConnectedCurve() + curve.set_single_value(self.default[i]) + curve.color = colors[i] + self.curves.append(curve) + + def format(self, value): + return "{:3d}, {:3d}, {:3d}".format(*(int(i) for i in value)) + + def get_scaled_value(self, value): + return tuple(i * 255.0 for i in value) + + def get_linear_value(self, scaled_value): + return tuple(i / 255.0 for i in scaled_value) diff --git a/rpcore/pluginbase/manager.py b/rpcore/pluginbase/manager.py new file mode 100644 index 0000000..2e6957b --- /dev/null +++ b/rpcore/pluginbase/manager.py @@ -0,0 +1,282 @@ +""" + +RenderPipeline + +Copyright (c) 2014-2016 tobspr + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. + +""" + +import importlib +import collections + +from rplibs.six import iteritems, itervalues +from rplibs.yaml import load_yaml_file + +from direct.stdpy.file import listdir, isdir, join, open + +from rpcore.rpobject import RPObject +from rpcore.native import NATIVE_CXX_LOADED +from rpcore.pluginbase.setting_types import make_setting_from_data +from rpcore.pluginbase.day_setting_types import make_daysetting_from_data + + +class PluginManager(RPObject): + + """ This class manages all plugins. It provides functionality to load plugin + settings, trigger callbacks on plugins, initialize the plugin instances + and much more. """ + + def __init__(self, pipeline): + """ Constructs a new manager with no plugins loaded. To load settings + and plugins, call load(). """ + RPObject.__init__(self) + self._pipeline = pipeline + self.settings = {} + self.day_settings = {} + self.instances = {} + self.enabled_plugins = set() + + # Used by the plugin configurator and to only load the required data + self.requires_daytime_settings = True + + def load(self): + """ Loads all plugins and their settings, and also constructs instances + of the main plugin classes for all enabled plugins """ + self.debug("Loading plugin settings") + self.load_base_settings("/$$rp/rpplugins") + self.load_setting_overrides("/$$rpconfig/plugins.yaml") + + if self.requires_daytime_settings: + self.load_daytime_overrides("/$$rpconfig/daytime.yaml") + + self.debug("Creating plugin instances ..") + for plugin_id in self.settings: + handle = self._load_plugin(plugin_id) + if handle: + self.instances[plugin_id] = handle + else: + self.disable_plugin(plugin_id) + + def disable_plugin(self, plugin_id): + """ Disables a plugin, given its plugin_id. This will remove it from + the list of enabled plugins, if it ever was there """ + self.warn("Disabling", plugin_id) + if plugin_id in self.enabled_plugins: + self.enabled_plugins.remove(plugin_id) + for instance in list(self.instances.values()): + if plugin_id in instance.required_plugins: + self.disable_plugin(instance.plugin_id) + # if plugin_id in self.instances: + # del self.instances[plugin_id] + + def unload(self): + """ Unloads all plugins """ + self.debug("Unloading all plugins") + self.instances = {} + self.settings = {} + self.day_settings = {} + self.enabled_plugins = set() + + def update(self): + """ Main update method """ + pass + + def load_base_settings(self, plugin_dir): + """ Loads the base settings of all plugins, even of disabled plugins. + This is required to verify all overrides. """ + for entry in listdir(plugin_dir): + abspath = join(plugin_dir, entry) + if isdir(abspath) and entry not in ("__pycache__", "plugin_prefab"): + self.load_plugin_settings(entry, abspath) + + def load_plugin_settings(self, plugin_id, plugin_pth): + """ Internal method to load all settings of a plugin, given its plugin + id and path to the plugin base directory """ + config_file = join(plugin_pth, "config.yaml") + config = load_yaml_file(config_file) + # When you don't specify anything in the settings, instead of + # returning an empty dictionary, pyyaml returns None + config["settings"] = config["settings"] or [] + config["daytime_settings"] = config["daytime_settings"] or [] + + if config["settings"] and len(config["settings"][0]) != 2: + self.fatal("Invalid plugin configuration, did you miss '!!omap'?") + + settings = collections.OrderedDict( + [(k, make_setting_from_data(v)) for k, v in config["settings"]]) + self.settings[plugin_id] = settings + + if self.requires_daytime_settings: + daysettings = collections.OrderedDict( + [(k, make_daysetting_from_data(v)) for k, v in config["daytime_settings"]]) + self.day_settings[plugin_id] = daysettings + + def load_setting_overrides(self, override_path): + """ Loads an override file for the settings, which contains values to + override the settings with """ + overrides = load_yaml_file(override_path) + if not overrides: + self.warn("Failed to load overrides") + return + self.enabled_plugins = set(overrides["enabled"] or []) + for plugin_id, pluginsettings in iteritems(overrides["overrides"] or {}): + if plugin_id not in self.settings: + self.warn("Unkown plugin in plugin config:", plugin_id) + continue + for setting_id, setting_val in iteritems(pluginsettings or {}): + if setting_id not in self.settings[plugin_id]: + self.warn("Unkown override:", plugin_id, ":", setting_id) + continue + self.settings[plugin_id][setting_id].set_value(setting_val) + + def load_daytime_overrides(self, override_path): + """ Loads an override file for the daytime settings, which contains + values to override the settings with """ + overrides = load_yaml_file(override_path) + if not overrides: + self.warn("Failed to load daytime overrides") + return + for plugin_id, settings in iteritems(overrides["control_points"] or {}): + for setting_id, control_points in iteritems(settings): + if setting_id not in self.day_settings[plugin_id]: + self.warn("Unkown daytime override:", plugin_id, ":", setting_id) + continue + self.day_settings[plugin_id][setting_id].set_control_points(control_points) + + def trigger_hook(self, hook_name): + """ Triggers a given hook on all plugins, effectively calling all + bound callbacks """ + hook_method = "on_{}".format(hook_name) + for plugin_id in self.enabled_plugins: + plugin_handle = self.instances[plugin_id] + if hasattr(plugin_handle, hook_method): + getattr(plugin_handle, hook_method)() + + def is_plugin_enabled(self, plugin_id): + """ Returns whether a plugin is currently enabled and loaded """ + return plugin_id in self.enabled_plugins + + def get_setting_handle(self, plugin_id, setting_id): + """ Returns the handle to a setting """ + return self.settings[plugin_id][setting_id] + + def init_defines(self): + """ Initializes all plugin settings as a define, so they can be queried + in a shader """ + for plugin_id in self.enabled_plugins: + pluginsettings = self.settings[plugin_id] + self._pipeline.stage_mgr.defines["HAVE_PLUGIN_{}".format(plugin_id)] = 1 + for setting_id, setting in iteritems(pluginsettings): + if setting.shader_runtime or not setting.runtime: + # Only store settings which either never change, or trigger + # a shader reload when they change + setting.add_defines(plugin_id, setting_id, self._pipeline.stage_mgr.defines) + + def _load_plugin(self, plugin_id): + """ Internal method to load a plugin """ + plugin_class = "rpplugins.{}.plugin".format(plugin_id) + module = importlib.import_module(plugin_class) + instance = module.Plugin(self._pipeline) + if instance.native_only and not NATIVE_CXX_LOADED: + if plugin_id in self.enabled_plugins: + self.warn("Cannot load", plugin_id, "since it requires the C++ modules.") + return False + for required_plugin in instance.required_plugins: + if required_plugin not in self.enabled_plugins: + if plugin_id in self.enabled_plugins: + self.warn("Cannot load {} since it requires {}".format( + plugin_id, required_plugin)) + return False + break + return instance + + def save_overrides(self, override_file): + """ Saves all overrides to the given file """ + output = "\n# Render Pipeline Plugin Configuration\n" + output += "# Instead of editing this file, prefer to use the Plugin Configurator\n" + output += "# Any formatting and comments will be lost\n\n" + output += "enabled:\n" + + def sort_criteria(pid): + return ("A" if self.is_plugin_enabled(pid) else "B") + pid + for plugin_id in sorted(self.settings, key=sort_criteria): + output += " {}- {}\n".format( + " # " if plugin_id not in self.enabled_plugins else " ", plugin_id) + output += "\n\noverrides:\n" + for plugin_id, pluginsettings in sorted(iteritems(self.settings)): + output += " " * 4 + plugin_id + ":\n" + for setting_id, setting_handle in iteritems(pluginsettings): + output += " " * 8 + "{}: {}\n".format(setting_id, setting_handle.value) + output += "\n" + with open(override_file, "w") as handle: + handle.write(output) + + def save_daytime_overrides(self, override_file): + """ Saves all time of day overrides to the given file """ + output = "\n# Render Pipeline Time Of Day Configuration\n" + output += "# Instead of editing this file, prefer to use the Time Of Day Editor\n" + output += "# Any formatting and comments will be lost\n\n" + output += "control_points:\n" + for plugin_id, settings in iteritems(self.day_settings): + if settings: + output += " " * 4 + plugin_id + ":\n" + for setting_id, setting_handle in iteritems(settings): + output += " " * 8 + setting_id + ": " + output += setting_handle.serialize() + "\n" + with open(override_file, "w") as handle: + handle.write(output) + + def set_plugin_enabled(self, plugin_id, enabled=True): + """ Sets whether a plugin is enabled or not, thus should be loaded when + the pipeline starts or not """ + if enabled: + self.enabled_plugins.add(plugin_id) + else: + self.enabled_plugins.remove(plugin_id) + + def reset_plugin_settings(self, plugin_id): + """ Resets all settings of a given plugin """ + for setting in itervalues(self.settings[plugin_id]): + setting.value = setting.default + + def on_setting_changed(self, plugin_id, setting_id, value): + """ Callback when a setting got changed. This will update the setting, + and also call the callback for that setting, in case the plugin defined + one. """ + if plugin_id not in self.settings or setting_id not in self.settings[plugin_id]: + self.warn("Got invalid setting change:", plugin_id, "/", setting_id) + return + + setting = self.settings[plugin_id][setting_id] + setting.set_value(value) + + if plugin_id not in self.enabled_plugins: + return + + if setting.runtime or setting.shader_runtime: + update_method = self.instances[plugin_id], "update_" + setting_id + if hasattr(*update_method): + getattr(*update_method)() + + if setting.shader_runtime: + self.init_defines() + self._pipeline.stage_mgr.write_autoconfig() + self.instances[plugin_id].reload_shaders() diff --git a/rpcore/pluginbase/setting_types.py b/rpcore/pluginbase/setting_types.py new file mode 100644 index 0000000..45322ab --- /dev/null +++ b/rpcore/pluginbase/setting_types.py @@ -0,0 +1,239 @@ +""" + +RenderPipeline + +Copyright (c) 2014-2016 tobspr + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. + +""" + +from __future__ import print_function + +from rplibs.six import iteritems, string_types +from rpcore.rpobject import RPObject + +__all__ = ["make_setting_from_data"] + + +def make_setting_from_factory(data, factory): + """ Constructs a new setting from a given dataset, alongst with a factory + to resolve the setting type to """ + if data["type"] not in factory: + raise Exception("Unkown setting type: {}".format(data["type"])) + try: + instance = factory[data["type"]](data) + except Exception: + print("Exception occured while parsing", data) + raise + if data: + raise Exception("Unparsed data left in plugin setting: {}".format(data)) + return instance + + +def make_setting_from_data(data): + """ Constructs a new setting from a given dataset. This method will automatically + instantiate a new class matching the type of the given dataset. It will fill + all values provided by the dataset and then return the created instance """ + factory = { + "int": IntType, + "float": FloatType, + "bool": BoolType, + "enum": EnumType, + "path": PathType, + "power_of_two": PowerOfTwoType, + "sample_sequence": SampleSequenceType + } + return make_setting_from_factory(data, factory) + + +class BaseType(RPObject): + + """ This is the base setting type, all setting types derive from this """ + + def __init__(self, data): + """ Fills in all settings from the given setting data """ + self.value = None + self.type = data.pop("type") + self.label = data.pop("label").strip() + self.description = data.pop("description").strip() + self.runtime = data.pop("runtime", False) + self.shader_runtime = data.pop("shader_runtime", False) + self.display_conditions = data.pop("display_if", {}) + + RPObject.__init__(self, "psetting:{}".format(self.label)) + + def set_value(self, value): + """ Sets the value of the setting, should get overridden """ + raise NotImplementedError() + + def add_defines(self, plugin_id, setting_id, defines): + """ Makes the value of this plugin available as a define """ + defines["{}_{}".format(plugin_id, setting_id)] = self.value + + def should_be_visible(self, settings): + """ Evaluates whether the plugin should be visible, taking all display + conditions into account """ + for key, val in iteritems(self.display_conditions): + if settings[key].value != val: + return False + return True + + +class TemplatedType(BaseType): + + """ This setting stores a single type including a minimum and maximum value. + It is shared between integer and floating point types. """ + + def __init__(self, template_type, data): + BaseType.__init__(self, data) + self.template_type = template_type + self.default = template_type(data.pop("default")) + self.value = self.default + + setting_range = data.pop("range") + self.minval = template_type(setting_range[0]) + self.maxval = template_type(setting_range[1]) + + def set_value(self, value): + value = self.template_type(value) + if self.minval <= value <= self.maxval: + self.value = value + else: + self.error("Invalid value: {}".format(value)) + + +class IntType(TemplatedType): + """ Template instantiation of TemplatedType using int """ + + def __init__(self, data): + TemplatedType.__init__(self, int, data) + +class PowerOfTwoType(IntType): + """ Type for any power of two resolution """ + + def __init__(self, data): + IntType.__init__(self, data) + + def set_value(self, value): + value = int(value) + if self.minval <= value <= self.maxval: + if value in [2**i for i in range(32)]: + self.value = value + else: + self.error("Not a power of two: {}".format(value)) + else: + self.error("Invalid value: {}".format(value)) + + +class FloatType(TemplatedType): + """ Template instantiation of TemplatedType using float """ + + def __init__(self, data): + TemplatedType.__init__(self, float, data) + + +class BoolType(BaseType): + """ Boolean setting type """ + + def __init__(self, data): + BaseType.__init__(self, data) + self.default = bool(data.pop("default")) + self.value = self.default + + def set_value(self, value): + if isinstance(value, string_types): + self.value = str(value.lower()) in ("true", "1") + else: + self.value = bool(value) + + +class EnumType(BaseType): + """ Enumeration setting type """ + def __init__(self, data): + BaseType.__init__(self, data) + self.values = tuple(data.pop("values")) + self.default = data.pop("default") + if self.default not in self.values: + raise Exception("Enum default not in enum values: {}".format(self.default)) + self.value = self.default + + def set_value(self, value): + if value not in self.values: + self.error("Value '" + str(value) + "' not in enum values!") + return + self.value = value + + def add_defines(self, plugin_id, setting_id, defines): + defines["{}_{}".format(plugin_id, setting_id)] = 1000 + self.values.index(self.value) + + for i, val in enumerate(self.values): + defines["enum_{}_{}_{}".format(plugin_id, setting_id, val)] = 1000 + i + +class SampleSequenceType(BaseType): + """ Type for any 2D or 3D sample sequence """ + + POISSON_2D_SIZES = (4, 8, 12, 16, 32, 64) + POISSON_3D_SIZES = (16, 32, 64) + HALTON_SIZES = (4, 8, 16, 32, 64, 128) + + def __init__(self, data): + BaseType.__init__(self, data) + self.dimension = int(data.pop("dimension")) + if self.dimension not in (2, 3): + raise Exception("Not a valid dimension, must be 2 or 3!") + self.default = data.pop("default") + if self.default not in self.sequences: + raise Exception("Not a valid sequence: {}".format(self.default)) + self.value = self.default + + def set_value(self, value): + if value not in self.sequences: + self.error("Value '" + str(value) + "' is not a valid sequence!") + return + self.value = value + + @property + def sequences(self): + result = [] + if self.dimension == 2: + for dim in self.POISSON_2D_SIZES: + result.append("poisson_2D_" + str(dim)) + else: + for dim in self.POISSON_3D_SIZES: + result.append("poisson_3D_" + str(dim)) + for dim in self.HALTON_SIZES: + result.append("halton_" + str(self.dimension) + "D_" + str(dim)) + return result + +class PathType(BaseType): + """ Path type to specify paths to files """ + def __init__(self, data): + BaseType.__init__(self, data) + self.default = str(data.pop("default")) + self.value = self.default + self.file_type = str(data.pop("file_type")) + self.base_path = str(data.pop("base_path")) + + def set_value(self, value): + self.value = str(value) + + def add_defines(self, *args): + # Paths are not available in shaders + pass diff --git a/rpcore/pynative/README.md b/rpcore/pynative/README.md new file mode 100644 index 0000000..7aa9036 --- /dev/null +++ b/rpcore/pynative/README.md @@ -0,0 +1,13 @@ + +## Python Implementation + +This is the Python implementation of the pipeline internals. + +**This folder contains no documentation!** + +To view the documented code, please head over to the C++ Modules at `code/native/source`, +which implement the same features but are commented! + +Besides of not being commented, the code is not written efficient and not in a +pythonic way, too, and instead tries to match the C++ code as close as possible, +to make updates as easy as possible. diff --git a/rpcore/pynative/__init__.py b/rpcore/pynative/__init__.py new file mode 100644 index 0000000..26e3b5c --- /dev/null +++ b/rpcore/pynative/__init__.py @@ -0,0 +1,38 @@ +""" + +RenderPipeline + +Copyright (c) 2014-2016 tobspr + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. + +""" + +# flake8: noqa + +from rpcore.pynative.gpu_command import GPUCommand +from rpcore.pynative.gpu_command_list import GPUCommandList +from rpcore.pynative.ies_dataset import IESDataset +from rpcore.pynative.internal_light_manager import InternalLightManager +from rpcore.pynative.rp_light import RPLight +from rpcore.pynative.rp_spot_light import RPSpotLight +from rpcore.pynative.rp_point_light import RPPointLight +from rpcore.pynative.shadow_manager import ShadowManager +from rpcore.pynative.tag_state_manager import TagStateManager +from rpcore.pynative.pssm_camera_rig import PSSMCameraRig diff --git a/rpcore/pynative/gpu_command.py b/rpcore/pynative/gpu_command.py new file mode 100644 index 0000000..9cb0c52 --- /dev/null +++ b/rpcore/pynative/gpu_command.py @@ -0,0 +1,85 @@ +""" + +RenderPipeline + +Copyright (c) 2014-2016 tobspr + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. + +""" + +from __future__ import print_function +from rplibs.six.moves import range # pylint: disable=import-error + +import struct + + +class GPUCommand(object): + + """ Please refer to the native C++ implementation for docstrings and comments. + This is just the python implementation, which does not contain documentation! """ + + CMD_invalid = 0 + CMD_store_light = 1 + CMD_remove_light = 2 + CMD_store_source = 3 + CMD_remove_sources = 4 + + def __init__(self, command_type): + self._command_type = command_type + self._current_index = 0 + self._data = [0.0] * 32 + self.push_int(command_type) + + def push_int(self, value): + self.push_float(float(value)) + + def push_float(self, value): + if self._current_index >= 32: + print("GPUCommand: out of bounds!") + return + self._data[self._current_index] = float(value) + self._current_index += 1 + + def push_vec3(self, value): + self.push_float(value.x) + self.push_float(value.y) + self.push_float(value.z) + + def push_vec4(self, value): + self.push_vec3(value) + self.push_float(value.get_w()) + + def push_mat4(self, value): + for i in range(4): + for j in range(4): + self.push_float(value.get_cell(i, j)) + + @staticmethod + def get_uses_integer_packing(): + return False + + def write_to(self, dest, command_index): + data = struct.pack("f" * 32, *self._data) + offset = command_index * 32 * 4 + dest.set_subdata(offset, 32 * 4, data) + + def write(self, out=None): # pylint: disable=unused-argument + print("GPUCommand(type=", self._command_type, "size=", self._current_index, ")") + print("Data:", ', '.join([str(i) for i in self._data])) diff --git a/rpcore/pynative/gpu_command_list.py b/rpcore/pynative/gpu_command_list.py new file mode 100644 index 0000000..322557d --- /dev/null +++ b/rpcore/pynative/gpu_command_list.py @@ -0,0 +1,50 @@ +""" + +RenderPipeline + +Copyright (c) 2014-2016 tobspr + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. + +""" + + +class GPUCommandList(object): + + """ Please refer to the native C++ implementation for docstrings and comments. + This is just the python implementation, which does not contain documentation! """ + + def __init__(self): + self._commands = [] + + def add_command(self, cmd): + self._commands.append(cmd) + + @property + def num_commands(self): + return len(self._commands) + + def write_commands_to(self, dest, limit=32): + num_commands_written = 0 + + while num_commands_written < limit and self._commands: + self._commands.pop(0).write_to(dest, num_commands_written) + num_commands_written += 1 + + return num_commands_written diff --git a/rpcore/pynative/ies_dataset.py b/rpcore/pynative/ies_dataset.py new file mode 100644 index 0000000..d24ba31 --- /dev/null +++ b/rpcore/pynative/ies_dataset.py @@ -0,0 +1,97 @@ +""" + +RenderPipeline + +Copyright (c) 2014-2016 tobspr + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. + +""" + +from rplibs.six.moves import range # pylint: disable=import-error + +import math +from panda3d.core import PNMImage + + +class IESDataset(object): + + """ Please refer to the native C++ implementation for docstrings and comments. + This is just the python implementation, which does not contain documentation! """ + + def __init__(self): + self._vertical_angles = None + self._horizontal_angles = None + self._candela_values = None + + def set_vertical_angles(self, vertical_angles): + self._vertical_angles = vertical_angles + + def set_horizontal_angles(self, horizontal_angles): + self._horizontal_angles = horizontal_angles + + def set_candela_values(self, candela_values): + self._candela_values = candela_values + + def generate_dataset_texture_into(self, dest_tex, layer_index): + resolution_vertical = dest_tex.get_y_size() + resolution_horizontal = dest_tex.get_x_size() + + dest = PNMImage(resolution_vertical, resolution_horizontal, 1, 65535) + + for vert in range(resolution_vertical): + for horiz in range(resolution_horizontal): + vert_angle = vert / (resolution_vertical - 1.0) + vert_angle = math.cos(vert_angle * math.pi) * 90.0 + 90.0 + horiz_angle = horiz / (resolution_horizontal - 1.0) * 360.0 + candela = self.get_candela_value(vert_angle, horiz_angle) + dest.set_xel(vert, horiz, candela) + + dest_tex.load(dest, layer_index, 0) + + def get_candela_value(self, vertical_angle, horizontal_angle): # noqa # pylint: disable=unused-argument + # NOTICE: Since python is slower, we always only assume a dataset without + # horizontal angles. This still produces convincing results, but does + # generate much faster. + return self.get_vertical_candela_value(0, vertical_angle) + + def get_candela_value_from_index(self, vertical_angle_idx, horizontal_angle_idx): + index = vertical_angle_idx + horizontal_angle_idx * len(self._vertical_angles) + return self._candela_values[index] + + def get_vertical_candela_value(self, horizontal_angle_idx, vertical_angle): + if vertical_angle < 0.0: + return 0.0 + + if vertical_angle > self._vertical_angles[len(self._vertical_angles) - 1]: + return 0.0 + + for vertical_index in range(1, len(self._vertical_angles)): + curr_angle = self._vertical_angles[vertical_index] + + if curr_angle > vertical_angle: + prev_angle = self._vertical_angles[vertical_index - 1] + prev_value = self.get_candela_value_from_index( + vertical_index - 1, horizontal_angle_idx) + curr_value = self.get_candela_value_from_index( + vertical_index, horizontal_angle_idx) + lerp = (vertical_angle - prev_angle) / (curr_angle - prev_angle) + assert lerp >= 0.0 and lerp <= 1.0 + return curr_value * lerp + prev_value * (1.0 - lerp) + return 0.0 diff --git a/rpcore/pynative/internal_light_manager.py b/rpcore/pynative/internal_light_manager.py new file mode 100644 index 0000000..96b82c7 --- /dev/null +++ b/rpcore/pynative/internal_light_manager.py @@ -0,0 +1,221 @@ +""" + +RenderPipeline + +Copyright (c) 2014-2016 tobspr + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. + +""" +from __future__ import print_function +from rplibs.six.moves import range # pylint: disable=import-error + +from panda3d.core import Vec3 + +from rpcore.pynative.pointer_slot_storage import PointerSlotStorage +from rpcore.pynative.gpu_command import GPUCommand + +MAX_LIGHT_COUNT = 65535 +MAX_SHADOW_SOURCES = 2048 + + +class InternalLightManager(object): + + """ Please refer to the native C++ implementation for docstrings and comments. + This is just the python implementation, which does not contain documentation! """ + + def __init__(self): + self._lights = PointerSlotStorage(MAX_LIGHT_COUNT) + self._shadow_sources = PointerSlotStorage(MAX_SHADOW_SOURCES) + self._cmd_list = None + self._shadow_manager = None + self._camera_pos = Vec3(0) + self._shadow_update_distance = 100.0 + + def get_max_light_index(self): + return self._lights.get_max_index() + + max_light_index = property(get_max_light_index) + + def get_num_lights(self): + return self._lights.get_num_entries() + + num_lights = property(get_num_lights) + + def get_num_shadow_sources(self): + return self._shadow_sources.get_num_entries() + + num_shadow_sources = property(get_num_shadow_sources) + + def set_shadow_manager(self, shadow_manager): + self._shadow_manager = shadow_manager + + def get_shadow_manager(self): + return self._shadow_manager + + shadow_manager = property(get_shadow_manager, set_shadow_manager) + + def set_command_list(self, cmd_list): + self._cmd_list = cmd_list + + def set_camera_pos(self, pos): + self._camera_pos = pos + + def set_shadow_update_distance(self, dist): + self._shadow_update_distance = dist + + def add_light(self, light): + if light.has_slot(): + print("ERROR: Cannot add light since it already has a slot!") + return + + slot = self._lights.find_slot() + if slot < 0: + print("ERROR: Could not find a free slot for a new light!") + return + + light.assign_slot(slot) + self._lights.reserve_slot(slot, light) + + if light.get_casts_shadows(): + self.setup_shadows(light) + + self.gpu_update_light(light) + + def setup_shadows(self, light): + light.init_shadow_sources() + light.update_shadow_sources() + + num_sources = light.get_num_shadow_sources() + base_slot = self._shadow_sources.find_consecutive_slots(num_sources) + if base_slot < 0: + print("ERROR: Failed to find slot for shadow sources!") + return + + for i in range(num_sources): + source = light.get_shadow_source(i) + source.set_needs_update(True) + slot = base_slot + i + self._shadow_sources.reserve_slot(slot, source) + source.set_slot(slot) + + def remove_light(self, light): + assert light is not None + if not light.has_slot(): + print("ERROR: Could not detach light, light was not attached!") + return + + self._lights.free_slot(light.get_slot()) + self.gpu_remove_light(light) + light.remove_slot() + + if light.get_casts_shadows(): + + for i in range(light.get_num_shadow_sources()): + source = light.get_shadow_source(i) + if source.has_slot(): + self._shadow_sources.free_slot(source.get_slot()) + if source.has_region(): + self._shadow_manager.get_atlas().free_region(source.get_region()) + source.clear_region() + + self.gpu_remove_consecutive_sources( + light.get_shadow_source(0), light.get_num_shadow_sources()) + + light.clear_shadow_sources() + + def gpu_remove_consecutive_sources(self, first_source, num_sources): + cmd_remove = GPUCommand(GPUCommand.CMD_remove_sources) + cmd_remove.push_int(first_source.get_slot()) + cmd_remove.push_int(num_sources) + self._cmd_list.add_command(cmd_remove) + + def gpu_remove_light(self, light): + cmd_remove = GPUCommand(GPUCommand.CMD_remove_light) + cmd_remove.push_int(light.get_slot()) + self._cmd_list.add_command(cmd_remove) + + def gpu_update_light(self, light): + cmd_update = GPUCommand(GPUCommand.CMD_store_light) + cmd_update.push_int(light.get_slot()) + light.write_to_command(cmd_update) + light.set_needs_update(False) + self._cmd_list.add_command(cmd_update) + + def gpu_update_source(self, source): + cmd_update = GPUCommand(GPUCommand.CMD_store_source) + cmd_update.push_int(source.get_slot()) + source.write_to_command(cmd_update) + self._cmd_list.add_command(cmd_update) + + def update_lights(self): + for light in self._lights.begin(): + if light.get_needs_update(): + if light.casts_shadows: + light.update_shadow_sources() + self.gpu_update_light(light) + + def update_shadow_sources(self): + sources_to_update = [] + + for source in self._shadow_sources.begin(): + # if source and source.get_needs_update(): + # sources_to_update.append(source) + if source: + bounds = source.get_bounds() + distance_to_camera = (self._camera_pos - bounds.get_center()) - bounds.get_radius() + if distance_to_camera < self._shadow_update_distance: + sources_to_update.append(source) + else: + if source.has_region(): + self._shadow_manager.get_atlas().free_region(source.get_region()) + source.clear_region() + + def get_source_score(source): + dist = (source.get_bounds().get_center() - self._camera_pos).length() + return -dist + (10**10 if source.has_region() else 0) + + sorted_sources = list(sorted(sources_to_update, key=get_source_score)) + + atlas = self._shadow_manager.get_atlas() + update_slots = min( + len(sorted_sources), + self._shadow_manager.get_num_update_slots_left()) + + for i in range(update_slots): + if sorted_sources[i].has_region(): + atlas.free_region(sorted_sources[i].get_region()) + + for i in range(update_slots): + source = sorted_sources[i] + + if not self._shadow_manager.add_update(source): + print("ERROR: Shadow manager ensured update slot, but slot is taken!") + break + + region_size = atlas.get_required_tiles(source.get_resolution()) + new_region = atlas.find_and_reserve_region(region_size, region_size) + new_uv_region = atlas.region_to_uv(new_region) + source.set_region(new_region, new_uv_region) + source.set_needs_update(False) + self.gpu_update_source(source) + + def update(self): + self.update_lights() + self.update_shadow_sources() diff --git a/rpcore/pynative/pointer_slot_storage.py b/rpcore/pynative/pointer_slot_storage.py new file mode 100644 index 0000000..d5e0c3f --- /dev/null +++ b/rpcore/pynative/pointer_slot_storage.py @@ -0,0 +1,90 @@ +""" + +RenderPipeline + +Copyright (c) 2014-2016 tobspr + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. + +""" + +from rplibs.six.moves import range # pylint: disable=import-error + + +class PointerSlotStorage(object): + + """ Please refer to the native C++ implementation for docstrings and comments. + This is just the python implementation, which does not contain documentation! """ + + def __init__(self, max_size): + self._data = [None] * max_size + self._max_index = 0 + self._num_entries = 0 + + def get_max_index(self): + return self._max_index + + def get_num_entries(self): + return self._num_entries + + def find_slot(self): + # Notice: returns None in case of no free slot, and the slot otherwise, this + # is different to the C++ Module + for i, value in enumerate(self._data): + if not value: + return i + return -1 + + def find_consecutive_slots(self, num_consecutive): + if num_consecutive == 1: + return self.find_slot() + + for i in range(len(self._data)): + any_taken = False + for k in range(num_consecutive): + if self._data[i + k]: + any_taken = True + break + if not any_taken: + return i + return -1 + + def free_slot(self, slot): + self._data[slot] = None + self._num_entries -= 1 + if slot == self._max_index: + while self._max_index >= 0 and not self._data[self._max_index]: + self._max_index -= 1 + + def free_consecutive_slots(self, slot, num_consecutive): + for i in range(num_consecutive): + self.free_slot(slot + i) + + def reserve_slot(self, slot, ptr): + self._max_index = max(self._max_index, slot) + self._data[slot] = ptr + self._num_entries += 1 + + def begin(self): + for i in range(self._max_index + 1): + if self._data[i]: + yield self._data[i] + + def end(self): + raise NotImplementedError("Use .begin() as iterator when using the python side!") diff --git a/rpcore/pynative/pssm_camera_rig.py b/rpcore/pynative/pssm_camera_rig.py new file mode 100644 index 0000000..fa48857 --- /dev/null +++ b/rpcore/pynative/pssm_camera_rig.py @@ -0,0 +1,101 @@ +""" + +RenderPipeline + +Copyright (c) 2014-2016 tobspr + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. + +""" + +from panda3d.core import PTALVecBase2f, PTALMatrix4f, Vec2, OrthographicLens +from panda3d.core import Camera, NodePath, Mat4 + +from rpcore.util.generic import snap_shadow_map + + +class PSSMCameraRig(object): + + """ PSSM is not really supported in python yet (too slow), so this is a stub, + supporting only one cascade """ + + def __init__(self, num_splits): + self._split_count = num_splits + self._mvps = PTALMatrix4f.empty_array(num_splits) + self._nearfar = PTALVecBase2f.empty_array(num_splits) + for i in range(num_splits): + self._nearfar[i] = Vec2(20, 1000) + mat = Mat4() + mat.fill(0) + self._mvps[i] = mat + self._lens = OrthographicLens() + self._lens.set_near_far(20, 1000) + self._lens.set_film_size(100, 100) + self._camera = Camera("PSSMDummy", self._lens) + self._cam_node = NodePath(self._camera) + self._parent = None + self._resolution = 1024 + self._snap_grid = True + self._sun_distance = 500.0 + + def set_resolution(self, resolution): + self._resolution = resolution + + def update(self, cam_node, light_vector): + cam_pos = cam_node.get_pos() + self._cam_node.set_pos(cam_pos + light_vector * self._sun_distance) + self._cam_node.look_at(cam_pos) + + if self._snap_grid: + snap_shadow_map(self.compute_mvp(), self._cam_node, self._resolution) + + self._mvps[0] = self.compute_mvp() + + def compute_mvp(self): + transform = self._parent.get_transform(self._cam_node).get_mat() + return transform * self._lens.get_projection_mat() + + def get_camera(self, index): # pylint: disable=unused-argument + return self._cam_node + + def set_sun_distance(self, dist): + self._sun_distance = dist + self._lens.set_near_far(10, 2 * dist) + + def reparent_to(self, parent): + self._cam_node.reparent_to(parent) + self._parent = parent + + def get_mvp_array(self): + return self._mvps + + def get_nearfar_array(self): + return self._nearfar + + def set_use_stable_csm(self, use_stable): + self._snap_grid = use_stable + + def _stub(self, *args, **kwargs): # pylint: disable=unused-argument + return None + + set_pssm_distance = _stub + set_logarithmic_factor = _stub + set_border_bias = _stub + set_use_fixed_film_size = _stub + reset_film_size_cache = _stub diff --git a/rpcore/pynative/rp_light.py b/rpcore/pynative/rp_light.py new file mode 100644 index 0000000..e823d5e --- /dev/null +++ b/rpcore/pynative/rp_light.py @@ -0,0 +1,208 @@ +""" + +RenderPipeline + +Copyright (c) 2014-2016 tobspr + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. + +""" +from __future__ import print_function + +from panda3d.core import Vec3, Mat3 + + +def color_from_temperature(temperature): + # Thanks to rdb for this conversion script + mm = 1000.0 / temperature # pylint: disable=invalid-name + mm2 = mm**2 + mm3 = mm2 * mm + x, y = 0, 0 + + if temperature < 4000: + x = -0.2661239 * mm3 - 0.2343580 * mm2 + 0.8776956 * mm + 0.179910 + else: + x = -3.0258469 * mm3 + 2.1070379 * mm2 + 0.2226347 * mm + 0.240390 + + x2 = x**2 # pylint: disable=invalid-name + x3 = x2 * x # pylint: disable=invalid-name + if temperature < 2222: + y = -1.1063814 * x3 - 1.34811020 * x2 + 2.18555832 * x - 0.20219683 + elif temperature < 4000: + y = -0.9549476 * x3 - 1.37418593 * x2 + 2.09137015 * x - 0.16748867 + else: + y = 3.0817580 * x3 - 5.87338670 * x2 + 3.75112997 * x - 0.37001483 + + # xyY to XYZ, assuming Y=1. + xyz = Vec3(x / y, 1, (1 - x - y) / y) + + # Convert XYZ to linearized sRGB. + xyz_to_rgb = Mat3(3.2406, -0.9689, 0.0557, -1.5372, 1.8758, -0.2050, -0.4986, 0.0415, 1.0570) + + return xyz_to_rgb.xform(xyz) + +__all__ = ["RPLight"] + + +class RPLight(object): + + """ Please refer to the native C++ implementation for docstrings and comments. + This is just the python implementation, which does not contain documentation! """ + + LT_empty = 0 + LT_point_light = 1 + LT_spot_light = 2 + + def __init__(self, light_type): + self._light_type = light_type + self._needs_update = False + self._casts_shadows = False + self._slot = -1 + self._position = Vec3(0) + self._color = Vec3(1) + self._ies_profile = -1 + self._source_resolution = 512 + self._near_plane = 0.5 + self._energy = 20 + self._shadow_sources = [] + + def get_num_shadow_sources(self): + return len(self._shadow_sources) + + def get_shadow_source(self, index): + return self._shadow_sources[index] + + def clear_shadow_sources(self): + self._shadow_sources = [] + + def set_needs_update(self, flag): + self._needs_update = flag + + def get_needs_update(self): + return self._needs_update + + def has_slot(self): + return self._slot >= 0 + + def get_slot(self): + return self._slot + + def remove_slot(self): + self._slot = -1 + + def assign_slot(self, slot): + self._slot = slot + + def invalidate_shadows(self): + for source in self._shadow_sources: + source.set_needs_update(True) + + def set_pos(self, *args): + self._position = Vec3(*args) + self.set_needs_update(True) + self.invalidate_shadows() + + def get_pos(self): + return self._position + + pos = property(get_pos, set_pos) + + def set_color(self, *args): + self._color = Vec3(*args) + self._color /= (0.2126 * self._color.x + + 0.7152 * self._color.y + + 0.0722 * self._color.z) + self.set_needs_update(True) + + def set_color_from_temperature(self, temperature): + self.set_color(color_from_temperature(temperature)) + + def get_color(self): + return self._color + + color = property(get_color, set_color) + + def set_energy(self, energy): + self._energy = energy + + def get_energy(self): + return self._energy + + energy = property(get_energy, set_energy) + + def get_light_type(self): + return self._light_type + + light_type = property(get_light_type) + + def set_casts_shadows(self, flag): + if self.has_slot(): + print("Light is already attached!") + return + self._casts_shadows = flag + + def get_casts_shadows(self): + return self._casts_shadows + + casts_shadows = property(get_casts_shadows, set_casts_shadows) + + def set_shadow_map_resolution(self, resolution): + self._source_resolution = resolution + self.invalidate_shadows() + + def get_shadow_map_resolution(self): + return self._source_resolution + + shadow_map_resolution = property(get_shadow_map_resolution, set_shadow_map_resolution) + + def set_ies_profile(self, profile): + self._ies_profile = profile + self.set_needs_update(True) + + def get_ies_profile(self): + return self._ies_profile + + def has_ies_profile(self): + return self._ies_profile >= 0 + + def clear_ies_profile(self): + self.set_ies_profile(-1) + + ies_profile = property(get_ies_profile, set_ies_profile) + + def set_near_plane(self, near_plane): + self._near_plane = near_plane + self.invalidate_shadows() + + def get_near_plane(self): + return self._near_plane + + near_plane = property(get_near_plane, set_near_plane) + + def write_to_command(self, cmd): + cmd.push_int(self._light_type) + cmd.push_int(self._ies_profile) + + if self._casts_shadows: + cmd.push_int(self._shadow_sources[0].get_slot()) + else: + cmd.push_int(-1) + + cmd.push_vec3(self._position) + cmd.push_vec3(self._color * self._energy / 100.0) diff --git a/rpcore/pynative/rp_point_light.py b/rpcore/pynative/rp_point_light.py new file mode 100644 index 0000000..c3db82c --- /dev/null +++ b/rpcore/pynative/rp_point_light.py @@ -0,0 +1,82 @@ +""" + +RenderPipeline + +Copyright (c) 2014-2016 tobspr + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. + +""" + +from rplibs.six.moves import range # pylint: disable=import-error + +from panda3d.core import Vec3 + +from rpcore.pynative.rp_light import RPLight +from rpcore.pynative.shadow_source import ShadowSource + + +class RPPointLight(RPLight): + + """ Please refer to the native C++ implementation for docstrings and comments. + This is just the python implementation, which does not contain documentation! """ + + def __init__(self): + RPLight.__init__(self, RPLight.LT_point_light) + self._radius = 10.0 + self._inner_radius = 0.01 + + def write_to_command(self, cmd): + RPLight.write_to_command(self, cmd) + cmd.push_float(self._radius) + cmd.push_float(self._inner_radius) + + def set_radius(self, radius): + self._radius = radius + self.set_needs_update(True) + self.invalidate_shadows() + + def get_radius(self): + return self._radius + + radius = property(get_radius, set_radius) + + def set_inner_radius(self, inner_radius): + assert inner_radius >= 0.01 + self._inner_radius = inner_radius + self.set_needs_update(True) + + def get_inner_radius(self): + return self._inner_radius + + inner_radius = property(get_inner_radius, set_inner_radius) + + def init_shadow_sources(self): + for _ in range(6): + self._shadow_sources.append(ShadowSource()) + + def update_shadow_sources(self): + directions = (Vec3(1, 0, 0), Vec3(-1, 0, 0), Vec3(0, 1, 0), + Vec3(0, -1, 0), Vec3(0, 0, 1), Vec3(0, 0, -1)) + + fov = 90.0 + 3.0 + for i, source in enumerate(self._shadow_sources): + source.set_resolution(self.get_shadow_map_resolution()) + source.set_perspective_lens( + fov, self._near_plane, self._radius, self._position, directions[i]) diff --git a/rpcore/pynative/rp_spot_light.py b/rpcore/pynative/rp_spot_light.py new file mode 100644 index 0000000..d9155fc --- /dev/null +++ b/rpcore/pynative/rp_spot_light.py @@ -0,0 +1,92 @@ +""" + +RenderPipeline + +Copyright (c) 2014-2016 tobspr + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. + +""" + +import math +from panda3d.core import Vec3 + +from rpcore.pynative.shadow_source import ShadowSource +from rpcore.pynative.rp_light import RPLight + + +class RPSpotLight(RPLight): + + """ Please refer to the native C++ implementation for docstrings and comments. + This is just the python implementation, which does not contain documentation! """ + + def __init__(self): + RPLight.__init__(self, RPLight.LT_spot_light) + self._radius = 10.0 + self._fov = 45.0 + self._direction = Vec3(0, 0, -1) + + def write_to_command(self, cmd): + RPLight.write_to_command(self, cmd) + cmd.push_float(self._radius) + cmd.push_float(math.cos(self._fov / 360.0 * math.pi)) + cmd.push_vec3(self._direction) + + def set_radius(self, radius): + self._radius = radius + self.set_needs_update(True) + self.invalidate_shadows() + + def get_radius(self): + return self._radius + + radius = property(get_radius, set_radius) + + def set_fov(self, fov): + self._fov = fov + self.set_needs_update(True) + self.invalidate_shadows() + + def get_fov(self): + return self._fov + + fov = property(get_fov, set_fov) + + def set_direction(self, *args): + self._direction = Vec3(*args) + self._direction.normalize() + self.set_needs_update(True) + self.invalidate_shadows() + + def get_direction(self): + return self._direction + + direction = property(get_direction, set_direction) + + def look_at(self, *args): + vec = Vec3(*args) - self._position + self.set_direction(vec) + + def init_shadow_sources(self): + self._shadow_sources.append(ShadowSource()) + + def update_shadow_sources(self): + self._shadow_sources[0].set_resolution(self.get_shadow_map_resolution()) + self._shadow_sources[0].set_perspective_lens( + self._fov, self._near_plane, self._radius, self._position, self._direction) diff --git a/rpcore/pynative/shadow_atlas.py b/rpcore/pynative/shadow_atlas.py new file mode 100644 index 0000000..0cbdf3f --- /dev/null +++ b/rpcore/pynative/shadow_atlas.py @@ -0,0 +1,100 @@ +""" + +RenderPipeline + +Copyright (c) 2014-2016 tobspr + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. + +""" + +from __future__ import print_function, division +from rplibs.six.moves import range # pylint: disable=import-error + +from panda3d.core import LVecBase4i, LVecBase4 + + +class ShadowAtlas(object): + + """ Please refer to the native C++ implementation for docstrings and comments. + This is just the python implementation, which does not contain documentation! """ + + def __init__(self, size, tile_size=32): + self._size = size + self._tile_size = tile_size + self._num_used_tiles = 0 + self.init_tiles() + + def init_tiles(self): + self._num_tiles = self._size // self._tile_size + + def row(): + return [False for i in range(self._num_tiles)] # pylint: disable=unused-variable + self._flags = [row() for j in range(self._num_tiles)] # pylint: disable=unused-variable + + def get_num_used_tiles(self): + return self._num_used_tiles + + num_used_tiles = property(get_num_used_tiles) + + def get_coverage(self): + return self._num_used_tiles / float(self._num_tiles ** 2) + + coverage = property(get_coverage) + + def reserve_region(self, x, y, w, h): + self._num_used_tiles += w * h + for x_offset in range(w): + for y_offset in range(h): + self._flags[x + x_offset][y + y_offset] = True + + def find_and_reserve_region(self, tile_width, tile_height): + for x in range(self._num_tiles - tile_height + 1): + for y in range(self._num_tiles - tile_width + 1): + if self.region_is_free(x, y, tile_width, tile_height): + self.reserve_region(x, y, tile_width, tile_height) + return LVecBase4i(x, y, tile_width, tile_height) + print("Failed to find a free region of size", tile_width, "x", tile_height) + return LVecBase4i(-1) + + def free_region(self, region): + self._num_used_tiles -= region.z * region.w + for x in range(region.z): + for y in range(region.w): + self._flags[region.x + x][region.y + y] = False + + def get_tile_size(self): + return self._tile_size + + def region_is_free(self, x, y, w, h): + for x_offset in range(w): + for y_offset in range(h): + if self._flags[x + x_offset][y + y_offset]: + return False + return True + + def get_required_tiles(self, resolution): + if resolution % self._tile_size != 0: + print("ShadowAtlas: Invalid atlas resolution!") + return + return resolution // self._tile_size + + def region_to_uv(self, region): + flt = LVecBase4(region.x, region.y, region.z, region.w) + return flt * (self._tile_size / self._size) diff --git a/rpcore/pynative/shadow_manager.py b/rpcore/pynative/shadow_manager.py new file mode 100644 index 0000000..bd9969a --- /dev/null +++ b/rpcore/pynative/shadow_manager.py @@ -0,0 +1,123 @@ +""" + +RenderPipeline + +Copyright (c) 2014-2016 tobspr + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. + +""" + +from __future__ import print_function + +from rplibs.six.moves import range # pylint: disable=import-error + +from panda3d.core import Camera, MatrixLens + +from rpcore.pynative.shadow_atlas import ShadowAtlas + + +class ShadowManager(object): + + """ Please refer to the native C++ implementation for docstrings and comments. + This is just the python implementation, which does not contain documentation! """ + + def __init__(self): + self._max_updates = 10 + self._atlas = None + self._atlas_size = 4096 + self._tag_state_mgr = None + self._atlas_graphics_output = None + self._display_regions = [] + self._queued_updates = [] + self._cameras = [] + self._camera_nps = [] + + def set_max_updates(self, max_updates): + if max_updates == 0: + print("Warning: max_updates set to 0, no shadow updates will happen") + self._max_updates = max_updates + + def set_atlas_size(self, atlas_size): + self._atlas_size = atlas_size + + def get_atlas_size(self): + return self._atlas_size + + atlas_size = property(get_atlas_size, set_atlas_size) + + def set_scene(self, scene_parent): + self._scene_parent = scene_parent + + def set_tag_state_manager(self, tag_mgr): + self._tag_state_mgr = tag_mgr + + def set_atlas_graphics_output(self, graphics_output): + self._atlas_graphics_output = graphics_output + + def get_num_update_slots_left(self): + return self._max_updates - len(self._queued_updates) + + num_update_slots_left = property(get_num_update_slots_left) + + def get_atlas(self): + return self._atlas + + atlas = property(get_atlas) + + def init(self): + for i in range(self._max_updates): + camera = Camera("ShadowCam-" + str(i)) + camera.set_lens(MatrixLens()) + camera.set_active(False) + camera.set_scene(self._scene_parent) + self._tag_state_mgr.register_camera("shadow", camera) + self._camera_nps.append(self._scene_parent.attach_new_node(camera)) + self._cameras.append(camera) + + region = self._atlas_graphics_output.make_display_region() + region.set_sort(1000) + region.set_clear_depth_active(True) + region.set_clear_depth(1.0) + region.set_clear_color_active(False) + region.set_camera(self._camera_nps[i]) + region.set_active(False) + self._display_regions.append(region) + + self._atlas = ShadowAtlas(self._atlas_size) + + def update(self): + for i in range(len(self._queued_updates), self._max_updates): + self._cameras[i].set_active(False) + self._display_regions[i].set_active(False) + + for i, source in enumerate(self._queued_updates): + self._cameras[i].set_active(True) + self._display_regions[i].set_active(True) + self._cameras[i].get_lens().set_user_mat(source.get_mvp()) + uv = source.get_uv_region() + self._display_regions[i].set_dimensions(uv.x, uv.x + uv.z, uv.y, uv.y + uv.w) + + self._queued_updates = [] + + def add_update(self, source): + if len(self._queued_updates) >= self._max_updates: + return False + self._queued_updates.append(source) + return True diff --git a/rpcore/pynative/shadow_source.py b/rpcore/pynative/shadow_source.py new file mode 100644 index 0000000..9a0d3a7 --- /dev/null +++ b/rpcore/pynative/shadow_source.py @@ -0,0 +1,108 @@ +""" + +RenderPipeline + +Copyright (c) 2014-2016 tobspr + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. + +""" + +from panda3d.core import Mat4, PerspectiveLens, LVector3, LVecBase2i, LVecBase2f +from panda3d.core import BoundingSphere + + +class ShadowSource(object): + + """ Please refer to the native C++ implementation for docstrings and comments. + This is just the python implementation, which does not contain documentation! """ + + def __init__(self): + self._slot = -1 + self._needs_update = True + self._resolution = 512 + self._mvp = 0.0 + self._region = LVecBase2i(-1) + self._region_uv = LVecBase2f(0.0) + self._bounds = BoundingSphere() + + def set_resolution(self, resolution): + self._resolution = resolution + + def set_needs_update(self, flag): + self._needs_update = flag + + def set_slot(self, slot): + self._slot = slot + + def set_region(self, region, region_uv): + self._region = region + self._region_uv = region_uv + + def clear_region(self): + self._region = LVecBase2i(-1) + self._region_uv = LVecBase2f(0.0) + + def get_bounds(self): + return self._bounds + + def set_perspective_lens(self, fov, near_plane, far_plane, pos, direction): + transform_mat = Mat4.translate_mat(-pos) + temp_lens = PerspectiveLens(fov, fov) + temp_lens.set_film_offset(0, 0) + temp_lens.set_near_far(near_plane, far_plane) + temp_lens.set_view_vector(direction, LVector3.up()) + self.set_matrix_lens(transform_mat * temp_lens.get_projection_mat()) + + hexahedron = temp_lens.make_bounds() + center = (hexahedron.get_min() + hexahedron.get_max()) * 0.5 + self._bounds = BoundingSphere(pos + center, (hexahedron.get_max() - center).length()) + + def set_matrix_lens(self, mvp): + self._mvp = mvp + self.set_needs_update(True) + + def has_region(self): + return (self._region.x >= 0 and self._region.y >= 0 and + self._region.z >= 0 and self._region.w >= 0) + + def has_slot(self): + return self._slot >= 0 + + def get_slot(self): + return self._slot + + def get_needs_update(self): + return not self.has_region or self._needs_update + + def get_resolution(self): + return self._resolution + + def get_mvp(self): + return self._mvp + + def get_region(self): + return self._region + + def get_uv_region(self): + return self._region_uv + + def write_to_command(self, cmd): + cmd.push_mat4(self._mvp) + cmd.push_vec4(self._region_uv) diff --git a/rpcore/pynative/tag_state_manager.py b/rpcore/pynative/tag_state_manager.py new file mode 100644 index 0000000..1e53a5b --- /dev/null +++ b/rpcore/pynative/tag_state_manager.py @@ -0,0 +1,101 @@ +""" + +RenderPipeline + +Copyright (c) 2014-2016 tobspr + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. + +""" + +from __future__ import print_function +from panda3d.core import RenderState, ColorWriteAttrib, ShaderAttrib, BitMask32 + +from rplibs.six import itervalues + + +class TagStateManager(object): + + """ Please refer to the native C++ implementation for docstrings and comments. + This is just the python implementation, which does not contain documentation! """ + + class StateContainer(object): # pylint: disable=too-few-public-methods + def __init__(self, tag_name, mask, write_color): + self.cameras = [] + self.tag_states = {} + self.tag_name = tag_name + self.mask = BitMask32.bit(mask) + self.write_color = write_color + + def __init__(self, main_cam_node): + self._main_cam_node = main_cam_node + self._main_cam_node.node().set_camera_mask(BitMask32.bit(1)) + self.containers = { + "shadow": self.StateContainer("Shadows", 2, False), + "voxelize": self.StateContainer("Voxelize", 3, False), + "envmap": self.StateContainer("Envmap", 4, True), + "forward": self.StateContainer("Forward", 5, True), + } + + def get_mask(self, container_name): + if container_name == "gbuffer": + return BitMask32.bit(1) + return self.containers[container_name].mask + + def apply_state(self, container_name, np, shader, name, sort): + assert shader + state = RenderState.make_empty() + container = self.containers[container_name] + + if not container.write_color: + state = state.set_attrib(ColorWriteAttrib.make(ColorWriteAttrib.C_off), 10000) + + state = state.set_attrib(ShaderAttrib.make(shader, sort), sort) + container.tag_states[name] = state + np.set_tag(container.tag_name, name) + + for camera in container.cameras: + camera.set_tag_state(name, state) + + def cleanup_states(self): + self._main_cam_node.node().clear_tag_states() + for container in itervalues(self.containers): + for camera in container.cameras: + camera.clear_tag_states() + container.tag_states = {} + + def register_camera(self, container_name, source): + container = self.containers[container_name] + source.set_tag_state_key(container.tag_name) + source.set_camera_mask(container.mask) + state = RenderState.make_empty() + if not container.write_color: + state = state.set_attrib(ColorWriteAttrib.make(ColorWriteAttrib.C_off), 10000) + source.set_initial_state(state) + container.cameras.append(source) + + def unregister_camera(self, container_name, source): + container = self.containers[container_name] + if source not in container.cameras: + print("Could not remove source, was never attached!") + return + + container.cameras.remove(source) + source.clear_tag_states() + source.set_initial_state(RenderState.make_empty()) diff --git a/rpcore/render_pipeline.py b/rpcore/render_pipeline.py new file mode 100644 index 0000000..f527169 --- /dev/null +++ b/rpcore/render_pipeline.py @@ -0,0 +1,714 @@ +""" + +RenderPipeline + +Copyright (c) 2014-2016 tobspr + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. + +""" + +from __future__ import division + +import sys +import math +import time + +import panda3d +from panda3d.core import LVecBase2i, TransformState, RenderState, load_prc_file +from panda3d.core import PandaSystem, MaterialAttrib, WindowProperties +from panda3d.core import GeomTristrips, Vec4 + +from direct.showbase.ShowBase import ShowBase +from direct.stdpy.file import isfile +import panda3d.core + +from rplibs.yaml import load_yaml_file_flat +from rplibs.six.moves import range # pylint: disable=import-error + +from rpcore.globals import Globals +from rpcore.effect import Effect +from rpcore.rpobject import RPObject +from rpcore.common_resources import CommonResources +from rpcore.native import TagStateManager, PointLight, SpotLight +from rpcore.render_target import RenderTarget +from rpcore.pluginbase.manager import PluginManager +from rpcore.pluginbase.day_manager import DayTimeManager + +from rpcore.util.task_scheduler import TaskScheduler +from rpcore.util.network_communication import NetworkCommunication +from rpcore.util.ies_profile_loader import IESProfileLoader + +from rpcore.gui.debugger import Debugger +from rpcore.gui.loading_screen import LoadingScreen + +from rpcore.mount_manager import MountManager +from rpcore.stage_manager import StageManager +from rpcore.light_manager import LightManager + +from rpcore.stages.ambient_stage import AmbientStage +from rpcore.stages.gbuffer_stage import GBufferStage +from rpcore.stages.final_stage import FinalStage +from rpcore.stages.downscale_z_stage import DownscaleZStage +from rpcore.stages.combine_velocity_stage import CombineVelocityStage +from rpcore.stages.upscale_stage import UpscaleStage + + +class RenderPipeline(RPObject): + + """ This is the main render pipeline class, it combines all components of + the pipeline to form a working system. It does not do much work itself, but + instead setups all the managers and systems to be able to do their work. """ + + def __init__(self): + """ Creates a new pipeline with a given showbase instance. This should + be done before intializing the ShowBase, the pipeline will take care of + that. If the showbase has been initialized before, have a look at + the alternative initialization of the render pipeline (the first sample).""" + RPObject.__init__(self) + self._analyze_system() + self.mount_mgr = MountManager(self) + self.settings = {} + self._applied_effects = [] + self._pre_showbase_initialized = False + self._first_frame = None + self.set_loading_screen_image("/$$rp/data/gui/meta_core.png") + + def load_settings(self, path): + """ Loads the pipeline configuration from a given filename. Usually + this is the 'config/pipeline.ini' file. If you call this more than once, + only the settings of the last file will be used. """ + self.settings = load_yaml_file_flat(path) + + def reload_shaders(self): + """ Reloads all shaders. This will reload the shaders of all plugins, + as well as the pipelines internally used shaders. Because of the + complexity of some shaders, this operation take might take several + seconds. Also notice that all applied effects will be lost, and instead + the default effect will be set on all elements again. Due to this fact, + this method is primarly useful for fast iterations when developing new + shaders. """ + if self.settings["pipeline.display_debugger"]: + self.debug("Reloading shaders ..") + self.debugger.error_msg_handler.clear_messages() + self.debugger.set_reload_hint_visible(True) + self._showbase.graphicsEngine.render_frame() + self._showbase.graphicsEngine.render_frame() + self.tag_mgr.cleanup_states() + self.stage_mgr.reload_shaders() + self.light_mgr.reload_shaders() + self._set_default_effect() + self.plugin_mgr.trigger_hook("shader_reload") + if self.settings["pipeline.display_debugger"]: + self.debugger.set_reload_hint_visible(False) + self._apply_custom_shaders() + + def _apply_custom_shaders(self): + """ Re-applies all custom shaders the user applied, to avoid them getting + removed when the shaders are reloaded """ + self.debug("Re-applying", len(self._applied_effects), "custom shaders") + for args in self._applied_effects: + self._internal_set_effect(*args) + + def pre_showbase_init(self): + """ Setups all required pipeline settings and configuration which have + to be set before the showbase is setup. This is called by create(), + in case the showbase was not initialized, however you can (and have to) + call it manually before you init your custom showbase instance. + See the 00-Loading the pipeline sample for more information. """ + if not self.mount_mgr.is_mounted: + self.debug("Mount manager was not mounted, mounting now ...") + self.mount_mgr.mount() + + if not self.settings: + self.debug("No settings loaded, loading from default location") + self.load_settings("/$$rpconfig/pipeline.yaml") + + if not isfile("/$$rp/data/install.flag"): + self.fatal("You didn't setup the pipeline yet! Please run setup.py.") + + load_prc_file("/$$rpconfig/panda3d-config.prc") + self._pre_showbase_initialized = True + + def create(self, base=None): + """ This creates the pipeline, and setups all buffers. It also + constructs the showbase. The settings should have been loaded before + calling this, and also the base and write path should have been + initialized properly (see MountManager). + + If base is None, the showbase used in the RenderPipeline constructor + will be used and initialized. Otherwise it is assumed that base is an + initialized ShowBase object. In this case, you should call + pre_showbase_init() before initializing the ShowBase""" + + start_time = time.time() + self._init_showbase(base) + + if not self._showbase.win.gsg.supports_compute_shaders: + self.fatal( + "Sorry, your GPU does not support compute shaders! Make sure\n" + "you have the latest drivers. If you already have, your gpu might\n" + "be too old, or you might be using the open source drivers on linux.") + + self._init_globals() + self.loading_screen.create() + self._adjust_camera_settings() + self._create_managers() + self.plugin_mgr.load() + self.daytime_mgr.load_settings() + self.common_resources.write_config() + self._init_debugger() + + self.plugin_mgr.trigger_hook("stage_setup") + self.plugin_mgr.trigger_hook("post_stage_setup") + + self._create_common_defines() + self._initialize_managers() + self._create_default_skybox() + + self.plugin_mgr.trigger_hook("pipeline_created") + + self._listener = NetworkCommunication(self) + self._set_default_effect() + + # Measure how long it took to initialize everything, and also store + # when we finished, so we can measure how long it took to render the + # first frame (where the shaders are actually compiled) + init_duration = (time.time() - start_time) + self._first_frame = time.process_time() + self.debug("Finished initialization in {:3.3f} s, first frame: {}".format( + init_duration, Globals.clock.get_frame_count())) + + def set_loading_screen_image(self, image_source): + """ Tells the pipeline to use the default loading screen, which consists + of a simple loading image. The image source should be a fullscreen + 16:9 image, and not too small, to avoid being blurred out. """ + self.loading_screen = LoadingScreen(self, image_source) + + def add_light(self, light): + """ Adds a new light to the rendered lights, check out the LightManager + add_light documentation for further information. """ + self.light_mgr.add_light(light) + + def remove_light(self, light): + """ Removes a previously attached light, check out the LightManager + remove_light documentation for further information. """ + self.light_mgr.remove_light(light) + + def load_ies_profile(self, filename): + """ Loads an IES profile from a given filename and returns a handle which + can be used to set an ies profile on a light """ + return self.ies_loader.load(filename) + + def _internal_set_effect(self, nodepath, effect_src, options=None, sort=30): + """ Sets an effect to the given object, using the specified options. + Check out the effect documentation for more information about possible + options and configurations. The object should be a nodepath, and the + effect will be applied to that nodepath and all nodepaths below whose + current effect sort is less than the new effect sort (passed by the + sort parameter). """ + effect = Effect.load(effect_src, options) + if effect is None: + return self.error("Could not apply effect") + + for i, stage in enumerate(("gbuffer", "shadow", "voxelize", "envmap", "forward")): + if not effect.get_option("render_" + stage): + nodepath.hide(self.tag_mgr.get_mask(stage)) + else: + shader = effect.get_shader_obj(stage) + if stage == "gbuffer": + nodepath.set_shader(shader, 25) + else: + self.tag_mgr.apply_state( + stage, nodepath, shader, str(effect.effect_id), 25 + 10 * i + sort) + nodepath.show_through(self.tag_mgr.get_mask(stage)) + + if effect.get_option("render_gbuffer") and effect.get_option("render_forward"): + self.error("You cannot render an object forward and deferred at the " + "same time! Either use render_gbuffer or use render_forward, " + "but not both.") + + def set_effect(self, nodepath, effect_src, options=None, sort=30): + """ See _internal_set_effect. """ + args = (nodepath, effect_src, options, sort) + self._applied_effects.append(args) + self._internal_set_effect(*args) + + def add_environment_probe(self): + """ Constructs a new environment probe and returns the handle, so that + the probe can be modified. In case the env_probes plugin is not activated, + this returns a dummy object which can be modified but has no impact. """ + if not self.plugin_mgr.is_plugin_enabled("env_probes"): + self.warn("env_probes plugin is not loaded - cannot add environment probe") + + class DummyEnvironmentProbe(object): # pylint: disable=too-few-public-methods + def __getattr__(self, *args, **kwargs): + return lambda *args, **kwargs: None + return DummyEnvironmentProbe() + + # Ugh .. + from rpplugins.env_probes.environment_probe import EnvironmentProbe + probe = EnvironmentProbe() + self.plugin_mgr.instances["env_probes"].probe_mgr.add_probe(probe) + return probe + + def prepare_scene(self, scene): + """ Prepares a given scene, by converting panda lights to render pipeline + lights. This also converts all empties with names starting with 'ENVPROBE' + to environment probes. Conversion of blender to render pipeline lights + is done by scaling their intensity by 100 to match lumens. + + Additionally, this finds all materials with the 'TRANSPARENT' shading + model, and sets the proper effects on them to ensure they are rendered + properly. + + This method also returns a dictionary with handles to all created + objects, that is lights, environment probes, and transparent objects. + This can be used to store them and process them later on, or delete + them when a newer scene is loaded.""" + lights = [] + for light in scene.find_all_matches("**/+PointLight"): + light_node = light.node() + rp_light = PointLight() + rp_light.pos = light.get_pos(Globals.base.render) + rp_light.radius = light_node.max_distance + rp_light.energy = 20.0 * light_node.color.w + rp_light.color = light_node.color.xyz + rp_light.casts_shadows = light_node.shadow_caster + rp_light.shadow_map_resolution = light_node.shadow_buffer_size.x + rp_light.inner_radius = 0.4 + + self.add_light(rp_light) + light.remove_node() + lights.append(rp_light) + + for light in scene.find_all_matches("**/+Spotlight"): + light_node = light.node() + rp_light = SpotLight() + rp_light.pos = light.get_pos(Globals.base.render) + rp_light.radius = light_node.max_distance + rp_light.energy = 20.0 * light_node.color.w + rp_light.color = light_node.color.xyz + rp_light.casts_shadows = light_node.shadow_caster + rp_light.shadow_map_resolution = light_node.shadow_buffer_size.x + rp_light.fov = light_node.exponent / math.pi * 180.0 + lpoint = light.get_mat(Globals.base.render).xform_vec((0, 0, -1)) + rp_light.direction = lpoint + self.add_light(rp_light) + light.remove_node() + lights.append(rp_light) + + envprobes = [] + for np in scene.find_all_matches("**/ENVPROBE*"): + probe = self.add_environment_probe() + probe.set_mat(np.get_mat()) + probe.border_smoothness = 0.0001 + probe.parallax_correction = True + np.remove_node() + envprobes.append(probe) + + tristrips_warning_emitted = False + transparent_objects = [] + for geom_np in scene.find_all_matches("**/+GeomNode"): + geom_node = geom_np.node() + geom_count = geom_node.get_num_geoms() + for i in range(geom_count): + state = geom_node.get_geom_state(i) + geom = geom_node.get_geom(i) + + needs_conversion = False + for prim in geom.get_primitives(): + if isinstance(prim, GeomTristrips): + needs_conversion = True + if not tristrips_warning_emitted: + self.warn("At least one GeomNode (", geom_node.get_name(), "and possible more..) contains tristrips.") + self.warn("Due to a NVIDIA Driver bug, we have to convert them to triangles now.") + self.warn("Consider exporting your models with the Bam Exporter to avoid this.") + tristrips_warning_emitted = True + break + + if needs_conversion: + geom_node.modify_geom(i).decompose_in_place() + + if not state.has_attrib(MaterialAttrib): + self.warn("Geom", geom_node, "has no material! Please fix this.") + continue + + material = state.get_attrib(MaterialAttrib).get_material() + shading_model = material.emission.x + + # SHADING_MODEL_TRANSPARENT + if shading_model == 3: + if geom_count > 1: + self.error("Transparent materials must be on their own geom!\n" + "If you are exporting from blender, split them into\n" + "seperate meshes, then re-export your scene. The\n" + "problematic mesh is: " + geom_np.get_name()) + continue + self.set_effect(geom_np, "effects/default.yaml", + {"render_forward": True, "render_gbuffer": False}, 100) + + return {"lights": lights, "envprobes": envprobes, + "transparent_objects": transparent_objects} + + def _create_managers(self): + """ Internal method to create all managers and instances. This also + initializes the commonly used render stages, which are always required, + independently of which plugins are enabled. """ + self.task_scheduler = TaskScheduler(self) + self.tag_mgr = TagStateManager(Globals.base.cam) + self.plugin_mgr = PluginManager(self) + self.stage_mgr = StageManager(self) + self.light_mgr = LightManager(self) + self.daytime_mgr = DayTimeManager(self) + self.ies_loader = IESProfileLoader(self) + self.common_resources = CommonResources(self) + self._init_common_stages() + + def _analyze_system(self): + """ Prints information about the system used, including information + about the used Panda3D build. Also checks if the Panda3D build is out + of date. """ + self.debug("Using Python {}.{} with architecture {}".format( + sys.version_info.major, sys.version_info.minor, PandaSystem.get_platform())) + + build_date = getattr(PandaSystem, 'build_date', None) + if build_date: + self.debug("Using Panda3D {} built on {}".format( + PandaSystem.get_version_string(), build_date)) + else: + self.debug("Using Panda3D {}".format(PandaSystem.get_version_string())) + + if PandaSystem.get_git_commit(): + self.debug("Using git commit {}".format(PandaSystem.get_git_commit())) + else: + self.debug("Using custom Panda3D build") + if not self._check_version(): + self.fatal("Your Panda3D version is outdated! Please update to the newest \n" + "git version! Checkout https://github.com/panda3d/panda3d to " + "compile panda from source, or get a recent buildbot build.") + + def _initialize_managers(self): + """ Internal method to initialize all managers, after they have been + created earlier in _create_managers. The creation and initialization + is seperated due to the fact that plugins and various other subprocesses + have to get initialized inbetween. """ + self.stage_mgr.setup() + self.stage_mgr.reload_shaders() + self.light_mgr.reload_shaders() + self._init_bindings() + self.light_mgr.init_shadows() + + def _init_debugger(self): + """ Internal method to initialize the GUI-based debugger. In case debugging + is disabled, this constructs a dummy debugger, which does nothing. + The debugger itself handles the various onscreen components. """ + if self.settings["pipeline.display_debugger"]: + self.debugger = Debugger(self) + else: + # Use an empty onscreen debugger in case the debugger is not + # enabled, which defines all member functions as empty lambdas + class EmptyDebugger(object): # pylint: disable=too-few-public-methods + def __getattr__(self, *args, **kwargs): + return lambda *args, **kwargs: None + self.debugger = EmptyDebugger() # pylint: disable=redefined-variable-type + del EmptyDebugger + + def _init_globals(self): + """ Inits all global bindings. This includes references to the global + ShowBase instance, as well as the render resolution, the GUI font, + and various global logging and output methods. """ + Globals.load(self._showbase) + native_w, native_h = self._showbase.win.get_x_size(), self._showbase.win.get_y_size() + Globals.native_resolution = LVecBase2i(native_w, native_h) + self._last_window_dims = LVecBase2i(Globals.native_resolution) + self._compute_render_resolution() + RenderTarget.RT_OUTPUT_FUNC = lambda *args: RPObject.global_warn( + "RenderTarget", *args[1:]) + RenderTarget.USE_R11G11B10 = self.settings["pipeline.use_r11_g11_b10"] + + def _set_default_effect(self): + """ Sets the default effect used for all objects if not overridden, this + just calls set_effect with the default effect and options as parameters. + This uses a very low sort, to make sure that overriding the default + effect does not require a custom sort parameter to be passed. """ + self.set_effect(Globals.render, "effects/default.yaml", {}, -10) + + def _adjust_camera_settings(self): + """ Sets the default camera settings, this includes the cameras + near and far plane, as well as FoV. The reason for this is, that pandas + default field of view is very small, and thus we increase it. """ + self._showbase.camLens.set_near_far(0.1, 70000) + self._showbase.camLens.set_fov(40) + + def _compute_render_resolution(self): + """ Computes the internally used render resolution. This might differ + from the window dimensions in case a resolution scale is set. """ + scale_factor = self.settings["pipeline.resolution_scale"] + w = int(float(Globals.native_resolution.x) * scale_factor) + h = int(float(Globals.native_resolution.y) * scale_factor) + # Make sure the resolution is a multiple of 4 + w, h = w - w % 4, h - h % 4 + self.debug("Render resolution is", w, "x", h) + Globals.resolution = LVecBase2i(w, h) + + def _init_showbase(self, base): + """ Inits the the given showbase object. This is part of an alternative + method of initializing the showbase. In case base is None, a new + ShowBase instance will be created and initialized. Otherwise base() is + expected to either be an uninitialized ShowBase instance, or an + initialized instance with pre_showbase_init() called inbefore. """ + if not base: + self.pre_showbase_init() + self._showbase = ShowBase() + else: + if not hasattr(base, "render"): + self.pre_showbase_init() + ShowBase.__init__(base) + else: + if not self._pre_showbase_initialized: + self.fatal("You constructed your own ShowBase object but you\n" + "did not call pre_show_base_init() on the render\n" + "pipeline object before! Checkout the 00-Loading the\n" + "pipeline sample to see how to initialize the RP.") + self._showbase = base + + # Now that we have a showbase and a window, we can print out driver info + self.debug("Driver Version =", self._showbase.win.gsg.driver_version) + self.debug("Driver Vendor =", self._showbase.win.gsg.driver_vendor) + self.debug("Driver Renderer =", self._showbase.win.gsg.driver_renderer) + + def _init_bindings(self): + """ Internal method to init the tasks and keybindings. This constructs + the tasks to be run on a per-frame basis. """ + self._showbase.addTask(self._manager_update_task, "RP_UpdateManagers", sort=10) + self._showbase.addTask(self._plugin_pre_render_update, "RP_Plugin_BeforeRender", sort=12) + self._showbase.addTask(self._plugin_post_render_update, "RP_Plugin_AfterRender", sort=15) + self._showbase.addTask(self._update_inputs_and_stages, "RP_UpdateInputsAndStages", sort=18) + self._showbase.taskMgr.doMethodLater(0.5, self._clear_state_cache, "RP_ClearStateCache") + self._showbase.accept("window-event", self._handle_window_event) + def resize_window(self, w, h): + props: panda3d.core.GraphicsBuffer = self._showbase.win + props.setSize(w, h) + window_dims = LVecBase2i(w, h) + if window_dims != self._last_window_dims and window_dims != Globals.native_resolution: + self._last_window_dims = LVecBase2i(window_dims) + + # Ensure the dimensions are a multiple of 4, and if not, correct it + if window_dims.x % 4 != 0 or window_dims.y % 4 != 0: + window_dims.x = window_dims.x - window_dims.x % 4 + window_dims.y = window_dims.y - window_dims.y % 4 + + # self.debug("Resizing to", window_dims.x, "x", window_dims.y) + Globals.native_resolution = window_dims + self._compute_render_resolution() + self.light_mgr.compute_tile_size() + self.stage_mgr.handle_window_resize() + # self.debugger.handle_window_resize() + self.plugin_mgr.trigger_hook("window_resized") + def _handle_window_event(self, event): + """ Checks for window events. This mainly handles incoming resizes, + and calls the required handlers """ + self._showbase.windowEvent(event) + window_dims = LVecBase2i(self._showbase.win.get_x_size(), self._showbase.win.get_y_size()) + if window_dims != self._last_window_dims and window_dims != Globals.native_resolution: + self._last_window_dims = LVecBase2i(window_dims) + + # Ensure the dimensions are a multiple of 4, and if not, correct it + if window_dims.x % 4 != 0 or window_dims.y % 4 != 0: + self.debug("Correcting non-multiple of 4 window size:", window_dims) + window_dims.x = window_dims.x - window_dims.x % 4 + window_dims.y = window_dims.y - window_dims.y % 4 + props = WindowProperties.size(window_dims.x, window_dims.y) + self._showbase.win.request_properties(props) + + self.debug("Resizing to", window_dims.x, "x", window_dims.y) + Globals.native_resolution = window_dims + self._compute_render_resolution() + self.light_mgr.compute_tile_size() + self.stage_mgr.handle_window_resize() + self.debugger.handle_window_resize() + self.plugin_mgr.trigger_hook("window_resized") + + def _clear_state_cache(self, task=None): + """ Task which repeatedly clears the state cache to avoid storing + unused states. While running once a while, this task prevents over-polluting + the state-cache with unused states. This complements Panda3D's internal + state garbarge collector, which does a great job, but still cannot clear + up all states. """ + task.delayTime = 2.0 + TransformState.clear_cache() + RenderState.clear_cache() + return task.again + + def _manager_update_task(self, task): + """ Update task which gets called before the rendering, and updates + all managers.""" + self.task_scheduler.step() + self._listener.update() + self.debugger.update() + self.daytime_mgr.update() + self.light_mgr.update() + + if Globals.clock.get_frame_count() == 10: + self.debug("Hiding loading screen after 10 pre-rendered frames.") + self.loading_screen.remove() + + return task.cont + + def _update_inputs_and_stages(self, task): + """ Updates the commonly used inputs each frame. This is a seperate + task to be able view detailed performance information in pstats, since + a lot of matrix calculations are involved here. """ + self.common_resources.update() + self.stage_mgr.update() + return task.cont + + def _plugin_pre_render_update(self, task): + """ Update task which gets called before the rendering, and updates the + plugins. This is a seperate task to split the work, and be able to do + better performance analysis in pstats later on. """ + self.plugin_mgr.trigger_hook("pre_render_update") + return task.cont + + def _plugin_post_render_update(self, task): + """ Update task which gets called after the rendering, and should cleanup + all unused states and objects. This also triggers the plugin post-render + update hook. """ + self.plugin_mgr.trigger_hook("post_render_update") + if self._first_frame is not None: + duration = time.process_time() - self._first_frame + self.debug("Took", round(duration, 3), "s until first frame") + self._first_frame = None + return task.cont + + def _create_common_defines(self): + """ Creates commonly used defines for the shader configuration. """ + defines = self.stage_mgr.defines + defines["CAMERA_NEAR"] = round(Globals.base.camLens.get_near(), 10) + defines["CAMERA_FAR"] = round(Globals.base.camLens.get_far(), 10) + + # Work arround buggy nvidia driver, which expects arrays to be const + if "NVIDIA 361.43" in self._showbase.win.gsg.get_driver_version(): + defines["CONST_ARRAY"] = "const" + else: + defines["CONST_ARRAY"] = "" + + # Provide driver vendor as a define + vendor = self._showbase.win.gsg.get_driver_vendor().lower() + defines["IS_NVIDIA"] = "nvidia" in vendor + defines["IS_AMD"] = vendor.startswith("ati") + defines["IS_INTEL"] = "intel" in vendor + + defines["REFERENCE_MODE"] = self.settings["pipeline.reference_mode"] + self.light_mgr.init_defines() + self.plugin_mgr.init_defines() + + def _create_default_skybox(self, size=40000): + """ Returns the default skybox, with a scale of , and all + proper effects and shaders already applied. The skybox is already + parented to render as well. """ + skybox = self.common_resources.load_default_skybox() + skybox.set_scale(size) + skybox.reparent_to(Globals.render) + skybox.set_bin("unsorted", 10000) + self.set_effect(skybox, "effects/skybox.yaml", { + "render_shadow": False, + "render_envmap": False, + "render_voxelize": False, + "alpha_testing": False, + "normal_mapping": False, + "parallax_mapping": False + }, 1000) + return skybox + + def _check_version(self): + """ Internal method to check if the required Panda3D version is met. Returns + True if the version is new enough, and False if the version is outdated. """ + from panda3d.core import Texture + if not hasattr(Texture, "F_r16i"): + return False + return True + + def _init_common_stages(self): + """ Inits the commonly used stages, which don't belong to any plugin, + but yet are necessary and widely used. """ + add_stage = self.stage_mgr.add_stage + self._ambient_stage = AmbientStage(self) + add_stage(self._ambient_stage) + self._gbuffer_stage = GBufferStage(self) + add_stage(self._gbuffer_stage) + self._final_stage = FinalStage(self) + add_stage(self._final_stage) + self._downscale_stage = DownscaleZStage(self) + add_stage(self._downscale_stage) + self._combine_velocity_stage = CombineVelocityStage(self) + add_stage(self._combine_velocity_stage) + + # Add an upscale/downscale stage in case we render at a different resolution + if abs(1 - self.settings["pipeline.resolution_scale"]) > 0.005: + self._upscale_stage = UpscaleStage(self) + add_stage(self._upscale_stage) + + def _get_serialized_material_name(self, material, index=0): + """ Returns a serializable material name """ + return str(index) + "-" + (material.get_name().replace(" ", "").strip() or "unnamed") + + def export_materials(self, pth): + """ Exports a list of all materials found in the current scene in a + serialized format to the given path """ + + with open(pth, "w") as handle: + for i, material in enumerate(Globals.render.find_all_materials()): + if not material.has_base_color() or not material.has_roughness() or not material.has_refractive_index(): + print("Skipping non-pbr material:", material.name) + continue + + handle.write(("{} " * 11).format( + self._get_serialized_material_name(material, i), + material.base_color.x, + material.base_color.y, + material.base_color.z, + material.roughness, + material.refractive_index, + material.metallic, + material.emission.x, # shading model + material.emission.y, # normal strength + material.emission.z, # arbitrary 0 + material.emission.w, # arbitrary 1 + ) + "\n") + + def update_serialized_material(self, data): + """ Internal method to update a material from a given serialized material """ + name = data[0] + + for i, material in enumerate(Globals.render.find_all_materials()): + if self._get_serialized_material_name(material, i) == name: + material.set_base_color(Vec4(float(data[1]), float(data[2]), float(data[3]), 1.0)) + material.set_roughness(float(data[4])) + material.set_refractive_index(float(data[5])) + material.set_metallic(float(data[6])) + material.set_emission(Vec4( + float(data[7]), + float(data[8]), + float(data[9]), + float(data[10]), + )) + + RenderState.clear_cache() diff --git a/rpcore/render_stage.py b/rpcore/render_stage.py new file mode 100644 index 0000000..2af34ba --- /dev/null +++ b/rpcore/render_stage.py @@ -0,0 +1,179 @@ +""" + +RenderPipeline + +Copyright (c) 2014-2016 tobspr + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. + +""" + +from rplibs.six import itervalues, iteritems + +from rpcore.rpobject import RPObject +from rpcore.render_target import RenderTarget +from rpcore.loader import RPLoader + + +class RenderStage(RPObject): + + """ This class is the abstract class for all stages used in the pipeline. + It represents a part of the pipeline render process. Each stage specifies + which pipes it uses and which pipes it produces. A pipe can be seen as a + texture, which gets modified. E.g. the gbuffer pass produces the gbuffer + pipe, the ambient occlusion pass produces the occlusion pipe and so on. The + lighting pass can then specify which pipes it needs and compute the image. + Using a pipe system ensures that new techniques can be inserted easily, + without the other techniques even being aware of them """ + + required_inputs = [] + required_pipes = [] + + produced_inputs = {} + produced_pipes = {} + produced_defines = {} + + disabled = False + + def __init__(self, pipeline): + """ Creates a new render stage """ + RPObject.__init__(self) + self.stage_id = self.__class__.__name__ + self._pipeline = pipeline + self._active = True + self._targets = {} + + def create(self): + """ This method should setup the stage and create the pipes """ + raise NotImplementedError() + + def reload_shaders(self): + """ This method should set all required shaders, there should be no + shaders set in the create method, because the shader auto config is not + generated there """ + pass + + def set_shader_input(self, *args): + """ This method sets a shader input on all stages, which is mainly used + by the stage manager """ + for target in itervalues(self._targets): + target.set_shader_input(*args) + + def set_shader_inputs(self, **kwargs): + """ This method sets shader inputs on all stages, which is mainly used + by the stage manager """ + for target in itervalues(self._targets): + target.set_shader_inputs(**kwargs) + + def update(self): + """ This method gets called every frame, and can be overridden by render + stages to perform custom updates """ + pass + + @property + def active(self): + """ Returns whether *all* targets of the stage are active """ + return self._active + + @active.setter + def active(self, state): + """ Enables or disables this stage. In case the stage is disabled, it will + not get updated anymore, and all stages are distabled """ + if self._active != state: + self._active = state + for target in itervalues(self._targets): + target.active = self._active + + def create_target(self, name): + """ Creates a new render target and binds it to this stage """ + # Format the name like Plugin:Stage:Name, so it can be easily + # found in pstats below the plugin cagetory + name = self._get_plugin_id() + ":" + self.stage_id + ":" + name + if name in self._targets: + return self.error("Overriding existing target: " + name) + self._targets[name] = RenderTarget(name) + return self._targets[name] + + def remove_target(self, target): + """ Removes a previously registered target. This unregisters the + target, as well as removing it from the list of assigned targets. """ + target.remove() + target_key = None + for key, value_target in iteritems(self._targets): + if target == value_target: + target_key = key + break + del self._targets[target_key] + + def _get_shader_handle(self, path, *args): + """ Returns a handle to a Shader object, containing all sources passed + as arguments. The path argument will be used to locate shaders if no + absolute path is given. This is the internal method used in load_shader + and load_plugin_shader. """ + assert len(args) > 0 and len(args) <= 3 + path_args = [] + + for source in args: + for prefix in ("/$$rpconfig", "/$$rp/shader", "/$$rptemp"): + if prefix in source: + path_args.append(source) + break + else: + path_args.append(path.format(source)) + + # If only one shader is specified, assume its a postprocess fragment shader, + # and use the default vertex shader + if len(args) == 1: + path_args = ["/$$rp/shader/default_post_process.vert.glsl"] + path_args + return RPLoader.load_shader(*path_args) + + def _get_plugin_id(self): + """ Returns the id of the plugin which created this stage. This is done + by extracting the name of the plugin from the module name """ + if "rpcore.stages" in self.__class__.__module__: + return "render_pipeline_internal" + return str(self.__class__.__module__).split(".")[-2] + + def load_shader(self, *args): + """ Loads a shader from the given args. If only one argument is passed, + the default template for the stage is loaded. If two arguments are + passed, the first argument should be the vertex shader and the second + argument should be the fragment shader. If three arguments are passed, + the order should be vertex, fragment, geometry """ + return self._get_shader_handle("/$$rp/shader/{0}", *args) + + def load_plugin_shader(self, *args): + """ Loads a shader from the plugin directory. This method is useful + for RenderStages created by plugins. For a description of the arguments, + see the load_shader function. """ + shader_path = "rpplugins/" + self._get_plugin_id() + "/shader/{0}" + return self._get_shader_handle(shader_path, *args) + + def handle_window_resize(self): + """ This method gets called when the window gets resized. By default, + this just resizes all render targets. """ + self.set_dimensions() + for target in itervalues(self._targets): + target.consider_resize() + + def set_dimensions(self): + """ This method should set the dimensions on all targets which don't + have a relative constraint, and also the size of all images. This + is called after initialization, and when the window resized. """ + pass diff --git a/rpcore/render_target.py b/rpcore/render_target.py new file mode 100644 index 0000000..f8ecf5e --- /dev/null +++ b/rpcore/render_target.py @@ -0,0 +1,405 @@ +""" + +RenderTarget + +Copyright (c) 2015 tobspr + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. + +""" + +from __future__ import print_function, division + +from panda3d.core import GraphicsOutput, Texture, AuxBitplaneAttrib, NodePath +from panda3d.core import Vec4, TransparencyAttrib, ColorWriteAttrib, SamplerState +from panda3d.core import WindowProperties, FrameBufferProperties, GraphicsPipe +from panda3d.core import LVecBase2i + +from rplibs.six.moves import range # pylint: disable=import-error +from rplibs.six import iterkeys, itervalues + +from rpcore.globals import Globals +from rpcore.rpobject import RPObject +from rpcore.util.post_process_region import PostProcessRegion + +__all__ = "RenderTarget", +__version__ = "2.0" + + +class setter(object): # noqa # pylint: disable=invalid-name,too-few-public-methods + """ Setter only property """ + def __init__(self, func): + self.__func = func + self.__doc__ = func.__doc__ + + def __set__(self, name, value): + return self.__func(name, value) + + +class RenderTarget(RPObject): + + """ Second version of the RenderTarget library, provides functions + to easily setup buffers in Panda3D. """ + + NUM_ALLOCATED_BUFFERS = 0 + USE_R11G11B10 = True + REGISTERED_TARGETS = [] + CURRENT_SORT = -300 + + def __init__(self, name="target"): + RPObject.__init__(self, name) + self._targets = {} + self._color_bits = (0, 0, 0, 0) + self._aux_bits = 8 + self._aux_count = 0 + self._depth_bits = 0 + self._size = LVecBase2i(-1) + self._size_constraint = LVecBase2i(-1) + self._source_window = Globals.base.win + self._source_region = None + self._active = False + self._internal_buffer = None + self.sort = None + + # Public attributes + self.engine = Globals.base.graphicsEngine + self.support_transparency = False + self.create_default_region = True + + # Disable all global clears, since they are not required + for region in Globals.base.win.get_display_regions(): + region.disable_clears() + + def add_color_attachment(self, bits=8, alpha=False): + """ Adds a new color attachment with the given amount of bits, bits can + be either a single int or a tuple determining the bits. If bits is a + single int, alpha determines whether alpha bits are requested """ + self._targets["color"] = Texture(self.debug_name + "_color") + if isinstance(bits, (list, tuple)): + self._color_bits = (bits[0], bits[1], bits[2], bits[3] if len(bits) == 4 else 0) + else: + self._color_bits = ((bits, bits, bits, (bits if alpha else 0))) + + def add_depth_attachment(self, bits=32): + """ Adds a depth attachment wit the given amount of bits """ + self._targets["depth"] = Texture(self.debug_name + "_depth") + self._depth_bits = bits + + def add_aux_attachment(self, bits=8): + """ Adds a new aux attachment with the given amount of bits. The amount + of bits passed overrides all previous bits set, since all aux textures + have to have the same amount of bits. """ + self._aux_bits = bits + self._aux_count += 1 + + def add_aux_attachments(self, bits=8, count=1): + """ Adds n new aux attachments, with the given amount of bits. All + previously set aux bits are overriden, since all aux textures have to + have the same amount of bits """ + self._aux_bits = bits + self._aux_count += count + + @setter + def size(self, *args): + """ Sets the render target size. This can be either a single integer, + in which case it applies to both dimensions. Negative integers cause + the render target to be proportional to the screen size, i.e. a value + of -4 produces a quarter resolution target, a value of -2 a half + resolution target, and a value of -1 a full resolution target + (the default). """ + self._size_constraint = LVecBase2i(*args) + + @property + def active(self): + """ Returns whether the target is currently active """ + return self._active + + @active.setter + def active(self, flag): + """ Sets whether the target is active, this just propagates the active + flag to all display regions """ + for region in self._internal_buffer.get_display_regions(): + region.set_active(flag) + + @property + def color_tex(self): + """ Returns the color attachment if present """ + return self._targets["color"] + + @property + def depth_tex(self): + """ Returns the depth attachment if present """ + return self._targets["depth"] + + @property + def aux_tex(self): + """ Returns a list of aux textures, can be used like target.aux_tex[2], + notice the indices start at zero, so the first target has the index 0. """ + return [self._targets[i] for i in sorted(iterkeys(self._targets)) if i.startswith("aux_")] + + def set_shader_input(self, *args, **kwargs): + """ Sets a shader input available to the target """ + if self.create_default_region: + self._source_region.set_shader_input(*args, **kwargs) + + def set_shader_inputs(self, **kwargs): + """ Sets shader inputs available to the target """ + if self.create_default_region: + self._source_region.set_shader_inputs(**kwargs) + + @setter + def shader(self, shader_obj): + """ Sets a shader on the target """ + if not shader_obj: + self.error("shader must not be None!") + return + self._source_region.set_shader(shader_obj) + + @property + def internal_buffer(self): + """ Returns a handle to the internal GraphicsBuffer object """ + return self._internal_buffer + + @property + def targets(self): + """ Returns the dictionary of attachments, whereas the key is the name + of the attachment and the value is the Texture handle of the attachment """ + return self._targets + + @property + def region(self): + """ Returns the internally used PostProcessRegion """ + return self._source_region + + def prepare_render(self, camera_np): + """ Prepares to render a scene """ + self.create_default_region = False + self._create_buffer() + self._source_region = self._internal_buffer.get_display_region(0) + + if camera_np: + initial_state = NodePath("rtis") + initial_state.set_state(camera_np.node().get_initial_state()) + + if self._aux_count: + initial_state.set_attrib(AuxBitplaneAttrib.make(self._aux_bits), 20) + initial_state.set_attrib(TransparencyAttrib.make(TransparencyAttrib.M_none), 20) + + if max(self._color_bits) == 0: + initial_state.set_attrib(ColorWriteAttrib.make(ColorWriteAttrib.C_off), 20) + + # Disable existing regions of the camera + for region in camera_np.node().get_display_regions(): + region.set_active(False) + + # Remove the existing display region of the camera + for region in self._source_window.get_display_regions(): + if region.get_camera() == camera_np: + self._source_window.remove_display_region(region) + + camera_np.node().set_initial_state(initial_state.get_state()) + self._source_region.set_camera(camera_np) + + self._internal_buffer.disable_clears() + self._source_region.disable_clears() + self._source_region.set_active(True) + self._source_region.set_sort(20) + + # Reenable depth-clear, usually desireable + self._source_region.set_clear_depth_active(True) + self._source_region.set_clear_depth(1.0) + self._active = True + + def prepare_buffer(self): + """ Prepares the target to render to an offscreen buffer """ + self._create_buffer() + self._active = True + + def present_on_screen(self): + """ Prepares the target to render on the main window, to present the + final rendered image """ + self._source_region = PostProcessRegion.make(self._source_window) + self._source_region.set_sort(5) + + def remove(self): + """ Deletes this buffer, restoring the previous state """ + self._internal_buffer.clear_render_textures() + self.engine.remove_window(self._internal_buffer) + self._active = False + for target in itervalues(self._targets): + target.release_all() + RenderTarget.REGISTERED_TARGETS.remove(self) + + def set_clear_color(self, *args): + """ Sets the clear color """ + self._internal_buffer.set_clear_color_active(True) + self._internal_buffer.set_clear_color(Vec4(*args)) + + @setter + def instance_count(self, count): + """ Sets the instance count """ + self._source_region.set_instance_count(count) + + def _create_buffer(self): + """ Internal method to create the buffer object """ + self._compute_size_from_constraint() + if not self._create(): + self.error("Failed to create buffer!") + return False + + if self.create_default_region: + self._source_region = PostProcessRegion.make(self._internal_buffer) + + if max(self._color_bits) == 0: + self._source_region.set_attrib(ColorWriteAttrib.make(ColorWriteAttrib.M_none), 1000) + + def _compute_size_from_constraint(self): + """ Computes the actual size in pixels from the targets size constraint """ + w, h = Globals.resolution.x, Globals.resolution.y + self._size = LVecBase2i(self._size_constraint) + if self._size_constraint.x < 0: + self._size.x = (w - self._size_constraint.x - 1) // (-self._size_constraint.x) + if self._size_constraint.y < 0: + self._size.y = (h - self._size_constraint.y - 1) // (-self._size_constraint.y) + + def _setup_textures(self): + """ Prepares all bound textures """ + for i in range(self._aux_count): + self._targets["aux_{}".format(i)] = Texture( + self.debug_name + "_aux{}".format(i)) + for tex in itervalues(self._targets): + tex.set_wrap_u(SamplerState.WM_clamp) + tex.set_wrap_v(SamplerState.WM_clamp) + tex.set_anisotropic_degree(0) + tex.set_x_size(self._size.x) + tex.set_y_size(self._size.y) + tex.set_minfilter(SamplerState.FT_linear) + tex.set_magfilter(SamplerState.FT_linear) + + def _make_properties(self): + """ Creates the window and buffer properties """ + window_props = WindowProperties.size(self._size.x, self._size.y) + buffer_props = FrameBufferProperties() + + if self._size_constraint.x == 0 or self._size_constraint.y == 0: + window_props = WindowProperties.size(1, 1) + + if self._color_bits == (16, 16, 16, 0): + if RenderTarget.USE_R11G11B10: + buffer_props.set_rgba_bits(11, 11, 10, 0) + else: + buffer_props.set_rgba_bits(*self._color_bits) + elif 8 in self._color_bits: + # When specifying 8 bits, specify 1 bit, this is a workarround + # to a legacy logic in panda + buffer_props.set_rgba_bits(*[i if i != 8 else 1 for i in self._color_bits]) + else: + buffer_props.set_rgba_bits(*self._color_bits) + + buffer_props.set_accum_bits(0) + buffer_props.set_stencil_bits(0) + buffer_props.set_back_buffers(0) + buffer_props.set_coverage_samples(0) + buffer_props.set_depth_bits(self._depth_bits) + + if self._depth_bits == 32: + buffer_props.set_float_depth(True) + + buffer_props.set_float_color(max(self._color_bits) > 8) + + buffer_props.set_force_hardware(True) + buffer_props.set_multisamples(0) + buffer_props.set_srgb_color(False) + buffer_props.set_stereo(False) + buffer_props.set_stencil_bits(0) + + if self._aux_bits == 8: + buffer_props.set_aux_rgba(self._aux_count) + elif self._aux_bits == 16: + buffer_props.set_aux_hrgba(self._aux_count) + elif self._aux_bits == 32: + buffer_props.set_aux_float(self._aux_count) + else: + self.error("Invalid aux bits") + + return window_props, buffer_props + + def _create(self): + """ Creates the internally used buffer """ + self._setup_textures() + window_props, buffer_props = self._make_properties() + + # Some window types (e.g., offscreen buffers) may report no pipe; fall back to Globals.base.pipe + pipe = self._source_window.get_pipe() if self._source_window else None + if pipe is None and Globals.base is not None: + pipe = getattr(Globals.base, "pipe", None) + + self._internal_buffer = self.engine.make_output( + pipe, self.debug_name, 1, + buffer_props, window_props, GraphicsPipe.BF_refuse_window | GraphicsPipe.BF_resizeable, + self._source_window.gsg, self._source_window) + + if not self._internal_buffer: + self.error("Failed to create buffer") + return + + if self._depth_bits: + self._internal_buffer.add_render_texture( + self.depth_tex, GraphicsOutput.RTM_bind_or_copy, + GraphicsOutput.RTP_depth) + + if max(self._color_bits) > 0: + self._internal_buffer.add_render_texture( + self.color_tex, GraphicsOutput.RTM_bind_or_copy, + GraphicsOutput.RTP_color) + + aux_prefix = { + 8: "RTP_aux_rgba_{}", + 16: "RTP_aux_hrgba_{}", + 32: "RTP_aux_float_{}", + }[self._aux_bits] + + for i in range(self._aux_count): + target_mode = getattr(GraphicsOutput, aux_prefix.format(i)) + self._internal_buffer.add_render_texture( + self.aux_tex[i], GraphicsOutput.RTM_bind_or_copy, target_mode) + + if not self.sort: + RenderTarget.CURRENT_SORT += 20 + self.sort = RenderTarget.CURRENT_SORT + + RenderTarget.NUM_ALLOCATED_BUFFERS += 1 + self._internal_buffer.set_sort(self.sort) + self._internal_buffer.disable_clears() + self._internal_buffer.get_display_region(0).disable_clears() + self._internal_buffer.get_overlay_display_region().disable_clears() + self._internal_buffer.get_overlay_display_region().set_active(False) + + RenderTarget.REGISTERED_TARGETS.append(self) + return True + + def consider_resize(self): + """ Checks if the target has to get resized, and if this is the case, + performs the resize. This should be called when the window resolution + changed. """ + current_size = LVecBase2i(self._size) + self._compute_size_from_constraint() + if current_size != self._size: + if self._internal_buffer: + self._internal_buffer.set_size(self._size.x, self._size.y) diff --git a/rpcore/rpobject.py b/rpcore/rpobject.py new file mode 100644 index 0000000..1fe2b64 --- /dev/null +++ b/rpcore/rpobject.py @@ -0,0 +1,144 @@ +""" + +RenderPipeline + +Copyright (c) 2014-2016 tobspr + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. + +""" + +# Disable the xxx has no yyy member warning, pylint seems to be +# unable to figure out the Colorama properties, and throws an error +# for each property. +# pylint: disable=no-member + +from __future__ import print_function + +import sys + +# Load and init colorama, used to color the output +from rplibs.colorama import init as init_colorama +from rplibs.colorama import Fore, Style +init_colorama() + + +class RPObject(object): + + """ This is the base class for every object in the render pipeline. It + provides the functions debug, warn, error and fatal for classes which + inherit from this object, including the name of the class when printing out + the message. """ + + _OUTPUT_LEVEL = 0 + _OUTPUT_LEVELS = ["debug", "warning", "error", "fatal"] + + @classmethod + def set_output_level(cls, level): + """ Sets the output level, messages with a level below will not be + printed. E.g. if you set the output level to "error", only error and + fatal messages will be shown. """ + assert level in RPObject._OUTPUT_LEVELS + RPObject._OUTPUT_LEVEL = RPObject._OUTPUT_LEVELS.index(level) + + @staticmethod + def global_debug(context, *args, **kwargs): + """ This method can be used from a static context to print a debug + message. The first argument should be the name of the object / context, + all other arguments should be the message. """ + if RPObject._OUTPUT_LEVEL > 0: + return + print(kwargs.get("color", Fore.GREEN) + "[>] " + + context.ljust(25) + " " + Style.RESET_ALL + Fore.WHITE + + ' '.join([str(i) for i in args]), Fore.RESET + Style.RESET_ALL) + + @staticmethod + def global_warn(context, *args): + """ This method can be used from a static context to print a warning. + The first argument should be the name of the object / context, all + other arguments should be the message. """ + if RPObject._OUTPUT_LEVEL > 1: + return + print(Fore.YELLOW + Style.BRIGHT + "[!] " + context.ljust(25) + + Fore.YELLOW + Style.BRIGHT + " " + ' '.join([str(i) for i in args]) + + Fore.RESET + Style.RESET_ALL) + + @staticmethod + def global_error(context, *args): + """ This method can be used from a static context to print an error. + The first argument should be the name of the object / context, all + other arguments should be the message. """ + if RPObject._OUTPUT_LEVEL > 2: + return + print(Fore.RED + Style.BRIGHT + "\n[!!!] " + + context.ljust(23) + " " + ' '.join([str(i) for i in args]) + + "\n" + Fore.RESET + Style.RESET_ALL) + + def __init__(self, name=None): + """ Initiates the RPObject with a given name. The name should be + representative about the class. If no name is given, the classname + is used """ + if name is None: + name = self.__class__.__name__ + self._debug_name = name + self._debug_color = Fore.GREEN + + def _set_debug_color(self, color, style=None): + """ Sets the color used to output debug messages """ + self._debug_color = getattr(Fore, color.upper()) + if style: + self._debug_color += getattr(Style, style.upper()) + + @property + def debug_name(self): + """ Returns the name of the debug object """ + return self._debug_name + + @debug_name.setter + def debug_name(self, name): + """ Renames this object """ + self._debug_name = name + + def debug(self, *args): + """ Outputs a debug message, something that is not necessarry + but provides useful information for the developer """ + self.global_debug(self._debug_name, *args, color=self._debug_color) + + def warn(self, *args): + """ Outputs a warning message, something that failed or does + not work, but does not prevent the program from running """ + self.global_warn(self._debug_name, *args) + + def error(self, *args): + """ Outputs an error message, something really serious. + Hopefully this never get's called! """ + self.global_error(self._debug_name, *args) + + def fatal(self, *args): + """ Outputs a fatal error message, printing out the errors and then + calling sys.exit to terminate the program. This method should be called + when something failed so hard that the pipeline has to exit. """ + # We have to set output level to 0 here, so we can print out errors + RPObject._OUTPUT_LEVEL = 0 + self.error(*args) + sys.exit(0) + + def __repr__(self): + """ Represents this object. Subclasses can override this """ + return self._debug_name diff --git a/rpcore/shader/ambient_stage.frag.glsl b/rpcore/shader/ambient_stage.frag.glsl new file mode 100644 index 0000000..51fab7e --- /dev/null +++ b/rpcore/shader/ambient_stage.frag.glsl @@ -0,0 +1,294 @@ +/** + * + * RenderPipeline + * + * Copyright (c) 2014-2016 tobspr + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + */ + +#version 430 + +// This shader applies the ambient term to the shaded scene + +#pragma include "render_pipeline_base.inc.glsl" +#pragma include "includes/gbuffer.inc.glsl" +#pragma include "includes/brdf.inc.glsl" +#pragma include "includes/lights.inc.glsl" +#pragma include "includes/color_spaces.inc.glsl" + +uniform sampler2D ShadedScene; +uniform GBufferData GBuffer; +uniform sampler3D PrefilteredBRDF; +uniform sampler2D PrefilteredMetalBRDF; +uniform sampler2D PrefilteredCoatBRDF; + +uniform samplerCube DefaultEnvmap; + +#if HAVE_PLUGIN(scattering) + uniform samplerCube ScatteringIBLDiffuse; + uniform samplerCube ScatteringIBLSpecular; +#endif + +#if HAVE_PLUGIN(ao) + uniform sampler2D AmbientOcclusion; +#endif + +#if HAVE_PLUGIN(sky_ao) + uniform sampler2D SkyAO; +#endif + +#if HAVE_PLUGIN(vxgi) + // uniform sampler2D VXGISpecular; + uniform sampler2D VXGIDiffuse; +#endif + +#if HAVE_PLUGIN(env_probes) + uniform sampler2D EnvmapAmbientDiff; + uniform sampler2D EnvmapAmbientSpec; +#endif + +#if HAVE_PLUGIN(ssr) + uniform sampler2D SSRSpecular; +#endif + +out vec4 result; + +float compute_specular_occlusion(float NxV, float occlusion, float roughness) { + return saturate(pow(NxV + occlusion, roughness) - 1 + occlusion); +} + +// From: http://www.frostbite.com/wp-content/uploads/2014/11/course_notes_moving_frostbite_to_pbr.pdf +vec3 compute_bloom_luminance(vec3 bloom_color, float bloom_ec, float current_ev) { + float bloom_ev = current_ev + bloom_ec; + return bloom_color * pow(2, bloom_ev - 3); +} + +void main() { + vec2 texcoord = get_texcoord(); + Material m = unpack_material(GBuffer); + vec3 view_vector = normalize(m.position - MainSceneData.camera_pos); + + // Store the accumulated ambient term in a variable + vec3 ambient = vec3(0); + + #if !DEBUG_MODE || MODE_ACTIVE(DIFFUSE_AMBIENT) || MODE_ACTIVE(SPECULAR_AMBIENT) || MODE_ACTIVE(OCCLUSION) || MODE_ACTIVE(SKY_AO) + + // Skip skybox shading + if (is_skybox(m)) { + + #if !REFERENCE_MODE + result = textureLod(ShadedScene, texcoord, 0); + + #if !HAVE_PLUGIN(scattering) + result = textureLod( + DefaultEnvmap, view_vector.yxz * vec3(-1, 1, 1), 0) * + DEFAULT_ENVMAP_BRIGHTNESS; + #endif + #else + + // When in reference mode, display the used environment cubemap as background + #if USE_WHITE_ENVIRONMENT + result = vec4(1); + #else + result = textureLod(DefaultEnvmap, view_vector.yxz * vec3(-1, 1, 1), 0); + #endif + #endif + + return; + } + + + #if HAVE_PLUGIN(sky_ao) + float sky_ao_factor = textureLod(SkyAO, texcoord, 0).x; + sky_ao_factor = pow(sky_ao_factor, 3.0); + + // Prevent total dark ao term + sky_ao_factor = max(0.2, sky_ao_factor); + #else + float sky_ao_factor = 1.0; + #endif + + // Get reflection directory + vec3 reflected_dir = get_reflection_vector(m, view_vector); + float roughness = get_effective_roughness(m); + + // Compute angle between normal and view vector + float NxV = clamp(-dot(m.normal, view_vector), 1e-5, 1.0); + + // Get mipmap offset for the material roughness + float env_mipmap = get_mipmap_for_roughness(DefaultEnvmap, roughness , NxV); + + // Sample default environment map + vec3 ibl_specular = textureLod(DefaultEnvmap, + fix_cubemap_coord(reflected_dir), env_mipmap).xyz * DEFAULT_ENVMAP_BRIGHTNESS; + + // Get cheap irradiance by sampling low levels of the environment map + float ibl_diffuse_mip = get_mipmap_count(DefaultEnvmap) - 3.0; + vec3 ibl_diffuse = textureLod(DefaultEnvmap, fix_cubemap_coord(m.normal), + ibl_diffuse_mip).xyz * DEFAULT_ENVMAP_BRIGHTNESS; + + // Scattering specific code + #if HAVE_PLUGIN(scattering) + float scat_mipmap = m.shading_model == SHADING_MODEL_CLEARCOAT ? + CLEARCOAT_ROUGHNESS : get_specular_mipmap(m); + + ibl_specular = textureLod(ScatteringIBLSpecular, reflected_dir, scat_mipmap).xyz * sky_ao_factor; + ibl_diffuse = textureLod(ScatteringIBLDiffuse, m.normal, 0).xyz * sky_ao_factor; + #endif + + // Blend environment maps + #if HAVE_PLUGIN(env_probes) + vec4 probe_spec = textureLod(EnvmapAmbientSpec, texcoord, 0); + vec4 probe_diff = textureLod(EnvmapAmbientDiff, texcoord, 0); + ibl_diffuse = ibl_diffuse * (1 - probe_diff.w) + probe_diff.xyz; + ibl_specular = ibl_specular * (1 - probe_spec.w) + probe_spec.xyz; + #endif + + // Blend VXGI on top + #if HAVE_PLUGIN(vxgi) + // vec4 vxgi_spec = textureLod(VXGISpecular, texcoord, 0); + ibl_diffuse = textureLod(VXGIDiffuse, texcoord, 0).xyz; + // ibl_specular *= ibl_diffuse; + // ibl_specular = ibl_specular * (1 - vxgi_spec.w) + vxgi_spec.xyz; + #endif + + // Blend screen space reflections + #if HAVE_PLUGIN(ssr) + vec4 ssr_spec = textureLod(SSRSpecular, texcoord, 0); + + // Fade out SSR on high roughness values + ssr_spec *= 1.0 - saturate(m.roughness / GET_SETTING(ssr, roughness_fade)); + ssr_spec *= GET_SETTING(ssr, effect_scale); + ibl_specular = ibl_specular * (1 - ssr_spec.w) + ssr_spec.xyz; + #endif + + #if USE_WHITE_ENVIRONMENT + ibl_specular = vec3(1); + ibl_diffuse = vec3(1); + #endif + + vec3 material_f0 = get_material_f0(m); + vec3 specular_ambient = vec3(0); + + // Pre-Integrated environment BRDF + vec3 env_brdf = get_brdf_from_lut(PrefilteredBRDF, NxV, sqrt(roughness), m.specular_ior); + + // Exact metallic brdf lut, unused right now + // vec3 env_brdf_metal = get_brdf_from_lut(PrefilteredMetalBRDF, NxV, roughness); + + // Diffuse and fresnel ambient term + vec3 diffuse_ambient = ibl_diffuse * m.basecolor * (1-m.metallic); + vec3 fresnel = env_brdf.ggg; + diffuse_ambient *= env_brdf.r; + + // Approximate metallic fresnel + vec3 metallic_fresnel = get_metallic_fresnel_approx(m, NxV); + + // Mix between normal and metallic fresnel + fresnel = mix(fresnel, metallic_fresnel, m.metallic); + + if (m.shading_model == SHADING_MODEL_CLEARCOAT) { + vec3 env_brdf_coat = get_brdf_from_lut( + PrefilteredCoatBRDF, NxV, m.linear_roughness * 1.333); + + #if HAVE_PLUGIN(scattering) + vec3 ibl_specular_base = textureLod( + ScatteringIBLSpecular, reflected_dir, + get_specular_mipmap(m)).xyz * sky_ao_factor; + #else + vec3 ibl_specular_base = textureLod( + DefaultEnvmap, fix_cubemap_coord(reflected_dir), + get_mipmap_for_roughness(DefaultEnvmap, m.roughness, NxV)).xyz * + DEFAULT_ENVMAP_BRIGHTNESS; + #endif + + #if REFERENCE_MODE && USE_WHITE_ENVIRONMENT + // ibl_specular_base = vec3(1); + #endif + + specular_ambient = env_brdf_coat.g * ibl_specular; + specular_ambient += env_brdf_coat.r * ibl_specular_base * m.basecolor; + } else { + specular_ambient = fresnel * ibl_specular; + } + + // Sample precomputed occlusion and multiply the ambient term with it + #if HAVE_PLUGIN(ao) + float occlusion = textureLod(AmbientOcclusion, texcoord, 0).x; + #else + float occlusion = 1.0; + #endif + + + float specular_occlusion = compute_specular_occlusion(NxV, occlusion, roughness); + + // Add diffuse and specular ambient term + ambient += diffuse_ambient * occlusion + specular_ambient * specular_occlusion; + + #endif + + // Emissive materials + #if !DEBUG_MODE + if (m.shading_model == SHADING_MODEL_EMISSIVE) { + // TODO: For emissive, use: compute_bloom_luminance() instead of a fixed value + ambient = m.basecolor * 5000.0; + } + #endif + + #if DEBUG_MODE + #if MODE_ACTIVE(OCCLUSION) + result = vec4(occlusion); + result.w = 1; + return; + #endif + + #if MODE_ACTIVE(SKY_AO) + result = vec4(sky_ao_factor); + result.w = 1; + return; + #endif + + #if MODE_ACTIVE(DIFFUSE_AMBIENT) + result = vec4((diffuse_ambient / (1 + diffuse_ambient)) * occlusion, 1); + return; + #endif + + #if MODE_ACTIVE(SPECULAR_AMBIENT) + result = vec4((specular_ambient / (1 + specular_ambient)) * specular_occlusion, 1); + return; + #endif + #endif + + vec4 scene_color = textureLod(ShadedScene, texcoord, 0); + + #if HAVE_PLUGIN(scattering) && !DEBUG_MODE + // Scattering extinction is stored in the w component of the scene texture + ambient *= scene_color.w; + #endif + + #if MODE_ACTIVE(ENVPROBE_COUNT) + // Pass through debug modes + result = texture(EnvmapAmbientDiff, texcoord); + return; + #endif + + result = vec4(scene_color.xyz + ambient, 1); +} diff --git a/rpcore/shader/apply_lights.frag.glsl b/rpcore/shader/apply_lights.frag.glsl new file mode 100644 index 0000000..a2c433c --- /dev/null +++ b/rpcore/shader/apply_lights.frag.glsl @@ -0,0 +1,121 @@ +/** + * + * RenderPipeline + * + * Copyright (c) 2014-2016 tobspr + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + */ + +#version 430 + +// This shader performs the screen space shading of all lights + +#pragma include "render_pipeline_base.inc.glsl" + +// Tell the lighting pipeline we are doing this in screen space, so gl_FragCoord +// is available. +#define IS_SCREEN_SPACE 1 + +#pragma include "includes/light_culling.inc.glsl" +#pragma include "includes/transforms.inc.glsl" +#pragma include "includes/lighting_pipeline.inc.glsl" +#pragma include "includes/gbuffer.inc.glsl" + +out vec4 result; + +uniform GBufferData GBuffer; + +// Used for velocity rendering mode +#if MODE_ACTIVE(VELOCITY) + uniform sampler2D CombinedVelocity; +#endif + +void main() { + + // Extract material properties + vec2 texcoord = get_texcoord(); + Material m = unpack_material(GBuffer); + ivec3 tile = get_lc_cell_index(ivec2(gl_FragCoord.xy), + distance(MainSceneData.camera_pos, m.position)); + + // Don't shade pixels out of the shading range + #if !DEBUG_MODE + if (tile.z >= LC_TILE_SLICES) { + result = vec4(0, 0, 0, 1); + return; + } + #endif + + // Apply all lights + result = vec4(shade_material_from_tile_buffer(m, tile), 1); + + /* + + Various debugging modes for previewing materials + + */ + + #if MODE_ACTIVE(DIFFUSE) + result.xyz = vec3(m.basecolor); + #endif + + #if MODE_ACTIVE(ROUGHNESS) + result.xyz = vec3(m.roughness); + #endif + + #if MODE_ACTIVE(SPECULAR) + + // Multiply specular on diffuse materials to make it visible + result.xyz = vec3(mix( + m.specular / 0.18, + m.specular, + m.metallic + )); + #endif + + #if MODE_ACTIVE(NORMAL) + result.xyz = vec3(abs(m.normal)); + #endif + + #if MODE_ACTIVE(METALLIC) + result.xyz = vec3(m.metallic); + #endif + + #if MODE_ACTIVE(TRANSLUCENCY) + result.xyz = vec3(m.shading_model == SHADING_MODEL_FOLIAGE ? m.shading_model_param0 : 0.0); + #endif + + #if MODE_ACTIVE(SHADING_MODEL) + result.xyz = vec3(0.1, 0.1, 0.1); + switch (m.shading_model) { + case SHADING_MODEL_FOLIAGE: result.xyz = vec3(0, 1, 0); break; + case SHADING_MODEL_CLEARCOAT: result.xyz = vec3(0, 0, 1); break; + case SHADING_MODEL_SKIN: result.xyz = vec3(1, 0, 0); break; + case SHADING_MODEL_EMISSIVE: result.xyz = vec3(1, 0, 1); break; + case SHADING_MODEL_TRANSPARENT: result.xyz = vec3(0, 1, 1); break; + } + #endif + + #if MODE_ACTIVE(VELOCITY) + result.xyz = abs(textureLod(CombinedVelocity, texcoord, 0).xyz) * 20.0; + #endif + +} diff --git a/rpcore/shader/bilateral_blur.frag.glsl b/rpcore/shader/bilateral_blur.frag.glsl new file mode 100644 index 0000000..af90d4b --- /dev/null +++ b/rpcore/shader/bilateral_blur.frag.glsl @@ -0,0 +1,92 @@ +/** + * + * RenderPipeline + * + * Copyright (c) 2014-2016 tobspr + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + */ + +#version 430 + +// This shader provides a generic blur respecting depth and normals + +#pragma optionNV (unroll all) + +#pragma include "render_pipeline_base.inc.glsl" +#pragma include "includes/gbuffer.inc.glsl" +#pragma include "includes/gaussian_weights.inc.glsl" + +uniform ivec2 blur_direction; +uniform sampler2D SourceTex; +uniform sampler2D DownscaledDepth; +uniform GBufferData GBuffer; + +uniform float pixel_stretch; + +// Can be used to only select a specific component. Currently hardcoded and unused. +#define ONLY_RED_COMPONENT 1 +#if ONLY_RED_COMPONENT + #define VALUE_TYPE float + #define SWIZLLE .x +#else + #define VALUE_TYPE vec4 + #define SWIZLLE .xyzw +#endif + +out VALUE_TYPE result; + +void main() { + vec2 texcoord = get_texcoord(); + vec2 pixel_size = 1.0 * pixel_stretch / SCREEN_SIZE; + + // Store accumulated color + VALUE_TYPE accum = VALUE_TYPE(0); + float accum_w = 0.0; + + // Amount of samples, don't forget to change the weights array in case you change this. + const int blur_size = 7; + + // Get the mid pixel normal and depth + vec3 pixel_nrm = get_gbuffer_normal(GBuffer, texcoord); + float pixel_depth = textureLod(DownscaledDepth, texcoord, 0).x; + + // Blur to the right and left + for (int i = -blur_size + 1; i < blur_size; ++i) { + vec2 offcoord = texcoord + pixel_size * i * blur_direction; + VALUE_TYPE sampled = textureLod(SourceTex, offcoord, 0) SWIZLLE; + vec3 nrm = get_gbuffer_normal(GBuffer, offcoord); + float depth = textureLod(DownscaledDepth, offcoord, 0).x; + + float weight = gaussian_weights_7[abs(i)]; // Change this if you modify the blur size + + // Weight by normal and depth + weight *= 1.0 - saturate(GET_SETTING(ao, blur_normal_factor) * + distance(nrm, pixel_nrm) * 1.0); + weight *= 1.0 - saturate(GET_SETTING(ao, blur_depth_factor) * + abs(depth - pixel_depth) * 3); + + accum += sampled * weight; + accum_w += weight; + } + + accum /= max(0.04, accum_w); + result = accum; +} diff --git a/rpcore/shader/bilateral_halfres_blur.frag.glsl b/rpcore/shader/bilateral_halfres_blur.frag.glsl new file mode 100644 index 0000000..4015964 --- /dev/null +++ b/rpcore/shader/bilateral_halfres_blur.frag.glsl @@ -0,0 +1,81 @@ +/** + * + * RenderPipeline + * + * Copyright (c) 2014-2016 tobspr + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + */ + +#version 430 + +// This shader provides a bilateral blur at half-resolution + +#pragma optionNV (unroll all) + +#pragma include "render_pipeline_base.inc.glsl" +#pragma include "includes/gbuffer.inc.glsl" +#pragma include "includes/gaussian_weights.inc.glsl" + +uniform ivec2 blur_direction; +uniform sampler2D SourceTex; +uniform GBufferData GBuffer; + +out vec4 result; + +float get_lin_z(vec2 ccoord) { + return get_linear_z_from_z(get_gbuffer_depth(GBuffer, ccoord)); +} + +void main() { + vec2 texcoord = get_half_native_texcoord(); + vec2 pixel_size = 2.0 / SCREEN_SIZE; + + // Store accumulated color + vec4 accum = vec4(0); + float accum_w = 0.0; + + // Amount of samples, don't forget to change the weights array in case you change this. + const int blur_size = 4; + + // Get the mid pixel normal and depth + vec3 pixel_nrm = get_gbuffer_normal(GBuffer, texcoord); + float pixel_depth = get_lin_z(texcoord); + + // Blur to the right + for (int i = -blur_size + 1; i < blur_size; ++i) { + vec2 offcoord = texcoord + pixel_size * i * blur_direction; + vec4 sampled = textureLod(SourceTex, offcoord, 0); + vec3 nrm = get_gbuffer_normal(GBuffer, offcoord); + float depth = get_lin_z(offcoord); + + float weight = gaussian_weights_4[abs(i)]; + weight *= 1.0 - saturate(GET_SETTING(ao, blur_normal_factor) * + distance(nrm, pixel_nrm) / 0.01); + weight *= 1.0 - saturate(GET_SETTING(ao, blur_depth_factor) * + abs(depth - pixel_depth) / 0.001); + + accum += sampled * weight; + accum_w += weight; + } + + accum /= max(0.04, accum_w); + result = accum; +} diff --git a/rpcore/shader/bilateral_upscale.frag.glsl b/rpcore/shader/bilateral_upscale.frag.glsl new file mode 100644 index 0000000..21c6534 --- /dev/null +++ b/rpcore/shader/bilateral_upscale.frag.glsl @@ -0,0 +1,96 @@ +/** + * + * RenderPipeline + * + * Copyright (c) 2014-2016 tobspr + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + */ + +#version 430 + +// Shader which upscales a half resolution image to full resolution, +// respecting the normals and depth + +#pragma optionNV (unroll all) + +#pragma include "render_pipeline_base.inc.glsl" +#pragma include "includes/gbuffer.inc.glsl" + +// x: Max depth difference, y: Max normal difference +uniform vec2 upscaleWeights; +uniform sampler2D SourceTex; +uniform GBufferData GBuffer; + +out vec4 result; + +void main() { + // Get sample coordinates + ivec2 coord = ivec2(gl_FragCoord.xy); + ivec2 bil_start_coord = get_bilateral_coord(coord); + + // Get current pixel data + float mid_depth = get_gbuffer_depth(GBuffer, coord); + vec3 mid_nrm = get_gbuffer_normal(GBuffer, coord); + + const float max_depth_diff = upscaleWeights.x; + const float max_nrm_diff = upscaleWeights.y; + + float weights = 0.0; + vec4 accum = vec4(0); + + // Controls how many other pixels should be taken into account, besides + // of the 4 direct neighbors. + const int search_radius = 0; + + // Accumulate all samples + for (int x = -search_radius; x < 2 + search_radius; ++x) { + for (int y = -search_radius; y < 2 + search_radius; ++y) { + + ivec2 source_coord = bil_start_coord + ivec2(x, y); + vec4 source_sample = texelFetch(SourceTex, source_coord, 0); + + // Check how much information those pixels share, and if it is + // enough, use that sample + float sample_depth = get_gbuffer_depth(GBuffer, source_coord * 2); + vec3 sample_nrm = get_gbuffer_normal(GBuffer, source_coord * 2); + float depth_diff = abs(sample_depth - mid_depth) / max_depth_diff; + float nrm_diff = max(0, dot(sample_nrm, mid_nrm)); + float weight = 1.0 - saturate(depth_diff); + weight *= pow(nrm_diff, 1.0 / max_nrm_diff); + + // Make sure we don't have a null-weight, but instead only a very + // small weight, so that in case no pixel matches, we still have + // data to work with. + // weight = max(1e-5, weight); + + accum += source_sample * weight; + weights += weight; + } + } + + if (weights < 1e-5) { + // When no sample was valid, take the center sample - this is still + // better than invalid pixels + result = texelFetch(SourceTex, coord / 2, 0); + } else { + result = accum / weights; + } +} diff --git a/rpcore/shader/collect_used_cells.frag.glsl b/rpcore/shader/collect_used_cells.frag.glsl new file mode 100644 index 0000000..4e1995e --- /dev/null +++ b/rpcore/shader/collect_used_cells.frag.glsl @@ -0,0 +1,59 @@ +/** + * + * RenderPipeline + * + * Copyright (c) 2014-2016 tobspr + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + */ + +#version 430 + +// Shader which iterates over the camera-space voxel grid and collects +// all cells which have been flagged into a big atomic driven list. + +#pragma optionNV (unroll all) + +#pragma include "render_pipeline_base.inc.glsl" +#pragma include "includes/light_culling.inc.glsl" + +uniform sampler2DArray FlaggedCells; +layout(r32i) uniform iimageBuffer CellListBuffer; +uniform writeonly iimage2DArray RESTRICT CellListIndices; + +void main() { + ivec2 coord = ivec2(gl_FragCoord.xy); + + // Iterate over all slices + for (int i = 0; i < LC_TILE_SLICES; ++i) { + + // Check if the cell is flagged + bool visible = texelFetch(FlaggedCells, ivec3(coord, i), 0).x > 0.5; + if (visible) { + // Append the cell and mark it + // Notice: We add 1 since the first index stores the amount + // of collected cells. + int flag_index = imageAtomicAdd(CellListBuffer, 0, 1) + 1; + int cell_data = coord.x | coord.y << 10 | i << 20; + imageStore(CellListBuffer, flag_index, ivec4(cell_data)); + imageStore(CellListIndices, ivec3(coord, i), ivec4(flag_index)); + } + } +} diff --git a/rpcore/shader/combine_velocity.frag.glsl b/rpcore/shader/combine_velocity.frag.glsl new file mode 100644 index 0000000..7d4d1e0 --- /dev/null +++ b/rpcore/shader/combine_velocity.frag.glsl @@ -0,0 +1,66 @@ +/** + * + * RenderPipeline + * + * Copyright (c) 2014-2016 tobspr + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + */ + +#version 430 + +// Combines camera and per object velocity by using the velocity of the +// closest fragment + +#pragma optionNV (unroll all) + +#define USE_GBUFFER_EXTENSIONS +#pragma include "render_pipeline_base.inc.glsl" +#pragma include "includes/gbuffer.inc.glsl" + +out vec2 result; + +void main() { + vec2 texcoord = get_texcoord(); + ivec2 coord = ivec2(gl_FragCoord.xy); + + vec3 closest = vec3(0, 0, 1); + const int filter_size = 1; + + // Take velocity of closest fragment + for (int i = -filter_size; i <= filter_size; ++i) { + for (int j = -filter_size; j <= filter_size; ++j) { + if ((i == 0 && j == 0) || (abs(i) == 2 && abs(j) == 2)) { + vec2 offcoord = texcoord + vec2(i, j) / SCREEN_SIZE; + float depth = get_depth_at(offcoord); + if (depth < closest.z) { + closest = vec3(offcoord, depth); + } + } + } + } + + // Combine camera and per object velocity. + // XXX: Most likely this is wrong. But since per-object velocity currently + // is disabled, its not an issue. + vec2 camera_velocity = get_camera_velocity(closest.xy); + vec2 per_object_velocity = get_object_velocity_at(closest.xy); + result = camera_velocity + per_object_velocity; +} diff --git a/rpcore/shader/cull_lights.frag.glsl b/rpcore/shader/cull_lights.frag.glsl new file mode 100644 index 0000000..17e8a94 --- /dev/null +++ b/rpcore/shader/cull_lights.frag.glsl @@ -0,0 +1,131 @@ +/** + * + * RenderPipeline + * + * Copyright (c) 2014-2016 tobspr + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + */ + +#version 430 + +// This shader collects the list of all lights for a given cell, sorts them +// and then writes them out as a list. + +layout(early_fragment_tests) in; + +#pragma include "render_pipeline_base.inc.glsl" +#pragma include "includes/transforms.inc.glsl" +#pragma include "includes/light_culling.inc.glsl" +#pragma include "includes/light_data.inc.glsl" +#pragma include "includes/light_classification.inc.glsl" + +uniform isamplerBuffer CellListBuffer; +uniform usamplerBuffer FrustumLights; +uniform isamplerBuffer FrustumLightsCount; + +uniform writeonly uimageBuffer PerCellLightsBuffer; +layout(r32i) uniform iimageBuffer PerCellLightCountsBuffer; + +uniform samplerBuffer AllLightsData; + +void main() { + + ivec2 coord = ivec2(gl_FragCoord.xy); + + int thread_id = (coord.x + coord.y * LC_CULLING_SLICE_WIDTH); + int local_offset = thread_id % LC_CULL_THREADS; + + // Find the index of the cell we are about to process + int idx = 1 + thread_id / LC_CULL_THREADS; + int num_total_cells = texelFetch(CellListBuffer, 0).x; + ivec2 precompute_size = MainSceneData.lc_tile_count; + + // If we found no remaining cell, we are done, so just return and hope for + // good coherency. + if (idx > num_total_cells) { + return; + } + + // Fetch the cell data, this contains the cells position + int packed_cell_data = texelFetch(CellListBuffer, idx).x; + int cell_x, cell_y, cell_slice; + unpack_cell_data(packed_cell_data, cell_x, cell_y, cell_slice); + + // Amount to increment the minimum and maximum distance of the slice. This + // avoids false negatives in culling. + const float distance_bias = 0.05; + + // Find the tiles minimum and maximum distance + float min_distance = get_distance_from_slice(cell_slice) - distance_bias; + float max_distance = get_distance_from_slice(cell_slice + 1) + distance_bias; + + // Get the offset in the per-cell light list + int storage_offs = LC_MAX_LIGHTS_PER_CELL * idx; + int num_rendered_lights = 0; + + // Compute sample directions + vec3 local_ray_dirs[num_raydirs] = get_raydirs(cell_x, cell_y, precompute_size); + + // Get amount of visible lights in frustum + int max_frustum_lights = texelFetch(FrustumLightsCount, 0).x; + + // Cull all lights + for (int i = local_offset; + i < max_frustum_lights && num_rendered_lights < LC_MAX_LIGHTS_PER_CELL; + i += LC_CULL_THREADS) { + + int light_index = int(texelFetch(FrustumLights, i).x); + + // Fetch data of current light + LightData light_data = read_light_data(AllLightsData, light_index); + + // Get Light position and project it to view space + vec3 light_pos = get_light_position(light_data); + vec4 light_pos_view = MainSceneData.view_mat_z_up * vec4(light_pos, 1); + + bool visible = false; + + // Get a sphere encapsulating the light and cull against that + Sphere sphere = get_representative_sphere(light_data); + + // XXX: This prevents invalid light culling for very distant small lights. + // Should find a better solution for this! + sphere.radius *= max(1.0, length(light_pos_view.xyz) / 200.0); + + for (int k = 0; k < num_raydirs; ++k) { + visible = visible || viewspace_ray_sphere_distance_intersection( + sphere, local_ray_dirs[k], min_distance, max_distance); + } + + // Uncomment this to see if the culling produces any issues + // visible = true; + + // Write the light to the light buffer + if (visible) { + + // Add one since the first element is the counter storing the total count + int num_lights = imageAtomicAdd(PerCellLightCountsBuffer, idx, 1).x; + imageStore(PerCellLightsBuffer, storage_offs + num_lights, uvec4(light_index)); + + num_rendered_lights = num_lights; + } + } +} diff --git a/rpcore/shader/default_gui_shader.vert.glsl b/rpcore/shader/default_gui_shader.vert.glsl new file mode 100644 index 0000000..8d24439 --- /dev/null +++ b/rpcore/shader/default_gui_shader.vert.glsl @@ -0,0 +1,38 @@ +/** + * + * RenderPipeline + * + * Copyright (c) 2014-2016 tobspr + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + */ + +#version 430 + +in vec4 p3d_Vertex; +in vec2 p3d_MultiTexCoord0; +out vec2 texcoord; + +uniform mat4 p3d_ModelViewProjectionMatrix; + +void main() { + texcoord = p3d_MultiTexCoord0; + gl_Position = p3d_ModelViewProjectionMatrix * p3d_Vertex; +} diff --git a/rpcore/shader/default_post_process.vert.glsl b/rpcore/shader/default_post_process.vert.glsl new file mode 100644 index 0000000..a820c93 --- /dev/null +++ b/rpcore/shader/default_post_process.vert.glsl @@ -0,0 +1,32 @@ +/** + * + * RenderPipeline + * + * Copyright (c) 2014-2016 tobspr + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + */ + +#version 430 +in vec4 p3d_Vertex; + +void main() { + gl_Position = vec4(p3d_Vertex.xz, 0, 1); +} diff --git a/rpcore/shader/default_post_process_instanced.vert.glsl b/rpcore/shader/default_post_process_instanced.vert.glsl new file mode 100644 index 0000000..6deecf0 --- /dev/null +++ b/rpcore/shader/default_post_process_instanced.vert.glsl @@ -0,0 +1,35 @@ +/** + * + * RenderPipeline + * + * Copyright (c) 2014-2016 tobspr + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + */ + +#version 430 + +in vec4 p3d_Vertex; +flat out int instance_id; + +void main() { + gl_Position = vec4(p3d_Vertex.xz, 0, 1); + instance_id = gl_InstanceID; +} diff --git a/rpcore/shader/downscale_depth.frag.glsl b/rpcore/shader/downscale_depth.frag.glsl new file mode 100644 index 0000000..c1b9b95 --- /dev/null +++ b/rpcore/shader/downscale_depth.frag.glsl @@ -0,0 +1,39 @@ +/** + * + * RenderPipeline + * + * Copyright (c) 2014-2016 tobspr + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + */ + +#version 430 + +#define USE_GBUFFER_EXTENSIONS +#pragma include "render_pipeline_base.inc.glsl" +#pragma include "includes/gbuffer.inc.glsl" +#pragma include "includes/transforms.inc.glsl" + +out float result; + +void main() { + ivec2 coord = ivec2(gl_FragCoord.xy); + result = get_linear_z_from_z(get_depth_at(coord)); +} diff --git a/rpcore/shader/final_present_stage.frag.glsl b/rpcore/shader/final_present_stage.frag.glsl new file mode 100644 index 0000000..607b969 --- /dev/null +++ b/rpcore/shader/final_present_stage.frag.glsl @@ -0,0 +1,61 @@ +/** + * + * RenderPipeline + * + * Copyright (c) 2014-2016 tobspr + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + */ + +#version 430 + +#pragma include "render_pipeline_base.inc.glsl" +#pragma include "includes/color_spaces.inc.glsl" + +uniform sampler2D SourceTex; +out vec4 result; + +// This shader just passes through the input texture + +void main() { + vec2 texcoord = (ivec2(gl_FragCoord.xy) + 0.5) / NATIVE_SCREEN_SIZE; + result = vec4(textureLod(SourceTex, texcoord, 0).xyz, 1); + + #if SPECIAL_MODE_ACTIVE(LUMINANCE) + + // Luminance debug mode, too bright pixels get red, too dark pixels get blue, + // rest stays green + + vec3 color = textureLod(SourceTex, texcoord, 0).xyz; + float luminance = get_luminance(color); + + vec3 color_ok = vec3(0, 1, 0); + vec3 color_too_bright = vec3(1, 0, 0); + vec3 color_too_dark = vec3(0, 0, 1); + + const float max_brightness = 0.7; + const float max_darkness = 0.3; + + color = mix(color_ok, color_too_bright, saturate(5.0 * (luminance - max_brightness))); + color = mix(color, color_too_dark, saturate(5.0 * (max_darkness - luminance))); + + result.xyz = color; + #endif +} diff --git a/rpcore/shader/final_stage.frag.glsl b/rpcore/shader/final_stage.frag.glsl new file mode 100644 index 0000000..c916c8e --- /dev/null +++ b/rpcore/shader/final_stage.frag.glsl @@ -0,0 +1,55 @@ +/** + * + * RenderPipeline + * + * Copyright (c) 2014-2016 tobspr + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + */ + +#version 430 + +#pragma include "render_pipeline_base.inc.glsl" +#pragma include "includes/noise.inc.glsl" +#pragma include "includes/color_spaces.inc.glsl" + +uniform sampler2D ShadedScene; +out vec4 result; + +void main() { + vec2 texcoord = get_texcoord(); + + // Fetch the current's scene color + vec3 scene_color = textureLod(ShadedScene, texcoord, 0).xyz; + + #if !DEBUG_MODE && !HAVE_PLUGIN(color_correction) + // Do a simple sRGB correction + scene_color = rgb_to_srgb(scene_color); + #endif + + // Apply dithering to prevent banding, since we are converting from 16 bit + // precision to 8 bit precision here + #if !REFERENCE_MODE + vec3 dither = (rand_rgb(texcoord) + rand_rgb(texcoord + 0.5787)) * 0.5 - 0.4; + scene_color += dither / 128.0; + #endif + + result = vec4(scene_color, 1); +} diff --git a/rpcore/shader/flag_used_cells.frag.glsl b/rpcore/shader/flag_used_cells.frag.glsl new file mode 100644 index 0000000..2ebabe4 --- /dev/null +++ b/rpcore/shader/flag_used_cells.frag.glsl @@ -0,0 +1,50 @@ +/** + * + * RenderPipeline + * + * Copyright (c) 2014-2016 tobspr + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + */ + +#version 430 + +#pragma include "render_pipeline_base.inc.glsl" +#pragma include "includes/light_culling.inc.glsl" +#pragma include "includes/transforms.inc.glsl" + +#define USE_GBUFFER_EXTENSIONS 1 +#pragma include "includes/gbuffer.inc.glsl" + +uniform writeonly image2DArray RESTRICT cellGridFlags; + +void main() { + vec2 texcoord = get_texcoord(); + + // Get the distance to the camera + vec3 surf_pos = get_world_pos_at(texcoord); + float surf_dist = distance(MainSceneData.camera_pos, surf_pos); + + // Find the affected cell + ivec3 tile = get_lc_cell_index(ivec2(gl_FragCoord.xy), surf_dist); + + // Mark the cell as used + imageStore(cellGridFlags, tile, vec4(1)); +} diff --git a/rpcore/shader/fps_chart.compute.glsl b/rpcore/shader/fps_chart.compute.glsl new file mode 100644 index 0000000..d3a968a --- /dev/null +++ b/rpcore/shader/fps_chart.compute.glsl @@ -0,0 +1,73 @@ +/** + * + * RenderPipeline + * + * Copyright (c) 2014-2016 tobspr + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + */ + +#version 430 + +#pragma include "render_pipeline_base.inc.glsl" + +#pragma optionNV (unroll all) + +layout(local_size_x = 10, local_size_y = 4, local_size_z = 1) in; + +uniform writeonly image2D RESTRICT DestTex; +uniform samplerBuffer FPSValues; +uniform int index; +uniform float maxMs; + +void main() { + + // TODO: Might make this an input + const ivec2 widget_size = ivec2(250, 120); + ivec2 coord = ivec2(gl_GlobalInvocationID.xy); + + // Store the current pixels color + vec4 color = vec4(0); + + int buffer_offset = coord.x + index; + + // Make sure the value does not get negative + buffer_offset += 10 * widget_size.x; + buffer_offset = buffer_offset % widget_size.x; + + float ms_value = texelFetch(FPSValues, buffer_offset).x; + float prev_ms_value = texelFetch( + FPSValues, (buffer_offset - 1 + widget_size.x) % widget_size.x).x; + + int ms_pixel = int(ms_value / maxMs * widget_size.y); + int prev_ms_pixel = int(prev_ms_value / maxMs * widget_size.y); + + if (coord.y >= min(ms_pixel, prev_ms_pixel) && + coord.y <= max(ms_pixel, prev_ms_pixel)) { + color = vec4(0, 1, 0, 1); + } + + // Axis + if (coord.x == 0 || coord.y == 0) { + color = vec4(1); + } + + imageStore(DestTex, coord, color); +} diff --git a/rpcore/shader/fps_chart_update.compute.glsl b/rpcore/shader/fps_chart_update.compute.glsl new file mode 100644 index 0000000..cdcf86b --- /dev/null +++ b/rpcore/shader/fps_chart_update.compute.glsl @@ -0,0 +1,43 @@ +/** + * + * RenderPipeline + * + * Copyright (c) 2014-2016 tobspr + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + */ + +#version 430 + +#pragma include "render_pipeline_base.inc.glsl" + +#pragma optionNV (unroll all) + +layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in; + +// Stores the current FPS value in the buffer + +uniform writeonly imageBuffer RESTRICT DestTex; +uniform int index; +uniform float currentData; + +void main() { + imageStore(DestTex, index, vec4(currentData)); +} diff --git a/rpcore/shader/group_lights.frag.glsl b/rpcore/shader/group_lights.frag.glsl new file mode 100644 index 0000000..1766950 --- /dev/null +++ b/rpcore/shader/group_lights.frag.glsl @@ -0,0 +1,105 @@ +/** + * + * RenderPipeline + * + * Copyright (c) 2014-2016 tobspr + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + */ + +#version 430 + +// This shader collects the list of all lights for a given cell, sorts them +// and then writes them out as a list. + +layout(early_fragment_tests) in; + +#pragma include "render_pipeline_base.inc.glsl" +#pragma include "includes/transforms.inc.glsl" +#pragma include "includes/light_culling.inc.glsl" +#pragma include "includes/light_data.inc.glsl" +#pragma include "includes/light_classification.inc.glsl" + +uniform isamplerBuffer CellListBuffer; +uniform usamplerBuffer PerCellLightsBuffer; +layout(r32i) uniform iimageBuffer PerCellLightCountsBuffer; +uniform writeonly uimageBuffer RESTRICT GroupedCellLightsBuffer; +uniform writeonly uimageBuffer RESTRICT GroupedPerCellLightsCountBuffer; + +uniform samplerBuffer AllLightsData; +uniform int maxLightIndex; + +void main() { + ivec2 coord = ivec2(gl_FragCoord.xy); + + // Find the index of the cell we are about to process + int idx = 1 + coord.x + coord.y * LC_CULLING_SLICE_WIDTH; + int num_total_cells = texelFetch(CellListBuffer, 0).x; + + // If we found no remaining cell, we are done, so just return and hope for + // good coherency. + if (idx > num_total_cells) { + return; + } + + // Get the offset in the per-cell culled light list + int data_offset = LC_MAX_LIGHTS_PER_CELL * idx; // Culled lights offset + int dest_offset = LC_MAX_LIGHTS_PER_CELL * idx; // Destination offset + + // Offset into the per-cell culled light counts + int cell_lights_offset = idx * (1 + LIGHT_CLS_COUNT); + + // Get the amount of (unsorted) lights for this cell + int num_culled_lights = imageLoad(PerCellLightCountsBuffer, idx).x; + imageStore(PerCellLightCountsBuffer, idx, ivec4(0)); + + num_culled_lights = min(LC_MAX_LIGHTS_PER_CELL, num_culled_lights); + int num_processed_lights = 0; + + // Fetch the data of all light classes + for (int light_class = 0; light_class < LIGHT_CLS_COUNT; ++light_class) { + int light_count = 0; + + // Iterate over the list of culled lights, and store all lights which + // belong to this class + for (int i = 0; i < num_culled_lights; ++i) { + // XXX: Have to use int, because of stupid OpenGL specification, + // indexes into buffers are ints and not unsigned ints. + int light_index = int(texelFetch(PerCellLightsBuffer, data_offset + i).x); + int light_type = read_light_type(AllLightsData, light_index); + bool casts_shadows = read_casts_shadows(AllLightsData, light_index); + + // In case the culled light is of the same type as the type we are looking for + if (classify_light(light_type, casts_shadows) == light_class) { + imageStore( + GroupedCellLightsBuffer, + dest_offset + num_processed_lights, uvec4(light_index)); + ++light_count; + ++num_processed_lights; + } + } + + // Store the light class count + imageStore(GroupedPerCellLightsCountBuffer, cell_lights_offset + 1 + light_class, uvec4(light_count)); + } + + // Store the total light count to be able to early out + imageStore(GroupedPerCellLightsCountBuffer, cell_lights_offset, uvec4(num_processed_lights)); +} diff --git a/rpcore/shader/ibl/cubemap_diffuse.frag.glsl b/rpcore/shader/ibl/cubemap_diffuse.frag.glsl new file mode 100644 index 0000000..72e4462 --- /dev/null +++ b/rpcore/shader/ibl/cubemap_diffuse.frag.glsl @@ -0,0 +1,67 @@ +/** + * + * RenderPipeline + * + * Copyright (c) 2014-2016 tobspr + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + */ + +#version 430 + +#pragma include "render_pipeline_base.inc.glsl" +#pragma include "includes/importance_sampling.inc.glsl" +#pragma include "includes/poisson_disk.inc.glsl" +#pragma include "includes/noise.inc.glsl" + +#pragma optionNV (unroll all) + +uniform samplerCube SourceCubemap; +uniform writeonly imageCube RESTRICT DestCubemap; +uniform int cubeSize; + +void main() { + const int sample_count = 64; + + // Get cubemap coordinate + ivec2 coord = ivec2(gl_FragCoord.xy); + ivec2 clamped_coord; int face; + vec3 n = texcoord_to_cubemap(cubeSize, coord, clamped_coord, face); + + // Convert normal to spherical coordinates + float theta, phi; + vector_to_spherical(n, theta, phi); + + // Get tangent and binormal + vec3 tangent, binormal; + find_arbitrary_tangent(n, tangent, binormal); + + vec3 accum = vec3(0); + for (int i = 0; i < sample_count; ++i) + { + vec2 xi = hammersley(i, sample_count); + vec3 offset = importance_sample_lambert(xi); + offset = normalize(tangent * offset.x + binormal * offset.y + n * offset.z); + accum += textureLod(SourceCubemap, offset, 0).xyz; + } + + accum /= sample_count; + imageStore(DestCubemap, ivec3(clamped_coord, face), vec4(accum, 1)); +} diff --git a/rpcore/shader/ibl/cubemap_diffuse_filter.frag.glsl b/rpcore/shader/ibl/cubemap_diffuse_filter.frag.glsl new file mode 100644 index 0000000..d3c0029 --- /dev/null +++ b/rpcore/shader/ibl/cubemap_diffuse_filter.frag.glsl @@ -0,0 +1,64 @@ +/** + * + * RenderPipeline + * + * Copyright (c) 2014-2016 tobspr + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + */ + +#version 430 + +// Filters the generated noisy diffuse cubemap to make it smooth + +#pragma include "render_pipeline_base.inc.glsl" +#pragma include "includes/poisson_disk.inc.glsl" + +#pragma optionNV (unroll all) + +uniform samplerCube SourceCubemap; +uniform writeonly imageCube RESTRICT DestCubemap; +uniform int cubeSize; + +void main() { + const int num_samples = 64; + const float filter_radius = 0.5; + + // Get cubemap coordinate + ivec2 coord = ivec2(gl_FragCoord.xy); + ivec2 clamped_coord; int face; + vec3 n = texcoord_to_cubemap(cubeSize, coord, clamped_coord, face); + + // Get tangent and binormal + vec3 tangent, binormal; + find_arbitrary_tangent(n, tangent, binormal); + + vec3 accum = vec3(0.0); + for (int i = 0; i < num_samples; ++i) { + vec2 offset = poisson_2D_64[i]; + vec3 sample_vec = normalize(n + + filter_radius * offset.x * tangent + + filter_radius * offset.y * binormal); + accum += textureLod(SourceCubemap, sample_vec, 0).xyz; + } + accum /= num_samples; + + imageStore(DestCubemap, ivec3(clamped_coord, face), vec4(accum, 1.0)); +} diff --git a/rpcore/shader/ibl/cubemap_specular_filter.frag.glsl b/rpcore/shader/ibl/cubemap_specular_filter.frag.glsl new file mode 100644 index 0000000..95c6d78 --- /dev/null +++ b/rpcore/shader/ibl/cubemap_specular_filter.frag.glsl @@ -0,0 +1,65 @@ +/** + * + * RenderPipeline + * + * Copyright (c) 2014-2016 tobspr + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + */ + +#version 430 + +#pragma include "render_pipeline_base.inc.glsl" +#pragma include "includes/poisson_disk.inc.glsl" + +#pragma optionNV (unroll all) + +uniform samplerCube SourceTex; +uniform writeonly imageCube RESTRICT DestMipmap; +uniform int currentMip; + +void main() { + + const int num_samples = 12; + + // Get cubemap coordinate + int texsize = textureSize(SourceTex, currentMip).x; + ivec2 coord = ivec2(gl_FragCoord.xy); + ivec2 clamped_coord; int face; + vec3 n = texcoord_to_cubemap(texsize, coord, clamped_coord, face); + + // Get tangent and binormal + vec3 tangent, binormal; + find_arbitrary_tangent(n, tangent, binormal); + + const float filter_radius = 0.00 + currentMip * 0.06; + + vec3 accum = vec3(0.0); + for (int i = 0; i < num_samples; ++i) { + vec2 offset = poisson_2D_12[i]; + vec3 sample_vec = normalize(n + + filter_radius * offset.x * tangent + + filter_radius * offset.y * binormal); + accum += textureLod(SourceTex, sample_vec, currentMip).xyz; + } + + accum /= num_samples; + imageStore(DestMipmap, ivec3(clamped_coord, face), vec4(accum, 1.0)); +} diff --git a/rpcore/shader/ibl/cubemap_specular_filter_first.frag.glsl b/rpcore/shader/ibl/cubemap_specular_filter_first.frag.glsl new file mode 100644 index 0000000..b6e7400 --- /dev/null +++ b/rpcore/shader/ibl/cubemap_specular_filter_first.frag.glsl @@ -0,0 +1,66 @@ +/** + * + * RenderPipeline + * + * Copyright (c) 2014-2016 tobspr + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + */ + +#version 430 + +#pragma include "render_pipeline_base.inc.glsl" +#pragma include "includes/poisson_disk.inc.glsl" +#pragma include "includes/noise.inc.glsl" + +#pragma optionNV (unroll all) + +uniform samplerCube SourceTex; +uniform writeonly imageCube RESTRICT DestMipmap; +uniform int currentMip; + +void main() { + + const int num_samples = 12; + + // Get cubemap coordinate + int texsize = textureSize(SourceTex, currentMip).x; + ivec2 coord = ivec2(gl_FragCoord.xy); + ivec2 clamped_coord; int face; + vec3 n = texcoord_to_cubemap(texsize, coord, clamped_coord, face); + + // Get tangent and binormal + vec3 tangent, binormal; + find_arbitrary_tangent(n, tangent, binormal); + + const float filter_radius = 0.05; + vec3 accum = vec3(0.0); + for (int i = 0; i < num_samples; ++i) { + vec2 offset = poisson_2D_12[i]; + vec3 sample_vec = normalize(n + + filter_radius * offset.x * tangent + + filter_radius * offset.y * binormal + + (rand(vec2(coord + 23 * i))-0.5) * 0.01); + accum += textureLod(SourceTex, sample_vec, currentMip).xyz; + } + + accum /= num_samples; + imageStore(DestMipmap, ivec3(clamped_coord, face), vec4(accum, 1.0)); +} diff --git a/rpcore/shader/ibl/cubemap_specular_prefilter.frag.glsl b/rpcore/shader/ibl/cubemap_specular_prefilter.frag.glsl new file mode 100644 index 0000000..c580324 --- /dev/null +++ b/rpcore/shader/ibl/cubemap_specular_prefilter.frag.glsl @@ -0,0 +1,70 @@ +/** + * + * RenderPipeline + * + * Copyright (c) 2014-2016 tobspr + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + */ + +#version 430 + +#pragma include "render_pipeline_base.inc.glsl" +#pragma include "includes/importance_sampling.inc.glsl" +#pragma include "includes/poisson_disk.inc.glsl" +#pragma include "includes/brdf.inc.glsl" +#pragma include "includes/noise.inc.glsl" + +#pragma optionNV (unroll all) + +uniform int currentMip; +uniform samplerCube SourceTex; +layout(r11f_g11f_b10f) uniform imageCube RESTRICT DestMipmap; + +void main() { + const int num_samples = 64; + + // Get cubemap coordinate + int texsize = imageSize(DestMipmap).x; + ivec2 coord = ivec2(gl_FragCoord.xy); + ivec2 clamped_coord; int face; + vec3 n = texcoord_to_cubemap(texsize, coord, clamped_coord, face); + + // Determine target roughenss + float sample_roughness = 1e-10 + (currentMip + 1) / 7.0 - 0.04; + + vec3 tangent, binormal; + find_arbitrary_tangent(n, tangent, binormal); + + vec3 accum = vec3(0); + float accum_weights = 0.0; + + // Importance sampling + for (int i = 0; i < num_samples; ++i) { + vec2 Xi = hammersley(i, num_samples); + vec3 h = importance_sample_ggx(Xi, sample_roughness); + h = normalize(h.x * tangent + h.y * binormal + h.z * n); + accum += textureLod(SourceTex, h, 1).xyz; + } + + // Energy conservation + accum /= num_samples; + imageStore(DestMipmap, ivec3(clamped_coord, face), vec4(accum, 1.0)); +} diff --git a/rpcore/shader/ibl/cubemap_specular_prefilter_first.frag.glsl b/rpcore/shader/ibl/cubemap_specular_prefilter_first.frag.glsl new file mode 100644 index 0000000..e22ffca --- /dev/null +++ b/rpcore/shader/ibl/cubemap_specular_prefilter_first.frag.glsl @@ -0,0 +1,50 @@ +/** + * + * RenderPipeline + * + * Copyright (c) 2014-2016 tobspr + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + */ + +#version 430 + +#pragma include "render_pipeline_base.inc.glsl" +#pragma include "includes/importance_sampling.inc.glsl" +#pragma include "includes/poisson_disk.inc.glsl" +#pragma include "includes/brdf.inc.glsl" + +#pragma optionNV (unroll all) + +uniform int currentMip; +uniform samplerCube SourceTex; +layout(r11f_g11f_b10f) uniform imageCube RESTRICT DestMipmap; + +void main() { + const int num_samples = 0; + + // Get cubemap coordinate + int texsize = imageSize(DestMipmap).x; + ivec2 coord = ivec2(gl_FragCoord.xy); + ivec2 clamped_coord; int face; + vec3 n = texcoord_to_cubemap(texsize, coord, clamped_coord, face); + vec3 accum = textureLod(SourceTex, n, 0).xyz; + imageStore(DestMipmap, ivec3(clamped_coord, face), vec4(accum, 1.0)); +} diff --git a/rpcore/shader/includes/brdf.inc.glsl b/rpcore/shader/includes/brdf.inc.glsl new file mode 100644 index 0000000..ffb469a --- /dev/null +++ b/rpcore/shader/includes/brdf.inc.glsl @@ -0,0 +1,354 @@ +/** + * + * RenderPipeline + * + * Copyright (c) 2014-2016 tobspr + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + */ + +#pragma once + +#pragma include "render_pipeline_base.inc.glsl" +#pragma include "includes/material.inc.glsl" +#pragma include "includes/color_spaces.inc.glsl" + + +/* + + BRDFs from: + http://www.frostbite.com/wp-content/uploads/2014/11/course_notes_moving_frostbite_to_pbr.pdf + + Also from: + http://www.trentreed.net/blog/physically-based-shading-and-image-based-lighting/ + + Also inspired by the implementation in Disneys BRDF Explorer: + http://www.disneyanimation.com/technology/brdf.html + +*/ + + +// Lambert BRDF +float brdf_lambert() { + return ONE_BY_PI; +} + +// Schlicks approximation to fresnel +vec3 brdf_schlick_fresnel(vec3 specular, float f90, float VxH) +{ + // Fast pow, proposed in + // http://blog.selfshadow.com/publications/s2013-shading-course/karis/s2013_pbs_epic_notes_v2.pdf + return mix(specular, vec3(f90), pow(2, (-5.55473 * VxH - 6.98316) * VxH)); + + // Regular pow + // return mix(specular, vec3(f90), pow( 1.0 - VxH, 5.0)); +} + +vec3 brdf_schlick_fresnel(vec3 specular, float VxH) +{ + return brdf_schlick_fresnel(specular, 1.0, VxH); +} + +// BRDF Proposed by Burley +float brdf_disney_diffuse(float NxV, float NxL, float LxH, float roughness) { + + // In case of squared roughness: + float lin_roughness = roughness; + float energy_bias = 0.5 * lin_roughness; + float energy_factor = mix(1.0, 1.0 / 1.51, lin_roughness); + float fd90 = energy_bias + 2.0 * LxH * LxH * lin_roughness; + vec3 f0 = vec3(1); + float light_scatter = brdf_schlick_fresnel(f0, fd90, NxL).x; + float view_scatter = brdf_schlick_fresnel(f0, fd90, NxV).x; + return light_scatter * view_scatter * energy_factor / M_PI; +} + +/* Distribution functions */ +float brdf_distribution_blinn_phong(float NxH, float roughness) { + float r_sq = roughness * roughness; + float inv_r = 1.0 / r_sq; + return inv_r * ONE_BY_PI * pow(NxH, fma(inv_r, 2.0, -2.0)); +} + +float brdf_distribution_beckmann(float NxH, float roughness) { + float r_sq = roughness * roughness; + float nxh_sq = NxH * NxH; + return exp((nxh_sq - 1.0) / (r_sq * nxh_sq)) / (M_PI * r_sq * nxh_sq * nxh_sq); +} + +float brdf_distribution_ggx(float NxH, float alpha) { + float r_square = alpha * alpha; + float f = (NxH * r_square - NxH) * NxH + 1.0; + return r_square / (f * f); +} + +float brdf_distribution_exponential(float NxH, float roughness) { + float r_sq = roughness * roughness; + float d = exp(-acos(NxH) / roughness); // TODO: optimize + return d * (1.0 + 4.0 * r_sq) / (2.0 * r_sq * + (1.0 + exp(-(M_PI / (2.0 * roughness)))) * M_PI); +} + +float brdf_distribution_gaussian(float NxH, float roughness) { + float theta = acos(NxH); // TODO: optimize + return exp(-theta * theta / (roughness * roughness)); +} + +float brdf_distribution_trowbridge_reitz(float NxH, float roughness) { + float r_sq = roughness * roughness; + float f = r_sq / (NxH * NxH * (r_sq - 1.0) + 1.0); + return f * f * ONE_BY_PI / r_sq; +} + + +/* Visibility functions */ +float brdf_visibility_implicit(float NxL, float NxV) { + return NxL * NxV; +} + +float brdf_visibility_neumann(float NxV, float NxL) { + return NxL * NxV / max(1e-7, max(NxL, NxV)); +} + +float brdf_visibility_cook_torrance(float NxL, float NxV, float NxH, float VxH) { + float nh_by_vh = 2.0 * NxH / VxH; + float eq_nv = NxV * nh_by_vh; + float eq_nl = NxL * nh_by_vh; + return min(1.0, min(eq_nv, eq_nl)); +} + +float brdf_visibility_smith(float NxL, float NxV, float roughness) { + float r_sq = roughness * roughness; + float vis_v = NxL * (NxV * (1 - r_sq) + r_sq); + float vis_l = NxV * (NxL * (1 - r_sq) + r_sq); + return 0.5 / (vis_v + vis_l); +} + +// Helper function for the schlick visibility +float _schlick_g(float NxL, float roughness_sq) { + float k = sqrt(2.0 * roughness_sq * ONE_BY_PI); + return NxL > 0.0 ? NxL / (NxL - k * NxL + k) : 0.0; +} + +float brdf_visibility_schlick(float NxV, float NxL, float roughness) { + float r_sq = roughness * roughness; + return _schlick_g(NxL, r_sq) * _schlick_g(NxV, r_sq); +} + + +float brdf_visibility_smith_ggx(float NxL, float NxV, float roughness) { + float alpha = roughness * roughness; + float lambda_GGXV = NxL * sqrt((-NxV * alpha + NxV) * NxV + alpha); + float lambda_GGXL = NxV * sqrt((-NxL * alpha + NxL) * NxL + alpha); + return 0.5 / (lambda_GGXV + lambda_GGXL) * NxL; +} + + +/* Fresnel functions */ + +float ior_to_specular(float ior) { + float f0 = (ior - AIR_IOR) / (ior + AIR_IOR); + // Clamp between ior of 1 and 2.5 + return clamp(f0 * f0, 0.0, 0.18); +} + +float brdf_fresnel_cook_torrance(float LxH, float roughness, float ior) { + float g = sqrt(max(0, ior * ior + LxH * LxH - 1.0)); + float gpc = g + LxH; + float gmc = g - LxH; + return 0.5 * pow(gmc, 2) / pow(gpc, 2) * (1 + pow(LxH * gpc - 1, 2) / + pow(LxH * gmc + 1, 2)); +} + +float brdf_fresnel_schlick_f0(float LxH, float roughness, float f0) { + return f0 + (1 - f0) * pow(2, (-5.55473 * LxH - 6.98316) * LxH); +} + +float brdf_fresnel_schlick(float LxH, float roughness, float ior) { + float f0 = ior_to_specular(ior); + return brdf_fresnel_schlick_f0(LxH, roughness, f0); +} + +// Exact fresnel, can be slow. +float brdf_fresnel_exact(float cos_theta) { + const float eta = 1.51; + + float scale = 1 / eta; + float cos_theta_t_sqr = 1 - (1 - cos_theta * cos_theta) * (scale * scale); + + if (cos_theta_t_sqr <= 0.0) + return 1.0; + + float cos_theta_i = abs(cos_theta); + float cos_theta_t = sqrt(cos_theta_t_sqr); + + float Rs = (cos_theta_i - eta * cos_theta_t) / (cos_theta_i + eta * cos_theta_t); + float Rp = (eta * cos_theta_i - cos_theta_t) / (eta * cos_theta_i + cos_theta_t); + + return 0.5 * (Rs * Rs + Rp * Rp); +} + +// Exact conductor fresnel, can be slow, also only single channel +float brdf_fresnel_conductor_exact(float cos_theta_i, float eta, float k) { + /* Modified from "Optics" by K.D. Moeller, University Science Books, 1988 */ + float cosThetaI2 = cos_theta_i * cos_theta_i; + float sinThetaI2 = 1 - cosThetaI2; + float sinThetaI4 = sinThetaI2 * sinThetaI2; + + float temp1 = eta * eta - k * k - sinThetaI2; + float a2pb2 = sqrt(temp1 * temp1 + 4 * k * k * eta * eta); + float a = sqrt(0.5f * (a2pb2 + temp1)); + + float term1 = a2pb2 + cosThetaI2; + float term2 = 2 * a * cos_theta_i; + + float Rs2 = (term1 - term2) / (term1 + term2); + + float term3 = a2pb2 * cosThetaI2 + sinThetaI4; + float term4 = term2 * sinThetaI2; + + float Rp2 = Rs2 * (term3 - term4) / (term3 + term4); + return 0.5f * (Rp2 + Rs2); +} + + +// Approximation proposed in +// http://sirkan.iit.bme.hu/~szirmay/fresnel.pdf +vec3 brdf_fresnel_conductor_approx(float cos_theta, vec3 n, vec3 k) { + vec3 k_sq = k * k; + vec3 term0 = square(n - 1.0) + 4 * n * pow(1 - cos_theta, 5.0) + k_sq; + vec3 term1 = square(n + 1.0) + k_sq; + return term0 / term1; +} + +// Diffuse BRDF +float brdf_diffuse(float NxV, float NxL, float LxH, float VxH, float roughness) { + + // Choose one: + return brdf_lambert(); + // return brdf_disney_diffuse(NxV, NxL, LxH, roughness); +} + + +// Distribution +float brdf_distribution(float NxH, float roughness) +{ + NxH = max(1e-5, NxH); + roughness = max(0.0019, roughness); + + // Choose one: + // return brdf_distribution_blinn_phong(NxH, roughness); + // return brdf_distribution_beckmann(NxH, roughness); + // return brdf_distribution_exponential(NxH, roughness); + // return brdf_distribution_gaussian(NxH, roughness); + return brdf_distribution_trowbridge_reitz(NxH, roughness); + // return brdf_distribution_ggx(NxH, roughness); +} + +// Geometric Visibility +float brdf_visibility(float NxL, float NxV, float NxH, float VxH, float roughness) { + + // Choose one: + // float vis = brdf_visibility_neumann(NxV, NxL); + float vis = brdf_visibility_implicit(NxV, NxL); + // float vis = brdf_visibility_smith_ggx(NxV, NxL, roughness); + // float vis = brdf_visibility_schlick(NxV, NxL, roughness); + // float vis = brdf_visibility_cook_torrance(NxL, NxV, NxH, VxH); + // float vis = brdf_visibility_smith(NxL, NxV, roughness); + + + return vis; +} + +// Fresnel +float brdf_fresnel(float LxH, float roughness) { + // Default index of refraction + // TODO: Maybe make this configurable? + const float ior = 1.2; + + return brdf_fresnel_schlick(LxH, roughness, ior); + // return brdf_fresnel_cook_torrance(LxH, roughness, ior); +} + + +/* Material Functions */ +vec3 get_material_f0(Material m) { + // Material specular is already in the 0 .. 0.08 range + return mix(vec3(m.specular), m.basecolor, m.metallic); +} + + +// Returns a reflection vector, bent into the normal direction +vec3 get_reflection_vector(Material m, vec3 view_vector) { + float roughness = m.shading_model == SHADING_MODEL_CLEARCOAT ? + CLEARCOAT_ROUGHNESS : m.roughness; + vec3 reflected_dir = reflect(view_vector, m.normal); + // XXX: Evaluate whats more physically correct + // return normalize(mix(m.normal, reflected_dir, (1 - roughness) * (roughness + sqrt(1 - roughness)))); + return reflected_dir; +} + + +// Returns an approximated mipmap level based on the materials roughness +// level to approximate importance sampled references +float get_specular_mipmap(float roughness) { + + // Approximation to match importance sampled reference, tuned for a + // resolution of 128. + return (roughness * 12.0 - pow(roughness, 6.0) * 1.5); +} + +float get_specular_mipmap(Material m) { + return get_specular_mipmap(m.roughness); +} + +vec3 get_brdf_from_lut(sampler3D lut_texture, float NxV, float roughness, float ior) { + float lookup_slice = (ior - 1.01) / 1.5 + 0.5 / 15.0; + vec3 data = textureLod(lut_texture, vec3(NxV, roughness, lookup_slice), 0).xyz; + + // Unpack packed data + data *= data; + + return data; +} + +vec3 get_brdf_from_lut(sampler2D lut_texture, float NxV, float roughness) { + vec3 data = textureLod(lut_texture, vec2(NxV, roughness), 0).xyz; + // Unpack packed data + data *= data; + return data; +} + +float get_effective_roughness(Material m) { + return m.shading_model == SHADING_MODEL_CLEARCOAT ? CLEARCOAT_ROUGHNESS : m.roughness; +} + +float get_mipmap_for_roughness(samplerCube map, float roughness, float NxV) { + return sqrt(roughness) * 7.0; +} + + +vec3 get_metallic_fresnel_approx(Material m, float NxV) { + vec3 metallic_energy_f0 = vec3(1.0 - 0.7 * m.roughness) * m.basecolor; + vec3 metallic_energy_f90 = mix(vec3(1), 0.5 * m.basecolor, m.linear_roughness); + vec3 metallic_fresnel = mix(metallic_energy_f0, metallic_energy_f90, + pow(1 - NxV, 3.6 - 2.6 * m.linear_roughness)); + return metallic_fresnel; +} diff --git a/rpcore/shader/includes/color_spaces.inc.glsl b/rpcore/shader/includes/color_spaces.inc.glsl new file mode 100644 index 0000000..cde2c67 --- /dev/null +++ b/rpcore/shader/includes/color_spaces.inc.glsl @@ -0,0 +1,301 @@ +/* + +GLSL Color Space Utility Functions +(c) 2015 tobspr + +------------------------------------------------------------------------------- + +The MIT License (MIT) + +Copyright (c) 2015 + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. + +------------------------------------------------------------------------------- + +Most formulars / matrices are from: +https://en.wikipedia.org/wiki/SRGB + +Some are from: +http://www.chilliant.com/rgb2hsv.html + +*/ + +#pragma once + +// Define saturation macro, if not already user-defined +#ifndef saturate +#define saturate(v) clamp(v, 0, 1) +#endif + +// Constants +const float HCV_EPSILON = 1e-10; +const float HSL_EPSILON = 1e-10; +const float HCY_EPSILON = 1e-10; + +const float SRGB_GAMMA = 1.0 / 2.2; +const float SRGB_INVERSE_GAMMA = 2.2; +const float SRGB_ALPHA = 0.055; + + +// Used to convert from linear RGB to XYZ space +const mat3 RGB_2_XYZ = (mat3( + 0.4124564, 0.3575761, 0.1804375, + 0.2126729, 0.7151522, 0.0721750, + 0.0193339, 0.1191920, 0.9503041 +)); + +// Used to convert from XYZ to linear RGB space +const mat3 XYZ_2_RGB = (mat3( + 3.2404542, -1.5371385, -0.4985314, + -0.9692660, 1.8760108, 0.0415560, + 0.0556434, -0.2040259, 1.0572252 +)); + +const vec3 LUMA_COEFFS = vec3(0.2126, 0.7152, 0.0722); + + +// Returns the luminance of a !! linear !! rgb color +float get_luminance(vec3 rgb) { + return dot(LUMA_COEFFS, rgb); +} + +// Converts a linear rgb color to a srgb color (approximated, but fast) +vec3 rgb_to_srgb_approx(vec3 rgb) { + return pow(rgb, vec3(SRGB_GAMMA)); +} + +// Converts a srgb color to a rgb color (approximated, but fast) +vec3 srgb_to_rgb_approx(vec3 srgb) { + return pow(srgb, vec3(SRGB_INVERSE_GAMMA)); +} + +// Converts a single linear channel to srgb +float linear_to_srgb(float channel) { + if(channel <= 0.0031308) + return 12.92 * channel; + else + return (1.0 + SRGB_ALPHA) * pow(channel, 1.0 / 2.4) - SRGB_ALPHA; +} + +// Converts a single srgb channel to rgb +float srgb_to_linear(float channel) { + if (channel <= 0.04045) + return channel / 12.92; + else + return pow((channel + SRGB_ALPHA) / (1.0 + SRGB_ALPHA), 2.4); +} + +// Converts a linear rgb color to a srgb color (exact, not approximated) +vec3 rgb_to_srgb(vec3 rgb) { + return vec3( + linear_to_srgb(rgb.r), + linear_to_srgb(rgb.g), + linear_to_srgb(rgb.b) + ); +} + +// Converts a srgb color to a linear rgb color (exact, not approximated) +vec3 srgb_to_rgb(vec3 srgb) { + return vec3( + srgb_to_linear(srgb.r), + srgb_to_linear(srgb.g), + srgb_to_linear(srgb.b) + ); +} + +// Converts a color from linear RGB to XYZ space +vec3 rgb_to_xyz(vec3 rgb) { + return RGB_2_XYZ * rgb; +} + +// Converts a color from XYZ to linear RGB space +vec3 xyz_to_rgb(vec3 xyz) { + return XYZ_2_RGB * xyz; +} + +// Converts a color from XYZ to xyY space (Y is luminosity) +vec3 xyz_to_xyY(vec3 xyz) { + float Y = xyz.y; + float x = xyz.x / (xyz.x + xyz.y + xyz.z); + float y = xyz.y / (xyz.x + xyz.y + xyz.z); + return vec3(x, y, Y); +} + +// Converts a color from xyY space to XYZ space +vec3 xyY_to_xyz(vec3 xyY) { + float Y = xyY.z; + float x = Y * xyY.x / xyY.y; + float z = Y * (1.0 - xyY.x - xyY.y) / xyY.y; + return vec3(x, Y, z); +} + +// Converts a color from linear RGB to xyY space +vec3 rgb_to_xyY(vec3 rgb) { + vec3 xyz = rgb_to_xyz(rgb); + return xyz_to_xyY(xyz); +} + +// Converts a color from xyY space to linear RGB +vec3 xyY_to_rgb(vec3 xyY) { + vec3 xyz = xyY_to_xyz(xyY); + return xyz_to_rgb(xyz); +} + +// Converts a value from linear RGB to HCV (Hue, Chroma, Value) +vec3 rgb_to_hcv(vec3 rgb) +{ + // Based on work by Sam Hocevar and Emil Persson + vec4 P = (rgb.g < rgb.b) ? + vec4(rgb.bg, -1.0, 2.0 / 3.0) : vec4(rgb.gb, 0.0, -1.0 / 3.0); + vec4 Q = (rgb.r < P.x) ? vec4(P.xyw, rgb.r) : vec4(rgb.r, P.yzx); + float C = Q.x - min(Q.w, Q.y); + float H = abs((Q.w - Q.y) / (6 * C + HCV_EPSILON) + Q.z); + return vec3(H, C, Q.x); +} + +// Converts from pure Hue to linear RGB +vec3 hue_to_rgb(float hue) +{ + float R = abs(hue * 6 - 3) - 1; + float G = 2 - abs(hue * 6 - 2); + float B = 2 - abs(hue * 6 - 4); + return saturate(vec3(R, G, B)); +} + +// Converts from HSV to linear RGB +vec3 hsv_to_rgb(vec3 hsv) +{ + vec3 rgb = hue_to_rgb(hsv.x); + return ((rgb - 1.0) * hsv.y + 1.0) * hsv.z; +} + +// Converts from HSL to linear RGB +vec3 hsl_to_rgb(vec3 hsl) +{ + vec3 rgb = hue_to_rgb(hsl.x); + float C = (1 - abs(2 * hsl.z - 1)) * hsl.y; + return (rgb - 0.5) * C + hsl.z; +} + +// Converts from HCY to linear RGB +vec3 hcy_to_rgb(vec3 hcy) +{ + const vec3 HCYwts = vec3(0.299, 0.587, 0.114); + vec3 RGB = hue_to_rgb(hcy.x); + float Z = dot(RGB, HCYwts); + if (hcy.z < Z) { + hcy.y *= hcy.z / Z; + } else if (Z < 1) { + hcy.y *= (1 - hcy.z) / (1 - Z); + } + return (RGB - Z) * hcy.y + hcy.z; +} + + +// Converts from linear RGB to HSV +vec3 rgb_to_hsv(vec3 rgb) +{ + vec3 HCV = rgb_to_hcv(rgb); + float S = HCV.y / (HCV.z + HCV_EPSILON); + return vec3(HCV.x, S, HCV.z); +} + +// Converts from linear rgb to HSL +vec3 rgb_to_hsl(vec3 rgb) +{ + vec3 HCV = rgb_to_hcv(rgb); + float L = HCV.z - HCV.y * 0.5; + float S = HCV.y / (1 - abs(L * 2 - 1) + HSL_EPSILON); + return vec3(HCV.x, S, L); +} + +// Converts from rgb to hcy (Hue, Chroma, Luminance) +vec3 rgb_to_hcy(vec3 rgb) +{ + const vec3 HCYwts = vec3(0.299, 0.587, 0.114); + // Corrected by David Schaeffer + vec3 HCV = rgb_to_hcv(rgb); + float Y = dot(rgb, HCYwts); + float Z = dot(hue_to_rgb(HCV.x), HCYwts); + if (Y < Z) { + HCV.y *= Z / (HCY_EPSILON + Y); + } else { + HCV.y *= (1 - Z) / (HCY_EPSILON + 1 - Y); + } + return vec3(HCV.x, HCV.y, Y); +} + +// Additional conversions converting to rgb first and then to the desired +// color space. + +// To srgb +vec3 xyz_to_srgb(vec3 xyz) { return rgb_to_srgb(xyz_to_rgb(xyz)); } +vec3 xyY_to_srgb(vec3 xyY) { return rgb_to_srgb(xyY_to_rgb(xyY)); } +vec3 hue_to_srgb(float hue) { return rgb_to_srgb(hue_to_rgb(hue)); } +vec3 hsv_to_srgb(vec3 hsv) { return rgb_to_srgb(hsv_to_rgb(hsv)); } +vec3 hsl_to_srgb(vec3 hsl) { return rgb_to_srgb(hsl_to_rgb(hsl)); } +vec3 hcy_to_srgb(vec3 hcy) { return rgb_to_srgb(hcy_to_rgb(hcy)); } + +// To xyz +vec3 srgb_to_xyz(vec3 srgb) { return rgb_to_xyz(srgb_to_rgb(srgb)); } +vec3 hue_to_xyz(float hue) { return rgb_to_xyz(hue_to_rgb(hue)); } +vec3 hsv_to_xyz(vec3 hsv) { return rgb_to_xyz(hsv_to_rgb(hsv)); } +vec3 hsl_to_xyz(vec3 hsl) { return rgb_to_xyz(hsl_to_rgb(hsl)); } +vec3 hcy_to_xyz(vec3 hcy) { return rgb_to_xyz(hcy_to_rgb(hcy)); } + +// To xyY +vec3 srgb_to_xyY(vec3 srgb) { return rgb_to_xyY(srgb_to_rgb(srgb)); } +vec3 hue_to_xyY(float hue) { return rgb_to_xyY(hue_to_rgb(hue)); } +vec3 hsv_to_xyY(vec3 hsv) { return rgb_to_xyY(hsv_to_rgb(hsv)); } +vec3 hsl_to_xyY(vec3 hsl) { return rgb_to_xyY(hsl_to_rgb(hsl)); } +vec3 hcy_to_xyY(vec3 hcy) { return rgb_to_xyY(hcy_to_rgb(hcy)); } + +// To HCV +vec3 srgb_to_hcv(vec3 srgb) { return rgb_to_hcv(srgb_to_rgb(srgb)); } +vec3 xyz_to_hcv(vec3 xyz) { return rgb_to_hcv(xyz_to_rgb(xyz)); } +vec3 xyY_to_hcv(vec3 xyY) { return rgb_to_hcv(xyY_to_rgb(xyY)); } +vec3 hue_to_hcv(float hue) { return rgb_to_hcv(hue_to_rgb(hue)); } +vec3 hsv_to_hcv(vec3 hsv) { return rgb_to_hcv(hsv_to_rgb(hsv)); } +vec3 hsl_to_hcv(vec3 hsl) { return rgb_to_hcv(hsl_to_rgb(hsl)); } +vec3 hcy_to_hcv(vec3 hcy) { return rgb_to_hcv(hcy_to_rgb(hcy)); } + +// To HSV +vec3 srgb_to_hsv(vec3 srgb) { return rgb_to_hsv(srgb_to_rgb(srgb)); } +vec3 xyz_to_hsv(vec3 xyz) { return rgb_to_hsv(xyz_to_rgb(xyz)); } +vec3 xyY_to_hsv(vec3 xyY) { return rgb_to_hsv(xyY_to_rgb(xyY)); } +vec3 hue_to_hsv(float hue) { return rgb_to_hsv(hue_to_rgb(hue)); } +vec3 hsl_to_hsv(vec3 hsl) { return rgb_to_hsv(hsl_to_rgb(hsl)); } +vec3 hcy_to_hsv(vec3 hcy) { return rgb_to_hsv(hcy_to_rgb(hcy)); } + +// To HSL +vec3 srgb_to_hsl(vec3 srgb) { return rgb_to_hsl(srgb_to_rgb(srgb)); } +vec3 xyz_to_hsl(vec3 xyz) { return rgb_to_hsl(xyz_to_rgb(xyz)); } +vec3 xyY_to_hsl(vec3 xyY) { return rgb_to_hsl(xyY_to_rgb(xyY)); } +vec3 hue_to_hsl(float hue) { return rgb_to_hsl(hue_to_rgb(hue)); } +vec3 hsv_to_hsl(vec3 hsv) { return rgb_to_hsl(hsv_to_rgb(hsv)); } +vec3 hcy_to_hsl(vec3 hcy) { return rgb_to_hsl(hcy_to_rgb(hcy)); } + +// To HCY +vec3 srgb_to_hcy(vec3 srgb) { return rgb_to_hcy(srgb_to_rgb(srgb)); } +vec3 xyz_to_hcy(vec3 xyz) { return rgb_to_hcy(xyz_to_rgb(xyz)); } +vec3 xyY_to_hcy(vec3 xyY) { return rgb_to_hcy(xyY_to_rgb(xyY)); } +vec3 hue_to_hcy(float hue) { return rgb_to_hcy(hue_to_rgb(hue)); } +vec3 hsv_to_hcy(vec3 hsv) { return rgb_to_hcy(hsv_to_rgb(hsv)); } +vec3 hsl_to_hcy(vec3 hcy) { return rgb_to_hcy(hsl_to_rgb(hcy)); } diff --git a/rpcore/shader/includes/common_functions.inc.glsl b/rpcore/shader/includes/common_functions.inc.glsl new file mode 100644 index 0000000..3dcd4e1 --- /dev/null +++ b/rpcore/shader/includes/common_functions.inc.glsl @@ -0,0 +1,320 @@ +/** + * + * RenderPipeline + * + * Copyright (c) 2014-2016 tobspr + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + */ + +#pragma once + +#define saturate(v) clamp(v, 0, 1) + +#define M_PI 3.1415926535897932384626433 +#define HALF_PI 1.5707963267948966192313216 +#define TWO_PI 6.2831853071795864769252867 +#define FOUR_PI 12.566370614359172953850573 +#define ONE_BY_PI 0.3183098861837906715377675 +#define SQRT_TWO 1.4142135623730950488016887 + +#define AIR_IOR 1.000277 + +// Fixes the cubemap direction +vec3 fix_cubemap_coord(vec3 coord) { + // return normalize(coord.xzy * vec3(1,-1,1)); + return normalize(coord.yxz * vec3(-1, 1, 1)); +} + + +// Converts a texture coodinate and face index to a direction vector +vec3 get_cubemap_coordinate(int face_index, vec2 coord) { + vec3 baseDir = vec3(0); + if (face_index == 0) baseDir = vec3(1.0, -coord.y, -coord.x); + else if (face_index == 1) baseDir = vec3(-1.0, -coord.y, coord.x); + else if (face_index == 2) baseDir = vec3(coord.x, 1.0, coord.y); + else if (face_index == 3) baseDir = vec3(coord.x, -1.0, -coord.y); + else if (face_index == 4) baseDir = vec3(coord.x, -coord.y, 1.0); + else if (face_index == 5) baseDir = vec3(-coord.x, -coord.y, -1.0); + return normalize(baseDir); +} + +// Computes the skydome texcoord based on the pixels view direction +vec2 get_skydome_coord(vec3 view_dir) { + float angle = (atan(view_dir.x, view_dir.y) + M_PI) / (2.0 * M_PI); + return vec2(angle, view_dir.z); +} + +// Converts a coordinate like "gl_FragCoord" to a cubemap direction, with a given +// cubemap size. Assumes the render target has a size of (6 * cubemap_size, cubemap_size). +// clamped_coord will contain a coordinate from (0 .. cubemap_size), this can be +// used for further processing or writing the result. +// face will contain the selected cubemap face. +vec3 texcoord_to_cubemap(int cubemap_size, ivec2 coord, out ivec2 clamped_coord, out int face) { + face = coord.x / cubemap_size; + clamped_coord = coord % cubemap_size; + vec2 local_coord = saturate((clamped_coord + 0.5) / float(cubemap_size)) * 2.0 - 1.0; + return get_cubemap_coordinate(face, local_coord); +} + + +// Version of texcoord_to_cubemap without the out parameters +vec3 texcoord_to_cubemap(int cubemap_size, ivec2 coord) { + ivec2 clamped_coord; int face; + return texcoord_to_cubemap(cubemap_size, coord, clamped_coord, face); +} + + +// Rotate a vector by a given sinus and cosinus of an angle +vec2 rotate(vec2 vector, float cos_alpha, float sin_alpha) { + return vec2( + vector.x * cos_alpha - vector.y * sin_alpha, + vector.x * sin_alpha + vector.y * cos_alpha + ); +} + +// Rotate a vector by an angle +vec2 rotate(vec2 vector, float angle) { + float cos_alpha = cos(angle); + float sin_alpha = sin(angle); + return rotate(vector, cos_alpha, sin_alpha); +} + +// Returns a coordinate which can be used for bilateral upscaling +ivec2 get_bilateral_coord(ivec2 coord) { + return (coord + 1) / 2 - 1; +} + +// Checks if a 2D-coordinate exceeds the [0, 1] range +bool out_of_screen(vec2 tcoord) { + return tcoord.x < 0.0 || tcoord.y < 0.0 || tcoord.x > 1.0 || tcoord.y > 1.0; +} + +// Checks if a 3D-coordinate exceeds the [0, 1] range +bool out_of_unit_box(vec3 coord) { + return coord.x < 0.0 || coord.y < 0.0 || coord.z < 0.0 || + coord.x > 1.0 || coord.y > 1.0 || coord.z > 1.0; +} + + +// Finds a tangent and bitangent vector based on a given normal +void find_arbitrary_tangent(vec3 normal, out vec3 tangent, out vec3 bitangent) { + vec3 v0 = abs(normal.z) < (0.99) ? vec3(0, 0, 1) : vec3(0, 1, 0); + tangent = normalize(cross(v0, normal)); + bitangent = normalize(cross(tangent, normal)); +} + +// Transforms a given vector to tangent space +vec3 tangent_to_world(vec3 normal, vec3 vector) +{ + vec3 tangent, binormal; + find_arbitrary_tangent(normal, tangent, binormal); + return vector.x * tangent + vector.y * binormal + vector.z * normal; +} + + +// Returns the number of mipmaps of a cubemap +int get_mipmap_count(samplerCube cubemap) { + int cubemap_size = textureSize(cubemap, 0).x; + return int(1 + floor(log2(cubemap_size))); +} + +// Returns the number of mipmaps of a 2D Texture +int get_mipmap_count(sampler2D tex) { + int tex_size = textureSize(tex, 0).x; + return int(1 + floor(log2(tex_size))); +} + +// Returns the number of mipmaps of a cubemap arry +int get_mipmap_count(samplerCubeArray cubemap) { + int cubemap_size = textureSize(cubemap, 0).x; + return int(1 + floor(log2(cubemap_size))); +} + +// Converts a normalized spherical coordinate (r = 1) to cartesian coordinates +vec3 spherical_to_vector(float theta, float phi) { + float sin_theta = sin(theta); + return normalize(vec3( + sin_theta * cos(phi), + sin_theta * sin(phi), + cos(theta) + )); +} + +// Converts a cartesian coordinate to spherical coordinates +void vector_to_spherical(vec3 v, out float theta, out float phi, out float radius) { + radius = sqrt(dot(v, v)); + phi = acos(v.z / radius); + theta = atan(v.y, v.x) + M_PI; +} + +// Convertsa normalized vector to spherical coordinates +void vector_to_spherical(vec3 v, out float theta, out float phi) { + phi = acos(v.z); + theta = atan(v.y, v.x) + M_PI; +} + + + +// Converts a given sun azimuth and altitude to a direction vector +vec3 sun_azimuth_to_angle(float azimuth, float altitude) { + float theta = (90 - altitude) / 180.0 * M_PI; + float phi = azimuth / 180.0 * M_PI; + return spherical_to_vector(theta, phi); +} + + +// Blends a given color soft with the base color +// From: https://github.com/mattdesl/glsl-blend-soft-light/blob/master/index.glsl +vec3 blend_soft_light(vec3 base, vec3 blend) { + return mix( + sqrt(base) * (2.0 * blend - 1.0) + 2.0 * base * (1.0 - blend), + 2.0 * base * blend + base * base * (1.0 - 2.0 * blend), + step(base, vec3(0.5)) + ); +} + +// Normalizes v without taking the w component into account +vec4 normalize_without_w(vec4 v) { + return v / length(v.xyz); +} + +// Unpacks a normal from 0 .. 1 range to the -1 .. 1 range +vec3 unpack_texture_normal(vec3 n) { + return fma(n, vec3(2.0), vec3(-1.0)); +} + +// Converts a value from linear to logarithmic distribution, using a given factor +float make_logarithmic(float x, float factor) { + // return (exp(factor * x)-1) / (exp(factor)-1); + return log(factor * x + 1.0 + 1e-6) / log(1.0 + factor); +} + +// Makes a 3 component vector logarithmic +vec3 make_logarithmic(vec3 v, float factor) { + return log(factor * v + 1.0 + 1e-6) / log(1.0 + factor); +} + +// Unpacks an integer from a float, packed by the GPUCommandQueue. +int gpu_cq_unpack_int_from_float(float v) { + #if GPU_CMD_INT_AS_FLOAT + return floatBitsToInt(v); + #else + return int(v); + #endif +} + +// Computes the diffuse antialiasing factor +// From: http://blog.selfshadow.com/sandbox/diffuse_aa.html +float get_diffuse_aa(float w, float NxL) { + float x = sqrt(1.0 - w); + float x0 = 0.373837 * NxL; + float x1 = 0.66874 * x; + float n = x0 + x1; + return w * ((abs(x0) <= x1) ? n * n / x : saturate(NxL)); +} + +// Blends a material +float blend_material(float material_factor, float detailmap, float add_factor, float pow_factor) { + material_factor = max(0, material_factor); + return saturate( + mix(pow(max(0, detailmap + add_factor), pow_factor), 1.0, material_factor) * + material_factor); +} + +// Blends a specular IOR to make sure it never drops below 1.0 +float blend_ior(float material_specular, float sampled_specular) { + return 1.0 + max(0, material_specular - 1.0) * 2.0 * sampled_specular; +} + +// We need to define them as macros instead of functions, since gl_FragCoord is +// not available in compute shaders + +// Regular texcoord +#define get_texcoord() (gl_FragCoord.xy / SCREEN_SIZE) + +// Texcoord for half-res targets sampling full-res targets +#define get_half_texcoord() vec2((ivec2(gl_FragCoord.xy) * 2 + 0.5) / SCREEN_SIZE) + +// Texcoord for half-res targets sampling half-res targets +#define get_half_native_texcoord() ((vec2(gl_FragCoord.xy) + 0.5) / ivec2(SCREEN_SIZE / 2)) + +// Converts degree (0 .. 360) to radians (0 .. 2 PI) +float degree_to_radians(float degree) { + return degree / 180.0 * M_PI; +} + +// Converts radians (0 .. 2 PI) to degree (0 .. 360) +float radians_to_degree(float radians) { + return radians / M_PI * 180.0; +} + +// Simulates a near filter on a fullscreen texture +vec2 truncate_coordinate(vec2 tcoord) { + return (ivec2(tcoord * SCREEN_SIZE) + 0.5) / SCREEN_SIZE; +} + +// Returns the squared length of v +float length_squared(vec2 v) { return dot(v, v); } +float length_squared(vec3 v) { return dot(v, v); } +float length_squared(vec4 v) { return dot(v, v); } + +// Squared distance between a and b +float distance_squared(vec3 a, vec3 b) { return length_squared(a - b); } +float distance_squared(vec4 a, vec4 b) { return length_squared(a - b); } +float distance_squared(vec2 a, vec2 b) { return length_squared(a - b); } + +// Returns x * x +float square(float x) { return x * x; } +vec2 square(vec2 x) { return x * x; } +vec3 square(vec3 x) { return x * x; } +vec4 square(vec4 x) { return x * x; } + +// Minimum and maximum for multiple components +// XXX: There are hardware instructions (at least on AMD) for it: +// https://www.opengl.org/registry/specs/AMD/shader_trinary_minmax.txt +#define min3(a, b, c) min(a, min(b, c)) +#define max3(a, b, c) max(a, max(b, c)) +#define min4(a, b, c, d) min(a, min(b, min(c, d))) +#define max4(a, b, c, d) max(a, max(b, max(c, d))) +#define min5(a, b, c, d, e) min(a, min(b, min(c, min(d, e)))) +#define max5(a, b, c, d, e) max(a, max(b, max(c, max(d, e)))) + +// Convenience function which ensures v dot n is > 0 +vec3 face_forward(vec3 v, vec3 n) { + return dot(v, n) < 0 ? -v : v; +} + +// Creates a rotation mat, rotation should be 0 .. 2 * pi +mat2 make_rotation_mat(float rotation) { + float r_sin = sin(rotation); + float r_cos = cos(rotation); + return mat2(r_cos, -r_sin, r_sin, r_cos); +} + +// Convenience functions for the scattering plugin - probably don't belong here +#define get_sun_vector() sun_azimuth_to_angle(TimeOfDay.scattering.sun_azimuth, TimeOfDay.scattering.sun_altitude) +#define get_sun_color() (TimeOfDay.scattering.sun_color * TimeOfDay.scattering.sun_intensity) +#define get_sun_color_scale(_v) saturate(square((_v.z) / 0.15)) + +#if !HAVE_PLUGIN(color_correction) + #undef get_sun_color + #define get_sun_color() (TimeOfDay.scattering.sun_color * TimeOfDay.scattering.sun_intensity) +#endif diff --git a/rpcore/shader/includes/envprobes.inc.glsl b/rpcore/shader/includes/envprobes.inc.glsl new file mode 100644 index 0000000..7796226 --- /dev/null +++ b/rpcore/shader/includes/envprobes.inc.glsl @@ -0,0 +1,253 @@ +/** + * + * RenderPipeline + * + * Copyright (c) 2014-2016 tobspr + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + */ + +#pragma once + +#pragma include "includes/material.inc.glsl" +#pragma include "includes/brdf.inc.glsl" +#pragma include "includes/color_spaces.inc.glsl" +#pragma include "includes/light_culling.inc.glsl" + +// Global probe data +uniform struct { + int num_probes; + samplerCubeArray cubemaps; + samplerCubeArray diffuse_cubemaps; + samplerBuffer dataset; +} EnvProbes; + +// Per probe instance +struct Cubemap { + mat4 transform; + bool use_parallax; + float border_smoothness; + uint index; + + vec3 bounding_sphere_center; + float bounding_sphere_radius; +}; + +// Per cell data +#ifdef APPLY_ENVPROBES_PASS + uniform isampler2DArray CellIndices; + uniform isamplerBuffer PerCellProbes; +#endif + +Cubemap get_cubemap(int index) { + Cubemap result; + int offs = index * 5; + vec4 data0 = texelFetch(EnvProbes.dataset, offs); + vec4 data1 = texelFetch(EnvProbes.dataset, offs + 1); + vec4 data2 = texelFetch(EnvProbes.dataset, offs + 2); + vec4 data3 = texelFetch(EnvProbes.dataset, offs + 3); + vec4 data4 = texelFetch(EnvProbes.dataset, offs + 4); + + // Unpack the packed matrix, we only store a 3x4 matrix to save space, + // sine the last row is always (0, 0, 0, 1) + result.transform = mat4( + data0.x, data0.y, data0.z, 0, + data0.w, data1.x, data1.y, 0, + data1.z, data1.w, data2.x, 0, + data2.y, data2.z, data2.w, 1 + ); + result.index = uint(data3.x + 0.5); + result.use_parallax = data3.y > 0.5; + result.border_smoothness = data3.z; + result.bounding_sphere_center = data4.xyz; + result.bounding_sphere_radius = data4.w; + return result; +} + +// https://seblagarde.wordpress.com/2012/09/29/image-based-lighting-approaches-and-parallax-corrected-cubemap/ +float correct_parallax(Cubemap map, Material m, vec3 vector, out float factor) { + // Intersection with OBB, convert to unit box space + // Transform in local unit parallax cube space (scaled and rotated) + vec3 ray_ls = (map.transform * vec4(vector, 0)).xyz; + vec3 position_ls = (map.transform * vec4(m.position, 1)).xyz; + + // Get fading factor + vec3 local_v = abs(position_ls); + factor = max(local_v.x, max(local_v.y, local_v.z)); + + if (!map.use_parallax) { + return 1e10; + } + + // Intersect with unit box + vec3 first_plane = (1.0 - position_ls) / ray_ls; + vec3 second_plane = (-1.0 - position_ls) / ray_ls; + vec3 furthest_plane = max(first_plane, second_plane); + return min(furthest_plane.x, min(furthest_plane.y, furthest_plane.z)); +} + +vec3 get_cubemap_vector(Cubemap map, Material m, vec3 vector, out float factor, out float dist) { + dist = correct_parallax(map, m, vector, factor); + + // Use distance in world space directly to recover intersection. + // Mix parallax corrected and original vector based on roughness + vec3 intersection_pos = mix( + m.position + vector * dist, + map.bounding_sphere_center + vector, + m.roughness); + return (map.transform * vec4(intersection_pos, 1)).xyz; +} + +vec3 get_reflection_vector(Cubemap map, Material m, out float factor, out float dist) { + vec3 view_vector = normalize(m.position - MainSceneData.camera_pos); + vec3 reflected = get_reflection_vector(m, view_vector); + return get_cubemap_vector(map, m, reflected, factor, dist); +} + +vec3 get_diffuse_vector(Cubemap map, Material m) { + #if 0 + // very expensive, have to think of a better solution - + // maybe we can precompute the matrix and store it. + mat3 tpose_inverse = transpose(inverse(mat3(map.transform))); + return tpose_inverse * (m.normal); + #else + // This is mathematically wrong, but it works fast and reasonable + vec4 transformed = map.transform * vec4(fma(m.normal, vec3(1e5), + map.bounding_sphere_center), 1); + return transformed.xyz; + #endif +} + +void apply_cubemap(int id, Material m, out vec4 diffuse, out vec4 specular, + inout float total_weight, inout float total_blend) { + + const float max_mip = 7.0; + float roughness = get_effective_roughness(m); + + float factor = 0.0; + float mipmap = m.linear_roughness * 10.0; + float intersection_distance = 1.0; + + Cubemap map = get_cubemap(id); + + vec3 direction = get_reflection_vector(map, m, factor, intersection_distance); + vec3 diffuse_direction = get_diffuse_vector(map, m); + + vec3 vector_to_source = normalize(map.bounding_sphere_center - m.position); + + // float normal_blend_factor = saturate(0.1 + 1 * dot(vector_to_source, m.normal)); + float normal_blend_factor = saturate(3.0 * dot(vector_to_source, m.normal)); + float blend = saturate((1 - factor) / max(1e-10, map.border_smoothness)); + blend *= normal_blend_factor; + + // Make sure the gradient looks right after tonemapping + // blend = square(blend); + + float local_distance = intersection_distance / map.bounding_sphere_radius; + + #if 0 + if (map.use_parallax) { + // mipmap *= intersection_distance * 0.012; + } else { + mipmap *= 0.1; + } + #else + // mipmap *= 0.1; + #endif + + + specular = textureLod(EnvProbes.cubemaps, + vec4(direction, map.index), clamp(mipmap, 0.0, max_mip)); + diffuse = textureLod(EnvProbes.diffuse_cubemaps, + vec4(diffuse_direction, map.index), 0); + + // Optional: Correct specular based on diffuse scolor intensity + // specular.xyz = mix(specular.xyz, specular.xyz * get_luminance(diffuse.xyz), diffuse.w); + + // Make sure small probes contribute much more than large ones + float weight = exp(-0.05 * map.bounding_sphere_radius); + weight *= factor >= 1.0 ? 0.0 : 1.0; + + // Apply clip factors + specular *= weight * blend; + diffuse *= weight * blend; + + total_weight += weight * blend; + total_blend += blend; +} + + +#ifdef APPLY_ENVPROBES_PASS + void apply_all_probes(Material m, out vec4 specular, out vec4 diffuse) { + ivec3 tile = get_lc_cell_index( + ivec2(gl_FragCoord.xy), + distance(MainSceneData.camera_pos, m.position)); + + // Don't shade pixels out of the shading range + if (tile.z >= LC_TILE_SLICES) { + specular = vec4(0); + diffuse = vec4(0); + return; + } + + int cell_index = texelFetch(CellIndices, tile, 0).x; + int data_offs = cell_index * MAX_PROBES_PER_CELL; + + vec4 total_diffuse = vec4(0); + vec4 total_specular = vec4(0); + float total_blend = 0; + float total_weight = 0; + + int processed_probes = 0; + for (int i = 0; i < MAX_PROBES_PER_CELL; ++i) { + int cubemap_index = texelFetch(PerCellProbes, data_offs + i).x - 1; + if (cubemap_index < 0) break; + vec4 diff, spec; + + processed_probes += 1; + apply_cubemap(cubemap_index, m, diff, spec, total_weight, total_blend); + total_diffuse += diff; + total_specular += spec; + } + + float scale = 1.0 / max(1e-9, total_weight) * min(1.0, total_blend); + + vec4 result_spec = total_specular * scale; + vec4 result_diff = total_diffuse * scale; + + // Fade out cubemaps as they reach the culling distance + float curr_dist = distance(m.position, MainSceneData.camera_pos); + float fade = saturate(curr_dist / LC_MAX_DISTANCE); + fade = 1 - pow(fade, 5.0); + + result_spec *= fade; + result_diff *= fade; + + // Visualize probe count + #if MODE_ACTIVE(ENVPROBE_COUNT) + float probe_factor = float(processed_probes) / MAX_PROBES_PER_CELL; + result_spec = result_diff = vec4(probe_factor, 1 - probe_factor, 0, 1); + #endif + + specular = result_spec; + diffuse = result_diff; + } + +#endif diff --git a/rpcore/shader/includes/forward_shading.inc.glsl b/rpcore/shader/includes/forward_shading.inc.glsl new file mode 100644 index 0000000..bde551f --- /dev/null +++ b/rpcore/shader/includes/forward_shading.inc.glsl @@ -0,0 +1,323 @@ +/** + * + * RenderPipeline + * + * Copyright (c) 2014-2016 tobspr + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + */ + +#pragma once + +// Forward shading pipeline + +#pragma include "includes/shadows.inc.glsl" +#pragma include "includes/brdf.inc.glsl" +#pragma include "includes/lights.inc.glsl" +#pragma include "includes/light_data.inc.glsl" +#pragma include "includes/poisson_disk.inc.glsl" + +uniform samplerCube DefaultEnvmap; +uniform samplerBuffer AllLightsData; +uniform int maxLightIndex; + +#if VIEWSPACE_SHADING + uniform sampler3D PrefilteredBRDF; + uniform sampler2D PrefilteredCoatBRDF; +#endif + +// Samplers for the specular cubemaps +#if HAVE_PLUGIN(scattering) + uniform samplerCube ScatteringIBLDiffuse; + uniform samplerCube ScatteringIBLSpecular; +#endif + + +#if HAVE_PLUGIN(pssm) + uniform sampler2DShadow PSSMSceneSunShadowMapPCF; + uniform mat4 PSSMSceneSunShadowMVP; +#endif + +#if HAVE_PLUGIN(sky_ao) + #pragma include "/$$rp/rpplugins/sky_ao/shader/sky_ao.inc.glsl" +#endif + +#if VIEWSPACE_SHADING + + // Also include environment probes + + #if HAVE_PLUGIN(env_probes) + #define APPLY_ENVPROBES_PASS + #pragma include "includes/light_culling.inc.glsl" + #pragma include "includes/envprobes.inc.glsl" + #endif + + struct AmbientResult { + vec3 specular; + vec3 diffuse; + float fresnel; + }; + + // Full forward ambient, expensive, and only available when shading in view-space + AmbientResult get_full_forward_ambient(Material m, vec3 v) { + vec3 reflected_dir = get_reflection_vector(m, v); + float roughness = get_effective_roughness(m); + + // Compute angle between normal and view vector + float NxV = clamp(-dot(m.normal, v), 1e-5, 1.0); + + float env_mipmap = get_mipmap_for_roughness(DefaultEnvmap, roughness , NxV); + + // Sample default environment map + vec3 ibl_specular = textureLod(DefaultEnvmap, fix_cubemap_coord(reflected_dir), + env_mipmap).xyz * DEFAULT_ENVMAP_BRIGHTNESS; + + // Get cheap irradiance by sampling low levels of the environment map + float ibl_diffuse_mip = get_mipmap_count(DefaultEnvmap) - 3.0; + vec3 ibl_diffuse = textureLod(DefaultEnvmap, fix_cubemap_coord(m.normal), + ibl_diffuse_mip).xyz * DEFAULT_ENVMAP_BRIGHTNESS; + + // Scattering specific code + #if HAVE_PLUGIN(scattering) + float scat_mipmap = m.shading_model == SHADING_MODEL_CLEARCOAT ? + CLEARCOAT_ROUGHNESS : get_specular_mipmap(m); + + // Sample prefiltered scattering cubemap + // ibl_specular = textureLod(ScatteringIBLSpecular, reflected_dir, scat_mipmap).xyz; + + // Diffuse IBL + // ibl_diffuse = textureLod(ScatteringIBLDiffuse, m.normal, 0).xyz; + #endif + + #if HAVE_PLUGIN(env_probes) + // vec4 probe_spec, probe_diff; + // apply_all_probes(m, probe_spec, probe_diff); + + // ibl_diffuse = ibl_diffuse * (1 - probe_diff.w) + probe_diff.xyz; + // ibl_specular = ibl_specular * (1 - probe_spec.w) + probe_spec.xyz; + + #endif + + vec3 env_brdf = get_brdf_from_lut(PrefilteredBRDF, NxV, sqrt(roughness), m.specular_ior); + + // Diffuse and fresnel ambient term + vec3 diffuse_ambient = ibl_diffuse * m.basecolor * (1-m.metallic); + vec3 fresnel = env_brdf.ggg; + diffuse_ambient *= env_brdf.r; + + vec3 metallic_fresnel = get_metallic_fresnel_approx(m, NxV); + + // Mix between normal and metallic fresnel + fresnel = mix(fresnel, metallic_fresnel, m.metallic); + + // XXX: Clearcoat not supported here + vec3 specular_ambient = fresnel * ibl_specular; + + AmbientResult ret; + ret.specular = specular_ambient; + ret.diffuse = diffuse_ambient; + ret.fresnel = env_brdf.g; + return ret; + } + +#else + + // cheap forward shaded ambient + vec3 get_forward_ambient(Material m) { + vec3 shading_result = vec3(0); + + #if HAVE_PLUGIN(scattering) + vec3 diff_env = textureLod(ScatteringIBLDiffuse, m.normal, 0).rgb; + #else + int ibl_diffuse_mip = get_mipmap_count(DefaultEnvmap) - 5; + vec3 diff_env = textureLod(DefaultEnvmap, m.normal, ibl_diffuse_mip).rgb * + DEFAULT_ENVMAP_BRIGHTNESS; + #endif + + #if HAVE_PLUGIN(env_probes) + const float sky_ambient_factor = TimeOfDay.env_probes.sky_ambient_scale; + const float ambient_factor = TimeOfDay.env_probes.ambient_scale; + #else + const float sky_ambient_factor = 0.05; + const float ambient_factor = 0.1; + #endif + + #if HAVE_PLUGIN(sky_ao) + float sky_ao = compute_sky_ao(m.position, m.normal); + #else + float sky_ao = 1.0; + #endif + shading_result += (sky_ambient_factor + ambient_factor * sqrt(m.basecolor)) * sky_ao * diff_env; + + + + // Emission + if (m.shading_model == SHADING_MODEL_EMISSIVE) { + shading_result = m.basecolor * (0.005 + diff_env) * 30.0; + } + + return shading_result; + } + +#endif + + +float get_sun_shadow_factor(vec3 position, vec3 normal) { + #if !HAVE_PLUGIN(scattering) || !HAVE_PLUGIN(pssm) + return 1.0; + #else + vec3 sun_vector = get_sun_vector(); + + vec3 biased_position = position; + + // XXX: make this configurable + const float slope_bias = 0.3 * 0.02; + const float normal_bias = 0.0 * 0.005; + const float fixed_bias = 0.5 * 0.001; + vec3 biased_pos = get_biased_position( + position, slope_bias, normal_bias, vOutput.normal, sun_vector); + + vec3 projected = project(PSSMSceneSunShadowMVP, biased_position); + projected.z -= fixed_bias; + + // Fast shadow filtering + float filter_radius = 1.0 / textureSize(PSSMSceneSunShadowMapPCF, 0).y; + float shadow_term = 0; + for(uint i = 0; i < 12; ++i) { + vec3 offset = vec3(poisson_2D_12[i] * filter_radius, 0); + shadow_term += textureLod(PSSMSceneSunShadowMapPCF, projected + offset, 0).x; + } + shadow_term /= 12.0; + return shadow_term; + #endif +} + +#if VIEWSPACE_SHADING + + vec3 get_sun_shading(Material m, vec3 view_vector) { + #if HAVE_PLUGIN(scattering) + + // Compute the sun lighting + vec3 sun_vector = get_sun_vector(); + vec3 l = sun_vector; + vec3 sun_color = get_sun_color() * get_sun_color_scale(sun_vector); + + { + vec3 reflected_dir = reflect(view_vector, m.normal); + const float sun_angular_radius = degree_to_radians(0.54); + const float r = sin(sun_angular_radius); // Disk radius + const float d = cos(sun_angular_radius); // Distance to disk + + // Closest point to a disk (since the radius is small, this is + // a good approximation) + float DdotR = dot(sun_vector, reflected_dir); + vec3 S = reflected_dir - DdotR * sun_vector; + l = DdotR < d ? normalize(d * sun_vector + normalize(S) * r) : reflected_dir; + } + + // XXX: Need a shadow map. Maybe reuse pssm but thats super expensive + // float shadow = get_sun_shadow_factor(m.position, m.normal); + + float shadow = 1.0; + return apply_light(m, view_vector, l, sun_color, 1.0, shadow, vec3(1)); + + + #else + return vec3(0); + #endif + } + + +#else + + // Applies the sun shading, and if the pssm plugin is activated, also the + // sun shadows + vec3 get_sun_shading(Material m) { + #if HAVE_PLUGIN(scattering) + float shadow = 0.0; + vec3 shading_result = vec3(0); + vec3 sun_vector = get_sun_vector(); + vec3 sun_color = get_sun_color() * get_sun_color_scale(sun_vector); + + if (sun_vector.z >= SUN_VECTOR_HORIZON) { + float NxL = saturate(dot(sun_vector, m.normal)); + if (NxL > 0.0) { + shadow = NxL * get_sun_shadow_factor(m.position, m.normal); + } + } + #if HAVE_PLUGIN(env_probes) + const float factor = TimeOfDay.env_probes.sun_ambient_scale; + #else + const float factor = 1.0; + #endif + return shadow * sun_color * factor * m.basecolor; + #else + return vec3(0); + #endif + } +#endif + + + +vec3 get_forward_light_shading(Material m) { + + vec3 shading_result = vec3(0); + + for (int i = 0; i <= maxLightIndex; ++i) { + LightData light_data = read_light_data(AllLightsData, i); + int light_type = get_light_type(light_data); + + // Skip Null-Lights + if (light_type < 1) continue; + + vec3 light_pos = get_light_position(light_data); + vec3 l = light_pos - m.position; + float l_len = length(l); + vec3 light_color = get_light_color(light_data); + + // Shade depending on light type + switch(light_type) { + case LT_POINT_LIGHT: { + float radius = get_pointlight_radius(light_data); + float inner_radius = get_pointlight_inner_radius(light_data); + float att = attenuation_curve(dot(l, l), radius); + float NxL = saturate(dot(m.normal, l) / l_len); + shading_result += saturate(att) * NxL * (m.basecolor * light_color); + break; + } + + case LT_SPOT_LIGHT: { + float radius = get_spotlight_radius(light_data); + float fov = get_spotlight_fov(light_data); + vec3 direction = get_spotlight_direction(light_data); + + float att = get_spotlight_attenuation(l / l_len, direction, + fov, radius, dot(l, l), -1); + float NxL = saturate(dot(m.normal, l) / l_len); + shading_result += saturate(att) * NxL * (m.basecolor * light_color); + break; + } + + } + + } + + return shading_result / M_PI; +} diff --git a/rpcore/shader/includes/gaussian_weights.inc.glsl b/rpcore/shader/includes/gaussian_weights.inc.glsl new file mode 100644 index 0000000..2900e9e --- /dev/null +++ b/rpcore/shader/includes/gaussian_weights.inc.glsl @@ -0,0 +1,242 @@ +/** + * + * RenderPipeline + * + * Copyright (c) 2014-2016 tobspr + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + */ + +// lint: skip-file + +#pragma once + + +// Autogenerated, do not edit! + +// python-script to generate the weights: +/* +from __future__ import print_function +SIGMA = 1.0 +file_handle = open("gaussian_weights.txt", "w") +import math +def gauss(x): + return math.exp( -(x**2) / (2.0 * (SIGMA**2) ) ) +for i in range(2, 40): + weights = [gauss(k / float(i-1) * 3.0) for k in range(0, i)] + wsum = weights[0] + 2 * sum(weights[1:]) + weights = [k / wsum for k in weights] + print("CONST_ARRAY float gaussian_weights_{0}[{0}] = float[{0}]({1});".format(i, ', '.join([str(i) for i in weights])), file=file_handle) +file_handle.close() + +*/ + +CONST_ARRAY float gaussian_weights_2[2] = float[2](0.97826491685, 0.0108675415748); +CONST_ARRAY float gaussian_weights_3[3] = float[3](0.598256825182, 0.194225554409, 0.00664603299992); +CONST_ARRAY float gaussian_weights_4[4] = float[4](0.399050279652, 0.242036229376, 0.0540055826224, 0.00443304817524); +CONST_ARRAY float gaussian_weights_5[5] = float[5](0.299372412212, 0.22597815248, 0.0971919922835, 0.0238179220394, 0.0033257270909); +CONST_ARRAY float gaussian_weights_6[6] = float[6](0.239559410861, 0.200096839755, 0.116606083673, 0.0474084957625, 0.0134476107133, 0.00266126466595); +CONST_ARRAY float gaussian_weights_7[7] = float[7](0.199675627498, 0.176213122789, 0.121109390075, 0.0648251851385, 0.0270231576029, 0.00877313479159, 0.00221819585465); +CONST_ARRAY float gaussian_weights_8[8] = float[8](0.171180679737, 0.156160272964, 0.118554487683, 0.0749026292285, 0.0393829054464, 0.0172325706915, 0.00627514853941, 0.00190164557861); +CONST_ARRAY float gaussian_weights_9[9] = float[9](0.149804857814, 0.139633481336, 0.113078639248, 0.0795607594227, 0.0486345167116, 0.0258295968515, 0.0119184008913, 0.00477799498463, 0.00166418164687); +CONST_ARRAY float gaussian_weights_10[10] = float[10](0.133175996016, 0.125979094462, 0.10663900118, 0.0807753247212, 0.0547502887625, 0.0332077287626, 0.0180234111411, 0.00875346226514, 0.00380423901867, 0.00147945167871); +CONST_ARRAY float gaussian_weights_11[11] = float[11](0.119870627342, 0.114596017885, 0.100124364242, 0.0799509287402, 0.0583472982821, 0.0389162949304, 0.0237222412093, 0.013215799633, 0.00672890923663, 0.00313118978625, 0.00133164238418); +CONST_ARRAY float gaussian_weights_12[12] = float[12](0.108982774698, 0.105004137779, 0.0939186994792, 0.0779820830369, 0.0601083349811, 0.043010220493, 0.0285697042449, 0.0176172016263, 0.0100847516981, 0.00535908443022, 0.00264370561491, 0.00121068926685); +CONST_ARRAY float gaussian_weights_13[13] = float[13](0.099908358105, 0.0968345010773, 0.0881688165699, 0.0754147852673, 0.0605974823522, 0.0457413794603, 0.0324354949685, 0.0216066977333, 0.0135211259418, 0.00794865988767, 0.00438966689848, 0.00227732918643, 0.00110988160433); +CONST_ARRAY float gaussian_weights_14[14] = float[14](0.0922291029445, 0.0898057057742, 0.0829109263623, 0.0725757439402, 0.060234195822, 0.0473987215842, 0.0353640528944, 0.0250166600045, 0.0167790942071, 0.0106703727296, 0.0064337259728, 0.00367804823216, 0.00199362821896, 0.00102457278534); +CONST_ARRAY float gaussian_weights_15[15] = float[15](0.0856461968131, 0.0837022313712, 0.0781310922076, 0.0696576247716, 0.0593159286476, 0.0482427341138, 0.0374757556435, 0.0278052491152, 0.0197043035237, 0.0133368508235, 0.00862190840291, 0.00532367362189, 0.00313962187592, 0.00176848417109, 0.00095144330391); +CONST_ARRAY float gaussian_weights_16[16] = float[16](0.0799404796215, 0.0783575520685, 0.0737943634766, 0.0667719013138, 0.0580487023004, 0.0484863518426, 0.0389112087983, 0.0300025492495, 0.0222264351509, 0.0158201169212, 0.0108187674517, 0.00710843674843, 0.0044874398644, 0.00272176986138, 0.00158610663008, 0.000888058511381); +CONST_ARRAY float gaussian_weights_17[17] = float[17](0.0749475595843, 0.0736416335058, 0.0698588070848, 0.0639809599576, 0.0565733860467, 0.0482953623493, 0.0398043484331, 0.0316728718988, 0.0243319101415, 0.0180466584178, 0.0129225799304, 0.0089337437364, 0.00596279102016, 0.00384235530188, 0.00239043692594, 0.00143578327773, 0.000832592179972); +CONST_ARRAY float gaussian_weights_18[18] = float[18](0.0705417098914, 0.069451816911, 0.0662821365674, 0.0613175289906, 0.0549854836326, 0.047795467276, 0.0402717621111, 0.03289196444, 0.0260407956595, 0.0199845303108, 0.0148665056404, 0.0107201068137, 0.00749315271104, 0.00507697836848, 0.00333442766635, 0.00212281695053, 0.0013100233939, 0.000783647610985); +CONST_ARRAY float gaussian_weights_19[19] = float[19](0.0666251318775, 0.0657061792116, 0.0630246743667, 0.0587964725162, 0.0533492350686, 0.0470805347033, 0.0404101851911, 0.0337346772335, 0.0273904105715, 0.0216300134521, 0.0166131237937, 0.0124102942088, 0.00901673109332, 0.006371657499, 0.00437917188719, 0.00292730399695, 0.00190318025692, 0.0012034506512, 0.000740138359388); +CONST_ARRAY float gaussian_weights_20[20] = float[20](0.0631206079092, 0.0623386696286, 0.0600504962028, 0.0564219880656, 0.0517074216853, 0.0462200163444, 0.0402976778174, 0.0342690969121, 0.0284248389542, 0.0229967296489, 0.0181470844488, 0.0139675538565, 0.0104859205472, 0.00767830721424, 0.00548399588371, 0.00382033519528, 0.00259584365953, 0.00172039554551, 0.00111211782068, 0.000701206614755); +CONST_ARRAY float gaussian_weights_21[21] = float[21](0.0599663578227, 0.0592955168529, 0.0573276870732, 0.0541920219987, 0.0500881123762, 0.0452649816716, 0.0399961700994, 0.0345543588197, 0.0291887599519, 0.024107758111, 0.0194682260256, 0.0153717852441, 0.0118672642019, 0.00895788098686, 0.00661132245055, 0.004770893968, 0.00336619727441, 0.00232224340187, 0.00156640581013, 0.00103306870905, 0.000666166061464); +CONST_ARRAY float gaussian_weights_22[22] = float[22](0.057112364552, 0.0565325485975, 0.0548281807346, 0.0521009873998, 0.0485092901538, 0.0442527977069, 0.0395542717215, 0.0346404001495, 0.0297241370428, 0.0249903568146, 0.0205860255043, 0.0166153465249, 0.0131396303393, 0.0101810773885, 0.00772931803295, 0.00574943890287, 0.004190314276, 0.0029922961728, 0.0020936274558, 0.0014352616483, 0.000964050097101, 0.000634461060099); +CONST_ARRAY float gaussian_weights_23[23] = float[23](0.054517701579, 0.0540131711974, 0.0525274224654, 0.0501414375277, 0.0469820267016, 0.0432106689856, 0.0390098705349, 0.034568640811, 0.030068680835, 0.0256726513374, 0.021515495198, 0.0176993063323, 0.0142917503664, 0.0113276252744, 0.00881285454125, 0.00673005489098, 0.00504481084372, 0.00371189295693, 0.00268083618271, 0.00190050661455, 0.0013224911384, 0.000903317516786, 0.000605636958114); +CONST_ARRAY float gaussian_weights_24[24] = float[24](0.0521485573767, 0.0517068310725, 0.050403975608, 0.0483050916261, 0.0455126658702, 0.042158280221, 0.0383923542943, 0.0343730326211, 0.0302553514918, 0.0261816975872, 0.0222743299567, 0.0186304241426, 0.0153197642695, 0.0123849047314, 0.00984338574556, 0.00769143875473, 0.00590856360058, 0.00446238965579, 0.00331332710032, 0.00241864641078, 0.00173576808421, 0.00122467897537, 0.00084950134862, 0.000579318143372); +CONST_ARRAY float gaussian_weights_25[25] = float[25](0.0499767536015, 0.0495878314194, 0.0484391305418, 0.046583456592, 0.0441043302545, 0.0411097561541, 0.0377244327973, 0.0340811848931, 0.0303124333322, 0.0265424534827, 0.0228810251118, 0.0194188737985, 0.0162250763673, 0.0133463837679, 0.0108082309552, 0.00861707301291, 0.0067636181039, 0.00522651897931, 0.00397612596387, 0.00297798074754, 0.0021958253057, 0.00159399822903, 0.00113917916157, 0.000801512644787, 0.000555191582752); +CONST_ARRAY float gaussian_weights_26[26] = float[26](0.0479786188192, 0.0476344133902, 0.0466165426396, 0.0449681953731, 0.0427579639989, 0.0400751110844, 0.0370235971586, 0.033715425763, 0.0302638965903, 0.0267773256187, 0.0233537009481, 0.0200766102918, 0.0170126208304, 0.0142101353977, 0.0116996095611, 0.00949490624815, 0.00759549623064, 0.00598918576442, 0.00465506312071, 0.00356639567308, 0.00269326838853, 0.00200482238421, 0.00147101916547, 0.00106391496797, 0.000758475690917, 0.000532994310372); +CONST_ARRAY float gaussian_weights_27[27] = float[27](0.0461341220677, 0.0458280361329, 0.0449219092487, 0.0434513364077, 0.041473056502, 0.0390613205401, 0.0363032722123, 0.03329374093, 0.0301298793329, 0.0269060634368, 0.0237094185849, 0.0206162474982, 0.0176895305381, 0.0149775565587, 0.0125136384235, 0.0103167809312, 0.00839310755091, 0.00673781900749, 0.00533745056926, 0.00417221196467, 0.00321822819374, 0.00244954419315, 0.00183980458116, 0.00136356575469, 0.000997237148304, 0.000719678922527, 0.000512503802344); +CONST_ARRAY float gaussian_weights_28[28] = float[28](0.0444261989064, 0.0441528077786, 0.0433426874556, 0.0420253835231, 0.0402481455205, 0.0380731143611, 0.0355737191338, 0.0328305743187, 0.0299271960082, 0.0269458517312, 0.0239638252082, 0.021050320394, 0.0182641563909, 0.0156523252517, 0.0132494072776, 0.0110777708249, 0.00914843153174, 0.00746241242714, 0.00601243221213, 0.00478475249866, 0.00376103264156, 0.00292006868614, 0.00223932625116, 0.00169621154636, 0.00126905661972, 0.000937821796457, 0.000684538667784, 0.000493530489859); +CONST_ARRAY float gaussian_weights_29[29] = float[29](0.0428402218449, 0.0425950320572, 0.0418678504625, 0.0406833639509, 0.0390811670302, 0.0371135646233, 0.0348427391927, 0.0323374960065, 0.0296698234919, 0.0269115067302, 0.0241310123361, 0.0213908255587, 0.0187453704346, 0.0162395871695, 0.0139081837241, 0.0117755263835, 0.00985609128793, 0.00815536834958, 0.00667109187858, 0.00539466821111, 0.00431267799915, 0.00340834700336, 0.00266290118508, 0.00205674653671, 0.00157043864968, 0.00118542928527, 0.000884595662595, 0.000652572000374, 0.000475911876172); +CONST_ARRAY float gaussian_weights_30[30] = float[30](0.0413635803064, 0.0411428442631, 0.0404876787473, 0.0394188384355, 0.0379696981566, 0.0361845223744, 0.034116221224, 0.0318237516855, 0.0293693415551, 0.02681571743, 0.0242235064343, 0.02164895686, 0.0191420884567, 0.0167453427128, 0.0144927613074, 0.0124096809627, 0.0105128984936, 0.00881123336238, 0.00730639779605, 0.00599407677732, 0.00486512123495, 0.00390676609731, 0.00310379858835, 0.00243961912893, 0.00189715540038, 0.0014596077497, 0.00111101978377, 0.000836680798136, 0.000623376159936, 0.000459507870433); +CONST_ARRAY float gaussian_weights_31[31] = float[31](0.0399853445765, 0.0397859168385, 0.0391935817056, 0.0382258887254, 0.0369111251945, 0.0352869427376, 0.0333985672178, 0.0312967106632, 0.0290353194613, 0.0266692976067, 0.0242523374248, 0.0218349741136, 0.019462956678, 0.0171759989834, 0.015006943611, 0.0129813407749, 0.0111174172637, 0.00942638810365, 0.00791304767411, 0.00657656782027, 0.00541142793358, 0.00440840524404, 0.00355556151442, 0.00283917353606, 0.00224456783464, 0.00175683343057, 0.00136139920952, 0.00104447357383, 0.000793353010129, 0.000596612772324, 0.000444197054481); +CONST_ARRAY float gaussian_weights_32[32] = float[32](0.0386959947766, 0.038515219631, 0.0379779455684, 0.0370990921929, 0.035902758976, 0.0344211273781, 0.03269302325, 0.0307622290963, 0.0286756484161, 0.0264814290509, 0.0242271492383, 0.0219581595966, 0.0197161578279, 0.017538052295, 0.0154551477556, 0.0134926634575, 0.0116695723433, 0.00999873179996, 0.00848726229109, 0.00713712091343, 0.00594581251708, 0.00490718118467, 0.00401222890115, 0.00324991525467, 0.00260790097568, 0.00207320803451, 0.00163277896075, 0.001273927269, 0.000984678824041, 0.0007540103176, 0.000571995622223, 0.000429873672017); +CONST_ARRAY float gaussian_weights_33[33] = float[33](0.0374872006405, 0.0373228234108, 0.0368340037493, 0.0360334897628, 0.0349419131486, 0.0335869056163, 0.0320019370398, 0.0302249435008, 0.0282968236112, 0.0262598859882, 0.024156329418, 0.0220268304723, 0.0199093019753, 0.0178378709241, 0.0158421076059, 0.0139465201734, 0.0121703121823, 0.0105273857368, 0.00902656082137, 0.00767197268489, 0.00646360400967, 0.0053979069534, 0.00446847163236, 0.00366670165813, 0.00298246326618, 0.00240468165596, 0.00192186570093, 0.00152254956825, 0.00119564651815, 0.000930715882533, 0.000718148744363, 0.000549281085644, 0.000416445182144); +CONST_ARRAY float gaussian_weights_34[34] = float[34](0.0363516413217, 0.036201737859, 0.0357557262315, 0.0350245510305, 0.0340259562937, 0.0327837698447, 0.0313269586531, 0.0296885074803, 0.0279041813374, 0.0260112363621, 0.0240471434912, 0.0220483849925, 0.0200493760572, 0.0180815530273, 0.0161726573904, 0.0143462314376, 0.0126213284443, 0.0110124282972, 0.00952953936303, 0.00817845959286, 0.00696116464401, 0.00587628821513, 0.00491965967439, 0.00408486607427, 0.00336380935028, 0.00274723438686, 0.00222520918402, 0.0017875440918, 0.00142414258053, 0.00112528095772, 0.000881818604268, 0.00068534355663, 0.000528260575697, 0.000403830257603); +CONST_ARRAY float gaussian_weights_35[35] = float[35](0.0352828569912, 0.0351457772102, 0.0347377250654, 0.034068138963, 0.0331523456006, 0.0320109768082, 0.0306691971283, 0.0291557825023, 0.027502097108, 0.025741019002, 0.0239058656123, 0.0220293674457, 0.0201427329382, 0.0182748397359, 0.0164515784956, 0.0146953652717, 0.0130248284398, 0.0114546665776, 0.00999566534574, 0.00865485462404, 0.0074357822241, 0.00633887752729, 0.00536187733782, 0.00450028691203, 0.00374785124891, 0.00309701495804, 0.00253935298702, 0.00206595882394, 0.00166778115643, 0.00133590408651, 0.00106176965372, 0.000837344464398, 0.000655234585795, 0.000508754527564, 0.000391957136174); +CONST_ARRAY float gaussian_weights_36[36] = float[36](0.0342751258684, 0.0341494482206, 0.0337751734808, 0.0331604756171, 0.0323186475622, 0.0312676233073, 0.0300293428847, 0.0286289916303, 0.0270941505287, 0.0254538975676, 0.0237379007598, 0.021975541872, 0.0201951061634, 0.0184230679295, 0.0166834948398, 0.0149975864603, 0.013383354516, 0.0118554448693, 0.0104250943304, 0.00910020962319, 0.0078855513561, 0.00678300282029, 0.00579190187853, 0.0049094140256, 0.00413092573351, 0.00345043921075, 0.0028609524436, 0.00235481157601, 0.00192402606174, 0.00156054035493, 0.00125645900204, 0.00100422471517, 0.000796751251198, 0.000627514647567, 0.000490607571324, 0.00038076225462); +CONST_ARRAY float gaussian_weights_37[37] = float[37](0.0333233617429, 0.0332078562721, 0.0328637365047, 0.0322981096857, 0.0315225495765, 0.030552702685, 0.0294077635218, 0.0281098434571, 0.0266832621385, 0.025153793115, 0.0235478961881, 0.0218919680964, 0.0202116405818, 0.0185311509155, 0.0168728049169, 0.0152565467323, 0.0136996435735, 0.0122164876079, 0.0108185116105, 0.00951421011541, 0.00830925385448, 0.00720668238666, 0.00620715804382, 0.00530926362864, 0.00450982659987, 0.00380425362601, 0.00318686120024, 0.00265119028911, 0.00219029553592, 0.00179700217107, 0.00146412633301, 0.00118465684373, 0.000951898516011, 0.000759578735218, 0.000601920330354, 0.000473684629482, 0.000370189110245); +CONST_ARRAY float gaussian_weights_38[38] = float[38](0.0324230281088, 0.0323166262891, 0.0319995113068, 0.0314778862896, 0.0307618652238, 0.0298651468432, 0.028804578888, 0.02759963209, 0.0262718068088, 0.0248439975284, 0.0233398413379, 0.0217830760655, 0.0201969319937, 0.0186035782268, 0.0170236410318, 0.0154758070976, 0.0139765199563, 0.0125397730562, 0.011176998459, 0.00989704607063, 0.00870624489846, 0.00760853518304, 0.00660565843784, 0.00569739146478, 0.0048818102413, 0.00415557011334, 0.00351418985579, 0.00295232873728, 0.00246404760181, 0.00204304700967, 0.00168287753264, 0.00137711925802, 0.00111952933378, 0.000904157917575, 0.000725434137119, 0.000578224612709, 0.000457867740317, 0.00036018730702); +CONST_ARRAY float gaussian_weights_39[39] = float[39](0.0315700658546, 0.0314718358241, 0.0311789757839, 0.0306969191808, 0.0300345351942, 0.0292038573418, 0.0282197199596, 0.0270993178919, 0.0258617076395, 0.0245272701486, 0.0231171563159, 0.0216527361219, 0.0201550711348, 0.0186444280746, 0.0171398483337, 0.0156587850296, 0.0142168155126, 0.0128274335027, 0.0115019213772, 0.0102492997744, 0.00907634875668, 0.00798769241821, 0.00698593707642, 0.00607185210057, 0.0052445819707, 0.00450187828841, 0.00384034109358, 0.00325565988292, 0.00274284606771, 0.00229645013991, 0.00191075843051, 0.00157996594715, 0.00129832328924, 0.00106025699581, 0.000860463840048, 0.00069398052067, 0.000556230904611, 0.000443053455279, 0.000350711752291); + + + +// Offsets and weights for n = 2, relative to pixel center +CONST_ARRAY float opt_gaussian_weights_2[] = float[2] (0.274068619061, 0.725931380939); +CONST_ARRAY float opt_gaussian_offsets_2[] = float[2] (-1.0, 0.377540668798); + +// Offsets and weights for n = 3, relative to pixel center +CONST_ARRAY float opt_gaussian_weights_3[] = float[3] (0.15246914402, 0.473220416416, 0.374310439564); +CONST_ARRAY float opt_gaussian_offsets_3[] = float[3] (-2.0, -0.468790626626, 1.40733340005); + +// Offsets and weights for n = 4, relative to pixel center +CONST_ARRAY float opt_gaussian_weights_4[] = float[4] (0.106288519406, 0.306091409205, 0.341010215168, 0.24660985622); +CONST_ARRAY float opt_gaussian_offsets_4[] = float[4] (-2.0, -0.458429516783, 1.48611468225, 3.43099866743); + +// Offsets and weights for n = 5, relative to pixel center +CONST_ARRAY float opt_gaussian_weights_5[] = float[5] (0.0816744222584, 0.220481043971, 0.265173712396, 0.249350938326, 0.183319883049); +CONST_ARRAY float opt_gaussian_offsets_5[] = float[5] (-3.0, -1.46101677931, 0.507811864279, 2.47657965106, 4.44552953504); + +// Offsets and weights for n = 6, relative to pixel center +CONST_ARRAY float opt_gaussian_weights_6[] = float[6] (0.0663416657403, 0.170786343946, 0.208182532594, 0.216591983241, 0.192330414616, 0.145767059863); +CONST_ARRAY float opt_gaussian_offsets_6[] = float[6] (-3.0, -1.46505705484, 0.514995501619, 2.49500016666, 4.47502081252, 6.45512110763); + +// Offsets and weights for n = 7, relative to pixel center +CONST_ARRAY float opt_gaussian_weights_7[] = float[7] (0.0558645795815, 0.138837939971, 0.168410194672, 0.182939846093, 0.177962436458, 0.155034498765, 0.12095050446); +CONST_ARRAY float opt_gaussian_offsets_7[] = float[7] (-4.0, -2.46879062663, -0.482645862567, 1.50347216641, 3.48958484011, 5.47571357137, 7.46187967409); + +// Offsets and weights for n = 8, relative to pixel center +CONST_ARRAY float opt_gaussian_weights_8[] = float[8] (0.0482490884887, 0.116731177798, 0.140135626714, 0.155109457758, 0.158290996847, 0.148936931244, 0.12920422877, 0.10334249238); +CONST_ARRAY float opt_gaussian_offsets_8[] = float[8] (-4.0, -2.47196820019, -0.482150445594, 1.50765246363, 3.49744900173, 5.48724766412, 7.47705693918, 9.46688527998); + +// Offsets and weights for n = 9, relative to pixel center +CONST_ARRAY float opt_gaussian_weights_9[] = float[9] (0.042462603473, 0.100587552233, 0.119370554051, 0.133110608252, 0.139473180769, 0.137319230357, 0.127038284604, 0.110433394405, 0.0902045918559); +CONST_ARRAY float opt_gaussian_offsets_9[] = float[9] (-5.0, -3.47463117774, -1.48242911339, 0.509764383426, 2.50195311507, 4.49414089321, 6.48633153138, 8.47852883754, 10.4707366066); + +// Offsets and weights for n = 10, relative to pixel center +CONST_ARRAY float opt_gaussian_weights_10[] = float[10] (0.0379163821476, 0.0883084946127, 0.103630848659, 0.115769751833, 0.12311774987, 0.124642393984, 0.120124182183, 0.110208385676, 0.0962539004871, 0.0800279105479); +CONST_ARRAY float opt_gaussian_offsets_10[] = float[10] (-5.0, -3.47686837586, -1.48303121052, 0.510800788681, 2.50462949733, 4.49845679502, 6.49228456308, 8.48611468225, 10.4799490304, 12.4737894803); + +// Offsets and weights for n = 11, relative to pixel center +CONST_ARRAY float opt_gaussian_weights_11[] = float[11] (0.034250034987, 0.0786680908358, 0.0913650297743, 0.101960743385, 0.109334598331, 0.112655883289, 0.111537726901, 0.106111230043, 0.0970001809665, 0.0852030922382, 0.0719133892488); +CONST_ARRAY float opt_gaussian_offsets_11[] = float[11] (-6.0, -4.47876278503, -2.48375571894, -0.488751898053, 1.5062496745, 3.5012499974, 5.49625007031, 7.49125089312, 9.4862534651, 11.4812587841, 13.4762678459); + +// Offsets and weights for n = 12, relative to pixel center +CONST_ARRAY float opt_gaussian_weights_12[] = float[12] (0.0312305401816, 0.0709054311219, 0.0815774390232, 0.0908099474451, 0.0978069207462, 0.101924493536, 0.10276858031, 0.100257061632, 0.0946329555381, 0.0864256482923, 0.0763687507926, 0.0652922313807); +CONST_ARRAY float opt_gaussian_offsets_12[] = float[12] (-6.0, -4.48038197724, -2.48450909152, -0.488638319781, 1.5072309008, 3.50309913386, 5.49896694362, 7.49483489448, 9.49070355081, 11.4865734766, 13.482445235, 15.4783193884); + +// Offsets and weights for n = 13, relative to pixel center +CONST_ARRAY float opt_gaussian_weights_13[] = float[13] (0.0287005193039, 0.0645245840776, 0.0736085919864, 0.0816749725356, 0.0881468265092, 0.0925297883119, 0.0944742956035, 0.093821628, 0.0906253035588, 0.0851438313916, 0.0778061819627, 0.0691563739381, 0.0597871028205); +CONST_ARRAY float opt_gaussian_offsets_13[] = float[13] (-7.0, -5.48177890584, -3.48524733884, -1.48871719346, 0.507811864279, 2.50434016876, 4.50086805468, 6.49739585688, 8.49392391023, 10.4904525495, 12.4869821093, 14.4835129238, 16.4800453267); + +// Offsets and weights for n = 14, relative to pixel center +CONST_ARRAY float opt_gaussian_weights_14[] = float[14] (0.0265498357372, 0.0591891116629, 0.067008146258, 0.0740882641635, 0.080003184581, 0.084372549444, 0.0869022686967, 0.0874172424738, 0.0858814043683, 0.0824018985422, 0.0772167186324, 0.0706677895493, 0.0631637213247, 0.0551378645661); +CONST_ARRAY float opt_gaussian_offsets_14[] = float[14] (-7.0, -5.482994727, -3.48595044497, -1.48890714597, 0.508135376648, 2.50517732975, 4.50221892034, 6.49926035557, 8.49630184259, 10.4933435885, 12.4903858005, 14.4874286855, 16.4844724502, 18.4815173012); + +// Offsets and weights for n = 15, relative to pixel center +CONST_ARRAY float opt_gaussian_weights_15[] = float[15] (0.0246991001359, 0.0546630307477, 0.0614599000867, 0.0677077117875, 0.0730857269119, 0.0772992275365, 0.0801061552404, 0.0813401134339, 0.0809266963759, 0.0788909166077, 0.0753546997316, 0.0705247954691, 0.0646727718699, 0.0581097839419, 0.0511593701234); +CONST_ARRAY float opt_gaussian_offsets_15[] = float[15] (-8.0, -6.48406152432, -4.48661034495, -2.48915986216, -0.491709943445, 1.5057395438, 3.50318873228, 5.50063775476, 7.49808674403, 9.49553583291, 11.4929851542, 13.4904348406, 15.4878850248, 17.4853358393, 19.4827874166); + +// Offsets and weights for n = 16, relative to pixel center +CONST_ARRAY float opt_gaussian_weights_16[] = float[16] (0.0230896376799, 0.050776085665, 0.0567362408729, 0.0622801542701, 0.0671624585612, 0.0711526823588, 0.074053187201, 0.0757153650032, 0.0760522510849, 0.0750460631044, 0.0727497562674, 0.0692824055002, 0.0648189750606, 0.0595756988869, 0.0537927708459, 0.0477162676376); +CONST_ARRAY float opt_gaussian_offsets_16[] = float[16] (-8.0, -6.48500449838, -4.48722500316, -2.48944601229, -0.491667438186, 1.50611080683, 3.50388881047, 5.50166666049, 7.49944444467, 9.4972222508, 11.4950001667, 13.49277828, 15.4905566786, 17.4883354502, 19.4861146823, 21.4838944625); + +// Offsets and weights for n = 17, relative to pixel center +CONST_ARRAY float opt_gaussian_weights_17[] = float[17] (0.0216771440358, 0.0474024431083, 0.0526696583526, 0.0576157272943, 0.0620500832243, 0.0657906931345, 0.0686763697103, 0.0705782641713, 0.0714094011985, 0.0711312736702, 0.0697568007769, 0.0673493330105, 0.0640178107627, 0.0599085918637, 0.0551948018209, 0.0500642848839, 0.0447073189814); +CONST_ARRAY float opt_gaussian_offsets_17[] = float[17] (-9.0, -7.48584362821, -5.48779539349, -3.489747531, -1.49169998126, 0.506347315253, 2.5043944181, 4.50244138685, 6.50048828109, 8.49853516044, 10.4965820845, 12.4946291128, 14.4926763051, 16.4907237208, 18.4887714194, 20.4868194606, 22.4848679037); + +// Offsets and weights for n = 18, relative to pixel center +CONST_ARRAY float opt_gaussian_weights_18[] = float[18] (0.0204275387753, 0.0444471422165, 0.0491344246582, 0.0535700569458, 0.0576039868414, 0.0610909922542, 0.063899287897, 0.0659187647663, 0.0670681468019, 0.0673004170345, 0.0666060084333, 0.0650134576635, 0.062587459498, 0.0594245067401, 0.0556465251586, 0.0513930883489, 0.0468129040831, 0.0420552918834); +CONST_ARRAY float opt_gaussian_offsets_18[] = float[18] (-9.0, -7.48659490868, -5.48832392241, -3.49005321559, -1.49178274685, 0.506487525174, 2.50475764187, 4.50302764466, 6.50129757494, 8.49956747416, 10.4978373837, 12.4961073451, 14.4943773996, 16.4926475888, 18.490917954, 20.4891885367, 22.487459378, 24.4857305195); + +// Offsets and weights for n = 19, relative to pixel center +CONST_ARRAY float opt_gaussian_weights_19[] = float[19] (0.0193141765234, 0.0418372042117, 0.0460345037418, 0.0500318718292, 0.0537096734822, 0.0569509205974, 0.0596473922603, 0.0617056100684, 0.0630522103997, 0.063638283716, 0.0634423231446, 0.0624715344916, 0.0607613964306, 0.058373508293, 0.0553919075004, 0.0519181635644, 0.0480656477248, 0.0439534278952, 0.0397002441254); +CONST_ARRAY float opt_gaussian_offsets_19[] = float[19] (-10.0, -8.48727126934, -6.48881359538, -4.49035613443, -2.49189885715, -0.493441734166, 1.50501526389, 3.50347216641, 5.50192900278, 7.50038580239, 9.49884259466, 11.497299409, 13.4957562747, 15.4942132214, 17.4926702782, 19.4911274747, 21.4895848401, 23.4880424039, 25.4865001954); + +// Offsets and weights for n = 20, relative to pixel center +CONST_ARRAY float opt_gaussian_weights_20[] = float[20] (0.0183159239212, 0.0395156384342, 0.0432953808504, 0.0469143095749, 0.0502759514807, 0.0532851842709, 0.0558526585709, 0.0578991827119, 0.0593597716547, 0.0601870718495, 0.0603539103928, 0.0598547770814, 0.0587061266098, 0.0569454777934, 0.0546293785999, 0.0518303909461, 0.0486333194666, 0.0451309573637, 0.0414196460388, 0.0375949423883); +CONST_ARRAY float opt_gaussian_offsets_20[] = float[20] (-10.0, -8.48788325916, -6.48926757672, -4.4906520589, -2.4920366845, -0.493421432277, 1.50519371901, 3.50380879059, 5.50242380373, 7.50103877967, 9.49965373967, 11.498268705, 13.4968836969, 15.4954987366, 17.4941138453, 19.4927290444, 21.4913443551, 23.4899597986, 25.488575396, 27.4871911687); + +// Offsets and weights for n = 21, relative to pixel center +CONST_ARRAY float opt_gaussian_weights_21[] = float[21] (0.017415804187, 0.0374373032386, 0.0408584208729, 0.0441487454036, 0.0472296714025, 0.050023174672, 0.0524550548792, 0.0544581909425, 0.0559756111883, 0.0569631828342, 0.0573917437838, 0.0572485330749, 0.0565378220739, 0.0552807028518, 0.0535140483716, 0.0512887160172, 0.0486671165854, 0.0457203108183, 0.0425248216691, 0.0391593610009, 0.0357016641323); +CONST_ARRAY float opt_gaussian_offsets_21[] = float[21] (-11.0, -9.48843956064, -7.48968896203, -5.49093849226, -3.49218813572, -1.49343787681, 0.505312300099, 2.50406241061, 4.50281247034, 6.50156249491, 8.50031249996, 10.4990625011, 12.497812514, 14.4965625542, 16.4953126373, 18.4940627791, 20.492812995, 22.4915633008, 24.490313712, 26.4890642443, 28.4878149131); + +// Offsets and weights for n = 22, relative to pixel center +CONST_ARRAY float opt_gaussian_weights_22[] = float[22] (0.0166000229565, 0.0355659864281, 0.0386768958381, 0.0416803556939, 0.044511709669, 0.047106429585, 0.0494025259225, 0.0513429921806, 0.0528781496068, 0.0539677581387, 0.0545827685096, 0.0547066090713, 0.0543359277732, 0.0534807429267, 0.05216399329, 0.0504205156771, 0.0482955136927, 0.0458426115287, 0.0431216096972, 0.040196073531, 0.0371308894807, 0.0339899188026); +CONST_ARRAY float opt_gaussian_offsets_22[] = float[22] (-11.0, -9.48894737902, -7.49008066671, -5.49121405638, -3.49234753637, -1.49348109503, 0.505385279274, 2.50425159821, 4.50311787342, 6.50198411657, 8.50085033932, 10.4997165533, 12.4985827702, 14.4974490017, 16.4963152595, 18.4951815551, 20.4940479002, 22.4929143066, 24.4917807858, 26.4906473495, 28.4895140094, 30.488380777); + +// Offsets and weights for n = 23, relative to pixel center +CONST_ARRAY float opt_gaussian_weights_23[] = float[23] (0.0158572558637, 0.0338723065065, 0.0367131374703, 0.0394648878577, 0.0420739114357, 0.0444864291153, 0.0466503437274, 0.0485170953621, 0.0500434658737, 0.0511932393217, 0.0519386294298, 0.0522613955547, 0.0521535845943, 0.0516178567066, 0.0506673762143, 0.0493252739403, 0.0476237116354, 0.0456026013273, 0.0433080507681, 0.0407906194304, 0.0381034769055, 0.0353005567664, 0.0324347941928); +CONST_ARRAY float opt_gaussian_offsets_23[] = float[23] (-12.0, -10.4894127398, -8.49044537813, -6.49147809805, -4.49251089071, -2.49354374729, -0.494576658982, 1.50439038303, 3.50335738756, 5.50232436342, 7.50129131944, 9.50025826444, 11.4992252072, 13.4981921566, 15.4971591215, 17.4961261106, 19.4950931327, 21.4940601968, 23.4930273116, 25.4919944858, 27.4909617284, 29.4899290482, 31.4888964539); + +// Offsets and weights for n = 24, relative to pixel center +CONST_ARRAY float opt_gaussian_weights_24[] = float[24] (0.0151781193223, 0.0323321780903, 0.0349364627792, 0.0374662789601, 0.0398767590653, 0.0421227588364, 0.0441602397335, 0.0459476917322, 0.0474475330031, 0.0486274208977, 0.0494614105199, 0.0499309029722, 0.0500253348908, 0.0497425735707, 0.0490889970417, 0.0480792548951, 0.0467357223884, 0.0450876762325, 0.0431702344581, 0.0410231139437, 0.0386892669072, 0.0362134615119, 0.0336408715991, 0.0310157366487); +CONST_ARRAY float opt_gaussian_offsets_24[] = float[24] (-12.0, -10.4898407179, -8.49078554242, -6.49173043279, -4.49267538225, -2.49362038404, -0.494565431416, 1.50448948237, 3.50354436407, 5.50259922044, 7.50165405824, 9.50070888421, 11.4997637051, 13.4988185277, 15.4978733588, 17.496928205, 19.4959830732, 21.4950379701, 23.4940929025, 25.493147877, 27.4922029006, 29.4912579798, 31.4903131215, 33.4893683324); + +// Offsets and weights for n = 25, relative to pixel center +CONST_ARRAY float opt_gaussian_weights_25[] = float[25] (0.0145547717977, 0.0309256724585, 0.0333216402417, 0.0356548788588, 0.0378875858988, 0.0399816099167, 0.0418995150216, 0.0436056826279, 0.0450674056297, 0.0462559283339, 0.0471473860962, 0.047723601823, 0.0479727022219, 0.0478895246213, 0.0474757948889, 0.0467400678857, 0.0456974333241, 0.0443690011569, 0.04278119101, 0.0409648590605, 0.0389543026351, 0.0367861873003, 0.0344984431302, 0.032129176157, 0.0297156379033); +CONST_ARRAY float opt_gaussian_offsets_25[] = float[25] (-13.0, -11.4902356166, -9.49110336963, -7.49197117629, -5.49283903134, -3.49370692955, -1.49457486569, 0.504557165471, 2.50368916916, 4.50282115062, 6.50195311507, 8.50108506774, 10.5002170139, 12.4993489587, 14.4984809075, 16.4976128654, 18.4967448377, 20.4958768296, 22.4950088463, 24.4941408932, 26.4932729754, 28.4924050981, 30.4915372666, 32.4906694861, 34.4898017618); + +// Offsets and weights for n = 26, relative to pixel center +CONST_ARRAY float opt_gaussian_weights_26[] = float[26] (0.0139806095106, 0.0296361596261, 0.0318477401908, 0.0340061091799, 0.0360791996382, 0.0380345665842, 0.0398402151893, 0.0414654617847, 0.0428817957719, 0.0440637088489, 0.0449894579767, 0.0456417302531, 0.0460081813069, 0.0460818238265, 0.0458612491398, 0.0453506720284, 0.0445597967842, 0.0435035104568, 0.0422014168346, 0.0406772315419, 0.0389580643162, 0.0370736187825, 0.0350553426473, 0.0329355621081, 0.0307466334336, 0.028520142239); +CONST_ARRAY float opt_gaussian_offsets_26[] = float[26] (-13.0, -11.4906011073, -9.49140084797, -7.49220063267, -5.4930004573, -3.49380031775, -1.49460020994, 0.504599870223, 2.50379992684, 4.502999964, 6.5021999858, 8.50139999634, 10.5005999997, 12.4998, 14.4990000013, 16.4982000078, 18.4974000234, 20.4966000524, 22.4958000988, 24.4950001667, 26.4942002601, 28.4934003833, 30.4926005403, 32.4918007351, 34.4910009719, 36.4902012547); + +// Offsets and weights for n = 27, relative to pixel center +CONST_ARRAY float opt_gaussian_weights_27[] = float[27] (0.0134500314681, 0.028449654128, 0.0304972623514, 0.0324994402414, 0.0344288143118, 0.0362576299487, 0.0379584017792, 0.0395045923815, 0.040871296279, 0.0420359047813, 0.0429787269811, 0.0436835431173, 0.0441380685956, 0.0443343101221, 0.0442687995259, 0.0439426957131, 0.043361750565, 0.0425361401822, 0.0414801683926, 0.0402118545935, 0.0387524225201, 0.0371257101947, 0.0353575239501, 0.0334749609143, 0.0315057246655, 0.0294774579359, 0.0274171143604); +CONST_ARRAY float opt_gaussian_offsets_27[] = float[27] (-14.0, -12.4909403408, -10.4916797622, -8.49241922001, -6.493158711, -4.49389823193, -2.49463777955, -0.495377350649, 1.50388305803, 3.50314344971, 5.50240382763, 7.50166419504, 9.50092455516, 11.5001849112, 13.4994452665, 15.4987056242, 17.4979659876, 19.4972263598, 21.4964867442, 23.495747144, 25.4950075624, 27.4942680026, 29.4935284679, 31.4927889616, 33.4920494867, 35.4913100467, 37.4905706447); + +// Offsets and weights for n = 28, relative to pixel center +CONST_ARRAY float opt_gaussian_weights_28[] = float[28] (0.0129582560674, 0.0273543103165, 0.0292554660583, 0.0311176025635, 0.0329172158359, 0.0346304326621, 0.0362335258515, 0.0377034536229, 0.0390184062889, 0.0401583422803, 0.0411054951919, 0.0418448339636, 0.0423644595612, 0.0426559235313, 0.0427144565149, 0.0425390980829, 0.0421327229529, 0.0415019625886, 0.0406570251689, 0.0396114207574, 0.0383816020104, 0.0369865337755, 0.0354472073009, 0.0337861164192, 0.0320267139071, 0.030192866258, 0.0283083243587, 0.0263962261095); +CONST_ARRAY float opt_gaussian_offsets_28[] = float[28] (-14.0, -12.4912560356, -10.4919417129, -8.49262742053, -6.4933131559, -4.49399891644, -2.49468469955, -0.495370502671, 1.50394367679, 3.50325784141, 5.50257199378, 7.50188613646, 9.50120027204, 11.5005144031, 13.4998285322, 15.499142662, 17.498456795, 19.4977709338, 21.497085081, 23.4963992392, 25.4957134109, 27.4950275988, 29.4943418053, 31.4936560332, 33.4929702849, 35.4922845631, 37.4915988703, 39.4909132091); + +// Offsets and weights for n = 29, relative to pixel center +CONST_ARRAY float opt_gaussian_weights_29[] = float[29] (0.0125011765317, 0.0263400288238, 0.0281098505852, 0.0298459733379, 0.0315281054522, 0.0331356062206, 0.0346478974098, 0.036044895224, 0.0373074502411, 0.0384177819917, 0.0393598944759, 0.0401199590865, 0.040686652145, 0.0410514355414, 0.0412087707617, 0.0411562588012, 0.0408947010275, 0.0404280788327, 0.039763452797, 0.0389107849351, 0.037882690277, 0.0366941264423, 0.0353620318792, 0.0339049249866, 0.03234247735, 0.030695074782, 0.0289833797506, 0.0272279081406, 0.0254486321699); +CONST_ARRAY float opt_gaussian_offsets_29[] = float[29] (-15.0, -13.4915505493, -11.4921881357, -9.49282574751, -7.49346338263, -5.49410103902, -3.49473871461, -1.49537640731, 0.503985884951, 2.50334816424, 4.50271043263, 6.50207269221, 8.50143494504, 10.5007971932, 12.5001594388, 14.4995216838, 16.4988839304, 18.4982461807, 20.4976084366, 22.4969707003, 24.4963329739, 26.4956952594, 28.4950575589, 30.4944198745, 32.4937822083, 34.4931445623, 36.4925069386, 38.4918693392, 40.4912317663); + +// Offsets and weights for n = 30, relative to pixel center +CONST_ARRAY float opt_gaussian_weights_30[] = float[30] (0.0120752459112, 0.0253981466755, 0.0270497479603, 0.0286720947252, 0.0302475794896, 0.031758269856, 0.0331862397737, 0.0345139179849, 0.0357244443761, 0.0368020242498, 0.0377322701791, 0.038502521139, 0.0391021290372, 0.0395227035884, 0.0397583076624, 0.0398055967488, 0.0396638979611, 0.0393352259681, 0.0388242353293, 0.0381381108078, 0.0372863992743, 0.0362807887003, 0.0351348413894, 0.033863689954, 0.0324837055512, 0.0310121485206, 0.0294668117938, 0.0278656672835, 0.0262265249262, 0.0245667131829); +CONST_ARRAY float opt_gaussian_offsets_30[] = float[30] (-15.0, -13.4918259364, -11.4924203191, -9.49301472323, -7.49360914711, -5.49420358906, -3.49479804739, -1.49539252043, 0.504012993496, 2.50341849608, 4.502823989, 6.50222947393, 8.50163495256, 10.5010404266, 12.5004458976, 14.4998513674, 16.4992568376, 18.49866231, 20.4980677861, 22.4974732676, 24.4968787564, 26.4962842539, 28.4956897619, 30.4950952822, 32.4945008163, 34.4939063659, 36.4933119328, 38.4927175186, 40.492123125, 42.4915287536); + +// Offsets and weights for n = 31, relative to pixel center +CONST_ARRAY float opt_gaussian_weights_31[] = float[31] (0.0116773848279, 0.0245211910437, 0.0260660009978, 0.0275852924479, 0.0290637143118, 0.0304856161901, 0.0318353169301, 0.0330973876259, 0.0342569420705, 0.0352999271142, 0.0362134050695, 0.0369858202625, 0.0376072420704, 0.0380695773066, 0.0383667456063, 0.0384948125006, 0.038452076108, 0.0382391047728, 0.0378587244857, 0.0373159564788, 0.0366179069173, 0.0357736120795, 0.0347938437368, 0.0336908805939, 0.0324782525631, 0.0311704653064, 0.0297827128626, 0.0283305862735, 0.0268297859433, 0.0252958450278, 0.0237438704745); +CONST_ARRAY float opt_gaussian_offsets_31[] = float[31] (-16.0, -14.4920839948, -12.4926394207, -10.4931948647, -8.4937503255, -6.49430580175, -4.49486129205, -2.49541679504, -0.495972309343, 1.50347216641, 3.50291663358, 5.50236109356, 7.50180554771, 9.5012499974, 11.500694444, 13.5001388889, 15.4995833334, 17.499027779, 19.498472227, 21.4979166787, 23.4973611356, 25.496805599, 27.4962500703, 29.4956945509, 31.495139042, 33.4945835452, 35.4940280618, 37.4934725931, 39.4929171405, 41.4923617054, 43.4918062891); + +// Offsets and weights for n = 32, relative to pixel center +CONST_ARRAY float opt_gaussian_weights_32[] = float[32] (0.011304906882, 0.0237026819171, 0.0251507065416, 0.0265763713896, 0.0279662329755, 0.0293065739824, 0.0305836224684, 0.0317837831985, 0.0328938757947, 0.033901373955, 0.0347946397202, 0.0355631466938, 0.0361976862432, 0.0366905510441, 0.0370356908544, 0.0372288361197, 0.037267585878, 0.037151457434, 0.0368818963668, 0.0364622465804, 0.0358976812639, 0.0351950967552, 0.0343629723527, 0.0334112000569, 0.0323508890215, 0.0311941501124, 0.0299538664055, 0.0286434556815, 0.0272766310021, 0.0258671652733, 0.0244286653474, 0.0229743606882); +CONST_ARRAY float opt_gaussian_offsets_32[] = float[32] (-16.0, -14.492326305, -12.4928464819, -10.4933666743, -8.49388688111, -6.49440710113, -4.49492733326, -2.49544757637, -0.495967829348, 1.50351190895, 3.50299163964, 5.50247136385, 7.50195108271, 9.50143079734, 11.5009105089, 13.5003902184, 15.4998699272, 17.4993496362, 19.4988293466, 21.4983090595, 23.4977887761, 25.4972684975, 27.4967482248, 29.4962279592, 31.4957077017, 33.4951874535, 35.4946672158, 37.4941469895, 39.493626776, 41.4931065762, 43.4925863914, 45.4920662227); + +// Offsets and weights for n = 33, relative to pixel center +CONST_ARRAY float opt_gaussian_weights_33[] = float[33] (0.010955457899, 0.022936972726, 0.0242970090863, 0.0256373708328, 0.0269462357952, 0.0282115324444, 0.0294211199518, 0.0305629784405, 0.0316254053597, 0.0325972135674, 0.0334679264771, 0.0342279655323, 0.0348688253347, 0.0353832319562, 0.0357652803168, 0.0360105470026, 0.0361161755112, 0.0360809316269, 0.0359052274243, 0.0355911132491, 0.035142237893, 0.0345637780447, 0.0338623389239, 0.0330458287657, 0.0321233104888, 0.0311048344353, 0.0300012564944, 0.0288240461997, 0.0275850895258, 0.0262964910892, 0.0249703803037, 0.0236187257427, 0.0222531615586); +CONST_ARRAY float opt_gaussian_offsets_33[] = float[33] (-17.0, -15.4925542614, -13.4930424413, -11.4935306345, -9.49401884001, -7.49450705693, -5.49499528434, -3.49548352128, -1.49597176684, 0.503539979913, 2.50305171992, 4.5025634541, 6.5020751834, 8.50158690873, 10.501098631, 12.5006103513, 14.5001220703, 16.4996337891, 18.4991455086, 20.4986572298, 22.4981689535, 24.4976806807, 26.4971924123, 28.4967041493, 30.4962158926, 32.495727643, 34.4952394017, 36.4947511694, 38.4942629471, 40.4937747358, 42.4932865363, 44.4927983496, 46.4923101767); + +// Offsets and weights for n = 34, relative to pixel center +CONST_ARRAY float opt_gaussian_weights_34[] = float[34] (0.0106269661092, 0.0222191206788, 0.0234989336619, 0.0247613662628, 0.0259959812184, 0.0271921148783, 0.0283390259971, 0.029426053101, 0.0304427772918, 0.031379187067, 0.03222584155, 0.03297402843, 0.0336159129307, 0.0341446742532, 0.0345546261735, 0.0348413188147, 0.0350016190478, 0.0350337674884, 0.0349374106417, 0.0347136073722, 0.0343648095349, 0.0338948172612, 0.0333087100411, 0.0326127553496, 0.0318142971136, 0.0309216267959, 0.0299438402574, 0.0288906838477, 0.0277723933565, 0.0265995295291, 0.025382813813, 0.0241329678608, 0.0228605600791, 0.0215758621912); +CONST_ARRAY float opt_gaussian_offsets_34[] = float[34] (-17.0, -15.4927690992, -13.493228146, -11.4936872042, -9.49414627298, -7.49460535168, -5.49506443947, -3.49552353559, -1.49598263925, 0.503558250306, 2.50309913386, 4.5026400122, 6.50218088608, 8.50172175628, 10.5012626236, 12.5008034887, 14.5003443526, 16.4998852158, 18.4994260792, 20.4989669436, 22.4985078098, 24.4980486784, 26.4975895504, 28.4971304264, 30.4966713072, 32.4962121937, 34.4957530865, 36.4952939865, 38.4948348945, 40.4943758111, 42.4939167373, 44.4934576737, 46.4929986211, 48.4925395803); + +// Offsets and weights for n = 35, relative to pixel center +CONST_ARRAY float opt_gaussian_weights_35[] = float[35] (0.0103176010324, 0.0215447805499, 0.0227512495695, 0.0239423078106, 0.025108706565, 0.0262409919812, 0.0273296287144, 0.0283651308048, 0.0293381973431, 0.0302398502594, 0.0310615714112, 0.0317954360651, 0.0324342398575, 0.0329716163978, 0.0334021428322, 0.0337214309223, 0.033926201499, 0.034014340527, 0.0339849354379, 0.0338382908596, 0.0335759233627, 0.0332005353504, 0.0327159687203, 0.0321271394105, 0.0314399543874, 0.0306612130365, 0.0297984952565, 0.0288600388309, 0.027854608845, 0.0267913620359, 0.0256797089935, 0.0245291770894, 0.0233492768839, 0.0221493745731, 0.0209385727842); +CONST_ARRAY float opt_gaussian_offsets_35[] = float[35] (-18.0, -16.4929719162, -14.4934043618, -12.4938368174, -10.4942692821, -8.49470175541, -6.49513423665, -4.49556672518, -2.49599922033, -0.49643172148, 1.50313577204, 3.50270326086, 5.50227074563, 7.50183822701, 9.50140570564, 11.5009731822, 13.5005406572, 15.5001081315, 17.4996756056, 19.4992430802, 21.4988105559, 23.4983780334, 25.4979455133, 27.4975129963, 29.497080483, 31.4966479741, 33.4962154702, 35.495782972, 37.49535048, 39.4949179951, 41.4944855177, 43.4940530486, 45.4936205884, 47.4931881378, 49.4927556973); + +// Offsets and weights for n = 36, relative to pixel center +CONST_ARRAY float opt_gaussian_weights_36[] = float[36] (0.0100257393422, 0.0209101171194, 0.0220493585518, 0.0231748877373, 0.0242784805505, 0.0253517271725, 0.0263861353948, 0.0273732400312, 0.0283047165243, 0.0291724966555, 0.029968884136, 0.0306866677818, 0.0313192299543, 0.0318606479935, 0.0323057864723, 0.0326503782638, 0.0328910926329, 0.0330255888321, 0.0330525539969, 0.0329717244812, 0.0327838901489, 0.0324908815237, 0.0320955400894, 0.0316016724148, 0.031013989138, 0.0303380301802, 0.0295800778452, 0.028747059714, 0.027846443428, 0.0268861255931, 0.0258743171068, 0.0248194272242, 0.0237299486283, 0.02261434567, 0.0214809477837, 0.0203378498874); +CONST_ARRAY float opt_gaussian_offsets_36[] = float[36] (-18.0, -16.4931636913, -14.4935717828, -12.4939798828, -10.4943879908, -8.49479610628, -6.49520422871, -4.49561235753, -2.4960204922, -0.496428632166, 1.5031632231, 3.50275507416, 5.50234692154, 7.50193876579, 9.50153060746, 11.5011224471, 13.5007142852, 15.5003061224, 17.4998979592, 19.4994897961, 21.4990816337, 23.4986734725, 25.4982653131, 27.497857156, 29.4974490017, 31.4970408509, 33.496632704, 35.4962245616, 37.4958164242, 39.4954082924, 41.4950001667, 43.4945920476, 45.4941839358, 47.4937758317, 49.493367736, 51.492959649); + +// Offsets and weights for n = 37, relative to pixel center +CONST_ARRAY float opt_gaussian_weights_37[] = float[37] (0.00974993636734, 0.0203117325559, 0.0213892024529, 0.0224544310942, 0.0235000813023, 0.0245186478884, 0.0255025443957, 0.0264441950142, 0.0273361301596, 0.0281710840642, 0.0289420926191, 0.0296425896425, 0.0302664997198, 0.0308083257886, 0.0312632297024, 0.0316271041272, 0.0318966342731, 0.032069348168, 0.0321436544031, 0.0321188665476, 0.031995213706, 0.0317738369926, 0.0314567719985, 0.0310469176281, 0.0305479919715, 0.0299644761535, 0.0293015473444, 0.0285650023323, 0.0277611732343, 0.0268968370582, 0.0259791209177, 0.0250154047456, 0.0240132233523, 0.0229801696268, 0.0219238005913, 0.0208515478943, 0.0197706341665); +CONST_ARRAY float opt_gaussian_offsets_37[] = float[37] (-19.0, -17.4933453004, -15.4937310384, -13.4941167839, -11.4945025364, -9.49488829538, -7.4952740605, -5.49565983124, -3.49604560714, -1.49643138776, 0.503182827378, 2.50279703872, 4.50241124674, 6.50202545188, 8.50163965462, 10.5012538554, 12.5008680547, 14.5004822529, 16.5000964506, 18.4997106482, 20.4993248461, 22.4989390448, 24.4985532448, 26.4981674465, 28.4977816504, 30.4973958569, 32.4970100665, 34.4966242797, 36.4962384969, 38.4958527186, 40.4954669452, 42.4950811772, 44.4946954151, 46.4943096593, 48.4939239102, 50.4935381684, 52.4931524343); + +// Offsets and weights for n = 38, relative to pixel center +CONST_ARRAY float opt_gaussian_weights_38[] = float[38] (0.00948890217078, 0.0197466058518, 0.0207671865319, 0.0217768050027, 0.0227688949424, 0.0237367380186, 0.0246735370734, 0.0255724936997, 0.0264268890116, 0.0272301662959, 0.0279760141433, 0.0286584485977, 0.0292718928381, 0.0298112529127, 0.030271988092, 0.030650174481, 0.030942560647, 0.0311466141591, 0.0312605581081, 0.0312833968702, 0.0312149305926, 0.0310557581051, 0.0308072681993, 0.0304716194529, 0.0300517090085, 0.0295511309394, 0.028974125038, 0.0283255170485, 0.0276106515206, 0.0268353185907, 0.0260056760908, 0.025128168447, 0.0242094438539, 0.0232562712038, 0.0222754582054, 0.0212737720531, 0.0202578639043, 0.0192341982982); +CONST_ARRAY float opt_gaussian_offsets_38[] = float[38] (-19.0, -17.4935175291, -15.4938827012, -13.4942478798, -11.4946130645, -9.49497825506, -7.49534345092, -5.49570865176, -3.49607385718, -1.49643906678, 0.503195719814, 2.502830503, 4.50246528316, 6.5021000607, 8.50173483599, 10.5013696094, 12.5010043814, 14.5006391523, 16.5002739225, 18.4999086925, 20.4995434625, 22.499178233, 24.4988130044, 26.4984477771, 28.4980825514, 30.4977173278, 32.4973521066, 34.4969868882, 36.496621673, 38.4962564615, 40.4958912539, 42.4955260507, 44.4951608523, 46.4947956591, 48.4944304714, 50.4940652897, 52.4937001143, 54.4933349456); + +// Offsets and weights for n = 39, relative to pixel center +CONST_ARRAY float opt_gaussian_weights_39[] = float[39] (0.00924148137305, 0.0192120420422, 0.0201801154313, 0.0211383429813, 0.0220808308543, 0.023001547634, 0.0238943863517, 0.0247532302506, 0.0255720213328, 0.0263448306384, 0.0270659291345, 0.0277298580395, 0.0283314973845, 0.0288661316105, 0.0293295110303, 0.0297179080354, 0.0300281670083, 0.0302577470078, 0.0304047564176, 0.030467978898, 0.0304468901444, 0.0303416651267, 0.0301531756723, 0.0298829784382, 0.0295332935044, 0.029106974001, 0.0286074673487, 0.0280387688511, 0.027405368511, 0.0267121920605, 0.0259645372878, 0.0251680068087, 0.0243284384733, 0.0234518346107, 0.0225442913003, 0.0216119288229, 0.0206608243792, 0.0196969480813, 0.0187261031213); +CONST_ARRAY float opt_gaussian_offsets_39[] = float[39] (-20.0, -18.4936810844, -16.4940272924, -14.4943735062, -12.4947197254, -10.4950659496, -8.49541217862, -6.495758412, -4.49610464945, -2.49645089063, -0.496797135222, 1.50285661712, 3.50251036672, 5.50216411391, 7.50181785903, 9.5014716024, 11.5011253444, 13.5007790852, 15.5004328254, 17.5000865651, 19.4997403047, 21.4993940446, 23.4990477851, 25.4987015265, 27.4983552691, 29.4980090133, 31.4976627594, 33.4973165078, 35.4969702587, 37.4966240125, 39.4962777696, 41.4959315302, 43.4955852948, 45.4952390636, 47.4948928369, 49.4945466151, 51.4942003986, 53.4938541877, 55.4935079826); diff --git a/rpcore/shader/includes/gbuffer.inc.glsl b/rpcore/shader/includes/gbuffer.inc.glsl new file mode 100644 index 0000000..3b08aea --- /dev/null +++ b/rpcore/shader/includes/gbuffer.inc.glsl @@ -0,0 +1,307 @@ +/** + * + * RenderPipeline + * + * Copyright (c) 2014-2016 tobspr + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + */ + +#pragma once + +#pragma include "includes/material.inc.glsl" +#pragma include "includes/normal_packing.inc.glsl" +#pragma include "includes/brdf.inc.glsl" + +uniform mat4 p3d_ProjectionMatrix; + +#if IN_GBUFFER_SHADER + + /* + + GBuffer Packing + + */ + + layout(location = 0) out vec4 gbuffer_out_0; + layout(location = 1) out vec4 gbuffer_out_1; + layout(location = 2) out vec4 gbuffer_out_2; + + vec2 compute_velocity() { + // Compute velocity based on this and last frames mvp matrix + vec4 last_proj_pos = vOutput.last_proj_position; + vec2 last_texcoord = fma(last_proj_pos.xy / last_proj_pos.w, vec2(0.5), vec2(0.5)); + vec2 curr_texcoord = gl_FragCoord.xy / SCREEN_SIZE; + return (curr_texcoord - last_texcoord); + } + + // Lean mapping + float adjust_roughness(float roughness, float avg_normal_length) { + // Based on The Order : 1886 SIGGRAPH course notes implementation + if (avg_normal_length < 1.0) + { + float avg_len_sq = avg_normal_length * avg_normal_length; + float kappa = (3 * avg_normal_length - avg_normal_length * avg_len_sq) / + (1 - avg_len_sq); + float variance = 1.0 / (2.0 * kappa) ; + return sqrt(roughness * roughness + variance); + } + return roughness; + } + + + void render_material(MaterialShaderOutput m) { + + // Compute material properties + vec3 normal = normalize(m.normal); + vec2 packed_normal = pack_normal_octahedron(normal); + vec2 velocity = compute_velocity(); + + // Clamp BaseColor, but only for negative values, we allow values > 1.0 + // vec3 basecolor = pow(max(vec3(0), m.basecolor), vec3(2.2)) * 1.0; + vec3 basecolor = max(vec3(0), m.basecolor); + + // Clamp properties like specular and metallic, which have to be in the + // 0 ... 1 range + float specular = clamp(m.specular_ior, 1.0001, 2.51); + float metallic = saturate(m.metallic); + float roughness = clamp(m.roughness, 0.03, 1.0); + + roughness = adjust_roughness(roughness, length(m.normal)); + + // Pack all values to the gbuffer + gbuffer_out_0 = vec4(basecolor.r, basecolor.g, basecolor.b, roughness); + gbuffer_out_1 = vec4(packed_normal.x, packed_normal.y, metallic, specular); + gbuffer_out_2 = vec4(velocity.x, velocity.y, m.shading_model, m.shading_model_param0); + } + + +#else // IN_GBUFFER_SHADER + + + /* + + GBuffer - Unpacking + + */ + + #pragma include "includes/transforms.inc.glsl" + + // Common gbuffer data + struct GBufferData { + sampler2D Depth; + sampler2D Data0; + sampler2D Data1; + sampler2D Data2; + }; + + // Checks whether the given material is the skybox + bool is_skybox(vec3 pos, vec3 camera_pos) { + #if REFERENCE_MODE + return distance(pos, camera_pos) > 1000.0; + #endif + return distance(pos, camera_pos) > 20000.0; + } + + bool is_skybox(Material m, vec3 camera_pos) { + return is_skybox(m.position, camera_pos); + } + + bool is_skybox(Material m) { return is_skybox(m, MainSceneData.camera_pos); } + bool is_skybox(vec3 pos) { return is_skybox(pos, MainSceneData.camera_pos); } + + // Returns the depth at a given texcoord + float get_gbuffer_depth(GBufferData data, vec2 coord) { + return textureLod(data.Depth, coord, 0).x; + } + + // Returns the depth at a given texcoord + float get_gbuffer_depth(GBufferData data, ivec2 coord) { + return texelFetch(data.Depth, coord, 0).x; + } + + // Returns the world space position at a given texcoord + vec3 get_gbuffer_position(GBufferData data, vec2 coord) { + float depth = get_gbuffer_depth(data, coord); + return calculate_surface_pos(depth, coord); + } + + // Returns the world space normal at a given texcoord + vec3 get_gbuffer_normal(GBufferData data, vec2 coord) { + vec2 packed_normal = textureLod(data.Data1, coord, 0).xy; + return unpack_normal_octahedron(packed_normal); + } + // Returns the world space normal at a given texcoord + vec3 get_gbuffer_normal(GBufferData data, ivec2 coord) { + vec2 packed_normal = texelFetch(data.Data1, coord, 0).xy; + return unpack_normal_octahedron(packed_normal); + } + + // Returns the velocity at a given coordinate + vec2 get_gbuffer_object_velocity(GBufferData data, vec2 coord) { + return textureLod(data.Data2, coord, 0).xy; + } + + // Returns the velocity at a given coordinate + vec2 get_gbuffer_object_velocity(GBufferData data, ivec2 coord) { + return texelFetch(data.Data2, coord, 0).xy; + } + + int get_gbuffer_shading_model(GBufferData data, vec2 coord) { + return int(textureLod(data.Data2, coord, 0).z); + } + + float get_gbuffer_roughness(GBufferData data, vec2 coord) { + // XXX: take clearcoat into account + return square(clamp(textureLod(data.Data0, coord, 0).w, MINIMUM_ROUGHNESS, 1.0)); + } + + float get_gbuffer_roughness(GBufferData data, ivec2 coord) { + // XXX: take clearcoat into account + return square(clamp(texelFetch(data.Data0, coord, 0).w, MINIMUM_ROUGHNESS, 1.0)); + } + + // Unpacks a material from the gbuffer + Material unpack_material(GBufferData data, vec2 fcoord) { + + // Fetch data from data-textures + vec4 data0 = textureLod(data.Data0, fcoord, 0); + vec4 data1 = textureLod(data.Data1, fcoord, 0); + vec4 data2 = textureLod(data.Data2, fcoord, 0); + + Material m; + m.position = get_gbuffer_position(data, fcoord); + m.basecolor = data0.xyz; + m.linear_roughness = clamp(data0.w, MINIMUM_ROUGHNESS, 1.0); + m.roughness = m.linear_roughness * m.linear_roughness; + m.normal = unpack_normal_octahedron(data1.xy); + m.metallic = saturate(data1.z * 1.001 - 0.0005); + m.specular_ior = data1.w; + m.specular = ior_to_specular(data1.w); + m.shading_model = int(data2.z); + m.shading_model_param0 = data2.w; + + // Velocity, not stored in the Material struct but stored in the G-Buffer + // vec2 velocity = data2.xy; + return m; + } + + // Unpacks a material from the gbuffer + Material unpack_material(GBufferData data) { + vec2 fcoord = get_texcoord(); + return unpack_material(data, fcoord); + } + + #ifdef USE_GBUFFER_EXTENSIONS + + /* + + GBuffer extensions for reading gbuffer values without having to specify + the gbuffer. + + */ + + uniform GBufferData GBuffer; + + // Returns the depth at a given texcoord + float get_depth_at(vec2 coord) { + return get_gbuffer_depth(GBuffer, coord); + } + // Returns the depth at a given texcoord + float get_depth_at(ivec2 coord) { + return get_gbuffer_depth(GBuffer, coord); + } + + // Returns the view space position at a given texcoord + vec3 get_view_pos_at(vec2 coord) { + return calculate_view_pos(get_depth_at(coord), coord); + } + + + // Returns the world space position at a given texcoord + vec3 get_world_pos_at(vec2 coord) { + return calculate_surface_pos(get_depth_at(coord), coord); + } + + // Returns the velocity given texcoord + vec2 get_object_velocity_at(vec2 coord) { + return get_gbuffer_object_velocity(GBuffer, coord); + } + // Returns the velocity given texcoord + vec2 get_object_velocity_at(ivec2 coord) { + return get_gbuffer_object_velocity(GBuffer, coord); + } + + // Returns the view space normal at a given texcoord. This tries to find + // a good fit normal, but thus is quite expensive. + // It does not include normal mapping, since it uses the depth buffer as source. + vec3 get_view_normal(vec2 coord) { + + // OPTIONAL: Just recover it from the world space normal. + // This has the advantage that it does include normal mapping. + #if 1 + vec3 world_normal = get_gbuffer_normal(GBuffer, coord); + return world_normal_to_view(world_normal); + #endif + + vec2 pixel_size = 1.0 / SCREEN_SIZE; + vec3 view_pos = get_view_pos_at(coord); + + // Do some work to find a good view normal + vec3 dx_px = view_pos - get_view_pos_at(coord + pixel_size * vec2(1, 0)); + vec3 dx_py = view_pos - get_view_pos_at(coord + pixel_size * vec2(0, 1)); + + vec3 dx_nx = get_view_pos_at(coord + pixel_size * vec2(-1, 0)) - view_pos; + vec3 dx_ny = get_view_pos_at(coord + pixel_size * vec2(0, -1)) - view_pos; + + // Find the closest distance in depth + vec3 dx_x = abs(dx_px.z) < abs(dx_nx.z) ? vec3(dx_px) : vec3(dx_nx); + vec3 dx_y = abs(dx_py.z) < abs(dx_ny.z) ? vec3(dx_py) : vec3(dx_ny); + + return normalize(cross(dx_x, dx_y)); + } + + // Returns the view space normal at a given texcoord. This approximates + // the normal instead of calculating it accurately, thus might produce + // smaller artifacts at edges. However you should prefer this method + // wherever possible. It does not include normal mapping, since it uses + // the depth buffer as source. + vec3 get_view_normal_approx(vec2 coord) { + vec3 view_pos = get_view_pos_at(coord); + vec2 pixel_size = 1.0 / SCREEN_SIZE; + vec3 dx_x = view_pos - get_view_pos_at(coord + pixel_size * vec2(1, 0)); + vec3 dx_y = view_pos - get_view_pos_at(coord + pixel_size * vec2(0, 1)); + return normalize(cross(dx_x, dx_y)); + } + + + // Returns the cameras velocity + vec2 get_camera_velocity(vec2 texcoord) { + vec2 film_offset_bias = MainSceneData.current_film_offset * + vec2(1.0, 1.0 / ASPECT_RATIO); + vec3 pos = get_world_pos_at(texcoord - film_offset_bias); + vec4 last_proj = MainSceneData.last_view_proj_mat_no_jitter * vec4(pos, 1); + vec2 last_coord = fma(last_proj.xy / last_proj.w, vec2(0.5), vec2(0.5)); + return last_coord - texcoord; + } + + #endif + +#endif // IN_GBUFFER_SHADER diff --git a/rpcore/shader/includes/halton_sequences.inc.glsl b/rpcore/shader/includes/halton_sequences.inc.glsl new file mode 100644 index 0000000..f621e28 --- /dev/null +++ b/rpcore/shader/includes/halton_sequences.inc.glsl @@ -0,0 +1,568 @@ +/** + * + * RenderPipeline + * + * Copyright (c) 2014-2016 tobspr + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + */ + +// Halton sequences + + +CONST_ARRAY vec2 halton_2D_4[4] = vec2[]( + vec2(0.00000, -0.33333), + vec2(-0.50000, 0.33333), + vec2(0.50000, -0.77778), + vec2(-0.75000, -0.11111) +); + +CONST_ARRAY vec2 halton_2D_8[8] = vec2[]( + vec2(0.00000, -0.33333), + vec2(-0.50000, 0.33333), + vec2(0.50000, -0.77778), + vec2(-0.75000, -0.11111), + vec2(0.25000, 0.55556), + vec2(-0.25000, -0.55556), + vec2(0.75000, 0.11111), + vec2(-0.87500, 0.77778) +); + +CONST_ARRAY vec2 halton_2D_16[16] = vec2[]( + vec2(0.00000, -0.33333), + vec2(-0.50000, 0.33333), + vec2(0.50000, -0.77778), + vec2(-0.75000, -0.11111), + vec2(0.25000, 0.55556), + vec2(-0.25000, -0.55556), + vec2(0.75000, 0.11111), + vec2(-0.87500, 0.77778), + vec2(0.12500, -0.92593), + vec2(-0.37500, -0.25926), + vec2(0.62500, 0.40741), + vec2(-0.62500, -0.70370), + vec2(0.37500, -0.03704), + vec2(-0.12500, 0.62963), + vec2(0.87500, -0.48148), + vec2(-0.93750, 0.18519) +); + +CONST_ARRAY vec2 halton_2D_32[32] = vec2[]( + vec2(0.00000, -0.33333), + vec2(-0.50000, 0.33333), + vec2(0.50000, -0.77778), + vec2(-0.75000, -0.11111), + vec2(0.25000, 0.55556), + vec2(-0.25000, -0.55556), + vec2(0.75000, 0.11111), + vec2(-0.87500, 0.77778), + vec2(0.12500, -0.92593), + vec2(-0.37500, -0.25926), + vec2(0.62500, 0.40741), + vec2(-0.62500, -0.70370), + vec2(0.37500, -0.03704), + vec2(-0.12500, 0.62963), + vec2(0.87500, -0.48148), + vec2(-0.93750, 0.18519), + vec2(0.06250, 0.85185), + vec2(-0.43750, -0.85185), + vec2(0.56250, -0.18519), + vec2(-0.68750, 0.48148), + vec2(0.31250, -0.62963), + vec2(-0.18750, 0.03704), + vec2(0.81250, 0.70370), + vec2(-0.81250, -0.40741), + vec2(0.18750, 0.25926), + vec2(-0.31250, 0.92593), + vec2(0.68750, -0.97531), + vec2(-0.56250, -0.30864), + vec2(0.43750, 0.35802), + vec2(-0.06250, -0.75309), + vec2(0.93750, -0.08642), + vec2(-0.96875, 0.58025) +); + +CONST_ARRAY vec2 halton_2D_64[64] = vec2[]( + vec2(0.00000, -0.33333), + vec2(-0.50000, 0.33333), + vec2(0.50000, -0.77778), + vec2(-0.75000, -0.11111), + vec2(0.25000, 0.55556), + vec2(-0.25000, -0.55556), + vec2(0.75000, 0.11111), + vec2(-0.87500, 0.77778), + vec2(0.12500, -0.92593), + vec2(-0.37500, -0.25926), + vec2(0.62500, 0.40741), + vec2(-0.62500, -0.70370), + vec2(0.37500, -0.03704), + vec2(-0.12500, 0.62963), + vec2(0.87500, -0.48148), + vec2(-0.93750, 0.18519), + vec2(0.06250, 0.85185), + vec2(-0.43750, -0.85185), + vec2(0.56250, -0.18519), + vec2(-0.68750, 0.48148), + vec2(0.31250, -0.62963), + vec2(-0.18750, 0.03704), + vec2(0.81250, 0.70370), + vec2(-0.81250, -0.40741), + vec2(0.18750, 0.25926), + vec2(-0.31250, 0.92593), + vec2(0.68750, -0.97531), + vec2(-0.56250, -0.30864), + vec2(0.43750, 0.35802), + vec2(-0.06250, -0.75309), + vec2(0.93750, -0.08642), + vec2(-0.96875, 0.58025), + vec2(0.03125, -0.53086), + vec2(-0.46875, 0.13580), + vec2(0.53125, 0.80247), + vec2(-0.71875, -0.90123), + vec2(0.28125, -0.23457), + vec2(-0.21875, 0.43210), + vec2(0.78125, -0.67901), + vec2(-0.84375, -0.01235), + vec2(0.15625, 0.65432), + vec2(-0.34375, -0.45679), + vec2(0.65625, 0.20988), + vec2(-0.59375, 0.87654), + vec2(0.40625, -0.82716), + vec2(-0.09375, -0.16049), + vec2(0.90625, 0.50617), + vec2(-0.90625, -0.60494), + vec2(0.09375, 0.06173), + vec2(-0.40625, 0.72840), + vec2(0.59375, -0.38272), + vec2(-0.65625, 0.28395), + vec2(0.34375, 0.95062), + vec2(-0.15625, -0.95062), + vec2(0.84375, -0.28395), + vec2(-0.78125, 0.38272), + vec2(0.21875, -0.72840), + vec2(-0.28125, -0.06173), + vec2(0.71875, 0.60494), + vec2(-0.53125, -0.50617), + vec2(0.46875, 0.16049), + vec2(-0.03125, 0.82716), + vec2(0.96875, -0.87654), + vec2(-0.98438, -0.20988) +); + +CONST_ARRAY vec2 halton_2D_128[128] = vec2[]( + vec2(0.00000, -0.33333), + vec2(-0.50000, 0.33333), + vec2(0.50000, -0.77778), + vec2(-0.75000, -0.11111), + vec2(0.25000, 0.55556), + vec2(-0.25000, -0.55556), + vec2(0.75000, 0.11111), + vec2(-0.87500, 0.77778), + vec2(0.12500, -0.92593), + vec2(-0.37500, -0.25926), + vec2(0.62500, 0.40741), + vec2(-0.62500, -0.70370), + vec2(0.37500, -0.03704), + vec2(-0.12500, 0.62963), + vec2(0.87500, -0.48148), + vec2(-0.93750, 0.18519), + vec2(0.06250, 0.85185), + vec2(-0.43750, -0.85185), + vec2(0.56250, -0.18519), + vec2(-0.68750, 0.48148), + vec2(0.31250, -0.62963), + vec2(-0.18750, 0.03704), + vec2(0.81250, 0.70370), + vec2(-0.81250, -0.40741), + vec2(0.18750, 0.25926), + vec2(-0.31250, 0.92593), + vec2(0.68750, -0.97531), + vec2(-0.56250, -0.30864), + vec2(0.43750, 0.35802), + vec2(-0.06250, -0.75309), + vec2(0.93750, -0.08642), + vec2(-0.96875, 0.58025), + vec2(0.03125, -0.53086), + vec2(-0.46875, 0.13580), + vec2(0.53125, 0.80247), + vec2(-0.71875, -0.90123), + vec2(0.28125, -0.23457), + vec2(-0.21875, 0.43210), + vec2(0.78125, -0.67901), + vec2(-0.84375, -0.01235), + vec2(0.15625, 0.65432), + vec2(-0.34375, -0.45679), + vec2(0.65625, 0.20988), + vec2(-0.59375, 0.87654), + vec2(0.40625, -0.82716), + vec2(-0.09375, -0.16049), + vec2(0.90625, 0.50617), + vec2(-0.90625, -0.60494), + vec2(0.09375, 0.06173), + vec2(-0.40625, 0.72840), + vec2(0.59375, -0.38272), + vec2(-0.65625, 0.28395), + vec2(0.34375, 0.95062), + vec2(-0.15625, -0.95062), + vec2(0.84375, -0.28395), + vec2(-0.78125, 0.38272), + vec2(0.21875, -0.72840), + vec2(-0.28125, -0.06173), + vec2(0.71875, 0.60494), + vec2(-0.53125, -0.50617), + vec2(0.46875, 0.16049), + vec2(-0.03125, 0.82716), + vec2(0.96875, -0.87654), + vec2(-0.98438, -0.20988), + vec2(0.01562, 0.45679), + vec2(-0.48438, -0.65432), + vec2(0.51562, 0.01235), + vec2(-0.73438, 0.67901), + vec2(0.26562, -0.43210), + vec2(-0.23438, 0.23457), + vec2(0.76562, 0.90123), + vec2(-0.85938, -0.80247), + vec2(0.14062, -0.13580), + vec2(-0.35938, 0.53086), + vec2(0.64062, -0.58025), + vec2(-0.60938, 0.08642), + vec2(0.39062, 0.75309), + vec2(-0.10938, -0.35802), + vec2(0.89062, 0.30864), + vec2(-0.92188, 0.97531), + vec2(0.07812, -0.99177), + vec2(-0.42188, -0.32510), + vec2(0.57812, 0.34156), + vec2(-0.67188, -0.76955), + vec2(0.32812, -0.10288), + vec2(-0.17188, 0.56379), + vec2(0.82812, -0.54733), + vec2(-0.79688, 0.11934), + vec2(0.20312, 0.78601), + vec2(-0.29688, -0.91770), + vec2(0.70312, -0.25103), + vec2(-0.54688, 0.41564), + vec2(0.45312, -0.69547), + vec2(-0.04688, -0.02881), + vec2(0.95312, 0.63786), + vec2(-0.95312, -0.47325), + vec2(0.04688, 0.19342), + vec2(-0.45312, 0.86008), + vec2(0.54688, -0.84362), + vec2(-0.70312, -0.17695), + vec2(0.29688, 0.48971), + vec2(-0.20312, -0.62140), + vec2(0.79688, 0.04527), + vec2(-0.82812, 0.71193), + vec2(0.17188, -0.39918), + vec2(-0.32812, 0.26749), + vec2(0.67188, 0.93416), + vec2(-0.57812, -0.96708), + vec2(0.42188, -0.30041), + vec2(-0.07812, 0.36626), + vec2(0.92188, -0.74486), + vec2(-0.89062, -0.07819), + vec2(0.10938, 0.58848), + vec2(-0.39062, -0.52263), + vec2(0.60938, 0.14403), + vec2(-0.64062, 0.81070), + vec2(0.35938, -0.89300), + vec2(-0.14062, -0.22634), + vec2(0.85938, 0.44033), + vec2(-0.76562, -0.67078), + vec2(0.23438, -0.00412), + vec2(-0.26562, 0.66255), + vec2(0.73438, -0.44856), + vec2(-0.51562, 0.21811), + vec2(0.48438, 0.88477), + vec2(-0.01562, -0.81893), + vec2(0.98438, -0.15226), + vec2(-0.99219, 0.51440) +); + +CONST_ARRAY vec3 halton_3D_4[4] = vec3[]( + vec3(0.00000, -0.33333, -0.60000), + vec3(-0.50000, 0.33333, -0.20000), + vec3(0.50000, -0.77778, 0.20000), + vec3(-0.75000, -0.11111, 0.60000) +); + +CONST_ARRAY vec3 halton_3D_8[8] = vec3[]( + vec3(0.00000, -0.33333, -0.60000), + vec3(-0.50000, 0.33333, -0.20000), + vec3(0.50000, -0.77778, 0.20000), + vec3(-0.75000, -0.11111, 0.60000), + vec3(0.25000, 0.55556, -0.92000), + vec3(-0.25000, -0.55556, -0.52000), + vec3(0.75000, 0.11111, -0.12000), + vec3(-0.87500, 0.77778, 0.28000) +); + +CONST_ARRAY vec3 halton_3D_16[16] = vec3[]( + vec3(0.00000, -0.33333, -0.60000), + vec3(-0.50000, 0.33333, -0.20000), + vec3(0.50000, -0.77778, 0.20000), + vec3(-0.75000, -0.11111, 0.60000), + vec3(0.25000, 0.55556, -0.92000), + vec3(-0.25000, -0.55556, -0.52000), + vec3(0.75000, 0.11111, -0.12000), + vec3(-0.87500, 0.77778, 0.28000), + vec3(0.12500, -0.92593, 0.68000), + vec3(-0.37500, -0.25926, -0.84000), + vec3(0.62500, 0.40741, -0.44000), + vec3(-0.62500, -0.70370, -0.04000), + vec3(0.37500, -0.03704, 0.36000), + vec3(-0.12500, 0.62963, 0.76000), + vec3(0.87500, -0.48148, -0.76000), + vec3(-0.93750, 0.18519, -0.36000) +); + +CONST_ARRAY vec3 halton_3D_32[32] = vec3[]( + vec3(0.00000, -0.33333, -0.60000), + vec3(-0.50000, 0.33333, -0.20000), + vec3(0.50000, -0.77778, 0.20000), + vec3(-0.75000, -0.11111, 0.60000), + vec3(0.25000, 0.55556, -0.92000), + vec3(-0.25000, -0.55556, -0.52000), + vec3(0.75000, 0.11111, -0.12000), + vec3(-0.87500, 0.77778, 0.28000), + vec3(0.12500, -0.92593, 0.68000), + vec3(-0.37500, -0.25926, -0.84000), + vec3(0.62500, 0.40741, -0.44000), + vec3(-0.62500, -0.70370, -0.04000), + vec3(0.37500, -0.03704, 0.36000), + vec3(-0.12500, 0.62963, 0.76000), + vec3(0.87500, -0.48148, -0.76000), + vec3(-0.93750, 0.18519, -0.36000), + vec3(0.06250, 0.85185, 0.04000), + vec3(-0.43750, -0.85185, 0.44000), + vec3(0.56250, -0.18519, 0.84000), + vec3(-0.68750, 0.48148, -0.68000), + vec3(0.31250, -0.62963, -0.28000), + vec3(-0.18750, 0.03704, 0.12000), + vec3(0.81250, 0.70370, 0.52000), + vec3(-0.81250, -0.40741, 0.92000), + vec3(0.18750, 0.25926, -0.98400), + vec3(-0.31250, 0.92593, -0.58400), + vec3(0.68750, -0.97531, -0.18400), + vec3(-0.56250, -0.30864, 0.21600), + vec3(0.43750, 0.35802, 0.61600), + vec3(-0.06250, -0.75309, -0.90400), + vec3(0.93750, -0.08642, -0.50400), + vec3(-0.96875, 0.58025, -0.10400) +); + +CONST_ARRAY vec3 halton_3D_64[64] = vec3[]( + vec3(0.00000, -0.33333, -0.60000), + vec3(-0.50000, 0.33333, -0.20000), + vec3(0.50000, -0.77778, 0.20000), + vec3(-0.75000, -0.11111, 0.60000), + vec3(0.25000, 0.55556, -0.92000), + vec3(-0.25000, -0.55556, -0.52000), + vec3(0.75000, 0.11111, -0.12000), + vec3(-0.87500, 0.77778, 0.28000), + vec3(0.12500, -0.92593, 0.68000), + vec3(-0.37500, -0.25926, -0.84000), + vec3(0.62500, 0.40741, -0.44000), + vec3(-0.62500, -0.70370, -0.04000), + vec3(0.37500, -0.03704, 0.36000), + vec3(-0.12500, 0.62963, 0.76000), + vec3(0.87500, -0.48148, -0.76000), + vec3(-0.93750, 0.18519, -0.36000), + vec3(0.06250, 0.85185, 0.04000), + vec3(-0.43750, -0.85185, 0.44000), + vec3(0.56250, -0.18519, 0.84000), + vec3(-0.68750, 0.48148, -0.68000), + vec3(0.31250, -0.62963, -0.28000), + vec3(-0.18750, 0.03704, 0.12000), + vec3(0.81250, 0.70370, 0.52000), + vec3(-0.81250, -0.40741, 0.92000), + vec3(0.18750, 0.25926, -0.98400), + vec3(-0.31250, 0.92593, -0.58400), + vec3(0.68750, -0.97531, -0.18400), + vec3(-0.56250, -0.30864, 0.21600), + vec3(0.43750, 0.35802, 0.61600), + vec3(-0.06250, -0.75309, -0.90400), + vec3(0.93750, -0.08642, -0.50400), + vec3(-0.96875, 0.58025, -0.10400), + vec3(0.03125, -0.53086, 0.29600), + vec3(-0.46875, 0.13580, 0.69600), + vec3(0.53125, 0.80247, -0.82400), + vec3(-0.71875, -0.90123, -0.42400), + vec3(0.28125, -0.23457, -0.02400), + vec3(-0.21875, 0.43210, 0.37600), + vec3(0.78125, -0.67901, 0.77600), + vec3(-0.84375, -0.01235, -0.74400), + vec3(0.15625, 0.65432, -0.34400), + vec3(-0.34375, -0.45679, 0.05600), + vec3(0.65625, 0.20988, 0.45600), + vec3(-0.59375, 0.87654, 0.85600), + vec3(0.40625, -0.82716, -0.66400), + vec3(-0.09375, -0.16049, -0.26400), + vec3(0.90625, 0.50617, 0.13600), + vec3(-0.90625, -0.60494, 0.53600), + vec3(0.09375, 0.06173, 0.93600), + vec3(-0.40625, 0.72840, -0.96800), + vec3(0.59375, -0.38272, -0.56800), + vec3(-0.65625, 0.28395, -0.16800), + vec3(0.34375, 0.95062, 0.23200), + vec3(-0.15625, -0.95062, 0.63200), + vec3(0.84375, -0.28395, -0.88800), + vec3(-0.78125, 0.38272, -0.48800), + vec3(0.21875, -0.72840, -0.08800), + vec3(-0.28125, -0.06173, 0.31200), + vec3(0.71875, 0.60494, 0.71200), + vec3(-0.53125, -0.50617, -0.80800), + vec3(0.46875, 0.16049, -0.40800), + vec3(-0.03125, 0.82716, -0.00800), + vec3(0.96875, -0.87654, 0.39200), + vec3(-0.98438, -0.20988, 0.79200) +); + +CONST_ARRAY vec3 halton_3D_128[128] = vec3[]( + vec3(0.00000, -0.33333, -0.60000), + vec3(-0.50000, 0.33333, -0.20000), + vec3(0.50000, -0.77778, 0.20000), + vec3(-0.75000, -0.11111, 0.60000), + vec3(0.25000, 0.55556, -0.92000), + vec3(-0.25000, -0.55556, -0.52000), + vec3(0.75000, 0.11111, -0.12000), + vec3(-0.87500, 0.77778, 0.28000), + vec3(0.12500, -0.92593, 0.68000), + vec3(-0.37500, -0.25926, -0.84000), + vec3(0.62500, 0.40741, -0.44000), + vec3(-0.62500, -0.70370, -0.04000), + vec3(0.37500, -0.03704, 0.36000), + vec3(-0.12500, 0.62963, 0.76000), + vec3(0.87500, -0.48148, -0.76000), + vec3(-0.93750, 0.18519, -0.36000), + vec3(0.06250, 0.85185, 0.04000), + vec3(-0.43750, -0.85185, 0.44000), + vec3(0.56250, -0.18519, 0.84000), + vec3(-0.68750, 0.48148, -0.68000), + vec3(0.31250, -0.62963, -0.28000), + vec3(-0.18750, 0.03704, 0.12000), + vec3(0.81250, 0.70370, 0.52000), + vec3(-0.81250, -0.40741, 0.92000), + vec3(0.18750, 0.25926, -0.98400), + vec3(-0.31250, 0.92593, -0.58400), + vec3(0.68750, -0.97531, -0.18400), + vec3(-0.56250, -0.30864, 0.21600), + vec3(0.43750, 0.35802, 0.61600), + vec3(-0.06250, -0.75309, -0.90400), + vec3(0.93750, -0.08642, -0.50400), + vec3(-0.96875, 0.58025, -0.10400), + vec3(0.03125, -0.53086, 0.29600), + vec3(-0.46875, 0.13580, 0.69600), + vec3(0.53125, 0.80247, -0.82400), + vec3(-0.71875, -0.90123, -0.42400), + vec3(0.28125, -0.23457, -0.02400), + vec3(-0.21875, 0.43210, 0.37600), + vec3(0.78125, -0.67901, 0.77600), + vec3(-0.84375, -0.01235, -0.74400), + vec3(0.15625, 0.65432, -0.34400), + vec3(-0.34375, -0.45679, 0.05600), + vec3(0.65625, 0.20988, 0.45600), + vec3(-0.59375, 0.87654, 0.85600), + vec3(0.40625, -0.82716, -0.66400), + vec3(-0.09375, -0.16049, -0.26400), + vec3(0.90625, 0.50617, 0.13600), + vec3(-0.90625, -0.60494, 0.53600), + vec3(0.09375, 0.06173, 0.93600), + vec3(-0.40625, 0.72840, -0.96800), + vec3(0.59375, -0.38272, -0.56800), + vec3(-0.65625, 0.28395, -0.16800), + vec3(0.34375, 0.95062, 0.23200), + vec3(-0.15625, -0.95062, 0.63200), + vec3(0.84375, -0.28395, -0.88800), + vec3(-0.78125, 0.38272, -0.48800), + vec3(0.21875, -0.72840, -0.08800), + vec3(-0.28125, -0.06173, 0.31200), + vec3(0.71875, 0.60494, 0.71200), + vec3(-0.53125, -0.50617, -0.80800), + vec3(0.46875, 0.16049, -0.40800), + vec3(-0.03125, 0.82716, -0.00800), + vec3(0.96875, -0.87654, 0.39200), + vec3(-0.98438, -0.20988, 0.79200), + vec3(0.01562, 0.45679, -0.72800), + vec3(-0.48438, -0.65432, -0.32800), + vec3(0.51562, 0.01235, 0.07200), + vec3(-0.73438, 0.67901, 0.47200), + vec3(0.26562, -0.43210, 0.87200), + vec3(-0.23438, 0.23457, -0.64800), + vec3(0.76562, 0.90123, -0.24800), + vec3(-0.85938, -0.80247, 0.15200), + vec3(0.14062, -0.13580, 0.55200), + vec3(-0.35938, 0.53086, 0.95200), + vec3(0.64062, -0.58025, -0.95200), + vec3(-0.60938, 0.08642, -0.55200), + vec3(0.39062, 0.75309, -0.15200), + vec3(-0.10938, -0.35802, 0.24800), + vec3(0.89062, 0.30864, 0.64800), + vec3(-0.92188, 0.97531, -0.87200), + vec3(0.07812, -0.99177, -0.47200), + vec3(-0.42188, -0.32510, -0.07200), + vec3(0.57812, 0.34156, 0.32800), + vec3(-0.67188, -0.76955, 0.72800), + vec3(0.32812, -0.10288, -0.79200), + vec3(-0.17188, 0.56379, -0.39200), + vec3(0.82812, -0.54733, 0.00800), + vec3(-0.79688, 0.11934, 0.40800), + vec3(0.20312, 0.78601, 0.80800), + vec3(-0.29688, -0.91770, -0.71200), + vec3(0.70312, -0.25103, -0.31200), + vec3(-0.54688, 0.41564, 0.08800), + vec3(0.45312, -0.69547, 0.48800), + vec3(-0.04688, -0.02881, 0.88800), + vec3(0.95312, 0.63786, -0.63200), + vec3(-0.95312, -0.47325, -0.23200), + vec3(0.04688, 0.19342, 0.16800), + vec3(-0.45312, 0.86008, 0.56800), + vec3(0.54688, -0.84362, 0.96800), + vec3(-0.70312, -0.17695, -0.93600), + vec3(0.29688, 0.48971, -0.53600), + vec3(-0.20312, -0.62140, -0.13600), + vec3(0.79688, 0.04527, 0.26400), + vec3(-0.82812, 0.71193, 0.66400), + vec3(0.17188, -0.39918, -0.85600), + vec3(-0.32812, 0.26749, -0.45600), + vec3(0.67188, 0.93416, -0.05600), + vec3(-0.57812, -0.96708, 0.34400), + vec3(0.42188, -0.30041, 0.74400), + vec3(-0.07812, 0.36626, -0.77600), + vec3(0.92188, -0.74486, -0.37600), + vec3(-0.89062, -0.07819, 0.02400), + vec3(0.10938, 0.58848, 0.42400), + vec3(-0.39062, -0.52263, 0.82400), + vec3(0.60938, 0.14403, -0.69600), + vec3(-0.64062, 0.81070, -0.29600), + vec3(0.35938, -0.89300, 0.10400), + vec3(-0.14062, -0.22634, 0.50400), + vec3(0.85938, 0.44033, 0.90400), + vec3(-0.76562, -0.67078, -0.61600), + vec3(0.23438, -0.00412, -0.21600), + vec3(-0.26562, 0.66255, 0.18400), + vec3(0.73438, -0.44856, 0.58400), + vec3(-0.51562, 0.21811, 0.98400), + vec3(0.48438, 0.88477, -0.99680), + vec3(-0.01562, -0.81893, -0.59680), + vec3(0.98438, -0.15226, -0.19680), + vec3(-0.99219, 0.51440, 0.20320) +); diff --git a/rpcore/shader/includes/ies_lighting.inc.glsl b/rpcore/shader/includes/ies_lighting.inc.glsl new file mode 100644 index 0000000..d019c4a --- /dev/null +++ b/rpcore/shader/includes/ies_lighting.inc.glsl @@ -0,0 +1,55 @@ +/** + * + * RenderPipeline + * + * Copyright (c) 2014-2016 tobspr + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + */ + +#pragma once + +uniform sampler3D IESDatasetTex; + +// The ies profiles give us candela values, which we can directly convert to lumens +const float IES_SCALE = 1.0 /* lumens */; + +// Computes the IES factor from a given light vector and profile. +// A profile < 0 means no light profile. +float get_ies_factor(vec3 light_vector, int profile) { + if (profile < 0) + return 1.0; + light_vector = normalize(light_vector); + float horiz_angle = acos(light_vector.z) / M_PI; + float vert_angle = fma(atan(light_vector.x, light_vector.y), 1.0 / TWO_PI, 0.5); + float profile_coord = (profile+0.5) / MAX_IES_PROFILES; + float data = textureLod(IESDatasetTex, vec3(horiz_angle, vert_angle, profile_coord), 0).x; + return data * IES_SCALE; +} + +// Computes the IES factor from a given spherical coordinate and profile. +// theta and phi should range from 0 to 1. +float get_ies_factor(int profile, float theta, float phi) { + if (profile < 0) + return 1.0; + float profile_coord = (profile+0.5) / MAX_IES_PROFILES; + float data = textureLod(IESDatasetTex, vec3(theta * 0.5 + 0.5, phi, profile_coord), 0).x; + return data * IES_SCALE; +} diff --git a/rpcore/shader/includes/importance_sampling.inc.glsl b/rpcore/shader/includes/importance_sampling.inc.glsl new file mode 100644 index 0000000..831e41f --- /dev/null +++ b/rpcore/shader/includes/importance_sampling.inc.glsl @@ -0,0 +1,55 @@ +/** + * + * RenderPipeline + * + * Copyright (c) 2014-2016 tobspr + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + */ + +#pragma once + +// From: +// http://www.trentreed.net/blog/physically-based-shading-and-image-based-lighting/ +vec2 hammersley(uint i, uint N) +{ + return vec2(float(i) / float(N), float(bitfieldReverse(i)) * 2.3283064365386963e-10); +} + +// From: +// http://www.gamedev.net/topic/655431-ibl-problem-with-consistency-using-ggx-anisotropy/ +vec3 importance_sample_ggx(vec2 Xi, float alpha) +{ + // alpha is already squared roughness + float r_square = alpha * alpha; + float phi = TWO_PI * Xi.x; + float cos_theta_sq = (1 - Xi.y) / max(1e-3, 1 + (r_square * r_square - 1) * Xi.y); + float cos_theta = sqrt(cos_theta_sq); + float sin_theta = sqrt(max(0.0, 1.0 - cos_theta_sq)); + return vec3(sin_theta * cos(phi), sin_theta * sin(phi), cos_theta); +} + +vec3 importance_sample_lambert(vec2 Xi) +{ + float phi = TWO_PI * Xi.x; + float cos_theta = sqrt(Xi.y); + float sin_theta = sqrt(1 - Xi.y); + return vec3(sin_theta * cos(phi), sin_theta * sin(phi), cos_theta); +} diff --git a/rpcore/shader/includes/light_classification.inc.glsl b/rpcore/shader/includes/light_classification.inc.glsl new file mode 100644 index 0000000..91646c6 --- /dev/null +++ b/rpcore/shader/includes/light_classification.inc.glsl @@ -0,0 +1,52 @@ +/** + * + * RenderPipeline + * + * Copyright (c) 2014-2016 tobspr + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + */ + +#pragma once + +#pragma include "includes/light_data.inc.glsl" + +#define LIGHT_CLS_INVALID -1 +#define LIGHT_CLS_SPOT_NOSHADOW 0 +#define LIGHT_CLS_POINT_NOSHADOW 1 +#define LIGHT_CLS_SPOT_SHADOW 2 +#define LIGHT_CLS_POINT_SHADOW 3 + +#define LIGHT_CLS_COUNT 4 + +#if LIGHT_CLS_COUNT != LC_LIGHT_CLASS_COUNT + #error GLSL and Python lighting system class count do not match up! +#endif + +int classify_light(int light_type, bool casts_shadows) { + switch (light_type) { + case LT_SPOT_LIGHT: + return casts_shadows ? LIGHT_CLS_SPOT_SHADOW : LIGHT_CLS_SPOT_NOSHADOW; + case LT_POINT_LIGHT: + return casts_shadows ? LIGHT_CLS_POINT_SHADOW : LIGHT_CLS_POINT_NOSHADOW; + + }; + return LIGHT_CLS_INVALID; +} diff --git a/rpcore/shader/includes/light_culling.inc.glsl b/rpcore/shader/includes/light_culling.inc.glsl new file mode 100644 index 0000000..3caf56d --- /dev/null +++ b/rpcore/shader/includes/light_culling.inc.glsl @@ -0,0 +1,186 @@ +/** + * + * RenderPipeline + * + * Copyright (c) 2014-2016 tobspr + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + */ + +#pragma once + +#pragma include "includes/transforms.inc.glsl" +#pragma include "includes/light_data.inc.glsl" + +// Controls the exponential factor, values < 1 produce a distribution closer to +// the camera, values > 1 produce a distribution which is further away from the camera. +#define SLICE_EXP_FACTOR 3.0 + +// Cell ray directions +const int num_raydirs = 5; + +// Increase the frustum size by a small bit, because we trace at the corners, +// since using this way we could miss some small parts of the sphere. With this +// bias we should be fine, except for very small spheres, but those will be +// out of the culling range then anyays +const float cull_bias = 1 + 0.01; +vec3 aspect_mul = vec3(1, ASPECT_RATIO, 1); + +CONST_ARRAY vec2 ray_dirs[num_raydirs] = vec2[]( + vec2(0, 0), + vec2(1.0, 1.0) * cull_bias, + vec2(-1.0, 1.0) * cull_bias, + vec2(1.0, -1.0) * cull_bias, + vec2(-1.0, -1.0) * cull_bias +); + +int get_slice_from_distance(float dist) { + float flt_dist = dist / LC_MAX_DISTANCE; + return int(log(flt_dist * SLICE_EXP_FACTOR + 1.0) / + log(1.0 + SLICE_EXP_FACTOR) * LC_TILE_SLICES); +} + +float get_distance_from_slice(int slice) { + float flt_dist = slice / float(LC_TILE_SLICES) * log(1.0 + SLICE_EXP_FACTOR); + float flt_exp = (exp(flt_dist) - 1.0) / SLICE_EXP_FACTOR; + return flt_exp * LC_MAX_DISTANCE; +} + +// Converts a coordinate and distance to the appropriate cell index +ivec3 get_lc_cell_index(ivec2 coord, float surface_distance) { + ivec2 tile = coord / ivec2(LC_TILE_SIZE_X, LC_TILE_SIZE_Y); + return ivec3(tile, get_slice_from_distance(surface_distance)); +} + +void unpack_cell_data(int packed_data, out int cell_x, out int cell_y, out int cell_slice) { + cell_x = packed_data & 0x3FF; + cell_y = (packed_data >> 10) & 0x3FF; + cell_slice = (packed_data >> 20) & 0x3FF; +} + +vec3 transform_raydir(vec2 dir, int cell_x, int cell_y, vec2 precompute_size) { + vec2 cell_pos = (vec2(cell_x, cell_y) + dir * 0.5 + 0.5) / precompute_size; + return normalize(mix( + mix(MainSceneData.vs_frustum_directions[0].xyz, + MainSceneData.vs_frustum_directions[1].xyz, cell_pos.x), + mix(MainSceneData.vs_frustum_directions[2].xyz, + MainSceneData.vs_frustum_directions[3].xyz, cell_pos.x), + cell_pos.y + )); +} + +CONST_ARRAY vec3[num_raydirs] get_raydirs(int cell_x, int cell_y, vec2 precompute_size) { + vec3 local_ray_dirs[num_raydirs]; + + // Generate ray directions + for (int i = 0; i < num_raydirs; ++i) { + local_ray_dirs[i] = transform_raydir(ray_dirs[i], cell_x, cell_y, precompute_size); + } + + return local_ray_dirs; +} + + +struct Sphere { + vec3 pos; + float radius; +}; + +// Interesects a sphere with a ray +// https://en.wikipedia.org/wiki/Line%E2%80%93sphere_intersection +bool ray_sphere_intersection(Sphere sphere, vec3 ray_start, vec3 ray_dir, + out float min_dist, out float max_dist) { + // Get vector from ray to sphere + vec3 o_minus_c = ray_start - sphere.pos; + + // Project that vector onto the ray + float l_dot_o_minus_c = dot(ray_dir, o_minus_c); + + // Compute the distance + float root = l_dot_o_minus_c * l_dot_o_minus_c - dot(o_minus_c, o_minus_c) + + sphere.radius * sphere.radius; + float sqr_root = sqrt(abs(root)); + + min_dist = -l_dot_o_minus_c + sqr_root; + max_dist = -l_dot_o_minus_c - sqr_root; + + return root > 0; // Can be >= 0 to include tangents as well. +} + +// Intersect a sphere with a ray +bool viewspace_ray_sphere_intersection(Sphere sphere, vec3 ray_dir, + out float min_dist, out float max_dist) { + return ray_sphere_intersection(sphere, vec3(0), ray_dir, min_dist, max_dist); +} + +// Intersect a sphere with a ray, given a minimum and maximum ray distance +bool viewspace_ray_sphere_distance_intersection(Sphere sphere, vec3 ray_dir, + float tile_start, float tile_end) { + float r_min, r_max; + bool visible = viewspace_ray_sphere_intersection(sphere, ray_dir, r_min, r_max); + return visible && r_max < tile_end && r_min > tile_start; +} + +// Returns a representative sphere for a light +Sphere get_representative_sphere(LightData data) { + Sphere ret; + + vec3 light_pos = (MainSceneData.view_mat_z_up * + vec4(get_light_position(data), 1)).xyz; + + switch (get_light_type(data)) { + case LT_POINT_LIGHT: { + ret.pos = light_pos; + ret.radius = get_pointlight_radius(data) + + get_pointlight_inner_radius(data); + break; + } + + case LT_SPOT_LIGHT: { + float cone_radius = get_spotlight_radius(data); + vec3 direction = get_spotlight_direction(data); + vec3 direction_view = world_normal_to_view(direction); + float cone_fov = get_spotlight_fov(data); + + // Approximate the cone with a sphere + // See: http://fs5.directupload.net/images/151219/xp2knkre.png + float half_cone_radius = cone_radius * 0.5; + ret.pos = light_pos + direction_view * half_cone_radius; + float hypotenuse = cone_radius / cone_fov; + + // cone_fov is encoded as cos(cone_fov) + // we can get the sin(cone_fov) using basic trigonometry: + // From sin(x)^2 + cos(x)^2 = 1 we can derive: + // sin(cone_fov) = sqrt(1 - cos(cone_fov) * cos(cone_fov)) + #if 0 + // Unoptimized version + float opposite_side = sqrt(1.0 - cone_fov * cone_fov) * hypotenuse; + ret.radius = sqrt(opposite_side * opposite_side + + half_cone_radius * half_cone_radius); + #else + // To optimize this, we don't need the square root any longer: + float opposite_side_sqr = (1.0 - cone_fov * cone_fov) * hypotenuse * hypotenuse; + ret.radius = sqrt(opposite_side_sqr + half_cone_radius * half_cone_radius); + #endif + } + } + + return ret; +} diff --git a/rpcore/shader/includes/light_data.inc.glsl b/rpcore/shader/includes/light_data.inc.glsl new file mode 100644 index 0000000..27f4225 --- /dev/null +++ b/rpcore/shader/includes/light_data.inc.glsl @@ -0,0 +1,126 @@ +#pragma once + + +#pragma include "includes/light_data.struct.glsl" +#pragma include "includes/source_data.struct.glsl" + +/* + +Description of the packing and the layout can be found here: +https://github.com/tobspr/RenderPipeline/wiki/LightStorage + +*/ + +// Reads the light data from a given buffer and offset +LightData read_light_data(samplerBuffer LightDataBuffer, int offset) { + LightData data; + data.Data0 = texelFetch(LightDataBuffer, offset * 4 + 0); + data.Data1 = texelFetch(LightDataBuffer, offset * 4 + 1); + data.Data2 = texelFetch(LightDataBuffer, offset * 4 + 2); + data.Data3 = texelFetch(LightDataBuffer, offset * 4 + 3); + return data; +} + +// Only reads the light type, in case nothing else is required +int read_light_type(samplerBuffer LightDataBuffer, int offset) { + float data0x = texelFetch(LightDataBuffer, offset * 4 + 0).x; + return gpu_cq_unpack_int_from_float(data0x); +} + +bool read_casts_shadows(samplerBuffer LightDataBuffer, int offset) { + float data0z = texelFetch(LightDataBuffer, offset * 4 + 0).z; + return gpu_cq_unpack_int_from_float(data0z) >= 0; +} + +// Extracts the type of a light +int get_light_type(LightData data) { + return gpu_cq_unpack_int_from_float(data.Data0.x); +} + +// Extracts the ies profile index of a light +int get_ies_profile(LightData data) { + return gpu_cq_unpack_int_from_float(data.Data0.y); +} + +int get_shadow_source_index(LightData data) { + return gpu_cq_unpack_int_from_float(data.Data0.z); +} + +bool get_casts_shadows(LightData data) { + return get_shadow_source_index(data) >= 0; +} + +// Extracts the light world space position +vec3 get_light_position(LightData data) { + return vec3(data.Data0.w, data.Data1.xy); +} + +// Extracts the light color +vec3 get_light_color(LightData data) { + return vec3(data.Data1.zw, data.Data2.x) * 100.0; +} + +/* + +Point Light Dataset + +*/ + +// Extracts the radius of a point light +float get_pointlight_radius(LightData data) { + return data.Data2.y; +} + +// Extracts the inner radius of a point light +float get_pointlight_inner_radius(LightData data) { + return data.Data2.z; +} + +/* + +Spot Light Dataset + +*/ + +// Extracts the radius of a spot light +float get_spotlight_radius(LightData data) { + return data.Data2.y; +} + +// Extracts the fov of a spot light +float get_spotlight_fov(LightData data) { + return data.Data2.z; +} + +// Extracts the direction of a spot light +vec3 get_spotlight_direction(LightData data) { + return vec3(data.Data2.w, data.Data3.xy); +} + + + +/* + +Shadow sources + +*/ + +// Reads the shadow source data from a given buffer and offset +SourceData read_source_data(samplerBuffer SourceDataBuffer, int offset) { + SourceData data; + data.Data0 = texelFetch(SourceDataBuffer, offset + 0); + data.Data1 = texelFetch(SourceDataBuffer, offset + 1); + data.Data2 = texelFetch(SourceDataBuffer, offset + 2); + data.Data3 = texelFetch(SourceDataBuffer, offset + 3); + data.Data4 = texelFetch(SourceDataBuffer, offset + 4); + return data; +} + + +mat4 get_source_mvp(SourceData data) { + return mat4(data.Data0, data.Data1, data.Data2, data.Data3); +} + +vec4 get_source_uv(SourceData data) { + return data.Data4; +} diff --git a/rpcore/shader/includes/light_data.struct.glsl b/rpcore/shader/includes/light_data.struct.glsl new file mode 100644 index 0000000..0ab1638 --- /dev/null +++ b/rpcore/shader/includes/light_data.struct.glsl @@ -0,0 +1,8 @@ +#pragma once + +struct LightData { + vec4 Data0; + vec4 Data1; + vec4 Data2; + vec4 Data3; +}; diff --git a/rpcore/shader/includes/lighting_pipeline.inc.glsl b/rpcore/shader/includes/lighting_pipeline.inc.glsl new file mode 100644 index 0000000..c0c2573 --- /dev/null +++ b/rpcore/shader/includes/lighting_pipeline.inc.glsl @@ -0,0 +1,267 @@ +/** + * + * RenderPipeline + * + * Copyright (c) 2014-2016 tobspr + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + */ + +#pragma once + +#pragma include "includes/material.inc.glsl" +#pragma include "includes/light_culling.inc.glsl" +#pragma include "includes/lights.inc.glsl" +#pragma include "includes/light_data.inc.glsl" +#pragma include "includes/shadows.inc.glsl" +#pragma include "includes/noise.inc.glsl" +#pragma include "includes/light_classification.inc.glsl" +#pragma include "includes/poisson_disk.inc.glsl" + +uniform isampler2DArray CellIndices; +uniform usamplerBuffer PerCellLights; +uniform usamplerBuffer PerCellLightsCounts; +uniform samplerBuffer AllLightsData; +uniform samplerBuffer ShadowSourceData; + +uniform sampler2D ShadowAtlas; + +#if SUPPORT_PCF +uniform sampler2DShadow ShadowAtlasPCF; +#endif + +int get_pointlight_source_offs(vec3 direction) { + vec3 abs_dir = abs(direction); + float max_comp = max3(abs_dir.x, abs_dir.y, abs_dir.z); + if (abs_dir.x >= max_comp - 1e-5) return direction.x >= 0.0 ? 0 : 1; + if (abs_dir.y >= max_comp - 1e-5) return direction.y >= 0.0 ? 2 : 3; + return direction.z >= 0.0 ? 4 : 5; +} + +// Processes a spot light +vec3 process_spotlight(Material m, LightData light_data, vec3 view_vector, float shadow_factor) { + const vec3 transmittance = vec3(1); // <-- TODO + + // Get the lights data + int ies_profile = get_ies_profile(light_data); + vec3 position = get_light_position(light_data); + float radius = get_spotlight_radius(light_data); + float fov = get_spotlight_fov(light_data); + vec3 direction = get_spotlight_direction(light_data); + vec3 l = position - m.position; + vec3 l_norm = normalize(l); + + float attenuation = get_spotlight_attenuation( + l_norm, direction, fov, radius, dot(l, l), ies_profile); + + // Compute the lights influence + return apply_light( + m, view_vector, l_norm, get_light_color(light_data), attenuation, + shadow_factor, transmittance, ONE_BY_PI, ONE_BY_PI, l_norm); +} + +// Processes a point light +vec3 process_pointlight(Material m, LightData light_data, vec3 view_vector, float shadow_factor) { + const vec3 transmittance = vec3(1); // <-- TODO + + // Get the lights data + float radius = get_pointlight_radius(light_data); + float inner_radius = get_pointlight_inner_radius(light_data); + vec3 position = get_light_position(light_data); + int ies_profile = get_ies_profile(light_data); + vec3 l = position - m.position; + float l_len_square = length_squared(l); + + float energy = 1.0 / FOUR_PI; + float dist_sq = l_len_square; + float clearcoat_energy = energy; + vec3 l_diff = l; + + // Spherical area light + if (inner_radius > 0.02) { + l_diff = get_spherical_area_light_horizon(l, m.normal, inner_radius); + l = get_spherical_area_light_vector(m.normal, l, view_vector, inner_radius); + energy = get_spherical_area_light_energy(m.roughness, inner_radius, dist_sq); + dist_sq = max(square(inner_radius) + 0.01, l_len_square - square(inner_radius)); + clearcoat_energy = get_spherical_area_light_energy(CLEARCOAT_ROUGHNESS, inner_radius, dist_sq); + } + + // Get the point light attenuation + float attenuation = attenuation_curve(dist_sq, radius) * get_ies_factor(-l, ies_profile); + + // Compute the lights influence + return apply_light(m, view_vector, normalize(l), get_light_color(light_data), + attenuation, shadow_factor, transmittance, energy, clearcoat_energy, l_diff); +} + + + +// Filters a shadow map +float filter_shadowmap(Material m, SourceData source, vec3 l) { + + // TODO: Examine if this is faster + // if (dot(m.normal, -l) < 0) return 0.0; + + mat4 mvp = get_source_mvp(source); + vec4 uv = get_source_uv(source); + + float rotation = interleaved_gradient_noise( + gl_FragCoord.xy + MainSceneData.frame_index % 32); + mat2 rotation_mat = make_rotation_mat(rotation); + + // TODO: make this configurable + // XXX: Scale by resolution (higher resolution needs smaller bias) + const float slope_bias = 0.001; + const float normal_bias = 0.0001; + const float const_bias = 0.003; + vec3 biased_pos = get_biased_position(m.position, slope_bias, normal_bias, m.normal, -l); + + vec3 projected = project(mvp, biased_pos); + vec2 projected_coord = projected.xy * uv.zw + uv.xy; + + const int num_samples = 8; + const float filter_size = 3.0 / SHADOW_ATLAS_SIZE; + + float accum = 0.0; + + for (int i = 0; i < num_samples; ++i) { + vec2 offs = projected_coord.xy + (rotation_mat * shadow_sample_offsets_8[i]) * filter_size; + #if SUPPORT_PCF + accum += textureLod(ShadowAtlasPCF, vec3(offs, projected.z - const_bias), 0).x; + #else + accum += textureLod(ShadowAtlas, vec2(offs), 0).x > + projected.z - const_bias ? 1.0 : 0.0; + #endif + } + + return accum / num_samples; +} + + + +// Shades the material from the per cell light buffer +vec3 shade_material_from_tile_buffer(Material m, ivec3 tile) { + + #if DEBUG_MODE && !MODE_ACTIVE(LIGHT_COUNT) && !SPECIAL_MODE_ACTIVE(LIGHT_TILES) + return vec3(0); + #endif + + // Skip emissive materials + if (m.shading_model == SHADING_MODEL_EMISSIVE) + return vec3(0); + + vec3 shading_result = vec3(0); + + // Find per tile lights + int cell_index = texelFetch(CellIndices, tile, 0).x; + int count_offs = cell_index * (1 + LIGHT_CLS_COUNT); // 1 for total count, rest for light classes + + + // Get the light counts + uint num_total_lights = texelFetch(PerCellLightsCounts, count_offs).x; + + // Early out when no lights are there + #if !MODE_ACTIVE(LIGHT_COUNT) && !SPECIAL_MODE_ACTIVE(LIGHT_TILES) + if (num_total_lights == 0) { + return vec3(0); + } + #endif + + // Get the per-class counts + uint num_spot_noshadow = texelFetch(PerCellLightsCounts, count_offs + 1 + LIGHT_CLS_SPOT_NOSHADOW).x; + uint num_spot_shadow = texelFetch(PerCellLightsCounts, count_offs + 1 + LIGHT_CLS_SPOT_SHADOW).x; + uint num_point_noshadow = texelFetch(PerCellLightsCounts, count_offs + 1 + LIGHT_CLS_POINT_NOSHADOW).x; + uint num_point_shadow = texelFetch(PerCellLightsCounts, count_offs + 1 + LIGHT_CLS_POINT_SHADOW).x; + + // Compute the index into the culled lights list + int data_offs = cell_index * LC_MAX_LIGHTS_PER_CELL; + int curr_offs = data_offs; + + #if MODE_ACTIVE(LIGHT_COUNT) + float factor = num_total_lights / float(LC_MAX_LIGHTS_PER_CELL); + return vec3(factor, 1 - factor, 0); + #endif + + // Debug mode, show tile bounds + #if SPECIAL_MODE_ACTIVE(LIGHT_TILES) + // Show tiles + #if IS_SCREEN_SPACE + if (int(gl_FragCoord.x) % LC_TILE_SIZE_X == 0 || + int(gl_FragCoord.y) % LC_TILE_SIZE_Y == 0) { + shading_result += 1.0; + } + float light_factor = num_total_lights / float(LC_MAX_LIGHTS_PER_CELL); + shading_result += ((tile.z + 1) % 2) * 0.2; + shading_result += light_factor; + #endif + #endif + + // Compute view vector + vec3 v = normalize(MainSceneData.camera_pos - m.position); + + // Spotlights without shadow + for (int i = 0; i < num_spot_noshadow; ++i) { + int light_offs = int(texelFetch(PerCellLights, curr_offs++).x); + LightData light_data = read_light_data(AllLightsData, light_offs); + shading_result += process_spotlight(m, light_data, v, 1.0); + } + + // Pointlights without shadow + for (int i = 0; i < num_point_noshadow; ++i) { + int light_offs = int(texelFetch(PerCellLights, curr_offs++).x); + LightData light_data = read_light_data(AllLightsData, light_offs); + shading_result += process_pointlight(m, light_data, v, 1.0); + } + + // Spotlights with shadow + for (int i = 0; i < num_spot_shadow; ++i) { + int light_offs = int(texelFetch(PerCellLights, curr_offs++).x); + LightData light_data = read_light_data(AllLightsData, light_offs); + + // Get shadow factor + vec3 v2l = normalize(m.position - get_light_position(light_data)); + int source_index = get_shadow_source_index(light_data); + SourceData source_data = read_source_data(ShadowSourceData, source_index * 5); + float shadow_factor = filter_shadowmap(m, source_data, v2l); + shading_result += process_spotlight(m, light_data, v, shadow_factor); + } + + // Pointlights with shadow + for (int i = 0; i < num_point_shadow; ++i) { + int light_offs = int(texelFetch(PerCellLights, curr_offs++).x); + LightData light_data = read_light_data(AllLightsData, light_offs); + + // Get shadow factor + int source_index = get_shadow_source_index(light_data); + vec3 v2l = normalize(m.position - get_light_position(light_data)); + source_index += get_pointlight_source_offs(v2l); + + SourceData source_data = read_source_data(ShadowSourceData, source_index * 5); + float shadow_factor = filter_shadowmap(m, source_data, v2l); + shading_result += process_pointlight(m, light_data, v, shadow_factor); + } + + // Fade out lights as they reach the culling distance + float curr_dist = distance(m.position, MainSceneData.camera_pos); + float fade = saturate(curr_dist / LC_MAX_DISTANCE); + fade = 1 - pow(fade, 10.0); + + return shading_result * fade; +} diff --git a/rpcore/shader/includes/lights.inc.glsl b/rpcore/shader/includes/lights.inc.glsl new file mode 100644 index 0000000..a423c50 --- /dev/null +++ b/rpcore/shader/includes/lights.inc.glsl @@ -0,0 +1,151 @@ +/** + * + * RenderPipeline + * + * Copyright (c) 2014-2016 tobspr + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + */ + +#pragma once + +#pragma include "includes/material.inc.glsl" +#pragma include "includes/brdf.inc.glsl" +#pragma include "includes/ies_lighting.inc.glsl" + +// Computes the quadratic attenuation curve +float attenuation_curve(float dist_square, float radius) { + #if 0 + return step(dist_square, radius * radius); + #endif + + #if 1 + float factor = dist_square / (radius * radius); + float smooth_factor = saturate(1.0 - factor * factor); + return smooth_factor * smooth_factor / max(0.01 * 0.01, dist_square); + #endif +} + + +// Computes the attenuation for a spot light +float get_spotlight_attenuation(vec3 l, vec3 light_dir, float fov, float radius, + float dist_sq, int ies_profile) { + float dist_attenuation = attenuation_curve(dist_sq, radius); + float cos_angle = dot(l, -light_dir); + + // Rescale angle to fit the full range of the IES profile. We only do this + // for spot lights, for point lights we use the actual angle. + // This is NOT physically correct for spotlights without a FoV of 180deg. + // However, IES profiles might look quite boring when not getting rescaled, + // so the rescaling is performed. + float linear_angle = (cos_angle - fov) / (1 - fov); + float angle_att = saturate(linear_angle); + float ies_factor = get_ies_factor(ies_profile, linear_angle, 0); + return ies_factor * angle_att * angle_att * dist_attenuation; +} + + +// Closest point on spherical area light, also returns energy factor +vec3 get_spherical_area_light_vector(vec3 n, vec3 l_unscaled, vec3 v, float radius) { + vec3 r = reflect(-v, n); + vec3 center_to_ray = dot(l_unscaled, r) * r - l_unscaled; + vec3 closest_point = l_unscaled + center_to_ray * + saturate(radius / max(1e-3, length(center_to_ray))); + return closest_point; +} + +vec3 get_spherical_area_light_horizon(vec3 l_unscaled, vec3 n, float radius) { + return normalize(l_unscaled + n * (0.5 * radius)); +} + +float get_spherical_area_light_energy(float alpha, float radius, float dist_sq) { + return max(0.000005, alpha * alpha) / max(0.01, radius * radius) * 4 * M_PI; +} + +// Computes a lights influence +// TODO: Make this method faster +vec3 apply_light(Material m, vec3 v, vec3 l, vec3 light_color, float attenuation, float shadow, + vec3 transmittance, float energy, float clearcoat_energy, vec3 l_diffuse) { + + // Debugging: Fast rendering path + #if 0 + return light_color * attenuation; + #endif + + float NxL = saturate(dot(m.normal, l_diffuse)); + + if (m.shading_model == SHADING_MODEL_FOLIAGE) { + transmittance = transmittance.xxx; + } else if (m.shading_model == SHADING_MODEL_SKIN) { + NxL = saturate(0.3 + dot(m.normal, l_diffuse)); + } else { + transmittance = vec3(1); + } + + // Compute the dot products + vec3 h = normalize(l + v); + float NxV = max(1e-5, dot(m.normal, v)); + float NxH = max(1e-5, dot(m.normal, h)); + float VxH = clamp(dot(v, h), 1e-5, 1.0); + float LxH = max(0, dot(l, h)); + + vec3 f0 = get_material_f0(m); + + // Diffuse contribution + vec3 shading_result = brdf_diffuse(NxV, NxL, LxH, VxH, m.roughness) + * m.basecolor * (1 - m.metallic); + + // Specular contribution: + // We add some roughness for clearcoat - this is due to the reason that + // light gets scattered and thus a wider highlight is shown. + // This approximates the reference in mitsuba very well. + // float distribution = brdf_distribution(NxH, m.roughness); + float distribution = brdf_distribution(NxH, m.roughness); // xxx + float visibility = brdf_visibility(NxL, NxV, NxH, VxH, m.roughness); + vec3 fresnel = brdf_schlick_fresnel(f0, LxH); + + + // The division by 4 * NxV * NxL is done in the geometric (visibility) term + // already, so to evaluate the complete brdf we just do a multiply + shading_result += (distribution * visibility) * fresnel / (4.0 * NxV * NxL) * energy; + + if (m.shading_model == SHADING_MODEL_CLEARCOAT) { + float distribution_coat = brdf_distribution(NxH, CLEARCOAT_ROUGHNESS); + float visibility_coat = brdf_visibility(NxL, NxV, NxH, VxH, CLEARCOAT_ROUGHNESS); + vec3 fresnel_coat = brdf_schlick_fresnel(vec3(CLEARCOAT_SPECULAR), LxH); + + // Approximation to match reference + shading_result *= (1 - fresnel_coat.x); + shading_result *= 0.4 + 3.0 * m.linear_roughness; + shading_result *= 0.5 + 0.5 * m.basecolor; + + vec3 coat_spec = (distribution_coat * visibility_coat * clearcoat_energy) * fresnel_coat; + shading_result += coat_spec; + } + + return max(vec3(0), + (shading_result * light_color) * (attenuation * shadow * NxL) * transmittance); +} + +vec3 apply_light(Material m, vec3 v, vec3 l, vec3 light_color, float attenuation, + float shadow, vec3 transmittance) { + return apply_light( + m, v, l, light_color, attenuation, shadow, transmittance, 1.0, 1.0, l); +} diff --git a/rpcore/shader/includes/material.inc.glsl b/rpcore/shader/includes/material.inc.glsl new file mode 100644 index 0000000..3fa42eb --- /dev/null +++ b/rpcore/shader/includes/material.inc.glsl @@ -0,0 +1,146 @@ +/** + * + * RenderPipeline + * + * Copyright (c) 2014-2016 tobspr + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + */ + +#pragma once + +#define SHADING_MODEL_DEFAULT 0 +#define SHADING_MODEL_EMISSIVE 1 +#define SHADING_MODEL_CLEARCOAT 2 +#define SHADING_MODEL_TRANSPARENT 3 +#define SHADING_MODEL_SKIN 4 +#define SHADING_MODEL_FOLIAGE 5 + +// Pandas material representation +struct Panda3DMaterial { + vec4 baseColor; + vec4 emission; + float roughness; + float metallic; + float refractiveIndex; +}; + +// Structure passed from the vertex to the fragment shader +struct MaterialBaseInput { + vec3 color; + int shading_model; + float specular_ior; + float metallic; + float roughness; + float normalfactor; + float arbitrary0; + // float arbitrary1; +}; + +// Converts from a Panda3D Material to a render pipeline material +MaterialBaseInput get_input_from_p3d(Panda3DMaterial m) { + MaterialBaseInput mi; + mi.color = m.baseColor.xyz; + mi.specular_ior = m.refractiveIndex; + mi.metallic = m.metallic; + mi.roughness = m.roughness; + mi.shading_model = int(m.emission.x); + mi.normalfactor = m.emission.y; + mi.arbitrary0 = m.emission.z; + // mi.arbitrary1 = m.emission.w; + return mi; +} + +// Structure used in the Material Templates +struct MaterialShaderOutput { + int shading_model; + vec3 basecolor; + vec3 normal; + float roughness; + float specular_ior; + float metallic; + float shading_model_param0; +}; + + +// Structure actually stored in the GBuffer, this *may* differ but not necessarily has to: +struct Material { + int shading_model; + vec3 basecolor; + vec3 normal; + vec3 position; + float roughness; + float specular; + float specular_ior; + float metallic; + float shading_model_param0; + float linear_roughness; +}; + +// Merges two materials, by doing (per component): +// result = current + to_add * factor; +void merge_material_output(inout MaterialShaderOutput current, + MaterialShaderOutput to_add, float factor) { + current.basecolor += to_add.basecolor * factor; + current.roughness += to_add.roughness * factor; + current.specular_ior += to_add.specular_ior * factor; + current.metallic += to_add.metallic * factor; + current.shading_model_param0 += to_add.shading_model_param0 * factor; + current.normal += to_add.normal * factor; +} + +// Creates an empty material +MaterialShaderOutput make_default_material_output() { + MaterialShaderOutput result; + result.shading_model = SHADING_MODEL_DEFAULT; + result.basecolor = vec3(0.8); + result.normal = vec3(0, 0, 1); + result.roughness = 0.3; + result.specular_ior = 1.51; + result.metallic = 0.0; + result.shading_model_param0 = 0.0; + return result; +} + +// Required for ior_to_specular +#pragma include "includes/brdf.inc.glsl" + +#ifdef IN_RENDERING_PASS + + + // Emulates the gbuffer pass + Material emulate_gbuffer_pass(MaterialShaderOutput m_out, vec3 position) { + // Copy properties + Material m; + m.shading_model = m_out.shading_model; + m.basecolor = m_out.basecolor; + m.normal = m_out.normal; + m.specular_ior = m_out.specular_ior; + m.metallic = m_out.metallic; + m.shading_model_param0 = m_out.shading_model_param0; + + // Assign new properties + m.position = position; + m.specular = ior_to_specular(m_out.specular_ior); + m.linear_roughness = m_out.roughness; + m.roughness *= m.roughness; + return m; + } +#endif diff --git a/rpcore/shader/includes/noise.inc.glsl b/rpcore/shader/includes/noise.inc.glsl new file mode 100644 index 0000000..c5bf7d0 --- /dev/null +++ b/rpcore/shader/includes/noise.inc.glsl @@ -0,0 +1,328 @@ +/** + * + * RenderPipeline + * + * Copyright (c) 2014-2016 tobspr + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + */ + +#pragma once + +/* + +Noise Functions from: +https://github.com/hughsk/glsl-noise + +Check out the repository for a copy of the license: +https://github.com/hughsk/glsl-noise/blob/master/LICENSE + +*/ + +vec3 mod289(vec3 x) { + return x - floor(x * (1.0 / 289.0)) * 289.0; +} + +vec4 mod289(vec4 x) { + return x - floor(x * (1.0 / 289.0)) * 289.0; +} + +vec4 permute(vec4 x) { + return mod289(((x * 34.0) + 1.0) * x); +} + +vec4 taylorInvSqrt(vec4 r) +{ + return 1.79284291400159 - 0.85373472095314 * r; +} + +vec3 fade(vec3 t) { + return t * t * t * (t * (t * 6.0 - 15.0) + 10.0); +} + + +float snoise3D(vec3 v) { + const vec2 C = vec2(1.0 / 6.0, 1.0 / 3.0) ; + const vec4 D = vec4(0.0, 0.5, 1.0, 2.0); + + // First corner + vec3 i = floor(v + dot(v, C.yyy)); + vec3 x0 = v - i + dot(i, C.xxx); + + // Other corners + vec3 g = step(x0.yzx, x0.xyz); + vec3 l = 1.0 - g; + vec3 i1 = min(g.xyz, l.zxy); + vec3 i2 = max(g.xyz, l.zxy); + + // x0 = x0 - 0.0 + 0.0 * C.xxx; + // x1 = x0 - i1 + 1.0 * C.xxx; + // x2 = x0 - i2 + 2.0 * C.xxx; + // x3 = x0 - 1.0 + 3.0 * C.xxx; + vec3 x1 = x0 - i1 + C.xxx; + vec3 x2 = x0 - i2 + C.yyy; // 2.0*C.x = 1/3 = C.y + vec3 x3 = x0 - D.yyy; // -1.0+3.0*C.x = -0.5 = -D.y + + // Permutations + i = mod289(i); + vec4 p = permute(permute(permute( + i.z + vec4(0.0, i1.z, i2.z, 1.0)) + + i.y + vec4(0.0, i1.y, i2.y, 1.0)) + + i.x + vec4(0.0, i1.x, i2.x, 1.0)); + + // Gradients: 7x7 points over a square, mapped onto an octahedron. + // The ring size 17*17 = 289 is close to a multiple of 49 (49*6 = 294) + float n_ = 0.142857142857; // 1.0/7.0 + vec3 ns = n_ * D.wyz - D.xzx; + + vec4 j = p - 49.0 * floor(p * ns.z * ns.z); // mod(p,7*7) + + vec4 x_ = floor(j * ns.z); + vec4 y_ = floor(j - 7.0 * x_); // mod(j,N) + + vec4 x = x_ * ns.x + ns.yyyy; + vec4 y = y_ * ns.x + ns.yyyy; + vec4 h = 1.0 - abs(x) - abs(y); + + vec4 b0 = vec4(x.xy, y.xy); + vec4 b1 = vec4(x.zw, y.zw); + + //vec4 s0 = vec4(lessThan(b0,0.0))*2.0 - 1.0; + //vec4 s1 = vec4(lessThan(b1,0.0))*2.0 - 1.0; + vec4 s0 = floor(b0) * 2.0 + 1.0; + vec4 s1 = floor(b1) * 2.0 + 1.0; + vec4 sh = -step(h, vec4(0.0)); + + vec4 a0 = b0.xzyw + s0.xzyw * sh.xxyy ; + vec4 a1 = b1.xzyw + s1.xzyw * sh.zzww ; + + vec3 p0 = vec3(a0.xy, h.x); + vec3 p1 = vec3(a0.zw, h.y); + vec3 p2 = vec3(a1.xy, h.z); + vec3 p3 = vec3(a1.zw, h.w); + + // Normalise gradients + vec4 norm = taylorInvSqrt(vec4(dot(p0, p0), dot(p1, p1), dot(p2, p2), dot(p3, p3))); + p0 *= norm.x; + p1 *= norm.y; + p2 *= norm.z; + p3 *= norm.w; + + // Mix final noise value + vec4 m = max(0.6 - vec4(dot(x0, x0), dot(x1, x1), dot(x2, x2), dot(x3, x3)), 0.0); + m = m * m; + return 42.0 * dot(m * m, + vec4(dot(p0, x0), dot(p1, x1), dot(p2, x2), dot(p3, x3))); +} + + +// Classic Perlin noise, periodic variant +float pnoise3D(vec3 P, vec3 rep) +{ + vec3 Pi0 = mod(floor(P), rep); // Integer part, modulo period + vec3 Pi1 = mod(Pi0 + vec3(1.0), rep); // Integer part + 1, mod period + Pi0 = mod289(Pi0); + Pi1 = mod289(Pi1); + vec3 Pf0 = fract(P); // Fractional part for interpolation + vec3 Pf1 = Pf0 - vec3(1.0); // Fractional part - 1.0 + vec4 ix = vec4(Pi0.x, Pi1.x, Pi0.x, Pi1.x); + vec4 iy = vec4(Pi0.yy, Pi1.yy); + vec4 iz0 = Pi0.zzzz; + vec4 iz1 = Pi1.zzzz; + + vec4 ixy = permute(permute(ix) + iy); + vec4 ixy0 = permute(ixy + iz0); + vec4 ixy1 = permute(ixy + iz1); + + vec4 gx0 = ixy0 * (1.0 / 7.0); + vec4 gy0 = fract(floor(gx0) * (1.0 / 7.0)) - 0.5; + gx0 = fract(gx0); + vec4 gz0 = vec4(0.5) - abs(gx0) - abs(gy0); + vec4 sz0 = step(gz0, vec4(0.0)); + gx0 -= sz0 * (step(0.0, gx0) - 0.5); + gy0 -= sz0 * (step(0.0, gy0) - 0.5); + + vec4 gx1 = ixy1 * (1.0 / 7.0); + vec4 gy1 = fract(floor(gx1) * (1.0 / 7.0)) - 0.5; + gx1 = fract(gx1); + vec4 gz1 = vec4(0.5) - abs(gx1) - abs(gy1); + vec4 sz1 = step(gz1, vec4(0.0)); + gx1 -= sz1 * (step(0.0, gx1) - 0.5); + gy1 -= sz1 * (step(0.0, gy1) - 0.5); + + vec3 g000 = vec3(gx0.x, gy0.x, gz0.x); + vec3 g100 = vec3(gx0.y, gy0.y, gz0.y); + vec3 g010 = vec3(gx0.z, gy0.z, gz0.z); + vec3 g110 = vec3(gx0.w, gy0.w, gz0.w); + vec3 g001 = vec3(gx1.x, gy1.x, gz1.x); + vec3 g101 = vec3(gx1.y, gy1.y, gz1.y); + vec3 g011 = vec3(gx1.z, gy1.z, gz1.z); + vec3 g111 = vec3(gx1.w, gy1.w, gz1.w); + + vec4 norm0 = taylorInvSqrt(vec4( + dot(g000, g000), dot(g010, g010), dot(g100, g100), dot(g110, g110))); + g000 *= norm0.x; + g010 *= norm0.y; + g100 *= norm0.z; + g110 *= norm0.w; + vec4 norm1 = taylorInvSqrt(vec4( + dot(g001, g001), dot(g011, g011), dot(g101, g101), dot(g111, g111))); + g001 *= norm1.x; + g011 *= norm1.y; + g101 *= norm1.z; + g111 *= norm1.w; + + float n000 = dot(g000, Pf0); + float n100 = dot(g100, vec3(Pf1.x, Pf0.yz)); + float n010 = dot(g010, vec3(Pf0.x, Pf1.y, Pf0.z)); + float n110 = dot(g110, vec3(Pf1.xy, Pf0.z)); + float n001 = dot(g001, vec3(Pf0.xy, Pf1.z)); + float n101 = dot(g101, vec3(Pf1.x, Pf0.y, Pf1.z)); + float n011 = dot(g011, vec3(Pf0.x, Pf1.yz)); + float n111 = dot(g111, Pf1); + + vec3 fade_xyz = fade(Pf0); + vec4 n_z = mix(vec4(n000, n100, n010, n110), vec4(n001, n101, n011, n111), fade_xyz.z); + vec2 n_yz = mix(n_z.xy, n_z.zw, fade_xyz.y); + float n_xyz = mix(n_yz.x, n_yz.y, fade_xyz.x); + return 2.2 * n_xyz; +} + + +float rand(vec2 co){ + return abs(fract(sin(dot(co.xy, vec2(12.9898, 78.233))) * 43758.5453)) * 2 - 1; +} + + +vec3 rand_rgb(vec2 co) +{ + return abs(fract(sin(dot(co.xy, vec2(34.4835, 89.6372))) * + vec3(29156.4765, 38273.56393, 47843.75468))) * 2 - 1; +} + + +uniform sampler2D PrecomputedGrain; + +// Computes the film grain using the precomputed grain +float grain(float frame_time) { + float offs = mod(frame_time, 7.2342); + ivec2 offs_coord = ivec2(offs * 28947.0, (offs - 2.5) * 12484.0); + return texelFetch(PrecomputedGrain, (ivec2(gl_FragCoord.xy) + offs_coord) % ivec2(2048), 0).x; +} + + +float fbm(vec3 x, float scale) { + float v = 0.0; + float a = 0.5; + float shift = 0.0; + x *= scale; + for (int i = 0; i < 5; ++i) { + v += a * (pnoise3D(x, vec3(scale)) * 0.5 + 0.5); + x = x * 2.0 + shift; + a *= 0.5; + } + return v; +} + + +// Returns the point in a given cell +vec2 worley_cell_point(ivec2 cell, int num_cells, float drop_rate) { + cell = cell % num_cells; + vec2 cell_base = vec2(cell) / num_cells; + float noise_x = rand(cell_base); + float noise_y = rand(cell_base.yx); + float drop_point = step(rand(cell) + 1e-7, drop_rate); + return cell_base + (0.5 + 1.0 * vec2(noise_x, noise_y)) / num_cells + drop_point * vec2(1e9); +} + + +// Distance accross borders +float distance_border(vec2 a, vec2 b) { + float dx = min(abs(a.x - b.x), min(abs(a.x - 1.0 - b.x), abs(a.x + 1.0 - b.x))); + float dy = min(abs(a.y - b.y), min(abs(a.y - 1.0 - b.y), abs(a.y + 1.0 - b.y))); + return length(vec2(dx, dy)); +} + +// Performs worley noise by checking all adjacent cells +// and comparing the distance to their points +float worley_noise(vec2 coord, int num_cells, float drop_rate) { + coord = fract(coord); + ivec2 cell = ivec2(coord * num_cells); + float dist = 1.0; + + // Search in the surrounding 5x5 cell block + for (int x = 0; x < 5; x++) { + for (int y = 0; y < 5; y++) { + vec2 cell_point = worley_cell_point(cell + ivec2(x-2, y-2), num_cells, drop_rate); + dist = min(dist, distance_border(cell_point, coord)); + } + } + dist /= length(vec2(1.0 / num_cells)); + dist = 1.0 - dist; + return dist; +} + +// Returns the point in a given cell +vec3 worley_cell_point(ivec3 cell, int num_cells, float drop_rate) { + cell = cell % num_cells; + vec3 cell_base = vec3(cell) / num_cells; + float noise_x = rand(cell_base.xy); + float noise_y = rand(cell_base.yx); + float noise_z = rand(cell_base.zx + cell_base.yy); + float drop_point = step(rand(cell.xy + cell.zz) + 1e-7, drop_rate); + return cell_base + (0.5 + 1.0 * vec3(noise_x, noise_y, noise_z)) / + num_cells + drop_point * vec3(1e9); +} + + +// Distance accross borders +float distance_border(vec3 a, vec3 b) { + float dx = min(abs(a.x - b.x), min(abs(a.x - 1.0 - b.x), abs(a.x + 1.0 - b.x))); + float dy = min(abs(a.y - b.y), min(abs(a.y - 1.0 - b.y), abs(a.y + 1.0 - b.y))); + float dz = min(abs(a.z - b.z), min(abs(a.z - 1.0 - b.z), abs(a.z + 1.0 - b.z))); + return length(vec3(dx, dy, dz)); +} + +// Performs worley noise by checking all adjacent cells +// and comparing the distance to their points +float worley_noise(vec3 coord, int num_cells, float drop_rate) { + coord = fract(coord); + ivec3 cell = ivec3(coord * num_cells); + float dist = 1.0; + + // Search in the surrounding 5x5 cell block + for (int x = 0; x < 5; x++) { + for (int y = 0; y < 5; y++) { + for (int z = 0; z < 5; z++) { + vec3 cell_point = worley_cell_point(cell + ivec3(x-2, y-2, z-2), num_cells, drop_rate); + dist = min(dist, distance_border(cell_point, coord)); + } + } + } + dist /= length(vec3(1.0 / num_cells)); + dist = 1.0 - dist; + return dist; +} + +float interleaved_gradient_noise(vec2 seed) { + const float scale = 3.14159; + vec3 magic = vec3(0.06711056, 0.00583715, 52.9829189); + return -scale + 2.0 * scale * fract(magic.z * fract(dot(seed, magic.xy))); +} diff --git a/rpcore/shader/includes/nonviewspace_shading_pipeline.inc.glsl b/rpcore/shader/includes/nonviewspace_shading_pipeline.inc.glsl new file mode 100644 index 0000000..1f3940d --- /dev/null +++ b/rpcore/shader/includes/nonviewspace_shading_pipeline.inc.glsl @@ -0,0 +1,77 @@ +/** + * + * RenderPipeline + * + * Copyright (c) 2014-2016 tobspr + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + */ + +#pragma once + +#pragma include "includes/shadows.inc.glsl" +#pragma include "includes/material.inc.glsl" +#pragma include "includes/poisson_disk.inc.glsl" +#pragma include "includes/vertex_output.struct.glsl" + +#if DONT_FETCH_DEFAULT_TEXTURES + // Don't bind any samplers in this case, so the user can do it on his own +#else + uniform sampler2D p3d_Texture0; +#endif + +uniform Panda3DMaterial p3d_Material; + +layout(location = 0) in VertexOutput vOutput; + +#pragma include "includes/normal_mapping.inc.glsl" +#pragma include "includes/forward_shading.inc.glsl" + +MaterialShaderOutput prepare_material(MaterialBaseInput mInput, vec2 texcoord) { + MaterialShaderOutput m; + + #if DONT_SET_MATERIAL_PROPERTIES + // Leave material properties unitialized, and hope the user knows + // what he's doing. + #else + + #if DONT_FETCH_DEFAULT_TEXTURES + vec4 sampled_diffuse = vec4(1); + #else + vec4 sampled_diffuse = texture(p3d_Texture0, texcoord); + #endif + + // XXX: Support for alpha testing + // if (sampled_diffuse.w < 0.5) discard; + + // XXX: *maybe* support for normal mapping + + // Copy default material properties + m.basecolor = sampled_diffuse.xyz * mInput.color; + m.shading_model = mInput.shading_model; + m.normal = vOutput.normal; + m.metallic = mInput.metallic; + m.specular_ior = mInput.specular_ior; + m.roughness = mInput.roughness; + m.shading_model_param0 = mInput.arbitrary0; + #endif + + return m; +} diff --git a/rpcore/shader/includes/normal_mapping.inc.glsl b/rpcore/shader/includes/normal_mapping.inc.glsl new file mode 100644 index 0000000..7c6488c --- /dev/null +++ b/rpcore/shader/includes/normal_mapping.inc.glsl @@ -0,0 +1,116 @@ +/** + * + * RenderPipeline + * + * Copyright (c) 2014-2016 tobspr + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + */ + +#pragma once + +// Reconstructs the tangent with the deltas of +// the position and texcoord +void reconstruct_tangent(out vec3 tangent, out vec3 binormal) { + vec3 pos_dx = dFdx(vOutput.position); + vec3 pos_dy = dFdy(vOutput.position); + float tcoord_dx = dFdx(vOutput.texcoord.y); + float tcoord_dy = dFdy(vOutput.texcoord.y); + + // Fix issues when the texture coordinate is wrong, this happens when + // two adjacent vertices have the same texture coordinate, as the gradient + // is 0 then. We just assume some hard-coded tangent and binormal then + if (abs(tcoord_dx) < 1e-24 && abs(tcoord_dy) < 1e-24) { + vec3 base = abs(vOutput.normal.z) < 0.999 ? vec3(0, 0, 1) : vec3(0, 1, 0); + tangent = normalize(cross(vOutput.normal, base)); + } else { + tangent = normalize(pos_dx * tcoord_dy - pos_dy * tcoord_dx); + } + + binormal = normalize(cross(tangent, vOutput.normal)); +} + + +// Aplies a normal map with a given base normal and displace normal, weighted by +// the bump factor +vec3 apply_normal_map(vec3 base_normal, vec3 displace_normal, float bump_factor, + vec3 tangent, vec3 binormal) { + // Optional: Make sure the base normal is correct + // base_normal = normalize(base_normal); + displace_normal = mix(vec3(0, 0, 1), displace_normal, saturate(bump_factor)); + return vec3( + tangent * displace_normal.x + + binormal * displace_normal.y + + base_normal * displace_normal.z + ); +} + + +vec3 apply_normal_map(vec3 base_normal, vec3 displace_normal, float bump_factor) { + vec3 tangent, binormal; + reconstruct_tangent(tangent, binormal); + return apply_normal_map(base_normal, displace_normal, bump_factor, tangent, binormal); +} + +// Parallax Mapping +vec2 get_parallax_texcoord(sampler2D displacement_map, float strength) { + // To disable parallax mapping: + // return vOutput.texcoord; + + const float max_dist = 50.0; + vec3 vec_to_cam = vOutput.position - MainSceneData.camera_pos; + + float initial_height = texture(displacement_map, vOutput.texcoord).x; + float pixel_dist = length(vec_to_cam); + + // Early out for materials without parallax mapping + if (initial_height > 0.999 || pixel_dist > max_dist) return vOutput.texcoord; + + float NxV = max(0.0, dot(vOutput.normal, vec_to_cam / pixel_dist)); // xxx merge with pixel dist + + float raymarch_distance = 0.2 * strength; + int num_steps = max(5, int((40 - (pixel_dist / max_dist) * 37.0) * (1 - NxV))); + + vec3 tangent, binormal; + reconstruct_tangent(tangent, binormal); + + vec3 view_vector = normalize(MainSceneData.camera_pos - vOutput.position); + + // Project view vector to tangent space + vec2 tex_offs = vec2(dot(-tangent, view_vector), dot(binormal, view_vector)); + + // Get the ray start and direction + vec3 current_pos = vec3(vOutput.texcoord, 1); + raymarch_distance *= 0.5 / clamp(dot(vOutput.normal, view_vector), 0.3, 1.0); + vec3 offs_step = vec3(tex_offs * raymarch_distance, -1.0) / float(num_steps); + + // Raymarch + vec3 last_hit = current_pos; + for (int i = 0; i < num_steps; ++i) { + float sample_h = texture(displacement_map, current_pos.xy).x; + current_pos += offs_step; + if (sample_h <= current_pos.z) { + last_hit = current_pos; + } + } + + float fade = square(square(square(pixel_dist / max_dist))); + return mix(last_hit.xy, vOutput.texcoord, fade); +} diff --git a/rpcore/shader/includes/normal_packing.inc.glsl b/rpcore/shader/includes/normal_packing.inc.glsl new file mode 100644 index 0000000..66f9a70 --- /dev/null +++ b/rpcore/shader/includes/normal_packing.inc.glsl @@ -0,0 +1,97 @@ +/** + * + * RenderPipeline + * + * Copyright (c) 2014-2016 tobspr + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + */ + +#pragma once + +/* + +Normal packing as described in: +A Survey of Efficient Representations for Independent Unit Vectors +Source: http://jcgt.org/published/0003/02/01/paper.pdf + +*/ + +// For each component of v, returns -1 if the component is < 0, else 1 +vec2 sign_not_zero(vec2 v) { + #if 1 + // Branch-Less version + return fma(step(vec2(0.0), v), vec2(2.0), vec2(-1.0)); + #else + // Version with branches (for GLSL < 4.00) + return vec2( + v.x >= 0 ? 1.0 : -1.0, + v.y >= 0 ? 1.0 : -1.0 + ); + #endif +} + +// Packs a 3-component normal to 2 channels using octahedron normals +vec2 pack_normal_octahedron(vec3 v) { + #if 0 + // Version as proposed by the paper + // Project the sphere onto the octahedron, and then onto the xy plane + vec2 p = v.xy * (1.0 / (abs(v.x) + abs(v.y) + abs(v.z))); + // Reflect the folds of the lower hemisphere over the diagonals + return (v.z <= 0.0) ? ((1.0 - abs(p.yx)) * sign_not_zero(p)) : p; + #else + // Faster version using newer GLSL capatibilities + v.xy /= dot(abs(v), vec3(1)); + + #if 0 + // Version with branches + if (v.z <= 0) v.xy = (1.0 - abs(v.yx)) * sign_not_zero(v.xy); + return v.xy; + #else + // Branch-Less version + return mix(v.xy, (1.0 - abs(v.yx)) * sign_not_zero(v.xy), step(v.z, 0.0)); + #endif + #endif +} + + +// Unpacking from octahedron normals, input is the output from pack_normal_octahedron +vec3 unpack_normal_octahedron(vec2 packed_nrm) { + #if 1 + // Version using newer GLSL capatibilities + vec3 v = vec3(packed_nrm.xy, 1.0 - abs(packed_nrm.x) - abs(packed_nrm.y)); + #if 1 + // Version with branches, seems to take less cycles than the + // branch-less version + if (v.z < 0) v.xy = (1.0 - abs(v.yx)) * sign_not_zero(v.xy); + #else + // Branch-Less version + v.xy = mix(v.xy, (1.0 - abs(v.yx)) * sign_not_zero(v.xy), step(v.z, 0)); + #endif + + return normalize(v); + #else + // Version as proposed in the paper. + vec3 v = vec3(packed_nrm, 1.0 - dot(vec2(1), abs(packed_nrm))); + if (v.z < 0) + v.xy = (vec2(1) - abs(v.yx)) * sign_not_zero(v.xy); + return normalize(v); + #endif +} diff --git a/rpcore/shader/includes/poisson_disk.inc.glsl b/rpcore/shader/includes/poisson_disk.inc.glsl new file mode 100644 index 0000000..e906d76 --- /dev/null +++ b/rpcore/shader/includes/poisson_disk.inc.glsl @@ -0,0 +1,333 @@ +/** + * + * RenderPipeline + * + * Copyright (c) 2014-2016 tobspr + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + */ + +#pragma once + + +/* + +This are uniformly distributed Poisson Disks. + +All disks are sorted depending on their angle and radius, to make sure texture +chaching works as intended. + +The program to generate the poisson disks can be found in +toolkit/poisson_disk_generator. + +*/ + + +/* + +2D Poisson Disks + +*/ + +CONST_ARRAY vec2 poisson_2D_4[4] = vec2[]( + vec2(-0.953543, -0.300415), + vec2(0.291287, -0.956411), + vec2(0.957769, 0.282242), + vec2(-0.277367, 0.960318) +); + +CONST_ARRAY vec2 poisson_2D_8[8] = vec2[]( + vec2(-0.994272, -0.104946), + vec2(-0.375669, -0.92651), + vec2(0.62611, -0.778924), + vec2(0.910956, 0.412246), + vec2(0.972791, -0.226412), + vec2(0.265636, 0.96113), + vec2(-0.549897, 0.833746), + vec2(0.00219648, 0.00555702) +); + +CONST_ARRAY vec2 poisson_2D_12[12] = vec2[]( + vec2(-0.759347, -0.650607), + vec2(-0.276351, -0.00941298), + vec2(-0.999368, -0.0324209), + vec2(-0.193248, -0.979636), + vec2(0.457157, -0.885871), + vec2(0.968703, -0.246042), + vec2(0.310191, -0.266896), + vec2(0.44068, 0.355746), + vec2(0.448887, 0.885861), + vec2(0.955905, 0.292457), + vec2(-0.79166, 0.605247), + vec2(-0.0714434, 0.980047) +); + + +CONST_ARRAY vec2 poisson_2D_16[16] = vec2[]( + vec2(-0.680088, -0.731923), + vec2(-0.957909, -0.247622), + vec2(0.0948045, -0.992508), + vec2(-0.316418, -0.93561), + vec2(0.508091, -0.270309), + vec2(0.986855, -0.161122), + vec2(-0.0783372, -0.377044), + vec2(0.678299, -0.730012), + vec2(0.264303, 0.150586), + vec2(0.375585, 0.926198), + vec2(0.869216, 0.485342), + vec2(-0.0303609, 0.582547), + vec2(-0.456659, 0.886469), + vec2(-0.0502123, 0.998242), + vec2(-0.522737, 0.0698312), + vec2(-0.857891, 0.512805) +); + +CONST_ARRAY vec2 poisson_2D_32[32] = vec2[]( + vec2(-0.645095, -0.281509), + vec2(-0.491004, -0.535543), + vec2(-0.251013, -0.96746), + vec2(-0.527482, -0.838249), + vec2(-0.940142, -0.338633), + vec2(-0.78887, -0.602182), + vec2(-0.306068, -0.207344), + vec2(0.0236232, -0.763255), + vec2(0.326509, -0.930717), + vec2(0.0188184, -0.427136), + vec2(0.734814, -0.2611), + vec2(0.997828, -0.0467772), + vec2(0.102272, -0.0652116), + vec2(0.800923, -0.596026), + vec2(0.532466, -0.718217), + vec2(0.45988, -0.0147904), + vec2(0.428033, -0.434308), + vec2(0.569939, 0.31757), + vec2(0.847669, 0.530125), + vec2(0.517769, 0.839368), + vec2(0.247533, 0.477887), + vec2(0.952392, 0.24895), + vec2(-0.49404, 0.843787), + vec2(0.071269, 0.98377), + vec2(-0.901791, 0.425404), + vec2(-0.511218, 0.404082), + vec2(-0.166727, 0.573622), + vec2(-0.719383, 0.656148), + vec2(-0.221952, 0.956912), + vec2(-0.639361, 0.0178937), + vec2(-0.192214, 0.149272), + vec2(-0.999393, 0.0286758) +); + +CONST_ARRAY vec2 poisson_2D_64[64] = vec2[]( + vec2(-0.086316, -0.968111), + vec2(-0.279227, -0.959008), + vec2(-0.174659, -0.779219), + vec2(-0.994046, -0.100337), + vec2(-0.830417, -0.258316), + vec2(-0.29098, -0.276363), + vec2(-0.0711791, -0.309748), + vec2(0.127704, -0.414434), + vec2(0.255973, -0.712316), + vec2(-0.472927, -0.394059), + vec2(0.35572, -0.928901), + vec2(-0.658504, -0.535877), + vec2(0.105184, -0.99382), + vec2(-0.414437, -0.0607066), + vec2(-0.366554, -0.691781), + vec2(-0.464703, -0.862405), + vec2(-0.161989, -0.104327), + vec2(-0.174757, -0.515362), + vec2(-0.637325, -0.770203), + vec2(-0.664806, -0.128825), + vec2(-0.879395, -0.465052), + vec2(0.0304411, -0.762748), + vec2(0.443908, -0.577779), + vec2(0.188869, -0.0525923), + vec2(0.988219, -0.136184), + vec2(0.369901, -0.259416), + vec2(0.805865, -0.578815), + vec2(0.628829, -0.776143), + vec2(0.626141, -0.343504), + vec2(0.74722, 0.655944), + vec2(0.234085, 0.806087), + vec2(0.93415, 0.337947), + vec2(0.412135, 0.901209), + vec2(0.676801, 0.206996), + vec2(0.0943238, 0.661738), + vec2(0.118536, 0.984615), + vec2(0.589421, 0.79131), + vec2(0.731047, 0.429766), + vec2(0.478587, 0.439142), + vec2(0.22497, 0.445659), + vec2(0.374495, 0.660695), + vec2(0.906059, 0.0973713), + vec2(0.33495, 0.190513), + vec2(0.757964, -0.136907), + vec2(0.54374, -0.0527806), + vec2(0.908866, -0.36894), + vec2(-0.0776111, 0.477161), + vec2(-0.181392, 0.975743), + vec2(-0.139923, 0.74221), + vec2(-0.78206, 0.102957), + vec2(-0.576849, 0.450708), + vec2(-0.00888789, 0.05214), + vec2(-0.708787, 0.698047), + vec2(-0.84552, 0.531998), + vec2(-0.253359, 0.267802), + vec2(-0.493709, 0.659425), + vec2(-0.992843, 0.11576), + vec2(-0.302095, 0.564714), + vec2(-0.464918, 0.874781), + vec2(-0.711149, 0.302547), + vec2(-0.915964, 0.323287), + vec2(-0.263747, 0.0616327), + vec2(-0.519476, 0.175641), + vec2(0.0307961, 0.26891) +); + + + +/* + + +3D Poisson Disks + + +*/ + +CONST_ARRAY vec3 poisson_3D_16[16] = vec3[]( + vec3(-0.0601252, -0.090253, 0.242585), + vec3(-0.954277, -0.230389, 0.0491814), + vec3(-0.440708, -0.751107, 0.48156), + vec3(0.157285, -0.98681, -0.0113457), + vec3(-0.463958, -0.603355, -0.645049), + vec3(0.352804, -0.600314, 0.705076), + vec3(0.945725, -0.167066, -0.26733), + vec3(0.378653, -0.457091, -0.789674), + vec3(0.175363, 0.326807, -0.923022), + vec3(0.75046, 0.133097, 0.643648), + vec3(0.533623, 0.832552, 0.0769863), + vec3(-0.685037, 0.662173, -0.295431), + vec3(-0.0454946, 0.134477, 0.985295), + vec3(-0.534475, 0.0997254, -0.826768), + vec3(-0.307152, 0.748555, 0.585295), + vec3(-0.709746, 0.0374277, 0.68205) +); + +CONST_ARRAY vec3 poisson_3D_32[32] = vec3[]( + vec3(-0.637433, -0.0795689, 0.749829), + vec3(-0.166216, -0.0315564, -0.983756), + vec3(-0.528491, -0.143633, 0.195646), + vec3(-0.249567, -0.825099, 0.498893), + vec3(-0.558757, -0.434904, -0.667499), + vec3(-0.858404, -0.473501, -0.145915), + vec3(-0.135047, -0.296593, -0.335407), + vec3(0.316311, -0.757367, 0.261108), + vec3(-0.163747, -0.374054, 0.88854), + vec3(0.268538, -0.898278, -0.335799), + vec3(-0.381943, -0.906282, -0.16664), + vec3(0.837301, -0.420993, 0.347183), + vec3(0.36155, -0.12942, 0.913665), + vec3(0.722952, 0.655391, 0.209401), + vec3(0.374059, 0.504317, -0.764699), + vec3(0.466859, 0.811274, -0.270417), + vec3(0.962492, 0.082706, 0.102222), + vec3(0.726909, 0.197392, 0.592712), + vec3(0.726963, -0.519139, -0.26076), + vec3(0.863379, 0.0510047, -0.479442), + vec3(0.39697, -0.392489, -0.778489), + vec3(0.395817, 0.28567, -0.152613), + vec3(0.0115477, 0.0392268, 0.262437), + vec3(-0.124912, 0.314161, 0.906488), + vec3(-0.795609, 0.124298, -0.584104), + vec3(-0.58822, 0.533162, 0.596359), + vec3(-0.465148, 0.867438, 0.068886), + vec3(-0.347131, 0.479682, -0.773511), + vec3(-0.0359631, 0.862508, 0.497219), + vec3(-0.869958, 0.454845, 0.0919322), + vec3(-0.100729, 0.895672, -0.400421), + vec3(-0.312793, 0.316496, -0.184027) +); + +CONST_ARRAY vec3 poisson_3D_64[64] = vec3[]( + vec3(-0.15773, -0.0451896, -0.9623), + vec3(-0.0130272, -0.640955, -0.751804), + vec3(-0.214195, -0.789982, 0.571629), + vec3(-0.22401, -0.127885, -0.479033), + vec3(-0.0381656, -0.400932, 0.389145), + vec3(-0.958604, -0.255706, 0.0608546), + vec3(-0.491959, -0.0240958, 0.867465), + vec3(-0.735088, -0.589627, -0.0952913), + vec3(-0.361071, -0.387626, -0.841852), + vec3(-0.454339, -0.716331, -0.490685), + vec3(-0.464857, -0.00371937, 0.416402), + vec3(-0.252955, -0.952897, -0.0173203), + vec3(-0.310376, -0.450015, 0.834997), + vec3(-0.481379, -0.12181, -0.0713362), + vec3(0.17995, -0.273669, -0.910183), + vec3(0.100674, -0.18972, 0.96892), + vec3(0.229951, -0.770195, -0.427458), + vec3(-0.534464, -0.703867, 0.273916), + vec3(-0.779887, -0.341913, 0.505745), + vec3(-0.793823, -0.290259, -0.406983), + vec3(0.512152, -0.541214, -0.661702), + vec3(0.616316, -0.597375, 0.505634), + vec3(0.798438, -0.464642, -0.225906), + vec3(0.546185, -0.833083, -0.0299397), + vec3(0.38638, -0.311687, 0.154036), + vec3(0.172597, -0.639959, 0.741325), + vec3(0.124675, -0.818478, 0.257105), + vec3(-0.172153, -0.492998, -0.0557574), + vec3(0.318022, -0.24362, -0.38011), + vec3(0.531653, -0.165474, 0.749569), + vec3(0.529882, 0.24116, -0.257057), + vec3(0.466419, 0.215838, 0.25547), + vec3(0.0712114, 0.0329548, 0.548568), + vec3(0.723801, -0.0377743, -0.668303), + vec3(0.814331, 0.205909, 0.504961), + vec3(0.93028, 0.357367, 0.0674278), + vec3(0.921439, -0.213509, 0.314967), + vec3(0.96477, -0.0016533, -0.256952), + vec3(-0.0662509, 0.986109, -0.0656959), + vec3(0.185578, 0.617772, -0.181412), + vec3(0.107275, 0.241256, -0.491317), + vec3(0.164571, 0.247343, 0.917695), + vec3(0.0651426, 0.739647, -0.652712), + vec3(0.456338, 0.504012, 0.706019), + vec3(0.293143, 0.169755, -0.932919), + vec3(0.032654, 0.0818838, 0.00303189), + vec3(0.601786, 0.735747, 0.216412), + vec3(0.151178, 0.940888, 0.300587), + vec3(0.702927, 0.659986, -0.246973), + vec3(0.0395814, 0.691424, 0.686644), + vec3(0.451051, 0.515958, -0.689563), + vec3(-0.891535, 0.111488, 0.301105), + vec3(-0.720135, 0.120472, -0.674127), + vec3(-0.747936, 0.51219, 0.177613), + vec3(-0.16722, 0.372523, -0.887329), + vec3(-0.674427, 0.357484, 0.643218), + vec3(-0.249121, 0.379101, 0.871001), + vec3(-0.929231, 0.219506, -0.255281), + vec3(-0.487606, 0.461665, -0.621111), + vec3(-0.451381, 0.890955, 0.0284355), + vec3(-0.724563, 0.612287, -0.273063), + vec3(-0.228439, 0.555403, 0.34383), + vec3(-0.328195, 0.828738, -0.447974), + vec3(-0.417829, 0.32502, -0.232616) +); diff --git a/rpcore/shader/includes/sampling_sequences.inc.glsl b/rpcore/shader/includes/sampling_sequences.inc.glsl new file mode 100644 index 0000000..39050e4 --- /dev/null +++ b/rpcore/shader/includes/sampling_sequences.inc.glsl @@ -0,0 +1,46 @@ +/** + * + * RenderPipeline + * + * Copyright (c) 2014-2016 tobspr + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + */ + +#pragma once + + +// Poisson disks +#pragma include "includes/poisson_disk.inc.glsl" +#pragma include "includes/halton_sequences.inc.glsl" + + +// Special getter for plugin sequences + +#define GET_SEQUENCE_SIZE(plugin_id, setting_id) (GET_SETTING(plugin_id, setting_id).length()) +#define GET_SEQUENCE_SAMPLE(plugin_id, setting_id, sample_id) (GET_SETTING(plugin_id, setting_id)[sample_id]) + +#define START_ITERATE_SEQUENCE(plugin_id, setting_id, storage) \ + for (uint _seq_count_000 = 0; _seq_count_000 < GET_SEQUENCE_SIZE(plugin_id, setting_id); ++_seq_count_000) {\ + storage = GET_SEQUENCE_SAMPLE(plugin_id, setting_id, _seq_count_000); + +#define END_ITERATE_SEQUENCE() } + +#define NORMALIZE_SEQUENCE(plugin_id, setting_id, var) var /= float(GET_SEQUENCE_SIZE(plugin_id, setting_id)); diff --git a/rpcore/shader/includes/shadows.inc.glsl b/rpcore/shader/includes/shadows.inc.glsl new file mode 100644 index 0000000..f162fa4 --- /dev/null +++ b/rpcore/shader/includes/shadows.inc.glsl @@ -0,0 +1,78 @@ +/** + * + * RenderPipeline + * + * Copyright (c) 2014-2016 tobspr + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + */ + +#pragma once + + +CONST_ARRAY vec2[] shadow_sample_offsets_8 = vec2[8]( + vec2(-0.7071, 0.7071), + vec2(-0.0000, -0.8750), + vec2(0.5303, 0.5303), + vec2(-0.6250, -0.0000), + vec2(0.3536, -0.3536), + vec2(-0.0000, 0.3750), + vec2(-0.1768, -0.1768), + vec2(0.1250, 0.0000) +); + +// Projects a point using the given mvp +vec3 project(mat4 mvp, vec3 p) { + vec4 projected = mvp * vec4(p, 1); + return fma(projected.xyz / projected.w, vec3(0.5), vec3(0.5)); +} + +// Given a shadow mvp matrix and the light vector, finds an appropriate filter size +vec2 find_filter_size(mat4 projection, vec3 light, float sample_radius) { + + // Find an arbitrary tangent and bitangent to the given normal + vec3 tangent = vec3(1, 0, 0); + vec3 binormal = vec3(0, 1, 0); + + // Project everything + // TODO: We could actually only use the 3x3 part of the mat and save the + // origin projection. + vec2 proj_origin = project(projection, vec3(0)).xy; + vec2 proj_tangent = abs(project(projection, tangent + binormal).xy - proj_origin); + + return vec2(max(proj_tangent.x, proj_tangent.y) * sample_radius) * 10.0; +} + +// http://the-witness.net/news/2013/09/shadow-mapping-summary-part-1/ +// Returns the normal and light dependent bias +vec2 get_shadow_bias(vec3 n, vec3 l) { + float cos_alpha = saturate(dot(n, l)); + float offset_scale_n = sqrt(1 - cos_alpha * cos_alpha); // sin(acos(L·N)) + float offset_scale_l = offset_scale_n / cos_alpha; // tan(acos(L·N)) + return vec2(offset_scale_n, min(2, offset_scale_l)); +} + +// Offsets a position based on slope and normal +vec3 get_biased_position(vec3 pos, float slope_bias, float normal_bias, vec3 normal, vec3 light) { + vec2 offsets = get_shadow_bias(normal, light); + pos += normal * offsets.x * normal_bias; + pos += light * offsets.y * slope_bias; + return pos; +} diff --git a/rpcore/shader/includes/skin_shading.inc.glsl b/rpcore/shader/includes/skin_shading.inc.glsl new file mode 100644 index 0000000..c1f18a7 --- /dev/null +++ b/rpcore/shader/includes/skin_shading.inc.glsl @@ -0,0 +1,46 @@ +/** + * + * RenderPipeline + * + * Copyright (c) 2014-2016 tobspr + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + */ + +#pragma once + +/* +From: +http://www.iryoku.com/translucency/ +*/ + +const float skin_travel_weight = 1.0; + +vec3 skin_transmittance(float distance_through_medium) { + float s = distance_through_medium * skin_travel_weight; + float s_sq = -s * s; + vec3 t = vec3(0.233, 0.455, 0.649) * exp(s_sq / 0.0064) + + vec3(0.1, 0.336, 0.344) * exp(s_sq / 0.0484) + + vec3(0.118, 0.198, 0.0) * exp(s_sq / 0.187) + + vec3(0.113, 0.007, 0.007) * exp(s_sq / 0.567) + + vec3(0.358, 0.004, 0.0) * exp(s_sq / 1.99) + + vec3(0.078, 0.0, 0.0) * exp(s_sq / 7.41); + return t; +} diff --git a/rpcore/shader/includes/source_data.struct.glsl b/rpcore/shader/includes/source_data.struct.glsl new file mode 100644 index 0000000..282ae3a --- /dev/null +++ b/rpcore/shader/includes/source_data.struct.glsl @@ -0,0 +1,9 @@ +#pragma once + +struct SourceData { + vec4 Data0; + vec4 Data1; + vec4 Data2; + vec4 Data3; + vec4 Data4; +}; diff --git a/rpcore/shader/includes/temporal_resolve.inc.glsl b/rpcore/shader/includes/temporal_resolve.inc.glsl new file mode 100644 index 0000000..4611489 --- /dev/null +++ b/rpcore/shader/includes/temporal_resolve.inc.glsl @@ -0,0 +1,253 @@ +/** + * + * RenderPipeline + * + * Copyright (c) 2014-2016 tobspr + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + */ + +#pragma once + +#define USE_GBUFFER_EXTENSIONS +#pragma include "includes/color_spaces.inc.glsl" +#pragma include "includes/transforms.inc.glsl" +#pragma include "includes/gbuffer.inc.glsl" + +// Maximum color distance +#ifndef RS_MAX_CLIP_DIST + #define RS_MAX_CLIP_DIST 0.5 +#endif + +// Blending factor +#ifndef RS_DISTANCE_SCALE + #define RS_DISTANCE_SCALE 10.0 +#endif + +// How long to keep good pixels +#ifndef RS_KEEP_GOOD_DURATION + #define RS_KEEP_GOOD_DURATION 10.0 +#endif + +// How long to keep bad pixels +#ifndef RS_KEEP_BAD_DURATION + #define RS_KEEP_BAD_DURATION 3.0 +#endif + +#ifndef RS_AABB_SIZE + #define RS_AABB_SIZE 1.0 +#endif + +#ifndef RS_USE_SMOOTH_TECHNIQUE + #define RS_USE_SMOOTH_TECHNIQUE 0 +#endif + +/* + +Uses the reprojection suggested in: +http://www.crytek.com/download/Sousa_Graphics_Gems_CryENGINE3.pdf + +Also based on: +https://github.com/playdeadgames/temporal + +*/ + +#define USE_OPTIMIZATIONS 0 +#define USE_CLIPPING 1 + +vec4 clip_aabb(vec3 aabb_min, vec3 aabb_max, vec4 p, vec4 q) +{ +#if USE_OPTIMIZATIONS + // note: only clips towards aabb center (but fast!) + vec3 p_clip = 0.5 * (aabb_max + aabb_min); + vec3 e_clip = 0.5 * (aabb_max - aabb_min); + + vec4 v_clip = q - vec4(p_clip, p.w); + vec3 v_unit = v_clip.xyz / e_clip; + vec3 a_unit = abs(v_unit); + float ma_unit = max(a_unit.x, max(a_unit.y, a_unit.z)); + + if (ma_unit > 1.0) + return vec4(p_clip, p.w) + v_clip / ma_unit; + else + return q; // point inside aabb +#else + vec4 r = q - p; + vec3 rmax = aabb_max - p.xyz; + vec3 rmin = aabb_min - p.xyz; + + const float eps = 1e-8; + + if (r.x > rmax.x + eps) + r *= (rmax.x / r.x); + if (r.y > rmax.y + eps) + r *= (rmax.y / r.y); + if (r.z > rmax.z + eps) + r *= (rmax.z / r.z); + + if (r.x < rmin.x - eps) + r *= (rmin.x / r.x); + if (r.y < rmin.y - eps) + r *= (rmin.y / r.y); + if (r.z < rmin.z - eps) + r *= (rmin.z / r.z); + + return p + r; +#endif +} + + +#if RS_USE_POSITION_TECHNIQUE + uniform sampler2D Previous_SceneDepth; +#endif + + +vec4 resolve_temporal(sampler2D current_tex, sampler2D last_tex, vec2 curr_coord, vec2 last_coord) { + vec2 one_pixel = 1.0 / SCREEN_SIZE; + vec4 curr_m = textureLod(current_tex, curr_coord, 0); + + // Out of screen, can early out + if (out_of_screen(last_coord)) { + return max(vec4(0.0), curr_m); + } + + #if !RS_USE_SMOOTH_TECHNIQUE + + #if RS_USE_POSITION_TECHNIQUE + + float curr_z = get_depth_at(curr_coord); + vec3 curr_pos = calculate_surface_pos(curr_z, curr_coord); + + float last_z = textureLod(Previous_SceneDepth, last_coord, 0).x; + vec3 last_pos = calculate_surface_pos( + last_z, last_coord, MainSceneData.last_inv_view_proj_mat_no_jitter); + + // Weight by distance + float max_distance = RS_DISTANCE_SCALE; + max_distance *= distance(curr_pos, MainSceneData.camera_pos) / 10.0; + + float weight = 1.0 - saturate(distance(curr_pos, last_pos) / max_distance); + weight *= 1 - 1.0 / RS_KEEP_GOOD_DURATION; + + vec4 last_m = textureLod(last_tex, last_coord, 0); + return mix(curr_m, last_m, weight); + + #else + + const float subpixel_threshold = 0.5; + const float gather_base = 0.5; + const float gather_subpixel_motion = 0.1666; + + float curr_depth = get_depth_at(curr_coord); + float vs_dist = get_linear_z_from_z(curr_depth); + + vec2 velocity = last_coord - curr_coord; + + float texel_vel_mag = length(velocity) * vs_dist; + float subpixel_motion = saturate(subpixel_threshold / (1e-8 + texel_vel_mag)); + float min_max_support = gather_base + gather_subpixel_motion * subpixel_motion; + + vec2 ss_offset01 = min_max_support * vec2(1, 0) / SCREEN_SIZE; + vec2 ss_offset11 = min_max_support * vec2(0, 1) / SCREEN_SIZE; + + vec4 c00 = textureLod(current_tex, curr_coord - ss_offset11, 0); + vec4 c10 = textureLod(current_tex, curr_coord - ss_offset01, 0); + vec4 c01 = textureLod(current_tex, curr_coord + ss_offset01, 0); + vec4 c11 = textureLod(current_tex, curr_coord + ss_offset11, 0); + + vec4 cmin = min4(c00, c10, c01, c11); + vec4 cmax = max4(c00, c10, c01, c11); + + vec4 cavg = (c00 + c10 + c01 + c11) / 4.0; + + vec4 last_m = textureLod(last_tex, curr_coord + velocity, 0); + + #if USE_CLIPPING + last_m = clip_aabb(cmin.xyz, cmax.xyz, clamp(cavg, cmin, cmax), last_m); + #else + last_m = clamp(last_m, cmin, cmax); + #endif + + float lum0 = get_luminance(curr_m.rgb); + float lum1 = get_luminance(last_m.rgb); + + const float feedback_min = 1 - 1.0 / RS_KEEP_BAD_DURATION; + const float feedback_max = 1 - 1.0 / RS_KEEP_GOOD_DURATION; + + float unbiased_diff = abs(lum0 - lum1) / max(lum0, max(lum1, 0.2)); + float unbiased_weight = 1.0 - unbiased_diff; + float unbiased_weight_sqr = unbiased_weight * unbiased_weight; + float feedback = mix(feedback_min, feedback_max, unbiased_weight_sqr); + + // output + return mix(curr_m, last_m, feedback); + + #endif + + #else + + // Bounding box size + const float bbs = RS_AABB_SIZE; + + // Get current frame neighbor texels + vec4 curr_tl = textureLod(current_tex, curr_coord + vec2(-bbs, -bbs) * one_pixel, 0); + vec4 curr_tr = textureLod(current_tex, curr_coord + vec2(bbs, -bbs) * one_pixel, 0); + vec4 curr_bl = textureLod(current_tex, curr_coord + vec2(-bbs, bbs) * one_pixel, 0); + vec4 curr_br = textureLod(current_tex, curr_coord + vec2(bbs, bbs) * one_pixel, 0); + + // Get current frame neighbor AABB + vec4 curr_min = min5(curr_m, curr_tl, curr_tr, curr_bl, curr_br); + vec4 curr_max = max5(curr_m, curr_tl, curr_tr, curr_bl, curr_br); + + // Get last frame texels + float blend_weight = 1.0; + vec4 last_m = textureLod(last_tex, last_coord, 0); + vec4 last_tl = textureLod(last_tex, last_coord + vec2(-bbs, -bbs) * one_pixel, 0); + vec4 last_tr = textureLod(last_tex, last_coord + vec2(bbs, -bbs) * one_pixel, 0); + vec4 last_bl = textureLod(last_tex, last_coord + vec2(-bbs, bbs) * one_pixel, 0); + vec4 last_br = textureLod(last_tex, last_coord + vec2(bbs, bbs) * one_pixel, 0); + + float neighbor_diff = length(clamp(last_tl.xyz, curr_min.xyz, curr_max.xyz) - last_tl.xyz) + + length(clamp(last_tr.xyz, curr_min.xyz, curr_max.xyz) - last_tr.xyz) + + length(clamp(last_bl.xyz, curr_min.xyz, curr_max.xyz) - last_bl.xyz) + + length(clamp(last_br.xyz, curr_min.xyz, curr_max.xyz) - last_br.xyz); + + const float tolerance = 0.0; + + float max_difference = clamp(max( + get_luminance(last_m.xyz), + get_luminance(curr_m.xyz)), 0.0001, 15.0) * RS_MAX_CLIP_DIST; + + if (neighbor_diff >= max_difference) + blend_weight = 0.0; + + float blend_amount = saturate(distance(last_m.xyz, curr_m.xyz) * + RS_DISTANCE_SCALE); + + // Merge the sample with the current color, in case we can't pick it + last_m = mix(curr_m, last_m, blend_weight); + + float weight = saturate(1.0 / + mix(RS_KEEP_GOOD_DURATION, RS_KEEP_BAD_DURATION, blend_amount)); + + return max(vec4(0.0), mix(last_m, curr_m, weight)); + #endif + +} diff --git a/rpcore/shader/includes/tonemapping.inc.glsl b/rpcore/shader/includes/tonemapping.inc.glsl new file mode 100644 index 0000000..37b1d06 --- /dev/null +++ b/rpcore/shader/includes/tonemapping.inc.glsl @@ -0,0 +1,200 @@ +/** + * + * RenderPipeline + * + * Copyright (c) 2014-2016 tobspr + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + */ + +#pragma once + +#pragma include "includes/color_spaces.inc.glsl" + +/* + +Tonemapping Operators, some are from: +http://filmicgames.com/archives/75 + +A good sample using them can be found here: +https://www.shadertoy.com/view/lslGzl + +*/ + + +const float exposure_adjustment = 2.0; + + +// No tonemapping +vec3 tonemap_none(vec3 color) { + color *= exposure_adjustment; + return color; +} + +// Different versions of the reinhard tonemap operators +vec3 tonemap_reinhard(vec3 color) +{ + color *= exposure_adjustment; + + #if ENUM_V_ACTIVE(color_correction, reinhard_version, rgb) + + // Simple reinhard operator in rgb space + vec3 rgb = color / (1.0 + color); + + #elif ENUM_V_ACTIVE(color_correction, reinhard_version, luminance) + + // Simple reinhard operator based on luminance + float luminance = get_luminance(color); + vec3 rgb = color / (1.0 + luminance); + + #elif ENUM_V_ACTIVE(color_correction, reinhard_version, white_preserve) + + // Reinhard operator based on luminance, but white preserving + float white = 5.0; + float luminance = get_luminance(color); + vec3 rgb = color * (1.0 + luminance / (white * white)) / (1.0 + luminance); + + #elif ENUM_V_ACTIVE(color_correction, reinhard_version, luminosity) + + // Reinhard operator in the CIE-Yxy color space + vec3 xyY = rgb_to_xyY(color); + + // This saturates too much? + xyY.z = xyY.z / (1.0 + xyY.z); + + // White preserving approach, doesn't work out well, too + // xyY.z = xyY.z * (1.0 + xyY.z * (white*white)) / (1.0 + xyY.z); + vec3 rgb = xyY_to_rgb(xyY); + + #else + #error Unkown reinhard operator version! + #endif + + return rgb; +} + + +// Optimized version of the Haarm-Peter Duiker’s curve +vec3 tonemap_optimized(vec3 color) +{ + color *= exposure_adjustment; + vec3 x = max(vec3(0.0), color - 0.004); + return (x * (6.2 * x + 0.5)) / (x * (6.2 * x + 1.7) + 0.06); +} + +// Exponential tonemapping +vec3 tonemap_exponential(vec3 color) { + color *= exposure_adjustment; + color = 1.0 - exp(-GET_SETTING(color_correction, exponential_factor) * color); + return color; +} + +// Alternative exponential tonemapping +vec3 tonemap_exponential_2(vec3 color) { + color *= exposure_adjustment; + color = exp(-1.0 / (2.72 * color + 0.15)); + return color; +} + + +// Uncharted 2 tonemapping formula +// See: http://de.slideshare.net/ozlael/hable-john-uncharted2-hdr-lighting +vec3 uncharted_2_tonemap_formula(vec3 x) +{ + const float A = GET_SETTING(color_correction, uc2t_shoulder_strength); + const float B = GET_SETTING(color_correction, uc2t_linear_strength); + const float C = GET_SETTING(color_correction, uc2t_linear_angle); + const float D = GET_SETTING(color_correction, uc2t_toe_strength); + const float E = GET_SETTING(color_correction, uc2t_toe_numerator); + const float F = GET_SETTING(color_correction, uc2t_toe_denumerator); + return ((x * (A * x + C * B) + D * E) / (x * (A * x + B) + D * F)) - E / F; +} + +// Uncharted 2 tonemap operator +vec3 tonemap_uncharted2(vec3 color) +{ + const float white_base = GET_SETTING(color_correction, uc2t_reference_white); + color *= exposure_adjustment; + const float exposure_bias = 2.0; + vec3 curr = uncharted_2_tonemap_formula(exposure_bias * color); + vec3 white = uncharted_2_tonemap_formula(vec3(white_base)); + return curr / white; +} + +// Tonemapping selector +vec3 do_tonemapping(vec3 color) { + + // Clamp extreme values of the color + color = clamp(color, 1e-5, 1000.0); + + // Select tonemapping operator + #if ENUM_V_ACTIVE(color_correction, tonemap_operator, none) + color = tonemap_none(color); + #elif ENUM_V_ACTIVE(color_correction, tonemap_operator, optimized) + color = tonemap_optimized(color); + return color; + #elif ENUM_V_ACTIVE(color_correction, tonemap_operator, reinhard) + color = tonemap_reinhard(color); + #elif ENUM_V_ACTIVE(color_correction, tonemap_operator, uncharted2) + color = tonemap_uncharted2(color); + #elif ENUM_V_ACTIVE(color_correction, tonemap_operator, exponential) + color = tonemap_exponential(color); + #elif ENUM_V_ACTIVE(color_correction, tonemap_operator, exponential2) + color = tonemap_exponential_2(color); + #else + #error Unkown tonemapping operator! + #endif + + return rgb_to_srgb(color); +} + + +// From: +// http://www.frostbite.com/wp-content/uploads/2014/11/course_notes_moving_frostbite_to_pbr.pdf + +float computeEV100(float aperture, float shutter_time, float ISO) { + // EV number is defined as: + // 2^ EV_s = N^2 / t and EV_s = EV_100 + log2 (S /100) + // This gives + // EV_s = log2 (N^2 / t) + // EV_100 + log2 (S /100) = log2 (N^2 / t) + // EV_100 = log2 (N^2 / t) - log2 (S /100) + // EV_100 = log2 (N^2 / t . 100 / S) + return log2((aperture * aperture) / shutter_time * 100 / ISO); +} + +float computeEV100FromAvgLuminance(float avg_luminance) { + // We later use the middle gray at 12.7% in order to have + // a middle gray at 18% with a sqrt (2) room for specular highlights + // But here we deal with the spot meter measuring the middle gray + // which is fixed at 12.5 for matching standard camera + // constructor settings (i.e. calibration constant K = 12.5) + return log2(avg_luminance * 100.0 / 12.5); +} + +float convertEV100ToExposure(float EV100) { + // Compute the maximum luminance possible with H_sbs sensitivity + // maxLum = 78 / ( S * q ) * N^2 / t + // = 78 / ( S * q ) * 2^ EV_100 + // = 78 / (100 * 0.65) * 2^ EV_100 + // = 1.2 * 2^ EV + float max_luminance = 1.2 * pow(2.0, EV100); + return 1.0 / max_luminance; +} diff --git a/rpcore/shader/includes/transforms.inc.glsl b/rpcore/shader/includes/transforms.inc.glsl new file mode 100644 index 0000000..ab0b24e --- /dev/null +++ b/rpcore/shader/includes/transforms.inc.glsl @@ -0,0 +1,123 @@ +/** + * + * RenderPipeline + * + * Copyright (c) 2014-2016 tobspr + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + */ + +#pragma once + +uniform mat4 trans_clip_of_mainCam_to_mainRender; +uniform mat4 trans_mainRender_to_view_of_mainCam; +uniform mat4 trans_mainRender_to_clip_of_mainCam; + +// Computes linear Z from a given Z value, and near and far plane +float get_linear_z_from_z(float z, float near, float far) { + return 2.0 * near * far / (far + near - (z * 2.0 - 1) * (far - near)); +} + +// Computes linear Z from a given Z value +float get_linear_z_from_z(float z) { + return get_linear_z_from_z(z, CAMERA_NEAR, CAMERA_FAR); +} + +// Computes the Z component from a position in NDC space +float get_z_from_ndc(vec3 ndc_pos) { + return get_linear_z_from_z(ndc_pos.z); +} + +// Computes linear Z from a given Z value, and near and far plane, for orthographic projections +float get_linear_z_from_z_ortographic(float z, float near, float far) { + return 2.0 / (far + near - fma(z, 2.0, -1.0) * (far - near)); +} + +// Computes the surface position based on a given Z, a texcoord, and the Inverse MVP matrix +vec3 calculate_surface_pos(float z, vec2 tcoord, mat4 inverse_mvp) { + vec3 ndc_pos = fma(vec3(tcoord.xy, z), vec3(2.0), vec3(-1.0)); + float clip_w = get_z_from_ndc(ndc_pos); + + vec4 proj = inverse_mvp * vec4(ndc_pos * clip_w, clip_w); + return proj.xyz / proj.w; +} + +// Computes the surface position based on a given Z and a texcoord +vec3 calculate_surface_pos(float z, vec2 tcoord) { + #if 0 + return calculate_surface_pos(z, tcoord, trans_clip_of_mainCam_to_mainRender); + #else + float linz = get_linear_z_from_z(z); + return mix( + mix(MainSceneData.ws_frustum_directions[0], + MainSceneData.ws_frustum_directions[1], tcoord.x), + mix(MainSceneData.ws_frustum_directions[2], + MainSceneData.ws_frustum_directions[3], tcoord.x), + tcoord.y + ).xyz * linz + MainSceneData.camera_pos; + #endif +} + +// Computes the surface position based on a given Z and a texcoord, aswell as a +// custom near and far plane, and the inverse MVP. This is for orthographic projections +vec3 calculate_surface_pos_ortho(float z, vec2 tcoord, float near, float far, mat4 inverse_mvp) { + vec3 ndc_pos = fma(vec3(tcoord.xy, z), vec3(2.0), vec3(-1.0)); + float clip_w = get_linear_z_from_z_ortographic(z, near, far); + vec4 result = inverse_mvp * vec4(ndc_pos * clip_w, clip_w); + return result.xyz / result.w; +} + +// Computes the view position from a given Z value and texcoord +vec3 calculate_view_pos(float z, vec2 tcoord) { + vec4 view_pos = MainSceneData.inv_proj_mat * + vec4(fma(tcoord.xy, vec2(2.0), vec2(-1.0)), z, 1.0); + return view_pos.xyz / view_pos.w; +} + +// Computes the NDC position from a given view position +vec3 view_to_screen(vec3 view_pos) { + vec4 projected = MainSceneData.proj_mat * vec4(view_pos, 1); + projected.xyz /= projected.w; + projected.xy = fma(projected.xy, vec2(0.5), vec2(0.5)); + return projected.xyz; +} + +// Converts a view space normal to world space +vec3 view_normal_to_world(vec3 view_normal) { + // We need to transform the coordinate system, should not be required, + // seems to be some panda bug? + view_normal = view_normal.xzy * vec3(1, -1, 1); + return normalize((vec4(view_normal, 0) * trans_mainRender_to_view_of_mainCam).xyz); +} + +// Converts a world space position to screen space position (NDC) +vec3 world_to_screen(vec3 world_pos) { + vec4 proj = trans_mainRender_to_clip_of_mainCam * vec4(world_pos, 1); + proj.xyz /= proj.w; + proj.xyz = fma(proj.xyz, vec3(0.5), vec3(0.5)); + return proj.xyz; +} + +// Converts a world space normal to view space +vec3 world_normal_to_view(vec3 world_normal) { + vec4 proj = trans_mainRender_to_view_of_mainCam * vec4(world_normal, 0); + proj.xyz *= vec3(1, -1, 1); + return normalize(proj.xzy); +} diff --git a/rpcore/shader/includes/upsampling.inc.glsl b/rpcore/shader/includes/upsampling.inc.glsl new file mode 100644 index 0000000..bc5c77a --- /dev/null +++ b/rpcore/shader/includes/upsampling.inc.glsl @@ -0,0 +1,142 @@ +/** + * + * RenderPipeline + * + * Copyright (c) 2014-2016 tobspr + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + */ + +#pragma once + +#pragma include "includes/color_spaces.inc.glsl" + +float mitchell_netravali_weights(float x) +{ + // Mitchell Netravali Reconstruction Filter + + // cubic B-spline + // const float b = 1.0, c = 0.0; + + // recommended + // const float b = 1.0 / 3.0, c = 1.0 / 3.0; + + // Catmull-Rom spline + const float b = 0.0, c = 1.0 / 2.0; + + float ax = abs(x); + return (ax < 1.0) ? + ((12.0 - 9.0 * b - 6.0 * c) * ax * ax * ax + + (-18.0 + 12.0 * b + 6.0 * c) * ax * ax + (6.0 - 2.0 * b)) / 6.0 + : ((ax >= 1.0) && (ax < 2.0)) ? + ((-b - 6.0 * c) * ax * ax * ax + (6.0 * b + 30.0 * c) * ax * ax + + (-12.0 * b - 48.0 * c) * ax + (8.0 * b + 24.0 * c)) / 6.0 + : 0.0; +} + +vec4 sample_color(sampler2D tex, vec2 uv) { + return saturate(textureLod(tex, uv, 0)); +} + +// Based on: +// http://glslsandbox.com/e#14615.1 +vec4 bicubic_filter(sampler2D tex, vec2 uv) +{ + + vec2 px = 1.0 / textureSize(tex, 0).xy; + vec2 f = fract(uv / px); + vec2 texel = (uv / px - f + 0.5) * px; + vec4 weights = vec4(mitchell_netravali_weights(1.0 + f.x), + mitchell_netravali_weights(f.x), + mitchell_netravali_weights(1.0 - f.x), + mitchell_netravali_weights(2.0 - f.x)); + vec4 t1 = + sample_color(tex, texel + vec2(-px.x, -px.y)) * weights.x + + sample_color(tex, texel + vec2(0.0, -px.y)) * weights.y + + sample_color(tex, texel + vec2(px.x, -px.y)) * weights.z + + sample_color(tex, texel + vec2(2.0 * px.x, -px.y)) * weights.w; + vec4 t2 = + sample_color(tex, texel + vec2(-px.x, 0.0)) * weights.x + + sample_color(tex, texel + vec2(0.0)) * weights.y + + sample_color(tex, texel + vec2(px.x, 0.0)) * weights.z + + sample_color(tex, texel + vec2(2.0 * px.x, 0.0)) * weights.w; + vec4 t3 = + sample_color(tex, texel + vec2(-px.x, px.y)) * weights.x + + sample_color(tex, texel + vec2(0.0, px.y)) * weights.y + + sample_color(tex, texel + vec2(px.x, px.y)) * weights.z + + sample_color(tex, texel + vec2(2.0 * px.x, px.y)) * weights.w; + vec4 t4 = + sample_color(tex, texel + vec2(-px.x, 2.0 * px.y)) * weights.x + + sample_color(tex, texel + vec2(0.0, 2.0 * px.y)) * weights.y + + sample_color(tex, texel + vec2(px.x, 2.0 * px.y)) * weights.z + + sample_color(tex, texel + vec2(2.0 * px.x, 2.0 * px.y)) * weights.w; + + return mitchell_netravali_weights(1.0 + f.y) * t1 + + mitchell_netravali_weights(f.y) * t2 + + mitchell_netravali_weights(1.0 - f.y) * t3 + + mitchell_netravali_weights(2.0 - f.y) * t4; +} + +// Simple bilinear filter +vec4 bilinear_filter(sampler2D tex, vec2 uv) { + vec2 pixel_size = 1.0 / textureSize(tex, 0).xy; + vec4 color = vec4(0); + float radius = 0.5; + color += sample_color(tex, uv + vec2(-radius, radius) * pixel_size); + color += sample_color(tex, uv + vec2(radius, radius) * pixel_size); + color += sample_color(tex, uv + vec2(-radius, -radius) * pixel_size); + color += sample_color(tex, uv + vec2(radius, -radius) * pixel_size); + return color * 0.25; +} + +// Directional filter with a small sharpen kernel +vec4 directional_filter(sampler2D tex, vec2 uv) { + vec2 pixel_size = 1.0 / textureSize(tex, 0).xy; + float radius = 1.0; + + vec4 color_nw = sample_color(tex, uv + vec2(-radius, -radius) * pixel_size); + vec4 color_ne = sample_color(tex, uv + vec2(radius, -radius) * pixel_size); + vec4 color_sw = sample_color(tex, uv + vec2(-radius, radius) * pixel_size); + vec4 color_se = sample_color(tex, uv + vec2(radius, radius) * pixel_size); + + vec4 color = (color_nw + color_ne + color_sw + color_se) * 0.25; + + float luma_nw = get_luminance(color_nw.xyz); + float luma_ne = get_luminance(color_ne.xyz) + 1e-5; + float luma_sw = get_luminance(color_sw.xyz); + float luma_se = get_luminance(color_se.xyz); + + float center_luminance = get_luminance(color.xyz); + float uv_offs = saturate(center_luminance) * 2 - 1; + + float diag_bl_tr = luma_sw - luma_ne; + float diag_br_tl = luma_se - luma_nw; + + vec2 direction = normalize(vec2(diag_bl_tr + diag_br_tl, diag_bl_tr - diag_br_tl) + 1e-7); + vec2 direction_inv = vec2(-direction.y, direction.x); + uv_offs = 1 - ((1 - uv_offs) * (1 - uv_offs)); + + vec2 uv_offset = uv + direction_inv * pixel_size * abs(uv_offs) * -0.125; + vec4 color_n = sample_color(tex, uv_offset - direction * 0.125 * pixel_size); + vec4 color_p = sample_color(tex, uv_offset + direction * 0.125 * pixel_size); + + const float sharpness = 0.9; + return (color_n + color_p) * ((sharpness + 1.0) * 0.5) - color * sharpness; +} diff --git a/rpcore/shader/includes/vertex_output.struct.glsl b/rpcore/shader/includes/vertex_output.struct.glsl new file mode 100644 index 0000000..b055548 --- /dev/null +++ b/rpcore/shader/includes/vertex_output.struct.glsl @@ -0,0 +1,36 @@ +/** + * + * RenderPipeline + * + * Copyright (c) 2014-2016 tobspr + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + */ + +#pragma once + +struct VertexOutput { + #if IN_GBUFFER_SHADER + vec4 last_proj_position; + #endif + vec3 normal; + vec2 texcoord; + vec3 position; +}; diff --git a/rpcore/shader/pixel_inspector.frag.glsl b/rpcore/shader/pixel_inspector.frag.glsl new file mode 100644 index 0000000..83c9e76 --- /dev/null +++ b/rpcore/shader/pixel_inspector.frag.glsl @@ -0,0 +1,48 @@ +/** + * + * RenderPipeline + * + * Copyright (c) 2014-2016 tobspr + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + */ + +#version 430 + +in vec2 texcoord; +out vec4 color; +uniform sampler2D SceneTex; +uniform vec2 mousePos; + +void main() { + int border = 3; + int zoom = 5; + + ivec2 int_coord = ivec2(texcoord * vec2(400, 300)); + if (int_coord.x < border || int_coord.y < border || + int_coord.x >= 400 - border || int_coord.y >= 300 - border) { + color = vec4(0.05, 0.05, 0.05, 1); + return; + } + + int_coord = (int_coord) / zoom - (ivec2(200, 150)) / zoom + ivec2(mousePos); + color = texelFetch(SceneTex, int_coord, 0); + color.w = 1.0; +} diff --git a/rpcore/shader/process_command_queue.frag.glsl b/rpcore/shader/process_command_queue.frag.glsl new file mode 100644 index 0000000..775ad00 --- /dev/null +++ b/rpcore/shader/process_command_queue.frag.glsl @@ -0,0 +1,140 @@ +/** + * + * RenderPipeline + * + * Copyright (c) 2014-2016 tobspr + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + */ + +#version 430 + +#pragma include "render_pipeline_base.inc.glsl" + +uniform samplerBuffer CommandQueue; +uniform writeonly imageBuffer RESTRICT LightData; +uniform writeonly imageBuffer RESTRICT SourceData; +uniform int commandCount; + +// Reads a single float from the data stack +float read_float(inout int stack_ptr) { + return texelFetch(CommandQueue, stack_ptr++).x; +} + +// Reads a single int from the data stack +int read_int(inout int stack_ptr) { + return gpu_cq_unpack_int_from_float(read_float(stack_ptr)); +} + +// Reads a 4-component vector from the data stack +vec4 read_vec4(inout int stack_ptr) { + stack_ptr += 4; + return vec4( + texelFetch(CommandQueue, stack_ptr - 4).x, + texelFetch(CommandQueue, stack_ptr - 3).x, + texelFetch(CommandQueue, stack_ptr - 2).x, + texelFetch(CommandQueue, stack_ptr - 1).x + ); +} + +void main() { + + // Store a pointer to the current stack index, its passed as a handle to all + // read functions + int stack_ptr = 0; + + // Process each command + for (int command_index = 0; command_index < commandCount; ++command_index) { + stack_ptr = command_index * 32; + int command_type = read_int(stack_ptr); + + switch(command_type) { + + // Invalid Command Code + case CMD_invalid: break; + + + // Store Light + case CMD_store_light: { + + // Read the destination slot of the light + int slot = read_int(stack_ptr); + int offs = slot * 4; + + // Copy the data over + for (int i = 0; i < 4; ++i) { + imageStore(LightData, offs + i, read_vec4(stack_ptr)); + } + break; + } + + // Remove Light + case CMD_remove_light: { + + // Read the lights slot position + int slot = read_int(stack_ptr); + int offs = slot * 4; + + // Set the data to all zeroes, this indicates a null light + for (int i = 0; i < 4; ++i) { + imageStore(LightData, offs + i, vec4(0)); + } + break; + } + + // Store Source + case CMD_store_source: { + + int slot = read_int(stack_ptr); + int offs = slot * 5; + + // Copy the data over + for (int i = 0; i < 5; ++i) { + imageStore(SourceData, offs + i, read_vec4(stack_ptr)); + } + + break; + } + + // Remove consecutive sources + case CMD_remove_sources: { + int base_slot = read_int(stack_ptr); + int num_slots = read_int(stack_ptr); + + for (int slot = base_slot; slot < base_slot + num_slots; ++slot) { + int offs = slot * 5; + + // Set the data to all zeroes, this indicates an unused source + for (int i = 0; i < 5; ++i) { + imageStore(SourceData, offs + i, vec4(0)); + } + } + break; + } + + + + // .. further commands will follow here + + } + + + } +} diff --git a/rpcore/shader/render_pipeline_base.inc.glsl b/rpcore/shader/render_pipeline_base.inc.glsl new file mode 100644 index 0000000..85b9050 --- /dev/null +++ b/rpcore/shader/render_pipeline_base.inc.glsl @@ -0,0 +1,134 @@ +/** + * + * RenderPipeline + * + * Copyright (c) 2014-2016 tobspr + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + */ + +#pragma once + +// Main configuration file, included by all shaders, provides generic defines +// and functions. + +#pragma include "/$$rptemp/$$pipeline_shader_config.inc.glsl" + +// Optionally unroll *all* loops, this might be faster, but might also be +// slower. Right now, every shader specifies on his own if he wants to unroll +// his loops or not. +// #pragma optionNV (unroll all) + +// Nvidia specific optimizations +#ifdef IS_NVIDIA +#pragma optionNV (fastmath on) +#pragma optionNV (ifcvt none) +#pragma optionNV (inline all) +#pragma optionNV (strict on) +#endif + +#pragma include "/$$rptemp/$$main_scene_data.inc.glsl" + +#ifdef USE_TIME_OF_DAY +#pragma include "/$$rptemp/$$daytime_config.inc.glsl" +#endif + +// Screen size macro +#define WINDOW_WIDTH MainSceneData.screen_size.x +#define WINDOW_HEIGHT MainSceneData.screen_size.y +#define NATIVE_WINDOW_WIDTH MainSceneData.native_screen_size.x +#define NATIVE_WINDOW_HEIGHT MainSceneData.native_screen_size.y +#define SCREEN_SIZE vec2(WINDOW_WIDTH, WINDOW_HEIGHT) +#define SCREEN_SIZE_INT ivec2(WINDOW_WIDTH, WINDOW_HEIGHT) +#define ASPECT_RATIO float(float(WINDOW_HEIGHT) / float(WINDOW_WIDTH)) +#define NATIVE_SCREEN_SIZE vec2(NATIVE_WINDOW_WIDTH, NATIVE_WINDOW_HEIGHT) + +// Plugin functions +#define HAVE_PLUGIN(PLUGIN_NAME) (HAVE_PLUGIN_ ## PLUGIN_NAME) +#define GET_SETTING(PLUGIN_NAME, SETTING_NAME) (PLUGIN_NAME ## _ ## SETTING_NAME) +#define GET_ENUM_VALUE(PLUGIN_NAME, SETTING_NAME, ENUM_KEY) (enum_ ##PLUGIN_NAME ## _ ## SETTING_NAME ## _ ## ENUM_KEY) +#define ENUM_V_ACTIVE(PLUGIN_NAME, SETTING_NAME, ENUM_KEY) (HAVE_PLUGIN(PLUGIN_NAME) && GET_SETTING(PLUGIN_NAME, SETTING_NAME) && GET_SETTING(PLUGIN_NAME, SETTING_NAME) == GET_ENUM_VALUE(PLUGIN_NAME, SETTING_NAME, ENUM_KEY)) + +// Render mode functions +#define DEBUG_MODE ANY_DEBUG_MODE +#define MODE_ACTIVE(MODE_ID) (DEBUG_MODE && (_RM_ ## MODE_ID)) +#define SPECIAL_MODE_ACTIVE(MODE_ID) (_RM_ ## MODE_ID) + +// Branch modes for translucency. +// This serves for the purpose to be enabled or disabled easily. +// Right now, it seems its faster not to branch. It heavily depends on +// the amount of translucent materials on the screen. +#if 0 +#define BRANCH_TRANSLUCENCY(m) if (m.translucency > 0.01) { +#define END_BRANCH_TRANSLUCENCY() } +#else +#define BRANCH_TRANSLUCENCY(m) +#define END_BRANCH_TRANSLUCENCY() +#endif + +// Disable translucency? +#if 1 +#undef BRANCH_TRANSLUCENCY +#undef END_BRANCH_TRANSLUCENCY +#define BRANCH_TRANSLUCENCY(m) if (false) { +#define END_BRANCH_TRANSLUCENCY() } +#endif + +// Restrict qualifier, only on AMD cards, Nvidia can't handle it. See: +// https://devtalk.nvidia.com/default/topic/546817/restrict-keyword-crashes-glsl-compiler/ +// Also, intel seems to expect the keyword (correctly) *before* the image specifier, +// in contrast to AMD, so we disable it on intel gpus, too. +#if IS_AMD + #define RESTRICT restrict +#else + #define RESTRICT +#endif + +// TODO: +#define SUPPORT_PCF 1 + +// Controls the roughness of the clearcoat layer +#define CLEARCOAT_ROUGHNESS 0.001 +#define CLEARCOAT_SPECULAR 0.16 +#define CLEARCOAT_IOR 1.51 + +// Controls the brightness of the fallback cubemap +#if REFERENCE_MODE + #define DEFAULT_ENVMAP_BRIGHTNESS 1.0 +#else + #if HAVE_PLUGIN(color_correction) + #define DEFAULT_ENVMAP_BRIGHTNESS 1.0 + #else + #define DEFAULT_ENVMAP_BRIGHTNESS 1.0 + #endif +#endif + +// Minimum roughness, avoids infinitely bright highlights +#define MINIMUM_ROUGHNESS 0.01 + +// Controls at which point the sun is below the horizon and does not have any +// influence anymore +#define SUN_VECTOR_HORIZON 0.0 + +// Whether to use a completely white environment, only used in reference mode +#define USE_WHITE_ENVIRONMENT 0 + + +#pragma include "includes/common_functions.inc.glsl" diff --git a/rpcore/shader/templates/envmap.frag.glsl b/rpcore/shader/templates/envmap.frag.glsl new file mode 100644 index 0000000..ea2f614 --- /dev/null +++ b/rpcore/shader/templates/envmap.frag.glsl @@ -0,0 +1,62 @@ +/** + * + * RenderPipeline + * + * Copyright (c) 2014-2016 tobspr + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + */ + +#version 430 + +// Shader used for the environment map + +%defines% + +#define USE_TIME_OF_DAY 1 +#pragma include "render_pipeline_base.inc.glsl" + +%includes% +%inout% + +#pragma include "includes/nonviewspace_shading_pipeline.inc.glsl" + +layout(location = 0) out vec4 result; + +void main() { + vec2 texcoord = vOutput.texcoord; + MaterialBaseInput mInput = get_input_from_p3d(p3d_Material); + + %texcoord% + + MaterialShaderOutput m = prepare_material(mInput, texcoord); + + %material% + + // Actual lighting pass + Material m_out = emulate_gbuffer_pass(m, vOutput.position); + + vec3 ambient = get_forward_ambient(m_out); + vec3 sun_lighting = get_sun_shading(m_out); + vec3 lights = get_forward_light_shading(m_out); + + vec3 combined_lighting = ambient + lights + sun_lighting; + result = vec4(combined_lighting, 1); +} diff --git a/rpcore/shader/templates/forward.frag.glsl b/rpcore/shader/templates/forward.frag.glsl new file mode 100644 index 0000000..68937bb --- /dev/null +++ b/rpcore/shader/templates/forward.frag.glsl @@ -0,0 +1,189 @@ +/** + * + * RenderPipeline + * + * Copyright (c) 2014-2016 tobspr + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + */ + +#version 430 + +// Forward shading shader + +// Set DONT_FETCH_DEFAULT_TEXTURES to prevent any material textures to get sampled +// Set DONT_SET_MATERIAL_PROPERTIES to prevent any material properties to be set. + +%defines% + +#define VIEWSPACE_SHADING 1 +#define USE_TIME_OF_DAY 1 +#pragma include "render_pipeline_base.inc.glsl" +#pragma include "includes/transforms.inc.glsl" +#pragma include "includes/vertex_output.struct.glsl" +#pragma include "includes/material.inc.glsl" + +%includes% + +layout(location = 0) in VertexOutput vOutput; + +uniform Panda3DMaterial p3d_Material; + +#pragma include "includes/normal_mapping.inc.glsl" +#pragma include "includes/forward_shading.inc.glsl" + +#if DONT_FETCH_DEFAULT_TEXTURES + // Don't bind any samplers in this case, so the user can do it on his own +#else + uniform sampler2D p3d_Texture0; + uniform sampler2D p3d_Texture1; + uniform sampler2D p3d_Texture2; + uniform sampler2D p3d_Texture3; + + // Only use the displacement texture if we actually need it. + #if OPT_PARALLAX_MAPPING + uniform sampler2D p3d_Texture4; + #endif + +#endif + +uniform sampler2D ShadedScene; + +%inout% + +layout(location = 0) out vec4 color_result; + +void main() { + + MaterialBaseInput mInput = get_input_from_p3d(p3d_Material); + + vec2 texcoord = vOutput.texcoord; + + // Get texture coordinate + #if OPT_PARALLAX_MAPPING + texcoord = get_parallax_texcoord(p3d_Texture4, mInput.normalfactor); + #endif + + %texcoord% + + // Fetch texture data + #if DONT_FETCH_DEFAULT_TEXTURES + float sampled_ior = 0.0; + float sampled_roughness = 0.0; + #else + float sampled_ior = texture(p3d_Texture2, texcoord).x; + float sampled_roughness = texture(p3d_Texture3, texcoord).x; + #endif + + #if OPT_ALPHA_TESTING + #if DONT_FETCH_DEFAULT_TEXTURES + // No alpha testing when not using default textures + #else + // Do binary alpha testing, but weight it based on the distance to the + // camera. This prevents alpha tested objects getting too thin when + // viewed from a high distance. + // TODO: Might want to make the alpha testing distance configurable + vec4 sampled_diffuse = texture(p3d_Texture0, texcoord); + float dist_to_camera = distance(MainSceneData.camera_pos, vOutput.position); + float alpha_factor = mix(0.99, 0.1, saturate(dist_to_camera / 15.0)); + if (sampled_diffuse.w < alpha_factor) discard; + #endif + #else + // In case we don't do alpha testing, we don't need the w-component, so + // don't fetch it. In practice, most GPU's will still load the w component + // and discard it, but it surely can't hurt. + #if DONT_FETCH_DEFAULT_TEXTURES + vec3 sampled_diffuse = vec3(0); + #else + vec3 sampled_diffuse = texture(p3d_Texture0, texcoord).xyz; + #endif + #endif + + vec3 material_nrm = vOutput.normal; + + #if OPT_NORMAL_MAPPING + #if DONT_FETCH_DEFAULT_TEXTURES + // No normal mapping when not using default textures + #else + { + // Perform normal mapping if enabled + vec3 sampled_normal = texture(p3d_Texture1, texcoord).xyz; + vec3 detail_normal = unpack_texture_normal(sampled_normal); + material_nrm = apply_normal_map(vOutput.normal, detail_normal, mInput.normalfactor); + } + #endif + #endif + + // Generate the material output + MaterialShaderOutput m; + + #if DONT_SET_MATERIAL_PROPERTIES + // Leave material properties unitialized, and hope the user knows + // what he's doing. + #else + m.shading_model = mInput.shading_model; + + #if DONT_FETCH_DEFAULT_TEXTURES + m.basecolor = mInput.color; + #else + m.basecolor = mInput.color * sampled_diffuse.xyz; + #endif + m.normal = material_nrm; + m.metallic = mInput.metallic; + m.specular_ior = blend_ior(mInput.specular_ior, sampled_ior); + m.roughness = mInput.roughness * sampled_roughness; + m.shading_model_param0 = mInput.arbitrary0; + #endif + + %material% + + // Emulate gbuffer pass + Material m_out = emulate_gbuffer_pass(m, vOutput.position); + + vec3 view_dir = normalize(m_out.position - MainSceneData.camera_pos); + vec3 color = vec3(0); + + float alpha = m_out.shading_model_param0; + AmbientResult ambient = get_full_forward_ambient(m_out, view_dir); + + color += ambient.diffuse; + color += ambient.specular; + color += get_sun_shading(m_out, view_dir); + + // XXX: Apply shading from lights too + + alpha = mix(alpha, 1.0, ambient.fresnel); + + // Refraction (experimental) + #if 0 + vec3 refracted_vector_view = refract(view_dir, m_out.normal, 1.04); + float refraction_dist = 0.5; + vec3 refraction_dest = m_out.position + refracted_vector_view * refraction_dist; + vec2 refraction_screen = saturate(world_to_screen(refraction_dest).xy); + + vec2 scene_coord = get_texcoord(); + vec3 back_color = textureLod(ShadedScene, refraction_screen, 0).xyz; + + color_result.xyz = back_color * (1 - alpha) + color * alpha; + color_result.w = 1.0; + #else + color_result = vec4(color, alpha); + #endif +} diff --git a/rpcore/shader/templates/gbuffer.frag.glsl b/rpcore/shader/templates/gbuffer.frag.glsl new file mode 100644 index 0000000..8b8c66c --- /dev/null +++ b/rpcore/shader/templates/gbuffer.frag.glsl @@ -0,0 +1,155 @@ +/** + * + * RenderPipeline + * + * Copyright (c) 2014-2016 tobspr + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + */ + +#version 430 + +// Default GBuffer fragment shader. Supports normal mapping, parallax mapping, +// and sampling default textures. + +// Set DONT_FETCH_DEFAULT_TEXTURES to prevent any material textures to get sampled +// Set DONT_SET_MATERIAL_PROPERTIES to prevent any material properties to be set. + +%defines% + +#pragma include "render_pipeline_base.inc.glsl" +#pragma include "includes/vertex_output.struct.glsl" +#pragma include "includes/material.inc.glsl" + +%includes% + +layout(location = 0) in VertexOutput vOutput; + +uniform Panda3DMaterial p3d_Material; + +// Late include of the gbuffer packing since it needs the vOutput +#pragma include "includes/normal_mapping.inc.glsl" +#pragma include "includes/gbuffer.inc.glsl" + + +#if DONT_FETCH_DEFAULT_TEXTURES + // Don't bind any samplers in this case, so the user can do it on his own +#else + uniform sampler2D p3d_Texture0; + uniform sampler2D p3d_Texture1; + uniform sampler2D p3d_Texture2; + uniform sampler2D p3d_Texture3; + + // Only use the displacement texture if we actually need it. + #if OPT_PARALLAX_MAPPING + uniform sampler2D p3d_Texture4; + #endif + +#endif + +%inout% + +void main() { + + MaterialBaseInput mInput = get_input_from_p3d(p3d_Material); + + vec2 texcoord = vOutput.texcoord; + + // Get texture coordinate + #if OPT_PARALLAX_MAPPING + texcoord = get_parallax_texcoord(p3d_Texture4, mInput.normalfactor); + #endif + + %texcoord% + + // Fetch texture data + #if DONT_FETCH_DEFAULT_TEXTURES + float sampled_ior = 0.0; + float sampled_roughness = 0.0; + #else + float sampled_ior = texture(p3d_Texture2, texcoord).x; + float sampled_roughness = texture(p3d_Texture3, texcoord).x; + #endif + + #if OPT_ALPHA_TESTING + #if DONT_FETCH_DEFAULT_TEXTURES + // No alpha testing when not using default textures + #else + // Do binary alpha testing, but weight it based on the distance to the + // camera. This prevents alpha tested objects getting too thin when + // viewed from a high distance. + // TODO: Might want to make the alpha testing distance configurable + vec4 sampled_diffuse = texture(p3d_Texture0, texcoord); + float dist_to_camera = distance(MainSceneData.camera_pos, vOutput.position); + float alpha_factor = mix(0.99, 0.1, saturate(dist_to_camera / 15.0)); + if (sampled_diffuse.w < alpha_factor) discard; + #endif + #else + // In case we don't do alpha testing, we don't need the w-component, so + // don't fetch it. In practice, most GPU's will still load the w component + // and discard it, but it surely can't hurt. + #if DONT_FETCH_DEFAULT_TEXTURES + vec3 sampled_diffuse = vec3(0); + #else + vec3 sampled_diffuse = texture(p3d_Texture0, texcoord).xyz; + #endif + #endif + + vec3 material_nrm = vOutput.normal; + + #if OPT_NORMAL_MAPPING + #if DONT_FETCH_DEFAULT_TEXTURES + // No normal mapping when not using default textures + #else + { + // Perform normal mapping if enabled + vec3 sampled_normal = texture(p3d_Texture1, texcoord).xyz; + vec3 detail_normal = unpack_texture_normal(sampled_normal); + material_nrm = apply_normal_map( + vOutput.normal, detail_normal, mInput.normalfactor); + } + #endif + #endif + + // Generate the material output + MaterialShaderOutput m; + + #if DONT_SET_MATERIAL_PROPERTIES + // Leave material properties unitialized, and hope the user knows + // what he's doing. + #else + m.shading_model = mInput.shading_model; + + #if DONT_FETCH_DEFAULT_TEXTURES + m.basecolor = mInput.color; + #else + m.basecolor = mInput.color * sampled_diffuse.xyz; + #endif + m.normal = material_nrm; + m.metallic = mInput.metallic; + m.specular_ior = blend_ior(mInput.specular_ior, sampled_ior); + m.roughness = mInput.roughness * sampled_roughness; + m.shading_model_param0 = mInput.arbitrary0; + #endif + + %material% + + render_material(m); +} diff --git a/rpcore/shader/templates/shadow.frag.glsl b/rpcore/shader/templates/shadow.frag.glsl new file mode 100644 index 0000000..73a26a1 --- /dev/null +++ b/rpcore/shader/templates/shadow.frag.glsl @@ -0,0 +1,59 @@ +/** + * + * RenderPipeline + * + * Copyright (c) 2014-2016 tobspr + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + */ + +#version 430 + +%defines% + +#pragma include "render_pipeline_base.inc.glsl" +#pragma include "includes/vertex_output.struct.glsl" + +%includes% +%inout% + +layout(location = 0) in VertexOutput vOutput; + +#if OPT_ALPHA_TESTING +uniform sampler2D p3d_Texture0; +#endif + +void main() { + #if OPT_ALPHA_TESTING + + // Alpha tested shadows. This seems to be quite expensive, so we are + // only doing this for the objects which really need it (like trees) + float sampled_alpha = texture(p3d_Texture0, vOutput.texcoord).w; + if (sampled_alpha < 0.1) discard; + #endif + + %alpha_test% + + #if 0 + // This prevents the effect compiler from emitting a warning about + // a undefined hook. + %material% + #endif +} diff --git a/rpcore/shader/templates/vertex.vert.glsl b/rpcore/shader/templates/vertex.vert.glsl new file mode 100644 index 0000000..9fe9158 --- /dev/null +++ b/rpcore/shader/templates/vertex.vert.glsl @@ -0,0 +1,75 @@ +/** + * + * RenderPipeline + * + * Copyright (c) 2014-2016 tobspr + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + */ + +#version 430 + +%defines% + +#pragma include "render_pipeline_base.inc.glsl" +#pragma include "includes/vertex_output.struct.glsl" +#pragma include "includes/material.inc.glsl" + +in vec4 p3d_Vertex; +in vec3 p3d_Normal; +in vec2 p3d_MultiTexCoord0; + +uniform mat4 p3d_ViewProjectionMatrix; +uniform mat4 p3d_ModelViewProjectionMatrix; + +#if EXPERIMENTAL_PREV_TRANSFORM + uniform mat4 p3d_PrevModelMatrix; +#endif + +uniform mat4 p3d_ModelMatrix; +uniform mat3 tpose_world_to_model; + +layout(location = 0) out VertexOutput vOutput; + +%includes% +%inout% + +void main() { + vOutput.texcoord = p3d_MultiTexCoord0; + vOutput.normal = normalize(tpose_world_to_model * p3d_Normal).xyz; + vOutput.position = (p3d_ModelMatrix * p3d_Vertex).xyz; + + %transform% + + // TODO: We have to account for skinning, we can maybe use hardware skinning for this. + #if IN_GBUFFER_SHADER + #if EXPERIMENTAL_PREV_TRANSFORM + vOutput.last_proj_position = p3d_ViewProjectionMatrix * + (p3d_PrevModelMatrix * p3d_Vertex); + #else + vOutput.last_proj_position = p3d_ViewProjectionMatrix * + vec4(vOutput.position, 1); + #endif + #endif + + gl_Position = p3d_ViewProjectionMatrix * vec4(vOutput.position, 1); + + %post_transform% +} diff --git a/rpcore/shader/templates/voxelize.frag.glsl b/rpcore/shader/templates/voxelize.frag.glsl new file mode 100644 index 0000000..ac52a74 --- /dev/null +++ b/rpcore/shader/templates/voxelize.frag.glsl @@ -0,0 +1,74 @@ +/** + * + * RenderPipeline + * + * Copyright (c) 2014-2016 tobspr + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + */ + +#version 430 + +// Shader used for voxelization, required for GI + +%defines% + +#define USE_TIME_OF_DAY 1 +#pragma include "render_pipeline_base.inc.glsl" + +%includes% +%inout% + +// Voxel data +uniform vec3 voxelGridPosition; +uniform writeonly image3D RESTRICT VoxelGridDest; + +#pragma include "includes/nonviewspace_shading_pipeline.inc.glsl" + +void main() { + vec2 texcoord = vOutput.texcoord; + MaterialBaseInput mInput = get_input_from_p3d(p3d_Material); + + %texcoord% + + MaterialShaderOutput m = prepare_material(mInput, texcoord); + + %material% + + Material m_out = emulate_gbuffer_pass(m, vOutput.position); + + // Actual lighting pass + vec3 sun_lighting = get_sun_shading(m_out); + vec3 lights = get_forward_light_shading(m_out); + vec3 combined_lighting = lights + sun_lighting; + + // Tonemapping to pack color + combined_lighting = combined_lighting / (1 + combined_lighting); + + // Get destination voxel + const int resolution = GET_SETTING(vxgi, grid_resolution); + const float ws_size = GET_SETTING(vxgi, grid_ws_size); + vec3 vs_coord = (vOutput.position + + vOutput.normal * 0.0 - voxelGridPosition + ws_size) / (2.0 * ws_size); + ivec3 vs_icoord = ivec3(vs_coord * resolution + 1e-5); + + // Write voxel + imageStore(VoxelGridDest, vs_icoord, vec4(combined_lighting, 1.0)); +} diff --git a/rpcore/shader/tiled_culling.vert.glsl b/rpcore/shader/tiled_culling.vert.glsl new file mode 100644 index 0000000..dad0c5e --- /dev/null +++ b/rpcore/shader/tiled_culling.vert.glsl @@ -0,0 +1,67 @@ +/** + * + * RenderPipeline + * + * Copyright (c) 2014-2016 tobspr + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + */ + +#version 430 + +#pragma include "render_pipeline_base.inc.glsl" + +in vec4 p3d_Vertex; +uniform isamplerBuffer CellListBuffer; +uniform int threadCount; + +uint get_slice_count(uint cell_count) { + return uint(ceil(float(cell_count * threadCount) / LC_CULLING_SLICE_WIDTH)); +} + +void main() { + + // XXX: Get rid of all of this unnecessary uint divides. It does not matter + // much for performance (since this is a vertex shader), but the logic + // is still awful and could be much simpler. + + // I don't want to move the logic to the CPU though, as passing uniforms + // is totally slow without UBO's. + + // Find the amount of cells to shade + int num_total_cells = texelFetch(CellListBuffer, 0).x; + + // Compute the amount of pixel lines required to shade all cells + uint num_used_slices = get_slice_count(num_total_cells); + + // Compute the percentage factor of the used slices + uint max_tiles = MainSceneData.lc_tile_count.x * + MainSceneData.lc_tile_count.y * + LC_TILE_SLICES; + uint max_slices = get_slice_count(max_tiles); + + float percentage_height = saturate(num_used_slices / float(max_slices)); + // percentage_height = 1; + + // Store the vertex position. + gl_Position = vec4( + p3d_Vertex.x, + fma(fma(p3d_Vertex.z, 0.5, 0.5) * percentage_height, 2.0, -1.0) , 0, 1); +} diff --git a/rpcore/shader/upscale_stage.frag.glsl b/rpcore/shader/upscale_stage.frag.glsl new file mode 100644 index 0000000..2d94cd9 --- /dev/null +++ b/rpcore/shader/upscale_stage.frag.glsl @@ -0,0 +1,48 @@ +/** + * + * RenderPipeline + * + * Copyright (c) 2014-2016 tobspr + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + */ + +#version 430 + +#pragma include "render_pipeline_base.inc.glsl" +#pragma include "includes/noise.inc.glsl" +#pragma include "includes/upsampling.inc.glsl" + +uniform sampler2D ShadedScene; +out vec4 result; + +void main() { + #if 1 + vec2 texcoord = (ivec2(gl_FragCoord.xy) + 0.5) / NATIVE_SCREEN_SIZE; + // vec4 scene_color = bicubic_filter(ShadedScene, texcoord); + // vec4 scene_color = bilinear_filter(ShadedScene, texcoord); + vec4 scene_color = directional_filter(ShadedScene, texcoord); + #else + vec2 texcoord = (ivec2(gl_FragCoord.xy) + 0.5) / NATIVE_SCREEN_SIZE; + vec4 scene_color = textureLod(ShadedScene, texcoord, 0); + #endif + + result = vec4(scene_color.xyz, 1); +} diff --git a/rpcore/shader/view_frustum_cull.frag.glsl b/rpcore/shader/view_frustum_cull.frag.glsl new file mode 100644 index 0000000..64c90d5 --- /dev/null +++ b/rpcore/shader/view_frustum_cull.frag.glsl @@ -0,0 +1,80 @@ +/** + * + * RenderPipeline + * + * Copyright (c) 2014-2016 tobspr + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + */ + +#version 430 + +// This shader takes the list of all lights, and evaluates whether they are +// in the camera frustum. This improves the performance of the actual culling +// pass. + +#pragma include "render_pipeline_base.inc.glsl" +#pragma include "includes/transforms.inc.glsl" +#pragma include "includes/light_culling.inc.glsl" +#pragma include "includes/light_data.inc.glsl" +#pragma include "includes/light_classification.inc.glsl" + +uniform writeonly uimageBuffer FrustumLights; +layout(r32i) uniform iimageBuffer FrustumLightsCount; + +uniform samplerBuffer AllLightsData; +uniform int maxLightIndex; + +void main() { + + const int tile_size = 16; + ivec2 coord = ivec2(gl_FragCoord.xy); + + float max_light_dist_sq = LC_MAX_DISTANCE * LC_MAX_DISTANCE; + + int start_offset = coord.y * tile_size + coord.x; + + // Iterate over all lights + for (int i = start_offset; i < maxLightIndex + 1; i += tile_size * tile_size) { + + // Fetch data of current light + LightData light_data = read_light_data(AllLightsData, i); + + // XXX: Might first read the type, then skip early + int light_type = get_light_type(light_data); + + // Skip Null-Lights + if (light_type < 1) continue; + + bool visible = true; + + Sphere sphere = get_representative_sphere(light_data); + + // XXX: Do actual culling here + + if (length_squared(sphere.pos) - square(sphere.radius) > max_light_dist_sq) + visible = false; + + if (visible) { + int index = imageAtomicAdd(FrustumLightsCount, 0, 1); + imageStore(FrustumLights, index, uvec4(i)); + } + } +} diff --git a/rpcore/shader/visualize_exposure.compute.glsl b/rpcore/shader/visualize_exposure.compute.glsl new file mode 100644 index 0000000..411837c --- /dev/null +++ b/rpcore/shader/visualize_exposure.compute.glsl @@ -0,0 +1,75 @@ +/** + * + * RenderPipeline + * + * Copyright (c) 2014-2016 tobspr + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + */ + +#version 430 + +#pragma include "render_pipeline_base.inc.glsl" + +layout(local_size_x = 10, local_size_y = 4, local_size_z = 1) in; + +uniform writeonly image2D RESTRICT DestTex; +uniform samplerBuffer ExposureTex; + +void main() { + + // TODO: Might make this an input + const ivec2 widget_size = ivec2(140, 20); + ivec2 coord = ivec2(gl_GlobalInvocationID.xy); + + // Store the current pixels color + vec4 color = vec4(0, 0, 0, 0); + vec4 border_color = vec4(0.9, 0.9, 0.9, 1.0); + + // Border + const int border_size = 1; + if (coord.x < border_size || coord.x >= widget_size.x - border_size || + coord.y < border_size || coord.y >= widget_size.y - border_size) { + color += border_color * (1 - color.w); + } + + // Fetch exposure settings + float min_exp = GET_SETTING(color_correction, min_exposure_value); + float max_exp = GET_SETTING(color_correction, max_exposure_value); + + // Fetch current exposure + float curr_exposure = texelFetch(ExposureTex, 0).x; + + // Slider + float slider_pos = saturate((curr_exposure - min_exp) / (max_exp - min_exp)); + + // Make visualization logarithmic + // slider_pos = make_logarithmic(slider_pos, factor); + + const int slider_w = 4; + int slider_pos_int = int(slider_pos * float(widget_size.x - 2 * border_size)) + border_size; + + if (coord.x > slider_pos_int - slider_w && coord.x < slider_pos_int + slider_w) { + // Don't draw the slider over the border + color += vec4(50, 255, 50, 255.0) / 255.0 * (1 - color.w); + } + + imageStore(DestTex, coord, color); +} diff --git a/rpcore/stage_manager.py b/rpcore/stage_manager.py new file mode 100644 index 0000000..810d481 --- /dev/null +++ b/rpcore/stage_manager.py @@ -0,0 +1,286 @@ +""" + +RenderPipeline + +Copyright (c) 2014-2016 tobspr + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. + +""" + +from rplibs.six import iteritems +from rplibs.yaml import load_yaml_file + +from direct.stdpy.file import open + +from rpcore.rpobject import RPObject +from rpcore.gui.pipe_viewer import PipeViewer +from rpcore.image import Image +from rpcore.util.shader_input_blocks import SimpleInputBlock, GroupedInputBlock +from rpcore.stages.update_previous_pipes_stage import UpdatePreviousPipesStage + + +class StageManager(RPObject): + + """ This manager takes a list of RenderStages and puts them into an order, + while connecting the different pipes, inputs, ubos and defines. """ + + def __init__(self, pipeline): + """ Constructs the stage manager """ + RPObject.__init__(self) + self.stages = [] + self.inputs = {} + self.pipes = {} + self.input_blocks = [] + self.previous_pipes = {} + self.future_bindings = [] + self.defines = {} + self.pipeline = pipeline + self.created = False + + self._load_stage_order() + + # Register the manager so the pipe viewer can read our data + PipeViewer.register_stage_mgr(self) + + def _load_stage_order(self): + """ Loads the order of all stages from the stages.yaml configuration + file """ + orders = load_yaml_file("/$$rpconfig/stages.yaml") + if "global_stage_order" not in orders: + self.error("Could not load stage order, root key does not exist!") + return + self._stage_order = orders["global_stage_order"] + + def add_stage(self, stage): + """ Adds a new stage """ + if stage.stage_id not in self._stage_order: + self.error("The stage type", stage.debug_name, + "is not registered yet! Please add it to the StageManager!") + return + + if self.created: + self.error("Cannot attach stage, stages are already created!") + return + + self.stages.append(stage) + + def get_stage(self, stage_class): + """ Returns a handle to an instantiated stage """ + for stage in self.stages: + if stage.__class__.__name__ == stage_class: + return stage + + def _prepare_stages(self): + """ Prepares all stages by removing disabled stages and sorting stages + by order """ + self.debug("Preparing stages ..") + + # Remove all disabled stages + to_remove = [] + for stage in self.stages: + if stage.disabled: + to_remove.append(stage) + + for stage in to_remove: + self.stages.remove(stage) + + self.stages.sort(key=lambda stage: self._stage_order.index(stage.stage_id)) + + def _bind_pipes_to_stage(self, stage): + """ Sets all required pipes on a stage """ + for pipe in stage.required_pipes: + + # Check if there is an input block named like the pipe + if pipe in self.input_blocks: + self.input_blocks[pipe].bind_to(stage) + continue + + if pipe.startswith("PreviousFrame::"): + # Special case: Pipes from the previous frame. We assume those + # pipes have the same size as the window and a format of + # F_rgba16. Could be subject to change. + pipe_name = pipe.split("::")[-1] + if pipe_name not in self.previous_pipes: + tex_format = "RGBA16" + + # XXX: Assuming we have a depth texture whenever "depth" + # occurs in the textures name + if "depth" in pipe_name.lower(): + tex_format = "R32" + + pipe_tex = Image.create_2d("Prev-" + pipe_name, 0, 0, tex_format) + pipe_tex.clear_image() + self.previous_pipes[pipe_name] = pipe_tex + stage.set_shader_input("Previous_" + pipe_name, self.previous_pipes[pipe_name]) + continue + + elif pipe.startswith("FuturePipe::"): + # Special case: Future Pipes which are not available yet. + # They will contain the unmodified data from the last + # frame. + pipe_name = pipe.split("::")[-1] + self.debug("Awaiting future pipe", pipe_name) + self.future_bindings.append((pipe_name, stage)) + continue + + if pipe not in self.pipes: + self.fatal("Pipe '" + pipe + "' is missing for", stage) + return False + + pipe_value = self.pipes[pipe] + if isinstance(pipe_value, list) or isinstance(pipe_value, tuple): + stage.set_shader_input(pipe, *pipe_value) + else: + stage.set_shader_input(pipe, pipe_value) + return True + + def _bind_inputs_to_stage(self, stage): + """ Binds all inputs including common inputs to the given stage """ + common_inputs = ["mainCam", "mainRender", "MainSceneData", "TimeOfDay"] + for input_binding in stage.required_inputs + common_inputs: + if input_binding not in self.inputs and \ + input_binding not in self.input_blocks: + self.error("Input", input_binding, "is missing for", stage) + continue + + if input_binding in self.inputs: + stage.set_shader_input(input_binding, self.inputs[input_binding]) + elif input_binding in self.input_blocks: + self.input_blocks[input_binding].bind_to(stage) + else: + assert False, "Input binding not in inputs and not in blocks!" + return True + + def _register_stage_result(self, stage): + """ Registers all produced pipes, inputs and defines from the given + stage, so they can be used by later stages. """ + for pipe_name, pipe_data in (iteritems)(stage.produced_pipes): + if isinstance(pipe_data, (SimpleInputBlock, GroupedInputBlock)): + self.input_blocks[pipe_name] = pipe_data + continue + self.pipes[pipe_name] = pipe_data + + for define_name, data in iteritems(stage.produced_defines): + if define_name in self.defines: + self.warn("Stage", stage, "overrides define", define_name) + self.defines[define_name] = data + + for input_name, data in iteritems(stage.produced_inputs): + if input_name in self.inputs: + self.warn("Stage", stage, "overrides input", input_name) + + if isinstance(data, (SimpleInputBlock, GroupedInputBlock)): + self.input_blocks[input_name] = data + continue + + self.inputs[input_name] = data + + def _create_previous_pipes(self): + """ Creates a target for each last-frame's pipe, any pipe starting + with the prefix 'Previous::' has to be stored and copied each frame. """ + if self.previous_pipes: + self._prev_stage = UpdatePreviousPipesStage(self.pipeline) + for prev_pipe, prev_tex in iteritems(self.previous_pipes): + + if prev_pipe not in self.pipes: + self.error("Attempted to use previous frame data from pipe", + prev_pipe, "- however, that pipe was never created!") + return False + + # Tell the stage to transfer the data from the current pipe to + # the current texture + self._prev_stage.add_transfer(self.pipes[prev_pipe], prev_tex) + self._prev_stage.create() + self._prev_stage.set_dimensions() + self.stages.append(self._prev_stage) + + def _apply_future_bindings(self): + """ Applies all future bindings. At this point all pipes and + inputs should be present """ + for pipe, stage in self.future_bindings: + if pipe not in self.pipes: + self.error("Could not bind future pipe:", pipe, "not present!") + continue + stage.set_shader_input(pipe, self.pipes[pipe]) + self.future_bindings = [] + + def setup(self): + """ Setups the stages """ + self.debug("Setup stages ..") + self.created = True + + # Convert input blocks so we can access them in a better way + self.input_blocks = {block.name: block for block in self.input_blocks} + self._prepare_stages() + + for stage in self.stages: + stage.create() + stage.handle_window_resize() + + # Rely on the methods to print an appropriate error message + if not self._bind_pipes_to_stage(stage): + continue + if not self._bind_inputs_to_stage(stage): + continue + + self._register_stage_result(stage) + self._create_previous_pipes() + self._apply_future_bindings() + + def reload_shaders(self): + """ This pass sets the shaders to all passes and also generates the + shader configuration """ + self.write_autoconfig() + for stage in self.stages: + stage.reload_shaders() + + def update(self): + """ Calls the update method for each registered stage. Inactive stages + are skipped. """ + for stage in self.stages: + if stage.active: + stage.update() + + def handle_window_resize(self): + """ Method to get called when the window got resized. Propagates the + resize event to all registered stages """ + for stage in self.stages: + stage.handle_window_resize() + + def write_autoconfig(self): + """ Writes the shader auto config, based on the defines specified by the + different stages """ + self.debug("Writing shader config") + + # Generate autoconfig as string + output = "#pragma once\n\n" + output += "// Autogenerated by the render pipeline\n" + output += "// Do not edit! Your changes will be lost.\n\n" + + for key, value in sorted(iteritems(self.defines)): + if isinstance(value, bool): + value = 1 if value else 0 + output += "#define " + key + " " + str(value) + "\n" + + try: + with open("/$$rptemp/$$pipeline_shader_config.inc.glsl", "w") as handle: + handle.write(output) + except IOError as msg: + self.error("Error writing shader autoconfig:", msg) diff --git a/rpcore/stages/__init__.py b/rpcore/stages/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/rpcore/stages/ambient_stage.py b/rpcore/stages/ambient_stage.py new file mode 100644 index 0000000..60772e2 --- /dev/null +++ b/rpcore/stages/ambient_stage.py @@ -0,0 +1,49 @@ +""" + +RenderPipeline + +Copyright (c) 2014-2016 tobspr + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. + +""" + +from rpcore.render_stage import RenderStage + + +class AmbientStage(RenderStage): + + """ This stage computes the ambient term """ + + required_inputs = ["DefaultEnvmap", "PrefilteredBRDF", "PrefilteredMetalBRDF", + "PrefilteredCoatBRDF"] + required_pipes = ["ShadedScene", "GBuffer"] + + @property + def produced_pipes(self): + return {"ShadedScene": self._target.color_tex, + "PostAmbientScene": self._target.color_tex} + + def create(self): + self._target = self.create_target("AmbientStage") + self._target.add_color_attachment(bits=16) + self._target.prepare_buffer() + + def reload_shaders(self): + self._target.shader = self.load_shader("ambient_stage.frag.glsl") diff --git a/rpcore/stages/apply_lights_stage.py b/rpcore/stages/apply_lights_stage.py new file mode 100644 index 0000000..6d530f4 --- /dev/null +++ b/rpcore/stages/apply_lights_stage.py @@ -0,0 +1,48 @@ +""" + +RenderPipeline + +Copyright (c) 2014-2016 tobspr + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. + +""" + +from rpcore.render_stage import RenderStage + + +class ApplyLightsStage(RenderStage): + + """ This stage applies the lights to the scene using the gbuffer """ + + required_inputs = ["AllLightsData", "IESDatasetTex", "ShadowSourceData"] + required_pipes = ["GBuffer", "CellIndices", "PerCellLights", "ShadowAtlas", + "ShadowAtlasPCF", "CombinedVelocity", "PerCellLightsCounts"] + + @property + def produced_pipes(self): + return {"ShadedScene": self.target.color_tex} + + def create(self): + self.target = self.create_target("ApplyLights") + self.target.add_color_attachment(bits=16) + self.target.prepare_buffer() + + def reload_shaders(self): + self.target.shader = self.load_shader("apply_lights.frag.glsl") diff --git a/rpcore/stages/collect_used_cells_stage.py b/rpcore/stages/collect_used_cells_stage.py new file mode 100644 index 0000000..1b7956c --- /dev/null +++ b/rpcore/stages/collect_used_cells_stage.py @@ -0,0 +1,77 @@ +""" + +RenderPipeline + +Copyright (c) 2014-2016 tobspr + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. + +""" + +from rpcore.image import Image +from rpcore.render_stage import RenderStage + + +class CollectUsedCellsStage(RenderStage): + + """ This stage collects the flagged cells from the FlagUsedCellsStage and + makes a list of them """ + + required_pipes = ["FlaggedCells"] + + @property + def produced_pipes(self): + return { + "CellListBuffer": self.cell_list_buffer, + "CellIndices": self.cell_index_buffer, + } + + def create(self): + self.target = self.create_target("CollectUsedCells") + self.target.size = 0, 0 + self.target.prepare_buffer() + + self.cell_list_buffer = Image.create_buffer("CellList", 0, "R32I") + self.cell_index_buffer = Image.create_2d_array("CellIndices", 0, 0, 0, "R32I") + + self.target.set_shader_inputs( + CellListBuffer=self.cell_list_buffer, + CellListIndices=self.cell_index_buffer) + + def update(self): + self.cell_list_buffer.clear_image() + self.cell_index_buffer.clear_image() + + def set_dimensions(self): + tile_amount = self._pipeline.light_mgr.num_tiles + num_slices = self._pipeline.settings["lighting.culling_grid_slices"] + max_cells = tile_amount.x * tile_amount.y * num_slices + + self.cell_list_buffer.set_x_size(1 + max_cells) + self.cell_index_buffer.set_x_size(tile_amount.x) + self.cell_index_buffer.set_y_size(tile_amount.y) + self.cell_index_buffer.set_z_size(num_slices) + + self.cell_list_buffer.clear_image() + self.cell_index_buffer.clear_image() + + self.target.size = tile_amount.x, tile_amount.y + + def reload_shaders(self): + self.target.shader = self.load_shader("collect_used_cells.frag.glsl") diff --git a/rpcore/stages/combine_velocity_stage.py b/rpcore/stages/combine_velocity_stage.py new file mode 100644 index 0000000..73df2c6 --- /dev/null +++ b/rpcore/stages/combine_velocity_stage.py @@ -0,0 +1,47 @@ +""" + +RenderPipeline + +Copyright (c) 2014-2016 tobspr + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. + +""" + +from rpcore.render_stage import RenderStage + + +class CombineVelocityStage(RenderStage): + + """ This stage combines the per-object velocity with the + camera velocity """ + + required_pipes = ["GBuffer"] + + @property + def produced_pipes(self): + return {"CombinedVelocity": self._target.color_tex} + + def create(self): + self._target = self.create_target("CombineVelocity") + self._target.add_color_attachment(bits=(16, 16, 0, 0)) + self._target.prepare_buffer() + + def reload_shaders(self): + self._target.shader = self.load_shader("combine_velocity.frag.glsl") diff --git a/rpcore/stages/cull_lights_stage.py b/rpcore/stages/cull_lights_stage.py new file mode 100644 index 0000000..8c301bd --- /dev/null +++ b/rpcore/stages/cull_lights_stage.py @@ -0,0 +1,137 @@ +""" + +RenderPipeline + +Copyright (c) 2014-2016 tobspr + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. + +""" + +import math + +from rpcore.render_stage import RenderStage +from rpcore.image import Image + + +class CullLightsStage(RenderStage): + + """ This stage takes the list of used cells and creates a list of lights + for each cell """ + + required_pipes = ["CellListBuffer"] + required_inputs = ["AllLightsData", "maxLightIndex"] + + def __init__(self, pipeline): + RenderStage.__init__(self, pipeline) + self.max_lights_per_cell = pipeline.settings["lighting.max_lights_per_cell"] + + if self.max_lights_per_cell > 2**16: + self.fatal("lighting.max_lights_per_cell must be <=", 2**16, "!") + + self.slice_width = pipeline.settings["lighting.culling_slice_width"] + self.cull_threads = 32 + + # Amount of light classes. Has to match the ones in LightClassification.inc.glsl + self.num_light_classes = 4 + + @property + def produced_pipes(self): + return { + "PerCellLights": self.grouped_cell_lights, + "PerCellLightsCounts": self.grouped_cell_lights_counts + } + + @property + def produced_defines(self): + return { + "LC_SLICE_WIDTH": self.slice_width, + "LC_CULL_THREADS": self.cull_threads, + "LC_LIGHT_CLASS_COUNT": self.num_light_classes + } + + def create(self): + self.target_visible = self.create_target("GetVisibleLights") + self.target_visible.size = 16, 16 + self.target_visible.prepare_buffer() + + # TODO: Use no oversized triangle in this stage + self.target_cull = self.create_target("CullLights") + self.target_cull.size = 0, 0 + self.target_cull.prepare_buffer() + + # TODO: Use no oversized triangle in this stage + self.target_group = self.create_target("GroupLightsByClass") + self.target_group.size = 0, 0 + self.target_group.prepare_buffer() + + self.frustum_lights_ctr = Image.create_counter("VisibleLightCount") + self.frustum_lights = Image.create_buffer( + "FrustumLights", self._pipeline.light_mgr.MAX_LIGHTS, "R16UI") + self.per_cell_lights = Image.create_buffer( + "PerCellLights", 0, "R16UI") + self.per_cell_light_counts = Image.create_buffer( + "PerCellLightCounts", 0, "R32I") # Needs to be R32 for atomic add in cull stage + self.grouped_cell_lights = Image.create_buffer( + "GroupedPerCellLights", 0, "R16UI") + self.grouped_cell_lights_counts = Image.create_buffer( + "GroupedPerCellLightsCount", 0, "R16UI") + + self.target_visible.set_shader_inputs( + FrustumLights=self.frustum_lights, + FrustumLightsCount=self.frustum_lights_ctr) + + self.target_cull.set_shader_inputs( + PerCellLightsBuffer=self.per_cell_lights, + PerCellLightCountsBuffer=self.per_cell_light_counts, + FrustumLights=self.frustum_lights, + FrustumLightsCount=self.frustum_lights_ctr, + threadCount=self.cull_threads) + + self.target_group.set_shader_inputs( + PerCellLightsBuffer=self.per_cell_lights, + PerCellLightCountsBuffer=self.per_cell_light_counts, + GroupedCellLightsBuffer=self.grouped_cell_lights, + GroupedPerCellLightsCountBuffer=self.grouped_cell_lights_counts, + threadCount=1) + + def reload_shaders(self): + self.target_cull.shader = self.load_shader( + "tiled_culling.vert.glsl", "cull_lights.frag.glsl") + self.target_group.shader = self.load_shader( + "tiled_culling.vert.glsl", "group_lights.frag.glsl") + self.target_visible.shader = self.load_shader( + "view_frustum_cull.frag.glsl") + + def update(self): + self.frustum_lights_ctr.clear_image() + + def set_dimensions(self): + max_cells = self._pipeline.light_mgr.total_tiles + num_rows_threaded = int( + math.ceil((max_cells * self.cull_threads) / float(self.slice_width))) + num_rows = int(math.ceil(max_cells / float(self.slice_width))) + self.per_cell_lights.set_x_size(max_cells * self.max_lights_per_cell) + self.per_cell_light_counts.set_x_size(max_cells) + self.grouped_cell_lights.set_x_size( + max_cells * (self.max_lights_per_cell + self.num_light_classes)) + self.target_cull.size = self.slice_width, num_rows_threaded + self.target_group.size = self.slice_width, num_rows + + self.grouped_cell_lights_counts.set_x_size(max_cells * (1 + self.num_light_classes)) diff --git a/rpcore/stages/downscale_z_stage.py b/rpcore/stages/downscale_z_stage.py new file mode 100644 index 0000000..88e61e9 --- /dev/null +++ b/rpcore/stages/downscale_z_stage.py @@ -0,0 +1,48 @@ +""" + +RenderPipeline + +Copyright (c) 2014-2016 tobspr + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. + +""" + +from __future__ import division + +from rpcore.render_stage import RenderStage + + +class DownscaleZStage(RenderStage): + + """ This stage downscales the depth buffer """ + + required_pipes = ["GBuffer"] + + @property + def produced_pipes(self): + return {"DownscaledDepth": self.target.color_tex} + + def create(self): + self.target = self.create_target("DownscaleDepth") + self.target.add_color_attachment(bits=(16, 0, 0, 0)) + self.target.prepare_buffer() + + def reload_shaders(self): + self.target.shader = self.load_shader("downscale_depth.frag.glsl") diff --git a/rpcore/stages/final_stage.py b/rpcore/stages/final_stage.py new file mode 100644 index 0000000..ad6e961 --- /dev/null +++ b/rpcore/stages/final_stage.py @@ -0,0 +1,62 @@ +""" + +RenderPipeline + +Copyright (c) 2014-2016 tobspr + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. + +""" + +from rpcore.render_stage import RenderStage + + +class FinalStage(RenderStage): + + """ This stage is the final stage and outputs the shaded scene to the + screen """ + + required_pipes = ["ShadedScene"] + + @property + def produced_pipes(self): + return {"ShadedScene": self.target.color_tex} + + def create(self): + + self.target = self.create_target("FinalStage") + self.target.add_color_attachment(bits=16) + self.target.prepare_buffer() + + # XXX: We cannot simply assign the final shader to the window display + # region. This is because of a bug that the last FBO always only gets + # 8 bits, regardles of what was requested - probably because of the + # assumption that no tonemapping/srgb correction will follow afterwards. + # + # This might be a driver bug, or an optimization in Panda3D. However, it + # also has the nice side effect that when taking screenshots (or using + # the pixel inspector), we get the srgb corrected data, so its not too + # much of a disadvantage. + self.present_target = self.create_target("FinalPresentStage") + self.present_target.present_on_screen() + self.present_target.set_shader_input("SourceTex", self.target.color_tex) + + def reload_shaders(self): + self.target.shader = self.load_shader("final_stage.frag.glsl") + self.present_target.shader = self.load_shader("final_present_stage.frag.glsl") diff --git a/rpcore/stages/flag_used_cells_stage.py b/rpcore/stages/flag_used_cells_stage.py new file mode 100644 index 0000000..ab48f41 --- /dev/null +++ b/rpcore/stages/flag_used_cells_stage.py @@ -0,0 +1,60 @@ +""" + +RenderPipeline + +Copyright (c) 2014-2016 tobspr + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. + +""" + +from rpcore.render_stage import RenderStage +from rpcore.image import Image + + +class FlagUsedCellsStage(RenderStage): + + """ This stage flags all used cells based on the depth buffer """ + + required_pipes = ["GBuffer"] + required_inputs = [] + + @property + def produced_pipes(self): + return {"FlaggedCells": self.cell_grid_flags} + + def create(self): + self.target = self.create_target("FlagUsedCells") + self.target.prepare_buffer() + + self.cell_grid_flags = Image.create_2d_array( + "CellGridFlags", 0, 0, + self._pipeline.settings["lighting.culling_grid_slices"], "R8") + self.target.set_shader_input("cellGridFlags", self.cell_grid_flags) + + def update(self): + self.cell_grid_flags.clear_image() + + def set_dimensions(self): + tile_amount = self._pipeline.light_mgr.num_tiles + self.cell_grid_flags.set_x_size(tile_amount.x) + self.cell_grid_flags.set_y_size(tile_amount.y) + + def reload_shaders(self): + self.target.shader = self.load_shader("flag_used_cells.frag.glsl") diff --git a/rpcore/stages/gbuffer_stage.py b/rpcore/stages/gbuffer_stage.py new file mode 100644 index 0000000..0b7b6d4 --- /dev/null +++ b/rpcore/stages/gbuffer_stage.py @@ -0,0 +1,66 @@ +""" + +RenderPipeline + +Copyright (c) 2014-2016 tobspr + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. + +""" + +from rpcore.globals import Globals +from rpcore.render_stage import RenderStage +from rpcore.util.shader_input_blocks import SimpleInputBlock + + +class GBufferStage(RenderStage): + + """ This is the main pass stage, rendering the objects and creating the + GBuffer which is used in later stages """ + + required_inputs = ["DefaultEnvmap"] + required_pipes = [] + + @property + def produced_pipes(self): + return { + "GBuffer": self.make_gbuffer_ubo(), + "SceneDepth": self.target.depth_tex + } + + def make_gbuffer_ubo(self): + ubo = SimpleInputBlock("GBuffer") + ubo.add_input("Depth", self.target.depth_tex) + ubo.add_input("Data0", self.target.color_tex) + ubo.add_input("Data1", self.target.aux_tex[0]) + ubo.add_input("Data2", self.target.aux_tex[1]) + return ubo + + def create(self): + self.target = self.create_target("GBuffer") + self.target.add_color_attachment(bits=16, alpha=True) + self.target.add_depth_attachment(bits=32) + self.target.add_aux_attachments(bits=16, count=2) + self.target.prepare_render(Globals.base.cam) + + def set_shader_input(self, *args): + Globals.render.set_shader_input(*args) + + def set_shader_inputs(self, **kwargs): + Globals.render.set_shader_inputs(**kwargs) diff --git a/rpcore/stages/shadow_stage.py b/rpcore/stages/shadow_stage.py new file mode 100644 index 0000000..f0a12c6 --- /dev/null +++ b/rpcore/stages/shadow_stage.py @@ -0,0 +1,78 @@ +""" + +RenderPipeline + +Copyright (c) 2014-2016 tobspr + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. + +""" + +from panda3d.core import SamplerState + +from rpcore.render_stage import RenderStage +from rpcore.globals import Globals + + +class ShadowStage(RenderStage): + + """ This is the stage which renders all shadows """ + required_inputs = [] + + def __init__(self, pipeline): + RenderStage.__init__(self, pipeline) + self.size = 4096 + + @property + def produced_pipes(self): + return { + "ShadowAtlas": self.target.depth_tex, + "ShadowAtlasPCF": (self.target.depth_tex, self.make_pcf_state()), + } + + def make_pcf_state(self): + state = SamplerState() + state.set_minfilter(SamplerState.FT_shadow) + state.set_magfilter(SamplerState.FT_shadow) + return state + + @property + def atlas_buffer(self): + return self.target.internal_buffer + + def create(self): + self.target = self.create_target("ShadowAtlas") + self.target.size = self.size + self.target.add_depth_attachment(bits=16) + self.target.prepare_render(None) + + # Remove all current display regions + self.target.internal_buffer.remove_all_display_regions() + self.target.internal_buffer.get_display_region(0).set_active(False) + + # Disable the target, and also disable depth clear + self.target.active = False + self.target.internal_buffer.set_clear_depth_active(False) + self.target.region.set_clear_depth_active(False) + + def set_shader_input(self, *args): + Globals.render.set_shader_input(*args) + + def set_shader_inputs(self, **kwargs): + Globals.render.set_shader_inputs(**kwargs) diff --git a/rpcore/stages/update_previous_pipes_stage.py b/rpcore/stages/update_previous_pipes_stage.py new file mode 100644 index 0000000..c6dd655 --- /dev/null +++ b/rpcore/stages/update_previous_pipes_stage.py @@ -0,0 +1,126 @@ +""" + +RenderPipeline + +Copyright (c) 2014-2016 tobspr + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. + +""" + +from direct.stdpy.file import open + +from rpcore.render_stage import RenderStage +from rpcore.globals import Globals + + +class UpdatePreviousPipesStage(RenderStage): + + """ This stage is constructed by the StageManager and stores all the + current pipes in the previous pipe storage. + + This stage is a bit special, and not like the other stages, it does not + specify inputs, since the StageManager passes all required inputs on demand. + Also this stage does not load any shaders, but creates them on the fly. + """ + + def __init__(self, pipeline): + RenderStage.__init__(self, pipeline) + self._transfers = [] + + def add_transfer(self, from_tex, to_tex): + """ Adds a new texture which should be copied from "from_tex" to + "to_tex". This should be called before the stage gets constructed. + The source texture is expected to have the same size as the render + resolution. """ + self._transfers.append((from_tex, to_tex)) + + def create(self): + self.debug("Creating previous pipes stage ..") + self._target = self.create_target("StorePreviousPipes") + self._target.prepare_buffer() + + # Set inputs + for i, (from_tex, to_tex) in enumerate(self._transfers): # pylint: disable=unused-variable + self._target.set_shader_input("SrcTex" + str(i), from_tex) + self._target.set_shader_input("DestTex" + str(i), to_tex) + + def set_dimensions(self): + """ Sets the dimensions on all targets. See RenderTarget::set_dimensions """ + for from_tex, to_tex in self._transfers: # pylint: disable=unused-variable + to_tex.set_x_size(Globals.resolution.x) + to_tex.set_y_size(Globals.resolution.y) + + def reload_shaders(self): + """ This method augo-generates a shader which copies all textures specified + as "from-tex" to the textures specified as "to-tex". """ + uniforms = [] + lines = [] + + # Collect all samplers and generate the required uniforms and copy code + for i, (from_tex, to_tex) in enumerate(self._transfers): + index = str(i) + uniforms.append(self.get_sampler_type(from_tex) + " SrcTex" + index) + uniforms.append(self.get_sampler_type(to_tex, True) + " DestTex" + index) + lines += [ + "\n // Copying " + from_tex.get_name() + " to " + to_tex.get_name(), + self.get_sampler_lookup(from_tex, "data" + index, "SrcTex" + index, "coord_2d_int"), + self.get_store_code(to_tex, "DestTex" + index, "coord_2d_int", "data" + index), + "\n", + ] + + # Actually create the shader + fragment = "#version 430\n" + fragment += "\n// Autogenerated, do not edit! Your changes will be lost.\n\n" + for uniform in uniforms: + fragment += "uniform " + uniform + ";\n" + fragment += "\nvoid main() {\n" + fragment += " ivec2 coord_2d_int = ivec2(gl_FragCoord.xy);\n" + for line in lines: + fragment += " " + line + "\n" + fragment += "}\n" + + # Write the shader + shader_dest = "/$$rptemp/$$update_previous_pipes.frag.glsl" + with open(shader_dest, "w") as handle: + handle.write(fragment) + + # Load it back again + self._target.shader = self.load_shader(shader_dest) + + def get_sampler_type(self, tex, can_write=False): # pylint: disable=unused-argument + """ Returns the matching GLSL sampler type for a Texture, or image type + in case write access is required """ + # TODO: Add more sampler types based on texture type + if not can_write: + return "sampler2D" + else: + return "writeonly image2D" + + def get_sampler_lookup(self, tex, dest_name, sampler_name, coord_var): # noqa # pylint: disable=unused-argument + """ Returns the matching GLSL sampler lookup for a texture, storing the + result in the given glsl variable """ + # TODO: Add more lookups based on texture type + return "vec4 " + dest_name + " = texelFetch(" + sampler_name + ", " + coord_var + ", 0);" + + def get_store_code(self, tex, sampler_name, coord_var, data_var): # noqa# pylint: disable=unused-argument + """ Returns the matching GLSL code to store the given data in a given + texture """ + # TODO: Add more stores based on texture type + return "imageStore(" + sampler_name + ", " + coord_var + ", vec4(" + data_var + "));" diff --git a/rpcore/stages/upscale_stage.py b/rpcore/stages/upscale_stage.py new file mode 100644 index 0000000..ec1681c --- /dev/null +++ b/rpcore/stages/upscale_stage.py @@ -0,0 +1,50 @@ +""" + +RenderPipeline + +Copyright (c) 2014-2016 tobspr + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. + +""" + +from rpcore.globals import Globals +from rpcore.render_stage import RenderStage + + +class UpscaleStage(RenderStage): + + """ This stage upscales the scene to native resolution, using a bicubic filter """ + + required_inputs = [] + required_pipes = ["ShadedScene"] + + @property + def produced_pipes(self): + return {"ShadedScene": self._target.color_tex} + + def create(self): + native_size = Globals.native_resolution.x, Globals.native_resolution.y + self._target = self.create_target("Upscale") + self._target.size = native_size + self._target.add_color_attachment(bits=16) + self._target.prepare_buffer() + + def reload_shaders(self): + self._target.shader = self.load_shader("upscale_stage.frag.glsl") diff --git a/rpcore/util/__init__.py b/rpcore/util/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/rpcore/util/cubemap_filter.py b/rpcore/util/cubemap_filter.py new file mode 100644 index 0000000..55ffe6f --- /dev/null +++ b/rpcore/util/cubemap_filter.py @@ -0,0 +1,199 @@ +""" + +RenderPipeline + +Copyright (c) 2014-2016 tobspr + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. + +""" + +from __future__ import division + +from panda3d.core import SamplerState, Vec4 + +from rpcore.rpobject import RPObject +from rpcore.image import Image + + +class CubemapFilter(RPObject): + + """ Util class for filtering cubemaps, provides funcionality to generate + a specular and diffuse IBL cubemap. """ + + # Fixed size for the diffuse cubemap, since it does not contain much detail + DIFFUSE_CUBEMAP_SIZE = 10 + PREFILTER_CUBEMAP_SIZE = 32 + + def __init__(self, parent_stage, name="Cubemap", size=128): + """ Inits the filter from a given stage """ + RPObject.__init__(self) + self._stage = parent_stage + self._name = name + self._size = size + self._make_maps() + + @property + def specular_cubemap(self): + """ Returns the generated specular cubemap. The specular cubemap is + mipmapped and provides the specular IBL components of the input cubemap. """ + return self._specular_map + + @property + def diffuse_cubemap(self): + """ Returns the generated diffuse cubemap. The diffuse cubemap has no + mipmaps and contains the filtered diffuse component of the input cubemap. """ + return self._diffuse_map + + @property + def target_cubemap(self): + """ Returns the target where the caller should write the initial cubemap + data to """ + return self._specular_map + + @property + def size(self): + """ Returns the size of the created cubemap, previously passed to the + constructor of the filter """ + return self._size + + def create(self): + """ Creates the filter. The input cubemap should be mipmapped, and will + get reused for the specular cubemap. """ + self._make_specular_targets() + self._make_diffuse_target() + + def _make_maps(self): + """ Internal method to create the cubemap storage """ + + # Create the cubemaps for the diffuse and specular components + self._prefilter_map = Image.create_cube( + self._name + "IBLPrefDiff", CubemapFilter.PREFILTER_CUBEMAP_SIZE, "R11G11B10") + self._diffuse_map = Image.create_cube( + self._name + "IBLDiff", CubemapFilter.DIFFUSE_CUBEMAP_SIZE, "R11G11B10") + self._spec_pref_map = Image.create_cube( + self._name + "IBLPrefSpec", self._size, "R11G11B10") + self._specular_map = Image.create_cube( + self._name + "IBLSpec", self._size, "R11G11B10") + + # Set the correct filtering modes + for tex in [self._diffuse_map, self._specular_map, + self._prefilter_map, self._spec_pref_map]: + tex.set_minfilter(SamplerState.FT_linear) + tex.set_magfilter(SamplerState.FT_linear) + tex.set_clear_color(Vec4(0)) + tex.clear_image() + + # Use mipmaps for the specular cubemap + self._spec_pref_map.set_minfilter(SamplerState.FT_linear_mipmap_linear) + self._specular_map.set_minfilter(SamplerState.FT_linear_mipmap_linear) + + def _make_specular_targets(self): + """ Internal method to create the specular mip chain """ + self._targets_spec = [] + self._targets_spec_filter = [] + mip, mipsize = 0, self._size + while mipsize >= 2: + + # Assuming an initial size of a power of 2, its safe to do this + mipsize = mipsize // 2 + + # Create the target which downsamples the mipmap + target = self._stage.create_target("CF:SpecIBL-PreFilter-" + str(mipsize)) + target.size = mipsize * 6, mipsize + target.prepare_buffer() + + if mip == 0: + target.set_shader_input("SourceTex", self._specular_map) + else: + target.set_shader_input("SourceTex", self._spec_pref_map) + target.set_shader_input( + "DestMipmap", self._spec_pref_map, False, True, -1, + mip + 1, 0) + target.set_shader_input("currentMip", mip) + + mip += 1 + + # Create the target which filters the mipmap and removes the noise + target_filter = self._stage.create_target("CF:SpecIBL-PostFilter-" + str(mipsize)) + target_filter.size = mipsize * 6, mipsize + target_filter.prepare_buffer() + target_filter.set_shader_inputs( + currentMip=mip, + SourceTex=self._spec_pref_map) + target_filter.set_shader_input( + "DestMipmap", self._specular_map, False, True, -1, mip, 0) + + self._targets_spec.append(target) + self._targets_spec_filter.append(target_filter) + + def _make_diffuse_target(self): + """ Internal method to create the diffuse cubemap """ + + # Create the target which integrates the lambert brdf + self._diffuse_target = self._stage.create_target("CF:DiffuseIBL") + self._diffuse_target.size = ( + CubemapFilter.PREFILTER_CUBEMAP_SIZE * 6, + CubemapFilter.PREFILTER_CUBEMAP_SIZE) + self._diffuse_target.prepare_buffer() + + self._diffuse_target.set_shader_inputs( + SourceCubemap=self._specular_map, + DestCubemap=self._prefilter_map, + cubeSize=CubemapFilter.PREFILTER_CUBEMAP_SIZE) + + # Create the target which removes the noise from the previous target, + # which is introduced with importance sampling + self._diff_filter_target = self._stage.create_target("CF:DiffPrefIBL") + self._diff_filter_target.size = ( + CubemapFilter.DIFFUSE_CUBEMAP_SIZE * 6, + CubemapFilter.DIFFUSE_CUBEMAP_SIZE) + self._diff_filter_target.prepare_buffer() + + self._diff_filter_target.set_shader_inputs( + SourceCubemap=self._prefilter_map, + DestCubemap=self._diffuse_map, + cubeSize=CubemapFilter.DIFFUSE_CUBEMAP_SIZE) + + def reload_shaders(self): + """ Sets all required shaders on the filter. """ + + # Set diffuse filter shaders + self._diffuse_target.shader = self._stage.load_shader( + "ibl/cubemap_diffuse.frag.glsl") + self._diff_filter_target.shader = self._stage.load_shader( + "ibl/cubemap_diffuse_filter.frag.glsl") + + # Set specular prefilter shaders + mip_shader = self._stage.load_shader("ibl/cubemap_specular_prefilter.frag.glsl") + for target in self._targets_spec: + target.shader = mip_shader + + # Special shader for the first prefilter target + self._targets_spec[0].shader = self._stage.load_shader( + "ibl/cubemap_specular_prefilter_first.frag.glsl") + + # Set specular filter sampling shaders + mip_filter_shader = self._stage.load_shader("ibl/cubemap_specular_filter.frag.glsl") + for target in self._targets_spec_filter: + target.shader = mip_filter_shader + + # Special shader for the first filter target + self._targets_spec_filter[0].shader = self._stage.load_shader( + "ibl/cubemap_specular_filter_first.frag.glsl") diff --git a/rpcore/util/display_shader_builder.py b/rpcore/util/display_shader_builder.py new file mode 100644 index 0000000..6f2d767 --- /dev/null +++ b/rpcore/util/display_shader_builder.py @@ -0,0 +1,176 @@ +""" + +RenderPipeline + +Copyright (c) 2014-2016 tobspr + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. + +""" + +# pylint: disable=line-too-long + +from direct.stdpy.file import isfile, open + +from rpcore.image import Image +from rpcore.rpobject import RPObject +from rpcore.loader import RPLoader + + +class DisplayShaderBuilder(object): # pylint: disable=too-few-public-methods + + """ Utility class to generate shaders on the fly to display texture previews + and also buffers """ + + @classmethod + def build(cls, texture, view_width, view_height): + """ Builds a shader to display in a view port with the size + * """ + view_width, view_height = int(view_width), int(view_height) + + cache_key = "/$$rptemp/$$TEXDISPLAY-X{}-Y{}-Z{}-TT{}-CT{}-VW{}-VH{}.frag.glsl".format( + texture.get_x_size(), + texture.get_y_size(), + texture.get_z_size(), + texture.get_texture_type(), + texture.get_component_type(), + view_width, + view_height) + + # Only regenerate the file when there is no cache entry for it + if not isfile(cache_key) or True: + fragment_shader = cls._build_fragment_shader(texture, view_width, view_height) + + with open(cache_key, "w") as handle: + handle.write(fragment_shader) + + return RPLoader.load_shader("/$$rp/shader/default_gui_shader.vert.glsl", cache_key) + + @classmethod + def _build_fragment_shader(cls, texture, view_width, view_height): + """ Internal method to build a fragment shader displaying the texture """ + + sampling_code, sampler_type = cls._generate_sampling_code(texture, view_width, view_height) + + # Build actual shader + built = """ + #version 400 + #extension GL_ARB_shading_language_420pack : enable + #pragma include "render_pipeline_base.inc.glsl" + in vec2 texcoord; + out vec3 result; + uniform int mipmap; + uniform int slice; + uniform float brightness; + uniform bool tonemap; + uniform """ + sampler_type + """ p3d_Texture0; + void main() { + int view_width = """ + str(view_width) + """; + int view_height = """ + str(view_height) + """; + ivec2 display_coord = ivec2(texcoord * vec2(view_width, view_height)); + int int_index = display_coord.x + display_coord.y * view_width; + """ + sampling_code + """ + result *= brightness; + if (tonemap) + result = result / (1 + result); + } + """ + + # Strip trailing spaces + built = '\n'.join([i.strip() for i in built.split("\n")]) + + return built + + @classmethod + def _generate_sampling_code(cls, texture, view_width, view_height): # noqa # pylint: disable=unused-argument,too-many-branches + """ Generates the GLSL code to sample a texture and also returns the + GLSL sampler type """ + + texture_type = texture.get_texture_type() + comp_type = texture.get_component_type() + + # Useful snippets + int_coord = "ivec2 int_coord = ivec2(texcoord * textureSize(p3d_Texture0, mipmap).xy);" + slice_count = "int slice_count = textureSize(p3d_Texture0, 0).z;" + + float_types = [Image.T_float, Image.T_unsigned_byte] + int_types = [Image.T_int, Image.T_unsigned_short, Image.T_unsigned_int_24_8] + + result = "result = vec3(1, 0, 1);", "sampler2D" + + if comp_type not in float_types + int_types: + RPObject.global_warn( + "DisplayShaderBuilder", "Unkown texture component type:", comp_type) + + # 2D Textures + if texture_type == Image.TT_2d_texture: + + if comp_type in float_types: + result = "result = textureLod(p3d_Texture0, texcoord, mipmap).xyz;", "sampler2D" + + elif comp_type in int_types: + result = int_coord + "result = texelFetch(p3d_Texture0, int_coord, mipmap).xyz / 10.0;", "isampler2D" # noqa + + # Buffer Textures + elif texture_type == Image.TT_buffer_texture: + + def range_check(code): + return "if (int_index < textureSize(p3d_Texture0)) {" + code + "} else { result = vec3(1.0, 0.6, 0.2);};" # noqa + + if comp_type in float_types: + result = range_check("result = texelFetch(p3d_Texture0, int_index).xyz;"), "samplerBuffer" # noqa + + elif comp_type in int_types: + result = range_check("result = texelFetch(p3d_Texture0, int_index).xyz / 10.0;"), "isamplerBuffer" # noqa + + # 3D Textures + elif texture_type == Image.TT_3d_texture: + + if comp_type in float_types: + result = slice_count + "result = textureLod(p3d_Texture0, vec3(texcoord, (0.5 + slice) / slice_count), mipmap).xyz;", "sampler3D" # noqa + + elif comp_type in int_types: + result = int_coord + "result = texelFetch(p3d_Texture0, ivec3(int_coord, slice), mipmap).xyz / 10.0;", "isampler3D" # noqa + + # 2D Texture Array + elif texture_type == Image.TT_2d_texture_array: + + if comp_type in float_types: + result = "result = textureLod(p3d_Texture0, vec3(texcoord, slice), mipmap).xyz;", "sampler2DArray" # noqa + + elif comp_type in int_types: + result = int_coord + "result = texelFetch(p3d_Texture0, ivec3(int_coord, slice), mipmap).xyz / 10.0;", "isampler2DArray" # noqa + + # Cubemap + elif texture_type == Image.TT_cube_map: + + code = "vec3 sample_dir = get_cubemap_coordinate(slice, texcoord*2-1);\n" + code += "result = textureLod(p3d_Texture0, sample_dir, mipmap).xyz;" + result = code, "samplerCube" + + # Cubemap array + elif texture_type == Image.TT_cube_map_array: + code = "vec3 sample_dir = get_cubemap_coordinate(slice % 6, texcoord*2-1);\n" + code += "result = textureLod(p3d_Texture0, vec4(sample_dir, slice / 6), mipmap).xyz;" + result = code, "samplerCubeArray" + + else: + print("WARNING: Unhandled texture type", texture_type, "in display shader builder") + + return result diff --git a/rpcore/util/generic.py b/rpcore/util/generic.py new file mode 100644 index 0000000..d034889 --- /dev/null +++ b/rpcore/util/generic.py @@ -0,0 +1,115 @@ +""" + +RenderPipeline + +Copyright (c) 2014-2016 tobspr + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. + +""" + + +from __future__ import print_function + +import time +import hashlib + +from panda3d.core import PStatCollector, Mat4, Point4, Vec3 +from rpcore.globals import Globals + + +def rgb_from_string(text, min_brightness=0.6): + """ Creates a rgb color from a given string """ + ohash = hashlib.md5(text[::-1].encode("ascii")).hexdigest() + r, g, b = int(ohash[0:2], 16), int(ohash[2:4], 16), int(ohash[4:6], 16) + neg_inf = 1.0 - min_brightness + return (min_brightness + r / 255.0 * neg_inf, + min_brightness + g / 255.0 * neg_inf, + min_brightness + b / 255.0 * neg_inf) + + +def profile(func): + """ Handy decorator which can be used to profile a function with pstats """ + collector_name = "Debug:%s" % func.__name__ + + global_showbase = Globals.base + + # Insert the collector to a custom dictionary attached to the base + if hasattr(global_showbase, 'custom_collectors'): + if collector_name in global_showbase.custom_collectors.keys(): + pstat = global_showbase.custom_collectors[collector_name] + else: + global_showbase.custom_collectors[collector_name] = \ + PStatCollector(collector_name) + pstat = global_showbase.custom_collectors[collector_name] + else: + pstat = PStatCollector(collector_name) + global_showbase.custom_collectors = {} + global_showbase.custom_collectors[collector_name] = pstat + + def do_pstat(*args, **kargs): + pstat.start() + returned = func(*args, **kargs) + pstat.stop() + return returned + + do_pstat.__name__ = func.__name__ + do_pstat.__dict__ = func.__dict__ + do_pstat.__doc__ = func.__doc__ + return do_pstat + + +class profile_cpu(object): # noqa # pylint: disable=invalid-name,too-few-public-methods + """ + Context manager for profiling CPU duration. This is useful for timing + loading of files or other CPU-heavy operations. Example usage: + + with profile_cpu("Some Task"): + some_slow_operation() + + Duration of the process will be print out on the console later on. + """ + + def __init__(self, name): + self.name = name + + def __enter__(self): + self.start_time = time.process_time() + + def __exit__(self, *args): + duration = (time.process_time() - self.start_time) * 1000.0 + print(self.name, "took", round(duration, 2), "ms ") + + +def snap_shadow_map(mvp, cam_node, resolution): + """ 'Snaps' a shadow map to make sure it always is on full texel centers. + This ensures no flickering occurs while moving the shadow map. + This works by projecting the Point (0,0,0) to light space, compute the + texcoord differences and offset the light world space position by that. """ + mvp = Mat4(mvp) + base_point = mvp.xform(Point4(0, 0, 0, 1)) * 0.5 + 0.5 + texel_size = 1.0 / float(resolution) + offset_x = base_point.x % texel_size + offset_y = base_point.y % texel_size + mvp.invert_in_place() + new_base = mvp.xform(Point4( + (base_point.x - offset_x) * 2.0 - 1.0, + (base_point.y - offset_y) * 2.0 - 1.0, + (base_point.z) * 2.0 - 1.0, 1)) + cam_node.set_pos(cam_node.get_pos() - Vec3(new_base.x, new_base.y, new_base.z)) diff --git a/rpcore/util/ies_profile_loader.py b/rpcore/util/ies_profile_loader.py new file mode 100644 index 0000000..69daa6f --- /dev/null +++ b/rpcore/util/ies_profile_loader.py @@ -0,0 +1,269 @@ +""" + +RenderPipeline + +Copyright (c) 2014-2016 tobspr + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. + +""" + +# Disable the unused variable warning - this occurs since we read a lot more +# properties from the IES file than we actually need +# pylint: disable=unused-variable + +from __future__ import print_function + +import re + +from panda3d.core import PTAFloat, Filename, SamplerState, VirtualFileSystem +from panda3d.core import get_model_path +from direct.stdpy.file import open, join, isfile + +from rplibs.six.moves import range # pylint: disable=import-error + +from rpcore.native import IESDataset +from rpcore.image import Image +from rpcore.rpobject import RPObject + + +class InvalidIESProfileException(Exception): + """ Exception which is thrown when an error occurs during loading an IES + Profile """ + + +class IESProfileLoader(RPObject): + + """ Loader class to load .IES files and create an IESDataset from it. + It generates a LUT for each loaded ies profile which is used by the lighting + pipeline later on. """ + + # Supported IES Profiles + PROFILES = [ + "IESNA:LM-63-1986", + "IESNA:LM-63-1991", + "IESNA91", + "IESNA:LM-63-1995", + "IESNA:LM-63-2002", + "ERCO Leuchten GmbH BY: ERCO/LUM650/8701", + "ERCO Leuchten GmbH" + ] + + # Regexp for extracting keywords + KEYWORD_REGEX = re.compile(r"\[([A-Za-z0-8_-]+)\](.*)") + + def __init__(self, pipeline): + RPObject.__init__(self) + self._pipeline = pipeline + self._entries = [] + self._max_entries = 32 + self._create_storage() + + def _create_storage(self): + """ Internal method to create the storage for the profile dataset textures """ + self._storage_tex = Image.create_3d("IESDatasets", 512, 512, self._max_entries, "R16") + self._storage_tex.set_minfilter(SamplerState.FT_linear) + self._storage_tex.set_magfilter(SamplerState.FT_linear) + self._storage_tex.set_wrap_u(SamplerState.WM_clamp) + self._storage_tex.set_wrap_v(SamplerState.WM_repeat) + self._storage_tex.set_wrap_w(SamplerState.WM_clamp) + + self._pipeline.stage_mgr.inputs["IESDatasetTex"] = self._storage_tex + self._pipeline.stage_mgr.defines["MAX_IES_PROFILES"] = self._max_entries + + def load(self, filename): + """ Loads a profile from a given filename and returns the internal + used index which can be assigned to a light.""" + + # Make sure the user can load profiles directly from the ies profile folder + data_path = join("/$$rp/data/ies_profiles/", filename) + if isfile(data_path): + filename = data_path + + # Make filename unique + fname = Filename.from_os_specific(filename) + if not VirtualFileSystem.get_global_ptr().resolve_filename( + fname, get_model_path().get_value(), "ies"): + self.error("Could not resolve", filename) + return -1 + fname = fname.get_fullpath() + + # Check for cache entries + if fname in self._entries: + return self._entries.index(fname) + + # Check for out of bounds + if len(self._entries) >= self._max_entries: + # TODO: Could remove unused profiles here or regenerate texture + self.warn("Cannot load IES Profile, too many loaded! (Maximum: 32)") + + # Try loading the dataset, and see what happes + try: + dataset = self._load_and_parse_file(fname) + except InvalidIESProfileException as msg: + self.warn("Failed to load profile from", filename, ":", msg) + return -1 + + if not dataset: + return -1 + + # Dataset was loaded successfully, now copy it + dataset.generate_dataset_texture_into(self._storage_tex, len(self._entries)) + self._entries.append(fname) + + return len(self._entries) - 1 + + def _load_and_parse_file(self, pth): + """ Loads a .IES file from a given filename, returns an IESDataset + which is used by the load function later on. """ + self.debug("Loading ies profile from", pth) + + try: + with open(pth, "r") as handle: + lines = handle.readlines() + except IOError as msg: + self.error("Failed to open", pth, ":", msg) + return None + + lines = [i.strip() for i in lines] + + # Parse version header + self._check_version_header(lines.pop(0)) + + # Parse arbitrary amount of keywords + keywords = self._extract_keywords(lines) # noqa + + # Next line should be TILT=NONE according to the spec + if lines.pop(0) != "TILT=NONE": + raise InvalidIESProfileException("Expected TILT=NONE line, but none found!") + + # From now on, lines do not matter anymore, instead everything is + # space seperated + new_parts = (' '.join(lines)).replace(",", " ").split() + + def read_int(): + return int(new_parts.pop(0)) + + def read_float(): + return float(new_parts.pop(0)) + + # Amount of Lamps + if read_int() != 1: + raise InvalidIESProfileException("Only 1 Lamp supported!") + + # Extract various properties + lumen_per_lamp = read_float() # noqa + candela_multiplier = read_float() # noqa + num_vertical_angles = read_int() + num_horizontal_angles = read_int() + + if num_vertical_angles < 1 or num_horizontal_angles < 1: + raise InvalidIESProfileException("Invalid of vertical/horizontal angles!") + + photometric_type = read_int() # noqa + unit_type = read_int() + + # Check for a correct unit type, should be 1 for meters and 2 for feet + if unit_type not in [1, 2]: + raise InvalidIESProfileException("Invalid unit type") + + width = read_float() # noqa + length = read_float() # noqa + height = read_float() # noqa + ballast_factor = read_float() # noqa + future_use = read_float() # Unused field for future usage # noqa + input_watts = read_float() # noqa + + # Read vertical angles + vertical_angles = [read_float() for i in range(num_vertical_angles)] + horizontal_angles = [read_float() for i in range(num_horizontal_angles)] + + candela_values = [] + candela_scale = 0.0 + + for i in range(num_horizontal_angles): + vertical_data = [read_float() for i in range(num_vertical_angles)] + candela_scale = max(candela_scale, max(vertical_data)) + candela_values += vertical_data + + # Rescale values, divide by maximum + candela_values = [i / candela_scale for i in candela_values] + + if len(new_parts) != 0: + self.warn("Unhandled data at file-end left:", new_parts) + + # Dont abort here, some formats like those from ERCO Leuchten GmbH + # have an END keyword, just ignore everything after the data was + # read in. + + dataset = IESDataset() + dataset.set_vertical_angles(self._list_to_pta(vertical_angles)) + dataset.set_horizontal_angles(self._list_to_pta(horizontal_angles)) + dataset.set_candela_values(self._list_to_pta(candela_values)) + + # Testing code to write out the LUT + # from panda3d.core import Texture + # tex = Texture("temp") + # tex.setup_3d_texture(512, 512, 1, Image.T_float, Image.F_r16) + # dataset.generate_dataset_texture_into(tex, 0) + # tex.write("generated.png") + + return dataset + + def _list_to_pta(self, list_values): + """ Converts a list to a PTAFloat """ + pta = PTAFloat.empty_array(len(list_values)) + for i, val in enumerate(list_values): + pta[i] = val + return pta + + def _check_version_header(self, first_line): + """ Checks if the IES version header is correct and the specified IES + version is supported """ + if first_line not in self.PROFILES: + raise InvalidIESProfileException("Unsupported Profile: " + first_line) + + def _extract_keywords(self, lines): + """ Extracts the keywords from a list of lines, and removes all lines + containing keywords """ + keywords = {} + while lines: + line = lines.pop(0) + if not line.startswith("["): + + # Special format used by some IES files, indicates end of properties + # By just checking for the tilt keyword instead of validating each line, + # we can read even malformed lines, like those from ERCO Leuchten GmbH + if line != "TILT=NONE": + continue + + # No keyword, we popped the line already tho, so append it again + lines.insert(0, line) + return keywords + else: + + # Try matching the keywords + match = self.KEYWORD_REGEX.match(line) + if match: + key, val = match.group(1, 2) + keywords[key.strip()] = val.strip() + else: + raise InvalidIESProfileException("Invalid keyword line: " + line) + + return keywords diff --git a/rpcore/util/movement_controller.py b/rpcore/util/movement_controller.py new file mode 100644 index 0000000..0c022c2 --- /dev/null +++ b/rpcore/util/movement_controller.py @@ -0,0 +1,413 @@ +""" + +RenderPipeline + +Copyright (c) 2014-2016 tobspr + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. + +""" + + +# Disable the "exactly one space required after comma" message, for the input +# bindings it looks nicer to insert some spaces (see the setup method) +# pylint: disable=bad-whitespace + +from __future__ import print_function + +import sys +import os +import subprocess +from typing import Optional + +from panda3d.core import ModifierButtons, Vec3, PStatClient +from panda3d.core import Point3, CurveFitter +from panda3d.core import KeyboardButton,MouseButton,Point2,LPoint2f,NodePath +from direct.showbase.ShowBase import ShowBase +import math + + +class MovementController(object): + + """ This is a helper class, used to controll the camera and enable various + debugging features. It is not really part of the pipeline, but included to + view the demo scenes. """ + + def __init__(self, showbase): + self.showbase:ShowBase = showbase + self.movement = [0, 0, 0] + self.velocity = Vec3(0.0) + self.hpr_movement = [0, 0] + self.speed = 0.4 + self.initial_position = Vec3(0) + self.initial_destination = Vec3(0) + self.initial_hpr = Vec3(0) + self.mouse_enabled = False + self.last_mouse_pos = [0, 0] + self.mouse_sensivity = 0.7 + self.keyboard_hpr_speed = 0.4 + self.use_hpr = False + self.smoothness = 6.0 + self.bobbing_amount = 1.5 + self.bobbing_speed = 0.5 + + def set_initial_position(self, pos, target): + """ Sets the initial camera position """ + self.initial_position = pos + self.initial_destination = target + self.use_hpr = False + self.reset_to_initial() + + def set_initial_position_hpr(self, pos, hpr): + """ Sets the initial camera position """ + self.initial_position = pos + self.initial_hpr = hpr + self.use_hpr = True + self.reset_to_initial() + + def reset_to_initial(self): + """ Resets the camera to the initial position """ + self.showbase.camera.set_pos(self.initial_position) + + if self.use_hpr: + self.showbase.camera.set_hpr(self.initial_hpr) + else: + self.showbase.camera.look_at( + self.initial_destination.x, self.initial_destination.y, + self.initial_destination.z) + + def set_movement(self, direction, amount): + self.movement[direction] = amount + + def set_hpr_movement(self, direction, amount): + self.hpr_movement[direction] = amount + + def set_mouse_enabled(self, enabled): + self.mouse_enabled = enabled + + def increase_speed(self): + self.speed *= 1.4 + + def decrease_speed(self): + self.speed *= 0.6 + + def unbind(self): + """ Unbinds the movement controler and restores the previous state """ + raise NotImplementedError() + + @property + def clock_obj(self): + """ Returns the global clock object """ + return self.showbase.taskMgr.globalClock + + def setup(self): + """ Attaches the movement controller and inits the keybindings """ + # x + self.showbase.accept("raw-w", self.set_movement, [0, 1]) + self.showbase.accept("raw-w-up", self.set_movement, [0, 0]) + self.showbase.accept("raw-s", self.set_movement, [0, -1]) + self.showbase.accept("raw-s-up", self.set_movement, [0, 0]) + + # y + self.showbase.accept("raw-a", self.set_movement, [1, -1]) + self.showbase.accept("raw-a-up", self.set_movement, [1, 0]) + self.showbase.accept("raw-d", self.set_movement, [1, 1]) + self.showbase.accept("raw-d-up", self.set_movement, [1, 0]) + + # z + self.showbase.accept("space", self.set_movement, [2, 1]) + self.showbase.accept("space-up", self.set_movement, [2, 0]) + self.showbase.accept("raw-e", self.set_movement, [2, 1]) + self.showbase.accept("raw-e-up", self.set_movement, [2, 0]) + # self.showbase.accept("shift", self.set_movement, [2, -1]) + # self.showbase.accept("shift-up", self.set_movement, [2, 0]) + self.showbase.accept("raw-q", self.set_movement, [2, -1]) + self.showbase.accept("raw-q-up", self.set_movement, [2, 0]) + + # wireframe + debug + buffer viewer + self.showbase.accept("f3", self.showbase.toggle_wireframe) + self.showbase.accept("f11", lambda: self.showbase.win.save_screenshot("screenshot.png")) + self.showbase.accept("j", self.print_position) + + # mouse + self.showbase.accept("mouse1", self.set_mouse_enabled, [True]) + self.showbase.accept("mouse1-up", self.set_mouse_enabled, [False]) + + # arrow mouse navigation + self.showbase.accept("arrow_up", self.set_hpr_movement, [1, 1]) + self.showbase.accept("arrow_up-up", self.set_hpr_movement, [1, 0]) + self.showbase.accept("arrow_down", self.set_hpr_movement, [1, -1]) + self.showbase.accept("arrow_down-up", self.set_hpr_movement, [1, 0]) + self.showbase.accept("arrow_left", self.set_hpr_movement, [0, 1]) + self.showbase.accept("arrow_left-up", self.set_hpr_movement, [0, 0]) + self.showbase.accept("arrow_right", self.set_hpr_movement, [0, -1]) + self.showbase.accept("arrow_right-up", self.set_hpr_movement, [0, 0]) + + # increase / decrease speed + self.showbase.accept("+", self.increase_speed) + self.showbase.accept("-", self.decrease_speed) + + # disable modifier buttons to be able to move while pressing shift for + # example + self.showbase.mouseWatcherNode.set_modifier_buttons(ModifierButtons()) + self.showbase.buttonThrowers[0].node().set_modifier_buttons(ModifierButtons()) + + # disable pandas builtin mouse control + self.showbase.disableMouse() + + # add ourself as an update task which gets executed very early before + # the rendering + self.update_task = self.showbase.addTask(self.update, "RP_UpdateMovementController", sort=-40) + + # Hotkeys to connect to pstats and reset the initial position + self.showbase.accept("1", PStatClient.connect) + self.showbase.accept("3", self.reset_to_initial) + + self.focus_distance = 8.0 + self.focus_target:Optional[NodePath] = None + self.last_mouse = None + self.pivot = Vec3(0, 0, 0) + self.radius = self.focus_distance + self.azimuth = 0.0 + self.elevation = 0.0 + self.showbase.accept("mouse1", self._orbit_mouse1) + self.showbase.accept("alt-mouse1",self._orbit_mouse1) + self.showbase.task_mgr.add(self._update_orbit, "update_orbit") + + self.last_mouse_pan = None + self.showbase.accept("mouse2", self._on_mouse2_down) + self.showbase.accept("wheel_up", lambda: self._on_wheel(1)) + self.showbase.accept("wheel_down", lambda: self._on_wheel(-1)) + + def _on_mouse2_down(self): + self.last_mouse_pan = Point2(self.showbase.mouseWatcherNode.getMouse()) + + def _on_wheel(self, direction): + # direction: +1 for wheel_up (zoom in), -1 for wheel_down (zoom out) + zoom_factor = 0.9 if direction > 0 else 1.1 + self.focus_distance += zoom_factor + # self.radius = max(0.5, min(200.0, self.focus_distance * zoom_factor)) + forward = self.showbase.camera.getQuat(self.showbase.render).getForward() + self.showbase.camera.set_pos(self.showbase.camera.get_pos() + forward.normalized() * direction * zoom_factor) + + def _orbit_mouse1(self): + forward = self.showbase.camera.getQuat(self.showbase.render).getForward() + if self.focus_target and not self.focus_target.is_empty(): + self.pivot = self.focus_target.get_pos(self.showbase.render) + else: + self.pivot = self.showbase.camera.getPos(self.showbase.render) + forward.normalized() * self.focus_distance + offset = self.showbase.camera.getPos(self.showbase.render) - self.pivot + self.radius = offset.length() + if self.radius < 1e-5: + self.radius = self.focus_distance + offset = Vec3(0, -self.radius, 0) + self.azimuth = math.atan2(offset.x, offset.y) + self.elevation = math.asin(max(-1.0, min(1.0, offset.z / self.radius))) + self.last_mouse = Point2(self.showbase.mouseWatcherNode.get_mouse()) + + def _refresh_camera_from_angles(self): + cos_el = math.cos(self.elevation) + x = math.sin(self.azimuth) * cos_el + y = math.cos(self.azimuth) * cos_el + z = math.sin(self.elevation) + + self.showbase.camera.setPos(self.pivot + Vec3(x, y, z) * self.radius) + self.showbase.camera.lookAt(self.pivot) + + def _update_orbit(self, task): + if self.showbase.mouseWatcherNode.isButtonDown(MouseButton.two()): + current = Point2(self.showbase.mouseWatcherNode.getMouse()) + if self.last_mouse_pan is not None: + delta = current - self.last_mouse_pan + right = self.showbase.camera.getQuat(self.showbase.render).getRight() + up = self.showbase.camera.getQuat(self.showbase.render).getUp() + pan_scale = -self.radius * 0.5 + offset = (right * delta.x + up * delta.y) * pan_scale + self.showbase.camera.setPos(self.showbase.camera.getPos(self.showbase.render) + offset) + self.last_mouse_pan = current + return task.cont + + if not self.showbase.mouseWatcherNode.isButtonDown(MouseButton.one()) or not self.showbase.mouseWatcherNode.isButtonDown(KeyboardButton.alt()): + return task.cont + + if not self.showbase.mouseWatcherNode.hasMouse() or self.last_mouse is None: + return task.cont + + current = Point2(self.showbase.mouseWatcherNode.getMouse()) + delta = current - self.last_mouse + self.last_mouse = current + + # Screen space is [-1, 1], so multiply by a comfortable radians-per-unit factor. + rot_speed = math.pi # 180° per full screen swipe. + self.azimuth += delta.x * rot_speed + self.elevation -= delta.y * rot_speed + self.elevation = max(math.radians(-85.0), min(math.radians(85.0), self.elevation)) + + self._refresh_camera_from_angles() + + return task.cont + + def focus_on(self,node:NodePath,margin=1.2): + """聚焦:让 cam_np 对准 node 并退到能完整看见它的位置。 + margin > 1 给一点边距。""" + if not node or node.is_empty(): + return + self.focus_target = node + cam_np = self.showbase.camera + lens = self.showbase.camLens + bounds = node.get_tight_bounds(self.showbase.render) + if not bounds or None in bounds: + return # 目标没几何或未就位 + bmin, bmax = bounds + center = (bmin + bmax) * 0.5 + radius = (bmax - bmin).length() * 0.5 + + # 取水平/垂直 FOV 较小的那个作为限制 + fovx, fovy = [math.radians(a) for a in lens.get_fov()] + fov = min(fovx, fovy) + dist = (radius / math.tan(fov * 0.5)) * margin + + forward = cam_np.get_quat(self.showbase.render).get_forward() # 相机当前朝向 + cam_np.set_pos(center - forward * dist) + cam_np.look_at(center) + + def print_position(self): + """ Prints the camera position and hpr """ + pos = self.showbase.cam.get_pos(self.showbase.render) + hpr = self.showbase.cam.get_hpr(self.showbase.render) + print("(Vec3({}, {}, {}), Vec3({}, {}, {})),".format( + pos.x, pos.y, pos.z, hpr.x, hpr.y, hpr.z)) + + def update(self, task): + """ Internal update method """ + + delta = self.clock_obj.get_dt() + + # Update mouse first + if self.showbase.mouseWatcherNode.has_mouse(): + x = self.showbase.mouseWatcherNode.get_mouse_x() + y = self.showbase.mouseWatcherNode.get_mouse_y() + self.current_mouse_pos = (x * self.showbase.camLens.get_fov().x * self.mouse_sensivity, + y * self.showbase.camLens.get_fov().y * self.mouse_sensivity) + + if self.mouse_enabled: + diffx = self.last_mouse_pos[0] - self.current_mouse_pos[0] + diffy = self.last_mouse_pos[1] - self.current_mouse_pos[1] + + # Don't move in the very beginning + if self.last_mouse_pos[0] == 0 and self.last_mouse_pos[1] == 0: + diffx = 0 + diffy = 0 + + self.showbase.camera.set_h(self.showbase.camera.get_h() + diffx) + self.showbase.camera.set_p(self.showbase.camera.get_p() - diffy) + + self.last_mouse_pos = self.current_mouse_pos[:] + + # Compute movement in render space + movement_direction = (Vec3(self.movement[1], self.movement[0], 0) * + self.speed * delta * 100.0) + + # transform by the camera direction + camera_quaternion = self.showbase.camera.get_quat(self.showbase.render) + translated_direction = camera_quaternion.xform(movement_direction) + + # z-force is inddpendent of camera direction + translated_direction.add_z( + self.movement[2] * delta * 120.0 * self.speed) + + self.velocity += translated_direction * 0.15 + + # apply the new position + self.showbase.camera.set_pos(self.showbase.camera.get_pos() + self.velocity) + + # transform rotation (keyboard keys) + rotation_speed = self.keyboard_hpr_speed * 100.0 + rotation_speed *= delta + self.showbase.camera.set_hpr( + self.showbase.camera.get_hpr() + Vec3( + self.hpr_movement[0], self.hpr_movement[1], 0) * rotation_speed) + + # fade out velocity + self.velocity = self.velocity * max( + 0.0, 1.0 - delta * 60.0 / max(0.01, self.smoothness)) + + # bobbing + ftime = self.clock_obj.get_frame_time() + rotation = (ftime % self.bobbing_speed) / self.bobbing_speed + rotation = (min(rotation, 1.0 - rotation) * 2.0 - 0.5) * 2.0 + if self.velocity.length_squared() > 1e-5 and self.speed > 1e-5: + rotation *= self.bobbing_amount + rotation *= min(1, self.velocity.length()) / self.speed * 0.5 + else: + rotation = 0 + self.showbase.camera.set_r(rotation) + return task.cont + + def play_motion_path(self, points, point_duration=1.2): + """ Plays a motion path from the given set of points """ + fitter = CurveFitter() + for i, (pos, hpr) in enumerate(points): + fitter.add_xyz_hpr(i, pos, hpr) + + fitter.compute_tangents(1.0) + curve = fitter.make_hermite() + print("Starting motion path with", len(points), "CVs") + + self.showbase.render2d.hide() + self.showbase.aspect2d.hide() + + self.curve = curve + self.curve_time_start = self.clock_obj.get_frame_time() + self.curve_time_end = self.clock_obj.get_frame_time() + len(points) * point_duration + self.delta_time_sum = 0.0 + self.delta_time_count = 0 + self.showbase.addTask(self.camera_motion_update, "RP_CameraMotionPath", sort=-50) + self.showbase.taskMgr.remove(self.update_task) + + def camera_motion_update(self, task): + if self.clock_obj.get_frame_time() > self.curve_time_end: + print("Camera motion path finished") + + # Print performance stats + avg_ms = self.delta_time_sum / self.delta_time_count + print("Average frame time (ms): {:4.1f}".format(avg_ms * 1000.0)) + print("Average frame rate: {:4.1f}".format(1.0 / avg_ms)) + + self.update_task = self.showbase.addTask( + self.update, "RP_UpdateMovementController", sort=-50) + self.showbase.render2d.show() + self.showbase.aspect2d.show() + return task.done + + lerp = (self.clock_obj.get_frame_time() - self.curve_time_start) /\ + (self.curve_time_end - self.curve_time_start) + lerp *= self.curve.get_max_t() + + pos, hpr = Point3(0), Vec3(0) + self.curve.evaluate_xyz(lerp, pos) + self.curve.evaluate_hpr(lerp, hpr) + + self.showbase.camera.set_pos(pos) + self.showbase.camera.set_hpr(hpr) + + self.delta_time_sum += self.clock_obj.get_dt() + self.delta_time_count += 1 + + return task.cont diff --git a/rpcore/util/network_communication.py b/rpcore/util/network_communication.py new file mode 100644 index 0000000..897293c --- /dev/null +++ b/rpcore/util/network_communication.py @@ -0,0 +1,150 @@ +""" + +RenderPipeline + +Copyright (c) 2014-2016 tobspr + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. + +""" + +import socket +from threading import Thread + +from rpcore.rpobject import RPObject + + +class NetworkCommunication(RPObject): + + """ Listener which accepts messages on several ports to detect incoming updates. + Also provides functionality to send updates. """ + + CONFIG_PORT = 63324 + DAYTIME_PORT = 63325 + MATERIAL_PORT = 63326 + + @classmethod + def send_async(cls, port, message): + """ Starts a new thread which sends a given message to a port """ + thread = Thread(target=cls.__send_message_async, args=(port, message), + name="NC-SendAsync") + thread.setDaemon(True) + thread.start() + return thread + + @classmethod + def listen_threaded(cls, port, callback): + """ Starts a new thread listening to the given port """ + thread = Thread(target=cls.__listen_forever, args=(port, callback), + name="NC-ListenForever") + thread.setDaemon(True) + thread.start() + return thread + + @staticmethod + def __send_message_async(port, message=""): + """ Sends a given message to a given port and immediately returns. """ + sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) + try: + sock.sendto(message.encode("utf-8"), ("127.0.0.1", port)) + finally: + sock.close() + + @staticmethod + def __listen_forever(port, callback): + """ Listens to a given port, and calls callback in case a message + arrives. This method never returns, except when the connection closed or + could not be established. """ + sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) + sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1) + try: + sock.bind(("127.0.0.1", port)) + while True: + data, addr = sock.recvfrom(1024) # pylint: disable=unused-variable + callback(data.decode("utf-8")) + finally: + sock.close() + + def __init__(self, pipeline): + """ Creates the listener service. This also starts listening on the various + ports for updates """ + RPObject.__init__(self) + self._pipeline = pipeline + self._config_updates = set() + self._daytime_updates = set() + self._material_updates = set() + self._config_thread = self.listen_threaded( + self.CONFIG_PORT, self._config_updates.add) + self._daytime_thread = self.listen_threaded( + self.DAYTIME_PORT, self._daytime_updates.add) + self._material_thread = self.listen_threaded( + self.MATERIAL_PORT, self._material_updates.add) + + + def update(self): + """ Update task which gets called every frame and executes the changes. + This takes the incoming scheduled commands and processes one at a time.""" + while self._config_updates: + cmd = self._config_updates.pop() + self._handle_config_command(cmd) + while self._daytime_updates: + cmd = self._daytime_updates.pop() + self._handle_daytime_command(cmd) + while self._material_updates: + cmd = self._material_updates.pop() + self._handle_material_command(cmd) + + def _handle_daytime_command(self, cmd): + """ Handles a daytime command. This could either be a command to set + the time, or a command to reload the time of day configuration. """ + if cmd.startswith("settime "): + daytime = float(cmd.split()[1]) + self._pipeline.daytime_mgr.time = daytime + elif cmd.startswith("loadconf"): + self._pipeline.plugin_mgr.load_daytime_overrides( + "/$$rpconfig/daytime.yaml") + else: + self.warn("Recieved unkown daytime command:", cmd) + + def _handle_config_command(self, cmd): + """ Handles an incomming configuration command. Currently this can only + be an update of a plugin setting """ + if cmd.startswith("setval "): + parts = cmd.split() + setting_parts = parts[1].split(".") + self._pipeline.plugin_mgr.on_setting_changed( + setting_parts[0], setting_parts[1], parts[2]) + else: + self.warn("Recieved unkown plugin command:", cmd) + + def _handle_material_command(self, cmd): + """ Handles an incomming material command """ + if cmd.startswith("dump_materials"): + path = cmd[len("dump_materials "):].strip() + self.debug("Writing materials to", path) + self._pipeline.export_materials(path) + + elif cmd.startswith("update_material"): + + data = cmd[len("update_material "):].strip() + parts = data.split() + self._pipeline.update_serialized_material(parts) + + else: + self.warn("Recieved unkown plugin command:", cmd) diff --git a/rpcore/util/post_process_region.py b/rpcore/util/post_process_region.py new file mode 100644 index 0000000..f686488 --- /dev/null +++ b/rpcore/util/post_process_region.py @@ -0,0 +1,110 @@ +""" + +RenderPipeline + +Copyright (c) 2014-2016 tobspr + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. + +""" + +from rpcore.rpobject import RPObject + +from panda3d.core import GeomVertexFormat, GeomVertexData, Geom, GeomVertexWriter +from panda3d.core import GeomTriangles, GeomNode, NodePath, Camera, OmniBoundingVolume +from panda3d.core import TransparencyAttrib, OrthographicLens, Vec4 + + +class PostProcessRegion(RPObject): + + """ Simple wrapper class to create fullscreen triangles and quads """ + + @classmethod + def make(cls, internal_buffer, *args): + return cls(internal_buffer, *args) + + def __init__(self, internal_buffer, *args): + RPObject.__init__(self) + self._buffer = internal_buffer + self._region = self._buffer.make_display_region(*args) + self._node = NodePath("RTRoot") + + self._make_fullscreen_tri() + self._make_fullscreen_cam() + self._init_function_pointers() + + def _init_function_pointers(self): + self.set_sort = self._region.set_sort + self.set_instance_count = self._tri.set_instance_count + self.disable_clears = self._region.disable_clears + self.set_active = self._region.set_active + self.set_clear_depth_active = self._region.set_clear_depth_active + self.set_clear_depth = self._region.set_clear_depth + self.set_shader = self._tri.set_shader + self.set_camera = self._region.set_camera + self.set_clear_color_active = self._region.set_clear_color_active + self.set_clear_color = self._region.set_clear_color + self.set_attrib = self._tri.set_attrib + + def _make_fullscreen_tri(self): + """ Creates the oversized triangle used for rendering """ + vformat = GeomVertexFormat.get_v3() + vdata = GeomVertexData("vertices", vformat, Geom.UH_static) + vdata.set_num_rows(3) + vwriter = GeomVertexWriter(vdata, "vertex") + vwriter.add_data3f(-1, 0, -1) + vwriter.add_data3f(3, 0, -1) + vwriter.add_data3f(-1, 0, 3) + gtris = GeomTriangles(Geom.UH_static) + gtris.add_next_vertices(3) + geom = Geom(vdata) + geom.add_primitive(gtris) + geom_node = GeomNode("gn") + geom_node.add_geom(geom) + geom_node.set_final(True) + geom_node.set_bounds(OmniBoundingVolume()) + tri = NodePath(geom_node) + tri.set_depth_test(False) + tri.set_depth_write(False) + tri.set_attrib(TransparencyAttrib.make(TransparencyAttrib.M_none), 10000) + tri.set_color(Vec4(1)) + tri.set_bin("unsorted", 10) + tri.reparent_to(self._node) + self._tri = tri + + def set_shader_input(self, *args, **kwargs): + if kwargs.get("override", False): + self._node.set_shader_input(*args, priority=100000) + else: + self._tri.set_shader_input(*args) + + def set_shader_inputs(self, **kwargs): + self._tri.set_shader_inputs(**kwargs) + + def _make_fullscreen_cam(self): + """ Creates an orthographic camera for the buffer """ + buffer_cam = Camera("BufferCamera") + lens = OrthographicLens() + lens.set_film_size(2, 2) + lens.set_film_offset(0, 0) + lens.set_near_far(-100, 100) + buffer_cam.set_lens(lens) + buffer_cam.set_cull_bounds(OmniBoundingVolume()) + self._camera = self._node.attach_new_node(buffer_cam) + self._region.set_camera(self._camera) diff --git a/rpcore/util/shader_input_blocks.py b/rpcore/util/shader_input_blocks.py new file mode 100644 index 0000000..44675bf --- /dev/null +++ b/rpcore/util/shader_input_blocks.py @@ -0,0 +1,191 @@ +""" + +RenderPipeline + +Copyright (c) 2014-2016 tobspr + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. + +""" +from rplibs.six import iteritems + +from panda3d.core import PTAFloat, PTALVecBase3f, PTALMatrix4f, PTALVecBase2f +from panda3d.core import PTALVecBase4f, PTALMatrix3f, PTAInt, TypeRegistry, PTALVecBase2i + +from rpcore.rpobject import RPObject + + +class SimpleInputBlock(RPObject): + + """ Simplest possible uniform buffer which just stores a set of values. + This does not use any fancy uniform buffer objects under the hood, and + instead just sets every value as a shader input. """ + + def __init__(self, name): + """ Creates the ubo with the given name """ + RPObject.__init__(self) + self._inputs = {} + self.name = name + + def add_input(self, name, value): + """ Adds a new input to the UBO """ + self._inputs[self.name + "." + name] = value + + def bind_to(self, target): + """ Binds the UBO to a target """ + target.set_shader_inputs(**self._inputs) + + +class GroupedInputBlock(RPObject): + + """ Grouped uniform buffer which either uses PointerToArray's to efficiently + store and update the shader inputs, or in case of uniform buffer object (UBO) + support, uses these to pass the inputs to the shaders. """ + + # Keeps track of the global allocated input blocks to be able to assign + # a unique binding to all of them + UBO_BINDING_INDEX = 0 + + # Mapping of the pta-types to glsl types, and vice versa + PTA_MAPPINGS = { + PTAInt: "int", + PTAFloat: "float", + PTALVecBase2f: "vec2", + PTALVecBase2i: "ivec2", + PTALVecBase3f: "vec3", + PTALVecBase4f: "vec4", + PTALMatrix3f: "mat3", + PTALMatrix4f: "mat4", + } + + def __init__(self, name): + """ Constructs the input block with a given name """ + RPObject.__init__(self) + self.ptas = {} + self._inputs = {} + self.name = name + self.use_ubo = bool(TypeRegistry.ptr().find_type("GLUniformBufferContext")) + + # Acquire a unique index for each UBO to store its binding + self.bind_id = GroupedInputBlock.UBO_BINDING_INDEX + GroupedInputBlock.UBO_BINDING_INDEX += 1 + + if self.bind_id == 0: + # Only output the bind support debug output once (for the first ubo) + self.debug("Native UBO support =", self.use_ubo) + + def register_pta(self, name, input_type): + """ Registers a new input, type should be a glsl type """ + pta = self.glsl_type_to_pta(input_type).empty_array(1) + self.ptas[name] = pta + if self.use_ubo: + self._inputs[self.name + "_UBO." + name] = pta + else: + self._inputs[self.name + "." + name] = pta + + def pta_to_glsl_type(self, pta_handle): + """ Converts a PtaXXX to a glsl type """ + for pta_type, glsl_type in iteritems(GroupedInputBlock.PTA_MAPPINGS): + if isinstance(pta_handle, pta_type): + return glsl_type + self.error("Unrecognized PTA type:", pta_handle) + + def glsl_type_to_pta(self, glsl_type): + """ Converts a glsl type to a PtaXXX type """ + for key, val in iteritems(GroupedInputBlock.PTA_MAPPINGS): + if val == glsl_type: + return key + self.error("Could not resolve GLSL type:", glsl_type) + + def bind_to(self, target): + """ Binds all inputs of this UBO to the given target, which may be + either a RenderTarget or a NodePath """ + + target.set_shader_inputs(**self._inputs) + + def update_input(self, name, value): + """ Updates an existing input """ + self.ptas[name][0] = value + + def get_input(self, name): + """ Returns the value of an existing input """ + return self.ptas[name][0] + + def generate_shader_code(self): # pylint: disable=too-many-branches + """ Generates the GLSL shader code to use the UBO """ + + content = "#pragma once\n\n" + content += "// Autogenerated by the render pipeline\n" + content += "// Do not edit! Your changes will be lost.\n\n" + + structs = {} + inputs = [] + + for input_name, handle in iteritems(self.ptas): + parts = input_name.split(".") + + # Single input, simply add it to the input list + if len(parts) == 1: + inputs.append(self.pta_to_glsl_type(handle) + " " + input_name + ";") + + # Nested input, like scattering.sun_color + elif len(parts) == 2: + struct_name = parts[0] + actual_input_name = parts[1] + if struct_name in structs: + # Struct is already defined, add member definition + structs[struct_name].append( + self.pta_to_glsl_type(handle) + " " + actual_input_name + ";") + else: + # Construct a new struct and add it to the list of inputs + inputs.append(struct_name + "_UBOSTRUCT " + struct_name + ";") + structs[struct_name] = [ + self.pta_to_glsl_type(handle) + " " + actual_input_name + ";" + ] + + # Nested input, like scattering.some_setting.sun_color, not supported yet + else: + self.warn("Structure definition too nested, not supported (yet):", input_name) + + # Add structures + for struct_name, members in iteritems(structs): + content += "struct " + struct_name + "_UBOSTRUCT {\n" + for member in members: + content += " " * 4 + member + "\n" + content += "};\n\n" + + # Add actual inputs + if len(inputs) < 1: + self.debug("No UBO inputs present for", self.name) + else: + if self.use_ubo: + + content += "layout(shared, binding={}) uniform {}_UBO {{\n".format( + self.bind_id, self.name) + for ipt in inputs: + content += " " * 4 + ipt + "\n" + content += "} " + self.name + ";\n" + else: + content += "uniform struct {\n" + for ipt in inputs: + content += " " * 4 + ipt + "\n" + content += "} " + self.name + ";\n" + + content += "\n" + return content diff --git a/rpcore/util/smooth_connected_curve.py b/rpcore/util/smooth_connected_curve.py new file mode 100644 index 0000000..f5305eb --- /dev/null +++ b/rpcore/util/smooth_connected_curve.py @@ -0,0 +1,139 @@ +""" + +RenderPipeline + +Copyright (c) 2014-2016 tobspr + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. + +""" + +from rplibs.six.moves import range # pylint: disable=import-error + +from panda3d.core import Vec3, CurveFitter + + +class SmoothConnectedCurve(object): + + """ Interface to a curve which also manages connecting the end of the + curve with the beginning. """ + + def __init__(self): + self._curve = None + self._modified = False + self._border_points = 1 + self._color = (0, 0, 0) + self._cv_points = [(0, 0), (0.5, 0), (1.0, 0)] + self.build_curve() + + @property + def modified(self): + """ Returns whether the curve was modified since the creation """ + return self._modified + + @property + def control_points(self): + """ Returns a list of all controll points """ + return self._cv_points + + @control_points.setter + def control_points(self, points): + """ Sets the cv points to the given list of points """ + self._cv_points = points + self._modified = True + self.build_curve() + + @property + def color(self): + """ Returns the display color of the curve """ + return self._color + + @color.setter + def color(self, rgb): + """ Sets the display color of the curve """ + self._color = rgb + + def set_single_value(self, val): + """ Sets the curve to be linear, and only use a single value """ + self._cv_points = [[0.5, val]] + self._modified = False + self.build_curve() + + def append_cv(self, x, y): + """ Appends a new cv and returns the index of the attached cv """ + self._cv_points.append([x, y]) + self.build_curve() + self._modified = True + return len(self._cv_points) - 1 + + def remove_cv(self, index): + """ Attempts to remove the cv at the given index, does nothing if only + one control point is left """ + if len(self._cv_points) > 1: + del self._cv_points[index] + self._modified = True + self.build_curve() + + def build_curve(self): + """ Rebuilds the curve based on the controll point values """ + sorted_points = sorted(self._cv_points, key=lambda v: v[0]) + first_point = sorted_points[0] + fitter = CurveFitter() + + # Duplicate curve at the beginning + for i in range(self._border_points): + end_point = self._cv_points[(-i + self._border_points - 1) % len(self._cv_points)] + end_point = first_point + fitter.add_xyz(0.0, Vec3(0, end_point[1], 0)) + + # Append the actual points + for point in self._cv_points: + # Clamp point x position to avoid artifacts at the beginning + point_t = max(0.01, point[0]) + fitter.add_xyz(point_t, Vec3(point_t, point[1], 0)) + + # Duplicate curve at the end + for i in range(self._border_points): + start_point = self._cv_points[i % len(self._cv_points)] + start_point = first_point + fitter.add_xyz(1.0, Vec3(1, start_point[1], 0)) + + fitter.sort_points() + fitter.wrap_hpr() + fitter.compute_tangents(1.0) + + self._curve = fitter.make_hermite() + + def set_cv_value(self, index, x_value, y_value): + """ Updates the cv point at the given index """ + self._cv_points[index] = [x_value, y_value] + self._modified = True + + def get_value(self, offset): + """ Returns the value on the curve ranging whereas the offset should be + from 0 to 1 (0 denotes the start of the curve). The returned value will + be a value from 0 to 1 as well. """ + point = Vec3(0) + self._curve.evaluate_xyz(offset, point) + return max(0.0, min(1.0, point.y)) + + def serialize(self): + """ Returns the value of the curve as yaml list """ + points = ["[{:5.10f},{:5.10f}]".format(float(a), float(b)) for a, b in self._cv_points] + return "[" + ','.join(points) + "]" diff --git a/rpcore/util/submodule_downloader.py b/rpcore/util/submodule_downloader.py new file mode 100644 index 0000000..bb15b93 --- /dev/null +++ b/rpcore/util/submodule_downloader.py @@ -0,0 +1,147 @@ +""" + +RenderPipeline + +Copyright (c) 2014-2016 tobspr + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. + +""" + +from __future__ import print_function + +import os +import sys +import zipfile +import shutil + +from rplibs.six.moves import urllib # pylint: disable=import-error +from rplibs.six import BytesIO, binary_type + + +def download_file(url, chunk_size=100 * 1024): + """ Helper method to download a file displaying a progress bar """ + print("Fetching:", url) + file_content = None + progressbar = None + + if sys.version_info.major <= 2: + + # Import progressbar library + from rplibs.progressbar import FileTransferSpeed, ETA, ProgressBar, Percentage + from rplibs.progressbar import Bar + widgets = ['\tDownloading: ', FileTransferSpeed(), ' ', Bar(), Percentage(), ' ', ETA()] + file_content = [] + bytes_read = 0 + + # Progressively download the file + try: + usock = urllib.request.urlopen(url) + file_size = int(usock.headers.get("Content-Length", 1e10)) + print("File size is", round(file_size / (1024**2), 2), "MB") + progressbar = ProgressBar(widgets=widgets, maxval=file_size).start() + while True: + data = usock.read(chunk_size) + file_content.append(data) + bytes_read += len(data) + progressbar.update(bytes_read) + if not data: + break + usock.close() + except Exception: + print("ERROR: Could not fetch", url, "!", file=sys.stderr) + raise + else: + # Don't use progressbar in python 3 + print("Downloading .. (progressbar disabled due to python 3 build)") + try: + usock = urllib.request.urlopen(url) + file_content = [] + while True: + data = usock.read(chunk_size) + file_content.append(data) + if not data: + break + usock.close() + except Exception: + print("ERROR: Could not fetch", url, "!", file=sys.stderr) + raise + + if progressbar: + progressbar.finish() + + return binary_type().join(file_content) + + +def download_submodule(author, module_name, dest_path, ignore_list): + """ Downloads a submodule from the given author and module name, and extracts + all files which are not on the ignore_list to the dest_path. + + Example: download_submodule("tobspr", "RenderPipeline", ".", ["README.md", "LICENSE"]) + """ + + # Make directory, if it does not exist yet + if not os.path.isdir(dest_path): + os.makedirs(dest_path) + + # Construct download url + source_url = "https://github.com/" + author + "/" + module_name + "/archive/master.zip" + prefix = module_name + "-master" + + # Extract the zip + zip_ptr = BytesIO(download_file(source_url)) + print("Extracting ZIP ...") + + try: + zip_handle = zipfile.ZipFile(zip_ptr) + except zipfile.BadZipfile: + print("ERROR: Invalid zip file!", file=sys.stderr) + sys.exit(3) + + if zip_handle.testzip() is not None: + print("ERROR: Invalid zip file checksums!", file=sys.stderr) + sys.exit(1) + + num_files, num_dirs = 0, 0 + + for fname in zip_handle.namelist(): + rel_name = fname.replace(prefix, "").replace("\\", "/").lstrip("/") + if not rel_name: + continue + + is_file = not rel_name.endswith("/") + rel_name = dest_path.rstrip("/\\") + "/" + rel_name + + # Files + if is_file: + for ignore in ignore_list: + if ignore in rel_name: + break + else: + with zip_handle.open(fname, "r") as source, open(rel_name, "wb") as dest: + shutil.copyfileobj(source, dest) + num_files += 1 + + # Directories + else: + if not os.path.isdir(rel_name): + os.makedirs(rel_name) + num_dirs += 1 + + print("Extracted", num_files, "files and", num_dirs, "directories") diff --git a/rpcore/util/task_scheduler.py b/rpcore/util/task_scheduler.py new file mode 100644 index 0000000..03d8986 --- /dev/null +++ b/rpcore/util/task_scheduler.py @@ -0,0 +1,77 @@ +""" + +RenderPipeline + +Copyright (c) 2014-2016 tobspr + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. + +""" + +from rplibs.yaml import load_yaml_file +from rpcore.rpobject import RPObject + + +class TaskScheduler(RPObject): + + """ This class manages the scheduled tasks and splits them over multiple + frames. Plugins can query whether their subtasks should be executed + or queued for later frames. Also performs analysis on the task configuration + to figure if tasks are distributed uniformly. """ + + def __init__(self, pipeline): + RPObject.__init__(self) + self._pipeline = pipeline + self._tasks = [] + self._frame_index = 0 + self._load_config() + + def _load_config(self): + """ Loads the tasks distribution configuration """ + config = load_yaml_file("/$$rpconfig/task-scheduler.yaml")["frame_cycles"] + for frame_name, tasks in config: # pylint: disable=unused-variable + self._tasks.append(tasks) + + def _check_missing_schedule(self, task_name): + """ Checks whether the given task is scheduled at some point. This can + be used to check whether any task is missing in the task scheduler config. """ + for tasks in self._tasks: + if task_name in tasks: + break + else: + self.error("Task '" + task_name + "' is never scheduled and thus will never run!") + + def is_scheduled(self, task_name): + """ Returns whether a given task is supposed to run this frame """ + self._check_missing_schedule(task_name) + return task_name in self._tasks[self._frame_index] + + def step(self): + """ Advances one frame """ + self._frame_index = (self._frame_index + 1) % len(self._tasks) + + @property + def num_tasks(self): + """ Returns the total amount of tasks """ + return sum((len(i) for i in self._tasks)) + + @property + def num_scheduled_tasks(self): + """ Returns the amount of scheduled tasks this frame """ + return len(self._tasks[self._frame_index]) diff --git a/rplibs/__init__.py b/rplibs/__init__.py new file mode 100644 index 0000000..0a992cc --- /dev/null +++ b/rplibs/__init__.py @@ -0,0 +1,29 @@ +""" +rplibs 包内置了一个 vendored six.py,但其内部不会自动在 sys.modules +中注册子模块名(如 rplibs.six.moves),在 Python 3.12 下直接 +`import rplibs.six.moves` 会失败。这里手动注入一个 module 别名, +让现有 RenderPipeline 的导入语句继续可用。 +""" + +import sys +import types + +from . import six as _six + +# 复制 six.moves 的属性到一个 ModuleType,挂到 sys.modules。 +# 为避免访问不存在的旧模块(如 _dummy_thread)引发异常,改为用 __getattr__ 延迟转发。 +_moves_mod = types.ModuleType(__name__ + ".six.moves") + +def __getattr__(name): + return getattr(_six.moves, name) + +def __dir__(): + return dir(_six.moves) + +_moves_mod.__getattr__ = __getattr__ +_moves_mod.__dir__ = __dir__ + +sys.modules[__name__ + ".six"] = _six +sys.modules[__name__ + ".six.moves"] = _moves_mod + +__all__ = ["six"] diff --git a/rplibs/colorama/LICENSE.txt b/rplibs/colorama/LICENSE.txt new file mode 100644 index 0000000..5f56779 --- /dev/null +++ b/rplibs/colorama/LICENSE.txt @@ -0,0 +1,28 @@ +Copyright (c) 2010 Jonathan Hartley +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + +* Redistributions of source code must retain the above copyright notice, this + list of conditions and the following disclaimer. + +* Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + +* Neither the name of the copyright holders, nor those of its contributors + may be used to endorse or promote products derived from this software without + specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE +FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR +SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER +CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, +OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + diff --git a/rplibs/colorama/SOURCE.txt b/rplibs/colorama/SOURCE.txt new file mode 100644 index 0000000..c90a8bd --- /dev/null +++ b/rplibs/colorama/SOURCE.txt @@ -0,0 +1,4 @@ +package: colorama +version: 0.3.7 +downloaded: 17.03.2016 +url: https://github.com/tartley/colorama diff --git a/rplibs/colorama/__init__.py b/rplibs/colorama/__init__.py new file mode 100644 index 0000000..670e6b3 --- /dev/null +++ b/rplibs/colorama/__init__.py @@ -0,0 +1,7 @@ +# Copyright Jonathan Hartley 2013. BSD 3-Clause license, see LICENSE file. +from .initialise import init, deinit, reinit, colorama_text +from .ansi import Fore, Back, Style, Cursor +from .ansitowin32 import AnsiToWin32 + +__version__ = '0.3.7' + diff --git a/rplibs/colorama/ansi.py b/rplibs/colorama/ansi.py new file mode 100644 index 0000000..7877658 --- /dev/null +++ b/rplibs/colorama/ansi.py @@ -0,0 +1,102 @@ +# Copyright Jonathan Hartley 2013. BSD 3-Clause license, see LICENSE file. +''' +This module generates ANSI character codes to printing colors to terminals. +See: http://en.wikipedia.org/wiki/ANSI_escape_code +''' + +CSI = '\033[' +OSC = '\033]' +BEL = '\007' + + +def code_to_chars(code): + return CSI + str(code) + 'm' + +def set_title(title): + return OSC + '2;' + title + BEL + +def clear_screen(mode=2): + return CSI + str(mode) + 'J' + +def clear_line(mode=2): + return CSI + str(mode) + 'K' + + +class AnsiCodes(object): + def __init__(self): + # the subclasses declare class attributes which are numbers. + # Upon instantiation we define instance attributes, which are the same + # as the class attributes but wrapped with the ANSI escape sequence + for name in dir(self): + if not name.startswith('_'): + value = getattr(self, name) + setattr(self, name, code_to_chars(value)) + + +class AnsiCursor(object): + def UP(self, n=1): + return CSI + str(n) + 'A' + def DOWN(self, n=1): + return CSI + str(n) + 'B' + def FORWARD(self, n=1): + return CSI + str(n) + 'C' + def BACK(self, n=1): + return CSI + str(n) + 'D' + def POS(self, x=1, y=1): + return CSI + str(y) + ';' + str(x) + 'H' + + +class AnsiFore(AnsiCodes): + BLACK = 30 + RED = 31 + GREEN = 32 + YELLOW = 33 + BLUE = 34 + MAGENTA = 35 + CYAN = 36 + WHITE = 37 + RESET = 39 + + # These are fairly well supported, but not part of the standard. + LIGHTBLACK_EX = 90 + LIGHTRED_EX = 91 + LIGHTGREEN_EX = 92 + LIGHTYELLOW_EX = 93 + LIGHTBLUE_EX = 94 + LIGHTMAGENTA_EX = 95 + LIGHTCYAN_EX = 96 + LIGHTWHITE_EX = 97 + + +class AnsiBack(AnsiCodes): + BLACK = 40 + RED = 41 + GREEN = 42 + YELLOW = 43 + BLUE = 44 + MAGENTA = 45 + CYAN = 46 + WHITE = 47 + RESET = 49 + + # These are fairly well supported, but not part of the standard. + LIGHTBLACK_EX = 100 + LIGHTRED_EX = 101 + LIGHTGREEN_EX = 102 + LIGHTYELLOW_EX = 103 + LIGHTBLUE_EX = 104 + LIGHTMAGENTA_EX = 105 + LIGHTCYAN_EX = 106 + LIGHTWHITE_EX = 107 + + +class AnsiStyle(AnsiCodes): + BRIGHT = 1 + DIM = 2 + NORMAL = 22 + RESET_ALL = 0 + +Fore = AnsiFore() +Back = AnsiBack() +Style = AnsiStyle() +Cursor = AnsiCursor() diff --git a/rplibs/colorama/ansitowin32.py b/rplibs/colorama/ansitowin32.py new file mode 100644 index 0000000..b7ff6f2 --- /dev/null +++ b/rplibs/colorama/ansitowin32.py @@ -0,0 +1,236 @@ +# Copyright Jonathan Hartley 2013. BSD 3-Clause license, see LICENSE file. +import re +import sys +import os + +from .ansi import AnsiFore, AnsiBack, AnsiStyle, Style +from .winterm import WinTerm, WinColor, WinStyle +from .win32 import windll, winapi_test + + +winterm = None +if windll is not None: + winterm = WinTerm() + + +def is_stream_closed(stream): + return not hasattr(stream, 'closed') or stream.closed + + +def is_a_tty(stream): + return hasattr(stream, 'isatty') and stream.isatty() + + +class StreamWrapper(object): + ''' + Wraps a stream (such as stdout), acting as a transparent proxy for all + attribute access apart from method 'write()', which is delegated to our + Converter instance. + ''' + def __init__(self, wrapped, converter): + # double-underscore everything to prevent clashes with names of + # attributes on the wrapped stream object. + self.__wrapped = wrapped + self.__convertor = converter + + def __getattr__(self, name): + return getattr(self.__wrapped, name) + + def write(self, text): + self.__convertor.write(text) + + +class AnsiToWin32(object): + ''' + Implements a 'write()' method which, on Windows, will strip ANSI character + sequences from the text, and if outputting to a tty, will convert them into + win32 function calls. + ''' + ANSI_CSI_RE = re.compile('\001?\033\[((?:\d|;)*)([a-zA-Z])\002?') # Control Sequence Introducer + ANSI_OSC_RE = re.compile('\001?\033\]((?:.|;)*?)(\x07)\002?') # Operating System Command + + def __init__(self, wrapped, convert=None, strip=None, autoreset=False): + # The wrapped stream (normally sys.stdout or sys.stderr) + self.wrapped = wrapped + + # should we reset colors to defaults after every .write() + self.autoreset = autoreset + + # create the proxy wrapping our output stream + self.stream = StreamWrapper(wrapped, self) + + on_windows = os.name == 'nt' + # We test if the WinAPI works, because even if we are on Windows + # we may be using a terminal that doesn't support the WinAPI + # (e.g. Cygwin Terminal). In this case it's up to the terminal + # to support the ANSI codes. + conversion_supported = on_windows and winapi_test() + + # should we strip ANSI sequences from our output? + if strip is None: + strip = conversion_supported or (not is_stream_closed(wrapped) and not is_a_tty(wrapped)) + self.strip = strip + + # should we should convert ANSI sequences into win32 calls? + if convert is None: + convert = conversion_supported and not is_stream_closed(wrapped) and is_a_tty(wrapped) + self.convert = convert + + # dict of ansi codes to win32 functions and parameters + self.win32_calls = self.get_win32_calls() + + # are we wrapping stderr? + self.on_stderr = self.wrapped is sys.stderr + + def should_wrap(self): + ''' + True if this class is actually needed. If false, then the output + stream will not be affected, nor will win32 calls be issued, so + wrapping stdout is not actually required. This will generally be + False on non-Windows platforms, unless optional functionality like + autoreset has been requested using kwargs to init() + ''' + return self.convert or self.strip or self.autoreset + + def get_win32_calls(self): + if self.convert and winterm: + return { + AnsiStyle.RESET_ALL: (winterm.reset_all, ), + AnsiStyle.BRIGHT: (winterm.style, WinStyle.BRIGHT), + AnsiStyle.DIM: (winterm.style, WinStyle.NORMAL), + AnsiStyle.NORMAL: (winterm.style, WinStyle.NORMAL), + AnsiFore.BLACK: (winterm.fore, WinColor.BLACK), + AnsiFore.RED: (winterm.fore, WinColor.RED), + AnsiFore.GREEN: (winterm.fore, WinColor.GREEN), + AnsiFore.YELLOW: (winterm.fore, WinColor.YELLOW), + AnsiFore.BLUE: (winterm.fore, WinColor.BLUE), + AnsiFore.MAGENTA: (winterm.fore, WinColor.MAGENTA), + AnsiFore.CYAN: (winterm.fore, WinColor.CYAN), + AnsiFore.WHITE: (winterm.fore, WinColor.GREY), + AnsiFore.RESET: (winterm.fore, ), + AnsiFore.LIGHTBLACK_EX: (winterm.fore, WinColor.BLACK, True), + AnsiFore.LIGHTRED_EX: (winterm.fore, WinColor.RED, True), + AnsiFore.LIGHTGREEN_EX: (winterm.fore, WinColor.GREEN, True), + AnsiFore.LIGHTYELLOW_EX: (winterm.fore, WinColor.YELLOW, True), + AnsiFore.LIGHTBLUE_EX: (winterm.fore, WinColor.BLUE, True), + AnsiFore.LIGHTMAGENTA_EX: (winterm.fore, WinColor.MAGENTA, True), + AnsiFore.LIGHTCYAN_EX: (winterm.fore, WinColor.CYAN, True), + AnsiFore.LIGHTWHITE_EX: (winterm.fore, WinColor.GREY, True), + AnsiBack.BLACK: (winterm.back, WinColor.BLACK), + AnsiBack.RED: (winterm.back, WinColor.RED), + AnsiBack.GREEN: (winterm.back, WinColor.GREEN), + AnsiBack.YELLOW: (winterm.back, WinColor.YELLOW), + AnsiBack.BLUE: (winterm.back, WinColor.BLUE), + AnsiBack.MAGENTA: (winterm.back, WinColor.MAGENTA), + AnsiBack.CYAN: (winterm.back, WinColor.CYAN), + AnsiBack.WHITE: (winterm.back, WinColor.GREY), + AnsiBack.RESET: (winterm.back, ), + AnsiBack.LIGHTBLACK_EX: (winterm.back, WinColor.BLACK, True), + AnsiBack.LIGHTRED_EX: (winterm.back, WinColor.RED, True), + AnsiBack.LIGHTGREEN_EX: (winterm.back, WinColor.GREEN, True), + AnsiBack.LIGHTYELLOW_EX: (winterm.back, WinColor.YELLOW, True), + AnsiBack.LIGHTBLUE_EX: (winterm.back, WinColor.BLUE, True), + AnsiBack.LIGHTMAGENTA_EX: (winterm.back, WinColor.MAGENTA, True), + AnsiBack.LIGHTCYAN_EX: (winterm.back, WinColor.CYAN, True), + AnsiBack.LIGHTWHITE_EX: (winterm.back, WinColor.GREY, True), + } + return dict() + + def write(self, text): + if self.strip or self.convert: + self.write_and_convert(text) + else: + self.wrapped.write(text) + self.wrapped.flush() + if self.autoreset: + self.reset_all() + + + def reset_all(self): + if self.convert: + self.call_win32('m', (0,)) + elif not self.strip and not is_stream_closed(self.wrapped): + self.wrapped.write(Style.RESET_ALL) + + + def write_and_convert(self, text): + ''' + Write the given text to our wrapped stream, stripping any ANSI + sequences from the text, and optionally converting them into win32 + calls. + ''' + cursor = 0 + text = self.convert_osc(text) + for match in self.ANSI_CSI_RE.finditer(text): + start, end = match.span() + self.write_plain_text(text, cursor, start) + self.convert_ansi(*match.groups()) + cursor = end + self.write_plain_text(text, cursor, len(text)) + + + def write_plain_text(self, text, start, end): + if start < end: + self.wrapped.write(text[start:end]) + self.wrapped.flush() + + + def convert_ansi(self, paramstring, command): + if self.convert: + params = self.extract_params(command, paramstring) + self.call_win32(command, params) + + + def extract_params(self, command, paramstring): + if command in 'Hf': + params = tuple(int(p) if len(p) != 0 else 1 for p in paramstring.split(';')) + while len(params) < 2: + # defaults: + params = params + (1,) + else: + params = tuple(int(p) for p in paramstring.split(';') if len(p) != 0) + if len(params) == 0: + # defaults: + if command in 'JKm': + params = (0,) + elif command in 'ABCD': + params = (1,) + + return params + + + def call_win32(self, command, params): + if command == 'm': + for param in params: + if param in self.win32_calls: + func_args = self.win32_calls[param] + func = func_args[0] + args = func_args[1:] + kwargs = dict(on_stderr=self.on_stderr) + func(*args, **kwargs) + elif command in 'J': + winterm.erase_screen(params[0], on_stderr=self.on_stderr) + elif command in 'K': + winterm.erase_line(params[0], on_stderr=self.on_stderr) + elif command in 'Hf': # cursor position - absolute + winterm.set_cursor_position(params, on_stderr=self.on_stderr) + elif command in 'ABCD': # cursor position - relative + n = params[0] + # A - up, B - down, C - forward, D - back + x, y = {'A': (0, -n), 'B': (0, n), 'C': (n, 0), 'D': (-n, 0)}[command] + winterm.cursor_adjust(x, y, on_stderr=self.on_stderr) + + + def convert_osc(self, text): + for match in self.ANSI_OSC_RE.finditer(text): + start, end = match.span() + text = text[:start] + text[end:] + paramstring, command = match.groups() + if command in '\x07': # \x07 = BEL + params = paramstring.split(";") + # 0 - change title and icon (we will only change title) + # 1 - change icon (we don't support this) + # 2 - change title + if params[0] in '02': + winterm.set_title(params[1]) + return text diff --git a/rplibs/colorama/initialise.py b/rplibs/colorama/initialise.py new file mode 100644 index 0000000..834962a --- /dev/null +++ b/rplibs/colorama/initialise.py @@ -0,0 +1,82 @@ +# Copyright Jonathan Hartley 2013. BSD 3-Clause license, see LICENSE file. +import atexit +import contextlib +import sys + +from .ansitowin32 import AnsiToWin32 + + +orig_stdout = None +orig_stderr = None + +wrapped_stdout = None +wrapped_stderr = None + +atexit_done = False + + +def reset_all(): + if AnsiToWin32 is not None: # Issue #74: objects might become None at exit + AnsiToWin32(orig_stdout).reset_all() + + +def init(autoreset=False, convert=None, strip=None, wrap=True): + + if not wrap and any([autoreset, convert, strip]): + raise ValueError('wrap=False conflicts with any other arg=True') + + global wrapped_stdout, wrapped_stderr + global orig_stdout, orig_stderr + + orig_stdout = sys.stdout + orig_stderr = sys.stderr + + if sys.stdout is None: + wrapped_stdout = None + else: + sys.stdout = wrapped_stdout = \ + wrap_stream(orig_stdout, convert, strip, autoreset, wrap) + if sys.stderr is None: + wrapped_stderr = None + else: + sys.stderr = wrapped_stderr = \ + wrap_stream(orig_stderr, convert, strip, autoreset, wrap) + + global atexit_done + if not atexit_done: + atexit.register(reset_all) + atexit_done = True + + +def deinit(): + if orig_stdout is not None: + sys.stdout = orig_stdout + if orig_stderr is not None: + sys.stderr = orig_stderr + + +@contextlib.contextmanager +def colorama_text(*args, **kwargs): + init(*args, **kwargs) + try: + yield + finally: + deinit() + + +def reinit(): + if wrapped_stdout is not None: + sys.stdout = wrapped_stdout + if wrapped_stderr is not None: + sys.stderr = wrapped_stderr + + +def wrap_stream(stream, convert, strip, autoreset, wrap): + if wrap: + wrapper = AnsiToWin32(stream, + convert=convert, strip=strip, autoreset=autoreset) + if wrapper.should_wrap(): + stream = wrapper.stream + return stream + + diff --git a/rplibs/colorama/win32.py b/rplibs/colorama/win32.py new file mode 100644 index 0000000..3d1d2f2 --- /dev/null +++ b/rplibs/colorama/win32.py @@ -0,0 +1,154 @@ +# Copyright Jonathan Hartley 2013. BSD 3-Clause license, see LICENSE file. + +# from winbase.h +STDOUT = -11 +STDERR = -12 + +try: + import ctypes + from ctypes import LibraryLoader + windll = LibraryLoader(ctypes.WinDLL) + from ctypes import wintypes +except (AttributeError, ImportError): + windll = None + SetConsoleTextAttribute = lambda *_: None + winapi_test = lambda *_: None +else: + from ctypes import byref, Structure, c_char, POINTER + + COORD = wintypes._COORD + + class CONSOLE_SCREEN_BUFFER_INFO(Structure): + """struct in wincon.h.""" + _fields_ = [ + ("dwSize", COORD), + ("dwCursorPosition", COORD), + ("wAttributes", wintypes.WORD), + ("srWindow", wintypes.SMALL_RECT), + ("dwMaximumWindowSize", COORD), + ] + def __str__(self): + return '(%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d)' % ( + self.dwSize.Y, self.dwSize.X + , self.dwCursorPosition.Y, self.dwCursorPosition.X + , self.wAttributes + , self.srWindow.Top, self.srWindow.Left, self.srWindow.Bottom, self.srWindow.Right + , self.dwMaximumWindowSize.Y, self.dwMaximumWindowSize.X + ) + + _GetStdHandle = windll.kernel32.GetStdHandle + _GetStdHandle.argtypes = [ + wintypes.DWORD, + ] + _GetStdHandle.restype = wintypes.HANDLE + + _GetConsoleScreenBufferInfo = windll.kernel32.GetConsoleScreenBufferInfo + _GetConsoleScreenBufferInfo.argtypes = [ + wintypes.HANDLE, + POINTER(CONSOLE_SCREEN_BUFFER_INFO), + ] + _GetConsoleScreenBufferInfo.restype = wintypes.BOOL + + _SetConsoleTextAttribute = windll.kernel32.SetConsoleTextAttribute + _SetConsoleTextAttribute.argtypes = [ + wintypes.HANDLE, + wintypes.WORD, + ] + _SetConsoleTextAttribute.restype = wintypes.BOOL + + _SetConsoleCursorPosition = windll.kernel32.SetConsoleCursorPosition + _SetConsoleCursorPosition.argtypes = [ + wintypes.HANDLE, + COORD, + ] + _SetConsoleCursorPosition.restype = wintypes.BOOL + + _FillConsoleOutputCharacterA = windll.kernel32.FillConsoleOutputCharacterA + _FillConsoleOutputCharacterA.argtypes = [ + wintypes.HANDLE, + c_char, + wintypes.DWORD, + COORD, + POINTER(wintypes.DWORD), + ] + _FillConsoleOutputCharacterA.restype = wintypes.BOOL + + _FillConsoleOutputAttribute = windll.kernel32.FillConsoleOutputAttribute + _FillConsoleOutputAttribute.argtypes = [ + wintypes.HANDLE, + wintypes.WORD, + wintypes.DWORD, + COORD, + POINTER(wintypes.DWORD), + ] + _FillConsoleOutputAttribute.restype = wintypes.BOOL + + _SetConsoleTitleW = windll.kernel32.SetConsoleTitleA + _SetConsoleTitleW.argtypes = [ + wintypes.LPCSTR + ] + _SetConsoleTitleW.restype = wintypes.BOOL + + handles = { + STDOUT: _GetStdHandle(STDOUT), + STDERR: _GetStdHandle(STDERR), + } + + def winapi_test(): + handle = handles[STDOUT] + csbi = CONSOLE_SCREEN_BUFFER_INFO() + success = _GetConsoleScreenBufferInfo( + handle, byref(csbi)) + return bool(success) + + def GetConsoleScreenBufferInfo(stream_id=STDOUT): + handle = handles[stream_id] + csbi = CONSOLE_SCREEN_BUFFER_INFO() + success = _GetConsoleScreenBufferInfo( + handle, byref(csbi)) + return csbi + + def SetConsoleTextAttribute(stream_id, attrs): + handle = handles[stream_id] + return _SetConsoleTextAttribute(handle, attrs) + + def SetConsoleCursorPosition(stream_id, position, adjust=True): + position = COORD(*position) + # If the position is out of range, do nothing. + if position.Y <= 0 or position.X <= 0: + return + # Adjust for Windows' SetConsoleCursorPosition: + # 1. being 0-based, while ANSI is 1-based. + # 2. expecting (x,y), while ANSI uses (y,x). + adjusted_position = COORD(position.Y - 1, position.X - 1) + if adjust: + # Adjust for viewport's scroll position + sr = GetConsoleScreenBufferInfo(STDOUT).srWindow + adjusted_position.Y += sr.Top + adjusted_position.X += sr.Left + # Resume normal processing + handle = handles[stream_id] + return _SetConsoleCursorPosition(handle, adjusted_position) + + def FillConsoleOutputCharacter(stream_id, char, length, start): + handle = handles[stream_id] + char = c_char(char.encode()) + length = wintypes.DWORD(length) + num_written = wintypes.DWORD(0) + # Note that this is hard-coded for ANSI (vs wide) bytes. + success = _FillConsoleOutputCharacterA( + handle, char, length, start, byref(num_written)) + return num_written.value + + def FillConsoleOutputAttribute(stream_id, attr, length, start): + ''' FillConsoleOutputAttribute( hConsole, csbi.wAttributes, dwConSize, coordScreen, &cCharsWritten )''' + handle = handles[stream_id] + attribute = wintypes.WORD(attr) + length = wintypes.DWORD(length) + num_written = wintypes.DWORD(0) + # Note that this is hard-coded for ANSI (vs wide) bytes. + return _FillConsoleOutputAttribute( + handle, attribute, length, start, byref(num_written)) + + def SetConsoleTitle(title): + return _SetConsoleTitleW(title) diff --git a/rplibs/colorama/winterm.py b/rplibs/colorama/winterm.py new file mode 100644 index 0000000..60309d3 --- /dev/null +++ b/rplibs/colorama/winterm.py @@ -0,0 +1,162 @@ +# Copyright Jonathan Hartley 2013. BSD 3-Clause license, see LICENSE file. +from . import win32 + + +# from wincon.h +class WinColor(object): + BLACK = 0 + BLUE = 1 + GREEN = 2 + CYAN = 3 + RED = 4 + MAGENTA = 5 + YELLOW = 6 + GREY = 7 + +# from wincon.h +class WinStyle(object): + NORMAL = 0x00 # dim text, dim background + BRIGHT = 0x08 # bright text, dim background + BRIGHT_BACKGROUND = 0x80 # dim text, bright background + +class WinTerm(object): + + def __init__(self): + self._default = win32.GetConsoleScreenBufferInfo(win32.STDOUT).wAttributes + self.set_attrs(self._default) + self._default_fore = self._fore + self._default_back = self._back + self._default_style = self._style + # In order to emulate LIGHT_EX in windows, we borrow the BRIGHT style. + # So that LIGHT_EX colors and BRIGHT style do not clobber each other, + # we track them separately, since LIGHT_EX is overwritten by Fore/Back + # and BRIGHT is overwritten by Style codes. + self._light = 0 + + def get_attrs(self): + return self._fore + self._back * 16 + (self._style | self._light) + + def set_attrs(self, value): + self._fore = value & 7 + self._back = (value >> 4) & 7 + self._style = value & (WinStyle.BRIGHT | WinStyle.BRIGHT_BACKGROUND) + + def reset_all(self, on_stderr=None): + self.set_attrs(self._default) + self.set_console(attrs=self._default) + + def fore(self, fore=None, light=False, on_stderr=False): + if fore is None: + fore = self._default_fore + self._fore = fore + # Emulate LIGHT_EX with BRIGHT Style + if light: + self._light |= WinStyle.BRIGHT + else: + self._light &= ~WinStyle.BRIGHT + self.set_console(on_stderr=on_stderr) + + def back(self, back=None, light=False, on_stderr=False): + if back is None: + back = self._default_back + self._back = back + # Emulate LIGHT_EX with BRIGHT_BACKGROUND Style + if light: + self._light |= WinStyle.BRIGHT_BACKGROUND + else: + self._light &= ~WinStyle.BRIGHT_BACKGROUND + self.set_console(on_stderr=on_stderr) + + def style(self, style=None, on_stderr=False): + if style is None: + style = self._default_style + self._style = style + self.set_console(on_stderr=on_stderr) + + def set_console(self, attrs=None, on_stderr=False): + if attrs is None: + attrs = self.get_attrs() + handle = win32.STDOUT + if on_stderr: + handle = win32.STDERR + win32.SetConsoleTextAttribute(handle, attrs) + + def get_position(self, handle): + position = win32.GetConsoleScreenBufferInfo(handle).dwCursorPosition + # Because Windows coordinates are 0-based, + # and win32.SetConsoleCursorPosition expects 1-based. + position.X += 1 + position.Y += 1 + return position + + def set_cursor_position(self, position=None, on_stderr=False): + if position is None: + # I'm not currently tracking the position, so there is no default. + # position = self.get_position() + return + handle = win32.STDOUT + if on_stderr: + handle = win32.STDERR + win32.SetConsoleCursorPosition(handle, position) + + def cursor_adjust(self, x, y, on_stderr=False): + handle = win32.STDOUT + if on_stderr: + handle = win32.STDERR + position = self.get_position(handle) + adjusted_position = (position.Y + y, position.X + x) + win32.SetConsoleCursorPosition(handle, adjusted_position, adjust=False) + + def erase_screen(self, mode=0, on_stderr=False): + # 0 should clear from the cursor to the end of the screen. + # 1 should clear from the cursor to the beginning of the screen. + # 2 should clear the entire screen, and move cursor to (1,1) + handle = win32.STDOUT + if on_stderr: + handle = win32.STDERR + csbi = win32.GetConsoleScreenBufferInfo(handle) + # get the number of character cells in the current buffer + cells_in_screen = csbi.dwSize.X * csbi.dwSize.Y + # get number of character cells before current cursor position + cells_before_cursor = csbi.dwSize.X * csbi.dwCursorPosition.Y + csbi.dwCursorPosition.X + if mode == 0: + from_coord = csbi.dwCursorPosition + cells_to_erase = cells_in_screen - cells_before_cursor + if mode == 1: + from_coord = win32.COORD(0, 0) + cells_to_erase = cells_before_cursor + elif mode == 2: + from_coord = win32.COORD(0, 0) + cells_to_erase = cells_in_screen + # fill the entire screen with blanks + win32.FillConsoleOutputCharacter(handle, ' ', cells_to_erase, from_coord) + # now set the buffer's attributes accordingly + win32.FillConsoleOutputAttribute(handle, self.get_attrs(), cells_to_erase, from_coord) + if mode == 2: + # put the cursor where needed + win32.SetConsoleCursorPosition(handle, (1, 1)) + + def erase_line(self, mode=0, on_stderr=False): + # 0 should clear from the cursor to the end of the line. + # 1 should clear from the cursor to the beginning of the line. + # 2 should clear the entire line. + handle = win32.STDOUT + if on_stderr: + handle = win32.STDERR + csbi = win32.GetConsoleScreenBufferInfo(handle) + if mode == 0: + from_coord = csbi.dwCursorPosition + cells_to_erase = csbi.dwSize.X - csbi.dwCursorPosition.X + if mode == 1: + from_coord = win32.COORD(0, csbi.dwCursorPosition.Y) + cells_to_erase = csbi.dwCursorPosition.X + elif mode == 2: + from_coord = win32.COORD(0, csbi.dwCursorPosition.Y) + cells_to_erase = csbi.dwSize.X + # fill the entire screen with blanks + win32.FillConsoleOutputCharacter(handle, ' ', cells_to_erase, from_coord) + # now set the buffer's attributes accordingly + win32.FillConsoleOutputAttribute(handle, self.get_attrs(), cells_to_erase, from_coord) + + def set_title(self, title): + win32.SetConsoleTitle(title) diff --git a/rplibs/progressbar/LICENSE.txt b/rplibs/progressbar/LICENSE.txt new file mode 100644 index 0000000..fc8ccdc --- /dev/null +++ b/rplibs/progressbar/LICENSE.txt @@ -0,0 +1,52 @@ +You can redistribute and/or modify this library under the terms of the +GNU LGPL license or BSD license (or both). + +--- + +progressbar - Text progress bar library for python. +Copyright (C) 2005 Nilton Volpato + +This library is free software; you can redistribute it and/or +modify it under the terms of the GNU Lesser General Public +License as published by the Free Software Foundation; either +version 2.1 of the License, or (at your option) any later version. + +This library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Lesser General Public License for more details. + +You should have received a copy of the GNU Lesser General Public +License along with this library; if not, write to the Free Software +Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +--- + +progressbar - Text progress bar library for python +Copyright (c) 2008 Nilton Volpato + +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + + a. Redistributions of source code must retain the above copyright notice, + this list of conditions and the following disclaimer. + b. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + c. Neither the name of the author nor the names of its contributors + may be used to endorse or promote products derived from this software + without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR +ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR +SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER +CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY +OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH +DAMAGE. diff --git a/rplibs/progressbar/SOURCE.txt b/rplibs/progressbar/SOURCE.txt new file mode 100644 index 0000000..ee5034c --- /dev/null +++ b/rplibs/progressbar/SOURCE.txt @@ -0,0 +1,6 @@ +package: progressbar +version: 2.3 +downloaded: 07.04.2016 +url: https://pypi.python.org/pypi/progressbar + +!! MODIFIED __init__.py to use relative imports !! diff --git a/rplibs/progressbar/__init__.py b/rplibs/progressbar/__init__.py new file mode 100644 index 0000000..7033879 --- /dev/null +++ b/rplibs/progressbar/__init__.py @@ -0,0 +1,323 @@ +#!/usr/bin/python +# -*- coding: utf-8 -*- +# +# progressbar - Text progress bar library for Python. +# Copyright (c) 2005 Nilton Volpato +# +# This library is free software; you can redistribute it and/or +# modify it under the terms of the GNU Lesser General Public +# License as published by the Free Software Foundation; either +# version 2.1 of the License, or (at your option) any later version. +# +# This library is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# Lesser General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public +# License along with this library; if not, write to the Free Software +# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + + +'''Text progress bar library for Python. + +A text progress bar is typically used to display the progress of a long +running operation, providing a visual cue that processing is underway. + +The ProgressBar class manages the current progress, and the format of the line +is given by a number of widgets. A widget is an object that may display +differently depending on the state of the progress bar. There are three types +of widgets: + - a string, which always shows itself + + - a ProgressBarWidget, which may return a different value every time its + update method is called + + - a ProgressBarWidgetHFill, which is like ProgressBarWidget, except it + expands to fill the remaining width of the line. + +The progressbar module is very easy to use, yet very powerful. It will also +automatically enable features like auto-resizing when the system supports it. +''' + +from __future__ import division + +import math +import os +import signal +import sys +import time + +try: + from fcntl import ioctl + from array import array + import termios +except ImportError: + pass + +from .compat import * +from .widgets import * + + +__author__ = 'Nilton Volpato' +__author_email__ = 'first-name dot last-name @ gmail.com' +__date__ = '2011-05-14' +__version__ = '2.3' + + +class UnknownLength: pass + + +class ProgressBar(object): + '''The ProgressBar class which updates and prints the bar. + + A common way of using it is like: + >>> pbar = ProgressBar().start() + >>> for i in range(100): + ... # do something + ... pbar.update(i+1) + ... + >>> pbar.finish() + + You can also use a ProgressBar as an iterator: + >>> progress = ProgressBar() + >>> for i in progress(some_iterable): + ... # do something + ... + + Since the progress bar is incredibly customizable you can specify + different widgets of any type in any order. You can even write your own + widgets! However, since there are already a good number of widgets you + should probably play around with them before moving on to create your own + widgets. + + The term_width parameter represents the current terminal width. If the + parameter is set to an integer then the progress bar will use that, + otherwise it will attempt to determine the terminal width falling back to + 80 columns if the width cannot be determined. + + When implementing a widget's update method you are passed a reference to + the current progress bar. As a result, you have access to the + ProgressBar's methods and attributes. Although there is nothing preventing + you from changing the ProgressBar you should treat it as read only. + + Useful methods and attributes include (Public API): + - currval: current progress (0 <= currval <= maxval) + - maxval: maximum (and final) value + - finished: True if the bar has finished (reached 100%) + - start_time: the time when start() method of ProgressBar was called + - seconds_elapsed: seconds elapsed since start_time and last call to + update + - percentage(): progress in percent [0..100] + ''' + + __slots__ = ('currval', 'fd', 'finished', 'last_update_time', + 'left_justify', 'maxval', 'next_update', 'num_intervals', + 'poll', 'seconds_elapsed', 'signal_set', 'start_time', + 'term_width', 'update_interval', 'widgets', '_time_sensitive', + '__iterable') + + _DEFAULT_MAXVAL = 100 + _DEFAULT_TERMSIZE = 80 + _DEFAULT_WIDGETS = [Percentage(), ' ', Bar()] + + def __init__(self, maxval=None, widgets=None, term_width=None, poll=1, + left_justify=True, fd=sys.stderr): + '''Initializes a progress bar with sane defaults''' + + # Don't share a reference with any other progress bars + if widgets is None: + widgets = list(self._DEFAULT_WIDGETS) + + self.maxval = maxval + self.widgets = widgets + self.fd = fd + self.left_justify = left_justify + + self.signal_set = False + if term_width is not None: + self.term_width = term_width + else: + try: + self._handle_resize() + signal.signal(signal.SIGWINCH, self._handle_resize) + self.signal_set = True + except (SystemExit, KeyboardInterrupt): raise + except: + self.term_width = self._env_size() + + self.__iterable = None + self._update_widgets() + self.currval = 0 + self.finished = False + self.last_update_time = None + self.poll = poll + self.seconds_elapsed = 0 + self.start_time = None + self.update_interval = 1 + + + def __call__(self, iterable): + 'Use a ProgressBar to iterate through an iterable' + + try: + self.maxval = len(iterable) + except: + if self.maxval is None: + self.maxval = UnknownLength + + self.__iterable = iter(iterable) + return self + + + def __iter__(self): + return self + + + def __next__(self): + try: + value = next(self.__iterable) + if self.start_time is None: self.start() + else: self.update(self.currval + 1) + return value + except StopIteration: + self.finish() + raise + + + # Create an alias so that Python 2.x won't complain about not being + # an iterator. + next = __next__ + + + def _env_size(self): + 'Tries to find the term_width from the environment.' + + return int(os.environ.get('COLUMNS', self._DEFAULT_TERMSIZE)) - 1 + + + def _handle_resize(self, signum=None, frame=None): + 'Tries to catch resize signals sent from the terminal.' + + h, w = array('h', ioctl(self.fd, termios.TIOCGWINSZ, '\0' * 8))[:2] + self.term_width = w + + + def percentage(self): + 'Returns the progress as a percentage.' + return self.currval * 100.0 / self.maxval + + percent = property(percentage) + + + def _format_widgets(self): + result = [] + expanding = [] + width = self.term_width + + for index, widget in enumerate(self.widgets): + if isinstance(widget, WidgetHFill): + result.append(widget) + expanding.insert(0, index) + else: + widget = format_updatable(widget, self) + result.append(widget) + width -= len(widget) + + count = len(expanding) + while count: + portion = max(int(math.ceil(width * 1. / count)), 0) + index = expanding.pop() + count -= 1 + + widget = result[index].update(self, portion) + width -= len(widget) + result[index] = widget + + return result + + + def _format_line(self): + 'Joins the widgets and justifies the line' + + widgets = ''.join(self._format_widgets()) + + if self.left_justify: return widgets.ljust(self.term_width) + else: return widgets.rjust(self.term_width) + + + def _need_update(self): + 'Returns whether the ProgressBar should redraw the line.' + if self.currval >= self.next_update or self.finished: return True + + delta = time.time() - self.last_update_time + return self._time_sensitive and delta > self.poll + + + def _update_widgets(self): + 'Checks all widgets for the time sensitive bit' + + self._time_sensitive = any(getattr(w, 'TIME_SENSITIVE', False) + for w in self.widgets) + + + def update(self, value=None): + 'Updates the ProgressBar to a new value.' + + if value is not None and value is not UnknownLength: + if (self.maxval is not UnknownLength + and not 0 <= value <= self.maxval): + + raise ValueError('Value out of range') + + self.currval = value + + + if not self._need_update(): return + if self.start_time is None: + raise RuntimeError('You must call "start" before calling "update"') + + now = time.time() + self.seconds_elapsed = now - self.start_time + self.next_update = self.currval + self.update_interval + self.fd.write(self._format_line() + '\r') + self.last_update_time = now + + + def start(self): + '''Starts measuring time, and prints the bar at 0%. + + It returns self so you can use it like this: + >>> pbar = ProgressBar().start() + >>> for i in range(100): + ... # do something + ... pbar.update(i+1) + ... + >>> pbar.finish() + ''' + + if self.maxval is None: + self.maxval = self._DEFAULT_MAXVAL + + self.num_intervals = max(100, self.term_width) + self.next_update = 0 + + if self.maxval is not UnknownLength: + if self.maxval < 0: raise ValueError('Value out of range') + self.update_interval = self.maxval / self.num_intervals + + + self.start_time = self.last_update_time = time.time() + self.update(0) + + return self + + + def finish(self): + 'Puts the ProgressBar bar in the finished state.' + + self.finished = True + self.update(self.maxval) + self.fd.write('\n') + if self.signal_set: + signal.signal(signal.SIGWINCH, signal.SIG_DFL) diff --git a/rplibs/progressbar/compat.py b/rplibs/progressbar/compat.py new file mode 100644 index 0000000..2514e7a --- /dev/null +++ b/rplibs/progressbar/compat.py @@ -0,0 +1,42 @@ +#!/usr/bin/python +# -*- coding: utf-8 -*- +# +# progressbar - Text progress bar library for Python. +# Copyright (c) 2005 Nilton Volpato +# +# This library is free software; you can redistribute it and/or +# modify it under the terms of the GNU Lesser General Public +# License as published by the Free Software Foundation; either +# version 2.1 of the License, or (at your option) any later version. +# +# This library is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# Lesser General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public +# License along with this library; if not, write to the Free Software +# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +'''Compatability methods and classes for the progressbar module''' + + +# Python 3.x (and backports) use a modified iterator syntax +# This will allow 2.x to behave with 3.x iterators +if not hasattr(__builtins__, 'next'): + def next(iter): + try: + # Try new style iterators + return iter.__next__() + except AttributeError: + # Fallback in case of a "native" iterator + return iter.__next__() + + +# Python < 2.5 does not have "any" +if not hasattr(__builtins__, 'any'): + def any(iterator): + for item in iterator: + if item: return True + + return False diff --git a/rplibs/progressbar/widgets.py b/rplibs/progressbar/widgets.py new file mode 100644 index 0000000..f19713d --- /dev/null +++ b/rplibs/progressbar/widgets.py @@ -0,0 +1,311 @@ +#!/usr/bin/python +# -*- coding: utf-8 -*- +# +# progressbar - Text progress bar library for Python. +# Copyright (c) 2005 Nilton Volpato +# +# This library is free software; you can redistribute it and/or +# modify it under the terms of the GNU Lesser General Public +# License as published by the Free Software Foundation; either +# version 2.1 of the License, or (at your option) any later version. +# +# This library is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# Lesser General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public +# License along with this library; if not, write to the Free Software +# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +'''Default ProgressBar widgets''' + +from __future__ import division + +import datetime +import math + +try: + from abc import ABCMeta, abstractmethod +except ImportError: + AbstractWidget = object + abstractmethod = lambda fn: fn +else: + AbstractWidget = ABCMeta('AbstractWidget', (object,), {}) + + +def format_updatable(updatable, pbar): + if hasattr(updatable, 'update'): return updatable.update(pbar) + else: return updatable + + +class Widget(AbstractWidget): + '''The base class for all widgets + + The ProgressBar will call the widget's update value when the widget should + be updated. The widget's size may change between calls, but the widget may + display incorrectly if the size changes drastically and repeatedly. + + The boolean TIME_SENSITIVE informs the ProgressBar that it should be + updated more often because it is time sensitive. + ''' + + TIME_SENSITIVE = False + + @abstractmethod + def update(self, pbar): + '''Updates the widget. + + pbar - a reference to the calling ProgressBar + ''' + + +class WidgetHFill(Widget): + '''The base class for all variable width widgets. + + This widget is much like the \\hfill command in TeX, it will expand to + fill the line. You can use more than one in the same line, and they will + all have the same width, and together will fill the line. + ''' + + @abstractmethod + def update(self, pbar, width): + '''Updates the widget providing the total width the widget must fill. + + pbar - a reference to the calling ProgressBar + width - The total width the widget must fill + ''' + + +class Timer(Widget): + 'Widget which displays the elapsed seconds.' + + TIME_SENSITIVE = True + + def __init__(self, format='Elapsed Time: %s'): + self.format = format + + @staticmethod + def format_time(seconds): + 'Formats time as the string "HH:MM:SS".' + + return str(datetime.timedelta(seconds=int(seconds))) + + + def update(self, pbar): + 'Updates the widget to show the elapsed time.' + + return self.format % self.format_time(pbar.seconds_elapsed) + + +class ETA(Timer): + 'Widget which attempts to estimate the time of arrival.' + + TIME_SENSITIVE = True + + def update(self, pbar): + 'Updates the widget to show the ETA or total time when finished.' + + if pbar.currval == 0: + return 'ETA: --:--:--' + elif pbar.finished: + return 'Time: %s' % self.format_time(pbar.seconds_elapsed) + else: + elapsed = pbar.seconds_elapsed + eta = elapsed * pbar.maxval / pbar.currval - elapsed + return 'ETA: %s' % self.format_time(eta) + + +class FileTransferSpeed(Widget): + 'Widget for showing the transfer speed (useful for file transfers).' + + format = '%6.2f %s%s/s' + prefixes = ' kMGTPEZY' + + def __init__(self, unit='B'): + self.unit = unit + + def update(self, pbar): + 'Updates the widget with the current SI prefixed speed.' + + if pbar.seconds_elapsed < 2e-6 or pbar.currval < 2e-6: # =~ 0 + scaled = power = 0 + else: + speed = pbar.currval / pbar.seconds_elapsed + power = int(math.log(speed, 1000)) + scaled = speed / 1000.**power + + return self.format % (scaled, self.prefixes[power], self.unit) + +class Rate(Widget): + 'Widget for showing the rate of entries per second' + + def update(self, pbar): + 'Updates the widget with the current SI prefixed speed.' + + + if pbar.seconds_elapsed < 2e-6 or pbar.currval < 2e-6: # =~ 0 + return "Rate: 0 /s" + else: + speed = pbar.currval / pbar.seconds_elapsed + return "Rate: {:4d} /s".format(int(speed)) + + return self.format % (scaled, self.prefixes[power], self.unit) + + +class AnimatedMarker(Widget): + '''An animated marker for the progress bar which defaults to appear as if + it were rotating. + ''' + + def __init__(self, markers='|/-\\'): + self.markers = markers + self.curmark = -1 + + def update(self, pbar): + '''Updates the widget to show the next marker or the first marker when + finished''' + + if pbar.finished: return self.markers[0] + + self.curmark = (self.curmark + 1) % len(self.markers) + return self.markers[self.curmark] + +# Alias for backwards compatibility +RotatingMarker = AnimatedMarker + + +class Counter(Widget): + 'Displays the current count' + + def __init__(self, format='%d'): + self.format = format + + def update(self, pbar): + return self.format % pbar.currval + + +class Percentage(Widget): + 'Displays the current percentage as a number with a percent sign.' + + def update(self, pbar): + return '%3d%%' % pbar.percentage() + + +class FormatLabel(Timer): + 'Displays a formatted label' + + mapping = { + 'elapsed': ('seconds_elapsed', Timer.format_time), + 'finished': ('finished', None), + 'last_update': ('last_update_time', None), + 'max': ('maxval', None), + 'seconds': ('seconds_elapsed', None), + 'start': ('start_time', None), + 'value': ('currval', None) + } + + def __init__(self, format): + self.format = format + + def update(self, pbar): + context = {} + for name, (key, transform) in self.mapping.items(): + try: + value = getattr(pbar, key) + + if transform is None: + context[name] = value + else: + context[name] = transform(value) + except: pass + + return self.format % context + + +class SimpleProgress(Widget): + 'Returns progress as a count of the total (e.g.: "5 of 47")' + + def __init__(self, sep=' of '): + self.sep = sep + + def update(self, pbar): + return '%d%s%d' % (pbar.currval, self.sep, pbar.maxval) + + +class Bar(WidgetHFill): + 'A progress bar which stretches to fill the line.' + + def __init__(self, marker='#', left='|', right='|', fill=' ', + fill_left=True): + '''Creates a customizable progress bar. + + marker - string or updatable object to use as a marker + left - string or updatable object to use as a left border + right - string or updatable object to use as a right border + fill - character to use for the empty part of the progress bar + fill_left - whether to fill from the left or the right + ''' + self.marker = marker + self.left = left + self.right = right + self.fill = fill + self.fill_left = fill_left + + + def update(self, pbar, width): + 'Updates the progress bar and its subcomponents' + + left, marker, right = (format_updatable(i, pbar) for i in + (self.left, self.marker, self.right)) + + width -= len(left) + len(right) + # Marker must *always* have length of 1 + marker *= int(pbar.currval / pbar.maxval * width) + + if self.fill_left: + return '%s%s%s' % (left, marker.ljust(width, self.fill), right) + else: + return '%s%s%s' % (left, marker.rjust(width, self.fill), right) + + +class ReverseBar(Bar): + 'A bar which has a marker which bounces from side to side.' + + def __init__(self, marker='#', left='|', right='|', fill=' ', + fill_left=False): + '''Creates a customizable progress bar. + + marker - string or updatable object to use as a marker + left - string or updatable object to use as a left border + right - string or updatable object to use as a right border + fill - character to use for the empty part of the progress bar + fill_left - whether to fill from the left or the right + ''' + self.marker = marker + self.left = left + self.right = right + self.fill = fill + self.fill_left = fill_left + + +class BouncingBar(Bar): + def update(self, pbar, width): + 'Updates the progress bar and its subcomponents' + + left, marker, right = (format_updatable(i, pbar) for i in + (self.left, self.marker, self.right)) + + width -= len(left) + len(right) + + if pbar.finished: return '%s%s%s' % (left, width * marker, right) + + position = int(pbar.currval % (width * 2 - 1)) + if position > width: position = width * 2 - position + lpad = self.fill * (position - 1) + rpad = self.fill * (width - len(marker) - len(lpad)) + + # Swap if we want to bounce the other way + if not self.fill_left: rpad, lpad = lpad, rpad + + return '%s%s%s%s%s' % (left, lpad, marker, rpad, right) diff --git a/rplibs/pyqt_imports.py b/rplibs/pyqt_imports.py new file mode 100644 index 0000000..5903149 --- /dev/null +++ b/rplibs/pyqt_imports.py @@ -0,0 +1,62 @@ +""" + +Wrapper script to import all qt classes + +""" + +from __future__ import print_function +import sys + +PYQT_VERSION = 5 + +try: + import PyQt5 +except ImportError: + print("Could not import PyQt5, trying to import PyQt4") + try: + import PyQt4 + PYQT_VERSION = 4 + except ImportError: + print("Failed to import either PyQt4 or PyQt5!") + sys.exit(-1) + +if PYQT_VERSION == 4: + from PyQt4.QtGui import * + from PyQt4.QtCore import * + + def qt_connect(obj, signal_name, handler): + QObject.connect(obj, SIGNAL(signal_name), handler) + +elif PYQT_VERSION == 5: + from PyQt5.QtGui import * + from PyQt5.QtWidgets import * + from PyQt5.QtCore import * + + def qt_connect(obj, signal_name, handler): + if "(" in signal_name: + slot_name = signal_name[:signal_name.index("(")] + handler_type = signal_name[signal_name.index("(") + 1:].rstrip(")") + handler_type = str(handler_type.replace("*", "")).strip() + if not handler_type: + getattr(obj, slot_name).connect(handler) + else: + py_type = { + "int": int, + "QString": str, + "double": float, + "QListWidgetItem": QListWidgetItem + }[handler_type] + getattr(obj, slot_name)[py_type].connect(handler) + else: + getattr(obj, signal_name).connect(handler) + + +def qt_register_fonts(): + import os + this_dir = os.path.realpath(os.path.dirname(__file__)) + font_dir = os.path.join(this_dir, "..", "data", "font") + for f in os.listdir(font_dir): + if f.endswith(".ttf"): + fpath = os.path.relpath(os.path.join(font_dir, f)) + QFontDatabase.addApplicationFont(fpath) + diff --git a/rplibs/six-source.txt b/rplibs/six-source.txt new file mode 100644 index 0000000..b5c5c10 --- /dev/null +++ b/rplibs/six-source.txt @@ -0,0 +1,4 @@ +package: six +version: 1.10 +downloaded: 01-06-2016 +url: https://pypi.python.org/pypi/six diff --git a/rplibs/six.py b/rplibs/six.py new file mode 100644 index 0000000..190c023 --- /dev/null +++ b/rplibs/six.py @@ -0,0 +1,868 @@ +"""Utilities for writing code that runs on Python 2 and 3""" + +# Copyright (c) 2010-2015 Benjamin Peterson +# +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to deal +# in the Software without restriction, including without limitation the rights +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +# copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in all +# copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +# SOFTWARE. + +from __future__ import absolute_import + +import functools +import itertools +import operator +import sys +import types + +__author__ = "Benjamin Peterson " +__version__ = "1.10.0" + + +# Useful for very coarse version differentiation. +PY2 = sys.version_info[0] == 2 +PY3 = sys.version_info[0] == 3 +PY34 = sys.version_info[0:2] >= (3, 4) + +if PY3: + string_types = str, + integer_types = int, + class_types = type, + text_type = str + binary_type = bytes + + MAXSIZE = sys.maxsize +else: + string_types = basestring, + integer_types = (int, long) + class_types = (type, types.ClassType) + text_type = unicode + binary_type = str + + if sys.platform.startswith("java"): + # Jython always uses 32 bits. + MAXSIZE = int((1 << 31) - 1) + else: + # It's possible to have sizeof(long) != sizeof(Py_ssize_t). + class X(object): + + def __len__(self): + return 1 << 31 + try: + len(X()) + except OverflowError: + # 32-bit + MAXSIZE = int((1 << 31) - 1) + else: + # 64-bit + MAXSIZE = int((1 << 63) - 1) + del X + + +def _add_doc(func, doc): + """Add documentation to a function.""" + func.__doc__ = doc + + +def _import_module(name): + """Import module, returning the module after the last dot.""" + __import__(name) + return sys.modules[name] + + +class _LazyDescr(object): + + def __init__(self, name): + self.name = name + + def __get__(self, obj, tp): + result = self._resolve() + setattr(obj, self.name, result) # Invokes __set__. + try: + # This is a bit ugly, but it avoids running this again by + # removing this descriptor. + delattr(obj.__class__, self.name) + except AttributeError: + pass + return result + + +class MovedModule(_LazyDescr): + + def __init__(self, name, old, new=None): + super(MovedModule, self).__init__(name) + if PY3: + if new is None: + new = name + self.mod = new + else: + self.mod = old + + def _resolve(self): + return _import_module(self.mod) + + def __getattr__(self, attr): + _module = self._resolve() + value = getattr(_module, attr) + setattr(self, attr, value) + return value + + +class _LazyModule(types.ModuleType): + + def __init__(self, name): + super(_LazyModule, self).__init__(name) + self.__doc__ = self.__class__.__doc__ + + def __dir__(self): + attrs = ["__doc__", "__name__"] + attrs += [attr.name for attr in self._moved_attributes] + return attrs + + # Subclasses should override this + _moved_attributes = [] + + +class MovedAttribute(_LazyDescr): + + def __init__(self, name, old_mod, new_mod, old_attr=None, new_attr=None): + super(MovedAttribute, self).__init__(name) + if PY3: + if new_mod is None: + new_mod = name + self.mod = new_mod + if new_attr is None: + if old_attr is None: + new_attr = name + else: + new_attr = old_attr + self.attr = new_attr + else: + self.mod = old_mod + if old_attr is None: + old_attr = name + self.attr = old_attr + + def _resolve(self): + module = _import_module(self.mod) + return getattr(module, self.attr) + + +class _SixMetaPathImporter(object): + + """ + A meta path importer to import six.moves and its submodules. + + This class implements a PEP302 finder and loader. It should be compatible + with Python 2.5 and all existing versions of Python3 + """ + + def __init__(self, six_module_name): + self.name = six_module_name + self.known_modules = {} + + def _add_module(self, mod, *fullnames): + for fullname in fullnames: + self.known_modules[self.name + "." + fullname] = mod + + def _get_module(self, fullname): + return self.known_modules[self.name + "." + fullname] + + def find_module(self, fullname, path=None): + if fullname in self.known_modules: + return self + return None + + def __get_module(self, fullname): + try: + return self.known_modules[fullname] + except KeyError: + raise ImportError("This loader does not know module " + fullname) + + def load_module(self, fullname): + try: + # in case of a reload + return sys.modules[fullname] + except KeyError: + pass + mod = self.__get_module(fullname) + if isinstance(mod, MovedModule): + mod = mod._resolve() + else: + mod.__loader__ = self + sys.modules[fullname] = mod + return mod + + def is_package(self, fullname): + """ + Return true, if the named module is a package. + + We need this method to get correct spec objects with + Python 3.4 (see PEP451) + """ + return hasattr(self.__get_module(fullname), "__path__") + + def get_code(self, fullname): + """Return None + + Required, if is_package is implemented""" + self.__get_module(fullname) # eventually raises ImportError + return None + get_source = get_code # same as get_code + +_importer = _SixMetaPathImporter(__name__) + + +class _MovedItems(_LazyModule): + + """Lazy loading of moved objects""" + __path__ = [] # mark as package + + +_moved_attributes = [ + MovedAttribute("cStringIO", "cStringIO", "io", "StringIO"), + MovedAttribute("filter", "itertools", "builtins", "ifilter", "filter"), + MovedAttribute("filterfalse", "itertools", "itertools", "ifilterfalse", "filterfalse"), + MovedAttribute("input", "__builtin__", "builtins", "raw_input", "input"), + MovedAttribute("intern", "__builtin__", "sys"), + MovedAttribute("map", "itertools", "builtins", "imap", "map"), + MovedAttribute("getcwd", "os", "os", "getcwdu", "getcwd"), + MovedAttribute("getcwdb", "os", "os", "getcwd", "getcwdb"), + MovedAttribute("range", "__builtin__", "builtins", "xrange", "range"), + MovedAttribute("reload_module", "__builtin__", "importlib" if PY34 else "imp", "reload"), + MovedAttribute("reduce", "__builtin__", "functools"), + MovedAttribute("shlex_quote", "pipes", "shlex", "quote"), + MovedAttribute("StringIO", "StringIO", "io"), + MovedAttribute("UserDict", "UserDict", "collections"), + MovedAttribute("UserList", "UserList", "collections"), + MovedAttribute("UserString", "UserString", "collections"), + MovedAttribute("xrange", "__builtin__", "builtins", "xrange", "range"), + MovedAttribute("zip", "itertools", "builtins", "izip", "zip"), + MovedAttribute("zip_longest", "itertools", "itertools", "izip_longest", "zip_longest"), + MovedModule("builtins", "__builtin__"), + MovedModule("configparser", "ConfigParser"), + MovedModule("copyreg", "copy_reg"), + MovedModule("dbm_gnu", "gdbm", "dbm.gnu"), + MovedModule("_dummy_thread", "dummy_thread", "_dummy_thread"), + MovedModule("http_cookiejar", "cookielib", "http.cookiejar"), + MovedModule("http_cookies", "Cookie", "http.cookies"), + MovedModule("html_entities", "htmlentitydefs", "html.entities"), + MovedModule("html_parser", "HTMLParser", "html.parser"), + MovedModule("http_client", "httplib", "http.client"), + MovedModule("email_mime_multipart", "email.MIMEMultipart", "email.mime.multipart"), + MovedModule("email_mime_nonmultipart", "email.MIMENonMultipart", "email.mime.nonmultipart"), + MovedModule("email_mime_text", "email.MIMEText", "email.mime.text"), + MovedModule("email_mime_base", "email.MIMEBase", "email.mime.base"), + MovedModule("BaseHTTPServer", "BaseHTTPServer", "http.server"), + MovedModule("CGIHTTPServer", "CGIHTTPServer", "http.server"), + MovedModule("SimpleHTTPServer", "SimpleHTTPServer", "http.server"), + MovedModule("cPickle", "cPickle", "pickle"), + MovedModule("queue", "Queue"), + MovedModule("reprlib", "repr"), + MovedModule("socketserver", "SocketServer"), + MovedModule("_thread", "thread", "_thread"), + MovedModule("tkinter", "Tkinter"), + MovedModule("tkinter_dialog", "Dialog", "tkinter.dialog"), + MovedModule("tkinter_filedialog", "FileDialog", "tkinter.filedialog"), + MovedModule("tkinter_scrolledtext", "ScrolledText", "tkinter.scrolledtext"), + MovedModule("tkinter_simpledialog", "SimpleDialog", "tkinter.simpledialog"), + MovedModule("tkinter_tix", "Tix", "tkinter.tix"), + MovedModule("tkinter_ttk", "ttk", "tkinter.ttk"), + MovedModule("tkinter_constants", "Tkconstants", "tkinter.constants"), + MovedModule("tkinter_dnd", "Tkdnd", "tkinter.dnd"), + MovedModule("tkinter_colorchooser", "tkColorChooser", + "tkinter.colorchooser"), + MovedModule("tkinter_commondialog", "tkCommonDialog", + "tkinter.commondialog"), + MovedModule("tkinter_tkfiledialog", "tkFileDialog", "tkinter.filedialog"), + MovedModule("tkinter_font", "tkFont", "tkinter.font"), + MovedModule("tkinter_messagebox", "tkMessageBox", "tkinter.messagebox"), + MovedModule("tkinter_tksimpledialog", "tkSimpleDialog", + "tkinter.simpledialog"), + MovedModule("urllib_parse", __name__ + ".moves.urllib_parse", "urllib.parse"), + MovedModule("urllib_error", __name__ + ".moves.urllib_error", "urllib.error"), + MovedModule("urllib", __name__ + ".moves.urllib", __name__ + ".moves.urllib"), + MovedModule("urllib_robotparser", "robotparser", "urllib.robotparser"), + MovedModule("xmlrpc_client", "xmlrpclib", "xmlrpc.client"), + MovedModule("xmlrpc_server", "SimpleXMLRPCServer", "xmlrpc.server"), +] +# Add windows specific modules. +if sys.platform == "win32": + _moved_attributes += [ + MovedModule("winreg", "_winreg"), + ] + +for attr in _moved_attributes: + setattr(_MovedItems, attr.name, attr) + if isinstance(attr, MovedModule): + _importer._add_module(attr, "moves." + attr.name) +del attr + +_MovedItems._moved_attributes = _moved_attributes + +moves = _MovedItems(__name__ + ".moves") +_importer._add_module(moves, "moves") + + +class Module_six_moves_urllib_parse(_LazyModule): + + """Lazy loading of moved objects in six.moves.urllib_parse""" + + +_urllib_parse_moved_attributes = [ + MovedAttribute("ParseResult", "urlparse", "urllib.parse"), + MovedAttribute("SplitResult", "urlparse", "urllib.parse"), + MovedAttribute("parse_qs", "urlparse", "urllib.parse"), + MovedAttribute("parse_qsl", "urlparse", "urllib.parse"), + MovedAttribute("urldefrag", "urlparse", "urllib.parse"), + MovedAttribute("urljoin", "urlparse", "urllib.parse"), + MovedAttribute("urlparse", "urlparse", "urllib.parse"), + MovedAttribute("urlsplit", "urlparse", "urllib.parse"), + MovedAttribute("urlunparse", "urlparse", "urllib.parse"), + MovedAttribute("urlunsplit", "urlparse", "urllib.parse"), + MovedAttribute("quote", "urllib", "urllib.parse"), + MovedAttribute("quote_plus", "urllib", "urllib.parse"), + MovedAttribute("unquote", "urllib", "urllib.parse"), + MovedAttribute("unquote_plus", "urllib", "urllib.parse"), + MovedAttribute("urlencode", "urllib", "urllib.parse"), + MovedAttribute("splitquery", "urllib", "urllib.parse"), + MovedAttribute("splittag", "urllib", "urllib.parse"), + MovedAttribute("splituser", "urllib", "urllib.parse"), + MovedAttribute("uses_fragment", "urlparse", "urllib.parse"), + MovedAttribute("uses_netloc", "urlparse", "urllib.parse"), + MovedAttribute("uses_params", "urlparse", "urllib.parse"), + MovedAttribute("uses_query", "urlparse", "urllib.parse"), + MovedAttribute("uses_relative", "urlparse", "urllib.parse"), +] +for attr in _urllib_parse_moved_attributes: + setattr(Module_six_moves_urllib_parse, attr.name, attr) +del attr + +Module_six_moves_urllib_parse._moved_attributes = _urllib_parse_moved_attributes + +_importer._add_module(Module_six_moves_urllib_parse(__name__ + ".moves.urllib_parse"), + "moves.urllib_parse", "moves.urllib.parse") + + +class Module_six_moves_urllib_error(_LazyModule): + + """Lazy loading of moved objects in six.moves.urllib_error""" + + +_urllib_error_moved_attributes = [ + MovedAttribute("URLError", "urllib2", "urllib.error"), + MovedAttribute("HTTPError", "urllib2", "urllib.error"), + MovedAttribute("ContentTooShortError", "urllib", "urllib.error"), +] +for attr in _urllib_error_moved_attributes: + setattr(Module_six_moves_urllib_error, attr.name, attr) +del attr + +Module_six_moves_urllib_error._moved_attributes = _urllib_error_moved_attributes + +_importer._add_module(Module_six_moves_urllib_error(__name__ + ".moves.urllib.error"), + "moves.urllib_error", "moves.urllib.error") + + +class Module_six_moves_urllib_request(_LazyModule): + + """Lazy loading of moved objects in six.moves.urllib_request""" + + +_urllib_request_moved_attributes = [ + MovedAttribute("urlopen", "urllib2", "urllib.request"), + MovedAttribute("install_opener", "urllib2", "urllib.request"), + MovedAttribute("build_opener", "urllib2", "urllib.request"), + MovedAttribute("pathname2url", "urllib", "urllib.request"), + MovedAttribute("url2pathname", "urllib", "urllib.request"), + MovedAttribute("getproxies", "urllib", "urllib.request"), + MovedAttribute("Request", "urllib2", "urllib.request"), + MovedAttribute("OpenerDirector", "urllib2", "urllib.request"), + MovedAttribute("HTTPDefaultErrorHandler", "urllib2", "urllib.request"), + MovedAttribute("HTTPRedirectHandler", "urllib2", "urllib.request"), + MovedAttribute("HTTPCookieProcessor", "urllib2", "urllib.request"), + MovedAttribute("ProxyHandler", "urllib2", "urllib.request"), + MovedAttribute("BaseHandler", "urllib2", "urllib.request"), + MovedAttribute("HTTPPasswordMgr", "urllib2", "urllib.request"), + MovedAttribute("HTTPPasswordMgrWithDefaultRealm", "urllib2", "urllib.request"), + MovedAttribute("AbstractBasicAuthHandler", "urllib2", "urllib.request"), + MovedAttribute("HTTPBasicAuthHandler", "urllib2", "urllib.request"), + MovedAttribute("ProxyBasicAuthHandler", "urllib2", "urllib.request"), + MovedAttribute("AbstractDigestAuthHandler", "urllib2", "urllib.request"), + MovedAttribute("HTTPDigestAuthHandler", "urllib2", "urllib.request"), + MovedAttribute("ProxyDigestAuthHandler", "urllib2", "urllib.request"), + MovedAttribute("HTTPHandler", "urllib2", "urllib.request"), + MovedAttribute("HTTPSHandler", "urllib2", "urllib.request"), + MovedAttribute("FileHandler", "urllib2", "urllib.request"), + MovedAttribute("FTPHandler", "urllib2", "urllib.request"), + MovedAttribute("CacheFTPHandler", "urllib2", "urllib.request"), + MovedAttribute("UnknownHandler", "urllib2", "urllib.request"), + MovedAttribute("HTTPErrorProcessor", "urllib2", "urllib.request"), + MovedAttribute("urlretrieve", "urllib", "urllib.request"), + MovedAttribute("urlcleanup", "urllib", "urllib.request"), + MovedAttribute("URLopener", "urllib", "urllib.request"), + MovedAttribute("FancyURLopener", "urllib", "urllib.request"), + MovedAttribute("proxy_bypass", "urllib", "urllib.request"), +] +for attr in _urllib_request_moved_attributes: + setattr(Module_six_moves_urllib_request, attr.name, attr) +del attr + +Module_six_moves_urllib_request._moved_attributes = _urllib_request_moved_attributes + +_importer._add_module(Module_six_moves_urllib_request(__name__ + ".moves.urllib.request"), + "moves.urllib_request", "moves.urllib.request") + + +class Module_six_moves_urllib_response(_LazyModule): + + """Lazy loading of moved objects in six.moves.urllib_response""" + + +_urllib_response_moved_attributes = [ + MovedAttribute("addbase", "urllib", "urllib.response"), + MovedAttribute("addclosehook", "urllib", "urllib.response"), + MovedAttribute("addinfo", "urllib", "urllib.response"), + MovedAttribute("addinfourl", "urllib", "urllib.response"), +] +for attr in _urllib_response_moved_attributes: + setattr(Module_six_moves_urllib_response, attr.name, attr) +del attr + +Module_six_moves_urllib_response._moved_attributes = _urllib_response_moved_attributes + +_importer._add_module(Module_six_moves_urllib_response(__name__ + ".moves.urllib.response"), + "moves.urllib_response", "moves.urllib.response") + + +class Module_six_moves_urllib_robotparser(_LazyModule): + + """Lazy loading of moved objects in six.moves.urllib_robotparser""" + + +_urllib_robotparser_moved_attributes = [ + MovedAttribute("RobotFileParser", "robotparser", "urllib.robotparser"), +] +for attr in _urllib_robotparser_moved_attributes: + setattr(Module_six_moves_urllib_robotparser, attr.name, attr) +del attr + +Module_six_moves_urllib_robotparser._moved_attributes = _urllib_robotparser_moved_attributes + +_importer._add_module(Module_six_moves_urllib_robotparser(__name__ + ".moves.urllib.robotparser"), + "moves.urllib_robotparser", "moves.urllib.robotparser") + + +class Module_six_moves_urllib(types.ModuleType): + + """Create a six.moves.urllib namespace that resembles the Python 3 namespace""" + __path__ = [] # mark as package + parse = _importer._get_module("moves.urllib_parse") + error = _importer._get_module("moves.urllib_error") + request = _importer._get_module("moves.urllib_request") + response = _importer._get_module("moves.urllib_response") + robotparser = _importer._get_module("moves.urllib_robotparser") + + def __dir__(self): + return ['parse', 'error', 'request', 'response', 'robotparser'] + +_importer._add_module(Module_six_moves_urllib(__name__ + ".moves.urllib"), + "moves.urllib") + + +def add_move(move): + """Add an item to six.moves.""" + setattr(_MovedItems, move.name, move) + + +def remove_move(name): + """Remove item from six.moves.""" + try: + delattr(_MovedItems, name) + except AttributeError: + try: + del moves.__dict__[name] + except KeyError: + raise AttributeError("no such move, %r" % (name,)) + + +if PY3: + _meth_func = "__func__" + _meth_self = "__self__" + + _func_closure = "__closure__" + _func_code = "__code__" + _func_defaults = "__defaults__" + _func_globals = "__globals__" +else: + _meth_func = "im_func" + _meth_self = "im_self" + + _func_closure = "func_closure" + _func_code = "func_code" + _func_defaults = "func_defaults" + _func_globals = "func_globals" + + +try: + advance_iterator = next +except NameError: + def advance_iterator(it): + return it.next() +next = advance_iterator + + +try: + callable = callable +except NameError: + def callable(obj): + return any("__call__" in klass.__dict__ for klass in type(obj).__mro__) + + +if PY3: + def get_unbound_function(unbound): + return unbound + + create_bound_method = types.MethodType + + def create_unbound_method(func, cls): + return func + + Iterator = object +else: + def get_unbound_function(unbound): + return unbound.im_func + + def create_bound_method(func, obj): + return types.MethodType(func, obj, obj.__class__) + + def create_unbound_method(func, cls): + return types.MethodType(func, None, cls) + + class Iterator(object): + + def next(self): + return type(self).__next__(self) + + callable = callable +_add_doc(get_unbound_function, + """Get the function out of a possibly unbound function""") + + +get_method_function = operator.attrgetter(_meth_func) +get_method_self = operator.attrgetter(_meth_self) +get_function_closure = operator.attrgetter(_func_closure) +get_function_code = operator.attrgetter(_func_code) +get_function_defaults = operator.attrgetter(_func_defaults) +get_function_globals = operator.attrgetter(_func_globals) + + +if PY3: + def iterkeys(d, **kw): + return iter(d.keys(**kw)) + + def itervalues(d, **kw): + return iter(d.values(**kw)) + + def iteritems(d, **kw): + return iter(d.items(**kw)) + + def iterlists(d, **kw): + return iter(d.lists(**kw)) + + viewkeys = operator.methodcaller("keys") + + viewvalues = operator.methodcaller("values") + + viewitems = operator.methodcaller("items") +else: + def iterkeys(d, **kw): + return d.iterkeys(**kw) + + def itervalues(d, **kw): + return d.itervalues(**kw) + + def iteritems(d, **kw): + return d.iteritems(**kw) + + def iterlists(d, **kw): + return d.iterlists(**kw) + + viewkeys = operator.methodcaller("viewkeys") + + viewvalues = operator.methodcaller("viewvalues") + + viewitems = operator.methodcaller("viewitems") + +_add_doc(iterkeys, "Return an iterator over the keys of a dictionary.") +_add_doc(itervalues, "Return an iterator over the values of a dictionary.") +_add_doc(iteritems, + "Return an iterator over the (key, value) pairs of a dictionary.") +_add_doc(iterlists, + "Return an iterator over the (key, [values]) pairs of a dictionary.") + + +if PY3: + def b(s): + return s.encode("latin-1") + + def u(s): + return s + unichr = chr + import struct + int2byte = struct.Struct(">B").pack + del struct + byte2int = operator.itemgetter(0) + indexbytes = operator.getitem + iterbytes = iter + import io + StringIO = io.StringIO + BytesIO = io.BytesIO + _assertCountEqual = "assertCountEqual" + if sys.version_info[1] <= 1: + _assertRaisesRegex = "assertRaisesRegexp" + _assertRegex = "assertRegexpMatches" + else: + _assertRaisesRegex = "assertRaisesRegex" + _assertRegex = "assertRegex" +else: + def b(s): + return s + # Workaround for standalone backslash + + def u(s): + return unicode(s.replace(r'\\', r'\\\\'), "unicode_escape") + unichr = unichr + int2byte = chr + + def byte2int(bs): + return ord(bs[0]) + + def indexbytes(buf, i): + return ord(buf[i]) + iterbytes = functools.partial(itertools.imap, ord) + import StringIO + StringIO = BytesIO = StringIO.StringIO + _assertCountEqual = "assertItemsEqual" + _assertRaisesRegex = "assertRaisesRegexp" + _assertRegex = "assertRegexpMatches" +_add_doc(b, """Byte literal""") +_add_doc(u, """Text literal""") + + +def assertCountEqual(self, *args, **kwargs): + return getattr(self, _assertCountEqual)(*args, **kwargs) + + +def assertRaisesRegex(self, *args, **kwargs): + return getattr(self, _assertRaisesRegex)(*args, **kwargs) + + +def assertRegex(self, *args, **kwargs): + return getattr(self, _assertRegex)(*args, **kwargs) + + +if PY3: + exec_ = getattr(moves.builtins, "exec") + + def reraise(tp, value, tb=None): + if value is None: + value = tp() + if value.__traceback__ is not tb: + raise value.with_traceback(tb) + raise value + +else: + def exec_(_code_, _globs_=None, _locs_=None): + """Execute code in a namespace.""" + if _globs_ is None: + frame = sys._getframe(1) + _globs_ = frame.f_globals + if _locs_ is None: + _locs_ = frame.f_locals + del frame + elif _locs_ is None: + _locs_ = _globs_ + exec("""exec _code_ in _globs_, _locs_""") + + exec_("""def reraise(tp, value, tb=None): + raise tp, value, tb +""") + + +if sys.version_info[:2] == (3, 2): + exec_("""def raise_from(value, from_value): + if from_value is None: + raise value + raise value from from_value +""") +elif sys.version_info[:2] > (3, 2): + exec_("""def raise_from(value, from_value): + raise value from from_value +""") +else: + def raise_from(value, from_value): + raise value + + +print_ = getattr(moves.builtins, "print", None) +if print_ is None: + def print_(*args, **kwargs): + """The new-style print function for Python 2.4 and 2.5.""" + fp = kwargs.pop("file", sys.stdout) + if fp is None: + return + + def write(data): + if not isinstance(data, basestring): + data = str(data) + # If the file has an encoding, encode unicode with it. + if (isinstance(fp, file) and + isinstance(data, unicode) and + fp.encoding is not None): + errors = getattr(fp, "errors", None) + if errors is None: + errors = "strict" + data = data.encode(fp.encoding, errors) + fp.write(data) + want_unicode = False + sep = kwargs.pop("sep", None) + if sep is not None: + if isinstance(sep, unicode): + want_unicode = True + elif not isinstance(sep, str): + raise TypeError("sep must be None or a string") + end = kwargs.pop("end", None) + if end is not None: + if isinstance(end, unicode): + want_unicode = True + elif not isinstance(end, str): + raise TypeError("end must be None or a string") + if kwargs: + raise TypeError("invalid keyword arguments to print()") + if not want_unicode: + for arg in args: + if isinstance(arg, unicode): + want_unicode = True + break + if want_unicode: + newline = unicode("\n") + space = unicode(" ") + else: + newline = "\n" + space = " " + if sep is None: + sep = space + if end is None: + end = newline + for i, arg in enumerate(args): + if i: + write(sep) + write(arg) + write(end) +if sys.version_info[:2] < (3, 3): + _print = print_ + + def print_(*args, **kwargs): + fp = kwargs.get("file", sys.stdout) + flush = kwargs.pop("flush", False) + _print(*args, **kwargs) + if flush and fp is not None: + fp.flush() + +_add_doc(reraise, """Reraise an exception.""") + +if sys.version_info[0:2] < (3, 4): + def wraps(wrapped, assigned=functools.WRAPPER_ASSIGNMENTS, + updated=functools.WRAPPER_UPDATES): + def wrapper(f): + f = functools.wraps(wrapped, assigned, updated)(f) + f.__wrapped__ = wrapped + return f + return wrapper +else: + wraps = functools.wraps + + +def with_metaclass(meta, *bases): + """Create a base class with a metaclass.""" + # This requires a bit of explanation: the basic idea is to make a dummy + # metaclass for one level of class instantiation that replaces itself with + # the actual metaclass. + class metaclass(meta): + + def __new__(cls, name, this_bases, d): + return meta(name, bases, d) + return type.__new__(metaclass, 'temporary_class', (), {}) + + +def add_metaclass(metaclass): + """Class decorator for creating a class with a metaclass.""" + def wrapper(cls): + orig_vars = cls.__dict__.copy() + slots = orig_vars.get('__slots__') + if slots is not None: + if isinstance(slots, str): + slots = [slots] + for slots_var in slots: + orig_vars.pop(slots_var) + orig_vars.pop('__dict__', None) + orig_vars.pop('__weakref__', None) + return metaclass(cls.__name__, cls.__bases__, orig_vars) + return wrapper + + +def python_2_unicode_compatible(klass): + """ + A decorator that defines __unicode__ and __str__ methods under Python 2. + Under Python 3 it does nothing. + + To support Python 2 and 3 with a single code base, define a __str__ method + returning text and apply this decorator to the class. + """ + if PY2: + if '__str__' not in klass.__dict__: + raise ValueError("@python_2_unicode_compatible cannot be applied " + "to %s because it doesn't define __str__()." % + klass.__name__) + klass.__unicode__ = klass.__str__ + klass.__str__ = lambda self: self.__unicode__().encode('utf-8') + return klass + + +# Complete the moves implementation. +# This code is at the end of this module to speed up module loading. +# Turn this module into a package. +__path__ = [] # required for PEP 302 and PEP 451 +__package__ = __name__ # see PEP 366 @ReservedAssignment +if globals().get("__spec__") is not None: + __spec__.submodule_search_locations = [] # PEP 451 @UndefinedVariable +# Remove other six meta path importers, since they cause problems. This can +# happen if six is removed from sys.modules and then reloaded. (Setuptools does +# this for some reason.) +if sys.meta_path: + for i, importer in enumerate(sys.meta_path): + # Here's some real nastiness: Another "instance" of the six module might + # be floating around. Therefore, we can't use isinstance() to check for + # the six meta path importer, since the other six instance will have + # inserted an importer with different class. + if (type(importer).__name__ == "_SixMetaPathImporter" and + importer.name == __name__): + del sys.meta_path[i] + break + del i, importer +# Finally, add the importer to the meta path import hook. +sys.meta_path.append(_importer) diff --git a/rplibs/yaml/LICENSE b/rplibs/yaml/LICENSE new file mode 100644 index 0000000..050ced2 --- /dev/null +++ b/rplibs/yaml/LICENSE @@ -0,0 +1,19 @@ +Copyright (c) 2006 Kirill Simonov + +Permission is hereby granted, free of charge, to any person obtaining a copy of +this software and associated documentation files (the "Software"), to deal in +the Software without restriction, including without limitation the rights to +use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies +of the Software, and to permit persons to whom the Software is furnished to do +so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/rplibs/yaml/SOURCE.txt b/rplibs/yaml/SOURCE.txt new file mode 100644 index 0000000..7a119d7 --- /dev/null +++ b/rplibs/yaml/SOURCE.txt @@ -0,0 +1,4 @@ +package: PyYAML +version: 3.11 +downloaded: 12-23-2015 +url: https://pypi.python.org/pypi/PyYAML diff --git a/rplibs/yaml/__init__.py b/rplibs/yaml/__init__.py new file mode 100644 index 0000000..fec84a6 --- /dev/null +++ b/rplibs/yaml/__init__.py @@ -0,0 +1,62 @@ +""" + +Main PyYAML importer script. Provides functions to load YAML files as dictionaries. + +""" + +from __future__ import print_function + +import sys +import collections +from direct.stdpy.file import open +from rpcore.rpobject import RPObject + +# Import different PyYaml versions depending on the used python version +if sys.version_info < (3, 0): + from .yaml_py2 import load as yaml_load + from .yaml_py2 import YAMLError, SafeLoader +else: + from .yaml_py3 import load as yaml_load + from .yaml_py3 import YAMLError, SafeLoader + +__all__ = ["load_yaml_file", "load_yaml_file_flat"] + +def load_yaml_file(filename): + """ This method is a wrapper arround yaml_load, and provides error checking """ + + import time + start = time.process_time() + + try: + with open(filename, "r") as handle: + parsed_yaml = yaml_load(handle, Loader=SafeLoader) + except IOError as msg: + RPObject.global_error("YAMLLoader", "Could not find or open file:", filename) + RPObject.global_error("YAMLLoader", msg) + raise Exception("Failed to load YAML file: File not found") + except YAMLError as msg: + RPObject.global_error("YAMLLoader", "Invalid yaml-syntax in file:", filename) + RPObject.global_error("YAMLLoader", msg) + raise Exception("Failed to load YAML file: Invalid syntax") + + duration = (time.process_time() - start) * 1000.0 + + # Optionally print out profiling information + # print("Took", round(duration, 2), "ms to load", filename) + + return parsed_yaml + +def __flatten(d, parent_key=''): + """ Internal method to flatten a dictionary """ + items = [] + for k, v in d.items(): + try: + items.extend(__flatten(v, '{}{}.'.format(parent_key, k)).items()) + except AttributeError: + items.append(('{}{}'.format(parent_key, k), v)) + return dict(items) + +def load_yaml_file_flat(filename): + """ Behaves like load_yaml_file, but instead of creating nested dictionaries + it connects keys via '.' """ + return __flatten(load_yaml_file(filename)) diff --git a/rplibs/yaml/yaml_py2/__init__.py b/rplibs/yaml/yaml_py2/__init__.py new file mode 100644 index 0000000..76e19e1 --- /dev/null +++ b/rplibs/yaml/yaml_py2/__init__.py @@ -0,0 +1,315 @@ + +from error import * + +from tokens import * +from events import * +from nodes import * + +from loader import * +from dumper import * + +__version__ = '3.11' + +try: + from cyaml import * + __with_libyaml__ = True +except ImportError: + __with_libyaml__ = False + +def scan(stream, Loader=Loader): + """ + Scan a YAML stream and produce scanning tokens. + """ + loader = Loader(stream) + try: + while loader.check_token(): + yield loader.get_token() + finally: + loader.dispose() + +def parse(stream, Loader=Loader): + """ + Parse a YAML stream and produce parsing events. + """ + loader = Loader(stream) + try: + while loader.check_event(): + yield loader.get_event() + finally: + loader.dispose() + +def compose(stream, Loader=Loader): + """ + Parse the first YAML document in a stream + and produce the corresponding representation tree. + """ + loader = Loader(stream) + try: + return loader.get_single_node() + finally: + loader.dispose() + +def compose_all(stream, Loader=Loader): + """ + Parse all YAML documents in a stream + and produce corresponding representation trees. + """ + loader = Loader(stream) + try: + while loader.check_node(): + yield loader.get_node() + finally: + loader.dispose() + +def load(stream, Loader=Loader): + """ + Parse the first YAML document in a stream + and produce the corresponding Python object. + """ + loader = Loader(stream) + try: + return loader.get_single_data() + finally: + loader.dispose() + +def load_all(stream, Loader=Loader): + """ + Parse all YAML documents in a stream + and produce corresponding Python objects. + """ + loader = Loader(stream) + try: + while loader.check_data(): + yield loader.get_data() + finally: + loader.dispose() + +def safe_load(stream): + """ + Parse the first YAML document in a stream + and produce the corresponding Python object. + Resolve only basic YAML tags. + """ + return load(stream, SafeLoader) + +def safe_load_all(stream): + """ + Parse all YAML documents in a stream + and produce corresponding Python objects. + Resolve only basic YAML tags. + """ + return load_all(stream, SafeLoader) + +def emit(events, stream=None, Dumper=Dumper, + canonical=None, indent=None, width=None, + allow_unicode=None, line_break=None): + """ + Emit YAML parsing events into a stream. + If stream is None, return the produced string instead. + """ + getvalue = None + if stream is None: + from StringIO import StringIO + stream = StringIO() + getvalue = stream.getvalue + dumper = Dumper(stream, canonical=canonical, indent=indent, width=width, + allow_unicode=allow_unicode, line_break=line_break) + try: + for event in events: + dumper.emit(event) + finally: + dumper.dispose() + if getvalue: + return getvalue() + +def serialize_all(nodes, stream=None, Dumper=Dumper, + canonical=None, indent=None, width=None, + allow_unicode=None, line_break=None, + encoding='utf-8', explicit_start=None, explicit_end=None, + version=None, tags=None): + """ + Serialize a sequence of representation trees into a YAML stream. + If stream is None, return the produced string instead. + """ + getvalue = None + if stream is None: + if encoding is None: + from StringIO import StringIO + else: + from cStringIO import StringIO + stream = StringIO() + getvalue = stream.getvalue + dumper = Dumper(stream, canonical=canonical, indent=indent, width=width, + allow_unicode=allow_unicode, line_break=line_break, + encoding=encoding, version=version, tags=tags, + explicit_start=explicit_start, explicit_end=explicit_end) + try: + dumper.open() + for node in nodes: + dumper.serialize(node) + dumper.close() + finally: + dumper.dispose() + if getvalue: + return getvalue() + +def serialize(node, stream=None, Dumper=Dumper, **kwds): + """ + Serialize a representation tree into a YAML stream. + If stream is None, return the produced string instead. + """ + return serialize_all([node], stream, Dumper=Dumper, **kwds) + +def dump_all(documents, stream=None, Dumper=Dumper, + default_style=None, default_flow_style=None, + canonical=None, indent=None, width=None, + allow_unicode=None, line_break=None, + encoding='utf-8', explicit_start=None, explicit_end=None, + version=None, tags=None): + """ + Serialize a sequence of Python objects into a YAML stream. + If stream is None, return the produced string instead. + """ + getvalue = None + if stream is None: + if encoding is None: + from StringIO import StringIO + else: + from cStringIO import StringIO + stream = StringIO() + getvalue = stream.getvalue + dumper = Dumper(stream, default_style=default_style, + default_flow_style=default_flow_style, + canonical=canonical, indent=indent, width=width, + allow_unicode=allow_unicode, line_break=line_break, + encoding=encoding, version=version, tags=tags, + explicit_start=explicit_start, explicit_end=explicit_end) + try: + dumper.open() + for data in documents: + dumper.represent(data) + dumper.close() + finally: + dumper.dispose() + if getvalue: + return getvalue() + +def dump(data, stream=None, Dumper=Dumper, **kwds): + """ + Serialize a Python object into a YAML stream. + If stream is None, return the produced string instead. + """ + return dump_all([data], stream, Dumper=Dumper, **kwds) + +def safe_dump_all(documents, stream=None, **kwds): + """ + Serialize a sequence of Python objects into a YAML stream. + Produce only basic YAML tags. + If stream is None, return the produced string instead. + """ + return dump_all(documents, stream, Dumper=SafeDumper, **kwds) + +def safe_dump(data, stream=None, **kwds): + """ + Serialize a Python object into a YAML stream. + Produce only basic YAML tags. + If stream is None, return the produced string instead. + """ + return dump_all([data], stream, Dumper=SafeDumper, **kwds) + +def add_implicit_resolver(tag, regexp, first=None, + Loader=Loader, Dumper=Dumper): + """ + Add an implicit scalar detector. + If an implicit scalar value matches the given regexp, + the corresponding tag is assigned to the scalar. + first is a sequence of possible initial characters or None. + """ + Loader.add_implicit_resolver(tag, regexp, first) + Dumper.add_implicit_resolver(tag, regexp, first) + +def add_path_resolver(tag, path, kind=None, Loader=Loader, Dumper=Dumper): + """ + Add a path based resolver for the given tag. + A path is a list of keys that forms a path + to a node in the representation tree. + Keys can be string values, integers, or None. + """ + Loader.add_path_resolver(tag, path, kind) + Dumper.add_path_resolver(tag, path, kind) + +def add_constructor(tag, constructor, Loader=Loader): + """ + Add a constructor for the given tag. + Constructor is a function that accepts a Loader instance + and a node object and produces the corresponding Python object. + """ + Loader.add_constructor(tag, constructor) + +def add_multi_constructor(tag_prefix, multi_constructor, Loader=Loader): + """ + Add a multi-constructor for the given tag prefix. + Multi-constructor is called for a node if its tag starts with tag_prefix. + Multi-constructor accepts a Loader instance, a tag suffix, + and a node object and produces the corresponding Python object. + """ + Loader.add_multi_constructor(tag_prefix, multi_constructor) + +def add_representer(data_type, representer, Dumper=Dumper): + """ + Add a representer for the given type. + Representer is a function accepting a Dumper instance + and an instance of the given data type + and producing the corresponding representation node. + """ + Dumper.add_representer(data_type, representer) + +def add_multi_representer(data_type, multi_representer, Dumper=Dumper): + """ + Add a representer for the given type. + Multi-representer is a function accepting a Dumper instance + and an instance of the given data type or subtype + and producing the corresponding representation node. + """ + Dumper.add_multi_representer(data_type, multi_representer) + +class YAMLObjectMetaclass(type): + """ + The metaclass for YAMLObject. + """ + def __init__(cls, name, bases, kwds): + super(YAMLObjectMetaclass, cls).__init__(name, bases, kwds) + if 'yaml_tag' in kwds and kwds['yaml_tag'] is not None: + cls.yaml_loader.add_constructor(cls.yaml_tag, cls.from_yaml) + cls.yaml_dumper.add_representer(cls, cls.to_yaml) + +class YAMLObject(object): + """ + An object that can dump itself to a YAML stream + and load itself from a YAML stream. + """ + + __metaclass__ = YAMLObjectMetaclass + __slots__ = () # no direct instantiation, so allow immutable subclasses + + yaml_loader = Loader + yaml_dumper = Dumper + + yaml_tag = None + yaml_flow_style = None + + def from_yaml(cls, loader, node): + """ + Convert a representation node to a Python object. + """ + return loader.construct_yaml_object(node, cls) + from_yaml = classmethod(from_yaml) + + def to_yaml(cls, dumper, data): + """ + Convert a Python object to a representation node. + """ + return dumper.represent_yaml_object(cls.yaml_tag, data, cls, + flow_style=cls.yaml_flow_style) + to_yaml = classmethod(to_yaml) + diff --git a/rplibs/yaml/yaml_py2/composer.py b/rplibs/yaml/yaml_py2/composer.py new file mode 100644 index 0000000..06e5ac7 --- /dev/null +++ b/rplibs/yaml/yaml_py2/composer.py @@ -0,0 +1,139 @@ + +__all__ = ['Composer', 'ComposerError'] + +from error import MarkedYAMLError +from events import * +from nodes import * + +class ComposerError(MarkedYAMLError): + pass + +class Composer(object): + + def __init__(self): + self.anchors = {} + + def check_node(self): + # Drop the STREAM-START event. + if self.check_event(StreamStartEvent): + self.get_event() + + # If there are more documents available? + return not self.check_event(StreamEndEvent) + + def get_node(self): + # Get the root node of the next document. + if not self.check_event(StreamEndEvent): + return self.compose_document() + + def get_single_node(self): + # Drop the STREAM-START event. + self.get_event() + + # Compose a document if the stream is not empty. + document = None + if not self.check_event(StreamEndEvent): + document = self.compose_document() + + # Ensure that the stream contains no more documents. + if not self.check_event(StreamEndEvent): + event = self.get_event() + raise ComposerError("expected a single document in the stream", + document.start_mark, "but found another document", + event.start_mark) + + # Drop the STREAM-END event. + self.get_event() + + return document + + def compose_document(self): + # Drop the DOCUMENT-START event. + self.get_event() + + # Compose the root node. + node = self.compose_node(None, None) + + # Drop the DOCUMENT-END event. + self.get_event() + + self.anchors = {} + return node + + def compose_node(self, parent, index): + if self.check_event(AliasEvent): + event = self.get_event() + anchor = event.anchor + if anchor not in self.anchors: + raise ComposerError(None, None, "found undefined alias %r" + % anchor.encode('utf-8'), event.start_mark) + return self.anchors[anchor] + event = self.peek_event() + anchor = event.anchor + if anchor is not None: + if anchor in self.anchors: + raise ComposerError("found duplicate anchor %r; first occurence" + % anchor.encode('utf-8'), self.anchors[anchor].start_mark, + "second occurence", event.start_mark) + self.descend_resolver(parent, index) + if self.check_event(ScalarEvent): + node = self.compose_scalar_node(anchor) + elif self.check_event(SequenceStartEvent): + node = self.compose_sequence_node(anchor) + elif self.check_event(MappingStartEvent): + node = self.compose_mapping_node(anchor) + self.ascend_resolver() + return node + + def compose_scalar_node(self, anchor): + event = self.get_event() + tag = event.tag + if tag is None or tag == u'!': + tag = self.resolve(ScalarNode, event.value, event.implicit) + node = ScalarNode(tag, event.value, + event.start_mark, event.end_mark, style=event.style) + if anchor is not None: + self.anchors[anchor] = node + return node + + def compose_sequence_node(self, anchor): + start_event = self.get_event() + tag = start_event.tag + if tag is None or tag == u'!': + tag = self.resolve(SequenceNode, None, start_event.implicit) + node = SequenceNode(tag, [], + start_event.start_mark, None, + flow_style=start_event.flow_style) + if anchor is not None: + self.anchors[anchor] = node + index = 0 + while not self.check_event(SequenceEndEvent): + node.value.append(self.compose_node(node, index)) + index += 1 + end_event = self.get_event() + node.end_mark = end_event.end_mark + return node + + def compose_mapping_node(self, anchor): + start_event = self.get_event() + tag = start_event.tag + if tag is None or tag == u'!': + tag = self.resolve(MappingNode, None, start_event.implicit) + node = MappingNode(tag, [], + start_event.start_mark, None, + flow_style=start_event.flow_style) + if anchor is not None: + self.anchors[anchor] = node + while not self.check_event(MappingEndEvent): + #key_event = self.peek_event() + item_key = self.compose_node(node, None) + #if item_key in node.value: + # raise ComposerError("while composing a mapping", start_event.start_mark, + # "found duplicate key", key_event.start_mark) + item_value = self.compose_node(node, item_key) + #node.value[item_key] = item_value + node.value.append((item_key, item_value)) + end_event = self.get_event() + node.end_mark = end_event.end_mark + return node + diff --git a/rplibs/yaml/yaml_py2/constructor.py b/rplibs/yaml/yaml_py2/constructor.py new file mode 100644 index 0000000..635faac --- /dev/null +++ b/rplibs/yaml/yaml_py2/constructor.py @@ -0,0 +1,675 @@ + +__all__ = ['BaseConstructor', 'SafeConstructor', 'Constructor', + 'ConstructorError'] + +from error import * +from nodes import * + +import datetime + +import binascii, re, sys, types + +class ConstructorError(MarkedYAMLError): + pass + +class BaseConstructor(object): + + yaml_constructors = {} + yaml_multi_constructors = {} + + def __init__(self): + self.constructed_objects = {} + self.recursive_objects = {} + self.state_generators = [] + self.deep_construct = False + + def check_data(self): + # If there are more documents available? + return self.check_node() + + def get_data(self): + # Construct and return the next document. + if self.check_node(): + return self.construct_document(self.get_node()) + + def get_single_data(self): + # Ensure that the stream contains a single document and construct it. + node = self.get_single_node() + if node is not None: + return self.construct_document(node) + return None + + def construct_document(self, node): + data = self.construct_object(node) + while self.state_generators: + state_generators = self.state_generators + self.state_generators = [] + for generator in state_generators: + for dummy in generator: + pass + self.constructed_objects = {} + self.recursive_objects = {} + self.deep_construct = False + return data + + def construct_object(self, node, deep=False): + if node in self.constructed_objects: + return self.constructed_objects[node] + if deep: + old_deep = self.deep_construct + self.deep_construct = True + if node in self.recursive_objects: + raise ConstructorError(None, None, + "found unconstructable recursive node", node.start_mark) + self.recursive_objects[node] = None + constructor = None + tag_suffix = None + if node.tag in self.yaml_constructors: + constructor = self.yaml_constructors[node.tag] + else: + for tag_prefix in self.yaml_multi_constructors: + if node.tag.startswith(tag_prefix): + tag_suffix = node.tag[len(tag_prefix):] + constructor = self.yaml_multi_constructors[tag_prefix] + break + else: + if None in self.yaml_multi_constructors: + tag_suffix = node.tag + constructor = self.yaml_multi_constructors[None] + elif None in self.yaml_constructors: + constructor = self.yaml_constructors[None] + elif isinstance(node, ScalarNode): + constructor = self.__class__.construct_scalar + elif isinstance(node, SequenceNode): + constructor = self.__class__.construct_sequence + elif isinstance(node, MappingNode): + constructor = self.__class__.construct_mapping + if tag_suffix is None: + data = constructor(self, node) + else: + data = constructor(self, tag_suffix, node) + if isinstance(data, types.GeneratorType): + generator = data + data = generator.next() + if self.deep_construct: + for dummy in generator: + pass + else: + self.state_generators.append(generator) + self.constructed_objects[node] = data + del self.recursive_objects[node] + if deep: + self.deep_construct = old_deep + return data + + def construct_scalar(self, node): + if not isinstance(node, ScalarNode): + raise ConstructorError(None, None, + "expected a scalar node, but found %s" % node.id, + node.start_mark) + return node.value + + def construct_sequence(self, node, deep=False): + if not isinstance(node, SequenceNode): + raise ConstructorError(None, None, + "expected a sequence node, but found %s" % node.id, + node.start_mark) + return [self.construct_object(child, deep=deep) + for child in node.value] + + def construct_mapping(self, node, deep=False): + if not isinstance(node, MappingNode): + raise ConstructorError(None, None, + "expected a mapping node, but found %s" % node.id, + node.start_mark) + mapping = {} + for key_node, value_node in node.value: + key = self.construct_object(key_node, deep=deep) + try: + hash(key) + except TypeError, exc: + raise ConstructorError("while constructing a mapping", node.start_mark, + "found unacceptable key (%s)" % exc, key_node.start_mark) + value = self.construct_object(value_node, deep=deep) + mapping[key] = value + return mapping + + def construct_pairs(self, node, deep=False): + if not isinstance(node, MappingNode): + raise ConstructorError(None, None, + "expected a mapping node, but found %s" % node.id, + node.start_mark) + pairs = [] + for key_node, value_node in node.value: + key = self.construct_object(key_node, deep=deep) + value = self.construct_object(value_node, deep=deep) + pairs.append((key, value)) + return pairs + + def add_constructor(cls, tag, constructor): + if not 'yaml_constructors' in cls.__dict__: + cls.yaml_constructors = cls.yaml_constructors.copy() + cls.yaml_constructors[tag] = constructor + add_constructor = classmethod(add_constructor) + + def add_multi_constructor(cls, tag_prefix, multi_constructor): + if not 'yaml_multi_constructors' in cls.__dict__: + cls.yaml_multi_constructors = cls.yaml_multi_constructors.copy() + cls.yaml_multi_constructors[tag_prefix] = multi_constructor + add_multi_constructor = classmethod(add_multi_constructor) + +class SafeConstructor(BaseConstructor): + + def construct_scalar(self, node): + if isinstance(node, MappingNode): + for key_node, value_node in node.value: + if key_node.tag == u'tag:yaml.org,2002:value': + return self.construct_scalar(value_node) + return BaseConstructor.construct_scalar(self, node) + + def flatten_mapping(self, node): + merge = [] + index = 0 + while index < len(node.value): + key_node, value_node = node.value[index] + if key_node.tag == u'tag:yaml.org,2002:merge': + del node.value[index] + if isinstance(value_node, MappingNode): + self.flatten_mapping(value_node) + merge.extend(value_node.value) + elif isinstance(value_node, SequenceNode): + submerge = [] + for subnode in value_node.value: + if not isinstance(subnode, MappingNode): + raise ConstructorError("while constructing a mapping", + node.start_mark, + "expected a mapping for merging, but found %s" + % subnode.id, subnode.start_mark) + self.flatten_mapping(subnode) + submerge.append(subnode.value) + submerge.reverse() + for value in submerge: + merge.extend(value) + else: + raise ConstructorError("while constructing a mapping", node.start_mark, + "expected a mapping or list of mappings for merging, but found %s" + % value_node.id, value_node.start_mark) + elif key_node.tag == u'tag:yaml.org,2002:value': + key_node.tag = u'tag:yaml.org,2002:str' + index += 1 + else: + index += 1 + if merge: + node.value = merge + node.value + + def construct_mapping(self, node, deep=False): + if isinstance(node, MappingNode): + self.flatten_mapping(node) + return BaseConstructor.construct_mapping(self, node, deep=deep) + + def construct_yaml_null(self, node): + self.construct_scalar(node) + return None + + bool_values = { + u'yes': True, + u'no': False, + u'true': True, + u'false': False, + u'on': True, + u'off': False, + } + + def construct_yaml_bool(self, node): + value = self.construct_scalar(node) + return self.bool_values[value.lower()] + + def construct_yaml_int(self, node): + value = str(self.construct_scalar(node)) + value = value.replace('_', '') + sign = +1 + if value[0] == '-': + sign = -1 + if value[0] in '+-': + value = value[1:] + if value == '0': + return 0 + elif value.startswith('0b'): + return sign*int(value[2:], 2) + elif value.startswith('0x'): + return sign*int(value[2:], 16) + elif value[0] == '0': + return sign*int(value, 8) + elif ':' in value: + digits = [int(part) for part in value.split(':')] + digits.reverse() + base = 1 + value = 0 + for digit in digits: + value += digit*base + base *= 60 + return sign*value + else: + return sign*int(value) + + inf_value = 1e300 + while inf_value != inf_value*inf_value: + inf_value *= inf_value + nan_value = -inf_value/inf_value # Trying to make a quiet NaN (like C99). + + def construct_yaml_float(self, node): + value = str(self.construct_scalar(node)) + value = value.replace('_', '').lower() + sign = +1 + if value[0] == '-': + sign = -1 + if value[0] in '+-': + value = value[1:] + if value == '.inf': + return sign*self.inf_value + elif value == '.nan': + return self.nan_value + elif ':' in value: + digits = [float(part) for part in value.split(':')] + digits.reverse() + base = 1 + value = 0.0 + for digit in digits: + value += digit*base + base *= 60 + return sign*value + else: + return sign*float(value) + + def construct_yaml_binary(self, node): + value = self.construct_scalar(node) + try: + return str(value).decode('base64') + except (binascii.Error, UnicodeEncodeError), exc: + raise ConstructorError(None, None, + "failed to decode base64 data: %s" % exc, node.start_mark) + + timestamp_regexp = re.compile( + ur'''^(?P[0-9][0-9][0-9][0-9]) + -(?P[0-9][0-9]?) + -(?P[0-9][0-9]?) + (?:(?:[Tt]|[ \t]+) + (?P[0-9][0-9]?) + :(?P[0-9][0-9]) + :(?P[0-9][0-9]) + (?:\.(?P[0-9]*))? + (?:[ \t]*(?PZ|(?P[-+])(?P[0-9][0-9]?) + (?::(?P[0-9][0-9]))?))?)?$''', re.X) + + def construct_yaml_timestamp(self, node): + value = self.construct_scalar(node) + match = self.timestamp_regexp.match(node.value) + values = match.groupdict() + year = int(values['year']) + month = int(values['month']) + day = int(values['day']) + if not values['hour']: + return datetime.date(year, month, day) + hour = int(values['hour']) + minute = int(values['minute']) + second = int(values['second']) + fraction = 0 + if values['fraction']: + fraction = values['fraction'][:6] + while len(fraction) < 6: + fraction += '0' + fraction = int(fraction) + delta = None + if values['tz_sign']: + tz_hour = int(values['tz_hour']) + tz_minute = int(values['tz_minute'] or 0) + delta = datetime.timedelta(hours=tz_hour, minutes=tz_minute) + if values['tz_sign'] == '-': + delta = -delta + data = datetime.datetime(year, month, day, hour, minute, second, fraction) + if delta: + data -= delta + return data + + def construct_yaml_omap(self, node): + # Note: we do not check for duplicate keys, because it's too + # CPU-expensive. + omap = [] + yield omap + if not isinstance(node, SequenceNode): + raise ConstructorError("while constructing an ordered map", node.start_mark, + "expected a sequence, but found %s" % node.id, node.start_mark) + for subnode in node.value: + if not isinstance(subnode, MappingNode): + raise ConstructorError("while constructing an ordered map", node.start_mark, + "expected a mapping of length 1, but found %s" % subnode.id, + subnode.start_mark) + if len(subnode.value) != 1: + raise ConstructorError("while constructing an ordered map", node.start_mark, + "expected a single mapping item, but found %d items" % len(subnode.value), + subnode.start_mark) + key_node, value_node = subnode.value[0] + key = self.construct_object(key_node) + value = self.construct_object(value_node) + omap.append((key, value)) + + def construct_yaml_pairs(self, node): + # Note: the same code as `construct_yaml_omap`. + pairs = [] + yield pairs + if not isinstance(node, SequenceNode): + raise ConstructorError("while constructing pairs", node.start_mark, + "expected a sequence, but found %s" % node.id, node.start_mark) + for subnode in node.value: + if not isinstance(subnode, MappingNode): + raise ConstructorError("while constructing pairs", node.start_mark, + "expected a mapping of length 1, but found %s" % subnode.id, + subnode.start_mark) + if len(subnode.value) != 1: + raise ConstructorError("while constructing pairs", node.start_mark, + "expected a single mapping item, but found %d items" % len(subnode.value), + subnode.start_mark) + key_node, value_node = subnode.value[0] + key = self.construct_object(key_node) + value = self.construct_object(value_node) + pairs.append((key, value)) + + def construct_yaml_set(self, node): + data = set() + yield data + value = self.construct_mapping(node) + data.update(value) + + def construct_yaml_str(self, node): + value = self.construct_scalar(node) + try: + return value.encode('ascii') + except UnicodeEncodeError: + return value + + def construct_yaml_seq(self, node): + data = [] + yield data + data.extend(self.construct_sequence(node)) + + def construct_yaml_map(self, node): + data = {} + yield data + value = self.construct_mapping(node) + data.update(value) + + def construct_yaml_object(self, node, cls): + data = cls.__new__(cls) + yield data + if hasattr(data, '__setstate__'): + state = self.construct_mapping(node, deep=True) + data.__setstate__(state) + else: + state = self.construct_mapping(node) + data.__dict__.update(state) + + def construct_undefined(self, node): + raise ConstructorError(None, None, + "could not determine a constructor for the tag %r" % node.tag.encode('utf-8'), + node.start_mark) + +SafeConstructor.add_constructor( + u'tag:yaml.org,2002:null', + SafeConstructor.construct_yaml_null) + +SafeConstructor.add_constructor( + u'tag:yaml.org,2002:bool', + SafeConstructor.construct_yaml_bool) + +SafeConstructor.add_constructor( + u'tag:yaml.org,2002:int', + SafeConstructor.construct_yaml_int) + +SafeConstructor.add_constructor( + u'tag:yaml.org,2002:float', + SafeConstructor.construct_yaml_float) + +SafeConstructor.add_constructor( + u'tag:yaml.org,2002:binary', + SafeConstructor.construct_yaml_binary) + +SafeConstructor.add_constructor( + u'tag:yaml.org,2002:timestamp', + SafeConstructor.construct_yaml_timestamp) + +SafeConstructor.add_constructor( + u'tag:yaml.org,2002:omap', + SafeConstructor.construct_yaml_omap) + +SafeConstructor.add_constructor( + u'tag:yaml.org,2002:pairs', + SafeConstructor.construct_yaml_pairs) + +SafeConstructor.add_constructor( + u'tag:yaml.org,2002:set', + SafeConstructor.construct_yaml_set) + +SafeConstructor.add_constructor( + u'tag:yaml.org,2002:str', + SafeConstructor.construct_yaml_str) + +SafeConstructor.add_constructor( + u'tag:yaml.org,2002:seq', + SafeConstructor.construct_yaml_seq) + +SafeConstructor.add_constructor( + u'tag:yaml.org,2002:map', + SafeConstructor.construct_yaml_map) + +SafeConstructor.add_constructor(None, + SafeConstructor.construct_undefined) + +class Constructor(SafeConstructor): + + def construct_python_str(self, node): + return self.construct_scalar(node).encode('utf-8') + + def construct_python_unicode(self, node): + return self.construct_scalar(node) + + def construct_python_long(self, node): + return long(self.construct_yaml_int(node)) + + def construct_python_complex(self, node): + return complex(self.construct_scalar(node)) + + def construct_python_tuple(self, node): + return tuple(self.construct_sequence(node)) + + def find_python_module(self, name, mark): + if not name: + raise ConstructorError("while constructing a Python module", mark, + "expected non-empty name appended to the tag", mark) + try: + __import__(name) + except ImportError, exc: + raise ConstructorError("while constructing a Python module", mark, + "cannot find module %r (%s)" % (name.encode('utf-8'), exc), mark) + return sys.modules[name] + + def find_python_name(self, name, mark): + if not name: + raise ConstructorError("while constructing a Python object", mark, + "expected non-empty name appended to the tag", mark) + if u'.' in name: + module_name, object_name = name.rsplit('.', 1) + else: + module_name = '__builtin__' + object_name = name + try: + __import__(module_name) + except ImportError, exc: + raise ConstructorError("while constructing a Python object", mark, + "cannot find module %r (%s)" % (module_name.encode('utf-8'), exc), mark) + module = sys.modules[module_name] + if not hasattr(module, object_name): + raise ConstructorError("while constructing a Python object", mark, + "cannot find %r in the module %r" % (object_name.encode('utf-8'), + module.__name__), mark) + return getattr(module, object_name) + + def construct_python_name(self, suffix, node): + value = self.construct_scalar(node) + if value: + raise ConstructorError("while constructing a Python name", node.start_mark, + "expected the empty value, but found %r" % value.encode('utf-8'), + node.start_mark) + return self.find_python_name(suffix, node.start_mark) + + def construct_python_module(self, suffix, node): + value = self.construct_scalar(node) + if value: + raise ConstructorError("while constructing a Python module", node.start_mark, + "expected the empty value, but found %r" % value.encode('utf-8'), + node.start_mark) + return self.find_python_module(suffix, node.start_mark) + + class classobj: pass + + def make_python_instance(self, suffix, node, + args=None, kwds=None, newobj=False): + if not args: + args = [] + if not kwds: + kwds = {} + cls = self.find_python_name(suffix, node.start_mark) + if newobj and isinstance(cls, type(self.classobj)) \ + and not args and not kwds: + instance = self.classobj() + instance.__class__ = cls + return instance + elif newobj and isinstance(cls, type): + return cls.__new__(cls, *args, **kwds) + else: + return cls(*args, **kwds) + + def set_python_instance_state(self, instance, state): + if hasattr(instance, '__setstate__'): + instance.__setstate__(state) + else: + slotstate = {} + if isinstance(state, tuple) and len(state) == 2: + state, slotstate = state + if hasattr(instance, '__dict__'): + instance.__dict__.update(state) + elif state: + slotstate.update(state) + for key, value in slotstate.items(): + setattr(object, key, value) + + def construct_python_object(self, suffix, node): + # Format: + # !!python/object:module.name { ... state ... } + instance = self.make_python_instance(suffix, node, newobj=True) + yield instance + deep = hasattr(instance, '__setstate__') + state = self.construct_mapping(node, deep=deep) + self.set_python_instance_state(instance, state) + + def construct_python_object_apply(self, suffix, node, newobj=False): + # Format: + # !!python/object/apply # (or !!python/object/new) + # args: [ ... arguments ... ] + # kwds: { ... keywords ... } + # state: ... state ... + # listitems: [ ... listitems ... ] + # dictitems: { ... dictitems ... } + # or short format: + # !!python/object/apply [ ... arguments ... ] + # The difference between !!python/object/apply and !!python/object/new + # is how an object is created, check make_python_instance for details. + if isinstance(node, SequenceNode): + args = self.construct_sequence(node, deep=True) + kwds = {} + state = {} + listitems = [] + dictitems = {} + else: + value = self.construct_mapping(node, deep=True) + args = value.get('args', []) + kwds = value.get('kwds', {}) + state = value.get('state', {}) + listitems = value.get('listitems', []) + dictitems = value.get('dictitems', {}) + instance = self.make_python_instance(suffix, node, args, kwds, newobj) + if state: + self.set_python_instance_state(instance, state) + if listitems: + instance.extend(listitems) + if dictitems: + for key in dictitems: + instance[key] = dictitems[key] + return instance + + def construct_python_object_new(self, suffix, node): + return self.construct_python_object_apply(suffix, node, newobj=True) + +Constructor.add_constructor( + u'tag:yaml.org,2002:python/none', + Constructor.construct_yaml_null) + +Constructor.add_constructor( + u'tag:yaml.org,2002:python/bool', + Constructor.construct_yaml_bool) + +Constructor.add_constructor( + u'tag:yaml.org,2002:python/str', + Constructor.construct_python_str) + +Constructor.add_constructor( + u'tag:yaml.org,2002:python/unicode', + Constructor.construct_python_unicode) + +Constructor.add_constructor( + u'tag:yaml.org,2002:python/int', + Constructor.construct_yaml_int) + +Constructor.add_constructor( + u'tag:yaml.org,2002:python/long', + Constructor.construct_python_long) + +Constructor.add_constructor( + u'tag:yaml.org,2002:python/float', + Constructor.construct_yaml_float) + +Constructor.add_constructor( + u'tag:yaml.org,2002:python/complex', + Constructor.construct_python_complex) + +Constructor.add_constructor( + u'tag:yaml.org,2002:python/list', + Constructor.construct_yaml_seq) + +Constructor.add_constructor( + u'tag:yaml.org,2002:python/tuple', + Constructor.construct_python_tuple) + +Constructor.add_constructor( + u'tag:yaml.org,2002:python/dict', + Constructor.construct_yaml_map) + +Constructor.add_multi_constructor( + u'tag:yaml.org,2002:python/name:', + Constructor.construct_python_name) + +Constructor.add_multi_constructor( + u'tag:yaml.org,2002:python/module:', + Constructor.construct_python_module) + +Constructor.add_multi_constructor( + u'tag:yaml.org,2002:python/object:', + Constructor.construct_python_object) + +Constructor.add_multi_constructor( + u'tag:yaml.org,2002:python/object/apply:', + Constructor.construct_python_object_apply) + +Constructor.add_multi_constructor( + u'tag:yaml.org,2002:python/object/new:', + Constructor.construct_python_object_new) + diff --git a/rplibs/yaml/yaml_py2/cyaml.py b/rplibs/yaml/yaml_py2/cyaml.py new file mode 100644 index 0000000..68dcd75 --- /dev/null +++ b/rplibs/yaml/yaml_py2/cyaml.py @@ -0,0 +1,85 @@ + +__all__ = ['CBaseLoader', 'CSafeLoader', 'CLoader', + 'CBaseDumper', 'CSafeDumper', 'CDumper'] + +from _yaml import CParser, CEmitter + +from constructor import * + +from serializer import * +from representer import * + +from resolver import * + +class CBaseLoader(CParser, BaseConstructor, BaseResolver): + + def __init__(self, stream): + CParser.__init__(self, stream) + BaseConstructor.__init__(self) + BaseResolver.__init__(self) + +class CSafeLoader(CParser, SafeConstructor, Resolver): + + def __init__(self, stream): + CParser.__init__(self, stream) + SafeConstructor.__init__(self) + Resolver.__init__(self) + +class CLoader(CParser, Constructor, Resolver): + + def __init__(self, stream): + CParser.__init__(self, stream) + Constructor.__init__(self) + Resolver.__init__(self) + +class CBaseDumper(CEmitter, BaseRepresenter, BaseResolver): + + def __init__(self, stream, + default_style=None, default_flow_style=None, + canonical=None, indent=None, width=None, + allow_unicode=None, line_break=None, + encoding=None, explicit_start=None, explicit_end=None, + version=None, tags=None): + CEmitter.__init__(self, stream, canonical=canonical, + indent=indent, width=width, encoding=encoding, + allow_unicode=allow_unicode, line_break=line_break, + explicit_start=explicit_start, explicit_end=explicit_end, + version=version, tags=tags) + Representer.__init__(self, default_style=default_style, + default_flow_style=default_flow_style) + Resolver.__init__(self) + +class CSafeDumper(CEmitter, SafeRepresenter, Resolver): + + def __init__(self, stream, + default_style=None, default_flow_style=None, + canonical=None, indent=None, width=None, + allow_unicode=None, line_break=None, + encoding=None, explicit_start=None, explicit_end=None, + version=None, tags=None): + CEmitter.__init__(self, stream, canonical=canonical, + indent=indent, width=width, encoding=encoding, + allow_unicode=allow_unicode, line_break=line_break, + explicit_start=explicit_start, explicit_end=explicit_end, + version=version, tags=tags) + SafeRepresenter.__init__(self, default_style=default_style, + default_flow_style=default_flow_style) + Resolver.__init__(self) + +class CDumper(CEmitter, Serializer, Representer, Resolver): + + def __init__(self, stream, + default_style=None, default_flow_style=None, + canonical=None, indent=None, width=None, + allow_unicode=None, line_break=None, + encoding=None, explicit_start=None, explicit_end=None, + version=None, tags=None): + CEmitter.__init__(self, stream, canonical=canonical, + indent=indent, width=width, encoding=encoding, + allow_unicode=allow_unicode, line_break=line_break, + explicit_start=explicit_start, explicit_end=explicit_end, + version=version, tags=tags) + Representer.__init__(self, default_style=default_style, + default_flow_style=default_flow_style) + Resolver.__init__(self) + diff --git a/rplibs/yaml/yaml_py2/dumper.py b/rplibs/yaml/yaml_py2/dumper.py new file mode 100644 index 0000000..f811d2c --- /dev/null +++ b/rplibs/yaml/yaml_py2/dumper.py @@ -0,0 +1,62 @@ + +__all__ = ['BaseDumper', 'SafeDumper', 'Dumper'] + +from emitter import * +from serializer import * +from representer import * +from resolver import * + +class BaseDumper(Emitter, Serializer, BaseRepresenter, BaseResolver): + + def __init__(self, stream, + default_style=None, default_flow_style=None, + canonical=None, indent=None, width=None, + allow_unicode=None, line_break=None, + encoding=None, explicit_start=None, explicit_end=None, + version=None, tags=None): + Emitter.__init__(self, stream, canonical=canonical, + indent=indent, width=width, + allow_unicode=allow_unicode, line_break=line_break) + Serializer.__init__(self, encoding=encoding, + explicit_start=explicit_start, explicit_end=explicit_end, + version=version, tags=tags) + Representer.__init__(self, default_style=default_style, + default_flow_style=default_flow_style) + Resolver.__init__(self) + +class SafeDumper(Emitter, Serializer, SafeRepresenter, Resolver): + + def __init__(self, stream, + default_style=None, default_flow_style=None, + canonical=None, indent=None, width=None, + allow_unicode=None, line_break=None, + encoding=None, explicit_start=None, explicit_end=None, + version=None, tags=None): + Emitter.__init__(self, stream, canonical=canonical, + indent=indent, width=width, + allow_unicode=allow_unicode, line_break=line_break) + Serializer.__init__(self, encoding=encoding, + explicit_start=explicit_start, explicit_end=explicit_end, + version=version, tags=tags) + SafeRepresenter.__init__(self, default_style=default_style, + default_flow_style=default_flow_style) + Resolver.__init__(self) + +class Dumper(Emitter, Serializer, Representer, Resolver): + + def __init__(self, stream, + default_style=None, default_flow_style=None, + canonical=None, indent=None, width=None, + allow_unicode=None, line_break=None, + encoding=None, explicit_start=None, explicit_end=None, + version=None, tags=None): + Emitter.__init__(self, stream, canonical=canonical, + indent=indent, width=width, + allow_unicode=allow_unicode, line_break=line_break) + Serializer.__init__(self, encoding=encoding, + explicit_start=explicit_start, explicit_end=explicit_end, + version=version, tags=tags) + Representer.__init__(self, default_style=default_style, + default_flow_style=default_flow_style) + Resolver.__init__(self) + diff --git a/rplibs/yaml/yaml_py2/emitter.py b/rplibs/yaml/yaml_py2/emitter.py new file mode 100644 index 0000000..e5bcdcc --- /dev/null +++ b/rplibs/yaml/yaml_py2/emitter.py @@ -0,0 +1,1140 @@ + +# Emitter expects events obeying the following grammar: +# stream ::= STREAM-START document* STREAM-END +# document ::= DOCUMENT-START node DOCUMENT-END +# node ::= SCALAR | sequence | mapping +# sequence ::= SEQUENCE-START node* SEQUENCE-END +# mapping ::= MAPPING-START (node node)* MAPPING-END + +__all__ = ['Emitter', 'EmitterError'] + +from error import YAMLError +from events import * + +class EmitterError(YAMLError): + pass + +class ScalarAnalysis(object): + def __init__(self, scalar, empty, multiline, + allow_flow_plain, allow_block_plain, + allow_single_quoted, allow_double_quoted, + allow_block): + self.scalar = scalar + self.empty = empty + self.multiline = multiline + self.allow_flow_plain = allow_flow_plain + self.allow_block_plain = allow_block_plain + self.allow_single_quoted = allow_single_quoted + self.allow_double_quoted = allow_double_quoted + self.allow_block = allow_block + +class Emitter(object): + + DEFAULT_TAG_PREFIXES = { + u'!' : u'!', + u'tag:yaml.org,2002:' : u'!!', + } + + def __init__(self, stream, canonical=None, indent=None, width=None, + allow_unicode=None, line_break=None): + + # The stream should have the methods `write` and possibly `flush`. + self.stream = stream + + # Encoding can be overriden by STREAM-START. + self.encoding = None + + # Emitter is a state machine with a stack of states to handle nested + # structures. + self.states = [] + self.state = self.expect_stream_start + + # Current event and the event queue. + self.events = [] + self.event = None + + # The current indentation level and the stack of previous indents. + self.indents = [] + self.indent = None + + # Flow level. + self.flow_level = 0 + + # Contexts. + self.root_context = False + self.sequence_context = False + self.mapping_context = False + self.simple_key_context = False + + # Characteristics of the last emitted character: + # - current position. + # - is it a whitespace? + # - is it an indention character + # (indentation space, '-', '?', or ':')? + self.line = 0 + self.column = 0 + self.whitespace = True + self.indention = True + + # Whether the document requires an explicit document indicator + self.open_ended = False + + # Formatting details. + self.canonical = canonical + self.allow_unicode = allow_unicode + self.best_indent = 2 + if indent and 1 < indent < 10: + self.best_indent = indent + self.best_width = 80 + if width and width > self.best_indent*2: + self.best_width = width + self.best_line_break = u'\n' + if line_break in [u'\r', u'\n', u'\r\n']: + self.best_line_break = line_break + + # Tag prefixes. + self.tag_prefixes = None + + # Prepared anchor and tag. + self.prepared_anchor = None + self.prepared_tag = None + + # Scalar analysis and style. + self.analysis = None + self.style = None + + def dispose(self): + # Reset the state attributes (to clear self-references) + self.states = [] + self.state = None + + def emit(self, event): + self.events.append(event) + while not self.need_more_events(): + self.event = self.events.pop(0) + self.state() + self.event = None + + # In some cases, we wait for a few next events before emitting. + + def need_more_events(self): + if not self.events: + return True + event = self.events[0] + if isinstance(event, DocumentStartEvent): + return self.need_events(1) + elif isinstance(event, SequenceStartEvent): + return self.need_events(2) + elif isinstance(event, MappingStartEvent): + return self.need_events(3) + else: + return False + + def need_events(self, count): + level = 0 + for event in self.events[1:]: + if isinstance(event, (DocumentStartEvent, CollectionStartEvent)): + level += 1 + elif isinstance(event, (DocumentEndEvent, CollectionEndEvent)): + level -= 1 + elif isinstance(event, StreamEndEvent): + level = -1 + if level < 0: + return False + return (len(self.events) < count+1) + + def increase_indent(self, flow=False, indentless=False): + self.indents.append(self.indent) + if self.indent is None: + if flow: + self.indent = self.best_indent + else: + self.indent = 0 + elif not indentless: + self.indent += self.best_indent + + # States. + + # Stream handlers. + + def expect_stream_start(self): + if isinstance(self.event, StreamStartEvent): + if self.event.encoding and not getattr(self.stream, 'encoding', None): + self.encoding = self.event.encoding + self.write_stream_start() + self.state = self.expect_first_document_start + else: + raise EmitterError("expected StreamStartEvent, but got %s" + % self.event) + + def expect_nothing(self): + raise EmitterError("expected nothing, but got %s" % self.event) + + # Document handlers. + + def expect_first_document_start(self): + return self.expect_document_start(first=True) + + def expect_document_start(self, first=False): + if isinstance(self.event, DocumentStartEvent): + if (self.event.version or self.event.tags) and self.open_ended: + self.write_indicator(u'...', True) + self.write_indent() + if self.event.version: + version_text = self.prepare_version(self.event.version) + self.write_version_directive(version_text) + self.tag_prefixes = self.DEFAULT_TAG_PREFIXES.copy() + if self.event.tags: + handles = self.event.tags.keys() + handles.sort() + for handle in handles: + prefix = self.event.tags[handle] + self.tag_prefixes[prefix] = handle + handle_text = self.prepare_tag_handle(handle) + prefix_text = self.prepare_tag_prefix(prefix) + self.write_tag_directive(handle_text, prefix_text) + implicit = (first and not self.event.explicit and not self.canonical + and not self.event.version and not self.event.tags + and not self.check_empty_document()) + if not implicit: + self.write_indent() + self.write_indicator(u'---', True) + if self.canonical: + self.write_indent() + self.state = self.expect_document_root + elif isinstance(self.event, StreamEndEvent): + if self.open_ended: + self.write_indicator(u'...', True) + self.write_indent() + self.write_stream_end() + self.state = self.expect_nothing + else: + raise EmitterError("expected DocumentStartEvent, but got %s" + % self.event) + + def expect_document_end(self): + if isinstance(self.event, DocumentEndEvent): + self.write_indent() + if self.event.explicit: + self.write_indicator(u'...', True) + self.write_indent() + self.flush_stream() + self.state = self.expect_document_start + else: + raise EmitterError("expected DocumentEndEvent, but got %s" + % self.event) + + def expect_document_root(self): + self.states.append(self.expect_document_end) + self.expect_node(root=True) + + # Node handlers. + + def expect_node(self, root=False, sequence=False, mapping=False, + simple_key=False): + self.root_context = root + self.sequence_context = sequence + self.mapping_context = mapping + self.simple_key_context = simple_key + if isinstance(self.event, AliasEvent): + self.expect_alias() + elif isinstance(self.event, (ScalarEvent, CollectionStartEvent)): + self.process_anchor(u'&') + self.process_tag() + if isinstance(self.event, ScalarEvent): + self.expect_scalar() + elif isinstance(self.event, SequenceStartEvent): + if self.flow_level or self.canonical or self.event.flow_style \ + or self.check_empty_sequence(): + self.expect_flow_sequence() + else: + self.expect_block_sequence() + elif isinstance(self.event, MappingStartEvent): + if self.flow_level or self.canonical or self.event.flow_style \ + or self.check_empty_mapping(): + self.expect_flow_mapping() + else: + self.expect_block_mapping() + else: + raise EmitterError("expected NodeEvent, but got %s" % self.event) + + def expect_alias(self): + if self.event.anchor is None: + raise EmitterError("anchor is not specified for alias") + self.process_anchor(u'*') + self.state = self.states.pop() + + def expect_scalar(self): + self.increase_indent(flow=True) + self.process_scalar() + self.indent = self.indents.pop() + self.state = self.states.pop() + + # Flow sequence handlers. + + def expect_flow_sequence(self): + self.write_indicator(u'[', True, whitespace=True) + self.flow_level += 1 + self.increase_indent(flow=True) + self.state = self.expect_first_flow_sequence_item + + def expect_first_flow_sequence_item(self): + if isinstance(self.event, SequenceEndEvent): + self.indent = self.indents.pop() + self.flow_level -= 1 + self.write_indicator(u']', False) + self.state = self.states.pop() + else: + if self.canonical or self.column > self.best_width: + self.write_indent() + self.states.append(self.expect_flow_sequence_item) + self.expect_node(sequence=True) + + def expect_flow_sequence_item(self): + if isinstance(self.event, SequenceEndEvent): + self.indent = self.indents.pop() + self.flow_level -= 1 + if self.canonical: + self.write_indicator(u',', False) + self.write_indent() + self.write_indicator(u']', False) + self.state = self.states.pop() + else: + self.write_indicator(u',', False) + if self.canonical or self.column > self.best_width: + self.write_indent() + self.states.append(self.expect_flow_sequence_item) + self.expect_node(sequence=True) + + # Flow mapping handlers. + + def expect_flow_mapping(self): + self.write_indicator(u'{', True, whitespace=True) + self.flow_level += 1 + self.increase_indent(flow=True) + self.state = self.expect_first_flow_mapping_key + + def expect_first_flow_mapping_key(self): + if isinstance(self.event, MappingEndEvent): + self.indent = self.indents.pop() + self.flow_level -= 1 + self.write_indicator(u'}', False) + self.state = self.states.pop() + else: + if self.canonical or self.column > self.best_width: + self.write_indent() + if not self.canonical and self.check_simple_key(): + self.states.append(self.expect_flow_mapping_simple_value) + self.expect_node(mapping=True, simple_key=True) + else: + self.write_indicator(u'?', True) + self.states.append(self.expect_flow_mapping_value) + self.expect_node(mapping=True) + + def expect_flow_mapping_key(self): + if isinstance(self.event, MappingEndEvent): + self.indent = self.indents.pop() + self.flow_level -= 1 + if self.canonical: + self.write_indicator(u',', False) + self.write_indent() + self.write_indicator(u'}', False) + self.state = self.states.pop() + else: + self.write_indicator(u',', False) + if self.canonical or self.column > self.best_width: + self.write_indent() + if not self.canonical and self.check_simple_key(): + self.states.append(self.expect_flow_mapping_simple_value) + self.expect_node(mapping=True, simple_key=True) + else: + self.write_indicator(u'?', True) + self.states.append(self.expect_flow_mapping_value) + self.expect_node(mapping=True) + + def expect_flow_mapping_simple_value(self): + self.write_indicator(u':', False) + self.states.append(self.expect_flow_mapping_key) + self.expect_node(mapping=True) + + def expect_flow_mapping_value(self): + if self.canonical or self.column > self.best_width: + self.write_indent() + self.write_indicator(u':', True) + self.states.append(self.expect_flow_mapping_key) + self.expect_node(mapping=True) + + # Block sequence handlers. + + def expect_block_sequence(self): + indentless = (self.mapping_context and not self.indention) + self.increase_indent(flow=False, indentless=indentless) + self.state = self.expect_first_block_sequence_item + + def expect_first_block_sequence_item(self): + return self.expect_block_sequence_item(first=True) + + def expect_block_sequence_item(self, first=False): + if not first and isinstance(self.event, SequenceEndEvent): + self.indent = self.indents.pop() + self.state = self.states.pop() + else: + self.write_indent() + self.write_indicator(u'-', True, indention=True) + self.states.append(self.expect_block_sequence_item) + self.expect_node(sequence=True) + + # Block mapping handlers. + + def expect_block_mapping(self): + self.increase_indent(flow=False) + self.state = self.expect_first_block_mapping_key + + def expect_first_block_mapping_key(self): + return self.expect_block_mapping_key(first=True) + + def expect_block_mapping_key(self, first=False): + if not first and isinstance(self.event, MappingEndEvent): + self.indent = self.indents.pop() + self.state = self.states.pop() + else: + self.write_indent() + if self.check_simple_key(): + self.states.append(self.expect_block_mapping_simple_value) + self.expect_node(mapping=True, simple_key=True) + else: + self.write_indicator(u'?', True, indention=True) + self.states.append(self.expect_block_mapping_value) + self.expect_node(mapping=True) + + def expect_block_mapping_simple_value(self): + self.write_indicator(u':', False) + self.states.append(self.expect_block_mapping_key) + self.expect_node(mapping=True) + + def expect_block_mapping_value(self): + self.write_indent() + self.write_indicator(u':', True, indention=True) + self.states.append(self.expect_block_mapping_key) + self.expect_node(mapping=True) + + # Checkers. + + def check_empty_sequence(self): + return (isinstance(self.event, SequenceStartEvent) and self.events + and isinstance(self.events[0], SequenceEndEvent)) + + def check_empty_mapping(self): + return (isinstance(self.event, MappingStartEvent) and self.events + and isinstance(self.events[0], MappingEndEvent)) + + def check_empty_document(self): + if not isinstance(self.event, DocumentStartEvent) or not self.events: + return False + event = self.events[0] + return (isinstance(event, ScalarEvent) and event.anchor is None + and event.tag is None and event.implicit and event.value == u'') + + def check_simple_key(self): + length = 0 + if isinstance(self.event, NodeEvent) and self.event.anchor is not None: + if self.prepared_anchor is None: + self.prepared_anchor = self.prepare_anchor(self.event.anchor) + length += len(self.prepared_anchor) + if isinstance(self.event, (ScalarEvent, CollectionStartEvent)) \ + and self.event.tag is not None: + if self.prepared_tag is None: + self.prepared_tag = self.prepare_tag(self.event.tag) + length += len(self.prepared_tag) + if isinstance(self.event, ScalarEvent): + if self.analysis is None: + self.analysis = self.analyze_scalar(self.event.value) + length += len(self.analysis.scalar) + return (length < 128 and (isinstance(self.event, AliasEvent) + or (isinstance(self.event, ScalarEvent) + and not self.analysis.empty and not self.analysis.multiline) + or self.check_empty_sequence() or self.check_empty_mapping())) + + # Anchor, Tag, and Scalar processors. + + def process_anchor(self, indicator): + if self.event.anchor is None: + self.prepared_anchor = None + return + if self.prepared_anchor is None: + self.prepared_anchor = self.prepare_anchor(self.event.anchor) + if self.prepared_anchor: + self.write_indicator(indicator+self.prepared_anchor, True) + self.prepared_anchor = None + + def process_tag(self): + tag = self.event.tag + if isinstance(self.event, ScalarEvent): + if self.style is None: + self.style = self.choose_scalar_style() + if ((not self.canonical or tag is None) and + ((self.style == '' and self.event.implicit[0]) + or (self.style != '' and self.event.implicit[1]))): + self.prepared_tag = None + return + if self.event.implicit[0] and tag is None: + tag = u'!' + self.prepared_tag = None + else: + if (not self.canonical or tag is None) and self.event.implicit: + self.prepared_tag = None + return + if tag is None: + raise EmitterError("tag is not specified") + if self.prepared_tag is None: + self.prepared_tag = self.prepare_tag(tag) + if self.prepared_tag: + self.write_indicator(self.prepared_tag, True) + self.prepared_tag = None + + def choose_scalar_style(self): + if self.analysis is None: + self.analysis = self.analyze_scalar(self.event.value) + if self.event.style == '"' or self.canonical: + return '"' + if not self.event.style and self.event.implicit[0]: + if (not (self.simple_key_context and + (self.analysis.empty or self.analysis.multiline)) + and (self.flow_level and self.analysis.allow_flow_plain + or (not self.flow_level and self.analysis.allow_block_plain))): + return '' + if self.event.style and self.event.style in '|>': + if (not self.flow_level and not self.simple_key_context + and self.analysis.allow_block): + return self.event.style + if not self.event.style or self.event.style == '\'': + if (self.analysis.allow_single_quoted and + not (self.simple_key_context and self.analysis.multiline)): + return '\'' + return '"' + + def process_scalar(self): + if self.analysis is None: + self.analysis = self.analyze_scalar(self.event.value) + if self.style is None: + self.style = self.choose_scalar_style() + split = (not self.simple_key_context) + #if self.analysis.multiline and split \ + # and (not self.style or self.style in '\'\"'): + # self.write_indent() + if self.style == '"': + self.write_double_quoted(self.analysis.scalar, split) + elif self.style == '\'': + self.write_single_quoted(self.analysis.scalar, split) + elif self.style == '>': + self.write_folded(self.analysis.scalar) + elif self.style == '|': + self.write_literal(self.analysis.scalar) + else: + self.write_plain(self.analysis.scalar, split) + self.analysis = None + self.style = None + + # Analyzers. + + def prepare_version(self, version): + major, minor = version + if major != 1: + raise EmitterError("unsupported YAML version: %d.%d" % (major, minor)) + return u'%d.%d' % (major, minor) + + def prepare_tag_handle(self, handle): + if not handle: + raise EmitterError("tag handle must not be empty") + if handle[0] != u'!' or handle[-1] != u'!': + raise EmitterError("tag handle must start and end with '!': %r" + % (handle.encode('utf-8'))) + for ch in handle[1:-1]: + if not (u'0' <= ch <= u'9' or u'A' <= ch <= u'Z' or u'a' <= ch <= u'z' \ + or ch in u'-_'): + raise EmitterError("invalid character %r in the tag handle: %r" + % (ch.encode('utf-8'), handle.encode('utf-8'))) + return handle + + def prepare_tag_prefix(self, prefix): + if not prefix: + raise EmitterError("tag prefix must not be empty") + chunks = [] + start = end = 0 + if prefix[0] == u'!': + end = 1 + while end < len(prefix): + ch = prefix[end] + if u'0' <= ch <= u'9' or u'A' <= ch <= u'Z' or u'a' <= ch <= u'z' \ + or ch in u'-;/?!:@&=+$,_.~*\'()[]': + end += 1 + else: + if start < end: + chunks.append(prefix[start:end]) + start = end = end+1 + data = ch.encode('utf-8') + for ch in data: + chunks.append(u'%%%02X' % ord(ch)) + if start < end: + chunks.append(prefix[start:end]) + return u''.join(chunks) + + def prepare_tag(self, tag): + if not tag: + raise EmitterError("tag must not be empty") + if tag == u'!': + return tag + handle = None + suffix = tag + prefixes = self.tag_prefixes.keys() + prefixes.sort() + for prefix in prefixes: + if tag.startswith(prefix) \ + and (prefix == u'!' or len(prefix) < len(tag)): + handle = self.tag_prefixes[prefix] + suffix = tag[len(prefix):] + chunks = [] + start = end = 0 + while end < len(suffix): + ch = suffix[end] + if u'0' <= ch <= u'9' or u'A' <= ch <= u'Z' or u'a' <= ch <= u'z' \ + or ch in u'-;/?:@&=+$,_.~*\'()[]' \ + or (ch == u'!' and handle != u'!'): + end += 1 + else: + if start < end: + chunks.append(suffix[start:end]) + start = end = end+1 + data = ch.encode('utf-8') + for ch in data: + chunks.append(u'%%%02X' % ord(ch)) + if start < end: + chunks.append(suffix[start:end]) + suffix_text = u''.join(chunks) + if handle: + return u'%s%s' % (handle, suffix_text) + else: + return u'!<%s>' % suffix_text + + def prepare_anchor(self, anchor): + if not anchor: + raise EmitterError("anchor must not be empty") + for ch in anchor: + if not (u'0' <= ch <= u'9' or u'A' <= ch <= u'Z' or u'a' <= ch <= u'z' \ + or ch in u'-_'): + raise EmitterError("invalid character %r in the anchor: %r" + % (ch.encode('utf-8'), anchor.encode('utf-8'))) + return anchor + + def analyze_scalar(self, scalar): + + # Empty scalar is a special case. + if not scalar: + return ScalarAnalysis(scalar=scalar, empty=True, multiline=False, + allow_flow_plain=False, allow_block_plain=True, + allow_single_quoted=True, allow_double_quoted=True, + allow_block=False) + + # Indicators and special characters. + block_indicators = False + flow_indicators = False + line_breaks = False + special_characters = False + + # Important whitespace combinations. + leading_space = False + leading_break = False + trailing_space = False + trailing_break = False + break_space = False + space_break = False + + # Check document indicators. + if scalar.startswith(u'---') or scalar.startswith(u'...'): + block_indicators = True + flow_indicators = True + + # First character or preceded by a whitespace. + preceeded_by_whitespace = True + + # Last character or followed by a whitespace. + followed_by_whitespace = (len(scalar) == 1 or + scalar[1] in u'\0 \t\r\n\x85\u2028\u2029') + + # The previous character is a space. + previous_space = False + + # The previous character is a break. + previous_break = False + + index = 0 + while index < len(scalar): + ch = scalar[index] + + # Check for indicators. + if index == 0: + # Leading indicators are special characters. + if ch in u'#,[]{}&*!|>\'\"%@`': + flow_indicators = True + block_indicators = True + if ch in u'?:': + flow_indicators = True + if followed_by_whitespace: + block_indicators = True + if ch == u'-' and followed_by_whitespace: + flow_indicators = True + block_indicators = True + else: + # Some indicators cannot appear within a scalar as well. + if ch in u',?[]{}': + flow_indicators = True + if ch == u':': + flow_indicators = True + if followed_by_whitespace: + block_indicators = True + if ch == u'#' and preceeded_by_whitespace: + flow_indicators = True + block_indicators = True + + # Check for line breaks, special, and unicode characters. + if ch in u'\n\x85\u2028\u2029': + line_breaks = True + if not (ch == u'\n' or u'\x20' <= ch <= u'\x7E'): + if (ch == u'\x85' or u'\xA0' <= ch <= u'\uD7FF' + or u'\uE000' <= ch <= u'\uFFFD') and ch != u'\uFEFF': + unicode_characters = True + if not self.allow_unicode: + special_characters = True + else: + special_characters = True + + # Detect important whitespace combinations. + if ch == u' ': + if index == 0: + leading_space = True + if index == len(scalar)-1: + trailing_space = True + if previous_break: + break_space = True + previous_space = True + previous_break = False + elif ch in u'\n\x85\u2028\u2029': + if index == 0: + leading_break = True + if index == len(scalar)-1: + trailing_break = True + if previous_space: + space_break = True + previous_space = False + previous_break = True + else: + previous_space = False + previous_break = False + + # Prepare for the next character. + index += 1 + preceeded_by_whitespace = (ch in u'\0 \t\r\n\x85\u2028\u2029') + followed_by_whitespace = (index+1 >= len(scalar) or + scalar[index+1] in u'\0 \t\r\n\x85\u2028\u2029') + + # Let's decide what styles are allowed. + allow_flow_plain = True + allow_block_plain = True + allow_single_quoted = True + allow_double_quoted = True + allow_block = True + + # Leading and trailing whitespaces are bad for plain scalars. + if (leading_space or leading_break + or trailing_space or trailing_break): + allow_flow_plain = allow_block_plain = False + + # We do not permit trailing spaces for block scalars. + if trailing_space: + allow_block = False + + # Spaces at the beginning of a new line are only acceptable for block + # scalars. + if break_space: + allow_flow_plain = allow_block_plain = allow_single_quoted = False + + # Spaces followed by breaks, as well as special character are only + # allowed for double quoted scalars. + if space_break or special_characters: + allow_flow_plain = allow_block_plain = \ + allow_single_quoted = allow_block = False + + # Although the plain scalar writer supports breaks, we never emit + # multiline plain scalars. + if line_breaks: + allow_flow_plain = allow_block_plain = False + + # Flow indicators are forbidden for flow plain scalars. + if flow_indicators: + allow_flow_plain = False + + # Block indicators are forbidden for block plain scalars. + if block_indicators: + allow_block_plain = False + + return ScalarAnalysis(scalar=scalar, + empty=False, multiline=line_breaks, + allow_flow_plain=allow_flow_plain, + allow_block_plain=allow_block_plain, + allow_single_quoted=allow_single_quoted, + allow_double_quoted=allow_double_quoted, + allow_block=allow_block) + + # Writers. + + def flush_stream(self): + if hasattr(self.stream, 'flush'): + self.stream.flush() + + def write_stream_start(self): + # Write BOM if needed. + if self.encoding and self.encoding.startswith('utf-16'): + self.stream.write(u'\uFEFF'.encode(self.encoding)) + + def write_stream_end(self): + self.flush_stream() + + def write_indicator(self, indicator, need_whitespace, + whitespace=False, indention=False): + if self.whitespace or not need_whitespace: + data = indicator + else: + data = u' '+indicator + self.whitespace = whitespace + self.indention = self.indention and indention + self.column += len(data) + self.open_ended = False + if self.encoding: + data = data.encode(self.encoding) + self.stream.write(data) + + def write_indent(self): + indent = self.indent or 0 + if not self.indention or self.column > indent \ + or (self.column == indent and not self.whitespace): + self.write_line_break() + if self.column < indent: + self.whitespace = True + data = u' '*(indent-self.column) + self.column = indent + if self.encoding: + data = data.encode(self.encoding) + self.stream.write(data) + + def write_line_break(self, data=None): + if data is None: + data = self.best_line_break + self.whitespace = True + self.indention = True + self.line += 1 + self.column = 0 + if self.encoding: + data = data.encode(self.encoding) + self.stream.write(data) + + def write_version_directive(self, version_text): + data = u'%%YAML %s' % version_text + if self.encoding: + data = data.encode(self.encoding) + self.stream.write(data) + self.write_line_break() + + def write_tag_directive(self, handle_text, prefix_text): + data = u'%%TAG %s %s' % (handle_text, prefix_text) + if self.encoding: + data = data.encode(self.encoding) + self.stream.write(data) + self.write_line_break() + + # Scalar streams. + + def write_single_quoted(self, text, split=True): + self.write_indicator(u'\'', True) + spaces = False + breaks = False + start = end = 0 + while end <= len(text): + ch = None + if end < len(text): + ch = text[end] + if spaces: + if ch is None or ch != u' ': + if start+1 == end and self.column > self.best_width and split \ + and start != 0 and end != len(text): + self.write_indent() + else: + data = text[start:end] + self.column += len(data) + if self.encoding: + data = data.encode(self.encoding) + self.stream.write(data) + start = end + elif breaks: + if ch is None or ch not in u'\n\x85\u2028\u2029': + if text[start] == u'\n': + self.write_line_break() + for br in text[start:end]: + if br == u'\n': + self.write_line_break() + else: + self.write_line_break(br) + self.write_indent() + start = end + else: + if ch is None or ch in u' \n\x85\u2028\u2029' or ch == u'\'': + if start < end: + data = text[start:end] + self.column += len(data) + if self.encoding: + data = data.encode(self.encoding) + self.stream.write(data) + start = end + if ch == u'\'': + data = u'\'\'' + self.column += 2 + if self.encoding: + data = data.encode(self.encoding) + self.stream.write(data) + start = end + 1 + if ch is not None: + spaces = (ch == u' ') + breaks = (ch in u'\n\x85\u2028\u2029') + end += 1 + self.write_indicator(u'\'', False) + + ESCAPE_REPLACEMENTS = { + u'\0': u'0', + u'\x07': u'a', + u'\x08': u'b', + u'\x09': u't', + u'\x0A': u'n', + u'\x0B': u'v', + u'\x0C': u'f', + u'\x0D': u'r', + u'\x1B': u'e', + u'\"': u'\"', + u'\\': u'\\', + u'\x85': u'N', + u'\xA0': u'_', + u'\u2028': u'L', + u'\u2029': u'P', + } + + def write_double_quoted(self, text, split=True): + self.write_indicator(u'"', True) + start = end = 0 + while end <= len(text): + ch = None + if end < len(text): + ch = text[end] + if ch is None or ch in u'"\\\x85\u2028\u2029\uFEFF' \ + or not (u'\x20' <= ch <= u'\x7E' + or (self.allow_unicode + and (u'\xA0' <= ch <= u'\uD7FF' + or u'\uE000' <= ch <= u'\uFFFD'))): + if start < end: + data = text[start:end] + self.column += len(data) + if self.encoding: + data = data.encode(self.encoding) + self.stream.write(data) + start = end + if ch is not None: + if ch in self.ESCAPE_REPLACEMENTS: + data = u'\\'+self.ESCAPE_REPLACEMENTS[ch] + elif ch <= u'\xFF': + data = u'\\x%02X' % ord(ch) + elif ch <= u'\uFFFF': + data = u'\\u%04X' % ord(ch) + else: + data = u'\\U%08X' % ord(ch) + self.column += len(data) + if self.encoding: + data = data.encode(self.encoding) + self.stream.write(data) + start = end+1 + if 0 < end < len(text)-1 and (ch == u' ' or start >= end) \ + and self.column+(end-start) > self.best_width and split: + data = text[start:end]+u'\\' + if start < end: + start = end + self.column += len(data) + if self.encoding: + data = data.encode(self.encoding) + self.stream.write(data) + self.write_indent() + self.whitespace = False + self.indention = False + if text[start] == u' ': + data = u'\\' + self.column += len(data) + if self.encoding: + data = data.encode(self.encoding) + self.stream.write(data) + end += 1 + self.write_indicator(u'"', False) + + def determine_block_hints(self, text): + hints = u'' + if text: + if text[0] in u' \n\x85\u2028\u2029': + hints += unicode(self.best_indent) + if text[-1] not in u'\n\x85\u2028\u2029': + hints += u'-' + elif len(text) == 1 or text[-2] in u'\n\x85\u2028\u2029': + hints += u'+' + return hints + + def write_folded(self, text): + hints = self.determine_block_hints(text) + self.write_indicator(u'>'+hints, True) + if hints[-1:] == u'+': + self.open_ended = True + self.write_line_break() + leading_space = True + spaces = False + breaks = True + start = end = 0 + while end <= len(text): + ch = None + if end < len(text): + ch = text[end] + if breaks: + if ch is None or ch not in u'\n\x85\u2028\u2029': + if not leading_space and ch is not None and ch != u' ' \ + and text[start] == u'\n': + self.write_line_break() + leading_space = (ch == u' ') + for br in text[start:end]: + if br == u'\n': + self.write_line_break() + else: + self.write_line_break(br) + if ch is not None: + self.write_indent() + start = end + elif spaces: + if ch != u' ': + if start+1 == end and self.column > self.best_width: + self.write_indent() + else: + data = text[start:end] + self.column += len(data) + if self.encoding: + data = data.encode(self.encoding) + self.stream.write(data) + start = end + else: + if ch is None or ch in u' \n\x85\u2028\u2029': + data = text[start:end] + self.column += len(data) + if self.encoding: + data = data.encode(self.encoding) + self.stream.write(data) + if ch is None: + self.write_line_break() + start = end + if ch is not None: + breaks = (ch in u'\n\x85\u2028\u2029') + spaces = (ch == u' ') + end += 1 + + def write_literal(self, text): + hints = self.determine_block_hints(text) + self.write_indicator(u'|'+hints, True) + if hints[-1:] == u'+': + self.open_ended = True + self.write_line_break() + breaks = True + start = end = 0 + while end <= len(text): + ch = None + if end < len(text): + ch = text[end] + if breaks: + if ch is None or ch not in u'\n\x85\u2028\u2029': + for br in text[start:end]: + if br == u'\n': + self.write_line_break() + else: + self.write_line_break(br) + if ch is not None: + self.write_indent() + start = end + else: + if ch is None or ch in u'\n\x85\u2028\u2029': + data = text[start:end] + if self.encoding: + data = data.encode(self.encoding) + self.stream.write(data) + if ch is None: + self.write_line_break() + start = end + if ch is not None: + breaks = (ch in u'\n\x85\u2028\u2029') + end += 1 + + def write_plain(self, text, split=True): + if self.root_context: + self.open_ended = True + if not text: + return + if not self.whitespace: + data = u' ' + self.column += len(data) + if self.encoding: + data = data.encode(self.encoding) + self.stream.write(data) + self.whitespace = False + self.indention = False + spaces = False + breaks = False + start = end = 0 + while end <= len(text): + ch = None + if end < len(text): + ch = text[end] + if spaces: + if ch != u' ': + if start+1 == end and self.column > self.best_width and split: + self.write_indent() + self.whitespace = False + self.indention = False + else: + data = text[start:end] + self.column += len(data) + if self.encoding: + data = data.encode(self.encoding) + self.stream.write(data) + start = end + elif breaks: + if ch not in u'\n\x85\u2028\u2029': + if text[start] == u'\n': + self.write_line_break() + for br in text[start:end]: + if br == u'\n': + self.write_line_break() + else: + self.write_line_break(br) + self.write_indent() + self.whitespace = False + self.indention = False + start = end + else: + if ch is None or ch in u' \n\x85\u2028\u2029': + data = text[start:end] + self.column += len(data) + if self.encoding: + data = data.encode(self.encoding) + self.stream.write(data) + start = end + if ch is not None: + spaces = (ch == u' ') + breaks = (ch in u'\n\x85\u2028\u2029') + end += 1 + diff --git a/rplibs/yaml/yaml_py2/error.py b/rplibs/yaml/yaml_py2/error.py new file mode 100644 index 0000000..577686d --- /dev/null +++ b/rplibs/yaml/yaml_py2/error.py @@ -0,0 +1,75 @@ + +__all__ = ['Mark', 'YAMLError', 'MarkedYAMLError'] + +class Mark(object): + + def __init__(self, name, index, line, column, buffer, pointer): + self.name = name + self.index = index + self.line = line + self.column = column + self.buffer = buffer + self.pointer = pointer + + def get_snippet(self, indent=4, max_length=75): + if self.buffer is None: + return None + head = '' + start = self.pointer + while start > 0 and self.buffer[start-1] not in u'\0\r\n\x85\u2028\u2029': + start -= 1 + if self.pointer-start > max_length/2-1: + head = ' ... ' + start += 5 + break + tail = '' + end = self.pointer + while end < len(self.buffer) and self.buffer[end] not in u'\0\r\n\x85\u2028\u2029': + end += 1 + if end-self.pointer > max_length/2-1: + tail = ' ... ' + end -= 5 + break + snippet = self.buffer[start:end].encode('utf-8') + return ' '*indent + head + snippet + tail + '\n' \ + + ' '*(indent+self.pointer-start+len(head)) + '^' + + def __str__(self): + snippet = self.get_snippet() + where = " in \"%s\", line %d, column %d" \ + % (self.name, self.line+1, self.column+1) + if snippet is not None: + where += ":\n"+snippet + return where + +class YAMLError(Exception): + pass + +class MarkedYAMLError(YAMLError): + + def __init__(self, context=None, context_mark=None, + problem=None, problem_mark=None, note=None): + self.context = context + self.context_mark = context_mark + self.problem = problem + self.problem_mark = problem_mark + self.note = note + + def __str__(self): + lines = [] + if self.context is not None: + lines.append(self.context) + if self.context_mark is not None \ + and (self.problem is None or self.problem_mark is None + or self.context_mark.name != self.problem_mark.name + or self.context_mark.line != self.problem_mark.line + or self.context_mark.column != self.problem_mark.column): + lines.append(str(self.context_mark)) + if self.problem is not None: + lines.append(self.problem) + if self.problem_mark is not None: + lines.append(str(self.problem_mark)) + if self.note is not None: + lines.append(self.note) + return '\n'.join(lines) + diff --git a/rplibs/yaml/yaml_py2/events.py b/rplibs/yaml/yaml_py2/events.py new file mode 100644 index 0000000..f79ad38 --- /dev/null +++ b/rplibs/yaml/yaml_py2/events.py @@ -0,0 +1,86 @@ + +# Abstract classes. + +class Event(object): + def __init__(self, start_mark=None, end_mark=None): + self.start_mark = start_mark + self.end_mark = end_mark + def __repr__(self): + attributes = [key for key in ['anchor', 'tag', 'implicit', 'value'] + if hasattr(self, key)] + arguments = ', '.join(['%s=%r' % (key, getattr(self, key)) + for key in attributes]) + return '%s(%s)' % (self.__class__.__name__, arguments) + +class NodeEvent(Event): + def __init__(self, anchor, start_mark=None, end_mark=None): + self.anchor = anchor + self.start_mark = start_mark + self.end_mark = end_mark + +class CollectionStartEvent(NodeEvent): + def __init__(self, anchor, tag, implicit, start_mark=None, end_mark=None, + flow_style=None): + self.anchor = anchor + self.tag = tag + self.implicit = implicit + self.start_mark = start_mark + self.end_mark = end_mark + self.flow_style = flow_style + +class CollectionEndEvent(Event): + pass + +# Implementations. + +class StreamStartEvent(Event): + def __init__(self, start_mark=None, end_mark=None, encoding=None): + self.start_mark = start_mark + self.end_mark = end_mark + self.encoding = encoding + +class StreamEndEvent(Event): + pass + +class DocumentStartEvent(Event): + def __init__(self, start_mark=None, end_mark=None, + explicit=None, version=None, tags=None): + self.start_mark = start_mark + self.end_mark = end_mark + self.explicit = explicit + self.version = version + self.tags = tags + +class DocumentEndEvent(Event): + def __init__(self, start_mark=None, end_mark=None, + explicit=None): + self.start_mark = start_mark + self.end_mark = end_mark + self.explicit = explicit + +class AliasEvent(NodeEvent): + pass + +class ScalarEvent(NodeEvent): + def __init__(self, anchor, tag, implicit, value, + start_mark=None, end_mark=None, style=None): + self.anchor = anchor + self.tag = tag + self.implicit = implicit + self.value = value + self.start_mark = start_mark + self.end_mark = end_mark + self.style = style + +class SequenceStartEvent(CollectionStartEvent): + pass + +class SequenceEndEvent(CollectionEndEvent): + pass + +class MappingStartEvent(CollectionStartEvent): + pass + +class MappingEndEvent(CollectionEndEvent): + pass + diff --git a/rplibs/yaml/yaml_py2/loader.py b/rplibs/yaml/yaml_py2/loader.py new file mode 100644 index 0000000..293ff46 --- /dev/null +++ b/rplibs/yaml/yaml_py2/loader.py @@ -0,0 +1,40 @@ + +__all__ = ['BaseLoader', 'SafeLoader', 'Loader'] + +from reader import * +from scanner import * +from parser import * +from composer import * +from constructor import * +from resolver import * + +class BaseLoader(Reader, Scanner, Parser, Composer, BaseConstructor, BaseResolver): + + def __init__(self, stream): + Reader.__init__(self, stream) + Scanner.__init__(self) + Parser.__init__(self) + Composer.__init__(self) + BaseConstructor.__init__(self) + BaseResolver.__init__(self) + +class SafeLoader(Reader, Scanner, Parser, Composer, SafeConstructor, Resolver): + + def __init__(self, stream): + Reader.__init__(self, stream) + Scanner.__init__(self) + Parser.__init__(self) + Composer.__init__(self) + SafeConstructor.__init__(self) + Resolver.__init__(self) + +class Loader(Reader, Scanner, Parser, Composer, Constructor, Resolver): + + def __init__(self, stream): + Reader.__init__(self, stream) + Scanner.__init__(self) + Parser.__init__(self) + Composer.__init__(self) + Constructor.__init__(self) + Resolver.__init__(self) + diff --git a/rplibs/yaml/yaml_py2/nodes.py b/rplibs/yaml/yaml_py2/nodes.py new file mode 100644 index 0000000..c4f070c --- /dev/null +++ b/rplibs/yaml/yaml_py2/nodes.py @@ -0,0 +1,49 @@ + +class Node(object): + def __init__(self, tag, value, start_mark, end_mark): + self.tag = tag + self.value = value + self.start_mark = start_mark + self.end_mark = end_mark + def __repr__(self): + value = self.value + #if isinstance(value, list): + # if len(value) == 0: + # value = '' + # elif len(value) == 1: + # value = '<1 item>' + # else: + # value = '<%d items>' % len(value) + #else: + # if len(value) > 75: + # value = repr(value[:70]+u' ... ') + # else: + # value = repr(value) + value = repr(value) + return '%s(tag=%r, value=%s)' % (self.__class__.__name__, self.tag, value) + +class ScalarNode(Node): + id = 'scalar' + def __init__(self, tag, value, + start_mark=None, end_mark=None, style=None): + self.tag = tag + self.value = value + self.start_mark = start_mark + self.end_mark = end_mark + self.style = style + +class CollectionNode(Node): + def __init__(self, tag, value, + start_mark=None, end_mark=None, flow_style=None): + self.tag = tag + self.value = value + self.start_mark = start_mark + self.end_mark = end_mark + self.flow_style = flow_style + +class SequenceNode(CollectionNode): + id = 'sequence' + +class MappingNode(CollectionNode): + id = 'mapping' + diff --git a/rplibs/yaml/yaml_py2/parser.py b/rplibs/yaml/yaml_py2/parser.py new file mode 100644 index 0000000..f9e3057 --- /dev/null +++ b/rplibs/yaml/yaml_py2/parser.py @@ -0,0 +1,589 @@ + +# The following YAML grammar is LL(1) and is parsed by a recursive descent +# parser. +# +# stream ::= STREAM-START implicit_document? explicit_document* STREAM-END +# implicit_document ::= block_node DOCUMENT-END* +# explicit_document ::= DIRECTIVE* DOCUMENT-START block_node? DOCUMENT-END* +# block_node_or_indentless_sequence ::= +# ALIAS +# | properties (block_content | indentless_block_sequence)? +# | block_content +# | indentless_block_sequence +# block_node ::= ALIAS +# | properties block_content? +# | block_content +# flow_node ::= ALIAS +# | properties flow_content? +# | flow_content +# properties ::= TAG ANCHOR? | ANCHOR TAG? +# block_content ::= block_collection | flow_collection | SCALAR +# flow_content ::= flow_collection | SCALAR +# block_collection ::= block_sequence | block_mapping +# flow_collection ::= flow_sequence | flow_mapping +# block_sequence ::= BLOCK-SEQUENCE-START (BLOCK-ENTRY block_node?)* BLOCK-END +# indentless_sequence ::= (BLOCK-ENTRY block_node?)+ +# block_mapping ::= BLOCK-MAPPING_START +# ((KEY block_node_or_indentless_sequence?)? +# (VALUE block_node_or_indentless_sequence?)?)* +# BLOCK-END +# flow_sequence ::= FLOW-SEQUENCE-START +# (flow_sequence_entry FLOW-ENTRY)* +# flow_sequence_entry? +# FLOW-SEQUENCE-END +# flow_sequence_entry ::= flow_node | KEY flow_node? (VALUE flow_node?)? +# flow_mapping ::= FLOW-MAPPING-START +# (flow_mapping_entry FLOW-ENTRY)* +# flow_mapping_entry? +# FLOW-MAPPING-END +# flow_mapping_entry ::= flow_node | KEY flow_node? (VALUE flow_node?)? +# +# FIRST sets: +# +# stream: { STREAM-START } +# explicit_document: { DIRECTIVE DOCUMENT-START } +# implicit_document: FIRST(block_node) +# block_node: { ALIAS TAG ANCHOR SCALAR BLOCK-SEQUENCE-START BLOCK-MAPPING-START FLOW-SEQUENCE-START FLOW-MAPPING-START } +# flow_node: { ALIAS ANCHOR TAG SCALAR FLOW-SEQUENCE-START FLOW-MAPPING-START } +# block_content: { BLOCK-SEQUENCE-START BLOCK-MAPPING-START FLOW-SEQUENCE-START FLOW-MAPPING-START SCALAR } +# flow_content: { FLOW-SEQUENCE-START FLOW-MAPPING-START SCALAR } +# block_collection: { BLOCK-SEQUENCE-START BLOCK-MAPPING-START } +# flow_collection: { FLOW-SEQUENCE-START FLOW-MAPPING-START } +# block_sequence: { BLOCK-SEQUENCE-START } +# block_mapping: { BLOCK-MAPPING-START } +# block_node_or_indentless_sequence: { ALIAS ANCHOR TAG SCALAR BLOCK-SEQUENCE-START BLOCK-MAPPING-START FLOW-SEQUENCE-START FLOW-MAPPING-START BLOCK-ENTRY } +# indentless_sequence: { ENTRY } +# flow_collection: { FLOW-SEQUENCE-START FLOW-MAPPING-START } +# flow_sequence: { FLOW-SEQUENCE-START } +# flow_mapping: { FLOW-MAPPING-START } +# flow_sequence_entry: { ALIAS ANCHOR TAG SCALAR FLOW-SEQUENCE-START FLOW-MAPPING-START KEY } +# flow_mapping_entry: { ALIAS ANCHOR TAG SCALAR FLOW-SEQUENCE-START FLOW-MAPPING-START KEY } + +__all__ = ['Parser', 'ParserError'] + +from error import MarkedYAMLError +from tokens import * +from events import * +from scanner import * + +class ParserError(MarkedYAMLError): + pass + +class Parser(object): + # Since writing a recursive-descendant parser is a straightforward task, we + # do not give many comments here. + + DEFAULT_TAGS = { + u'!': u'!', + u'!!': u'tag:yaml.org,2002:', + } + + def __init__(self): + self.current_event = None + self.yaml_version = None + self.tag_handles = {} + self.states = [] + self.marks = [] + self.state = self.parse_stream_start + + def dispose(self): + # Reset the state attributes (to clear self-references) + self.states = [] + self.state = None + + def check_event(self, *choices): + # Check the type of the next event. + if self.current_event is None: + if self.state: + self.current_event = self.state() + if self.current_event is not None: + if not choices: + return True + for choice in choices: + if isinstance(self.current_event, choice): + return True + return False + + def peek_event(self): + # Get the next event. + if self.current_event is None: + if self.state: + self.current_event = self.state() + return self.current_event + + def get_event(self): + # Get the next event and proceed further. + if self.current_event is None: + if self.state: + self.current_event = self.state() + value = self.current_event + self.current_event = None + return value + + # stream ::= STREAM-START implicit_document? explicit_document* STREAM-END + # implicit_document ::= block_node DOCUMENT-END* + # explicit_document ::= DIRECTIVE* DOCUMENT-START block_node? DOCUMENT-END* + + def parse_stream_start(self): + + # Parse the stream start. + token = self.get_token() + event = StreamStartEvent(token.start_mark, token.end_mark, + encoding=token.encoding) + + # Prepare the next state. + self.state = self.parse_implicit_document_start + + return event + + def parse_implicit_document_start(self): + + # Parse an implicit document. + if not self.check_token(DirectiveToken, DocumentStartToken, + StreamEndToken): + self.tag_handles = self.DEFAULT_TAGS + token = self.peek_token() + start_mark = end_mark = token.start_mark + event = DocumentStartEvent(start_mark, end_mark, + explicit=False) + + # Prepare the next state. + self.states.append(self.parse_document_end) + self.state = self.parse_block_node + + return event + + else: + return self.parse_document_start() + + def parse_document_start(self): + + # Parse any extra document end indicators. + while self.check_token(DocumentEndToken): + self.get_token() + + # Parse an explicit document. + if not self.check_token(StreamEndToken): + token = self.peek_token() + start_mark = token.start_mark + version, tags = self.process_directives() + if not self.check_token(DocumentStartToken): + raise ParserError(None, None, + "expected '', but found %r" + % self.peek_token().id, + self.peek_token().start_mark) + token = self.get_token() + end_mark = token.end_mark + event = DocumentStartEvent(start_mark, end_mark, + explicit=True, version=version, tags=tags) + self.states.append(self.parse_document_end) + self.state = self.parse_document_content + else: + # Parse the end of the stream. + token = self.get_token() + event = StreamEndEvent(token.start_mark, token.end_mark) + assert not self.states + assert not self.marks + self.state = None + return event + + def parse_document_end(self): + + # Parse the document end. + token = self.peek_token() + start_mark = end_mark = token.start_mark + explicit = False + if self.check_token(DocumentEndToken): + token = self.get_token() + end_mark = token.end_mark + explicit = True + event = DocumentEndEvent(start_mark, end_mark, + explicit=explicit) + + # Prepare the next state. + self.state = self.parse_document_start + + return event + + def parse_document_content(self): + if self.check_token(DirectiveToken, + DocumentStartToken, DocumentEndToken, StreamEndToken): + event = self.process_empty_scalar(self.peek_token().start_mark) + self.state = self.states.pop() + return event + else: + return self.parse_block_node() + + def process_directives(self): + self.yaml_version = None + self.tag_handles = {} + while self.check_token(DirectiveToken): + token = self.get_token() + if token.name == u'YAML': + if self.yaml_version is not None: + raise ParserError(None, None, + "found duplicate YAML directive", token.start_mark) + major, minor = token.value + if major != 1: + raise ParserError(None, None, + "found incompatible YAML document (version 1.* is required)", + token.start_mark) + self.yaml_version = token.value + elif token.name == u'TAG': + handle, prefix = token.value + if handle in self.tag_handles: + raise ParserError(None, None, + "duplicate tag handle %r" % handle.encode('utf-8'), + token.start_mark) + self.tag_handles[handle] = prefix + if self.tag_handles: + value = self.yaml_version, self.tag_handles.copy() + else: + value = self.yaml_version, None + for key in self.DEFAULT_TAGS: + if key not in self.tag_handles: + self.tag_handles[key] = self.DEFAULT_TAGS[key] + return value + + # block_node_or_indentless_sequence ::= ALIAS + # | properties (block_content | indentless_block_sequence)? + # | block_content + # | indentless_block_sequence + # block_node ::= ALIAS + # | properties block_content? + # | block_content + # flow_node ::= ALIAS + # | properties flow_content? + # | flow_content + # properties ::= TAG ANCHOR? | ANCHOR TAG? + # block_content ::= block_collection | flow_collection | SCALAR + # flow_content ::= flow_collection | SCALAR + # block_collection ::= block_sequence | block_mapping + # flow_collection ::= flow_sequence | flow_mapping + + def parse_block_node(self): + return self.parse_node(block=True) + + def parse_flow_node(self): + return self.parse_node() + + def parse_block_node_or_indentless_sequence(self): + return self.parse_node(block=True, indentless_sequence=True) + + def parse_node(self, block=False, indentless_sequence=False): + if self.check_token(AliasToken): + token = self.get_token() + event = AliasEvent(token.value, token.start_mark, token.end_mark) + self.state = self.states.pop() + else: + anchor = None + tag = None + start_mark = end_mark = tag_mark = None + if self.check_token(AnchorToken): + token = self.get_token() + start_mark = token.start_mark + end_mark = token.end_mark + anchor = token.value + if self.check_token(TagToken): + token = self.get_token() + tag_mark = token.start_mark + end_mark = token.end_mark + tag = token.value + elif self.check_token(TagToken): + token = self.get_token() + start_mark = tag_mark = token.start_mark + end_mark = token.end_mark + tag = token.value + if self.check_token(AnchorToken): + token = self.get_token() + end_mark = token.end_mark + anchor = token.value + if tag is not None: + handle, suffix = tag + if handle is not None: + if handle not in self.tag_handles: + raise ParserError("while parsing a node", start_mark, + "found undefined tag handle %r" % handle.encode('utf-8'), + tag_mark) + tag = self.tag_handles[handle]+suffix + else: + tag = suffix + #if tag == u'!': + # raise ParserError("while parsing a node", start_mark, + # "found non-specific tag '!'", tag_mark, + # "Please check 'http://pyyaml.org/wiki/YAMLNonSpecificTag' and share your opinion.") + if start_mark is None: + start_mark = end_mark = self.peek_token().start_mark + event = None + implicit = (tag is None or tag == u'!') + if indentless_sequence and self.check_token(BlockEntryToken): + end_mark = self.peek_token().end_mark + event = SequenceStartEvent(anchor, tag, implicit, + start_mark, end_mark) + self.state = self.parse_indentless_sequence_entry + else: + if self.check_token(ScalarToken): + token = self.get_token() + end_mark = token.end_mark + if (token.plain and tag is None) or tag == u'!': + implicit = (True, False) + elif tag is None: + implicit = (False, True) + else: + implicit = (False, False) + event = ScalarEvent(anchor, tag, implicit, token.value, + start_mark, end_mark, style=token.style) + self.state = self.states.pop() + elif self.check_token(FlowSequenceStartToken): + end_mark = self.peek_token().end_mark + event = SequenceStartEvent(anchor, tag, implicit, + start_mark, end_mark, flow_style=True) + self.state = self.parse_flow_sequence_first_entry + elif self.check_token(FlowMappingStartToken): + end_mark = self.peek_token().end_mark + event = MappingStartEvent(anchor, tag, implicit, + start_mark, end_mark, flow_style=True) + self.state = self.parse_flow_mapping_first_key + elif block and self.check_token(BlockSequenceStartToken): + end_mark = self.peek_token().start_mark + event = SequenceStartEvent(anchor, tag, implicit, + start_mark, end_mark, flow_style=False) + self.state = self.parse_block_sequence_first_entry + elif block and self.check_token(BlockMappingStartToken): + end_mark = self.peek_token().start_mark + event = MappingStartEvent(anchor, tag, implicit, + start_mark, end_mark, flow_style=False) + self.state = self.parse_block_mapping_first_key + elif anchor is not None or tag is not None: + # Empty scalars are allowed even if a tag or an anchor is + # specified. + event = ScalarEvent(anchor, tag, (implicit, False), u'', + start_mark, end_mark) + self.state = self.states.pop() + else: + if block: + node = 'block' + else: + node = 'flow' + token = self.peek_token() + raise ParserError("while parsing a %s node" % node, start_mark, + "expected the node content, but found %r" % token.id, + token.start_mark) + return event + + # block_sequence ::= BLOCK-SEQUENCE-START (BLOCK-ENTRY block_node?)* BLOCK-END + + def parse_block_sequence_first_entry(self): + token = self.get_token() + self.marks.append(token.start_mark) + return self.parse_block_sequence_entry() + + def parse_block_sequence_entry(self): + if self.check_token(BlockEntryToken): + token = self.get_token() + if not self.check_token(BlockEntryToken, BlockEndToken): + self.states.append(self.parse_block_sequence_entry) + return self.parse_block_node() + else: + self.state = self.parse_block_sequence_entry + return self.process_empty_scalar(token.end_mark) + if not self.check_token(BlockEndToken): + token = self.peek_token() + raise ParserError("while parsing a block collection", self.marks[-1], + "expected , but found %r" % token.id, token.start_mark) + token = self.get_token() + event = SequenceEndEvent(token.start_mark, token.end_mark) + self.state = self.states.pop() + self.marks.pop() + return event + + # indentless_sequence ::= (BLOCK-ENTRY block_node?)+ + + def parse_indentless_sequence_entry(self): + if self.check_token(BlockEntryToken): + token = self.get_token() + if not self.check_token(BlockEntryToken, + KeyToken, ValueToken, BlockEndToken): + self.states.append(self.parse_indentless_sequence_entry) + return self.parse_block_node() + else: + self.state = self.parse_indentless_sequence_entry + return self.process_empty_scalar(token.end_mark) + token = self.peek_token() + event = SequenceEndEvent(token.start_mark, token.start_mark) + self.state = self.states.pop() + return event + + # block_mapping ::= BLOCK-MAPPING_START + # ((KEY block_node_or_indentless_sequence?)? + # (VALUE block_node_or_indentless_sequence?)?)* + # BLOCK-END + + def parse_block_mapping_first_key(self): + token = self.get_token() + self.marks.append(token.start_mark) + return self.parse_block_mapping_key() + + def parse_block_mapping_key(self): + if self.check_token(KeyToken): + token = self.get_token() + if not self.check_token(KeyToken, ValueToken, BlockEndToken): + self.states.append(self.parse_block_mapping_value) + return self.parse_block_node_or_indentless_sequence() + else: + self.state = self.parse_block_mapping_value + return self.process_empty_scalar(token.end_mark) + if not self.check_token(BlockEndToken): + token = self.peek_token() + raise ParserError("while parsing a block mapping", self.marks[-1], + "expected , but found %r" % token.id, token.start_mark) + token = self.get_token() + event = MappingEndEvent(token.start_mark, token.end_mark) + self.state = self.states.pop() + self.marks.pop() + return event + + def parse_block_mapping_value(self): + if self.check_token(ValueToken): + token = self.get_token() + if not self.check_token(KeyToken, ValueToken, BlockEndToken): + self.states.append(self.parse_block_mapping_key) + return self.parse_block_node_or_indentless_sequence() + else: + self.state = self.parse_block_mapping_key + return self.process_empty_scalar(token.end_mark) + else: + self.state = self.parse_block_mapping_key + token = self.peek_token() + return self.process_empty_scalar(token.start_mark) + + # flow_sequence ::= FLOW-SEQUENCE-START + # (flow_sequence_entry FLOW-ENTRY)* + # flow_sequence_entry? + # FLOW-SEQUENCE-END + # flow_sequence_entry ::= flow_node | KEY flow_node? (VALUE flow_node?)? + # + # Note that while production rules for both flow_sequence_entry and + # flow_mapping_entry are equal, their interpretations are different. + # For `flow_sequence_entry`, the part `KEY flow_node? (VALUE flow_node?)?` + # generate an inline mapping (set syntax). + + def parse_flow_sequence_first_entry(self): + token = self.get_token() + self.marks.append(token.start_mark) + return self.parse_flow_sequence_entry(first=True) + + def parse_flow_sequence_entry(self, first=False): + if not self.check_token(FlowSequenceEndToken): + if not first: + if self.check_token(FlowEntryToken): + self.get_token() + else: + token = self.peek_token() + raise ParserError("while parsing a flow sequence", self.marks[-1], + "expected ',' or ']', but got %r" % token.id, token.start_mark) + + if self.check_token(KeyToken): + token = self.peek_token() + event = MappingStartEvent(None, None, True, + token.start_mark, token.end_mark, + flow_style=True) + self.state = self.parse_flow_sequence_entry_mapping_key + return event + elif not self.check_token(FlowSequenceEndToken): + self.states.append(self.parse_flow_sequence_entry) + return self.parse_flow_node() + token = self.get_token() + event = SequenceEndEvent(token.start_mark, token.end_mark) + self.state = self.states.pop() + self.marks.pop() + return event + + def parse_flow_sequence_entry_mapping_key(self): + token = self.get_token() + if not self.check_token(ValueToken, + FlowEntryToken, FlowSequenceEndToken): + self.states.append(self.parse_flow_sequence_entry_mapping_value) + return self.parse_flow_node() + else: + self.state = self.parse_flow_sequence_entry_mapping_value + return self.process_empty_scalar(token.end_mark) + + def parse_flow_sequence_entry_mapping_value(self): + if self.check_token(ValueToken): + token = self.get_token() + if not self.check_token(FlowEntryToken, FlowSequenceEndToken): + self.states.append(self.parse_flow_sequence_entry_mapping_end) + return self.parse_flow_node() + else: + self.state = self.parse_flow_sequence_entry_mapping_end + return self.process_empty_scalar(token.end_mark) + else: + self.state = self.parse_flow_sequence_entry_mapping_end + token = self.peek_token() + return self.process_empty_scalar(token.start_mark) + + def parse_flow_sequence_entry_mapping_end(self): + self.state = self.parse_flow_sequence_entry + token = self.peek_token() + return MappingEndEvent(token.start_mark, token.start_mark) + + # flow_mapping ::= FLOW-MAPPING-START + # (flow_mapping_entry FLOW-ENTRY)* + # flow_mapping_entry? + # FLOW-MAPPING-END + # flow_mapping_entry ::= flow_node | KEY flow_node? (VALUE flow_node?)? + + def parse_flow_mapping_first_key(self): + token = self.get_token() + self.marks.append(token.start_mark) + return self.parse_flow_mapping_key(first=True) + + def parse_flow_mapping_key(self, first=False): + if not self.check_token(FlowMappingEndToken): + if not first: + if self.check_token(FlowEntryToken): + self.get_token() + else: + token = self.peek_token() + raise ParserError("while parsing a flow mapping", self.marks[-1], + "expected ',' or '}', but got %r" % token.id, token.start_mark) + if self.check_token(KeyToken): + token = self.get_token() + if not self.check_token(ValueToken, + FlowEntryToken, FlowMappingEndToken): + self.states.append(self.parse_flow_mapping_value) + return self.parse_flow_node() + else: + self.state = self.parse_flow_mapping_value + return self.process_empty_scalar(token.end_mark) + elif not self.check_token(FlowMappingEndToken): + self.states.append(self.parse_flow_mapping_empty_value) + return self.parse_flow_node() + token = self.get_token() + event = MappingEndEvent(token.start_mark, token.end_mark) + self.state = self.states.pop() + self.marks.pop() + return event + + def parse_flow_mapping_value(self): + if self.check_token(ValueToken): + token = self.get_token() + if not self.check_token(FlowEntryToken, FlowMappingEndToken): + self.states.append(self.parse_flow_mapping_key) + return self.parse_flow_node() + else: + self.state = self.parse_flow_mapping_key + return self.process_empty_scalar(token.end_mark) + else: + self.state = self.parse_flow_mapping_key + token = self.peek_token() + return self.process_empty_scalar(token.start_mark) + + def parse_flow_mapping_empty_value(self): + self.state = self.parse_flow_mapping_key + return self.process_empty_scalar(self.peek_token().start_mark) + + def process_empty_scalar(self, mark): + return ScalarEvent(None, None, (True, False), u'', mark, mark) + diff --git a/rplibs/yaml/yaml_py2/reader.py b/rplibs/yaml/yaml_py2/reader.py new file mode 100644 index 0000000..3249e6b --- /dev/null +++ b/rplibs/yaml/yaml_py2/reader.py @@ -0,0 +1,190 @@ +# This module contains abstractions for the input stream. You don't have to +# looks further, there are no pretty code. +# +# We define two classes here. +# +# Mark(source, line, column) +# It's just a record and its only use is producing nice error messages. +# Parser does not use it for any other purposes. +# +# Reader(source, data) +# Reader determines the encoding of `data` and converts it to unicode. +# Reader provides the following methods and attributes: +# reader.peek(length=1) - return the next `length` characters +# reader.forward(length=1) - move the current position to `length` characters. +# reader.index - the number of the current character. +# reader.line, stream.column - the line and the column of the current character. + +__all__ = ['Reader', 'ReaderError'] + +from error import YAMLError, Mark + +import codecs, re + +class ReaderError(YAMLError): + + def __init__(self, name, position, character, encoding, reason): + self.name = name + self.character = character + self.position = position + self.encoding = encoding + self.reason = reason + + def __str__(self): + if isinstance(self.character, str): + return "'%s' codec can't decode byte #x%02x: %s\n" \ + " in \"%s\", position %d" \ + % (self.encoding, ord(self.character), self.reason, + self.name, self.position) + else: + return "unacceptable character #x%04x: %s\n" \ + " in \"%s\", position %d" \ + % (self.character, self.reason, + self.name, self.position) + +class Reader(object): + # Reader: + # - determines the data encoding and converts it to unicode, + # - checks if characters are in allowed range, + # - adds '\0' to the end. + + # Reader accepts + # - a `str` object, + # - a `unicode` object, + # - a file-like object with its `read` method returning `str`, + # - a file-like object with its `read` method returning `unicode`. + + # Yeah, it's ugly and slow. + + def __init__(self, stream): + self.name = None + self.stream = None + self.stream_pointer = 0 + self.eof = True + self.buffer = u'' + self.pointer = 0 + self.raw_buffer = None + self.raw_decode = None + self.encoding = None + self.index = 0 + self.line = 0 + self.column = 0 + if isinstance(stream, unicode): + self.name = "" + self.check_printable(stream) + self.buffer = stream+u'\0' + elif isinstance(stream, str): + self.name = "" + self.raw_buffer = stream + self.determine_encoding() + else: + self.stream = stream + self.name = getattr(stream, 'name', "") + self.eof = False + self.raw_buffer = '' + self.determine_encoding() + + def peek(self, index=0): + try: + return self.buffer[self.pointer+index] + except IndexError: + self.update(index+1) + return self.buffer[self.pointer+index] + + def prefix(self, length=1): + if self.pointer+length >= len(self.buffer): + self.update(length) + return self.buffer[self.pointer:self.pointer+length] + + def forward(self, length=1): + if self.pointer+length+1 >= len(self.buffer): + self.update(length+1) + while length: + ch = self.buffer[self.pointer] + self.pointer += 1 + self.index += 1 + if ch in u'\n\x85\u2028\u2029' \ + or (ch == u'\r' and self.buffer[self.pointer] != u'\n'): + self.line += 1 + self.column = 0 + elif ch != u'\uFEFF': + self.column += 1 + length -= 1 + + def get_mark(self): + if self.stream is None: + return Mark(self.name, self.index, self.line, self.column, + self.buffer, self.pointer) + else: + return Mark(self.name, self.index, self.line, self.column, + None, None) + + def determine_encoding(self): + while not self.eof and len(self.raw_buffer) < 2: + self.update_raw() + if not isinstance(self.raw_buffer, unicode): + if self.raw_buffer.startswith(codecs.BOM_UTF16_LE): + self.raw_decode = codecs.utf_16_le_decode + self.encoding = 'utf-16-le' + elif self.raw_buffer.startswith(codecs.BOM_UTF16_BE): + self.raw_decode = codecs.utf_16_be_decode + self.encoding = 'utf-16-be' + else: + self.raw_decode = codecs.utf_8_decode + self.encoding = 'utf-8' + self.update(1) + + NON_PRINTABLE = re.compile(u'[^\x09\x0A\x0D\x20-\x7E\x85\xA0-\uD7FF\uE000-\uFFFD]') + def check_printable(self, data): + match = self.NON_PRINTABLE.search(data) + if match: + character = match.group() + position = self.index+(len(self.buffer)-self.pointer)+match.start() + raise ReaderError(self.name, position, ord(character), + 'unicode', "special characters are not allowed") + + def update(self, length): + if self.raw_buffer is None: + return + self.buffer = self.buffer[self.pointer:] + self.pointer = 0 + while len(self.buffer) < length: + if not self.eof: + self.update_raw() + if self.raw_decode is not None: + try: + data, converted = self.raw_decode(self.raw_buffer, + 'strict', self.eof) + except UnicodeDecodeError, exc: + character = exc.object[exc.start] + if self.stream is not None: + position = self.stream_pointer-len(self.raw_buffer)+exc.start + else: + position = exc.start + raise ReaderError(self.name, position, character, + exc.encoding, exc.reason) + else: + data = self.raw_buffer + converted = len(data) + self.check_printable(data) + self.buffer += data + self.raw_buffer = self.raw_buffer[converted:] + if self.eof: + self.buffer += u'\0' + self.raw_buffer = None + break + + def update_raw(self, size=1024): + data = self.stream.read(size) + if data: + self.raw_buffer += data + self.stream_pointer += len(data) + else: + self.eof = True + +#try: +# import psyco +# psyco.bind(Reader) +#except ImportError: +# pass + diff --git a/rplibs/yaml/yaml_py2/representer.py b/rplibs/yaml/yaml_py2/representer.py new file mode 100644 index 0000000..5f4fc70 --- /dev/null +++ b/rplibs/yaml/yaml_py2/representer.py @@ -0,0 +1,484 @@ + +__all__ = ['BaseRepresenter', 'SafeRepresenter', 'Representer', + 'RepresenterError'] + +from error import * +from nodes import * + +import datetime + +import sys, copy_reg, types + +class RepresenterError(YAMLError): + pass + +class BaseRepresenter(object): + + yaml_representers = {} + yaml_multi_representers = {} + + def __init__(self, default_style=None, default_flow_style=None): + self.default_style = default_style + self.default_flow_style = default_flow_style + self.represented_objects = {} + self.object_keeper = [] + self.alias_key = None + + def represent(self, data): + node = self.represent_data(data) + self.serialize(node) + self.represented_objects = {} + self.object_keeper = [] + self.alias_key = None + + def get_classobj_bases(self, cls): + bases = [cls] + for base in cls.__bases__: + bases.extend(self.get_classobj_bases(base)) + return bases + + def represent_data(self, data): + if self.ignore_aliases(data): + self.alias_key = None + else: + self.alias_key = id(data) + if self.alias_key is not None: + if self.alias_key in self.represented_objects: + node = self.represented_objects[self.alias_key] + #if node is None: + # raise RepresenterError("recursive objects are not allowed: %r" % data) + return node + #self.represented_objects[alias_key] = None + self.object_keeper.append(data) + data_types = type(data).__mro__ + if type(data) is types.InstanceType: + data_types = self.get_classobj_bases(data.__class__)+list(data_types) + if data_types[0] in self.yaml_representers: + node = self.yaml_representers[data_types[0]](self, data) + else: + for data_type in data_types: + if data_type in self.yaml_multi_representers: + node = self.yaml_multi_representers[data_type](self, data) + break + else: + if None in self.yaml_multi_representers: + node = self.yaml_multi_representers[None](self, data) + elif None in self.yaml_representers: + node = self.yaml_representers[None](self, data) + else: + node = ScalarNode(None, unicode(data)) + #if alias_key is not None: + # self.represented_objects[alias_key] = node + return node + + def add_representer(cls, data_type, representer): + if not 'yaml_representers' in cls.__dict__: + cls.yaml_representers = cls.yaml_representers.copy() + cls.yaml_representers[data_type] = representer + add_representer = classmethod(add_representer) + + def add_multi_representer(cls, data_type, representer): + if not 'yaml_multi_representers' in cls.__dict__: + cls.yaml_multi_representers = cls.yaml_multi_representers.copy() + cls.yaml_multi_representers[data_type] = representer + add_multi_representer = classmethod(add_multi_representer) + + def represent_scalar(self, tag, value, style=None): + if style is None: + style = self.default_style + node = ScalarNode(tag, value, style=style) + if self.alias_key is not None: + self.represented_objects[self.alias_key] = node + return node + + def represent_sequence(self, tag, sequence, flow_style=None): + value = [] + node = SequenceNode(tag, value, flow_style=flow_style) + if self.alias_key is not None: + self.represented_objects[self.alias_key] = node + best_style = True + for item in sequence: + node_item = self.represent_data(item) + if not (isinstance(node_item, ScalarNode) and not node_item.style): + best_style = False + value.append(node_item) + if flow_style is None: + if self.default_flow_style is not None: + node.flow_style = self.default_flow_style + else: + node.flow_style = best_style + return node + + def represent_mapping(self, tag, mapping, flow_style=None): + value = [] + node = MappingNode(tag, value, flow_style=flow_style) + if self.alias_key is not None: + self.represented_objects[self.alias_key] = node + best_style = True + if hasattr(mapping, 'items'): + mapping = mapping.items() + mapping.sort() + for item_key, item_value in mapping: + node_key = self.represent_data(item_key) + node_value = self.represent_data(item_value) + if not (isinstance(node_key, ScalarNode) and not node_key.style): + best_style = False + if not (isinstance(node_value, ScalarNode) and not node_value.style): + best_style = False + value.append((node_key, node_value)) + if flow_style is None: + if self.default_flow_style is not None: + node.flow_style = self.default_flow_style + else: + node.flow_style = best_style + return node + + def ignore_aliases(self, data): + return False + +class SafeRepresenter(BaseRepresenter): + + def ignore_aliases(self, data): + if data in [None, ()]: + return True + if isinstance(data, (str, unicode, bool, int, float)): + return True + + def represent_none(self, data): + return self.represent_scalar(u'tag:yaml.org,2002:null', + u'null') + + def represent_str(self, data): + tag = None + style = None + try: + data = unicode(data, 'ascii') + tag = u'tag:yaml.org,2002:str' + except UnicodeDecodeError: + try: + data = unicode(data, 'utf-8') + tag = u'tag:yaml.org,2002:str' + except UnicodeDecodeError: + data = data.encode('base64') + tag = u'tag:yaml.org,2002:binary' + style = '|' + return self.represent_scalar(tag, data, style=style) + + def represent_unicode(self, data): + return self.represent_scalar(u'tag:yaml.org,2002:str', data) + + def represent_bool(self, data): + if data: + value = u'true' + else: + value = u'false' + return self.represent_scalar(u'tag:yaml.org,2002:bool', value) + + def represent_int(self, data): + return self.represent_scalar(u'tag:yaml.org,2002:int', unicode(data)) + + def represent_long(self, data): + return self.represent_scalar(u'tag:yaml.org,2002:int', unicode(data)) + + inf_value = 1e300 + while repr(inf_value) != repr(inf_value*inf_value): + inf_value *= inf_value + + def represent_float(self, data): + if data != data or (data == 0.0 and data == 1.0): + value = u'.nan' + elif data == self.inf_value: + value = u'.inf' + elif data == -self.inf_value: + value = u'-.inf' + else: + value = unicode(repr(data)).lower() + # Note that in some cases `repr(data)` represents a float number + # without the decimal parts. For instance: + # >>> repr(1e17) + # '1e17' + # Unfortunately, this is not a valid float representation according + # to the definition of the `!!float` tag. We fix this by adding + # '.0' before the 'e' symbol. + if u'.' not in value and u'e' in value: + value = value.replace(u'e', u'.0e', 1) + return self.represent_scalar(u'tag:yaml.org,2002:float', value) + + def represent_list(self, data): + #pairs = (len(data) > 0 and isinstance(data, list)) + #if pairs: + # for item in data: + # if not isinstance(item, tuple) or len(item) != 2: + # pairs = False + # break + #if not pairs: + return self.represent_sequence(u'tag:yaml.org,2002:seq', data) + #value = [] + #for item_key, item_value in data: + # value.append(self.represent_mapping(u'tag:yaml.org,2002:map', + # [(item_key, item_value)])) + #return SequenceNode(u'tag:yaml.org,2002:pairs', value) + + def represent_dict(self, data): + return self.represent_mapping(u'tag:yaml.org,2002:map', data) + + def represent_set(self, data): + value = {} + for key in data: + value[key] = None + return self.represent_mapping(u'tag:yaml.org,2002:set', value) + + def represent_date(self, data): + value = unicode(data.isoformat()) + return self.represent_scalar(u'tag:yaml.org,2002:timestamp', value) + + def represent_datetime(self, data): + value = unicode(data.isoformat(' ')) + return self.represent_scalar(u'tag:yaml.org,2002:timestamp', value) + + def represent_yaml_object(self, tag, data, cls, flow_style=None): + if hasattr(data, '__getstate__'): + state = data.__getstate__() + else: + state = data.__dict__.copy() + return self.represent_mapping(tag, state, flow_style=flow_style) + + def represent_undefined(self, data): + raise RepresenterError("cannot represent an object: %s" % data) + +SafeRepresenter.add_representer(type(None), + SafeRepresenter.represent_none) + +SafeRepresenter.add_representer(str, + SafeRepresenter.represent_str) + +SafeRepresenter.add_representer(unicode, + SafeRepresenter.represent_unicode) + +SafeRepresenter.add_representer(bool, + SafeRepresenter.represent_bool) + +SafeRepresenter.add_representer(int, + SafeRepresenter.represent_int) + +SafeRepresenter.add_representer(long, + SafeRepresenter.represent_long) + +SafeRepresenter.add_representer(float, + SafeRepresenter.represent_float) + +SafeRepresenter.add_representer(list, + SafeRepresenter.represent_list) + +SafeRepresenter.add_representer(tuple, + SafeRepresenter.represent_list) + +SafeRepresenter.add_representer(dict, + SafeRepresenter.represent_dict) + +SafeRepresenter.add_representer(set, + SafeRepresenter.represent_set) + +SafeRepresenter.add_representer(datetime.date, + SafeRepresenter.represent_date) + +SafeRepresenter.add_representer(datetime.datetime, + SafeRepresenter.represent_datetime) + +SafeRepresenter.add_representer(None, + SafeRepresenter.represent_undefined) + +class Representer(SafeRepresenter): + + def represent_str(self, data): + tag = None + style = None + try: + data = unicode(data, 'ascii') + tag = u'tag:yaml.org,2002:str' + except UnicodeDecodeError: + try: + data = unicode(data, 'utf-8') + tag = u'tag:yaml.org,2002:python/str' + except UnicodeDecodeError: + data = data.encode('base64') + tag = u'tag:yaml.org,2002:binary' + style = '|' + return self.represent_scalar(tag, data, style=style) + + def represent_unicode(self, data): + tag = None + try: + data.encode('ascii') + tag = u'tag:yaml.org,2002:python/unicode' + except UnicodeEncodeError: + tag = u'tag:yaml.org,2002:str' + return self.represent_scalar(tag, data) + + def represent_long(self, data): + tag = u'tag:yaml.org,2002:int' + if int(data) is not data: + tag = u'tag:yaml.org,2002:python/long' + return self.represent_scalar(tag, unicode(data)) + + def represent_complex(self, data): + if data.imag == 0.0: + data = u'%r' % data.real + elif data.real == 0.0: + data = u'%rj' % data.imag + elif data.imag > 0: + data = u'%r+%rj' % (data.real, data.imag) + else: + data = u'%r%rj' % (data.real, data.imag) + return self.represent_scalar(u'tag:yaml.org,2002:python/complex', data) + + def represent_tuple(self, data): + return self.represent_sequence(u'tag:yaml.org,2002:python/tuple', data) + + def represent_name(self, data): + name = u'%s.%s' % (data.__module__, data.__name__) + return self.represent_scalar(u'tag:yaml.org,2002:python/name:'+name, u'') + + def represent_module(self, data): + return self.represent_scalar( + u'tag:yaml.org,2002:python/module:'+data.__name__, u'') + + def represent_instance(self, data): + # For instances of classic classes, we use __getinitargs__ and + # __getstate__ to serialize the data. + + # If data.__getinitargs__ exists, the object must be reconstructed by + # calling cls(**args), where args is a tuple returned by + # __getinitargs__. Otherwise, the cls.__init__ method should never be + # called and the class instance is created by instantiating a trivial + # class and assigning to the instance's __class__ variable. + + # If data.__getstate__ exists, it returns the state of the object. + # Otherwise, the state of the object is data.__dict__. + + # We produce either a !!python/object or !!python/object/new node. + # If data.__getinitargs__ does not exist and state is a dictionary, we + # produce a !!python/object node . Otherwise we produce a + # !!python/object/new node. + + cls = data.__class__ + class_name = u'%s.%s' % (cls.__module__, cls.__name__) + args = None + state = None + if hasattr(data, '__getinitargs__'): + args = list(data.__getinitargs__()) + if hasattr(data, '__getstate__'): + state = data.__getstate__() + else: + state = data.__dict__ + if args is None and isinstance(state, dict): + return self.represent_mapping( + u'tag:yaml.org,2002:python/object:'+class_name, state) + if isinstance(state, dict) and not state: + return self.represent_sequence( + u'tag:yaml.org,2002:python/object/new:'+class_name, args) + value = {} + if args: + value['args'] = args + value['state'] = state + return self.represent_mapping( + u'tag:yaml.org,2002:python/object/new:'+class_name, value) + + def represent_object(self, data): + # We use __reduce__ API to save the data. data.__reduce__ returns + # a tuple of length 2-5: + # (function, args, state, listitems, dictitems) + + # For reconstructing, we calls function(*args), then set its state, + # listitems, and dictitems if they are not None. + + # A special case is when function.__name__ == '__newobj__'. In this + # case we create the object with args[0].__new__(*args). + + # Another special case is when __reduce__ returns a string - we don't + # support it. + + # We produce a !!python/object, !!python/object/new or + # !!python/object/apply node. + + cls = type(data) + if cls in copy_reg.dispatch_table: + reduce = copy_reg.dispatch_table[cls](data) + elif hasattr(data, '__reduce_ex__'): + reduce = data.__reduce_ex__(2) + elif hasattr(data, '__reduce__'): + reduce = data.__reduce__() + else: + raise RepresenterError("cannot represent object: %r" % data) + reduce = (list(reduce)+[None]*5)[:5] + function, args, state, listitems, dictitems = reduce + args = list(args) + if state is None: + state = {} + if listitems is not None: + listitems = list(listitems) + if dictitems is not None: + dictitems = dict(dictitems) + if function.__name__ == '__newobj__': + function = args[0] + args = args[1:] + tag = u'tag:yaml.org,2002:python/object/new:' + newobj = True + else: + tag = u'tag:yaml.org,2002:python/object/apply:' + newobj = False + function_name = u'%s.%s' % (function.__module__, function.__name__) + if not args and not listitems and not dictitems \ + and isinstance(state, dict) and newobj: + return self.represent_mapping( + u'tag:yaml.org,2002:python/object:'+function_name, state) + if not listitems and not dictitems \ + and isinstance(state, dict) and not state: + return self.represent_sequence(tag+function_name, args) + value = {} + if args: + value['args'] = args + if state or not isinstance(state, dict): + value['state'] = state + if listitems: + value['listitems'] = listitems + if dictitems: + value['dictitems'] = dictitems + return self.represent_mapping(tag+function_name, value) + +Representer.add_representer(str, + Representer.represent_str) + +Representer.add_representer(unicode, + Representer.represent_unicode) + +Representer.add_representer(long, + Representer.represent_long) + +Representer.add_representer(complex, + Representer.represent_complex) + +Representer.add_representer(tuple, + Representer.represent_tuple) + +Representer.add_representer(type, + Representer.represent_name) + +Representer.add_representer(types.ClassType, + Representer.represent_name) + +Representer.add_representer(types.FunctionType, + Representer.represent_name) + +Representer.add_representer(types.BuiltinFunctionType, + Representer.represent_name) + +Representer.add_representer(types.ModuleType, + Representer.represent_module) + +Representer.add_multi_representer(types.InstanceType, + Representer.represent_instance) + +Representer.add_multi_representer(object, + Representer.represent_object) + diff --git a/rplibs/yaml/yaml_py2/resolver.py b/rplibs/yaml/yaml_py2/resolver.py new file mode 100644 index 0000000..6b5ab87 --- /dev/null +++ b/rplibs/yaml/yaml_py2/resolver.py @@ -0,0 +1,224 @@ + +__all__ = ['BaseResolver', 'Resolver'] + +from error import * +from nodes import * + +import re + +class ResolverError(YAMLError): + pass + +class BaseResolver(object): + + DEFAULT_SCALAR_TAG = u'tag:yaml.org,2002:str' + DEFAULT_SEQUENCE_TAG = u'tag:yaml.org,2002:seq' + DEFAULT_MAPPING_TAG = u'tag:yaml.org,2002:map' + + yaml_implicit_resolvers = {} + yaml_path_resolvers = {} + + def __init__(self): + self.resolver_exact_paths = [] + self.resolver_prefix_paths = [] + + def add_implicit_resolver(cls, tag, regexp, first): + if not 'yaml_implicit_resolvers' in cls.__dict__: + cls.yaml_implicit_resolvers = cls.yaml_implicit_resolvers.copy() + if first is None: + first = [None] + for ch in first: + cls.yaml_implicit_resolvers.setdefault(ch, []).append((tag, regexp)) + add_implicit_resolver = classmethod(add_implicit_resolver) + + def add_path_resolver(cls, tag, path, kind=None): + # Note: `add_path_resolver` is experimental. The API could be changed. + # `new_path` is a pattern that is matched against the path from the + # root to the node that is being considered. `node_path` elements are + # tuples `(node_check, index_check)`. `node_check` is a node class: + # `ScalarNode`, `SequenceNode`, `MappingNode` or `None`. `None` + # matches any kind of a node. `index_check` could be `None`, a boolean + # value, a string value, or a number. `None` and `False` match against + # any _value_ of sequence and mapping nodes. `True` matches against + # any _key_ of a mapping node. A string `index_check` matches against + # a mapping value that corresponds to a scalar key which content is + # equal to the `index_check` value. An integer `index_check` matches + # against a sequence value with the index equal to `index_check`. + if not 'yaml_path_resolvers' in cls.__dict__: + cls.yaml_path_resolvers = cls.yaml_path_resolvers.copy() + new_path = [] + for element in path: + if isinstance(element, (list, tuple)): + if len(element) == 2: + node_check, index_check = element + elif len(element) == 1: + node_check = element[0] + index_check = True + else: + raise ResolverError("Invalid path element: %s" % element) + else: + node_check = None + index_check = element + if node_check is str: + node_check = ScalarNode + elif node_check is list: + node_check = SequenceNode + elif node_check is dict: + node_check = MappingNode + elif node_check not in [ScalarNode, SequenceNode, MappingNode] \ + and not isinstance(node_check, basestring) \ + and node_check is not None: + raise ResolverError("Invalid node checker: %s" % node_check) + if not isinstance(index_check, (basestring, int)) \ + and index_check is not None: + raise ResolverError("Invalid index checker: %s" % index_check) + new_path.append((node_check, index_check)) + if kind is str: + kind = ScalarNode + elif kind is list: + kind = SequenceNode + elif kind is dict: + kind = MappingNode + elif kind not in [ScalarNode, SequenceNode, MappingNode] \ + and kind is not None: + raise ResolverError("Invalid node kind: %s" % kind) + cls.yaml_path_resolvers[tuple(new_path), kind] = tag + add_path_resolver = classmethod(add_path_resolver) + + def descend_resolver(self, current_node, current_index): + if not self.yaml_path_resolvers: + return + exact_paths = {} + prefix_paths = [] + if current_node: + depth = len(self.resolver_prefix_paths) + for path, kind in self.resolver_prefix_paths[-1]: + if self.check_resolver_prefix(depth, path, kind, + current_node, current_index): + if len(path) > depth: + prefix_paths.append((path, kind)) + else: + exact_paths[kind] = self.yaml_path_resolvers[path, kind] + else: + for path, kind in self.yaml_path_resolvers: + if not path: + exact_paths[kind] = self.yaml_path_resolvers[path, kind] + else: + prefix_paths.append((path, kind)) + self.resolver_exact_paths.append(exact_paths) + self.resolver_prefix_paths.append(prefix_paths) + + def ascend_resolver(self): + if not self.yaml_path_resolvers: + return + self.resolver_exact_paths.pop() + self.resolver_prefix_paths.pop() + + def check_resolver_prefix(self, depth, path, kind, + current_node, current_index): + node_check, index_check = path[depth-1] + if isinstance(node_check, basestring): + if current_node.tag != node_check: + return + elif node_check is not None: + if not isinstance(current_node, node_check): + return + if index_check is True and current_index is not None: + return + if (index_check is False or index_check is None) \ + and current_index is None: + return + if isinstance(index_check, basestring): + if not (isinstance(current_index, ScalarNode) + and index_check == current_index.value): + return + elif isinstance(index_check, int) and not isinstance(index_check, bool): + if index_check != current_index: + return + return True + + def resolve(self, kind, value, implicit): + if kind is ScalarNode and implicit[0]: + if value == u'': + resolvers = self.yaml_implicit_resolvers.get(u'', []) + else: + resolvers = self.yaml_implicit_resolvers.get(value[0], []) + resolvers += self.yaml_implicit_resolvers.get(None, []) + for tag, regexp in resolvers: + if regexp.match(value): + return tag + implicit = implicit[1] + if self.yaml_path_resolvers: + exact_paths = self.resolver_exact_paths[-1] + if kind in exact_paths: + return exact_paths[kind] + if None in exact_paths: + return exact_paths[None] + if kind is ScalarNode: + return self.DEFAULT_SCALAR_TAG + elif kind is SequenceNode: + return self.DEFAULT_SEQUENCE_TAG + elif kind is MappingNode: + return self.DEFAULT_MAPPING_TAG + +class Resolver(BaseResolver): + pass + +Resolver.add_implicit_resolver( + u'tag:yaml.org,2002:bool', + re.compile(ur'''^(?:yes|Yes|YES|no|No|NO + |true|True|TRUE|false|False|FALSE + |on|On|ON|off|Off|OFF)$''', re.X), + list(u'yYnNtTfFoO')) + +Resolver.add_implicit_resolver( + u'tag:yaml.org,2002:float', + re.compile(ur'''^(?:[-+]?(?:[0-9][0-9_]*)\.[0-9_]*(?:[eE][-+][0-9]+)? + |\.[0-9_]+(?:[eE][-+][0-9]+)? + |[-+]?[0-9][0-9_]*(?::[0-5]?[0-9])+\.[0-9_]* + |[-+]?\.(?:inf|Inf|INF) + |\.(?:nan|NaN|NAN))$''', re.X), + list(u'-+0123456789.')) + +Resolver.add_implicit_resolver( + u'tag:yaml.org,2002:int', + re.compile(ur'''^(?:[-+]?0b[0-1_]+ + |[-+]?0[0-7_]+ + |[-+]?(?:0|[1-9][0-9_]*) + |[-+]?0x[0-9a-fA-F_]+ + |[-+]?[1-9][0-9_]*(?::[0-5]?[0-9])+)$''', re.X), + list(u'-+0123456789')) + +Resolver.add_implicit_resolver( + u'tag:yaml.org,2002:merge', + re.compile(ur'^(?:<<)$'), + [u'<']) + +Resolver.add_implicit_resolver( + u'tag:yaml.org,2002:null', + re.compile(ur'''^(?: ~ + |null|Null|NULL + | )$''', re.X), + [u'~', u'n', u'N', u'']) + +Resolver.add_implicit_resolver( + u'tag:yaml.org,2002:timestamp', + re.compile(ur'''^(?:[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9] + |[0-9][0-9][0-9][0-9] -[0-9][0-9]? -[0-9][0-9]? + (?:[Tt]|[ \t]+)[0-9][0-9]? + :[0-9][0-9] :[0-9][0-9] (?:\.[0-9]*)? + (?:[ \t]*(?:Z|[-+][0-9][0-9]?(?::[0-9][0-9])?))?)$''', re.X), + list(u'0123456789')) + +Resolver.add_implicit_resolver( + u'tag:yaml.org,2002:value', + re.compile(ur'^(?:=)$'), + [u'=']) + +# The following resolver is only for documentation purposes. It cannot work +# because plain scalars cannot start with '!', '&', or '*'. +Resolver.add_implicit_resolver( + u'tag:yaml.org,2002:yaml', + re.compile(ur'^(?:!|&|\*)$'), + list(u'!&*')) + diff --git a/rplibs/yaml/yaml_py2/scanner.py b/rplibs/yaml/yaml_py2/scanner.py new file mode 100644 index 0000000..5228fad --- /dev/null +++ b/rplibs/yaml/yaml_py2/scanner.py @@ -0,0 +1,1457 @@ + +# Scanner produces tokens of the following types: +# STREAM-START +# STREAM-END +# DIRECTIVE(name, value) +# DOCUMENT-START +# DOCUMENT-END +# BLOCK-SEQUENCE-START +# BLOCK-MAPPING-START +# BLOCK-END +# FLOW-SEQUENCE-START +# FLOW-MAPPING-START +# FLOW-SEQUENCE-END +# FLOW-MAPPING-END +# BLOCK-ENTRY +# FLOW-ENTRY +# KEY +# VALUE +# ALIAS(value) +# ANCHOR(value) +# TAG(value) +# SCALAR(value, plain, style) +# +# Read comments in the Scanner code for more details. +# + +__all__ = ['Scanner', 'ScannerError'] + +from error import MarkedYAMLError +from tokens import * + +class ScannerError(MarkedYAMLError): + pass + +class SimpleKey(object): + # See below simple keys treatment. + + def __init__(self, token_number, required, index, line, column, mark): + self.token_number = token_number + self.required = required + self.index = index + self.line = line + self.column = column + self.mark = mark + +class Scanner(object): + + def __init__(self): + """Initialize the scanner.""" + # It is assumed that Scanner and Reader will have a common descendant. + # Reader do the dirty work of checking for BOM and converting the + # input data to Unicode. It also adds NUL to the end. + # + # Reader supports the following methods + # self.peek(i=0) # peek the next i-th character + # self.prefix(l=1) # peek the next l characters + # self.forward(l=1) # read the next l characters and move the pointer. + + # Had we reached the end of the stream? + self.done = False + + # The number of unclosed '{' and '['. `flow_level == 0` means block + # context. + self.flow_level = 0 + + # List of processed tokens that are not yet emitted. + self.tokens = [] + + # Add the STREAM-START token. + self.fetch_stream_start() + + # Number of tokens that were emitted through the `get_token` method. + self.tokens_taken = 0 + + # The current indentation level. + self.indent = -1 + + # Past indentation levels. + self.indents = [] + + # Variables related to simple keys treatment. + + # A simple key is a key that is not denoted by the '?' indicator. + # Example of simple keys: + # --- + # block simple key: value + # ? not a simple key: + # : { flow simple key: value } + # We emit the KEY token before all keys, so when we find a potential + # simple key, we try to locate the corresponding ':' indicator. + # Simple keys should be limited to a single line and 1024 characters. + + # Can a simple key start at the current position? A simple key may + # start: + # - at the beginning of the line, not counting indentation spaces + # (in block context), + # - after '{', '[', ',' (in the flow context), + # - after '?', ':', '-' (in the block context). + # In the block context, this flag also signifies if a block collection + # may start at the current position. + self.allow_simple_key = True + + # Keep track of possible simple keys. This is a dictionary. The key + # is `flow_level`; there can be no more that one possible simple key + # for each level. The value is a SimpleKey record: + # (token_number, required, index, line, column, mark) + # A simple key may start with ALIAS, ANCHOR, TAG, SCALAR(flow), + # '[', or '{' tokens. + self.possible_simple_keys = {} + + # Public methods. + + def check_token(self, *choices): + # Check if the next token is one of the given types. + while self.need_more_tokens(): + self.fetch_more_tokens() + if self.tokens: + if not choices: + return True + for choice in choices: + if isinstance(self.tokens[0], choice): + return True + return False + + def peek_token(self): + # Return the next token, but do not delete if from the queue. + while self.need_more_tokens(): + self.fetch_more_tokens() + if self.tokens: + return self.tokens[0] + + def get_token(self): + # Return the next token. + while self.need_more_tokens(): + self.fetch_more_tokens() + if self.tokens: + self.tokens_taken += 1 + return self.tokens.pop(0) + + # Private methods. + + def need_more_tokens(self): + if self.done: + return False + if not self.tokens: + return True + # The current token may be a potential simple key, so we + # need to look further. + self.stale_possible_simple_keys() + if self.next_possible_simple_key() == self.tokens_taken: + return True + + def fetch_more_tokens(self): + + # Eat whitespaces and comments until we reach the next token. + self.scan_to_next_token() + + # Remove obsolete possible simple keys. + self.stale_possible_simple_keys() + + # Compare the current indentation and column. It may add some tokens + # and decrease the current indentation level. + self.unwind_indent(self.column) + + # Peek the next character. + ch = self.peek() + + # Is it the end of stream? + if ch == u'\0': + return self.fetch_stream_end() + + # Is it a directive? + if ch == u'%' and self.check_directive(): + return self.fetch_directive() + + # Is it the document start? + if ch == u'-' and self.check_document_start(): + return self.fetch_document_start() + + # Is it the document end? + if ch == u'.' and self.check_document_end(): + return self.fetch_document_end() + + # TODO: support for BOM within a stream. + #if ch == u'\uFEFF': + # return self.fetch_bom() <-- issue BOMToken + + # Note: the order of the following checks is NOT significant. + + # Is it the flow sequence start indicator? + if ch == u'[': + return self.fetch_flow_sequence_start() + + # Is it the flow mapping start indicator? + if ch == u'{': + return self.fetch_flow_mapping_start() + + # Is it the flow sequence end indicator? + if ch == u']': + return self.fetch_flow_sequence_end() + + # Is it the flow mapping end indicator? + if ch == u'}': + return self.fetch_flow_mapping_end() + + # Is it the flow entry indicator? + if ch == u',': + return self.fetch_flow_entry() + + # Is it the block entry indicator? + if ch == u'-' and self.check_block_entry(): + return self.fetch_block_entry() + + # Is it the key indicator? + if ch == u'?' and self.check_key(): + return self.fetch_key() + + # Is it the value indicator? + if ch == u':' and self.check_value(): + return self.fetch_value() + + # Is it an alias? + if ch == u'*': + return self.fetch_alias() + + # Is it an anchor? + if ch == u'&': + return self.fetch_anchor() + + # Is it a tag? + if ch == u'!': + return self.fetch_tag() + + # Is it a literal scalar? + if ch == u'|' and not self.flow_level: + return self.fetch_literal() + + # Is it a folded scalar? + if ch == u'>' and not self.flow_level: + return self.fetch_folded() + + # Is it a single quoted scalar? + if ch == u'\'': + return self.fetch_single() + + # Is it a double quoted scalar? + if ch == u'\"': + return self.fetch_double() + + # It must be a plain scalar then. + if self.check_plain(): + return self.fetch_plain() + + # No? It's an error. Let's produce a nice error message. + raise ScannerError("while scanning for the next token", None, + "found character %r that cannot start any token" + % ch.encode('utf-8'), self.get_mark()) + + # Simple keys treatment. + + def next_possible_simple_key(self): + # Return the number of the nearest possible simple key. Actually we + # don't need to loop through the whole dictionary. We may replace it + # with the following code: + # if not self.possible_simple_keys: + # return None + # return self.possible_simple_keys[ + # min(self.possible_simple_keys.keys())].token_number + min_token_number = None + for level in self.possible_simple_keys: + key = self.possible_simple_keys[level] + if min_token_number is None or key.token_number < min_token_number: + min_token_number = key.token_number + return min_token_number + + def stale_possible_simple_keys(self): + # Remove entries that are no longer possible simple keys. According to + # the YAML specification, simple keys + # - should be limited to a single line, + # - should be no longer than 1024 characters. + # Disabling this procedure will allow simple keys of any length and + # height (may cause problems if indentation is broken though). + for level in self.possible_simple_keys.keys(): + key = self.possible_simple_keys[level] + if key.line != self.line \ + or self.index-key.index > 1024: + if key.required: + raise ScannerError("while scanning a simple key", key.mark, + "could not found expected ':'", self.get_mark()) + del self.possible_simple_keys[level] + + def save_possible_simple_key(self): + # The next token may start a simple key. We check if it's possible + # and save its position. This function is called for + # ALIAS, ANCHOR, TAG, SCALAR(flow), '[', and '{'. + + # Check if a simple key is required at the current position. + required = not self.flow_level and self.indent == self.column + + # A simple key is required only if it is the first token in the current + # line. Therefore it is always allowed. + assert self.allow_simple_key or not required + + # The next token might be a simple key. Let's save it's number and + # position. + if self.allow_simple_key: + self.remove_possible_simple_key() + token_number = self.tokens_taken+len(self.tokens) + key = SimpleKey(token_number, required, + self.index, self.line, self.column, self.get_mark()) + self.possible_simple_keys[self.flow_level] = key + + def remove_possible_simple_key(self): + # Remove the saved possible key position at the current flow level. + if self.flow_level in self.possible_simple_keys: + key = self.possible_simple_keys[self.flow_level] + + if key.required: + raise ScannerError("while scanning a simple key", key.mark, + "could not found expected ':'", self.get_mark()) + + del self.possible_simple_keys[self.flow_level] + + # Indentation functions. + + def unwind_indent(self, column): + + ## In flow context, tokens should respect indentation. + ## Actually the condition should be `self.indent >= column` according to + ## the spec. But this condition will prohibit intuitively correct + ## constructions such as + ## key : { + ## } + #if self.flow_level and self.indent > column: + # raise ScannerError(None, None, + # "invalid intendation or unclosed '[' or '{'", + # self.get_mark()) + + # In the flow context, indentation is ignored. We make the scanner less + # restrictive then specification requires. + if self.flow_level: + return + + # In block context, we may need to issue the BLOCK-END tokens. + while self.indent > column: + mark = self.get_mark() + self.indent = self.indents.pop() + self.tokens.append(BlockEndToken(mark, mark)) + + def add_indent(self, column): + # Check if we need to increase indentation. + if self.indent < column: + self.indents.append(self.indent) + self.indent = column + return True + return False + + # Fetchers. + + def fetch_stream_start(self): + # We always add STREAM-START as the first token and STREAM-END as the + # last token. + + # Read the token. + mark = self.get_mark() + + # Add STREAM-START. + self.tokens.append(StreamStartToken(mark, mark, + encoding=self.encoding)) + + + def fetch_stream_end(self): + + # Set the current intendation to -1. + self.unwind_indent(-1) + + # Reset simple keys. + self.remove_possible_simple_key() + self.allow_simple_key = False + self.possible_simple_keys = {} + + # Read the token. + mark = self.get_mark() + + # Add STREAM-END. + self.tokens.append(StreamEndToken(mark, mark)) + + # The steam is finished. + self.done = True + + def fetch_directive(self): + + # Set the current intendation to -1. + self.unwind_indent(-1) + + # Reset simple keys. + self.remove_possible_simple_key() + self.allow_simple_key = False + + # Scan and add DIRECTIVE. + self.tokens.append(self.scan_directive()) + + def fetch_document_start(self): + self.fetch_document_indicator(DocumentStartToken) + + def fetch_document_end(self): + self.fetch_document_indicator(DocumentEndToken) + + def fetch_document_indicator(self, TokenClass): + + # Set the current intendation to -1. + self.unwind_indent(-1) + + # Reset simple keys. Note that there could not be a block collection + # after '---'. + self.remove_possible_simple_key() + self.allow_simple_key = False + + # Add DOCUMENT-START or DOCUMENT-END. + start_mark = self.get_mark() + self.forward(3) + end_mark = self.get_mark() + self.tokens.append(TokenClass(start_mark, end_mark)) + + def fetch_flow_sequence_start(self): + self.fetch_flow_collection_start(FlowSequenceStartToken) + + def fetch_flow_mapping_start(self): + self.fetch_flow_collection_start(FlowMappingStartToken) + + def fetch_flow_collection_start(self, TokenClass): + + # '[' and '{' may start a simple key. + self.save_possible_simple_key() + + # Increase the flow level. + self.flow_level += 1 + + # Simple keys are allowed after '[' and '{'. + self.allow_simple_key = True + + # Add FLOW-SEQUENCE-START or FLOW-MAPPING-START. + start_mark = self.get_mark() + self.forward() + end_mark = self.get_mark() + self.tokens.append(TokenClass(start_mark, end_mark)) + + def fetch_flow_sequence_end(self): + self.fetch_flow_collection_end(FlowSequenceEndToken) + + def fetch_flow_mapping_end(self): + self.fetch_flow_collection_end(FlowMappingEndToken) + + def fetch_flow_collection_end(self, TokenClass): + + # Reset possible simple key on the current level. + self.remove_possible_simple_key() + + # Decrease the flow level. + self.flow_level -= 1 + + # No simple keys after ']' or '}'. + self.allow_simple_key = False + + # Add FLOW-SEQUENCE-END or FLOW-MAPPING-END. + start_mark = self.get_mark() + self.forward() + end_mark = self.get_mark() + self.tokens.append(TokenClass(start_mark, end_mark)) + + def fetch_flow_entry(self): + + # Simple keys are allowed after ','. + self.allow_simple_key = True + + # Reset possible simple key on the current level. + self.remove_possible_simple_key() + + # Add FLOW-ENTRY. + start_mark = self.get_mark() + self.forward() + end_mark = self.get_mark() + self.tokens.append(FlowEntryToken(start_mark, end_mark)) + + def fetch_block_entry(self): + + # Block context needs additional checks. + if not self.flow_level: + + # Are we allowed to start a new entry? + if not self.allow_simple_key: + raise ScannerError(None, None, + "sequence entries are not allowed here", + self.get_mark()) + + # We may need to add BLOCK-SEQUENCE-START. + if self.add_indent(self.column): + mark = self.get_mark() + self.tokens.append(BlockSequenceStartToken(mark, mark)) + + # It's an error for the block entry to occur in the flow context, + # but we let the parser detect this. + else: + pass + + # Simple keys are allowed after '-'. + self.allow_simple_key = True + + # Reset possible simple key on the current level. + self.remove_possible_simple_key() + + # Add BLOCK-ENTRY. + start_mark = self.get_mark() + self.forward() + end_mark = self.get_mark() + self.tokens.append(BlockEntryToken(start_mark, end_mark)) + + def fetch_key(self): + + # Block context needs additional checks. + if not self.flow_level: + + # Are we allowed to start a key (not nessesary a simple)? + if not self.allow_simple_key: + raise ScannerError(None, None, + "mapping keys are not allowed here", + self.get_mark()) + + # We may need to add BLOCK-MAPPING-START. + if self.add_indent(self.column): + mark = self.get_mark() + self.tokens.append(BlockMappingStartToken(mark, mark)) + + # Simple keys are allowed after '?' in the block context. + self.allow_simple_key = not self.flow_level + + # Reset possible simple key on the current level. + self.remove_possible_simple_key() + + # Add KEY. + start_mark = self.get_mark() + self.forward() + end_mark = self.get_mark() + self.tokens.append(KeyToken(start_mark, end_mark)) + + def fetch_value(self): + + # Do we determine a simple key? + if self.flow_level in self.possible_simple_keys: + + # Add KEY. + key = self.possible_simple_keys[self.flow_level] + del self.possible_simple_keys[self.flow_level] + self.tokens.insert(key.token_number-self.tokens_taken, + KeyToken(key.mark, key.mark)) + + # If this key starts a new block mapping, we need to add + # BLOCK-MAPPING-START. + if not self.flow_level: + if self.add_indent(key.column): + self.tokens.insert(key.token_number-self.tokens_taken, + BlockMappingStartToken(key.mark, key.mark)) + + # There cannot be two simple keys one after another. + self.allow_simple_key = False + + # It must be a part of a complex key. + else: + + # Block context needs additional checks. + # (Do we really need them? They will be catched by the parser + # anyway.) + if not self.flow_level: + + # We are allowed to start a complex value if and only if + # we can start a simple key. + if not self.allow_simple_key: + raise ScannerError(None, None, + "mapping values are not allowed here", + self.get_mark()) + + # If this value starts a new block mapping, we need to add + # BLOCK-MAPPING-START. It will be detected as an error later by + # the parser. + if not self.flow_level: + if self.add_indent(self.column): + mark = self.get_mark() + self.tokens.append(BlockMappingStartToken(mark, mark)) + + # Simple keys are allowed after ':' in the block context. + self.allow_simple_key = not self.flow_level + + # Reset possible simple key on the current level. + self.remove_possible_simple_key() + + # Add VALUE. + start_mark = self.get_mark() + self.forward() + end_mark = self.get_mark() + self.tokens.append(ValueToken(start_mark, end_mark)) + + def fetch_alias(self): + + # ALIAS could be a simple key. + self.save_possible_simple_key() + + # No simple keys after ALIAS. + self.allow_simple_key = False + + # Scan and add ALIAS. + self.tokens.append(self.scan_anchor(AliasToken)) + + def fetch_anchor(self): + + # ANCHOR could start a simple key. + self.save_possible_simple_key() + + # No simple keys after ANCHOR. + self.allow_simple_key = False + + # Scan and add ANCHOR. + self.tokens.append(self.scan_anchor(AnchorToken)) + + def fetch_tag(self): + + # TAG could start a simple key. + self.save_possible_simple_key() + + # No simple keys after TAG. + self.allow_simple_key = False + + # Scan and add TAG. + self.tokens.append(self.scan_tag()) + + def fetch_literal(self): + self.fetch_block_scalar(style='|') + + def fetch_folded(self): + self.fetch_block_scalar(style='>') + + def fetch_block_scalar(self, style): + + # A simple key may follow a block scalar. + self.allow_simple_key = True + + # Reset possible simple key on the current level. + self.remove_possible_simple_key() + + # Scan and add SCALAR. + self.tokens.append(self.scan_block_scalar(style)) + + def fetch_single(self): + self.fetch_flow_scalar(style='\'') + + def fetch_double(self): + self.fetch_flow_scalar(style='"') + + def fetch_flow_scalar(self, style): + + # A flow scalar could be a simple key. + self.save_possible_simple_key() + + # No simple keys after flow scalars. + self.allow_simple_key = False + + # Scan and add SCALAR. + self.tokens.append(self.scan_flow_scalar(style)) + + def fetch_plain(self): + + # A plain scalar could be a simple key. + self.save_possible_simple_key() + + # No simple keys after plain scalars. But note that `scan_plain` will + # change this flag if the scan is finished at the beginning of the + # line. + self.allow_simple_key = False + + # Scan and add SCALAR. May change `allow_simple_key`. + self.tokens.append(self.scan_plain()) + + # Checkers. + + def check_directive(self): + + # DIRECTIVE: ^ '%' ... + # The '%' indicator is already checked. + if self.column == 0: + return True + + def check_document_start(self): + + # DOCUMENT-START: ^ '---' (' '|'\n') + if self.column == 0: + if self.prefix(3) == u'---' \ + and self.peek(3) in u'\0 \t\r\n\x85\u2028\u2029': + return True + + def check_document_end(self): + + # DOCUMENT-END: ^ '...' (' '|'\n') + if self.column == 0: + if self.prefix(3) == u'...' \ + and self.peek(3) in u'\0 \t\r\n\x85\u2028\u2029': + return True + + def check_block_entry(self): + + # BLOCK-ENTRY: '-' (' '|'\n') + return self.peek(1) in u'\0 \t\r\n\x85\u2028\u2029' + + def check_key(self): + + # KEY(flow context): '?' + if self.flow_level: + return True + + # KEY(block context): '?' (' '|'\n') + else: + return self.peek(1) in u'\0 \t\r\n\x85\u2028\u2029' + + def check_value(self): + + # VALUE(flow context): ':' + if self.flow_level: + return True + + # VALUE(block context): ':' (' '|'\n') + else: + return self.peek(1) in u'\0 \t\r\n\x85\u2028\u2029' + + def check_plain(self): + + # A plain scalar may start with any non-space character except: + # '-', '?', ':', ',', '[', ']', '{', '}', + # '#', '&', '*', '!', '|', '>', '\'', '\"', + # '%', '@', '`'. + # + # It may also start with + # '-', '?', ':' + # if it is followed by a non-space character. + # + # Note that we limit the last rule to the block context (except the + # '-' character) because we want the flow context to be space + # independent. + ch = self.peek() + return ch not in u'\0 \t\r\n\x85\u2028\u2029-?:,[]{}#&*!|>\'\"%@`' \ + or (self.peek(1) not in u'\0 \t\r\n\x85\u2028\u2029' + and (ch == u'-' or (not self.flow_level and ch in u'?:'))) + + # Scanners. + + def scan_to_next_token(self): + # We ignore spaces, line breaks and comments. + # If we find a line break in the block context, we set the flag + # `allow_simple_key` on. + # The byte order mark is stripped if it's the first character in the + # stream. We do not yet support BOM inside the stream as the + # specification requires. Any such mark will be considered as a part + # of the document. + # + # TODO: We need to make tab handling rules more sane. A good rule is + # Tabs cannot precede tokens + # BLOCK-SEQUENCE-START, BLOCK-MAPPING-START, BLOCK-END, + # KEY(block), VALUE(block), BLOCK-ENTRY + # So the checking code is + # if : + # self.allow_simple_keys = False + # We also need to add the check for `allow_simple_keys == True` to + # `unwind_indent` before issuing BLOCK-END. + # Scanners for block, flow, and plain scalars need to be modified. + + if self.index == 0 and self.peek() == u'\uFEFF': + self.forward() + found = False + while not found: + while self.peek() == u' ': + self.forward() + if self.peek() == u'#': + while self.peek() not in u'\0\r\n\x85\u2028\u2029': + self.forward() + if self.scan_line_break(): + if not self.flow_level: + self.allow_simple_key = True + else: + found = True + + def scan_directive(self): + # See the specification for details. + start_mark = self.get_mark() + self.forward() + name = self.scan_directive_name(start_mark) + value = None + if name == u'YAML': + value = self.scan_yaml_directive_value(start_mark) + end_mark = self.get_mark() + elif name == u'TAG': + value = self.scan_tag_directive_value(start_mark) + end_mark = self.get_mark() + else: + end_mark = self.get_mark() + while self.peek() not in u'\0\r\n\x85\u2028\u2029': + self.forward() + self.scan_directive_ignored_line(start_mark) + return DirectiveToken(name, value, start_mark, end_mark) + + def scan_directive_name(self, start_mark): + # See the specification for details. + length = 0 + ch = self.peek(length) + while u'0' <= ch <= u'9' or u'A' <= ch <= u'Z' or u'a' <= ch <= u'z' \ + or ch in u'-_': + length += 1 + ch = self.peek(length) + if not length: + raise ScannerError("while scanning a directive", start_mark, + "expected alphabetic or numeric character, but found %r" + % ch.encode('utf-8'), self.get_mark()) + value = self.prefix(length) + self.forward(length) + ch = self.peek() + if ch not in u'\0 \r\n\x85\u2028\u2029': + raise ScannerError("while scanning a directive", start_mark, + "expected alphabetic or numeric character, but found %r" + % ch.encode('utf-8'), self.get_mark()) + return value + + def scan_yaml_directive_value(self, start_mark): + # See the specification for details. + while self.peek() == u' ': + self.forward() + major = self.scan_yaml_directive_number(start_mark) + if self.peek() != '.': + raise ScannerError("while scanning a directive", start_mark, + "expected a digit or '.', but found %r" + % self.peek().encode('utf-8'), + self.get_mark()) + self.forward() + minor = self.scan_yaml_directive_number(start_mark) + if self.peek() not in u'\0 \r\n\x85\u2028\u2029': + raise ScannerError("while scanning a directive", start_mark, + "expected a digit or ' ', but found %r" + % self.peek().encode('utf-8'), + self.get_mark()) + return (major, minor) + + def scan_yaml_directive_number(self, start_mark): + # See the specification for details. + ch = self.peek() + if not (u'0' <= ch <= u'9'): + raise ScannerError("while scanning a directive", start_mark, + "expected a digit, but found %r" % ch.encode('utf-8'), + self.get_mark()) + length = 0 + while u'0' <= self.peek(length) <= u'9': + length += 1 + value = int(self.prefix(length)) + self.forward(length) + return value + + def scan_tag_directive_value(self, start_mark): + # See the specification for details. + while self.peek() == u' ': + self.forward() + handle = self.scan_tag_directive_handle(start_mark) + while self.peek() == u' ': + self.forward() + prefix = self.scan_tag_directive_prefix(start_mark) + return (handle, prefix) + + def scan_tag_directive_handle(self, start_mark): + # See the specification for details. + value = self.scan_tag_handle('directive', start_mark) + ch = self.peek() + if ch != u' ': + raise ScannerError("while scanning a directive", start_mark, + "expected ' ', but found %r" % ch.encode('utf-8'), + self.get_mark()) + return value + + def scan_tag_directive_prefix(self, start_mark): + # See the specification for details. + value = self.scan_tag_uri('directive', start_mark) + ch = self.peek() + if ch not in u'\0 \r\n\x85\u2028\u2029': + raise ScannerError("while scanning a directive", start_mark, + "expected ' ', but found %r" % ch.encode('utf-8'), + self.get_mark()) + return value + + def scan_directive_ignored_line(self, start_mark): + # See the specification for details. + while self.peek() == u' ': + self.forward() + if self.peek() == u'#': + while self.peek() not in u'\0\r\n\x85\u2028\u2029': + self.forward() + ch = self.peek() + if ch not in u'\0\r\n\x85\u2028\u2029': + raise ScannerError("while scanning a directive", start_mark, + "expected a comment or a line break, but found %r" + % ch.encode('utf-8'), self.get_mark()) + self.scan_line_break() + + def scan_anchor(self, TokenClass): + # The specification does not restrict characters for anchors and + # aliases. This may lead to problems, for instance, the document: + # [ *alias, value ] + # can be interpteted in two ways, as + # [ "value" ] + # and + # [ *alias , "value" ] + # Therefore we restrict aliases to numbers and ASCII letters. + start_mark = self.get_mark() + indicator = self.peek() + if indicator == u'*': + name = 'alias' + else: + name = 'anchor' + self.forward() + length = 0 + ch = self.peek(length) + while u'0' <= ch <= u'9' or u'A' <= ch <= u'Z' or u'a' <= ch <= u'z' \ + or ch in u'-_': + length += 1 + ch = self.peek(length) + if not length: + raise ScannerError("while scanning an %s" % name, start_mark, + "expected alphabetic or numeric character, but found %r" + % ch.encode('utf-8'), self.get_mark()) + value = self.prefix(length) + self.forward(length) + ch = self.peek() + if ch not in u'\0 \t\r\n\x85\u2028\u2029?:,]}%@`': + raise ScannerError("while scanning an %s" % name, start_mark, + "expected alphabetic or numeric character, but found %r" + % ch.encode('utf-8'), self.get_mark()) + end_mark = self.get_mark() + return TokenClass(value, start_mark, end_mark) + + def scan_tag(self): + # See the specification for details. + start_mark = self.get_mark() + ch = self.peek(1) + if ch == u'<': + handle = None + self.forward(2) + suffix = self.scan_tag_uri('tag', start_mark) + if self.peek() != u'>': + raise ScannerError("while parsing a tag", start_mark, + "expected '>', but found %r" % self.peek().encode('utf-8'), + self.get_mark()) + self.forward() + elif ch in u'\0 \t\r\n\x85\u2028\u2029': + handle = None + suffix = u'!' + self.forward() + else: + length = 1 + use_handle = False + while ch not in u'\0 \r\n\x85\u2028\u2029': + if ch == u'!': + use_handle = True + break + length += 1 + ch = self.peek(length) + handle = u'!' + if use_handle: + handle = self.scan_tag_handle('tag', start_mark) + else: + handle = u'!' + self.forward() + suffix = self.scan_tag_uri('tag', start_mark) + ch = self.peek() + if ch not in u'\0 \r\n\x85\u2028\u2029': + raise ScannerError("while scanning a tag", start_mark, + "expected ' ', but found %r" % ch.encode('utf-8'), + self.get_mark()) + value = (handle, suffix) + end_mark = self.get_mark() + return TagToken(value, start_mark, end_mark) + + def scan_block_scalar(self, style): + # See the specification for details. + + if style == '>': + folded = True + else: + folded = False + + chunks = [] + start_mark = self.get_mark() + + # Scan the header. + self.forward() + chomping, increment = self.scan_block_scalar_indicators(start_mark) + self.scan_block_scalar_ignored_line(start_mark) + + # Determine the indentation level and go to the first non-empty line. + min_indent = self.indent+1 + if min_indent < 1: + min_indent = 1 + if increment is None: + breaks, max_indent, end_mark = self.scan_block_scalar_indentation() + indent = max(min_indent, max_indent) + else: + indent = min_indent+increment-1 + breaks, end_mark = self.scan_block_scalar_breaks(indent) + line_break = u'' + + # Scan the inner part of the block scalar. + while self.column == indent and self.peek() != u'\0': + chunks.extend(breaks) + leading_non_space = self.peek() not in u' \t' + length = 0 + while self.peek(length) not in u'\0\r\n\x85\u2028\u2029': + length += 1 + chunks.append(self.prefix(length)) + self.forward(length) + line_break = self.scan_line_break() + breaks, end_mark = self.scan_block_scalar_breaks(indent) + if self.column == indent and self.peek() != u'\0': + + # Unfortunately, folding rules are ambiguous. + # + # This is the folding according to the specification: + + if folded and line_break == u'\n' \ + and leading_non_space and self.peek() not in u' \t': + if not breaks: + chunks.append(u' ') + else: + chunks.append(line_break) + + # This is Clark Evans's interpretation (also in the spec + # examples): + # + #if folded and line_break == u'\n': + # if not breaks: + # if self.peek() not in ' \t': + # chunks.append(u' ') + # else: + # chunks.append(line_break) + #else: + # chunks.append(line_break) + else: + break + + # Chomp the tail. + if chomping is not False: + chunks.append(line_break) + if chomping is True: + chunks.extend(breaks) + + # We are done. + return ScalarToken(u''.join(chunks), False, start_mark, end_mark, + style) + + def scan_block_scalar_indicators(self, start_mark): + # See the specification for details. + chomping = None + increment = None + ch = self.peek() + if ch in u'+-': + if ch == '+': + chomping = True + else: + chomping = False + self.forward() + ch = self.peek() + if ch in u'0123456789': + increment = int(ch) + if increment == 0: + raise ScannerError("while scanning a block scalar", start_mark, + "expected indentation indicator in the range 1-9, but found 0", + self.get_mark()) + self.forward() + elif ch in u'0123456789': + increment = int(ch) + if increment == 0: + raise ScannerError("while scanning a block scalar", start_mark, + "expected indentation indicator in the range 1-9, but found 0", + self.get_mark()) + self.forward() + ch = self.peek() + if ch in u'+-': + if ch == '+': + chomping = True + else: + chomping = False + self.forward() + ch = self.peek() + if ch not in u'\0 \r\n\x85\u2028\u2029': + raise ScannerError("while scanning a block scalar", start_mark, + "expected chomping or indentation indicators, but found %r" + % ch.encode('utf-8'), self.get_mark()) + return chomping, increment + + def scan_block_scalar_ignored_line(self, start_mark): + # See the specification for details. + while self.peek() == u' ': + self.forward() + if self.peek() == u'#': + while self.peek() not in u'\0\r\n\x85\u2028\u2029': + self.forward() + ch = self.peek() + if ch not in u'\0\r\n\x85\u2028\u2029': + raise ScannerError("while scanning a block scalar", start_mark, + "expected a comment or a line break, but found %r" + % ch.encode('utf-8'), self.get_mark()) + self.scan_line_break() + + def scan_block_scalar_indentation(self): + # See the specification for details. + chunks = [] + max_indent = 0 + end_mark = self.get_mark() + while self.peek() in u' \r\n\x85\u2028\u2029': + if self.peek() != u' ': + chunks.append(self.scan_line_break()) + end_mark = self.get_mark() + else: + self.forward() + if self.column > max_indent: + max_indent = self.column + return chunks, max_indent, end_mark + + def scan_block_scalar_breaks(self, indent): + # See the specification for details. + chunks = [] + end_mark = self.get_mark() + while self.column < indent and self.peek() == u' ': + self.forward() + while self.peek() in u'\r\n\x85\u2028\u2029': + chunks.append(self.scan_line_break()) + end_mark = self.get_mark() + while self.column < indent and self.peek() == u' ': + self.forward() + return chunks, end_mark + + def scan_flow_scalar(self, style): + # See the specification for details. + # Note that we loose indentation rules for quoted scalars. Quoted + # scalars don't need to adhere indentation because " and ' clearly + # mark the beginning and the end of them. Therefore we are less + # restrictive then the specification requires. We only need to check + # that document separators are not included in scalars. + if style == '"': + double = True + else: + double = False + chunks = [] + start_mark = self.get_mark() + quote = self.peek() + self.forward() + chunks.extend(self.scan_flow_scalar_non_spaces(double, start_mark)) + while self.peek() != quote: + chunks.extend(self.scan_flow_scalar_spaces(double, start_mark)) + chunks.extend(self.scan_flow_scalar_non_spaces(double, start_mark)) + self.forward() + end_mark = self.get_mark() + return ScalarToken(u''.join(chunks), False, start_mark, end_mark, + style) + + ESCAPE_REPLACEMENTS = { + u'0': u'\0', + u'a': u'\x07', + u'b': u'\x08', + u't': u'\x09', + u'\t': u'\x09', + u'n': u'\x0A', + u'v': u'\x0B', + u'f': u'\x0C', + u'r': u'\x0D', + u'e': u'\x1B', + u' ': u'\x20', + u'\"': u'\"', + u'\\': u'\\', + u'N': u'\x85', + u'_': u'\xA0', + u'L': u'\u2028', + u'P': u'\u2029', + } + + ESCAPE_CODES = { + u'x': 2, + u'u': 4, + u'U': 8, + } + + def scan_flow_scalar_non_spaces(self, double, start_mark): + # See the specification for details. + chunks = [] + while True: + length = 0 + while self.peek(length) not in u'\'\"\\\0 \t\r\n\x85\u2028\u2029': + length += 1 + if length: + chunks.append(self.prefix(length)) + self.forward(length) + ch = self.peek() + if not double and ch == u'\'' and self.peek(1) == u'\'': + chunks.append(u'\'') + self.forward(2) + elif (double and ch == u'\'') or (not double and ch in u'\"\\'): + chunks.append(ch) + self.forward() + elif double and ch == u'\\': + self.forward() + ch = self.peek() + if ch in self.ESCAPE_REPLACEMENTS: + chunks.append(self.ESCAPE_REPLACEMENTS[ch]) + self.forward() + elif ch in self.ESCAPE_CODES: + length = self.ESCAPE_CODES[ch] + self.forward() + for k in range(length): + if self.peek(k) not in u'0123456789ABCDEFabcdef': + raise ScannerError("while scanning a double-quoted scalar", start_mark, + "expected escape sequence of %d hexdecimal numbers, but found %r" % + (length, self.peek(k).encode('utf-8')), self.get_mark()) + code = int(self.prefix(length), 16) + chunks.append(unichr(code)) + self.forward(length) + elif ch in u'\r\n\x85\u2028\u2029': + self.scan_line_break() + chunks.extend(self.scan_flow_scalar_breaks(double, start_mark)) + else: + raise ScannerError("while scanning a double-quoted scalar", start_mark, + "found unknown escape character %r" % ch.encode('utf-8'), self.get_mark()) + else: + return chunks + + def scan_flow_scalar_spaces(self, double, start_mark): + # See the specification for details. + chunks = [] + length = 0 + while self.peek(length) in u' \t': + length += 1 + whitespaces = self.prefix(length) + self.forward(length) + ch = self.peek() + if ch == u'\0': + raise ScannerError("while scanning a quoted scalar", start_mark, + "found unexpected end of stream", self.get_mark()) + elif ch in u'\r\n\x85\u2028\u2029': + line_break = self.scan_line_break() + breaks = self.scan_flow_scalar_breaks(double, start_mark) + if line_break != u'\n': + chunks.append(line_break) + elif not breaks: + chunks.append(u' ') + chunks.extend(breaks) + else: + chunks.append(whitespaces) + return chunks + + def scan_flow_scalar_breaks(self, double, start_mark): + # See the specification for details. + chunks = [] + while True: + # Instead of checking indentation, we check for document + # separators. + prefix = self.prefix(3) + if (prefix == u'---' or prefix == u'...') \ + and self.peek(3) in u'\0 \t\r\n\x85\u2028\u2029': + raise ScannerError("while scanning a quoted scalar", start_mark, + "found unexpected document separator", self.get_mark()) + while self.peek() in u' \t': + self.forward() + if self.peek() in u'\r\n\x85\u2028\u2029': + chunks.append(self.scan_line_break()) + else: + return chunks + + def scan_plain(self): + # See the specification for details. + # We add an additional restriction for the flow context: + # plain scalars in the flow context cannot contain ',', ':' and '?'. + # We also keep track of the `allow_simple_key` flag here. + # Indentation rules are loosed for the flow context. + chunks = [] + start_mark = self.get_mark() + end_mark = start_mark + indent = self.indent+1 + # We allow zero indentation for scalars, but then we need to check for + # document separators at the beginning of the line. + #if indent == 0: + # indent = 1 + spaces = [] + while True: + length = 0 + if self.peek() == u'#': + break + while True: + ch = self.peek(length) + if ch in u'\0 \t\r\n\x85\u2028\u2029' \ + or (not self.flow_level and ch == u':' and + self.peek(length+1) in u'\0 \t\r\n\x85\u2028\u2029') \ + or (self.flow_level and ch in u',:?[]{}'): + break + length += 1 + # It's not clear what we should do with ':' in the flow context. + if (self.flow_level and ch == u':' + and self.peek(length+1) not in u'\0 \t\r\n\x85\u2028\u2029,[]{}'): + self.forward(length) + raise ScannerError("while scanning a plain scalar", start_mark, + "found unexpected ':'", self.get_mark(), + "Please check http://pyyaml.org/wiki/YAMLColonInFlowContext for details.") + if length == 0: + break + self.allow_simple_key = False + chunks.extend(spaces) + chunks.append(self.prefix(length)) + self.forward(length) + end_mark = self.get_mark() + spaces = self.scan_plain_spaces(indent, start_mark) + if not spaces or self.peek() == u'#' \ + or (not self.flow_level and self.column < indent): + break + return ScalarToken(u''.join(chunks), True, start_mark, end_mark) + + def scan_plain_spaces(self, indent, start_mark): + # See the specification for details. + # The specification is really confusing about tabs in plain scalars. + # We just forbid them completely. Do not use tabs in YAML! + chunks = [] + length = 0 + while self.peek(length) in u' ': + length += 1 + whitespaces = self.prefix(length) + self.forward(length) + ch = self.peek() + if ch in u'\r\n\x85\u2028\u2029': + line_break = self.scan_line_break() + self.allow_simple_key = True + prefix = self.prefix(3) + if (prefix == u'---' or prefix == u'...') \ + and self.peek(3) in u'\0 \t\r\n\x85\u2028\u2029': + return + breaks = [] + while self.peek() in u' \r\n\x85\u2028\u2029': + if self.peek() == ' ': + self.forward() + else: + breaks.append(self.scan_line_break()) + prefix = self.prefix(3) + if (prefix == u'---' or prefix == u'...') \ + and self.peek(3) in u'\0 \t\r\n\x85\u2028\u2029': + return + if line_break != u'\n': + chunks.append(line_break) + elif not breaks: + chunks.append(u' ') + chunks.extend(breaks) + elif whitespaces: + chunks.append(whitespaces) + return chunks + + def scan_tag_handle(self, name, start_mark): + # See the specification for details. + # For some strange reasons, the specification does not allow '_' in + # tag handles. I have allowed it anyway. + ch = self.peek() + if ch != u'!': + raise ScannerError("while scanning a %s" % name, start_mark, + "expected '!', but found %r" % ch.encode('utf-8'), + self.get_mark()) + length = 1 + ch = self.peek(length) + if ch != u' ': + while u'0' <= ch <= u'9' or u'A' <= ch <= u'Z' or u'a' <= ch <= u'z' \ + or ch in u'-_': + length += 1 + ch = self.peek(length) + if ch != u'!': + self.forward(length) + raise ScannerError("while scanning a %s" % name, start_mark, + "expected '!', but found %r" % ch.encode('utf-8'), + self.get_mark()) + length += 1 + value = self.prefix(length) + self.forward(length) + return value + + def scan_tag_uri(self, name, start_mark): + # See the specification for details. + # Note: we do not check if URI is well-formed. + chunks = [] + length = 0 + ch = self.peek(length) + while u'0' <= ch <= u'9' or u'A' <= ch <= u'Z' or u'a' <= ch <= u'z' \ + or ch in u'-;/?:@&=+$,_.!~*\'()[]%': + if ch == u'%': + chunks.append(self.prefix(length)) + self.forward(length) + length = 0 + chunks.append(self.scan_uri_escapes(name, start_mark)) + else: + length += 1 + ch = self.peek(length) + if length: + chunks.append(self.prefix(length)) + self.forward(length) + length = 0 + if not chunks: + raise ScannerError("while parsing a %s" % name, start_mark, + "expected URI, but found %r" % ch.encode('utf-8'), + self.get_mark()) + return u''.join(chunks) + + def scan_uri_escapes(self, name, start_mark): + # See the specification for details. + bytes = [] + mark = self.get_mark() + while self.peek() == u'%': + self.forward() + for k in range(2): + if self.peek(k) not in u'0123456789ABCDEFabcdef': + raise ScannerError("while scanning a %s" % name, start_mark, + "expected URI escape sequence of 2 hexdecimal numbers, but found %r" % + (self.peek(k).encode('utf-8')), self.get_mark()) + bytes.append(chr(int(self.prefix(2), 16))) + self.forward(2) + try: + value = unicode(''.join(bytes), 'utf-8') + except UnicodeDecodeError, exc: + raise ScannerError("while scanning a %s" % name, start_mark, str(exc), mark) + return value + + def scan_line_break(self): + # Transforms: + # '\r\n' : '\n' + # '\r' : '\n' + # '\n' : '\n' + # '\x85' : '\n' + # '\u2028' : '\u2028' + # '\u2029 : '\u2029' + # default : '' + ch = self.peek() + if ch in u'\r\n\x85': + if self.prefix(2) == u'\r\n': + self.forward(2) + else: + self.forward() + return u'\n' + elif ch in u'\u2028\u2029': + self.forward() + return ch + return u'' + +#try: +# import psyco +# psyco.bind(Scanner) +#except ImportError: +# pass + diff --git a/rplibs/yaml/yaml_py2/serializer.py b/rplibs/yaml/yaml_py2/serializer.py new file mode 100644 index 0000000..0bf1e96 --- /dev/null +++ b/rplibs/yaml/yaml_py2/serializer.py @@ -0,0 +1,111 @@ + +__all__ = ['Serializer', 'SerializerError'] + +from error import YAMLError +from events import * +from nodes import * + +class SerializerError(YAMLError): + pass + +class Serializer(object): + + ANCHOR_TEMPLATE = u'id%03d' + + def __init__(self, encoding=None, + explicit_start=None, explicit_end=None, version=None, tags=None): + self.use_encoding = encoding + self.use_explicit_start = explicit_start + self.use_explicit_end = explicit_end + self.use_version = version + self.use_tags = tags + self.serialized_nodes = {} + self.anchors = {} + self.last_anchor_id = 0 + self.closed = None + + def open(self): + if self.closed is None: + self.emit(StreamStartEvent(encoding=self.use_encoding)) + self.closed = False + elif self.closed: + raise SerializerError("serializer is closed") + else: + raise SerializerError("serializer is already opened") + + def close(self): + if self.closed is None: + raise SerializerError("serializer is not opened") + elif not self.closed: + self.emit(StreamEndEvent()) + self.closed = True + + #def __del__(self): + # self.close() + + def serialize(self, node): + if self.closed is None: + raise SerializerError("serializer is not opened") + elif self.closed: + raise SerializerError("serializer is closed") + self.emit(DocumentStartEvent(explicit=self.use_explicit_start, + version=self.use_version, tags=self.use_tags)) + self.anchor_node(node) + self.serialize_node(node, None, None) + self.emit(DocumentEndEvent(explicit=self.use_explicit_end)) + self.serialized_nodes = {} + self.anchors = {} + self.last_anchor_id = 0 + + def anchor_node(self, node): + if node in self.anchors: + if self.anchors[node] is None: + self.anchors[node] = self.generate_anchor(node) + else: + self.anchors[node] = None + if isinstance(node, SequenceNode): + for item in node.value: + self.anchor_node(item) + elif isinstance(node, MappingNode): + for key, value in node.value: + self.anchor_node(key) + self.anchor_node(value) + + def generate_anchor(self, node): + self.last_anchor_id += 1 + return self.ANCHOR_TEMPLATE % self.last_anchor_id + + def serialize_node(self, node, parent, index): + alias = self.anchors[node] + if node in self.serialized_nodes: + self.emit(AliasEvent(alias)) + else: + self.serialized_nodes[node] = True + self.descend_resolver(parent, index) + if isinstance(node, ScalarNode): + detected_tag = self.resolve(ScalarNode, node.value, (True, False)) + default_tag = self.resolve(ScalarNode, node.value, (False, True)) + implicit = (node.tag == detected_tag), (node.tag == default_tag) + self.emit(ScalarEvent(alias, node.tag, implicit, node.value, + style=node.style)) + elif isinstance(node, SequenceNode): + implicit = (node.tag + == self.resolve(SequenceNode, node.value, True)) + self.emit(SequenceStartEvent(alias, node.tag, implicit, + flow_style=node.flow_style)) + index = 0 + for item in node.value: + self.serialize_node(item, node, index) + index += 1 + self.emit(SequenceEndEvent()) + elif isinstance(node, MappingNode): + implicit = (node.tag + == self.resolve(MappingNode, node.value, True)) + self.emit(MappingStartEvent(alias, node.tag, implicit, + flow_style=node.flow_style)) + for key, value in node.value: + self.serialize_node(key, node, None) + self.serialize_node(value, node, key) + self.emit(MappingEndEvent()) + self.ascend_resolver() + diff --git a/rplibs/yaml/yaml_py2/tokens.py b/rplibs/yaml/yaml_py2/tokens.py new file mode 100644 index 0000000..4d0b48a --- /dev/null +++ b/rplibs/yaml/yaml_py2/tokens.py @@ -0,0 +1,104 @@ + +class Token(object): + def __init__(self, start_mark, end_mark): + self.start_mark = start_mark + self.end_mark = end_mark + def __repr__(self): + attributes = [key for key in self.__dict__ + if not key.endswith('_mark')] + attributes.sort() + arguments = ', '.join(['%s=%r' % (key, getattr(self, key)) + for key in attributes]) + return '%s(%s)' % (self.__class__.__name__, arguments) + +#class BOMToken(Token): +# id = '' + +class DirectiveToken(Token): + id = '' + def __init__(self, name, value, start_mark, end_mark): + self.name = name + self.value = value + self.start_mark = start_mark + self.end_mark = end_mark + +class DocumentStartToken(Token): + id = '' + +class DocumentEndToken(Token): + id = '' + +class StreamStartToken(Token): + id = '' + def __init__(self, start_mark=None, end_mark=None, + encoding=None): + self.start_mark = start_mark + self.end_mark = end_mark + self.encoding = encoding + +class StreamEndToken(Token): + id = '' + +class BlockSequenceStartToken(Token): + id = '' + +class BlockMappingStartToken(Token): + id = '' + +class BlockEndToken(Token): + id = '' + +class FlowSequenceStartToken(Token): + id = '[' + +class FlowMappingStartToken(Token): + id = '{' + +class FlowSequenceEndToken(Token): + id = ']' + +class FlowMappingEndToken(Token): + id = '}' + +class KeyToken(Token): + id = '?' + +class ValueToken(Token): + id = ':' + +class BlockEntryToken(Token): + id = '-' + +class FlowEntryToken(Token): + id = ',' + +class AliasToken(Token): + id = '' + def __init__(self, value, start_mark, end_mark): + self.value = value + self.start_mark = start_mark + self.end_mark = end_mark + +class AnchorToken(Token): + id = '' + def __init__(self, value, start_mark, end_mark): + self.value = value + self.start_mark = start_mark + self.end_mark = end_mark + +class TagToken(Token): + id = '' + def __init__(self, value, start_mark, end_mark): + self.value = value + self.start_mark = start_mark + self.end_mark = end_mark + +class ScalarToken(Token): + id = '' + def __init__(self, value, plain, start_mark, end_mark, style=None): + self.value = value + self.plain = plain + self.start_mark = start_mark + self.end_mark = end_mark + self.style = style + diff --git a/rplibs/yaml/yaml_py3/__init__.py b/rplibs/yaml/yaml_py3/__init__.py new file mode 100644 index 0000000..a5e20f9 --- /dev/null +++ b/rplibs/yaml/yaml_py3/__init__.py @@ -0,0 +1,312 @@ + +from .error import * + +from .tokens import * +from .events import * +from .nodes import * + +from .loader import * +from .dumper import * + +__version__ = '3.11' +try: + from .cyaml import * + __with_libyaml__ = True +except ImportError: + __with_libyaml__ = False + +import io + +def scan(stream, Loader=Loader): + """ + Scan a YAML stream and produce scanning tokens. + """ + loader = Loader(stream) + try: + while loader.check_token(): + yield loader.get_token() + finally: + loader.dispose() + +def parse(stream, Loader=Loader): + """ + Parse a YAML stream and produce parsing events. + """ + loader = Loader(stream) + try: + while loader.check_event(): + yield loader.get_event() + finally: + loader.dispose() + +def compose(stream, Loader=Loader): + """ + Parse the first YAML document in a stream + and produce the corresponding representation tree. + """ + loader = Loader(stream) + try: + return loader.get_single_node() + finally: + loader.dispose() + +def compose_all(stream, Loader=Loader): + """ + Parse all YAML documents in a stream + and produce corresponding representation trees. + """ + loader = Loader(stream) + try: + while loader.check_node(): + yield loader.get_node() + finally: + loader.dispose() + +def load(stream, Loader=Loader): + """ + Parse the first YAML document in a stream + and produce the corresponding Python object. + """ + loader = Loader(stream) + try: + return loader.get_single_data() + finally: + loader.dispose() + +def load_all(stream, Loader=Loader): + """ + Parse all YAML documents in a stream + and produce corresponding Python objects. + """ + loader = Loader(stream) + try: + while loader.check_data(): + yield loader.get_data() + finally: + loader.dispose() + +def safe_load(stream): + """ + Parse the first YAML document in a stream + and produce the corresponding Python object. + Resolve only basic YAML tags. + """ + return load(stream, SafeLoader) + +def safe_load_all(stream): + """ + Parse all YAML documents in a stream + and produce corresponding Python objects. + Resolve only basic YAML tags. + """ + return load_all(stream, SafeLoader) + +def emit(events, stream=None, Dumper=Dumper, + canonical=None, indent=None, width=None, + allow_unicode=None, line_break=None): + """ + Emit YAML parsing events into a stream. + If stream is None, return the produced string instead. + """ + getvalue = None + if stream is None: + stream = io.StringIO() + getvalue = stream.getvalue + dumper = Dumper(stream, canonical=canonical, indent=indent, width=width, + allow_unicode=allow_unicode, line_break=line_break) + try: + for event in events: + dumper.emit(event) + finally: + dumper.dispose() + if getvalue: + return getvalue() + +def serialize_all(nodes, stream=None, Dumper=Dumper, + canonical=None, indent=None, width=None, + allow_unicode=None, line_break=None, + encoding=None, explicit_start=None, explicit_end=None, + version=None, tags=None): + """ + Serialize a sequence of representation trees into a YAML stream. + If stream is None, return the produced string instead. + """ + getvalue = None + if stream is None: + if encoding is None: + stream = io.StringIO() + else: + stream = io.BytesIO() + getvalue = stream.getvalue + dumper = Dumper(stream, canonical=canonical, indent=indent, width=width, + allow_unicode=allow_unicode, line_break=line_break, + encoding=encoding, version=version, tags=tags, + explicit_start=explicit_start, explicit_end=explicit_end) + try: + dumper.open() + for node in nodes: + dumper.serialize(node) + dumper.close() + finally: + dumper.dispose() + if getvalue: + return getvalue() + +def serialize(node, stream=None, Dumper=Dumper, **kwds): + """ + Serialize a representation tree into a YAML stream. + If stream is None, return the produced string instead. + """ + return serialize_all([node], stream, Dumper=Dumper, **kwds) + +def dump_all(documents, stream=None, Dumper=Dumper, + default_style=None, default_flow_style=None, + canonical=None, indent=None, width=None, + allow_unicode=None, line_break=None, + encoding=None, explicit_start=None, explicit_end=None, + version=None, tags=None): + """ + Serialize a sequence of Python objects into a YAML stream. + If stream is None, return the produced string instead. + """ + getvalue = None + if stream is None: + if encoding is None: + stream = io.StringIO() + else: + stream = io.BytesIO() + getvalue = stream.getvalue + dumper = Dumper(stream, default_style=default_style, + default_flow_style=default_flow_style, + canonical=canonical, indent=indent, width=width, + allow_unicode=allow_unicode, line_break=line_break, + encoding=encoding, version=version, tags=tags, + explicit_start=explicit_start, explicit_end=explicit_end) + try: + dumper.open() + for data in documents: + dumper.represent(data) + dumper.close() + finally: + dumper.dispose() + if getvalue: + return getvalue() + +def dump(data, stream=None, Dumper=Dumper, **kwds): + """ + Serialize a Python object into a YAML stream. + If stream is None, return the produced string instead. + """ + return dump_all([data], stream, Dumper=Dumper, **kwds) + +def safe_dump_all(documents, stream=None, **kwds): + """ + Serialize a sequence of Python objects into a YAML stream. + Produce only basic YAML tags. + If stream is None, return the produced string instead. + """ + return dump_all(documents, stream, Dumper=SafeDumper, **kwds) + +def safe_dump(data, stream=None, **kwds): + """ + Serialize a Python object into a YAML stream. + Produce only basic YAML tags. + If stream is None, return the produced string instead. + """ + return dump_all([data], stream, Dumper=SafeDumper, **kwds) + +def add_implicit_resolver(tag, regexp, first=None, + Loader=Loader, Dumper=Dumper): + """ + Add an implicit scalar detector. + If an implicit scalar value matches the given regexp, + the corresponding tag is assigned to the scalar. + first is a sequence of possible initial characters or None. + """ + Loader.add_implicit_resolver(tag, regexp, first) + Dumper.add_implicit_resolver(tag, regexp, first) + +def add_path_resolver(tag, path, kind=None, Loader=Loader, Dumper=Dumper): + """ + Add a path based resolver for the given tag. + A path is a list of keys that forms a path + to a node in the representation tree. + Keys can be string values, integers, or None. + """ + Loader.add_path_resolver(tag, path, kind) + Dumper.add_path_resolver(tag, path, kind) + +def add_constructor(tag, constructor, Loader=Loader): + """ + Add a constructor for the given tag. + Constructor is a function that accepts a Loader instance + and a node object and produces the corresponding Python object. + """ + Loader.add_constructor(tag, constructor) + +def add_multi_constructor(tag_prefix, multi_constructor, Loader=Loader): + """ + Add a multi-constructor for the given tag prefix. + Multi-constructor is called for a node if its tag starts with tag_prefix. + Multi-constructor accepts a Loader instance, a tag suffix, + and a node object and produces the corresponding Python object. + """ + Loader.add_multi_constructor(tag_prefix, multi_constructor) + +def add_representer(data_type, representer, Dumper=Dumper): + """ + Add a representer for the given type. + Representer is a function accepting a Dumper instance + and an instance of the given data type + and producing the corresponding representation node. + """ + Dumper.add_representer(data_type, representer) + +def add_multi_representer(data_type, multi_representer, Dumper=Dumper): + """ + Add a representer for the given type. + Multi-representer is a function accepting a Dumper instance + and an instance of the given data type or subtype + and producing the corresponding representation node. + """ + Dumper.add_multi_representer(data_type, multi_representer) + +class YAMLObjectMetaclass(type): + """ + The metaclass for YAMLObject. + """ + def __init__(cls, name, bases, kwds): + super(YAMLObjectMetaclass, cls).__init__(name, bases, kwds) + if 'yaml_tag' in kwds and kwds['yaml_tag'] is not None: + cls.yaml_loader.add_constructor(cls.yaml_tag, cls.from_yaml) + cls.yaml_dumper.add_representer(cls, cls.to_yaml) + +class YAMLObject(metaclass=YAMLObjectMetaclass): + """ + An object that can dump itself to a YAML stream + and load itself from a YAML stream. + """ + + __slots__ = () # no direct instantiation, so allow immutable subclasses + + yaml_loader = Loader + yaml_dumper = Dumper + + yaml_tag = None + yaml_flow_style = None + + @classmethod + def from_yaml(cls, loader, node): + """ + Convert a representation node to a Python object. + """ + return loader.construct_yaml_object(node, cls) + + @classmethod + def to_yaml(cls, dumper, data): + """ + Convert a Python object to a representation node. + """ + return dumper.represent_yaml_object(cls.yaml_tag, data, cls, + flow_style=cls.yaml_flow_style) + diff --git a/rplibs/yaml/yaml_py3/composer.py b/rplibs/yaml/yaml_py3/composer.py new file mode 100644 index 0000000..d5c6a7a --- /dev/null +++ b/rplibs/yaml/yaml_py3/composer.py @@ -0,0 +1,139 @@ + +__all__ = ['Composer', 'ComposerError'] + +from .error import MarkedYAMLError +from .events import * +from .nodes import * + +class ComposerError(MarkedYAMLError): + pass + +class Composer: + + def __init__(self): + self.anchors = {} + + def check_node(self): + # Drop the STREAM-START event. + if self.check_event(StreamStartEvent): + self.get_event() + + # If there are more documents available? + return not self.check_event(StreamEndEvent) + + def get_node(self): + # Get the root node of the next document. + if not self.check_event(StreamEndEvent): + return self.compose_document() + + def get_single_node(self): + # Drop the STREAM-START event. + self.get_event() + + # Compose a document if the stream is not empty. + document = None + if not self.check_event(StreamEndEvent): + document = self.compose_document() + + # Ensure that the stream contains no more documents. + if not self.check_event(StreamEndEvent): + event = self.get_event() + raise ComposerError("expected a single document in the stream", + document.start_mark, "but found another document", + event.start_mark) + + # Drop the STREAM-END event. + self.get_event() + + return document + + def compose_document(self): + # Drop the DOCUMENT-START event. + self.get_event() + + # Compose the root node. + node = self.compose_node(None, None) + + # Drop the DOCUMENT-END event. + self.get_event() + + self.anchors = {} + return node + + def compose_node(self, parent, index): + if self.check_event(AliasEvent): + event = self.get_event() + anchor = event.anchor + if anchor not in self.anchors: + raise ComposerError(None, None, "found undefined alias %r" + % anchor, event.start_mark) + return self.anchors[anchor] + event = self.peek_event() + anchor = event.anchor + if anchor is not None: + if anchor in self.anchors: + raise ComposerError("found duplicate anchor %r; first occurence" + % anchor, self.anchors[anchor].start_mark, + "second occurence", event.start_mark) + self.descend_resolver(parent, index) + if self.check_event(ScalarEvent): + node = self.compose_scalar_node(anchor) + elif self.check_event(SequenceStartEvent): + node = self.compose_sequence_node(anchor) + elif self.check_event(MappingStartEvent): + node = self.compose_mapping_node(anchor) + self.ascend_resolver() + return node + + def compose_scalar_node(self, anchor): + event = self.get_event() + tag = event.tag + if tag is None or tag == '!': + tag = self.resolve(ScalarNode, event.value, event.implicit) + node = ScalarNode(tag, event.value, + event.start_mark, event.end_mark, style=event.style) + if anchor is not None: + self.anchors[anchor] = node + return node + + def compose_sequence_node(self, anchor): + start_event = self.get_event() + tag = start_event.tag + if tag is None or tag == '!': + tag = self.resolve(SequenceNode, None, start_event.implicit) + node = SequenceNode(tag, [], + start_event.start_mark, None, + flow_style=start_event.flow_style) + if anchor is not None: + self.anchors[anchor] = node + index = 0 + while not self.check_event(SequenceEndEvent): + node.value.append(self.compose_node(node, index)) + index += 1 + end_event = self.get_event() + node.end_mark = end_event.end_mark + return node + + def compose_mapping_node(self, anchor): + start_event = self.get_event() + tag = start_event.tag + if tag is None or tag == '!': + tag = self.resolve(MappingNode, None, start_event.implicit) + node = MappingNode(tag, [], + start_event.start_mark, None, + flow_style=start_event.flow_style) + if anchor is not None: + self.anchors[anchor] = node + while not self.check_event(MappingEndEvent): + #key_event = self.peek_event() + item_key = self.compose_node(node, None) + #if item_key in node.value: + # raise ComposerError("while composing a mapping", start_event.start_mark, + # "found duplicate key", key_event.start_mark) + item_value = self.compose_node(node, item_key) + #node.value[item_key] = item_value + node.value.append((item_key, item_value)) + end_event = self.get_event() + node.end_mark = end_event.end_mark + return node + diff --git a/rplibs/yaml/yaml_py3/constructor.py b/rplibs/yaml/yaml_py3/constructor.py new file mode 100644 index 0000000..6222808 --- /dev/null +++ b/rplibs/yaml/yaml_py3/constructor.py @@ -0,0 +1,686 @@ + +__all__ = ['BaseConstructor', 'SafeConstructor', 'Constructor', + 'ConstructorError'] + +from .error import * +from .nodes import * + +import collections, datetime, base64, binascii, re, sys, types + +class ConstructorError(MarkedYAMLError): + pass + +class BaseConstructor: + + yaml_constructors = {} + yaml_multi_constructors = {} + + def __init__(self): + self.constructed_objects = {} + self.recursive_objects = {} + self.state_generators = [] + self.deep_construct = False + + def check_data(self): + # If there are more documents available? + return self.check_node() + + def get_data(self): + # Construct and return the next document. + if self.check_node(): + return self.construct_document(self.get_node()) + + def get_single_data(self): + # Ensure that the stream contains a single document and construct it. + node = self.get_single_node() + if node is not None: + return self.construct_document(node) + return None + + def construct_document(self, node): + data = self.construct_object(node) + while self.state_generators: + state_generators = self.state_generators + self.state_generators = [] + for generator in state_generators: + for dummy in generator: + pass + self.constructed_objects = {} + self.recursive_objects = {} + self.deep_construct = False + return data + + def construct_object(self, node, deep=False): + if node in self.constructed_objects: + return self.constructed_objects[node] + if deep: + old_deep = self.deep_construct + self.deep_construct = True + if node in self.recursive_objects: + raise ConstructorError(None, None, + "found unconstructable recursive node", node.start_mark) + self.recursive_objects[node] = None + constructor = None + tag_suffix = None + if node.tag in self.yaml_constructors: + constructor = self.yaml_constructors[node.tag] + else: + for tag_prefix in self.yaml_multi_constructors: + if node.tag.startswith(tag_prefix): + tag_suffix = node.tag[len(tag_prefix):] + constructor = self.yaml_multi_constructors[tag_prefix] + break + else: + if None in self.yaml_multi_constructors: + tag_suffix = node.tag + constructor = self.yaml_multi_constructors[None] + elif None in self.yaml_constructors: + constructor = self.yaml_constructors[None] + elif isinstance(node, ScalarNode): + constructor = self.__class__.construct_scalar + elif isinstance(node, SequenceNode): + constructor = self.__class__.construct_sequence + elif isinstance(node, MappingNode): + constructor = self.__class__.construct_mapping + if tag_suffix is None: + data = constructor(self, node) + else: + data = constructor(self, tag_suffix, node) + if isinstance(data, types.GeneratorType): + generator = data + data = next(generator) + if self.deep_construct: + for dummy in generator: + pass + else: + self.state_generators.append(generator) + self.constructed_objects[node] = data + del self.recursive_objects[node] + if deep: + self.deep_construct = old_deep + return data + + def construct_scalar(self, node): + if not isinstance(node, ScalarNode): + raise ConstructorError(None, None, + "expected a scalar node, but found %s" % node.id, + node.start_mark) + return node.value + + def construct_sequence(self, node, deep=False): + if not isinstance(node, SequenceNode): + raise ConstructorError(None, None, + "expected a sequence node, but found %s" % node.id, + node.start_mark) + return [self.construct_object(child, deep=deep) + for child in node.value] + + def construct_mapping(self, node, deep=False): + if not isinstance(node, MappingNode): + raise ConstructorError(None, None, + "expected a mapping node, but found %s" % node.id, + node.start_mark) + mapping = {} + for key_node, value_node in node.value: + key = self.construct_object(key_node, deep=deep) + if not isinstance(key, collections.abc.Hashable): + raise ConstructorError("while constructing a mapping", node.start_mark, + "found unhashable key", key_node.start_mark) + value = self.construct_object(value_node, deep=deep) + mapping[key] = value + return mapping + + def construct_pairs(self, node, deep=False): + if not isinstance(node, MappingNode): + raise ConstructorError(None, None, + "expected a mapping node, but found %s" % node.id, + node.start_mark) + pairs = [] + for key_node, value_node in node.value: + key = self.construct_object(key_node, deep=deep) + value = self.construct_object(value_node, deep=deep) + pairs.append((key, value)) + return pairs + + @classmethod + def add_constructor(cls, tag, constructor): + if not 'yaml_constructors' in cls.__dict__: + cls.yaml_constructors = cls.yaml_constructors.copy() + cls.yaml_constructors[tag] = constructor + + @classmethod + def add_multi_constructor(cls, tag_prefix, multi_constructor): + if not 'yaml_multi_constructors' in cls.__dict__: + cls.yaml_multi_constructors = cls.yaml_multi_constructors.copy() + cls.yaml_multi_constructors[tag_prefix] = multi_constructor + +class SafeConstructor(BaseConstructor): + + def construct_scalar(self, node): + if isinstance(node, MappingNode): + for key_node, value_node in node.value: + if key_node.tag == 'tag:yaml.org,2002:value': + return self.construct_scalar(value_node) + return super().construct_scalar(node) + + def flatten_mapping(self, node): + merge = [] + index = 0 + while index < len(node.value): + key_node, value_node = node.value[index] + if key_node.tag == 'tag:yaml.org,2002:merge': + del node.value[index] + if isinstance(value_node, MappingNode): + self.flatten_mapping(value_node) + merge.extend(value_node.value) + elif isinstance(value_node, SequenceNode): + submerge = [] + for subnode in value_node.value: + if not isinstance(subnode, MappingNode): + raise ConstructorError("while constructing a mapping", + node.start_mark, + "expected a mapping for merging, but found %s" + % subnode.id, subnode.start_mark) + self.flatten_mapping(subnode) + submerge.append(subnode.value) + submerge.reverse() + for value in submerge: + merge.extend(value) + else: + raise ConstructorError("while constructing a mapping", node.start_mark, + "expected a mapping or list of mappings for merging, but found %s" + % value_node.id, value_node.start_mark) + elif key_node.tag == 'tag:yaml.org,2002:value': + key_node.tag = 'tag:yaml.org,2002:str' + index += 1 + else: + index += 1 + if merge: + node.value = merge + node.value + + def construct_mapping(self, node, deep=False): + if isinstance(node, MappingNode): + self.flatten_mapping(node) + return super().construct_mapping(node, deep=deep) + + def construct_yaml_null(self, node): + self.construct_scalar(node) + return None + + bool_values = { + 'yes': True, + 'no': False, + 'true': True, + 'false': False, + 'on': True, + 'off': False, + } + + def construct_yaml_bool(self, node): + value = self.construct_scalar(node) + return self.bool_values[value.lower()] + + def construct_yaml_int(self, node): + value = self.construct_scalar(node) + value = value.replace('_', '') + sign = +1 + if value[0] == '-': + sign = -1 + if value[0] in '+-': + value = value[1:] + if value == '0': + return 0 + elif value.startswith('0b'): + return sign*int(value[2:], 2) + elif value.startswith('0x'): + return sign*int(value[2:], 16) + elif value[0] == '0': + return sign*int(value, 8) + elif ':' in value: + digits = [int(part) for part in value.split(':')] + digits.reverse() + base = 1 + value = 0 + for digit in digits: + value += digit*base + base *= 60 + return sign*value + else: + return sign*int(value) + + inf_value = 1e300 + while inf_value != inf_value*inf_value: + inf_value *= inf_value + nan_value = -inf_value/inf_value # Trying to make a quiet NaN (like C99). + + def construct_yaml_float(self, node): + value = self.construct_scalar(node) + value = value.replace('_', '').lower() + sign = +1 + if value[0] == '-': + sign = -1 + if value[0] in '+-': + value = value[1:] + if value == '.inf': + return sign*self.inf_value + elif value == '.nan': + return self.nan_value + elif ':' in value: + digits = [float(part) for part in value.split(':')] + digits.reverse() + base = 1 + value = 0.0 + for digit in digits: + value += digit*base + base *= 60 + return sign*value + else: + return sign*float(value) + + def construct_yaml_binary(self, node): + try: + value = self.construct_scalar(node).encode('ascii') + except UnicodeEncodeError as exc: + raise ConstructorError(None, None, + "failed to convert base64 data into ascii: %s" % exc, + node.start_mark) + try: + if hasattr(base64, 'decodebytes'): + return base64.decodebytes(value) + else: + return base64.decodestring(value) + except binascii.Error as exc: + raise ConstructorError(None, None, + "failed to decode base64 data: %s" % exc, node.start_mark) + + timestamp_regexp = re.compile( + r'''^(?P[0-9][0-9][0-9][0-9]) + -(?P[0-9][0-9]?) + -(?P[0-9][0-9]?) + (?:(?:[Tt]|[ \t]+) + (?P[0-9][0-9]?) + :(?P[0-9][0-9]) + :(?P[0-9][0-9]) + (?:\.(?P[0-9]*))? + (?:[ \t]*(?PZ|(?P[-+])(?P[0-9][0-9]?) + (?::(?P[0-9][0-9]))?))?)?$''', re.X) + + def construct_yaml_timestamp(self, node): + value = self.construct_scalar(node) + match = self.timestamp_regexp.match(node.value) + values = match.groupdict() + year = int(values['year']) + month = int(values['month']) + day = int(values['day']) + if not values['hour']: + return datetime.date(year, month, day) + hour = int(values['hour']) + minute = int(values['minute']) + second = int(values['second']) + fraction = 0 + if values['fraction']: + fraction = values['fraction'][:6] + while len(fraction) < 6: + fraction += '0' + fraction = int(fraction) + delta = None + if values['tz_sign']: + tz_hour = int(values['tz_hour']) + tz_minute = int(values['tz_minute'] or 0) + delta = datetime.timedelta(hours=tz_hour, minutes=tz_minute) + if values['tz_sign'] == '-': + delta = -delta + data = datetime.datetime(year, month, day, hour, minute, second, fraction) + if delta: + data -= delta + return data + + def construct_yaml_omap(self, node): + # Note: we do not check for duplicate keys, because it's too + # CPU-expensive. + omap = [] + yield omap + if not isinstance(node, SequenceNode): + raise ConstructorError("while constructing an ordered map", node.start_mark, + "expected a sequence, but found %s" % node.id, node.start_mark) + for subnode in node.value: + if not isinstance(subnode, MappingNode): + raise ConstructorError("while constructing an ordered map", node.start_mark, + "expected a mapping of length 1, but found %s" % subnode.id, + subnode.start_mark) + if len(subnode.value) != 1: + raise ConstructorError("while constructing an ordered map", node.start_mark, + "expected a single mapping item, but found %d items" % len(subnode.value), + subnode.start_mark) + key_node, value_node = subnode.value[0] + key = self.construct_object(key_node) + value = self.construct_object(value_node) + omap.append((key, value)) + + def construct_yaml_pairs(self, node): + # Note: the same code as `construct_yaml_omap`. + pairs = [] + yield pairs + if not isinstance(node, SequenceNode): + raise ConstructorError("while constructing pairs", node.start_mark, + "expected a sequence, but found %s" % node.id, node.start_mark) + for subnode in node.value: + if not isinstance(subnode, MappingNode): + raise ConstructorError("while constructing pairs", node.start_mark, + "expected a mapping of length 1, but found %s" % subnode.id, + subnode.start_mark) + if len(subnode.value) != 1: + raise ConstructorError("while constructing pairs", node.start_mark, + "expected a single mapping item, but found %d items" % len(subnode.value), + subnode.start_mark) + key_node, value_node = subnode.value[0] + key = self.construct_object(key_node) + value = self.construct_object(value_node) + pairs.append((key, value)) + + def construct_yaml_set(self, node): + data = set() + yield data + value = self.construct_mapping(node) + data.update(value) + + def construct_yaml_str(self, node): + return self.construct_scalar(node) + + def construct_yaml_seq(self, node): + data = [] + yield data + data.extend(self.construct_sequence(node)) + + def construct_yaml_map(self, node): + data = {} + yield data + value = self.construct_mapping(node) + data.update(value) + + def construct_yaml_object(self, node, cls): + data = cls.__new__(cls) + yield data + if hasattr(data, '__setstate__'): + state = self.construct_mapping(node, deep=True) + data.__setstate__(state) + else: + state = self.construct_mapping(node) + data.__dict__.update(state) + + def construct_undefined(self, node): + raise ConstructorError(None, None, + "could not determine a constructor for the tag %r" % node.tag, + node.start_mark) + +SafeConstructor.add_constructor( + 'tag:yaml.org,2002:null', + SafeConstructor.construct_yaml_null) + +SafeConstructor.add_constructor( + 'tag:yaml.org,2002:bool', + SafeConstructor.construct_yaml_bool) + +SafeConstructor.add_constructor( + 'tag:yaml.org,2002:int', + SafeConstructor.construct_yaml_int) + +SafeConstructor.add_constructor( + 'tag:yaml.org,2002:float', + SafeConstructor.construct_yaml_float) + +SafeConstructor.add_constructor( + 'tag:yaml.org,2002:binary', + SafeConstructor.construct_yaml_binary) + +SafeConstructor.add_constructor( + 'tag:yaml.org,2002:timestamp', + SafeConstructor.construct_yaml_timestamp) + +SafeConstructor.add_constructor( + 'tag:yaml.org,2002:omap', + SafeConstructor.construct_yaml_omap) + +SafeConstructor.add_constructor( + 'tag:yaml.org,2002:pairs', + SafeConstructor.construct_yaml_pairs) + +SafeConstructor.add_constructor( + 'tag:yaml.org,2002:set', + SafeConstructor.construct_yaml_set) + +SafeConstructor.add_constructor( + 'tag:yaml.org,2002:str', + SafeConstructor.construct_yaml_str) + +SafeConstructor.add_constructor( + 'tag:yaml.org,2002:seq', + SafeConstructor.construct_yaml_seq) + +SafeConstructor.add_constructor( + 'tag:yaml.org,2002:map', + SafeConstructor.construct_yaml_map) + +SafeConstructor.add_constructor(None, + SafeConstructor.construct_undefined) + +class Constructor(SafeConstructor): + + def construct_python_str(self, node): + return self.construct_scalar(node) + + def construct_python_unicode(self, node): + return self.construct_scalar(node) + + def construct_python_bytes(self, node): + try: + value = self.construct_scalar(node).encode('ascii') + except UnicodeEncodeError as exc: + raise ConstructorError(None, None, + "failed to convert base64 data into ascii: %s" % exc, + node.start_mark) + try: + if hasattr(base64, 'decodebytes'): + return base64.decodebytes(value) + else: + return base64.decodestring(value) + except binascii.Error as exc: + raise ConstructorError(None, None, + "failed to decode base64 data: %s" % exc, node.start_mark) + + def construct_python_long(self, node): + return self.construct_yaml_int(node) + + def construct_python_complex(self, node): + return complex(self.construct_scalar(node)) + + def construct_python_tuple(self, node): + return tuple(self.construct_sequence(node)) + + def find_python_module(self, name, mark): + if not name: + raise ConstructorError("while constructing a Python module", mark, + "expected non-empty name appended to the tag", mark) + try: + __import__(name) + except ImportError as exc: + raise ConstructorError("while constructing a Python module", mark, + "cannot find module %r (%s)" % (name, exc), mark) + return sys.modules[name] + + def find_python_name(self, name, mark): + if not name: + raise ConstructorError("while constructing a Python object", mark, + "expected non-empty name appended to the tag", mark) + if '.' in name: + module_name, object_name = name.rsplit('.', 1) + else: + module_name = 'builtins' + object_name = name + try: + __import__(module_name) + except ImportError as exc: + raise ConstructorError("while constructing a Python object", mark, + "cannot find module %r (%s)" % (module_name, exc), mark) + module = sys.modules[module_name] + if not hasattr(module, object_name): + raise ConstructorError("while constructing a Python object", mark, + "cannot find %r in the module %r" + % (object_name, module.__name__), mark) + return getattr(module, object_name) + + def construct_python_name(self, suffix, node): + value = self.construct_scalar(node) + if value: + raise ConstructorError("while constructing a Python name", node.start_mark, + "expected the empty value, but found %r" % value, node.start_mark) + return self.find_python_name(suffix, node.start_mark) + + def construct_python_module(self, suffix, node): + value = self.construct_scalar(node) + if value: + raise ConstructorError("while constructing a Python module", node.start_mark, + "expected the empty value, but found %r" % value, node.start_mark) + return self.find_python_module(suffix, node.start_mark) + + def make_python_instance(self, suffix, node, + args=None, kwds=None, newobj=False): + if not args: + args = [] + if not kwds: + kwds = {} + cls = self.find_python_name(suffix, node.start_mark) + if newobj and isinstance(cls, type): + return cls.__new__(cls, *args, **kwds) + else: + return cls(*args, **kwds) + + def set_python_instance_state(self, instance, state): + if hasattr(instance, '__setstate__'): + instance.__setstate__(state) + else: + slotstate = {} + if isinstance(state, tuple) and len(state) == 2: + state, slotstate = state + if hasattr(instance, '__dict__'): + instance.__dict__.update(state) + elif state: + slotstate.update(state) + for key, value in slotstate.items(): + setattr(object, key, value) + + def construct_python_object(self, suffix, node): + # Format: + # !!python/object:module.name { ... state ... } + instance = self.make_python_instance(suffix, node, newobj=True) + yield instance + deep = hasattr(instance, '__setstate__') + state = self.construct_mapping(node, deep=deep) + self.set_python_instance_state(instance, state) + + def construct_python_object_apply(self, suffix, node, newobj=False): + # Format: + # !!python/object/apply # (or !!python/object/new) + # args: [ ... arguments ... ] + # kwds: { ... keywords ... } + # state: ... state ... + # listitems: [ ... listitems ... ] + # dictitems: { ... dictitems ... } + # or short format: + # !!python/object/apply [ ... arguments ... ] + # The difference between !!python/object/apply and !!python/object/new + # is how an object is created, check make_python_instance for details. + if isinstance(node, SequenceNode): + args = self.construct_sequence(node, deep=True) + kwds = {} + state = {} + listitems = [] + dictitems = {} + else: + value = self.construct_mapping(node, deep=True) + args = value.get('args', []) + kwds = value.get('kwds', {}) + state = value.get('state', {}) + listitems = value.get('listitems', []) + dictitems = value.get('dictitems', {}) + instance = self.make_python_instance(suffix, node, args, kwds, newobj) + if state: + self.set_python_instance_state(instance, state) + if listitems: + instance.extend(listitems) + if dictitems: + for key in dictitems: + instance[key] = dictitems[key] + return instance + + def construct_python_object_new(self, suffix, node): + return self.construct_python_object_apply(suffix, node, newobj=True) + +Constructor.add_constructor( + 'tag:yaml.org,2002:python/none', + Constructor.construct_yaml_null) + +Constructor.add_constructor( + 'tag:yaml.org,2002:python/bool', + Constructor.construct_yaml_bool) + +Constructor.add_constructor( + 'tag:yaml.org,2002:python/str', + Constructor.construct_python_str) + +Constructor.add_constructor( + 'tag:yaml.org,2002:python/unicode', + Constructor.construct_python_unicode) + +Constructor.add_constructor( + 'tag:yaml.org,2002:python/bytes', + Constructor.construct_python_bytes) + +Constructor.add_constructor( + 'tag:yaml.org,2002:python/int', + Constructor.construct_yaml_int) + +Constructor.add_constructor( + 'tag:yaml.org,2002:python/long', + Constructor.construct_python_long) + +Constructor.add_constructor( + 'tag:yaml.org,2002:python/float', + Constructor.construct_yaml_float) + +Constructor.add_constructor( + 'tag:yaml.org,2002:python/complex', + Constructor.construct_python_complex) + +Constructor.add_constructor( + 'tag:yaml.org,2002:python/list', + Constructor.construct_yaml_seq) + +Constructor.add_constructor( + 'tag:yaml.org,2002:python/tuple', + Constructor.construct_python_tuple) + +Constructor.add_constructor( + 'tag:yaml.org,2002:python/dict', + Constructor.construct_yaml_map) + +Constructor.add_multi_constructor( + 'tag:yaml.org,2002:python/name:', + Constructor.construct_python_name) + +Constructor.add_multi_constructor( + 'tag:yaml.org,2002:python/module:', + Constructor.construct_python_module) + +Constructor.add_multi_constructor( + 'tag:yaml.org,2002:python/object:', + Constructor.construct_python_object) + +Constructor.add_multi_constructor( + 'tag:yaml.org,2002:python/object/apply:', + Constructor.construct_python_object_apply) + +Constructor.add_multi_constructor( + 'tag:yaml.org,2002:python/object/new:', + Constructor.construct_python_object_new) + diff --git a/rplibs/yaml/yaml_py3/cyaml.py b/rplibs/yaml/yaml_py3/cyaml.py new file mode 100644 index 0000000..d5cb87e --- /dev/null +++ b/rplibs/yaml/yaml_py3/cyaml.py @@ -0,0 +1,85 @@ + +__all__ = ['CBaseLoader', 'CSafeLoader', 'CLoader', + 'CBaseDumper', 'CSafeDumper', 'CDumper'] + +from _yaml import CParser, CEmitter + +from .constructor import * + +from .serializer import * +from .representer import * + +from .resolver import * + +class CBaseLoader(CParser, BaseConstructor, BaseResolver): + + def __init__(self, stream): + CParser.__init__(self, stream) + BaseConstructor.__init__(self) + BaseResolver.__init__(self) + +class CSafeLoader(CParser, SafeConstructor, Resolver): + + def __init__(self, stream): + CParser.__init__(self, stream) + SafeConstructor.__init__(self) + Resolver.__init__(self) + +class CLoader(CParser, Constructor, Resolver): + + def __init__(self, stream): + CParser.__init__(self, stream) + Constructor.__init__(self) + Resolver.__init__(self) + +class CBaseDumper(CEmitter, BaseRepresenter, BaseResolver): + + def __init__(self, stream, + default_style=None, default_flow_style=None, + canonical=None, indent=None, width=None, + allow_unicode=None, line_break=None, + encoding=None, explicit_start=None, explicit_end=None, + version=None, tags=None): + CEmitter.__init__(self, stream, canonical=canonical, + indent=indent, width=width, encoding=encoding, + allow_unicode=allow_unicode, line_break=line_break, + explicit_start=explicit_start, explicit_end=explicit_end, + version=version, tags=tags) + Representer.__init__(self, default_style=default_style, + default_flow_style=default_flow_style) + Resolver.__init__(self) + +class CSafeDumper(CEmitter, SafeRepresenter, Resolver): + + def __init__(self, stream, + default_style=None, default_flow_style=None, + canonical=None, indent=None, width=None, + allow_unicode=None, line_break=None, + encoding=None, explicit_start=None, explicit_end=None, + version=None, tags=None): + CEmitter.__init__(self, stream, canonical=canonical, + indent=indent, width=width, encoding=encoding, + allow_unicode=allow_unicode, line_break=line_break, + explicit_start=explicit_start, explicit_end=explicit_end, + version=version, tags=tags) + SafeRepresenter.__init__(self, default_style=default_style, + default_flow_style=default_flow_style) + Resolver.__init__(self) + +class CDumper(CEmitter, Serializer, Representer, Resolver): + + def __init__(self, stream, + default_style=None, default_flow_style=None, + canonical=None, indent=None, width=None, + allow_unicode=None, line_break=None, + encoding=None, explicit_start=None, explicit_end=None, + version=None, tags=None): + CEmitter.__init__(self, stream, canonical=canonical, + indent=indent, width=width, encoding=encoding, + allow_unicode=allow_unicode, line_break=line_break, + explicit_start=explicit_start, explicit_end=explicit_end, + version=version, tags=tags) + Representer.__init__(self, default_style=default_style, + default_flow_style=default_flow_style) + Resolver.__init__(self) + diff --git a/rplibs/yaml/yaml_py3/dumper.py b/rplibs/yaml/yaml_py3/dumper.py new file mode 100644 index 0000000..0b69128 --- /dev/null +++ b/rplibs/yaml/yaml_py3/dumper.py @@ -0,0 +1,62 @@ + +__all__ = ['BaseDumper', 'SafeDumper', 'Dumper'] + +from .emitter import * +from .serializer import * +from .representer import * +from .resolver import * + +class BaseDumper(Emitter, Serializer, BaseRepresenter, BaseResolver): + + def __init__(self, stream, + default_style=None, default_flow_style=None, + canonical=None, indent=None, width=None, + allow_unicode=None, line_break=None, + encoding=None, explicit_start=None, explicit_end=None, + version=None, tags=None): + Emitter.__init__(self, stream, canonical=canonical, + indent=indent, width=width, + allow_unicode=allow_unicode, line_break=line_break) + Serializer.__init__(self, encoding=encoding, + explicit_start=explicit_start, explicit_end=explicit_end, + version=version, tags=tags) + Representer.__init__(self, default_style=default_style, + default_flow_style=default_flow_style) + Resolver.__init__(self) + +class SafeDumper(Emitter, Serializer, SafeRepresenter, Resolver): + + def __init__(self, stream, + default_style=None, default_flow_style=None, + canonical=None, indent=None, width=None, + allow_unicode=None, line_break=None, + encoding=None, explicit_start=None, explicit_end=None, + version=None, tags=None): + Emitter.__init__(self, stream, canonical=canonical, + indent=indent, width=width, + allow_unicode=allow_unicode, line_break=line_break) + Serializer.__init__(self, encoding=encoding, + explicit_start=explicit_start, explicit_end=explicit_end, + version=version, tags=tags) + SafeRepresenter.__init__(self, default_style=default_style, + default_flow_style=default_flow_style) + Resolver.__init__(self) + +class Dumper(Emitter, Serializer, Representer, Resolver): + + def __init__(self, stream, + default_style=None, default_flow_style=None, + canonical=None, indent=None, width=None, + allow_unicode=None, line_break=None, + encoding=None, explicit_start=None, explicit_end=None, + version=None, tags=None): + Emitter.__init__(self, stream, canonical=canonical, + indent=indent, width=width, + allow_unicode=allow_unicode, line_break=line_break) + Serializer.__init__(self, encoding=encoding, + explicit_start=explicit_start, explicit_end=explicit_end, + version=version, tags=tags) + Representer.__init__(self, default_style=default_style, + default_flow_style=default_flow_style) + Resolver.__init__(self) + diff --git a/rplibs/yaml/yaml_py3/emitter.py b/rplibs/yaml/yaml_py3/emitter.py new file mode 100644 index 0000000..34cb145 --- /dev/null +++ b/rplibs/yaml/yaml_py3/emitter.py @@ -0,0 +1,1137 @@ + +# Emitter expects events obeying the following grammar: +# stream ::= STREAM-START document* STREAM-END +# document ::= DOCUMENT-START node DOCUMENT-END +# node ::= SCALAR | sequence | mapping +# sequence ::= SEQUENCE-START node* SEQUENCE-END +# mapping ::= MAPPING-START (node node)* MAPPING-END + +__all__ = ['Emitter', 'EmitterError'] + +from .error import YAMLError +from .events import * + +class EmitterError(YAMLError): + pass + +class ScalarAnalysis: + def __init__(self, scalar, empty, multiline, + allow_flow_plain, allow_block_plain, + allow_single_quoted, allow_double_quoted, + allow_block): + self.scalar = scalar + self.empty = empty + self.multiline = multiline + self.allow_flow_plain = allow_flow_plain + self.allow_block_plain = allow_block_plain + self.allow_single_quoted = allow_single_quoted + self.allow_double_quoted = allow_double_quoted + self.allow_block = allow_block + +class Emitter: + + DEFAULT_TAG_PREFIXES = { + '!' : '!', + 'tag:yaml.org,2002:' : '!!', + } + + def __init__(self, stream, canonical=None, indent=None, width=None, + allow_unicode=None, line_break=None): + + # The stream should have the methods `write` and possibly `flush`. + self.stream = stream + + # Encoding can be overriden by STREAM-START. + self.encoding = None + + # Emitter is a state machine with a stack of states to handle nested + # structures. + self.states = [] + self.state = self.expect_stream_start + + # Current event and the event queue. + self.events = [] + self.event = None + + # The current indentation level and the stack of previous indents. + self.indents = [] + self.indent = None + + # Flow level. + self.flow_level = 0 + + # Contexts. + self.root_context = False + self.sequence_context = False + self.mapping_context = False + self.simple_key_context = False + + # Characteristics of the last emitted character: + # - current position. + # - is it a whitespace? + # - is it an indention character + # (indentation space, '-', '?', or ':')? + self.line = 0 + self.column = 0 + self.whitespace = True + self.indention = True + + # Whether the document requires an explicit document indicator + self.open_ended = False + + # Formatting details. + self.canonical = canonical + self.allow_unicode = allow_unicode + self.best_indent = 2 + if indent and 1 < indent < 10: + self.best_indent = indent + self.best_width = 80 + if width and width > self.best_indent*2: + self.best_width = width + self.best_line_break = '\n' + if line_break in ['\r', '\n', '\r\n']: + self.best_line_break = line_break + + # Tag prefixes. + self.tag_prefixes = None + + # Prepared anchor and tag. + self.prepared_anchor = None + self.prepared_tag = None + + # Scalar analysis and style. + self.analysis = None + self.style = None + + def dispose(self): + # Reset the state attributes (to clear self-references) + self.states = [] + self.state = None + + def emit(self, event): + self.events.append(event) + while not self.need_more_events(): + self.event = self.events.pop(0) + self.state() + self.event = None + + # In some cases, we wait for a few next events before emitting. + + def need_more_events(self): + if not self.events: + return True + event = self.events[0] + if isinstance(event, DocumentStartEvent): + return self.need_events(1) + elif isinstance(event, SequenceStartEvent): + return self.need_events(2) + elif isinstance(event, MappingStartEvent): + return self.need_events(3) + else: + return False + + def need_events(self, count): + level = 0 + for event in self.events[1:]: + if isinstance(event, (DocumentStartEvent, CollectionStartEvent)): + level += 1 + elif isinstance(event, (DocumentEndEvent, CollectionEndEvent)): + level -= 1 + elif isinstance(event, StreamEndEvent): + level = -1 + if level < 0: + return False + return (len(self.events) < count+1) + + def increase_indent(self, flow=False, indentless=False): + self.indents.append(self.indent) + if self.indent is None: + if flow: + self.indent = self.best_indent + else: + self.indent = 0 + elif not indentless: + self.indent += self.best_indent + + # States. + + # Stream handlers. + + def expect_stream_start(self): + if isinstance(self.event, StreamStartEvent): + if self.event.encoding and not hasattr(self.stream, 'encoding'): + self.encoding = self.event.encoding + self.write_stream_start() + self.state = self.expect_first_document_start + else: + raise EmitterError("expected StreamStartEvent, but got %s" + % self.event) + + def expect_nothing(self): + raise EmitterError("expected nothing, but got %s" % self.event) + + # Document handlers. + + def expect_first_document_start(self): + return self.expect_document_start(first=True) + + def expect_document_start(self, first=False): + if isinstance(self.event, DocumentStartEvent): + if (self.event.version or self.event.tags) and self.open_ended: + self.write_indicator('...', True) + self.write_indent() + if self.event.version: + version_text = self.prepare_version(self.event.version) + self.write_version_directive(version_text) + self.tag_prefixes = self.DEFAULT_TAG_PREFIXES.copy() + if self.event.tags: + handles = sorted(self.event.tags.keys()) + for handle in handles: + prefix = self.event.tags[handle] + self.tag_prefixes[prefix] = handle + handle_text = self.prepare_tag_handle(handle) + prefix_text = self.prepare_tag_prefix(prefix) + self.write_tag_directive(handle_text, prefix_text) + implicit = (first and not self.event.explicit and not self.canonical + and not self.event.version and not self.event.tags + and not self.check_empty_document()) + if not implicit: + self.write_indent() + self.write_indicator('---', True) + if self.canonical: + self.write_indent() + self.state = self.expect_document_root + elif isinstance(self.event, StreamEndEvent): + if self.open_ended: + self.write_indicator('...', True) + self.write_indent() + self.write_stream_end() + self.state = self.expect_nothing + else: + raise EmitterError("expected DocumentStartEvent, but got %s" + % self.event) + + def expect_document_end(self): + if isinstance(self.event, DocumentEndEvent): + self.write_indent() + if self.event.explicit: + self.write_indicator('...', True) + self.write_indent() + self.flush_stream() + self.state = self.expect_document_start + else: + raise EmitterError("expected DocumentEndEvent, but got %s" + % self.event) + + def expect_document_root(self): + self.states.append(self.expect_document_end) + self.expect_node(root=True) + + # Node handlers. + + def expect_node(self, root=False, sequence=False, mapping=False, + simple_key=False): + self.root_context = root + self.sequence_context = sequence + self.mapping_context = mapping + self.simple_key_context = simple_key + if isinstance(self.event, AliasEvent): + self.expect_alias() + elif isinstance(self.event, (ScalarEvent, CollectionStartEvent)): + self.process_anchor('&') + self.process_tag() + if isinstance(self.event, ScalarEvent): + self.expect_scalar() + elif isinstance(self.event, SequenceStartEvent): + if self.flow_level or self.canonical or self.event.flow_style \ + or self.check_empty_sequence(): + self.expect_flow_sequence() + else: + self.expect_block_sequence() + elif isinstance(self.event, MappingStartEvent): + if self.flow_level or self.canonical or self.event.flow_style \ + or self.check_empty_mapping(): + self.expect_flow_mapping() + else: + self.expect_block_mapping() + else: + raise EmitterError("expected NodeEvent, but got %s" % self.event) + + def expect_alias(self): + if self.event.anchor is None: + raise EmitterError("anchor is not specified for alias") + self.process_anchor('*') + self.state = self.states.pop() + + def expect_scalar(self): + self.increase_indent(flow=True) + self.process_scalar() + self.indent = self.indents.pop() + self.state = self.states.pop() + + # Flow sequence handlers. + + def expect_flow_sequence(self): + self.write_indicator('[', True, whitespace=True) + self.flow_level += 1 + self.increase_indent(flow=True) + self.state = self.expect_first_flow_sequence_item + + def expect_first_flow_sequence_item(self): + if isinstance(self.event, SequenceEndEvent): + self.indent = self.indents.pop() + self.flow_level -= 1 + self.write_indicator(']', False) + self.state = self.states.pop() + else: + if self.canonical or self.column > self.best_width: + self.write_indent() + self.states.append(self.expect_flow_sequence_item) + self.expect_node(sequence=True) + + def expect_flow_sequence_item(self): + if isinstance(self.event, SequenceEndEvent): + self.indent = self.indents.pop() + self.flow_level -= 1 + if self.canonical: + self.write_indicator(',', False) + self.write_indent() + self.write_indicator(']', False) + self.state = self.states.pop() + else: + self.write_indicator(',', False) + if self.canonical or self.column > self.best_width: + self.write_indent() + self.states.append(self.expect_flow_sequence_item) + self.expect_node(sequence=True) + + # Flow mapping handlers. + + def expect_flow_mapping(self): + self.write_indicator('{', True, whitespace=True) + self.flow_level += 1 + self.increase_indent(flow=True) + self.state = self.expect_first_flow_mapping_key + + def expect_first_flow_mapping_key(self): + if isinstance(self.event, MappingEndEvent): + self.indent = self.indents.pop() + self.flow_level -= 1 + self.write_indicator('}', False) + self.state = self.states.pop() + else: + if self.canonical or self.column > self.best_width: + self.write_indent() + if not self.canonical and self.check_simple_key(): + self.states.append(self.expect_flow_mapping_simple_value) + self.expect_node(mapping=True, simple_key=True) + else: + self.write_indicator('?', True) + self.states.append(self.expect_flow_mapping_value) + self.expect_node(mapping=True) + + def expect_flow_mapping_key(self): + if isinstance(self.event, MappingEndEvent): + self.indent = self.indents.pop() + self.flow_level -= 1 + if self.canonical: + self.write_indicator(',', False) + self.write_indent() + self.write_indicator('}', False) + self.state = self.states.pop() + else: + self.write_indicator(',', False) + if self.canonical or self.column > self.best_width: + self.write_indent() + if not self.canonical and self.check_simple_key(): + self.states.append(self.expect_flow_mapping_simple_value) + self.expect_node(mapping=True, simple_key=True) + else: + self.write_indicator('?', True) + self.states.append(self.expect_flow_mapping_value) + self.expect_node(mapping=True) + + def expect_flow_mapping_simple_value(self): + self.write_indicator(':', False) + self.states.append(self.expect_flow_mapping_key) + self.expect_node(mapping=True) + + def expect_flow_mapping_value(self): + if self.canonical or self.column > self.best_width: + self.write_indent() + self.write_indicator(':', True) + self.states.append(self.expect_flow_mapping_key) + self.expect_node(mapping=True) + + # Block sequence handlers. + + def expect_block_sequence(self): + indentless = (self.mapping_context and not self.indention) + self.increase_indent(flow=False, indentless=indentless) + self.state = self.expect_first_block_sequence_item + + def expect_first_block_sequence_item(self): + return self.expect_block_sequence_item(first=True) + + def expect_block_sequence_item(self, first=False): + if not first and isinstance(self.event, SequenceEndEvent): + self.indent = self.indents.pop() + self.state = self.states.pop() + else: + self.write_indent() + self.write_indicator('-', True, indention=True) + self.states.append(self.expect_block_sequence_item) + self.expect_node(sequence=True) + + # Block mapping handlers. + + def expect_block_mapping(self): + self.increase_indent(flow=False) + self.state = self.expect_first_block_mapping_key + + def expect_first_block_mapping_key(self): + return self.expect_block_mapping_key(first=True) + + def expect_block_mapping_key(self, first=False): + if not first and isinstance(self.event, MappingEndEvent): + self.indent = self.indents.pop() + self.state = self.states.pop() + else: + self.write_indent() + if self.check_simple_key(): + self.states.append(self.expect_block_mapping_simple_value) + self.expect_node(mapping=True, simple_key=True) + else: + self.write_indicator('?', True, indention=True) + self.states.append(self.expect_block_mapping_value) + self.expect_node(mapping=True) + + def expect_block_mapping_simple_value(self): + self.write_indicator(':', False) + self.states.append(self.expect_block_mapping_key) + self.expect_node(mapping=True) + + def expect_block_mapping_value(self): + self.write_indent() + self.write_indicator(':', True, indention=True) + self.states.append(self.expect_block_mapping_key) + self.expect_node(mapping=True) + + # Checkers. + + def check_empty_sequence(self): + return (isinstance(self.event, SequenceStartEvent) and self.events + and isinstance(self.events[0], SequenceEndEvent)) + + def check_empty_mapping(self): + return (isinstance(self.event, MappingStartEvent) and self.events + and isinstance(self.events[0], MappingEndEvent)) + + def check_empty_document(self): + if not isinstance(self.event, DocumentStartEvent) or not self.events: + return False + event = self.events[0] + return (isinstance(event, ScalarEvent) and event.anchor is None + and event.tag is None and event.implicit and event.value == '') + + def check_simple_key(self): + length = 0 + if isinstance(self.event, NodeEvent) and self.event.anchor is not None: + if self.prepared_anchor is None: + self.prepared_anchor = self.prepare_anchor(self.event.anchor) + length += len(self.prepared_anchor) + if isinstance(self.event, (ScalarEvent, CollectionStartEvent)) \ + and self.event.tag is not None: + if self.prepared_tag is None: + self.prepared_tag = self.prepare_tag(self.event.tag) + length += len(self.prepared_tag) + if isinstance(self.event, ScalarEvent): + if self.analysis is None: + self.analysis = self.analyze_scalar(self.event.value) + length += len(self.analysis.scalar) + return (length < 128 and (isinstance(self.event, AliasEvent) + or (isinstance(self.event, ScalarEvent) + and not self.analysis.empty and not self.analysis.multiline) + or self.check_empty_sequence() or self.check_empty_mapping())) + + # Anchor, Tag, and Scalar processors. + + def process_anchor(self, indicator): + if self.event.anchor is None: + self.prepared_anchor = None + return + if self.prepared_anchor is None: + self.prepared_anchor = self.prepare_anchor(self.event.anchor) + if self.prepared_anchor: + self.write_indicator(indicator+self.prepared_anchor, True) + self.prepared_anchor = None + + def process_tag(self): + tag = self.event.tag + if isinstance(self.event, ScalarEvent): + if self.style is None: + self.style = self.choose_scalar_style() + if ((not self.canonical or tag is None) and + ((self.style == '' and self.event.implicit[0]) + or (self.style != '' and self.event.implicit[1]))): + self.prepared_tag = None + return + if self.event.implicit[0] and tag is None: + tag = '!' + self.prepared_tag = None + else: + if (not self.canonical or tag is None) and self.event.implicit: + self.prepared_tag = None + return + if tag is None: + raise EmitterError("tag is not specified") + if self.prepared_tag is None: + self.prepared_tag = self.prepare_tag(tag) + if self.prepared_tag: + self.write_indicator(self.prepared_tag, True) + self.prepared_tag = None + + def choose_scalar_style(self): + if self.analysis is None: + self.analysis = self.analyze_scalar(self.event.value) + if self.event.style == '"' or self.canonical: + return '"' + if not self.event.style and self.event.implicit[0]: + if (not (self.simple_key_context and + (self.analysis.empty or self.analysis.multiline)) + and (self.flow_level and self.analysis.allow_flow_plain + or (not self.flow_level and self.analysis.allow_block_plain))): + return '' + if self.event.style and self.event.style in '|>': + if (not self.flow_level and not self.simple_key_context + and self.analysis.allow_block): + return self.event.style + if not self.event.style or self.event.style == '\'': + if (self.analysis.allow_single_quoted and + not (self.simple_key_context and self.analysis.multiline)): + return '\'' + return '"' + + def process_scalar(self): + if self.analysis is None: + self.analysis = self.analyze_scalar(self.event.value) + if self.style is None: + self.style = self.choose_scalar_style() + split = (not self.simple_key_context) + #if self.analysis.multiline and split \ + # and (not self.style or self.style in '\'\"'): + # self.write_indent() + if self.style == '"': + self.write_double_quoted(self.analysis.scalar, split) + elif self.style == '\'': + self.write_single_quoted(self.analysis.scalar, split) + elif self.style == '>': + self.write_folded(self.analysis.scalar) + elif self.style == '|': + self.write_literal(self.analysis.scalar) + else: + self.write_plain(self.analysis.scalar, split) + self.analysis = None + self.style = None + + # Analyzers. + + def prepare_version(self, version): + major, minor = version + if major != 1: + raise EmitterError("unsupported YAML version: %d.%d" % (major, minor)) + return '%d.%d' % (major, minor) + + def prepare_tag_handle(self, handle): + if not handle: + raise EmitterError("tag handle must not be empty") + if handle[0] != '!' or handle[-1] != '!': + raise EmitterError("tag handle must start and end with '!': %r" % handle) + for ch in handle[1:-1]: + if not ('0' <= ch <= '9' or 'A' <= ch <= 'Z' or 'a' <= ch <= 'z' \ + or ch in '-_'): + raise EmitterError("invalid character %r in the tag handle: %r" + % (ch, handle)) + return handle + + def prepare_tag_prefix(self, prefix): + if not prefix: + raise EmitterError("tag prefix must not be empty") + chunks = [] + start = end = 0 + if prefix[0] == '!': + end = 1 + while end < len(prefix): + ch = prefix[end] + if '0' <= ch <= '9' or 'A' <= ch <= 'Z' or 'a' <= ch <= 'z' \ + or ch in '-;/?!:@&=+$,_.~*\'()[]': + end += 1 + else: + if start < end: + chunks.append(prefix[start:end]) + start = end = end+1 + data = ch.encode('utf-8') + for ch in data: + chunks.append('%%%02X' % ord(ch)) + if start < end: + chunks.append(prefix[start:end]) + return ''.join(chunks) + + def prepare_tag(self, tag): + if not tag: + raise EmitterError("tag must not be empty") + if tag == '!': + return tag + handle = None + suffix = tag + prefixes = sorted(self.tag_prefixes.keys()) + for prefix in prefixes: + if tag.startswith(prefix) \ + and (prefix == '!' or len(prefix) < len(tag)): + handle = self.tag_prefixes[prefix] + suffix = tag[len(prefix):] + chunks = [] + start = end = 0 + while end < len(suffix): + ch = suffix[end] + if '0' <= ch <= '9' or 'A' <= ch <= 'Z' or 'a' <= ch <= 'z' \ + or ch in '-;/?:@&=+$,_.~*\'()[]' \ + or (ch == '!' and handle != '!'): + end += 1 + else: + if start < end: + chunks.append(suffix[start:end]) + start = end = end+1 + data = ch.encode('utf-8') + for ch in data: + chunks.append('%%%02X' % ord(ch)) + if start < end: + chunks.append(suffix[start:end]) + suffix_text = ''.join(chunks) + if handle: + return '%s%s' % (handle, suffix_text) + else: + return '!<%s>' % suffix_text + + def prepare_anchor(self, anchor): + if not anchor: + raise EmitterError("anchor must not be empty") + for ch in anchor: + if not ('0' <= ch <= '9' or 'A' <= ch <= 'Z' or 'a' <= ch <= 'z' \ + or ch in '-_'): + raise EmitterError("invalid character %r in the anchor: %r" + % (ch, anchor)) + return anchor + + def analyze_scalar(self, scalar): + + # Empty scalar is a special case. + if not scalar: + return ScalarAnalysis(scalar=scalar, empty=True, multiline=False, + allow_flow_plain=False, allow_block_plain=True, + allow_single_quoted=True, allow_double_quoted=True, + allow_block=False) + + # Indicators and special characters. + block_indicators = False + flow_indicators = False + line_breaks = False + special_characters = False + + # Important whitespace combinations. + leading_space = False + leading_break = False + trailing_space = False + trailing_break = False + break_space = False + space_break = False + + # Check document indicators. + if scalar.startswith('---') or scalar.startswith('...'): + block_indicators = True + flow_indicators = True + + # First character or preceded by a whitespace. + preceeded_by_whitespace = True + + # Last character or followed by a whitespace. + followed_by_whitespace = (len(scalar) == 1 or + scalar[1] in '\0 \t\r\n\x85\u2028\u2029') + + # The previous character is a space. + previous_space = False + + # The previous character is a break. + previous_break = False + + index = 0 + while index < len(scalar): + ch = scalar[index] + + # Check for indicators. + if index == 0: + # Leading indicators are special characters. + if ch in '#,[]{}&*!|>\'\"%@`': + flow_indicators = True + block_indicators = True + if ch in '?:': + flow_indicators = True + if followed_by_whitespace: + block_indicators = True + if ch == '-' and followed_by_whitespace: + flow_indicators = True + block_indicators = True + else: + # Some indicators cannot appear within a scalar as well. + if ch in ',?[]{}': + flow_indicators = True + if ch == ':': + flow_indicators = True + if followed_by_whitespace: + block_indicators = True + if ch == '#' and preceeded_by_whitespace: + flow_indicators = True + block_indicators = True + + # Check for line breaks, special, and unicode characters. + if ch in '\n\x85\u2028\u2029': + line_breaks = True + if not (ch == '\n' or '\x20' <= ch <= '\x7E'): + if (ch == '\x85' or '\xA0' <= ch <= '\uD7FF' + or '\uE000' <= ch <= '\uFFFD') and ch != '\uFEFF': + unicode_characters = True + if not self.allow_unicode: + special_characters = True + else: + special_characters = True + + # Detect important whitespace combinations. + if ch == ' ': + if index == 0: + leading_space = True + if index == len(scalar)-1: + trailing_space = True + if previous_break: + break_space = True + previous_space = True + previous_break = False + elif ch in '\n\x85\u2028\u2029': + if index == 0: + leading_break = True + if index == len(scalar)-1: + trailing_break = True + if previous_space: + space_break = True + previous_space = False + previous_break = True + else: + previous_space = False + previous_break = False + + # Prepare for the next character. + index += 1 + preceeded_by_whitespace = (ch in '\0 \t\r\n\x85\u2028\u2029') + followed_by_whitespace = (index+1 >= len(scalar) or + scalar[index+1] in '\0 \t\r\n\x85\u2028\u2029') + + # Let's decide what styles are allowed. + allow_flow_plain = True + allow_block_plain = True + allow_single_quoted = True + allow_double_quoted = True + allow_block = True + + # Leading and trailing whitespaces are bad for plain scalars. + if (leading_space or leading_break + or trailing_space or trailing_break): + allow_flow_plain = allow_block_plain = False + + # We do not permit trailing spaces for block scalars. + if trailing_space: + allow_block = False + + # Spaces at the beginning of a new line are only acceptable for block + # scalars. + if break_space: + allow_flow_plain = allow_block_plain = allow_single_quoted = False + + # Spaces followed by breaks, as well as special character are only + # allowed for double quoted scalars. + if space_break or special_characters: + allow_flow_plain = allow_block_plain = \ + allow_single_quoted = allow_block = False + + # Although the plain scalar writer supports breaks, we never emit + # multiline plain scalars. + if line_breaks: + allow_flow_plain = allow_block_plain = False + + # Flow indicators are forbidden for flow plain scalars. + if flow_indicators: + allow_flow_plain = False + + # Block indicators are forbidden for block plain scalars. + if block_indicators: + allow_block_plain = False + + return ScalarAnalysis(scalar=scalar, + empty=False, multiline=line_breaks, + allow_flow_plain=allow_flow_plain, + allow_block_plain=allow_block_plain, + allow_single_quoted=allow_single_quoted, + allow_double_quoted=allow_double_quoted, + allow_block=allow_block) + + # Writers. + + def flush_stream(self): + if hasattr(self.stream, 'flush'): + self.stream.flush() + + def write_stream_start(self): + # Write BOM if needed. + if self.encoding and self.encoding.startswith('utf-16'): + self.stream.write('\uFEFF'.encode(self.encoding)) + + def write_stream_end(self): + self.flush_stream() + + def write_indicator(self, indicator, need_whitespace, + whitespace=False, indention=False): + if self.whitespace or not need_whitespace: + data = indicator + else: + data = ' '+indicator + self.whitespace = whitespace + self.indention = self.indention and indention + self.column += len(data) + self.open_ended = False + if self.encoding: + data = data.encode(self.encoding) + self.stream.write(data) + + def write_indent(self): + indent = self.indent or 0 + if not self.indention or self.column > indent \ + or (self.column == indent and not self.whitespace): + self.write_line_break() + if self.column < indent: + self.whitespace = True + data = ' '*(indent-self.column) + self.column = indent + if self.encoding: + data = data.encode(self.encoding) + self.stream.write(data) + + def write_line_break(self, data=None): + if data is None: + data = self.best_line_break + self.whitespace = True + self.indention = True + self.line += 1 + self.column = 0 + if self.encoding: + data = data.encode(self.encoding) + self.stream.write(data) + + def write_version_directive(self, version_text): + data = '%%YAML %s' % version_text + if self.encoding: + data = data.encode(self.encoding) + self.stream.write(data) + self.write_line_break() + + def write_tag_directive(self, handle_text, prefix_text): + data = '%%TAG %s %s' % (handle_text, prefix_text) + if self.encoding: + data = data.encode(self.encoding) + self.stream.write(data) + self.write_line_break() + + # Scalar streams. + + def write_single_quoted(self, text, split=True): + self.write_indicator('\'', True) + spaces = False + breaks = False + start = end = 0 + while end <= len(text): + ch = None + if end < len(text): + ch = text[end] + if spaces: + if ch is None or ch != ' ': + if start+1 == end and self.column > self.best_width and split \ + and start != 0 and end != len(text): + self.write_indent() + else: + data = text[start:end] + self.column += len(data) + if self.encoding: + data = data.encode(self.encoding) + self.stream.write(data) + start = end + elif breaks: + if ch is None or ch not in '\n\x85\u2028\u2029': + if text[start] == '\n': + self.write_line_break() + for br in text[start:end]: + if br == '\n': + self.write_line_break() + else: + self.write_line_break(br) + self.write_indent() + start = end + else: + if ch is None or ch in ' \n\x85\u2028\u2029' or ch == '\'': + if start < end: + data = text[start:end] + self.column += len(data) + if self.encoding: + data = data.encode(self.encoding) + self.stream.write(data) + start = end + if ch == '\'': + data = '\'\'' + self.column += 2 + if self.encoding: + data = data.encode(self.encoding) + self.stream.write(data) + start = end + 1 + if ch is not None: + spaces = (ch == ' ') + breaks = (ch in '\n\x85\u2028\u2029') + end += 1 + self.write_indicator('\'', False) + + ESCAPE_REPLACEMENTS = { + '\0': '0', + '\x07': 'a', + '\x08': 'b', + '\x09': 't', + '\x0A': 'n', + '\x0B': 'v', + '\x0C': 'f', + '\x0D': 'r', + '\x1B': 'e', + '\"': '\"', + '\\': '\\', + '\x85': 'N', + '\xA0': '_', + '\u2028': 'L', + '\u2029': 'P', + } + + def write_double_quoted(self, text, split=True): + self.write_indicator('"', True) + start = end = 0 + while end <= len(text): + ch = None + if end < len(text): + ch = text[end] + if ch is None or ch in '"\\\x85\u2028\u2029\uFEFF' \ + or not ('\x20' <= ch <= '\x7E' + or (self.allow_unicode + and ('\xA0' <= ch <= '\uD7FF' + or '\uE000' <= ch <= '\uFFFD'))): + if start < end: + data = text[start:end] + self.column += len(data) + if self.encoding: + data = data.encode(self.encoding) + self.stream.write(data) + start = end + if ch is not None: + if ch in self.ESCAPE_REPLACEMENTS: + data = '\\'+self.ESCAPE_REPLACEMENTS[ch] + elif ch <= '\xFF': + data = '\\x%02X' % ord(ch) + elif ch <= '\uFFFF': + data = '\\u%04X' % ord(ch) + else: + data = '\\U%08X' % ord(ch) + self.column += len(data) + if self.encoding: + data = data.encode(self.encoding) + self.stream.write(data) + start = end+1 + if 0 < end < len(text)-1 and (ch == ' ' or start >= end) \ + and self.column+(end-start) > self.best_width and split: + data = text[start:end]+'\\' + if start < end: + start = end + self.column += len(data) + if self.encoding: + data = data.encode(self.encoding) + self.stream.write(data) + self.write_indent() + self.whitespace = False + self.indention = False + if text[start] == ' ': + data = '\\' + self.column += len(data) + if self.encoding: + data = data.encode(self.encoding) + self.stream.write(data) + end += 1 + self.write_indicator('"', False) + + def determine_block_hints(self, text): + hints = '' + if text: + if text[0] in ' \n\x85\u2028\u2029': + hints += str(self.best_indent) + if text[-1] not in '\n\x85\u2028\u2029': + hints += '-' + elif len(text) == 1 or text[-2] in '\n\x85\u2028\u2029': + hints += '+' + return hints + + def write_folded(self, text): + hints = self.determine_block_hints(text) + self.write_indicator('>'+hints, True) + if hints[-1:] == '+': + self.open_ended = True + self.write_line_break() + leading_space = True + spaces = False + breaks = True + start = end = 0 + while end <= len(text): + ch = None + if end < len(text): + ch = text[end] + if breaks: + if ch is None or ch not in '\n\x85\u2028\u2029': + if not leading_space and ch is not None and ch != ' ' \ + and text[start] == '\n': + self.write_line_break() + leading_space = (ch == ' ') + for br in text[start:end]: + if br == '\n': + self.write_line_break() + else: + self.write_line_break(br) + if ch is not None: + self.write_indent() + start = end + elif spaces: + if ch != ' ': + if start+1 == end and self.column > self.best_width: + self.write_indent() + else: + data = text[start:end] + self.column += len(data) + if self.encoding: + data = data.encode(self.encoding) + self.stream.write(data) + start = end + else: + if ch is None or ch in ' \n\x85\u2028\u2029': + data = text[start:end] + self.column += len(data) + if self.encoding: + data = data.encode(self.encoding) + self.stream.write(data) + if ch is None: + self.write_line_break() + start = end + if ch is not None: + breaks = (ch in '\n\x85\u2028\u2029') + spaces = (ch == ' ') + end += 1 + + def write_literal(self, text): + hints = self.determine_block_hints(text) + self.write_indicator('|'+hints, True) + if hints[-1:] == '+': + self.open_ended = True + self.write_line_break() + breaks = True + start = end = 0 + while end <= len(text): + ch = None + if end < len(text): + ch = text[end] + if breaks: + if ch is None or ch not in '\n\x85\u2028\u2029': + for br in text[start:end]: + if br == '\n': + self.write_line_break() + else: + self.write_line_break(br) + if ch is not None: + self.write_indent() + start = end + else: + if ch is None or ch in '\n\x85\u2028\u2029': + data = text[start:end] + if self.encoding: + data = data.encode(self.encoding) + self.stream.write(data) + if ch is None: + self.write_line_break() + start = end + if ch is not None: + breaks = (ch in '\n\x85\u2028\u2029') + end += 1 + + def write_plain(self, text, split=True): + if self.root_context: + self.open_ended = True + if not text: + return + if not self.whitespace: + data = ' ' + self.column += len(data) + if self.encoding: + data = data.encode(self.encoding) + self.stream.write(data) + self.whitespace = False + self.indention = False + spaces = False + breaks = False + start = end = 0 + while end <= len(text): + ch = None + if end < len(text): + ch = text[end] + if spaces: + if ch != ' ': + if start+1 == end and self.column > self.best_width and split: + self.write_indent() + self.whitespace = False + self.indention = False + else: + data = text[start:end] + self.column += len(data) + if self.encoding: + data = data.encode(self.encoding) + self.stream.write(data) + start = end + elif breaks: + if ch not in '\n\x85\u2028\u2029': + if text[start] == '\n': + self.write_line_break() + for br in text[start:end]: + if br == '\n': + self.write_line_break() + else: + self.write_line_break(br) + self.write_indent() + self.whitespace = False + self.indention = False + start = end + else: + if ch is None or ch in ' \n\x85\u2028\u2029': + data = text[start:end] + self.column += len(data) + if self.encoding: + data = data.encode(self.encoding) + self.stream.write(data) + start = end + if ch is not None: + spaces = (ch == ' ') + breaks = (ch in '\n\x85\u2028\u2029') + end += 1 + diff --git a/rplibs/yaml/yaml_py3/error.py b/rplibs/yaml/yaml_py3/error.py new file mode 100644 index 0000000..b796b4d --- /dev/null +++ b/rplibs/yaml/yaml_py3/error.py @@ -0,0 +1,75 @@ + +__all__ = ['Mark', 'YAMLError', 'MarkedYAMLError'] + +class Mark: + + def __init__(self, name, index, line, column, buffer, pointer): + self.name = name + self.index = index + self.line = line + self.column = column + self.buffer = buffer + self.pointer = pointer + + def get_snippet(self, indent=4, max_length=75): + if self.buffer is None: + return None + head = '' + start = self.pointer + while start > 0 and self.buffer[start-1] not in '\0\r\n\x85\u2028\u2029': + start -= 1 + if self.pointer-start > max_length/2-1: + head = ' ... ' + start += 5 + break + tail = '' + end = self.pointer + while end < len(self.buffer) and self.buffer[end] not in '\0\r\n\x85\u2028\u2029': + end += 1 + if end-self.pointer > max_length/2-1: + tail = ' ... ' + end -= 5 + break + snippet = self.buffer[start:end] + return ' '*indent + head + snippet + tail + '\n' \ + + ' '*(indent+self.pointer-start+len(head)) + '^' + + def __str__(self): + snippet = self.get_snippet() + where = " in \"%s\", line %d, column %d" \ + % (self.name, self.line+1, self.column+1) + if snippet is not None: + where += ":\n"+snippet + return where + +class YAMLError(Exception): + pass + +class MarkedYAMLError(YAMLError): + + def __init__(self, context=None, context_mark=None, + problem=None, problem_mark=None, note=None): + self.context = context + self.context_mark = context_mark + self.problem = problem + self.problem_mark = problem_mark + self.note = note + + def __str__(self): + lines = [] + if self.context is not None: + lines.append(self.context) + if self.context_mark is not None \ + and (self.problem is None or self.problem_mark is None + or self.context_mark.name != self.problem_mark.name + or self.context_mark.line != self.problem_mark.line + or self.context_mark.column != self.problem_mark.column): + lines.append(str(self.context_mark)) + if self.problem is not None: + lines.append(self.problem) + if self.problem_mark is not None: + lines.append(str(self.problem_mark)) + if self.note is not None: + lines.append(self.note) + return '\n'.join(lines) + diff --git a/rplibs/yaml/yaml_py3/events.py b/rplibs/yaml/yaml_py3/events.py new file mode 100644 index 0000000..f79ad38 --- /dev/null +++ b/rplibs/yaml/yaml_py3/events.py @@ -0,0 +1,86 @@ + +# Abstract classes. + +class Event(object): + def __init__(self, start_mark=None, end_mark=None): + self.start_mark = start_mark + self.end_mark = end_mark + def __repr__(self): + attributes = [key for key in ['anchor', 'tag', 'implicit', 'value'] + if hasattr(self, key)] + arguments = ', '.join(['%s=%r' % (key, getattr(self, key)) + for key in attributes]) + return '%s(%s)' % (self.__class__.__name__, arguments) + +class NodeEvent(Event): + def __init__(self, anchor, start_mark=None, end_mark=None): + self.anchor = anchor + self.start_mark = start_mark + self.end_mark = end_mark + +class CollectionStartEvent(NodeEvent): + def __init__(self, anchor, tag, implicit, start_mark=None, end_mark=None, + flow_style=None): + self.anchor = anchor + self.tag = tag + self.implicit = implicit + self.start_mark = start_mark + self.end_mark = end_mark + self.flow_style = flow_style + +class CollectionEndEvent(Event): + pass + +# Implementations. + +class StreamStartEvent(Event): + def __init__(self, start_mark=None, end_mark=None, encoding=None): + self.start_mark = start_mark + self.end_mark = end_mark + self.encoding = encoding + +class StreamEndEvent(Event): + pass + +class DocumentStartEvent(Event): + def __init__(self, start_mark=None, end_mark=None, + explicit=None, version=None, tags=None): + self.start_mark = start_mark + self.end_mark = end_mark + self.explicit = explicit + self.version = version + self.tags = tags + +class DocumentEndEvent(Event): + def __init__(self, start_mark=None, end_mark=None, + explicit=None): + self.start_mark = start_mark + self.end_mark = end_mark + self.explicit = explicit + +class AliasEvent(NodeEvent): + pass + +class ScalarEvent(NodeEvent): + def __init__(self, anchor, tag, implicit, value, + start_mark=None, end_mark=None, style=None): + self.anchor = anchor + self.tag = tag + self.implicit = implicit + self.value = value + self.start_mark = start_mark + self.end_mark = end_mark + self.style = style + +class SequenceStartEvent(CollectionStartEvent): + pass + +class SequenceEndEvent(CollectionEndEvent): + pass + +class MappingStartEvent(CollectionStartEvent): + pass + +class MappingEndEvent(CollectionEndEvent): + pass + diff --git a/rplibs/yaml/yaml_py3/loader.py b/rplibs/yaml/yaml_py3/loader.py new file mode 100644 index 0000000..08c8f01 --- /dev/null +++ b/rplibs/yaml/yaml_py3/loader.py @@ -0,0 +1,40 @@ + +__all__ = ['BaseLoader', 'SafeLoader', 'Loader'] + +from .reader import * +from .scanner import * +from .parser import * +from .composer import * +from .constructor import * +from .resolver import * + +class BaseLoader(Reader, Scanner, Parser, Composer, BaseConstructor, BaseResolver): + + def __init__(self, stream): + Reader.__init__(self, stream) + Scanner.__init__(self) + Parser.__init__(self) + Composer.__init__(self) + BaseConstructor.__init__(self) + BaseResolver.__init__(self) + +class SafeLoader(Reader, Scanner, Parser, Composer, SafeConstructor, Resolver): + + def __init__(self, stream): + Reader.__init__(self, stream) + Scanner.__init__(self) + Parser.__init__(self) + Composer.__init__(self) + SafeConstructor.__init__(self) + Resolver.__init__(self) + +class Loader(Reader, Scanner, Parser, Composer, Constructor, Resolver): + + def __init__(self, stream): + Reader.__init__(self, stream) + Scanner.__init__(self) + Parser.__init__(self) + Composer.__init__(self) + Constructor.__init__(self) + Resolver.__init__(self) + diff --git a/rplibs/yaml/yaml_py3/nodes.py b/rplibs/yaml/yaml_py3/nodes.py new file mode 100644 index 0000000..c4f070c --- /dev/null +++ b/rplibs/yaml/yaml_py3/nodes.py @@ -0,0 +1,49 @@ + +class Node(object): + def __init__(self, tag, value, start_mark, end_mark): + self.tag = tag + self.value = value + self.start_mark = start_mark + self.end_mark = end_mark + def __repr__(self): + value = self.value + #if isinstance(value, list): + # if len(value) == 0: + # value = '' + # elif len(value) == 1: + # value = '<1 item>' + # else: + # value = '<%d items>' % len(value) + #else: + # if len(value) > 75: + # value = repr(value[:70]+u' ... ') + # else: + # value = repr(value) + value = repr(value) + return '%s(tag=%r, value=%s)' % (self.__class__.__name__, self.tag, value) + +class ScalarNode(Node): + id = 'scalar' + def __init__(self, tag, value, + start_mark=None, end_mark=None, style=None): + self.tag = tag + self.value = value + self.start_mark = start_mark + self.end_mark = end_mark + self.style = style + +class CollectionNode(Node): + def __init__(self, tag, value, + start_mark=None, end_mark=None, flow_style=None): + self.tag = tag + self.value = value + self.start_mark = start_mark + self.end_mark = end_mark + self.flow_style = flow_style + +class SequenceNode(CollectionNode): + id = 'sequence' + +class MappingNode(CollectionNode): + id = 'mapping' + diff --git a/rplibs/yaml/yaml_py3/parser.py b/rplibs/yaml/yaml_py3/parser.py new file mode 100644 index 0000000..13a5995 --- /dev/null +++ b/rplibs/yaml/yaml_py3/parser.py @@ -0,0 +1,589 @@ + +# The following YAML grammar is LL(1) and is parsed by a recursive descent +# parser. +# +# stream ::= STREAM-START implicit_document? explicit_document* STREAM-END +# implicit_document ::= block_node DOCUMENT-END* +# explicit_document ::= DIRECTIVE* DOCUMENT-START block_node? DOCUMENT-END* +# block_node_or_indentless_sequence ::= +# ALIAS +# | properties (block_content | indentless_block_sequence)? +# | block_content +# | indentless_block_sequence +# block_node ::= ALIAS +# | properties block_content? +# | block_content +# flow_node ::= ALIAS +# | properties flow_content? +# | flow_content +# properties ::= TAG ANCHOR? | ANCHOR TAG? +# block_content ::= block_collection | flow_collection | SCALAR +# flow_content ::= flow_collection | SCALAR +# block_collection ::= block_sequence | block_mapping +# flow_collection ::= flow_sequence | flow_mapping +# block_sequence ::= BLOCK-SEQUENCE-START (BLOCK-ENTRY block_node?)* BLOCK-END +# indentless_sequence ::= (BLOCK-ENTRY block_node?)+ +# block_mapping ::= BLOCK-MAPPING_START +# ((KEY block_node_or_indentless_sequence?)? +# (VALUE block_node_or_indentless_sequence?)?)* +# BLOCK-END +# flow_sequence ::= FLOW-SEQUENCE-START +# (flow_sequence_entry FLOW-ENTRY)* +# flow_sequence_entry? +# FLOW-SEQUENCE-END +# flow_sequence_entry ::= flow_node | KEY flow_node? (VALUE flow_node?)? +# flow_mapping ::= FLOW-MAPPING-START +# (flow_mapping_entry FLOW-ENTRY)* +# flow_mapping_entry? +# FLOW-MAPPING-END +# flow_mapping_entry ::= flow_node | KEY flow_node? (VALUE flow_node?)? +# +# FIRST sets: +# +# stream: { STREAM-START } +# explicit_document: { DIRECTIVE DOCUMENT-START } +# implicit_document: FIRST(block_node) +# block_node: { ALIAS TAG ANCHOR SCALAR BLOCK-SEQUENCE-START BLOCK-MAPPING-START FLOW-SEQUENCE-START FLOW-MAPPING-START } +# flow_node: { ALIAS ANCHOR TAG SCALAR FLOW-SEQUENCE-START FLOW-MAPPING-START } +# block_content: { BLOCK-SEQUENCE-START BLOCK-MAPPING-START FLOW-SEQUENCE-START FLOW-MAPPING-START SCALAR } +# flow_content: { FLOW-SEQUENCE-START FLOW-MAPPING-START SCALAR } +# block_collection: { BLOCK-SEQUENCE-START BLOCK-MAPPING-START } +# flow_collection: { FLOW-SEQUENCE-START FLOW-MAPPING-START } +# block_sequence: { BLOCK-SEQUENCE-START } +# block_mapping: { BLOCK-MAPPING-START } +# block_node_or_indentless_sequence: { ALIAS ANCHOR TAG SCALAR BLOCK-SEQUENCE-START BLOCK-MAPPING-START FLOW-SEQUENCE-START FLOW-MAPPING-START BLOCK-ENTRY } +# indentless_sequence: { ENTRY } +# flow_collection: { FLOW-SEQUENCE-START FLOW-MAPPING-START } +# flow_sequence: { FLOW-SEQUENCE-START } +# flow_mapping: { FLOW-MAPPING-START } +# flow_sequence_entry: { ALIAS ANCHOR TAG SCALAR FLOW-SEQUENCE-START FLOW-MAPPING-START KEY } +# flow_mapping_entry: { ALIAS ANCHOR TAG SCALAR FLOW-SEQUENCE-START FLOW-MAPPING-START KEY } + +__all__ = ['Parser', 'ParserError'] + +from .error import MarkedYAMLError +from .tokens import * +from .events import * +from .scanner import * + +class ParserError(MarkedYAMLError): + pass + +class Parser: + # Since writing a recursive-descendant parser is a straightforward task, we + # do not give many comments here. + + DEFAULT_TAGS = { + '!': '!', + '!!': 'tag:yaml.org,2002:', + } + + def __init__(self): + self.current_event = None + self.yaml_version = None + self.tag_handles = {} + self.states = [] + self.marks = [] + self.state = self.parse_stream_start + + def dispose(self): + # Reset the state attributes (to clear self-references) + self.states = [] + self.state = None + + def check_event(self, *choices): + # Check the type of the next event. + if self.current_event is None: + if self.state: + self.current_event = self.state() + if self.current_event is not None: + if not choices: + return True + for choice in choices: + if isinstance(self.current_event, choice): + return True + return False + + def peek_event(self): + # Get the next event. + if self.current_event is None: + if self.state: + self.current_event = self.state() + return self.current_event + + def get_event(self): + # Get the next event and proceed further. + if self.current_event is None: + if self.state: + self.current_event = self.state() + value = self.current_event + self.current_event = None + return value + + # stream ::= STREAM-START implicit_document? explicit_document* STREAM-END + # implicit_document ::= block_node DOCUMENT-END* + # explicit_document ::= DIRECTIVE* DOCUMENT-START block_node? DOCUMENT-END* + + def parse_stream_start(self): + + # Parse the stream start. + token = self.get_token() + event = StreamStartEvent(token.start_mark, token.end_mark, + encoding=token.encoding) + + # Prepare the next state. + self.state = self.parse_implicit_document_start + + return event + + def parse_implicit_document_start(self): + + # Parse an implicit document. + if not self.check_token(DirectiveToken, DocumentStartToken, + StreamEndToken): + self.tag_handles = self.DEFAULT_TAGS + token = self.peek_token() + start_mark = end_mark = token.start_mark + event = DocumentStartEvent(start_mark, end_mark, + explicit=False) + + # Prepare the next state. + self.states.append(self.parse_document_end) + self.state = self.parse_block_node + + return event + + else: + return self.parse_document_start() + + def parse_document_start(self): + + # Parse any extra document end indicators. + while self.check_token(DocumentEndToken): + self.get_token() + + # Parse an explicit document. + if not self.check_token(StreamEndToken): + token = self.peek_token() + start_mark = token.start_mark + version, tags = self.process_directives() + if not self.check_token(DocumentStartToken): + raise ParserError(None, None, + "expected '', but found %r" + % self.peek_token().id, + self.peek_token().start_mark) + token = self.get_token() + end_mark = token.end_mark + event = DocumentStartEvent(start_mark, end_mark, + explicit=True, version=version, tags=tags) + self.states.append(self.parse_document_end) + self.state = self.parse_document_content + else: + # Parse the end of the stream. + token = self.get_token() + event = StreamEndEvent(token.start_mark, token.end_mark) + assert not self.states + assert not self.marks + self.state = None + return event + + def parse_document_end(self): + + # Parse the document end. + token = self.peek_token() + start_mark = end_mark = token.start_mark + explicit = False + if self.check_token(DocumentEndToken): + token = self.get_token() + end_mark = token.end_mark + explicit = True + event = DocumentEndEvent(start_mark, end_mark, + explicit=explicit) + + # Prepare the next state. + self.state = self.parse_document_start + + return event + + def parse_document_content(self): + if self.check_token(DirectiveToken, + DocumentStartToken, DocumentEndToken, StreamEndToken): + event = self.process_empty_scalar(self.peek_token().start_mark) + self.state = self.states.pop() + return event + else: + return self.parse_block_node() + + def process_directives(self): + self.yaml_version = None + self.tag_handles = {} + while self.check_token(DirectiveToken): + token = self.get_token() + if token.name == 'YAML': + if self.yaml_version is not None: + raise ParserError(None, None, + "found duplicate YAML directive", token.start_mark) + major, minor = token.value + if major != 1: + raise ParserError(None, None, + "found incompatible YAML document (version 1.* is required)", + token.start_mark) + self.yaml_version = token.value + elif token.name == 'TAG': + handle, prefix = token.value + if handle in self.tag_handles: + raise ParserError(None, None, + "duplicate tag handle %r" % handle, + token.start_mark) + self.tag_handles[handle] = prefix + if self.tag_handles: + value = self.yaml_version, self.tag_handles.copy() + else: + value = self.yaml_version, None + for key in self.DEFAULT_TAGS: + if key not in self.tag_handles: + self.tag_handles[key] = self.DEFAULT_TAGS[key] + return value + + # block_node_or_indentless_sequence ::= ALIAS + # | properties (block_content | indentless_block_sequence)? + # | block_content + # | indentless_block_sequence + # block_node ::= ALIAS + # | properties block_content? + # | block_content + # flow_node ::= ALIAS + # | properties flow_content? + # | flow_content + # properties ::= TAG ANCHOR? | ANCHOR TAG? + # block_content ::= block_collection | flow_collection | SCALAR + # flow_content ::= flow_collection | SCALAR + # block_collection ::= block_sequence | block_mapping + # flow_collection ::= flow_sequence | flow_mapping + + def parse_block_node(self): + return self.parse_node(block=True) + + def parse_flow_node(self): + return self.parse_node() + + def parse_block_node_or_indentless_sequence(self): + return self.parse_node(block=True, indentless_sequence=True) + + def parse_node(self, block=False, indentless_sequence=False): + if self.check_token(AliasToken): + token = self.get_token() + event = AliasEvent(token.value, token.start_mark, token.end_mark) + self.state = self.states.pop() + else: + anchor = None + tag = None + start_mark = end_mark = tag_mark = None + if self.check_token(AnchorToken): + token = self.get_token() + start_mark = token.start_mark + end_mark = token.end_mark + anchor = token.value + if self.check_token(TagToken): + token = self.get_token() + tag_mark = token.start_mark + end_mark = token.end_mark + tag = token.value + elif self.check_token(TagToken): + token = self.get_token() + start_mark = tag_mark = token.start_mark + end_mark = token.end_mark + tag = token.value + if self.check_token(AnchorToken): + token = self.get_token() + end_mark = token.end_mark + anchor = token.value + if tag is not None: + handle, suffix = tag + if handle is not None: + if handle not in self.tag_handles: + raise ParserError("while parsing a node", start_mark, + "found undefined tag handle %r" % handle, + tag_mark) + tag = self.tag_handles[handle]+suffix + else: + tag = suffix + #if tag == '!': + # raise ParserError("while parsing a node", start_mark, + # "found non-specific tag '!'", tag_mark, + # "Please check 'http://pyyaml.org/wiki/YAMLNonSpecificTag' and share your opinion.") + if start_mark is None: + start_mark = end_mark = self.peek_token().start_mark + event = None + implicit = (tag is None or tag == '!') + if indentless_sequence and self.check_token(BlockEntryToken): + end_mark = self.peek_token().end_mark + event = SequenceStartEvent(anchor, tag, implicit, + start_mark, end_mark) + self.state = self.parse_indentless_sequence_entry + else: + if self.check_token(ScalarToken): + token = self.get_token() + end_mark = token.end_mark + if (token.plain and tag is None) or tag == '!': + implicit = (True, False) + elif tag is None: + implicit = (False, True) + else: + implicit = (False, False) + event = ScalarEvent(anchor, tag, implicit, token.value, + start_mark, end_mark, style=token.style) + self.state = self.states.pop() + elif self.check_token(FlowSequenceStartToken): + end_mark = self.peek_token().end_mark + event = SequenceStartEvent(anchor, tag, implicit, + start_mark, end_mark, flow_style=True) + self.state = self.parse_flow_sequence_first_entry + elif self.check_token(FlowMappingStartToken): + end_mark = self.peek_token().end_mark + event = MappingStartEvent(anchor, tag, implicit, + start_mark, end_mark, flow_style=True) + self.state = self.parse_flow_mapping_first_key + elif block and self.check_token(BlockSequenceStartToken): + end_mark = self.peek_token().start_mark + event = SequenceStartEvent(anchor, tag, implicit, + start_mark, end_mark, flow_style=False) + self.state = self.parse_block_sequence_first_entry + elif block and self.check_token(BlockMappingStartToken): + end_mark = self.peek_token().start_mark + event = MappingStartEvent(anchor, tag, implicit, + start_mark, end_mark, flow_style=False) + self.state = self.parse_block_mapping_first_key + elif anchor is not None or tag is not None: + # Empty scalars are allowed even if a tag or an anchor is + # specified. + event = ScalarEvent(anchor, tag, (implicit, False), '', + start_mark, end_mark) + self.state = self.states.pop() + else: + if block: + node = 'block' + else: + node = 'flow' + token = self.peek_token() + raise ParserError("while parsing a %s node" % node, start_mark, + "expected the node content, but found %r" % token.id, + token.start_mark) + return event + + # block_sequence ::= BLOCK-SEQUENCE-START (BLOCK-ENTRY block_node?)* BLOCK-END + + def parse_block_sequence_first_entry(self): + token = self.get_token() + self.marks.append(token.start_mark) + return self.parse_block_sequence_entry() + + def parse_block_sequence_entry(self): + if self.check_token(BlockEntryToken): + token = self.get_token() + if not self.check_token(BlockEntryToken, BlockEndToken): + self.states.append(self.parse_block_sequence_entry) + return self.parse_block_node() + else: + self.state = self.parse_block_sequence_entry + return self.process_empty_scalar(token.end_mark) + if not self.check_token(BlockEndToken): + token = self.peek_token() + raise ParserError("while parsing a block collection", self.marks[-1], + "expected , but found %r" % token.id, token.start_mark) + token = self.get_token() + event = SequenceEndEvent(token.start_mark, token.end_mark) + self.state = self.states.pop() + self.marks.pop() + return event + + # indentless_sequence ::= (BLOCK-ENTRY block_node?)+ + + def parse_indentless_sequence_entry(self): + if self.check_token(BlockEntryToken): + token = self.get_token() + if not self.check_token(BlockEntryToken, + KeyToken, ValueToken, BlockEndToken): + self.states.append(self.parse_indentless_sequence_entry) + return self.parse_block_node() + else: + self.state = self.parse_indentless_sequence_entry + return self.process_empty_scalar(token.end_mark) + token = self.peek_token() + event = SequenceEndEvent(token.start_mark, token.start_mark) + self.state = self.states.pop() + return event + + # block_mapping ::= BLOCK-MAPPING_START + # ((KEY block_node_or_indentless_sequence?)? + # (VALUE block_node_or_indentless_sequence?)?)* + # BLOCK-END + + def parse_block_mapping_first_key(self): + token = self.get_token() + self.marks.append(token.start_mark) + return self.parse_block_mapping_key() + + def parse_block_mapping_key(self): + if self.check_token(KeyToken): + token = self.get_token() + if not self.check_token(KeyToken, ValueToken, BlockEndToken): + self.states.append(self.parse_block_mapping_value) + return self.parse_block_node_or_indentless_sequence() + else: + self.state = self.parse_block_mapping_value + return self.process_empty_scalar(token.end_mark) + if not self.check_token(BlockEndToken): + token = self.peek_token() + raise ParserError("while parsing a block mapping", self.marks[-1], + "expected , but found %r" % token.id, token.start_mark) + token = self.get_token() + event = MappingEndEvent(token.start_mark, token.end_mark) + self.state = self.states.pop() + self.marks.pop() + return event + + def parse_block_mapping_value(self): + if self.check_token(ValueToken): + token = self.get_token() + if not self.check_token(KeyToken, ValueToken, BlockEndToken): + self.states.append(self.parse_block_mapping_key) + return self.parse_block_node_or_indentless_sequence() + else: + self.state = self.parse_block_mapping_key + return self.process_empty_scalar(token.end_mark) + else: + self.state = self.parse_block_mapping_key + token = self.peek_token() + return self.process_empty_scalar(token.start_mark) + + # flow_sequence ::= FLOW-SEQUENCE-START + # (flow_sequence_entry FLOW-ENTRY)* + # flow_sequence_entry? + # FLOW-SEQUENCE-END + # flow_sequence_entry ::= flow_node | KEY flow_node? (VALUE flow_node?)? + # + # Note that while production rules for both flow_sequence_entry and + # flow_mapping_entry are equal, their interpretations are different. + # For `flow_sequence_entry`, the part `KEY flow_node? (VALUE flow_node?)?` + # generate an inline mapping (set syntax). + + def parse_flow_sequence_first_entry(self): + token = self.get_token() + self.marks.append(token.start_mark) + return self.parse_flow_sequence_entry(first=True) + + def parse_flow_sequence_entry(self, first=False): + if not self.check_token(FlowSequenceEndToken): + if not first: + if self.check_token(FlowEntryToken): + self.get_token() + else: + token = self.peek_token() + raise ParserError("while parsing a flow sequence", self.marks[-1], + "expected ',' or ']', but got %r" % token.id, token.start_mark) + + if self.check_token(KeyToken): + token = self.peek_token() + event = MappingStartEvent(None, None, True, + token.start_mark, token.end_mark, + flow_style=True) + self.state = self.parse_flow_sequence_entry_mapping_key + return event + elif not self.check_token(FlowSequenceEndToken): + self.states.append(self.parse_flow_sequence_entry) + return self.parse_flow_node() + token = self.get_token() + event = SequenceEndEvent(token.start_mark, token.end_mark) + self.state = self.states.pop() + self.marks.pop() + return event + + def parse_flow_sequence_entry_mapping_key(self): + token = self.get_token() + if not self.check_token(ValueToken, + FlowEntryToken, FlowSequenceEndToken): + self.states.append(self.parse_flow_sequence_entry_mapping_value) + return self.parse_flow_node() + else: + self.state = self.parse_flow_sequence_entry_mapping_value + return self.process_empty_scalar(token.end_mark) + + def parse_flow_sequence_entry_mapping_value(self): + if self.check_token(ValueToken): + token = self.get_token() + if not self.check_token(FlowEntryToken, FlowSequenceEndToken): + self.states.append(self.parse_flow_sequence_entry_mapping_end) + return self.parse_flow_node() + else: + self.state = self.parse_flow_sequence_entry_mapping_end + return self.process_empty_scalar(token.end_mark) + else: + self.state = self.parse_flow_sequence_entry_mapping_end + token = self.peek_token() + return self.process_empty_scalar(token.start_mark) + + def parse_flow_sequence_entry_mapping_end(self): + self.state = self.parse_flow_sequence_entry + token = self.peek_token() + return MappingEndEvent(token.start_mark, token.start_mark) + + # flow_mapping ::= FLOW-MAPPING-START + # (flow_mapping_entry FLOW-ENTRY)* + # flow_mapping_entry? + # FLOW-MAPPING-END + # flow_mapping_entry ::= flow_node | KEY flow_node? (VALUE flow_node?)? + + def parse_flow_mapping_first_key(self): + token = self.get_token() + self.marks.append(token.start_mark) + return self.parse_flow_mapping_key(first=True) + + def parse_flow_mapping_key(self, first=False): + if not self.check_token(FlowMappingEndToken): + if not first: + if self.check_token(FlowEntryToken): + self.get_token() + else: + token = self.peek_token() + raise ParserError("while parsing a flow mapping", self.marks[-1], + "expected ',' or '}', but got %r" % token.id, token.start_mark) + if self.check_token(KeyToken): + token = self.get_token() + if not self.check_token(ValueToken, + FlowEntryToken, FlowMappingEndToken): + self.states.append(self.parse_flow_mapping_value) + return self.parse_flow_node() + else: + self.state = self.parse_flow_mapping_value + return self.process_empty_scalar(token.end_mark) + elif not self.check_token(FlowMappingEndToken): + self.states.append(self.parse_flow_mapping_empty_value) + return self.parse_flow_node() + token = self.get_token() + event = MappingEndEvent(token.start_mark, token.end_mark) + self.state = self.states.pop() + self.marks.pop() + return event + + def parse_flow_mapping_value(self): + if self.check_token(ValueToken): + token = self.get_token() + if not self.check_token(FlowEntryToken, FlowMappingEndToken): + self.states.append(self.parse_flow_mapping_key) + return self.parse_flow_node() + else: + self.state = self.parse_flow_mapping_key + return self.process_empty_scalar(token.end_mark) + else: + self.state = self.parse_flow_mapping_key + token = self.peek_token() + return self.process_empty_scalar(token.start_mark) + + def parse_flow_mapping_empty_value(self): + self.state = self.parse_flow_mapping_key + return self.process_empty_scalar(self.peek_token().start_mark) + + def process_empty_scalar(self, mark): + return ScalarEvent(None, None, (True, False), '', mark, mark) + diff --git a/rplibs/yaml/yaml_py3/reader.py b/rplibs/yaml/yaml_py3/reader.py new file mode 100644 index 0000000..f70e920 --- /dev/null +++ b/rplibs/yaml/yaml_py3/reader.py @@ -0,0 +1,192 @@ +# This module contains abstractions for the input stream. You don't have to +# looks further, there are no pretty code. +# +# We define two classes here. +# +# Mark(source, line, column) +# It's just a record and its only use is producing nice error messages. +# Parser does not use it for any other purposes. +# +# Reader(source, data) +# Reader determines the encoding of `data` and converts it to unicode. +# Reader provides the following methods and attributes: +# reader.peek(length=1) - return the next `length` characters +# reader.forward(length=1) - move the current position to `length` characters. +# reader.index - the number of the current character. +# reader.line, stream.column - the line and the column of the current character. + +__all__ = ['Reader', 'ReaderError'] + +from .error import YAMLError, Mark + +import codecs, re + +class ReaderError(YAMLError): + + def __init__(self, name, position, character, encoding, reason): + self.name = name + self.character = character + self.position = position + self.encoding = encoding + self.reason = reason + + def __str__(self): + if isinstance(self.character, bytes): + return "'%s' codec can't decode byte #x%02x: %s\n" \ + " in \"%s\", position %d" \ + % (self.encoding, ord(self.character), self.reason, + self.name, self.position) + else: + return "unacceptable character #x%04x: %s\n" \ + " in \"%s\", position %d" \ + % (self.character, self.reason, + self.name, self.position) + +class Reader(object): + # Reader: + # - determines the data encoding and converts it to a unicode string, + # - checks if characters are in allowed range, + # - adds '\0' to the end. + + # Reader accepts + # - a `bytes` object, + # - a `str` object, + # - a file-like object with its `read` method returning `str`, + # - a file-like object with its `read` method returning `unicode`. + + # Yeah, it's ugly and slow. + + def __init__(self, stream): + self.name = None + self.stream = None + self.stream_pointer = 0 + self.eof = True + self.buffer = '' + self.pointer = 0 + self.raw_buffer = None + self.raw_decode = None + self.encoding = None + self.index = 0 + self.line = 0 + self.column = 0 + if isinstance(stream, str): + self.name = "" + self.check_printable(stream) + self.buffer = stream+'\0' + elif isinstance(stream, bytes): + self.name = "" + self.raw_buffer = stream + self.determine_encoding() + else: + self.stream = stream + self.name = getattr(stream, 'name', "") + self.eof = False + self.raw_buffer = None + self.determine_encoding() + + def peek(self, index=0): + try: + return self.buffer[self.pointer+index] + except IndexError: + self.update(index+1) + return self.buffer[self.pointer+index] + + def prefix(self, length=1): + if self.pointer+length >= len(self.buffer): + self.update(length) + return self.buffer[self.pointer:self.pointer+length] + + def forward(self, length=1): + if self.pointer+length+1 >= len(self.buffer): + self.update(length+1) + while length: + ch = self.buffer[self.pointer] + self.pointer += 1 + self.index += 1 + if ch in '\n\x85\u2028\u2029' \ + or (ch == '\r' and self.buffer[self.pointer] != '\n'): + self.line += 1 + self.column = 0 + elif ch != '\uFEFF': + self.column += 1 + length -= 1 + + def get_mark(self): + if self.stream is None: + return Mark(self.name, self.index, self.line, self.column, + self.buffer, self.pointer) + else: + return Mark(self.name, self.index, self.line, self.column, + None, None) + + def determine_encoding(self): + while not self.eof and (self.raw_buffer is None or len(self.raw_buffer) < 2): + self.update_raw() + if isinstance(self.raw_buffer, bytes): + if self.raw_buffer.startswith(codecs.BOM_UTF16_LE): + self.raw_decode = codecs.utf_16_le_decode + self.encoding = 'utf-16-le' + elif self.raw_buffer.startswith(codecs.BOM_UTF16_BE): + self.raw_decode = codecs.utf_16_be_decode + self.encoding = 'utf-16-be' + else: + self.raw_decode = codecs.utf_8_decode + self.encoding = 'utf-8' + self.update(1) + + NON_PRINTABLE = re.compile('[^\x09\x0A\x0D\x20-\x7E\x85\xA0-\uD7FF\uE000-\uFFFD]') + def check_printable(self, data): + match = self.NON_PRINTABLE.search(data) + if match: + character = match.group() + position = self.index+(len(self.buffer)-self.pointer)+match.start() + raise ReaderError(self.name, position, ord(character), + 'unicode', "special characters are not allowed") + + def update(self, length): + if self.raw_buffer is None: + return + self.buffer = self.buffer[self.pointer:] + self.pointer = 0 + while len(self.buffer) < length: + if not self.eof: + self.update_raw() + if self.raw_decode is not None: + try: + data, converted = self.raw_decode(self.raw_buffer, + 'strict', self.eof) + except UnicodeDecodeError as exc: + character = self.raw_buffer[exc.start] + if self.stream is not None: + position = self.stream_pointer-len(self.raw_buffer)+exc.start + else: + position = exc.start + raise ReaderError(self.name, position, character, + exc.encoding, exc.reason) + else: + data = self.raw_buffer + converted = len(data) + self.check_printable(data) + self.buffer += data + self.raw_buffer = self.raw_buffer[converted:] + if self.eof: + self.buffer += '\0' + self.raw_buffer = None + break + + def update_raw(self, size=4096): + data = self.stream.read(size) + if self.raw_buffer is None: + self.raw_buffer = data + else: + self.raw_buffer += data + self.stream_pointer += len(data) + if not data: + self.eof = True + +#try: +# import psyco +# psyco.bind(Reader) +#except ImportError: +# pass + diff --git a/rplibs/yaml/yaml_py3/representer.py b/rplibs/yaml/yaml_py3/representer.py new file mode 100644 index 0000000..67cd6fd --- /dev/null +++ b/rplibs/yaml/yaml_py3/representer.py @@ -0,0 +1,374 @@ + +__all__ = ['BaseRepresenter', 'SafeRepresenter', 'Representer', + 'RepresenterError'] + +from .error import * +from .nodes import * + +import datetime, sys, copyreg, types, base64 + +class RepresenterError(YAMLError): + pass + +class BaseRepresenter: + + yaml_representers = {} + yaml_multi_representers = {} + + def __init__(self, default_style=None, default_flow_style=None): + self.default_style = default_style + self.default_flow_style = default_flow_style + self.represented_objects = {} + self.object_keeper = [] + self.alias_key = None + + def represent(self, data): + node = self.represent_data(data) + self.serialize(node) + self.represented_objects = {} + self.object_keeper = [] + self.alias_key = None + + def represent_data(self, data): + if self.ignore_aliases(data): + self.alias_key = None + else: + self.alias_key = id(data) + if self.alias_key is not None: + if self.alias_key in self.represented_objects: + node = self.represented_objects[self.alias_key] + #if node is None: + # raise RepresenterError("recursive objects are not allowed: %r" % data) + return node + #self.represented_objects[alias_key] = None + self.object_keeper.append(data) + data_types = type(data).__mro__ + if data_types[0] in self.yaml_representers: + node = self.yaml_representers[data_types[0]](self, data) + else: + for data_type in data_types: + if data_type in self.yaml_multi_representers: + node = self.yaml_multi_representers[data_type](self, data) + break + else: + if None in self.yaml_multi_representers: + node = self.yaml_multi_representers[None](self, data) + elif None in self.yaml_representers: + node = self.yaml_representers[None](self, data) + else: + node = ScalarNode(None, str(data)) + #if alias_key is not None: + # self.represented_objects[alias_key] = node + return node + + @classmethod + def add_representer(cls, data_type, representer): + if not 'yaml_representers' in cls.__dict__: + cls.yaml_representers = cls.yaml_representers.copy() + cls.yaml_representers[data_type] = representer + + @classmethod + def add_multi_representer(cls, data_type, representer): + if not 'yaml_multi_representers' in cls.__dict__: + cls.yaml_multi_representers = cls.yaml_multi_representers.copy() + cls.yaml_multi_representers[data_type] = representer + + def represent_scalar(self, tag, value, style=None): + if style is None: + style = self.default_style + node = ScalarNode(tag, value, style=style) + if self.alias_key is not None: + self.represented_objects[self.alias_key] = node + return node + + def represent_sequence(self, tag, sequence, flow_style=None): + value = [] + node = SequenceNode(tag, value, flow_style=flow_style) + if self.alias_key is not None: + self.represented_objects[self.alias_key] = node + best_style = True + for item in sequence: + node_item = self.represent_data(item) + if not (isinstance(node_item, ScalarNode) and not node_item.style): + best_style = False + value.append(node_item) + if flow_style is None: + if self.default_flow_style is not None: + node.flow_style = self.default_flow_style + else: + node.flow_style = best_style + return node + + def represent_mapping(self, tag, mapping, flow_style=None): + value = [] + node = MappingNode(tag, value, flow_style=flow_style) + if self.alias_key is not None: + self.represented_objects[self.alias_key] = node + best_style = True + if hasattr(mapping, 'items'): + mapping = list(mapping.items()) + try: + mapping = sorted(mapping) + except TypeError: + pass + for item_key, item_value in mapping: + node_key = self.represent_data(item_key) + node_value = self.represent_data(item_value) + if not (isinstance(node_key, ScalarNode) and not node_key.style): + best_style = False + if not (isinstance(node_value, ScalarNode) and not node_value.style): + best_style = False + value.append((node_key, node_value)) + if flow_style is None: + if self.default_flow_style is not None: + node.flow_style = self.default_flow_style + else: + node.flow_style = best_style + return node + + def ignore_aliases(self, data): + return False + +class SafeRepresenter(BaseRepresenter): + + def ignore_aliases(self, data): + if data in [None, ()]: + return True + if isinstance(data, (str, bytes, bool, int, float)): + return True + + def represent_none(self, data): + return self.represent_scalar('tag:yaml.org,2002:null', 'null') + + def represent_str(self, data): + return self.represent_scalar('tag:yaml.org,2002:str', data) + + def represent_binary(self, data): + if hasattr(base64, 'encodebytes'): + data = base64.encodebytes(data).decode('ascii') + else: + data = base64.encodestring(data).decode('ascii') + return self.represent_scalar('tag:yaml.org,2002:binary', data, style='|') + + def represent_bool(self, data): + if data: + value = 'true' + else: + value = 'false' + return self.represent_scalar('tag:yaml.org,2002:bool', value) + + def represent_int(self, data): + return self.represent_scalar('tag:yaml.org,2002:int', str(data)) + + inf_value = 1e300 + while repr(inf_value) != repr(inf_value*inf_value): + inf_value *= inf_value + + def represent_float(self, data): + if data != data or (data == 0.0 and data == 1.0): + value = '.nan' + elif data == self.inf_value: + value = '.inf' + elif data == -self.inf_value: + value = '-.inf' + else: + value = repr(data).lower() + # Note that in some cases `repr(data)` represents a float number + # without the decimal parts. For instance: + # >>> repr(1e17) + # '1e17' + # Unfortunately, this is not a valid float representation according + # to the definition of the `!!float` tag. We fix this by adding + # '.0' before the 'e' symbol. + if '.' not in value and 'e' in value: + value = value.replace('e', '.0e', 1) + return self.represent_scalar('tag:yaml.org,2002:float', value) + + def represent_list(self, data): + #pairs = (len(data) > 0 and isinstance(data, list)) + #if pairs: + # for item in data: + # if not isinstance(item, tuple) or len(item) != 2: + # pairs = False + # break + #if not pairs: + return self.represent_sequence('tag:yaml.org,2002:seq', data) + #value = [] + #for item_key, item_value in data: + # value.append(self.represent_mapping(u'tag:yaml.org,2002:map', + # [(item_key, item_value)])) + #return SequenceNode(u'tag:yaml.org,2002:pairs', value) + + def represent_dict(self, data): + return self.represent_mapping('tag:yaml.org,2002:map', data) + + def represent_set(self, data): + value = {} + for key in data: + value[key] = None + return self.represent_mapping('tag:yaml.org,2002:set', value) + + def represent_date(self, data): + value = data.isoformat() + return self.represent_scalar('tag:yaml.org,2002:timestamp', value) + + def represent_datetime(self, data): + value = data.isoformat(' ') + return self.represent_scalar('tag:yaml.org,2002:timestamp', value) + + def represent_yaml_object(self, tag, data, cls, flow_style=None): + if hasattr(data, '__getstate__'): + state = data.__getstate__() + else: + state = data.__dict__.copy() + return self.represent_mapping(tag, state, flow_style=flow_style) + + def represent_undefined(self, data): + raise RepresenterError("cannot represent an object: %s" % data) + +SafeRepresenter.add_representer(type(None), + SafeRepresenter.represent_none) + +SafeRepresenter.add_representer(str, + SafeRepresenter.represent_str) + +SafeRepresenter.add_representer(bytes, + SafeRepresenter.represent_binary) + +SafeRepresenter.add_representer(bool, + SafeRepresenter.represent_bool) + +SafeRepresenter.add_representer(int, + SafeRepresenter.represent_int) + +SafeRepresenter.add_representer(float, + SafeRepresenter.represent_float) + +SafeRepresenter.add_representer(list, + SafeRepresenter.represent_list) + +SafeRepresenter.add_representer(tuple, + SafeRepresenter.represent_list) + +SafeRepresenter.add_representer(dict, + SafeRepresenter.represent_dict) + +SafeRepresenter.add_representer(set, + SafeRepresenter.represent_set) + +SafeRepresenter.add_representer(datetime.date, + SafeRepresenter.represent_date) + +SafeRepresenter.add_representer(datetime.datetime, + SafeRepresenter.represent_datetime) + +SafeRepresenter.add_representer(None, + SafeRepresenter.represent_undefined) + +class Representer(SafeRepresenter): + + def represent_complex(self, data): + if data.imag == 0.0: + data = '%r' % data.real + elif data.real == 0.0: + data = '%rj' % data.imag + elif data.imag > 0: + data = '%r+%rj' % (data.real, data.imag) + else: + data = '%r%rj' % (data.real, data.imag) + return self.represent_scalar('tag:yaml.org,2002:python/complex', data) + + def represent_tuple(self, data): + return self.represent_sequence('tag:yaml.org,2002:python/tuple', data) + + def represent_name(self, data): + name = '%s.%s' % (data.__module__, data.__name__) + return self.represent_scalar('tag:yaml.org,2002:python/name:'+name, '') + + def represent_module(self, data): + return self.represent_scalar( + 'tag:yaml.org,2002:python/module:'+data.__name__, '') + + def represent_object(self, data): + # We use __reduce__ API to save the data. data.__reduce__ returns + # a tuple of length 2-5: + # (function, args, state, listitems, dictitems) + + # For reconstructing, we calls function(*args), then set its state, + # listitems, and dictitems if they are not None. + + # A special case is when function.__name__ == '__newobj__'. In this + # case we create the object with args[0].__new__(*args). + + # Another special case is when __reduce__ returns a string - we don't + # support it. + + # We produce a !!python/object, !!python/object/new or + # !!python/object/apply node. + + cls = type(data) + if cls in copyreg.dispatch_table: + reduce = copyreg.dispatch_table[cls](data) + elif hasattr(data, '__reduce_ex__'): + reduce = data.__reduce_ex__(2) + elif hasattr(data, '__reduce__'): + reduce = data.__reduce__() + else: + raise RepresenterError("cannot represent object: %r" % data) + reduce = (list(reduce)+[None]*5)[:5] + function, args, state, listitems, dictitems = reduce + args = list(args) + if state is None: + state = {} + if listitems is not None: + listitems = list(listitems) + if dictitems is not None: + dictitems = dict(dictitems) + if function.__name__ == '__newobj__': + function = args[0] + args = args[1:] + tag = 'tag:yaml.org,2002:python/object/new:' + newobj = True + else: + tag = 'tag:yaml.org,2002:python/object/apply:' + newobj = False + function_name = '%s.%s' % (function.__module__, function.__name__) + if not args and not listitems and not dictitems \ + and isinstance(state, dict) and newobj: + return self.represent_mapping( + 'tag:yaml.org,2002:python/object:'+function_name, state) + if not listitems and not dictitems \ + and isinstance(state, dict) and not state: + return self.represent_sequence(tag+function_name, args) + value = {} + if args: + value['args'] = args + if state or not isinstance(state, dict): + value['state'] = state + if listitems: + value['listitems'] = listitems + if dictitems: + value['dictitems'] = dictitems + return self.represent_mapping(tag+function_name, value) + +Representer.add_representer(complex, + Representer.represent_complex) + +Representer.add_representer(tuple, + Representer.represent_tuple) + +Representer.add_representer(type, + Representer.represent_name) + +Representer.add_representer(types.FunctionType, + Representer.represent_name) + +Representer.add_representer(types.BuiltinFunctionType, + Representer.represent_name) + +Representer.add_representer(types.ModuleType, + Representer.represent_module) + +Representer.add_multi_representer(object, + Representer.represent_object) + diff --git a/rplibs/yaml/yaml_py3/resolver.py b/rplibs/yaml/yaml_py3/resolver.py new file mode 100644 index 0000000..0eece25 --- /dev/null +++ b/rplibs/yaml/yaml_py3/resolver.py @@ -0,0 +1,224 @@ + +__all__ = ['BaseResolver', 'Resolver'] + +from .error import * +from .nodes import * + +import re + +class ResolverError(YAMLError): + pass + +class BaseResolver: + + DEFAULT_SCALAR_TAG = 'tag:yaml.org,2002:str' + DEFAULT_SEQUENCE_TAG = 'tag:yaml.org,2002:seq' + DEFAULT_MAPPING_TAG = 'tag:yaml.org,2002:map' + + yaml_implicit_resolvers = {} + yaml_path_resolvers = {} + + def __init__(self): + self.resolver_exact_paths = [] + self.resolver_prefix_paths = [] + + @classmethod + def add_implicit_resolver(cls, tag, regexp, first): + if not 'yaml_implicit_resolvers' in cls.__dict__: + cls.yaml_implicit_resolvers = cls.yaml_implicit_resolvers.copy() + if first is None: + first = [None] + for ch in first: + cls.yaml_implicit_resolvers.setdefault(ch, []).append((tag, regexp)) + + @classmethod + def add_path_resolver(cls, tag, path, kind=None): + # Note: `add_path_resolver` is experimental. The API could be changed. + # `new_path` is a pattern that is matched against the path from the + # root to the node that is being considered. `node_path` elements are + # tuples `(node_check, index_check)`. `node_check` is a node class: + # `ScalarNode`, `SequenceNode`, `MappingNode` or `None`. `None` + # matches any kind of a node. `index_check` could be `None`, a boolean + # value, a string value, or a number. `None` and `False` match against + # any _value_ of sequence and mapping nodes. `True` matches against + # any _key_ of a mapping node. A string `index_check` matches against + # a mapping value that corresponds to a scalar key which content is + # equal to the `index_check` value. An integer `index_check` matches + # against a sequence value with the index equal to `index_check`. + if not 'yaml_path_resolvers' in cls.__dict__: + cls.yaml_path_resolvers = cls.yaml_path_resolvers.copy() + new_path = [] + for element in path: + if isinstance(element, (list, tuple)): + if len(element) == 2: + node_check, index_check = element + elif len(element) == 1: + node_check = element[0] + index_check = True + else: + raise ResolverError("Invalid path element: %s" % element) + else: + node_check = None + index_check = element + if node_check is str: + node_check = ScalarNode + elif node_check is list: + node_check = SequenceNode + elif node_check is dict: + node_check = MappingNode + elif node_check not in [ScalarNode, SequenceNode, MappingNode] \ + and not isinstance(node_check, str) \ + and node_check is not None: + raise ResolverError("Invalid node checker: %s" % node_check) + if not isinstance(index_check, (str, int)) \ + and index_check is not None: + raise ResolverError("Invalid index checker: %s" % index_check) + new_path.append((node_check, index_check)) + if kind is str: + kind = ScalarNode + elif kind is list: + kind = SequenceNode + elif kind is dict: + kind = MappingNode + elif kind not in [ScalarNode, SequenceNode, MappingNode] \ + and kind is not None: + raise ResolverError("Invalid node kind: %s" % kind) + cls.yaml_path_resolvers[tuple(new_path), kind] = tag + + def descend_resolver(self, current_node, current_index): + if not self.yaml_path_resolvers: + return + exact_paths = {} + prefix_paths = [] + if current_node: + depth = len(self.resolver_prefix_paths) + for path, kind in self.resolver_prefix_paths[-1]: + if self.check_resolver_prefix(depth, path, kind, + current_node, current_index): + if len(path) > depth: + prefix_paths.append((path, kind)) + else: + exact_paths[kind] = self.yaml_path_resolvers[path, kind] + else: + for path, kind in self.yaml_path_resolvers: + if not path: + exact_paths[kind] = self.yaml_path_resolvers[path, kind] + else: + prefix_paths.append((path, kind)) + self.resolver_exact_paths.append(exact_paths) + self.resolver_prefix_paths.append(prefix_paths) + + def ascend_resolver(self): + if not self.yaml_path_resolvers: + return + self.resolver_exact_paths.pop() + self.resolver_prefix_paths.pop() + + def check_resolver_prefix(self, depth, path, kind, + current_node, current_index): + node_check, index_check = path[depth-1] + if isinstance(node_check, str): + if current_node.tag != node_check: + return + elif node_check is not None: + if not isinstance(current_node, node_check): + return + if index_check is True and current_index is not None: + return + if (index_check is False or index_check is None) \ + and current_index is None: + return + if isinstance(index_check, str): + if not (isinstance(current_index, ScalarNode) + and index_check == current_index.value): + return + elif isinstance(index_check, int) and not isinstance(index_check, bool): + if index_check != current_index: + return + return True + + def resolve(self, kind, value, implicit): + if kind is ScalarNode and implicit[0]: + if value == '': + resolvers = self.yaml_implicit_resolvers.get('', []) + else: + resolvers = self.yaml_implicit_resolvers.get(value[0], []) + resolvers += self.yaml_implicit_resolvers.get(None, []) + for tag, regexp in resolvers: + if regexp.match(value): + return tag + implicit = implicit[1] + if self.yaml_path_resolvers: + exact_paths = self.resolver_exact_paths[-1] + if kind in exact_paths: + return exact_paths[kind] + if None in exact_paths: + return exact_paths[None] + if kind is ScalarNode: + return self.DEFAULT_SCALAR_TAG + elif kind is SequenceNode: + return self.DEFAULT_SEQUENCE_TAG + elif kind is MappingNode: + return self.DEFAULT_MAPPING_TAG + +class Resolver(BaseResolver): + pass + +Resolver.add_implicit_resolver( + 'tag:yaml.org,2002:bool', + re.compile(r'''^(?:yes|Yes|YES|no|No|NO + |true|True|TRUE|false|False|FALSE + |on|On|ON|off|Off|OFF)$''', re.X), + list('yYnNtTfFoO')) + +Resolver.add_implicit_resolver( + 'tag:yaml.org,2002:float', + re.compile(r'''^(?:[-+]?(?:[0-9][0-9_]*)\.[0-9_]*(?:[eE][-+][0-9]+)? + |\.[0-9_]+(?:[eE][-+][0-9]+)? + |[-+]?[0-9][0-9_]*(?::[0-5]?[0-9])+\.[0-9_]* + |[-+]?\.(?:inf|Inf|INF) + |\.(?:nan|NaN|NAN))$''', re.X), + list('-+0123456789.')) + +Resolver.add_implicit_resolver( + 'tag:yaml.org,2002:int', + re.compile(r'''^(?:[-+]?0b[0-1_]+ + |[-+]?0[0-7_]+ + |[-+]?(?:0|[1-9][0-9_]*) + |[-+]?0x[0-9a-fA-F_]+ + |[-+]?[1-9][0-9_]*(?::[0-5]?[0-9])+)$''', re.X), + list('-+0123456789')) + +Resolver.add_implicit_resolver( + 'tag:yaml.org,2002:merge', + re.compile(r'^(?:<<)$'), + ['<']) + +Resolver.add_implicit_resolver( + 'tag:yaml.org,2002:null', + re.compile(r'''^(?: ~ + |null|Null|NULL + | )$''', re.X), + ['~', 'n', 'N', '']) + +Resolver.add_implicit_resolver( + 'tag:yaml.org,2002:timestamp', + re.compile(r'''^(?:[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9] + |[0-9][0-9][0-9][0-9] -[0-9][0-9]? -[0-9][0-9]? + (?:[Tt]|[ \t]+)[0-9][0-9]? + :[0-9][0-9] :[0-9][0-9] (?:\.[0-9]*)? + (?:[ \t]*(?:Z|[-+][0-9][0-9]?(?::[0-9][0-9])?))?)$''', re.X), + list('0123456789')) + +Resolver.add_implicit_resolver( + 'tag:yaml.org,2002:value', + re.compile(r'^(?:=)$'), + ['=']) + +# The following resolver is only for documentation purposes. It cannot work +# because plain scalars cannot start with '!', '&', or '*'. +Resolver.add_implicit_resolver( + 'tag:yaml.org,2002:yaml', + re.compile(r'^(?:!|&|\*)$'), + list('!&*')) + diff --git a/rplibs/yaml/yaml_py3/scanner.py b/rplibs/yaml/yaml_py3/scanner.py new file mode 100644 index 0000000..494d975 --- /dev/null +++ b/rplibs/yaml/yaml_py3/scanner.py @@ -0,0 +1,1448 @@ + +# Scanner produces tokens of the following types: +# STREAM-START +# STREAM-END +# DIRECTIVE(name, value) +# DOCUMENT-START +# DOCUMENT-END +# BLOCK-SEQUENCE-START +# BLOCK-MAPPING-START +# BLOCK-END +# FLOW-SEQUENCE-START +# FLOW-MAPPING-START +# FLOW-SEQUENCE-END +# FLOW-MAPPING-END +# BLOCK-ENTRY +# FLOW-ENTRY +# KEY +# VALUE +# ALIAS(value) +# ANCHOR(value) +# TAG(value) +# SCALAR(value, plain, style) +# +# Read comments in the Scanner code for more details. +# + +__all__ = ['Scanner', 'ScannerError'] + +from .error import MarkedYAMLError +from .tokens import * + +class ScannerError(MarkedYAMLError): + pass + +class SimpleKey: + # See below simple keys treatment. + + def __init__(self, token_number, required, index, line, column, mark): + self.token_number = token_number + self.required = required + self.index = index + self.line = line + self.column = column + self.mark = mark + +class Scanner: + + def __init__(self): + """Initialize the scanner.""" + # It is assumed that Scanner and Reader will have a common descendant. + # Reader do the dirty work of checking for BOM and converting the + # input data to Unicode. It also adds NUL to the end. + # + # Reader supports the following methods + # self.peek(i=0) # peek the next i-th character + # self.prefix(l=1) # peek the next l characters + # self.forward(l=1) # read the next l characters and move the pointer. + + # Had we reached the end of the stream? + self.done = False + + # The number of unclosed '{' and '['. `flow_level == 0` means block + # context. + self.flow_level = 0 + + # List of processed tokens that are not yet emitted. + self.tokens = [] + + # Add the STREAM-START token. + self.fetch_stream_start() + + # Number of tokens that were emitted through the `get_token` method. + self.tokens_taken = 0 + + # The current indentation level. + self.indent = -1 + + # Past indentation levels. + self.indents = [] + + # Variables related to simple keys treatment. + + # A simple key is a key that is not denoted by the '?' indicator. + # Example of simple keys: + # --- + # block simple key: value + # ? not a simple key: + # : { flow simple key: value } + # We emit the KEY token before all keys, so when we find a potential + # simple key, we try to locate the corresponding ':' indicator. + # Simple keys should be limited to a single line and 1024 characters. + + # Can a simple key start at the current position? A simple key may + # start: + # - at the beginning of the line, not counting indentation spaces + # (in block context), + # - after '{', '[', ',' (in the flow context), + # - after '?', ':', '-' (in the block context). + # In the block context, this flag also signifies if a block collection + # may start at the current position. + self.allow_simple_key = True + + # Keep track of possible simple keys. This is a dictionary. The key + # is `flow_level`; there can be no more that one possible simple key + # for each level. The value is a SimpleKey record: + # (token_number, required, index, line, column, mark) + # A simple key may start with ALIAS, ANCHOR, TAG, SCALAR(flow), + # '[', or '{' tokens. + self.possible_simple_keys = {} + + # Public methods. + + def check_token(self, *choices): + # Check if the next token is one of the given types. + while self.need_more_tokens(): + self.fetch_more_tokens() + if self.tokens: + if not choices: + return True + for choice in choices: + if isinstance(self.tokens[0], choice): + return True + return False + + def peek_token(self): + # Return the next token, but do not delete if from the queue. + while self.need_more_tokens(): + self.fetch_more_tokens() + if self.tokens: + return self.tokens[0] + + def get_token(self): + # Return the next token. + while self.need_more_tokens(): + self.fetch_more_tokens() + if self.tokens: + self.tokens_taken += 1 + return self.tokens.pop(0) + + # Private methods. + + def need_more_tokens(self): + if self.done: + return False + if not self.tokens: + return True + # The current token may be a potential simple key, so we + # need to look further. + self.stale_possible_simple_keys() + if self.next_possible_simple_key() == self.tokens_taken: + return True + + def fetch_more_tokens(self): + + # Eat whitespaces and comments until we reach the next token. + self.scan_to_next_token() + + # Remove obsolete possible simple keys. + self.stale_possible_simple_keys() + + # Compare the current indentation and column. It may add some tokens + # and decrease the current indentation level. + self.unwind_indent(self.column) + + # Peek the next character. + ch = self.peek() + + # Is it the end of stream? + if ch == '\0': + return self.fetch_stream_end() + + # Is it a directive? + if ch == '%' and self.check_directive(): + return self.fetch_directive() + + # Is it the document start? + if ch == '-' and self.check_document_start(): + return self.fetch_document_start() + + # Is it the document end? + if ch == '.' and self.check_document_end(): + return self.fetch_document_end() + + # TODO: support for BOM within a stream. + #if ch == '\uFEFF': + # return self.fetch_bom() <-- issue BOMToken + + # Note: the order of the following checks is NOT significant. + + # Is it the flow sequence start indicator? + if ch == '[': + return self.fetch_flow_sequence_start() + + # Is it the flow mapping start indicator? + if ch == '{': + return self.fetch_flow_mapping_start() + + # Is it the flow sequence end indicator? + if ch == ']': + return self.fetch_flow_sequence_end() + + # Is it the flow mapping end indicator? + if ch == '}': + return self.fetch_flow_mapping_end() + + # Is it the flow entry indicator? + if ch == ',': + return self.fetch_flow_entry() + + # Is it the block entry indicator? + if ch == '-' and self.check_block_entry(): + return self.fetch_block_entry() + + # Is it the key indicator? + if ch == '?' and self.check_key(): + return self.fetch_key() + + # Is it the value indicator? + if ch == ':' and self.check_value(): + return self.fetch_value() + + # Is it an alias? + if ch == '*': + return self.fetch_alias() + + # Is it an anchor? + if ch == '&': + return self.fetch_anchor() + + # Is it a tag? + if ch == '!': + return self.fetch_tag() + + # Is it a literal scalar? + if ch == '|' and not self.flow_level: + return self.fetch_literal() + + # Is it a folded scalar? + if ch == '>' and not self.flow_level: + return self.fetch_folded() + + # Is it a single quoted scalar? + if ch == '\'': + return self.fetch_single() + + # Is it a double quoted scalar? + if ch == '\"': + return self.fetch_double() + + # It must be a plain scalar then. + if self.check_plain(): + return self.fetch_plain() + + # No? It's an error. Let's produce a nice error message. + raise ScannerError("while scanning for the next token", None, + "found character %r that cannot start any token" % ch, + self.get_mark()) + + # Simple keys treatment. + + def next_possible_simple_key(self): + # Return the number of the nearest possible simple key. Actually we + # don't need to loop through the whole dictionary. We may replace it + # with the following code: + # if not self.possible_simple_keys: + # return None + # return self.possible_simple_keys[ + # min(self.possible_simple_keys.keys())].token_number + min_token_number = None + for level in self.possible_simple_keys: + key = self.possible_simple_keys[level] + if min_token_number is None or key.token_number < min_token_number: + min_token_number = key.token_number + return min_token_number + + def stale_possible_simple_keys(self): + # Remove entries that are no longer possible simple keys. According to + # the YAML specification, simple keys + # - should be limited to a single line, + # - should be no longer than 1024 characters. + # Disabling this procedure will allow simple keys of any length and + # height (may cause problems if indentation is broken though). + for level in list(self.possible_simple_keys): + key = self.possible_simple_keys[level] + if key.line != self.line \ + or self.index-key.index > 1024: + if key.required: + raise ScannerError("while scanning a simple key", key.mark, + "could not found expected ':'", self.get_mark()) + del self.possible_simple_keys[level] + + def save_possible_simple_key(self): + # The next token may start a simple key. We check if it's possible + # and save its position. This function is called for + # ALIAS, ANCHOR, TAG, SCALAR(flow), '[', and '{'. + + # Check if a simple key is required at the current position. + required = not self.flow_level and self.indent == self.column + + # A simple key is required only if it is the first token in the current + # line. Therefore it is always allowed. + assert self.allow_simple_key or not required + + # The next token might be a simple key. Let's save it's number and + # position. + if self.allow_simple_key: + self.remove_possible_simple_key() + token_number = self.tokens_taken+len(self.tokens) + key = SimpleKey(token_number, required, + self.index, self.line, self.column, self.get_mark()) + self.possible_simple_keys[self.flow_level] = key + + def remove_possible_simple_key(self): + # Remove the saved possible key position at the current flow level. + if self.flow_level in self.possible_simple_keys: + key = self.possible_simple_keys[self.flow_level] + + if key.required: + raise ScannerError("while scanning a simple key", key.mark, + "could not found expected ':'", self.get_mark()) + + del self.possible_simple_keys[self.flow_level] + + # Indentation functions. + + def unwind_indent(self, column): + + ## In flow context, tokens should respect indentation. + ## Actually the condition should be `self.indent >= column` according to + ## the spec. But this condition will prohibit intuitively correct + ## constructions such as + ## key : { + ## } + #if self.flow_level and self.indent > column: + # raise ScannerError(None, None, + # "invalid intendation or unclosed '[' or '{'", + # self.get_mark()) + + # In the flow context, indentation is ignored. We make the scanner less + # restrictive then specification requires. + if self.flow_level: + return + + # In block context, we may need to issue the BLOCK-END tokens. + while self.indent > column: + mark = self.get_mark() + self.indent = self.indents.pop() + self.tokens.append(BlockEndToken(mark, mark)) + + def add_indent(self, column): + # Check if we need to increase indentation. + if self.indent < column: + self.indents.append(self.indent) + self.indent = column + return True + return False + + # Fetchers. + + def fetch_stream_start(self): + # We always add STREAM-START as the first token and STREAM-END as the + # last token. + + # Read the token. + mark = self.get_mark() + + # Add STREAM-START. + self.tokens.append(StreamStartToken(mark, mark, + encoding=self.encoding)) + + + def fetch_stream_end(self): + + # Set the current intendation to -1. + self.unwind_indent(-1) + + # Reset simple keys. + self.remove_possible_simple_key() + self.allow_simple_key = False + self.possible_simple_keys = {} + + # Read the token. + mark = self.get_mark() + + # Add STREAM-END. + self.tokens.append(StreamEndToken(mark, mark)) + + # The steam is finished. + self.done = True + + def fetch_directive(self): + + # Set the current intendation to -1. + self.unwind_indent(-1) + + # Reset simple keys. + self.remove_possible_simple_key() + self.allow_simple_key = False + + # Scan and add DIRECTIVE. + self.tokens.append(self.scan_directive()) + + def fetch_document_start(self): + self.fetch_document_indicator(DocumentStartToken) + + def fetch_document_end(self): + self.fetch_document_indicator(DocumentEndToken) + + def fetch_document_indicator(self, TokenClass): + + # Set the current intendation to -1. + self.unwind_indent(-1) + + # Reset simple keys. Note that there could not be a block collection + # after '---'. + self.remove_possible_simple_key() + self.allow_simple_key = False + + # Add DOCUMENT-START or DOCUMENT-END. + start_mark = self.get_mark() + self.forward(3) + end_mark = self.get_mark() + self.tokens.append(TokenClass(start_mark, end_mark)) + + def fetch_flow_sequence_start(self): + self.fetch_flow_collection_start(FlowSequenceStartToken) + + def fetch_flow_mapping_start(self): + self.fetch_flow_collection_start(FlowMappingStartToken) + + def fetch_flow_collection_start(self, TokenClass): + + # '[' and '{' may start a simple key. + self.save_possible_simple_key() + + # Increase the flow level. + self.flow_level += 1 + + # Simple keys are allowed after '[' and '{'. + self.allow_simple_key = True + + # Add FLOW-SEQUENCE-START or FLOW-MAPPING-START. + start_mark = self.get_mark() + self.forward() + end_mark = self.get_mark() + self.tokens.append(TokenClass(start_mark, end_mark)) + + def fetch_flow_sequence_end(self): + self.fetch_flow_collection_end(FlowSequenceEndToken) + + def fetch_flow_mapping_end(self): + self.fetch_flow_collection_end(FlowMappingEndToken) + + def fetch_flow_collection_end(self, TokenClass): + + # Reset possible simple key on the current level. + self.remove_possible_simple_key() + + # Decrease the flow level. + self.flow_level -= 1 + + # No simple keys after ']' or '}'. + self.allow_simple_key = False + + # Add FLOW-SEQUENCE-END or FLOW-MAPPING-END. + start_mark = self.get_mark() + self.forward() + end_mark = self.get_mark() + self.tokens.append(TokenClass(start_mark, end_mark)) + + def fetch_flow_entry(self): + + # Simple keys are allowed after ','. + self.allow_simple_key = True + + # Reset possible simple key on the current level. + self.remove_possible_simple_key() + + # Add FLOW-ENTRY. + start_mark = self.get_mark() + self.forward() + end_mark = self.get_mark() + self.tokens.append(FlowEntryToken(start_mark, end_mark)) + + def fetch_block_entry(self): + + # Block context needs additional checks. + if not self.flow_level: + + # Are we allowed to start a new entry? + if not self.allow_simple_key: + raise ScannerError(None, None, + "sequence entries are not allowed here", + self.get_mark()) + + # We may need to add BLOCK-SEQUENCE-START. + if self.add_indent(self.column): + mark = self.get_mark() + self.tokens.append(BlockSequenceStartToken(mark, mark)) + + # It's an error for the block entry to occur in the flow context, + # but we let the parser detect this. + else: + pass + + # Simple keys are allowed after '-'. + self.allow_simple_key = True + + # Reset possible simple key on the current level. + self.remove_possible_simple_key() + + # Add BLOCK-ENTRY. + start_mark = self.get_mark() + self.forward() + end_mark = self.get_mark() + self.tokens.append(BlockEntryToken(start_mark, end_mark)) + + def fetch_key(self): + + # Block context needs additional checks. + if not self.flow_level: + + # Are we allowed to start a key (not nessesary a simple)? + if not self.allow_simple_key: + raise ScannerError(None, None, + "mapping keys are not allowed here", + self.get_mark()) + + # We may need to add BLOCK-MAPPING-START. + if self.add_indent(self.column): + mark = self.get_mark() + self.tokens.append(BlockMappingStartToken(mark, mark)) + + # Simple keys are allowed after '?' in the block context. + self.allow_simple_key = not self.flow_level + + # Reset possible simple key on the current level. + self.remove_possible_simple_key() + + # Add KEY. + start_mark = self.get_mark() + self.forward() + end_mark = self.get_mark() + self.tokens.append(KeyToken(start_mark, end_mark)) + + def fetch_value(self): + + # Do we determine a simple key? + if self.flow_level in self.possible_simple_keys: + + # Add KEY. + key = self.possible_simple_keys[self.flow_level] + del self.possible_simple_keys[self.flow_level] + self.tokens.insert(key.token_number-self.tokens_taken, + KeyToken(key.mark, key.mark)) + + # If this key starts a new block mapping, we need to add + # BLOCK-MAPPING-START. + if not self.flow_level: + if self.add_indent(key.column): + self.tokens.insert(key.token_number-self.tokens_taken, + BlockMappingStartToken(key.mark, key.mark)) + + # There cannot be two simple keys one after another. + self.allow_simple_key = False + + # It must be a part of a complex key. + else: + + # Block context needs additional checks. + # (Do we really need them? They will be catched by the parser + # anyway.) + if not self.flow_level: + + # We are allowed to start a complex value if and only if + # we can start a simple key. + if not self.allow_simple_key: + raise ScannerError(None, None, + "mapping values are not allowed here", + self.get_mark()) + + # If this value starts a new block mapping, we need to add + # BLOCK-MAPPING-START. It will be detected as an error later by + # the parser. + if not self.flow_level: + if self.add_indent(self.column): + mark = self.get_mark() + self.tokens.append(BlockMappingStartToken(mark, mark)) + + # Simple keys are allowed after ':' in the block context. + self.allow_simple_key = not self.flow_level + + # Reset possible simple key on the current level. + self.remove_possible_simple_key() + + # Add VALUE. + start_mark = self.get_mark() + self.forward() + end_mark = self.get_mark() + self.tokens.append(ValueToken(start_mark, end_mark)) + + def fetch_alias(self): + + # ALIAS could be a simple key. + self.save_possible_simple_key() + + # No simple keys after ALIAS. + self.allow_simple_key = False + + # Scan and add ALIAS. + self.tokens.append(self.scan_anchor(AliasToken)) + + def fetch_anchor(self): + + # ANCHOR could start a simple key. + self.save_possible_simple_key() + + # No simple keys after ANCHOR. + self.allow_simple_key = False + + # Scan and add ANCHOR. + self.tokens.append(self.scan_anchor(AnchorToken)) + + def fetch_tag(self): + + # TAG could start a simple key. + self.save_possible_simple_key() + + # No simple keys after TAG. + self.allow_simple_key = False + + # Scan and add TAG. + self.tokens.append(self.scan_tag()) + + def fetch_literal(self): + self.fetch_block_scalar(style='|') + + def fetch_folded(self): + self.fetch_block_scalar(style='>') + + def fetch_block_scalar(self, style): + + # A simple key may follow a block scalar. + self.allow_simple_key = True + + # Reset possible simple key on the current level. + self.remove_possible_simple_key() + + # Scan and add SCALAR. + self.tokens.append(self.scan_block_scalar(style)) + + def fetch_single(self): + self.fetch_flow_scalar(style='\'') + + def fetch_double(self): + self.fetch_flow_scalar(style='"') + + def fetch_flow_scalar(self, style): + + # A flow scalar could be a simple key. + self.save_possible_simple_key() + + # No simple keys after flow scalars. + self.allow_simple_key = False + + # Scan and add SCALAR. + self.tokens.append(self.scan_flow_scalar(style)) + + def fetch_plain(self): + + # A plain scalar could be a simple key. + self.save_possible_simple_key() + + # No simple keys after plain scalars. But note that `scan_plain` will + # change this flag if the scan is finished at the beginning of the + # line. + self.allow_simple_key = False + + # Scan and add SCALAR. May change `allow_simple_key`. + self.tokens.append(self.scan_plain()) + + # Checkers. + + def check_directive(self): + + # DIRECTIVE: ^ '%' ... + # The '%' indicator is already checked. + if self.column == 0: + return True + + def check_document_start(self): + + # DOCUMENT-START: ^ '---' (' '|'\n') + if self.column == 0: + if self.prefix(3) == '---' \ + and self.peek(3) in '\0 \t\r\n\x85\u2028\u2029': + return True + + def check_document_end(self): + + # DOCUMENT-END: ^ '...' (' '|'\n') + if self.column == 0: + if self.prefix(3) == '...' \ + and self.peek(3) in '\0 \t\r\n\x85\u2028\u2029': + return True + + def check_block_entry(self): + + # BLOCK-ENTRY: '-' (' '|'\n') + return self.peek(1) in '\0 \t\r\n\x85\u2028\u2029' + + def check_key(self): + + # KEY(flow context): '?' + if self.flow_level: + return True + + # KEY(block context): '?' (' '|'\n') + else: + return self.peek(1) in '\0 \t\r\n\x85\u2028\u2029' + + def check_value(self): + + # VALUE(flow context): ':' + if self.flow_level: + return True + + # VALUE(block context): ':' (' '|'\n') + else: + return self.peek(1) in '\0 \t\r\n\x85\u2028\u2029' + + def check_plain(self): + + # A plain scalar may start with any non-space character except: + # '-', '?', ':', ',', '[', ']', '{', '}', + # '#', '&', '*', '!', '|', '>', '\'', '\"', + # '%', '@', '`'. + # + # It may also start with + # '-', '?', ':' + # if it is followed by a non-space character. + # + # Note that we limit the last rule to the block context (except the + # '-' character) because we want the flow context to be space + # independent. + ch = self.peek() + return ch not in '\0 \t\r\n\x85\u2028\u2029-?:,[]{}#&*!|>\'\"%@`' \ + or (self.peek(1) not in '\0 \t\r\n\x85\u2028\u2029' + and (ch == '-' or (not self.flow_level and ch in '?:'))) + + # Scanners. + + def scan_to_next_token(self): + # We ignore spaces, line breaks and comments. + # If we find a line break in the block context, we set the flag + # `allow_simple_key` on. + # The byte order mark is stripped if it's the first character in the + # stream. We do not yet support BOM inside the stream as the + # specification requires. Any such mark will be considered as a part + # of the document. + # + # TODO: We need to make tab handling rules more sane. A good rule is + # Tabs cannot precede tokens + # BLOCK-SEQUENCE-START, BLOCK-MAPPING-START, BLOCK-END, + # KEY(block), VALUE(block), BLOCK-ENTRY + # So the checking code is + # if : + # self.allow_simple_keys = False + # We also need to add the check for `allow_simple_keys == True` to + # `unwind_indent` before issuing BLOCK-END. + # Scanners for block, flow, and plain scalars need to be modified. + + if self.index == 0 and self.peek() == '\uFEFF': + self.forward() + found = False + while not found: + while self.peek() == ' ': + self.forward() + if self.peek() == '#': + while self.peek() not in '\0\r\n\x85\u2028\u2029': + self.forward() + if self.scan_line_break(): + if not self.flow_level: + self.allow_simple_key = True + else: + found = True + + def scan_directive(self): + # See the specification for details. + start_mark = self.get_mark() + self.forward() + name = self.scan_directive_name(start_mark) + value = None + if name == 'YAML': + value = self.scan_yaml_directive_value(start_mark) + end_mark = self.get_mark() + elif name == 'TAG': + value = self.scan_tag_directive_value(start_mark) + end_mark = self.get_mark() + else: + end_mark = self.get_mark() + while self.peek() not in '\0\r\n\x85\u2028\u2029': + self.forward() + self.scan_directive_ignored_line(start_mark) + return DirectiveToken(name, value, start_mark, end_mark) + + def scan_directive_name(self, start_mark): + # See the specification for details. + length = 0 + ch = self.peek(length) + while '0' <= ch <= '9' or 'A' <= ch <= 'Z' or 'a' <= ch <= 'z' \ + or ch in '-_': + length += 1 + ch = self.peek(length) + if not length: + raise ScannerError("while scanning a directive", start_mark, + "expected alphabetic or numeric character, but found %r" + % ch, self.get_mark()) + value = self.prefix(length) + self.forward(length) + ch = self.peek() + if ch not in '\0 \r\n\x85\u2028\u2029': + raise ScannerError("while scanning a directive", start_mark, + "expected alphabetic or numeric character, but found %r" + % ch, self.get_mark()) + return value + + def scan_yaml_directive_value(self, start_mark): + # See the specification for details. + while self.peek() == ' ': + self.forward() + major = self.scan_yaml_directive_number(start_mark) + if self.peek() != '.': + raise ScannerError("while scanning a directive", start_mark, + "expected a digit or '.', but found %r" % self.peek(), + self.get_mark()) + self.forward() + minor = self.scan_yaml_directive_number(start_mark) + if self.peek() not in '\0 \r\n\x85\u2028\u2029': + raise ScannerError("while scanning a directive", start_mark, + "expected a digit or ' ', but found %r" % self.peek(), + self.get_mark()) + return (major, minor) + + def scan_yaml_directive_number(self, start_mark): + # See the specification for details. + ch = self.peek() + if not ('0' <= ch <= '9'): + raise ScannerError("while scanning a directive", start_mark, + "expected a digit, but found %r" % ch, self.get_mark()) + length = 0 + while '0' <= self.peek(length) <= '9': + length += 1 + value = int(self.prefix(length)) + self.forward(length) + return value + + def scan_tag_directive_value(self, start_mark): + # See the specification for details. + while self.peek() == ' ': + self.forward() + handle = self.scan_tag_directive_handle(start_mark) + while self.peek() == ' ': + self.forward() + prefix = self.scan_tag_directive_prefix(start_mark) + return (handle, prefix) + + def scan_tag_directive_handle(self, start_mark): + # See the specification for details. + value = self.scan_tag_handle('directive', start_mark) + ch = self.peek() + if ch != ' ': + raise ScannerError("while scanning a directive", start_mark, + "expected ' ', but found %r" % ch, self.get_mark()) + return value + + def scan_tag_directive_prefix(self, start_mark): + # See the specification for details. + value = self.scan_tag_uri('directive', start_mark) + ch = self.peek() + if ch not in '\0 \r\n\x85\u2028\u2029': + raise ScannerError("while scanning a directive", start_mark, + "expected ' ', but found %r" % ch, self.get_mark()) + return value + + def scan_directive_ignored_line(self, start_mark): + # See the specification for details. + while self.peek() == ' ': + self.forward() + if self.peek() == '#': + while self.peek() not in '\0\r\n\x85\u2028\u2029': + self.forward() + ch = self.peek() + if ch not in '\0\r\n\x85\u2028\u2029': + raise ScannerError("while scanning a directive", start_mark, + "expected a comment or a line break, but found %r" + % ch, self.get_mark()) + self.scan_line_break() + + def scan_anchor(self, TokenClass): + # The specification does not restrict characters for anchors and + # aliases. This may lead to problems, for instance, the document: + # [ *alias, value ] + # can be interpteted in two ways, as + # [ "value" ] + # and + # [ *alias , "value" ] + # Therefore we restrict aliases to numbers and ASCII letters. + start_mark = self.get_mark() + indicator = self.peek() + if indicator == '*': + name = 'alias' + else: + name = 'anchor' + self.forward() + length = 0 + ch = self.peek(length) + while '0' <= ch <= '9' or 'A' <= ch <= 'Z' or 'a' <= ch <= 'z' \ + or ch in '-_': + length += 1 + ch = self.peek(length) + if not length: + raise ScannerError("while scanning an %s" % name, start_mark, + "expected alphabetic or numeric character, but found %r" + % ch, self.get_mark()) + value = self.prefix(length) + self.forward(length) + ch = self.peek() + if ch not in '\0 \t\r\n\x85\u2028\u2029?:,]}%@`': + raise ScannerError("while scanning an %s" % name, start_mark, + "expected alphabetic or numeric character, but found %r" + % ch, self.get_mark()) + end_mark = self.get_mark() + return TokenClass(value, start_mark, end_mark) + + def scan_tag(self): + # See the specification for details. + start_mark = self.get_mark() + ch = self.peek(1) + if ch == '<': + handle = None + self.forward(2) + suffix = self.scan_tag_uri('tag', start_mark) + if self.peek() != '>': + raise ScannerError("while parsing a tag", start_mark, + "expected '>', but found %r" % self.peek(), + self.get_mark()) + self.forward() + elif ch in '\0 \t\r\n\x85\u2028\u2029': + handle = None + suffix = '!' + self.forward() + else: + length = 1 + use_handle = False + while ch not in '\0 \r\n\x85\u2028\u2029': + if ch == '!': + use_handle = True + break + length += 1 + ch = self.peek(length) + handle = '!' + if use_handle: + handle = self.scan_tag_handle('tag', start_mark) + else: + handle = '!' + self.forward() + suffix = self.scan_tag_uri('tag', start_mark) + ch = self.peek() + if ch not in '\0 \r\n\x85\u2028\u2029': + raise ScannerError("while scanning a tag", start_mark, + "expected ' ', but found %r" % ch, self.get_mark()) + value = (handle, suffix) + end_mark = self.get_mark() + return TagToken(value, start_mark, end_mark) + + def scan_block_scalar(self, style): + # See the specification for details. + + if style == '>': + folded = True + else: + folded = False + + chunks = [] + start_mark = self.get_mark() + + # Scan the header. + self.forward() + chomping, increment = self.scan_block_scalar_indicators(start_mark) + self.scan_block_scalar_ignored_line(start_mark) + + # Determine the indentation level and go to the first non-empty line. + min_indent = self.indent+1 + if min_indent < 1: + min_indent = 1 + if increment is None: + breaks, max_indent, end_mark = self.scan_block_scalar_indentation() + indent = max(min_indent, max_indent) + else: + indent = min_indent+increment-1 + breaks, end_mark = self.scan_block_scalar_breaks(indent) + line_break = '' + + # Scan the inner part of the block scalar. + while self.column == indent and self.peek() != '\0': + chunks.extend(breaks) + leading_non_space = self.peek() not in ' \t' + length = 0 + while self.peek(length) not in '\0\r\n\x85\u2028\u2029': + length += 1 + chunks.append(self.prefix(length)) + self.forward(length) + line_break = self.scan_line_break() + breaks, end_mark = self.scan_block_scalar_breaks(indent) + if self.column == indent and self.peek() != '\0': + + # Unfortunately, folding rules are ambiguous. + # + # This is the folding according to the specification: + + if folded and line_break == '\n' \ + and leading_non_space and self.peek() not in ' \t': + if not breaks: + chunks.append(' ') + else: + chunks.append(line_break) + + # This is Clark Evans's interpretation (also in the spec + # examples): + # + #if folded and line_break == '\n': + # if not breaks: + # if self.peek() not in ' \t': + # chunks.append(' ') + # else: + # chunks.append(line_break) + #else: + # chunks.append(line_break) + else: + break + + # Chomp the tail. + if chomping is not False: + chunks.append(line_break) + if chomping is True: + chunks.extend(breaks) + + # We are done. + return ScalarToken(''.join(chunks), False, start_mark, end_mark, + style) + + def scan_block_scalar_indicators(self, start_mark): + # See the specification for details. + chomping = None + increment = None + ch = self.peek() + if ch in '+-': + if ch == '+': + chomping = True + else: + chomping = False + self.forward() + ch = self.peek() + if ch in '0123456789': + increment = int(ch) + if increment == 0: + raise ScannerError("while scanning a block scalar", start_mark, + "expected indentation indicator in the range 1-9, but found 0", + self.get_mark()) + self.forward() + elif ch in '0123456789': + increment = int(ch) + if increment == 0: + raise ScannerError("while scanning a block scalar", start_mark, + "expected indentation indicator in the range 1-9, but found 0", + self.get_mark()) + self.forward() + ch = self.peek() + if ch in '+-': + if ch == '+': + chomping = True + else: + chomping = False + self.forward() + ch = self.peek() + if ch not in '\0 \r\n\x85\u2028\u2029': + raise ScannerError("while scanning a block scalar", start_mark, + "expected chomping or indentation indicators, but found %r" + % ch, self.get_mark()) + return chomping, increment + + def scan_block_scalar_ignored_line(self, start_mark): + # See the specification for details. + while self.peek() == ' ': + self.forward() + if self.peek() == '#': + while self.peek() not in '\0\r\n\x85\u2028\u2029': + self.forward() + ch = self.peek() + if ch not in '\0\r\n\x85\u2028\u2029': + raise ScannerError("while scanning a block scalar", start_mark, + "expected a comment or a line break, but found %r" % ch, + self.get_mark()) + self.scan_line_break() + + def scan_block_scalar_indentation(self): + # See the specification for details. + chunks = [] + max_indent = 0 + end_mark = self.get_mark() + while self.peek() in ' \r\n\x85\u2028\u2029': + if self.peek() != ' ': + chunks.append(self.scan_line_break()) + end_mark = self.get_mark() + else: + self.forward() + if self.column > max_indent: + max_indent = self.column + return chunks, max_indent, end_mark + + def scan_block_scalar_breaks(self, indent): + # See the specification for details. + chunks = [] + end_mark = self.get_mark() + while self.column < indent and self.peek() == ' ': + self.forward() + while self.peek() in '\r\n\x85\u2028\u2029': + chunks.append(self.scan_line_break()) + end_mark = self.get_mark() + while self.column < indent and self.peek() == ' ': + self.forward() + return chunks, end_mark + + def scan_flow_scalar(self, style): + # See the specification for details. + # Note that we loose indentation rules for quoted scalars. Quoted + # scalars don't need to adhere indentation because " and ' clearly + # mark the beginning and the end of them. Therefore we are less + # restrictive then the specification requires. We only need to check + # that document separators are not included in scalars. + if style == '"': + double = True + else: + double = False + chunks = [] + start_mark = self.get_mark() + quote = self.peek() + self.forward() + chunks.extend(self.scan_flow_scalar_non_spaces(double, start_mark)) + while self.peek() != quote: + chunks.extend(self.scan_flow_scalar_spaces(double, start_mark)) + chunks.extend(self.scan_flow_scalar_non_spaces(double, start_mark)) + self.forward() + end_mark = self.get_mark() + return ScalarToken(''.join(chunks), False, start_mark, end_mark, + style) + + ESCAPE_REPLACEMENTS = { + '0': '\0', + 'a': '\x07', + 'b': '\x08', + 't': '\x09', + '\t': '\x09', + 'n': '\x0A', + 'v': '\x0B', + 'f': '\x0C', + 'r': '\x0D', + 'e': '\x1B', + ' ': '\x20', + '\"': '\"', + '\\': '\\', + 'N': '\x85', + '_': '\xA0', + 'L': '\u2028', + 'P': '\u2029', + } + + ESCAPE_CODES = { + 'x': 2, + 'u': 4, + 'U': 8, + } + + def scan_flow_scalar_non_spaces(self, double, start_mark): + # See the specification for details. + chunks = [] + while True: + length = 0 + while self.peek(length) not in '\'\"\\\0 \t\r\n\x85\u2028\u2029': + length += 1 + if length: + chunks.append(self.prefix(length)) + self.forward(length) + ch = self.peek() + if not double and ch == '\'' and self.peek(1) == '\'': + chunks.append('\'') + self.forward(2) + elif (double and ch == '\'') or (not double and ch in '\"\\'): + chunks.append(ch) + self.forward() + elif double and ch == '\\': + self.forward() + ch = self.peek() + if ch in self.ESCAPE_REPLACEMENTS: + chunks.append(self.ESCAPE_REPLACEMENTS[ch]) + self.forward() + elif ch in self.ESCAPE_CODES: + length = self.ESCAPE_CODES[ch] + self.forward() + for k in range(length): + if self.peek(k) not in '0123456789ABCDEFabcdef': + raise ScannerError("while scanning a double-quoted scalar", start_mark, + "expected escape sequence of %d hexdecimal numbers, but found %r" % + (length, self.peek(k)), self.get_mark()) + code = int(self.prefix(length), 16) + chunks.append(chr(code)) + self.forward(length) + elif ch in '\r\n\x85\u2028\u2029': + self.scan_line_break() + chunks.extend(self.scan_flow_scalar_breaks(double, start_mark)) + else: + raise ScannerError("while scanning a double-quoted scalar", start_mark, + "found unknown escape character %r" % ch, self.get_mark()) + else: + return chunks + + def scan_flow_scalar_spaces(self, double, start_mark): + # See the specification for details. + chunks = [] + length = 0 + while self.peek(length) in ' \t': + length += 1 + whitespaces = self.prefix(length) + self.forward(length) + ch = self.peek() + if ch == '\0': + raise ScannerError("while scanning a quoted scalar", start_mark, + "found unexpected end of stream", self.get_mark()) + elif ch in '\r\n\x85\u2028\u2029': + line_break = self.scan_line_break() + breaks = self.scan_flow_scalar_breaks(double, start_mark) + if line_break != '\n': + chunks.append(line_break) + elif not breaks: + chunks.append(' ') + chunks.extend(breaks) + else: + chunks.append(whitespaces) + return chunks + + def scan_flow_scalar_breaks(self, double, start_mark): + # See the specification for details. + chunks = [] + while True: + # Instead of checking indentation, we check for document + # separators. + prefix = self.prefix(3) + if (prefix == '---' or prefix == '...') \ + and self.peek(3) in '\0 \t\r\n\x85\u2028\u2029': + raise ScannerError("while scanning a quoted scalar", start_mark, + "found unexpected document separator", self.get_mark()) + while self.peek() in ' \t': + self.forward() + if self.peek() in '\r\n\x85\u2028\u2029': + chunks.append(self.scan_line_break()) + else: + return chunks + + def scan_plain(self): + # See the specification for details. + # We add an additional restriction for the flow context: + # plain scalars in the flow context cannot contain ',', ':' and '?'. + # We also keep track of the `allow_simple_key` flag here. + # Indentation rules are loosed for the flow context. + chunks = [] + start_mark = self.get_mark() + end_mark = start_mark + indent = self.indent+1 + # We allow zero indentation for scalars, but then we need to check for + # document separators at the beginning of the line. + #if indent == 0: + # indent = 1 + spaces = [] + while True: + length = 0 + if self.peek() == '#': + break + while True: + ch = self.peek(length) + if ch in '\0 \t\r\n\x85\u2028\u2029' \ + or (not self.flow_level and ch == ':' and + self.peek(length+1) in '\0 \t\r\n\x85\u2028\u2029') \ + or (self.flow_level and ch in ',:?[]{}'): + break + length += 1 + # It's not clear what we should do with ':' in the flow context. + if (self.flow_level and ch == ':' + and self.peek(length+1) not in '\0 \t\r\n\x85\u2028\u2029,[]{}'): + self.forward(length) + raise ScannerError("while scanning a plain scalar", start_mark, + "found unexpected ':'", self.get_mark(), + "Please check http://pyyaml.org/wiki/YAMLColonInFlowContext for details.") + if length == 0: + break + self.allow_simple_key = False + chunks.extend(spaces) + chunks.append(self.prefix(length)) + self.forward(length) + end_mark = self.get_mark() + spaces = self.scan_plain_spaces(indent, start_mark) + if not spaces or self.peek() == '#' \ + or (not self.flow_level and self.column < indent): + break + return ScalarToken(''.join(chunks), True, start_mark, end_mark) + + def scan_plain_spaces(self, indent, start_mark): + # See the specification for details. + # The specification is really confusing about tabs in plain scalars. + # We just forbid them completely. Do not use tabs in YAML! + chunks = [] + length = 0 + while self.peek(length) in ' ': + length += 1 + whitespaces = self.prefix(length) + self.forward(length) + ch = self.peek() + if ch in '\r\n\x85\u2028\u2029': + line_break = self.scan_line_break() + self.allow_simple_key = True + prefix = self.prefix(3) + if (prefix == '---' or prefix == '...') \ + and self.peek(3) in '\0 \t\r\n\x85\u2028\u2029': + return + breaks = [] + while self.peek() in ' \r\n\x85\u2028\u2029': + if self.peek() == ' ': + self.forward() + else: + breaks.append(self.scan_line_break()) + prefix = self.prefix(3) + if (prefix == '---' or prefix == '...') \ + and self.peek(3) in '\0 \t\r\n\x85\u2028\u2029': + return + if line_break != '\n': + chunks.append(line_break) + elif not breaks: + chunks.append(' ') + chunks.extend(breaks) + elif whitespaces: + chunks.append(whitespaces) + return chunks + + def scan_tag_handle(self, name, start_mark): + # See the specification for details. + # For some strange reasons, the specification does not allow '_' in + # tag handles. I have allowed it anyway. + ch = self.peek() + if ch != '!': + raise ScannerError("while scanning a %s" % name, start_mark, + "expected '!', but found %r" % ch, self.get_mark()) + length = 1 + ch = self.peek(length) + if ch != ' ': + while '0' <= ch <= '9' or 'A' <= ch <= 'Z' or 'a' <= ch <= 'z' \ + or ch in '-_': + length += 1 + ch = self.peek(length) + if ch != '!': + self.forward(length) + raise ScannerError("while scanning a %s" % name, start_mark, + "expected '!', but found %r" % ch, self.get_mark()) + length += 1 + value = self.prefix(length) + self.forward(length) + return value + + def scan_tag_uri(self, name, start_mark): + # See the specification for details. + # Note: we do not check if URI is well-formed. + chunks = [] + length = 0 + ch = self.peek(length) + while '0' <= ch <= '9' or 'A' <= ch <= 'Z' or 'a' <= ch <= 'z' \ + or ch in '-;/?:@&=+$,_.!~*\'()[]%': + if ch == '%': + chunks.append(self.prefix(length)) + self.forward(length) + length = 0 + chunks.append(self.scan_uri_escapes(name, start_mark)) + else: + length += 1 + ch = self.peek(length) + if length: + chunks.append(self.prefix(length)) + self.forward(length) + length = 0 + if not chunks: + raise ScannerError("while parsing a %s" % name, start_mark, + "expected URI, but found %r" % ch, self.get_mark()) + return ''.join(chunks) + + def scan_uri_escapes(self, name, start_mark): + # See the specification for details. + codes = [] + mark = self.get_mark() + while self.peek() == '%': + self.forward() + for k in range(2): + if self.peek(k) not in '0123456789ABCDEFabcdef': + raise ScannerError("while scanning a %s" % name, start_mark, + "expected URI escape sequence of 2 hexdecimal numbers, but found %r" + % self.peek(k), self.get_mark()) + codes.append(int(self.prefix(2), 16)) + self.forward(2) + try: + value = bytes(codes).decode('utf-8') + except UnicodeDecodeError as exc: + raise ScannerError("while scanning a %s" % name, start_mark, str(exc), mark) + return value + + def scan_line_break(self): + # Transforms: + # '\r\n' : '\n' + # '\r' : '\n' + # '\n' : '\n' + # '\x85' : '\n' + # '\u2028' : '\u2028' + # '\u2029 : '\u2029' + # default : '' + ch = self.peek() + if ch in '\r\n\x85': + if self.prefix(2) == '\r\n': + self.forward(2) + else: + self.forward() + return '\n' + elif ch in '\u2028\u2029': + self.forward() + return ch + return '' + +#try: +# import psyco +# psyco.bind(Scanner) +#except ImportError: +# pass + diff --git a/rplibs/yaml/yaml_py3/serializer.py b/rplibs/yaml/yaml_py3/serializer.py new file mode 100644 index 0000000..fe911e6 --- /dev/null +++ b/rplibs/yaml/yaml_py3/serializer.py @@ -0,0 +1,111 @@ + +__all__ = ['Serializer', 'SerializerError'] + +from .error import YAMLError +from .events import * +from .nodes import * + +class SerializerError(YAMLError): + pass + +class Serializer: + + ANCHOR_TEMPLATE = 'id%03d' + + def __init__(self, encoding=None, + explicit_start=None, explicit_end=None, version=None, tags=None): + self.use_encoding = encoding + self.use_explicit_start = explicit_start + self.use_explicit_end = explicit_end + self.use_version = version + self.use_tags = tags + self.serialized_nodes = {} + self.anchors = {} + self.last_anchor_id = 0 + self.closed = None + + def open(self): + if self.closed is None: + self.emit(StreamStartEvent(encoding=self.use_encoding)) + self.closed = False + elif self.closed: + raise SerializerError("serializer is closed") + else: + raise SerializerError("serializer is already opened") + + def close(self): + if self.closed is None: + raise SerializerError("serializer is not opened") + elif not self.closed: + self.emit(StreamEndEvent()) + self.closed = True + + #def __del__(self): + # self.close() + + def serialize(self, node): + if self.closed is None: + raise SerializerError("serializer is not opened") + elif self.closed: + raise SerializerError("serializer is closed") + self.emit(DocumentStartEvent(explicit=self.use_explicit_start, + version=self.use_version, tags=self.use_tags)) + self.anchor_node(node) + self.serialize_node(node, None, None) + self.emit(DocumentEndEvent(explicit=self.use_explicit_end)) + self.serialized_nodes = {} + self.anchors = {} + self.last_anchor_id = 0 + + def anchor_node(self, node): + if node in self.anchors: + if self.anchors[node] is None: + self.anchors[node] = self.generate_anchor(node) + else: + self.anchors[node] = None + if isinstance(node, SequenceNode): + for item in node.value: + self.anchor_node(item) + elif isinstance(node, MappingNode): + for key, value in node.value: + self.anchor_node(key) + self.anchor_node(value) + + def generate_anchor(self, node): + self.last_anchor_id += 1 + return self.ANCHOR_TEMPLATE % self.last_anchor_id + + def serialize_node(self, node, parent, index): + alias = self.anchors[node] + if node in self.serialized_nodes: + self.emit(AliasEvent(alias)) + else: + self.serialized_nodes[node] = True + self.descend_resolver(parent, index) + if isinstance(node, ScalarNode): + detected_tag = self.resolve(ScalarNode, node.value, (True, False)) + default_tag = self.resolve(ScalarNode, node.value, (False, True)) + implicit = (node.tag == detected_tag), (node.tag == default_tag) + self.emit(ScalarEvent(alias, node.tag, implicit, node.value, + style=node.style)) + elif isinstance(node, SequenceNode): + implicit = (node.tag + == self.resolve(SequenceNode, node.value, True)) + self.emit(SequenceStartEvent(alias, node.tag, implicit, + flow_style=node.flow_style)) + index = 0 + for item in node.value: + self.serialize_node(item, node, index) + index += 1 + self.emit(SequenceEndEvent()) + elif isinstance(node, MappingNode): + implicit = (node.tag + == self.resolve(MappingNode, node.value, True)) + self.emit(MappingStartEvent(alias, node.tag, implicit, + flow_style=node.flow_style)) + for key, value in node.value: + self.serialize_node(key, node, None) + self.serialize_node(value, node, key) + self.emit(MappingEndEvent()) + self.ascend_resolver() + diff --git a/rplibs/yaml/yaml_py3/tokens.py b/rplibs/yaml/yaml_py3/tokens.py new file mode 100644 index 0000000..4d0b48a --- /dev/null +++ b/rplibs/yaml/yaml_py3/tokens.py @@ -0,0 +1,104 @@ + +class Token(object): + def __init__(self, start_mark, end_mark): + self.start_mark = start_mark + self.end_mark = end_mark + def __repr__(self): + attributes = [key for key in self.__dict__ + if not key.endswith('_mark')] + attributes.sort() + arguments = ', '.join(['%s=%r' % (key, getattr(self, key)) + for key in attributes]) + return '%s(%s)' % (self.__class__.__name__, arguments) + +#class BOMToken(Token): +# id = '' + +class DirectiveToken(Token): + id = '' + def __init__(self, name, value, start_mark, end_mark): + self.name = name + self.value = value + self.start_mark = start_mark + self.end_mark = end_mark + +class DocumentStartToken(Token): + id = '' + +class DocumentEndToken(Token): + id = '' + +class StreamStartToken(Token): + id = '' + def __init__(self, start_mark=None, end_mark=None, + encoding=None): + self.start_mark = start_mark + self.end_mark = end_mark + self.encoding = encoding + +class StreamEndToken(Token): + id = '' + +class BlockSequenceStartToken(Token): + id = '' + +class BlockMappingStartToken(Token): + id = '' + +class BlockEndToken(Token): + id = '' + +class FlowSequenceStartToken(Token): + id = '[' + +class FlowMappingStartToken(Token): + id = '{' + +class FlowSequenceEndToken(Token): + id = ']' + +class FlowMappingEndToken(Token): + id = '}' + +class KeyToken(Token): + id = '?' + +class ValueToken(Token): + id = ':' + +class BlockEntryToken(Token): + id = '-' + +class FlowEntryToken(Token): + id = ',' + +class AliasToken(Token): + id = '' + def __init__(self, value, start_mark, end_mark): + self.value = value + self.start_mark = start_mark + self.end_mark = end_mark + +class AnchorToken(Token): + id = '' + def __init__(self, value, start_mark, end_mark): + self.value = value + self.start_mark = start_mark + self.end_mark = end_mark + +class TagToken(Token): + id = '' + def __init__(self, value, start_mark, end_mark): + self.value = value + self.start_mark = start_mark + self.end_mark = end_mark + +class ScalarToken(Token): + id = '' + def __init__(self, value, plain, start_mark, end_mark, style=None): + self.value = value + self.plain = plain + self.start_mark = start_mark + self.end_mark = end_mark + self.style = style + diff --git a/rpplugins/README.md b/rpplugins/README.md new file mode 100644 index 0000000..bca8880 --- /dev/null +++ b/rpplugins/README.md @@ -0,0 +1,8 @@ + +## Plugins + +This is the plugin directory of the pipeline. It contains all plugins, including +their source code, resources and shaders. + +In case anybody ever makes plugins for the pipeline, you would want to copy +them into this folder to make them available for the render pipeline. diff --git a/rpplugins/__init__.py b/rpplugins/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/rpplugins/ao/__init__.py b/rpplugins/ao/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/rpplugins/ao/ao_stage.py b/rpplugins/ao/ao_stage.py new file mode 100644 index 0000000..9f982a1 --- /dev/null +++ b/rpplugins/ao/ao_stage.py @@ -0,0 +1,116 @@ +""" + +RenderPipeline + +Copyright (c) 2014-2016 tobspr + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. + +""" + +from panda3d.core import LVecBase2i, Vec2 +from rpcore.render_stage import RenderStage + + +class AOStage(RenderStage): + + required_inputs = [] + required_pipes = ["GBuffer", "DownscaledDepth", "PreviousFrame::AmbientOcclusion", + "CombinedVelocity", "PreviousFrame::SceneDepth"] + + @property + def produced_pipes(self): + return {"AmbientOcclusion": self.target_resolve.color_tex} + + def create(self): + self.target = self.create_target("Sample") + self.target.size = -2 + self.target.add_color_attachment(bits=(8, 0, 0, 0)) + self.target.prepare_buffer() + + self.target_upscale = self.create_target("Upscale") + self.target_upscale.add_color_attachment(bits=(8, 0, 0, 0)) + self.target_upscale.prepare_buffer() + + self.target_upscale.set_shader_inputs( + SourceTex=self.target.color_tex, + upscaleWeights=Vec2(0.001, 0.001)) + + self.tarrget_detail_ao = self.create_target("DetailAO") + self.tarrget_detail_ao.add_color_attachment(bits=(8, 0, 0, 0)) + self.tarrget_detail_ao.prepare_buffer() + self.tarrget_detail_ao.set_shader_input("AOResult", self.target_upscale.color_tex) + + self.debug("Blur quality is", self.quality) + + # Low + pixel_stretch = 2.0 + blur_passes = 1 + + if self.quality == "MEDIUM": + pixel_stretch = 1.0 + blur_passes = 2 + elif self.quality == "HIGH": + pixel_stretch = 1.0 + blur_passes = 3 + elif self.quality == "ULTRA": + pixel_stretch = 1.0 + blur_passes = 5 + + self.blur_targets = [] + + current_tex = self.tarrget_detail_ao.color_tex + + for i in range(blur_passes): + target_blur_v = self.create_target("BlurV-" + str(i)) + target_blur_v.add_color_attachment(bits=(8, 0, 0, 0)) + target_blur_v.prepare_buffer() + + target_blur_h = self.create_target("BlurH-" + str(i)) + target_blur_h.add_color_attachment(bits=(8, 0, 0, 0)) + target_blur_h.prepare_buffer() + + target_blur_v.set_shader_inputs( + SourceTex=current_tex, + blur_direction=LVecBase2i(0, 1), + pixel_stretch=pixel_stretch) + + target_blur_h.set_shader_inputs( + SourceTex=target_blur_v.color_tex, + blur_direction=LVecBase2i(1, 0), + pixel_stretch=pixel_stretch) + + current_tex = target_blur_h.color_tex + self.blur_targets += [target_blur_v, target_blur_h] + + self.target_resolve = self.create_target("ResolveAO") + self.target_resolve.add_color_attachment(bits=(8, 0, 0, 0)) + self.target_resolve.prepare_buffer() + self.target_resolve.set_shader_input("CurrentTex", current_tex) + + def reload_shaders(self): + self.target.shader = self.load_plugin_shader("ao_sample.frag.glsl") + self.target_upscale.shader = self.load_plugin_shader( + "/$$rp/shader/bilateral_upscale.frag.glsl") + blur_shader = self.load_plugin_shader( + "/$$rp/shader/bilateral_blur.frag.glsl") + for target in self.blur_targets: + target.shader = blur_shader + self.tarrget_detail_ao.shader = self.load_plugin_shader("small_scale_ao.frag.glsl") + self.target_resolve.shader = self.load_plugin_shader("resolve_ao.frag.glsl") diff --git a/rpplugins/ao/config.yaml b/rpplugins/ao/config.yaml new file mode 100644 index 0000000..0005023 --- /dev/null +++ b/rpplugins/ao/config.yaml @@ -0,0 +1,280 @@ + +settings: !!omap + + - blur_quality: + type: enum + values: ["LOW", "MEDIUM", "HIGH", "ULTRA"] + default: "MEDIUM" + label: Blur quality + description: > + Controls the quality of the post-ao blur, higher values produce smoother + ambient occlusion, but also cost more performance. + + # General settings + - blur_normal_factor: + type: float + range: [0.1, 10.0] + default: 1.2 + shader_runtime: true + label: Bilateral Blur Normal Factor + description: > + This setting controls the normal influence for the bilateral blur. + A value of 0.0 means a normal blur, and a higher value will prevent + blurring over normals. + + - blur_depth_factor: + type: float + range: [0.1, 10.0] + default: 0.9 + shader_runtime: true + label: Biliteral Blur Depth Factor + description: > + This setting controls the depth influence for the bilateral blur. + If a pixel exceeds the distance to the mid pixel by this amount, it + will not get weighted. + + - occlusion_strength: + type: float + range: [0.1, 6.0] + default: 1.6 + shader_runtime: true + label: Occlusion Strength + description: > + This controls the strength of the occlusion. Higher values will make + the occlusion look darker, and lower values will make it less + noticeable. You most likely will have to adjust it differently for + every technique. + + - clip_length: + type: int + range: [1, 16] + default: 2 + shader_runtime: true + label: Clip length + description: > + Controls how long to keep AO samples in the history. Bigger values + will produce a smoother effect but might also produce artifacts, + especially when moving. + + - technique: + type: enum + values: ["SSAO", "HBAO", "SSVO", "ALCHEMY", "UE4AO"] + default: SSAO + shader_runtime: true + label: Technique + description: > + The kernel to use for computing ambient occlusion. The settings below + depend on the kernel, so choose a kernel first! + + + # Settings for SSAO + + - ssao_sample_radius: + display_if: {technique: "SSAO"} + type: float + range: [5, 400] + default: 80 + shader_runtime: true + label: SSAO Sample Radius + description: > + Size of the sampling radius in pixels, higher values might look better, + but also perform worse due to less caching. + + - ssao_sequence: + display_if: {technique: "SSAO"} + type: sample_sequence + dimension: 3 + default: halton_3D_8 + shader_runtime: true + label: SSAO Sample Sequence + description: > + Amount and type of samples to use. A higher amount of samples provides + a better quality but also a decrease in performance. + + - ssao_bias: + display_if: {technique: "SSAO"} + type: float + range: [0.0, 0.5] + default: 0.0333 + shader_runtime: true + label: SSAO Depth Bias + description: > + This is a small bias which prevents self-occlusion artifacts on + curved objects. + + - ssao_max_distance: + display_if: {technique: "SSAO"} + type: float + range: [0.0, 15.0] + default: 6.9 + shader_runtime: true + label: SSAO Max distance + description: > + Prevents halos by specifying the maximum distance between two + pixels to account for ambient occlusion. The distance should be + in world space. + + # Settings for HBAO + + - hbao_sample_radius: + display_if: {technique: "HBAO"} + type: float + range: [5, 400] + default: 255.0 + shader_runtime: true + label: HBAO Sample Radius + description: > + Size of the sampling radius in pixels, higher values might look better, + but also perform worse due to less caching. + + - hbao_ray_count: + display_if: {technique: "HBAO"} + type: int + range: [1, 8] + default: 4 + shader_runtime: true + label: HBAO Ray count + description: > + Amount of rays to march from the pixel position. + + - hbao_ray_steps: + display_if: {technique: "HBAO"} + type: int + range: [1, 16] + default: 3 + shader_runtime: true + label: HBAO Ray steps + description: > + Amount of steps to perform for each ray. + + - hbao_tangent_bias: + display_if: {technique: "HBAO"} + type: float + range: [0.0, 1.0] + default: 0.65 + shader_runtime: true + label: HBAO Tangent bias + description: > + Used to prevent self-occlusion on curved objects, this increases the tangent angle + by a fixed value. + + - hbao_max_distance: + display_if: {technique: "HBAO"} + type: float + range: [0.01, 25.0] + default: 11.5 + shader_runtime: true + label: HBAO Max sample distance + description: > + Maximum distance of a sample to the pixel center in world space + + + # Settings for SSVO + - ssvo_sequence: + display_if: {technique: "SSVO"} + type: sample_sequence + dimension: 2 + default: halton_2D_8 + shader_runtime: true + label: SSVO Sample Sequence + description: > + Amount and type of samples to use. A higher amount of samples + provides a better quality but also a decrease in performance. + + - ssvo_sphere_radius: + display_if: {technique: "SSVO"} + type: float + range: [0.1, 40.0] + default: 18.0 + shader_runtime: true + label: SSVO Sphere sample radius + description: > + Size of the sphere in view space to integrate. High values may produce + artifacts. + + - ssvo_max_distance: + display_if: {technique: "SSVO"} + type: float + range: [0.05, 10.0] + default: 0.82 + shader_runtime: true + label: SSVO Max distance + description: > + Maximum distance until a sample gets rejected, in world space. This prevents halos arround objects. + + + # Settings for ALCHEMY + + + - alchemy_sample_radius: + display_if: {technique: "ALCHEMY"} + type: float + range: [5, 400] + default: 210.0 + shader_runtime: true + label: ALCHEMY Sample Radius + description: > + Size of the sampling radius in pixels, higher values might look better, + but also perform worse due to less caching. + + - alchemy_sequence: + display_if: {technique: "ALCHEMY"} + type: sample_sequence + dimension: 2 + default: halton_2D_8 + shader_runtime: true + label: ALCHEMY Sample Sequence + description: > + Amount and type of samples to use. A higher amount of samples provides + a better quality but also a decrease in performance. + + - alchemy_max_distance: + display_if: {technique: "ALCHEMY"} + type: float + range: [0.1, 20.0] + default: 4.75 + shader_runtime: true + label: ALCHEMY Maximum distance + description: > + Specifies the maximum distance between two samples until one sample + is rejected. This prevents halos arround objects. + + + # Settings for UE4AO + + - ue4ao_sample_radius: + display_if: {technique: "UE4AO"} + type: float + range: [5, 400] + default: 110.5 + shader_runtime: true + label: UE4AO Sample Radius + description: > + Size of the sampling radius in pixels, higher values might look better, + but also perform worse due to less caching. + + - ue4ao_sample_sequence: + display_if: {technique: "UE4AO"} + type: sample_sequence + dimension: 2 + default: halton_2D_8 + shader_runtime: true + label: UE4AO Sample Sequence + description: > + Amount and type of samples to use. A higher amount of samples provides + a better quality but also a decrease in performance. + + - ue4ao_max_distance: + display_if: {technique: "UE4AO"} + type: float + range: [0.1, 15.0] + default: 1.87 + shader_runtime: true + label: UE4AO Maximum distance + description: > + Specifies the maximum distance between two samples until one sample + is rejected. This prevents halos arround objects. + + + +daytime_settings: diff --git a/rpplugins/ao/plugin.py b/rpplugins/ao/plugin.py new file mode 100644 index 0000000..7369d9a --- /dev/null +++ b/rpplugins/ao/plugin.py @@ -0,0 +1,46 @@ +""" + +RenderPipeline + +Copyright (c) 2014-2016 tobspr + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. + +""" + +from rpcore.pluginbase.base_plugin import BasePlugin +from rpcore.stages.ambient_stage import AmbientStage + +from .ao_stage import AOStage + + +class Plugin(BasePlugin): + + name = "Ambient Occlusion" + author = "tobspr " + description = ("A plugin to render ambient occlusion supporting multiple" + "techniques such as SSAO, HBAO and much more ") + version = "1.1" + + def on_stage_setup(self): + self.stage = self.create_stage(AOStage) + self.stage.quality = self.get_setting("blur_quality") + + # Make the stages use our output + AmbientStage.required_pipes.append("AmbientOcclusion") diff --git a/rpplugins/ao/shader/alchemy.kernel.glsl b/rpplugins/ao/shader/alchemy.kernel.glsl new file mode 100644 index 0000000..c5ad798 --- /dev/null +++ b/rpplugins/ao/shader/alchemy.kernel.glsl @@ -0,0 +1,71 @@ +/** + * + * RenderPipeline + * + * Copyright (c) 2014-2016 tobspr + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + */ + + +/* + +ALCHEMY AO + +Projects random points to screen space, and uses the average unoccluded vector +to approximate AO. + +*/ + + +const float sample_radius = GET_SETTING(ao, alchemy_sample_radius); + +float max_dist = GET_SETTING(ao, alchemy_max_distance); +float accum = 0.0; +int accum_count = 0; +vec2 offset_scale = pixel_size * sample_radius * kernel_scale * 0.5; + + +START_ITERATE_SEQUENCE(ao, alchemy_sequence, vec2 offset) + + offset = mix(offset, noise_vec.xy, 0.3); + + vec2 offcoord = texcoord + offset * offset_scale; + + // Get view position at that offset + vec3 off_pos = get_view_pos_at(offcoord); + + // Get the vector s-p to that sample position + vec3 sample_vec = normalize(off_pos - pixel_view_pos); + + // Check if the distance matches, discard matches which are too far away + float dist = distance(off_pos, pixel_view_pos) / max_dist; + if (dist < 1.0) { + // Weight sample by the angle + accum += max(0, dot(pixel_view_normal, sample_vec)) * (1-dist); + } + + ++accum_count; + +END_ITERATE_SEQUENCE(); + +// Normalize values +accum /= max(1.0, float(accum_count)); +result = 1 - accum; diff --git a/rpplugins/ao/shader/ao_sample.frag.glsl b/rpplugins/ao/shader/ao_sample.frag.glsl new file mode 100644 index 0000000..d20b9b4 --- /dev/null +++ b/rpplugins/ao/shader/ao_sample.frag.glsl @@ -0,0 +1,97 @@ +/** + * + * RenderPipeline + * + * Copyright (c) 2014-2016 tobspr + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + */ + +#version 430 + +#pragma optionNV (unroll all) + +#pragma include "render_pipeline_base.inc.glsl" +#pragma include "includes/transforms.inc.glsl" +#pragma include "includes/noise.inc.glsl" +#pragma include "includes/sampling_sequences.inc.glsl" + +out float result; + +uniform sampler2D DownscaledDepth; + +// use the extended gbuffer api +#define USE_GBUFFER_EXTENSIONS 1 +#pragma include "includes/gbuffer.inc.glsl" + +float get_linear_depth_at(vec2 coord) { + return textureLod(DownscaledDepth, coord, 0).x; + // return get_linear_z_from_z(textureLod(GBuffer.Depth, coord, 0).x); +} + +void main() { + + // Provide some variables to the kernel + vec2 screen_size = vec2(WINDOW_WIDTH, WINDOW_HEIGHT); + vec2 pixel_size = vec2(1.0) / screen_size; + + ivec2 coord = ivec2(gl_FragCoord.xy) * 2; + vec2 texcoord = (coord + 0.5) / SCREEN_SIZE; + + // Shader variables + float pixel_depth = get_depth_at(texcoord); + float pixel_distance = get_linear_z_from_z(pixel_depth); + + if (pixel_distance > 1000.0) { + result = 1.0; + return; + } + + // vec3 view_vector = normalize(pixel_world_pos - MainSceneData.camera_pos); + float view_dist = pixel_distance; + + vec3 noise_vec = rand_rgb(coord % 8 + + 0.05 * (MainSceneData.frame_index % (GET_SETTING(ao, clip_length)))); + + vec3 pixel_view_normal = get_view_normal(texcoord); + vec3 pixel_view_pos = get_view_pos_at(texcoord); + vec3 pixel_world_normal = get_gbuffer_normal(GBuffer, texcoord); + + // float kernel_scale = 10.0 / get_linear_z_from_z(pixel_depth); + float kernel_scale = min(5.0, 10.0 / view_dist); + + // Include the appropriate kernel + #if ENUM_V_ACTIVE(ao, technique, SSAO) + #pragma include "ssao.kernel.glsl" + #elif ENUM_V_ACTIVE(ao, technique, HBAO) + #pragma include "hbao.kernel.glsl" + #elif ENUM_V_ACTIVE(ao, technique, SSVO) + #pragma include "ssvo.kernel.glsl" + #elif ENUM_V_ACTIVE(ao, technique, ALCHEMY) + #pragma include "alchemy.kernel.glsl" + #elif ENUM_V_ACTIVE(ao, technique, UE4AO) + #pragma include "ue4ao.kernel.glsl" + #else + #error Unkown AO technique! + #endif + + result = pow(saturate(result), GET_SETTING(ao, occlusion_strength)); + result = pow(result, 3.0); +} diff --git a/rpplugins/ao/shader/hbao.kernel.glsl b/rpplugins/ao/shader/hbao.kernel.glsl new file mode 100644 index 0000000..8b02143 --- /dev/null +++ b/rpplugins/ao/shader/hbao.kernel.glsl @@ -0,0 +1,85 @@ +/** + * + * RenderPipeline + * + * Copyright (c) 2014-2016 tobspr + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + */ + + + + +const float sample_radius = GET_SETTING(ao, hbao_sample_radius); +const int num_angles = GET_SETTING(ao, hbao_ray_count); +const int num_ray_steps = GET_SETTING(ao, hbao_ray_steps); +const float tangent_bias = GET_SETTING(ao, hbao_tangent_bias); +const float max_sample_distance = GET_SETTING(ao, hbao_max_distance) * 0.3; + +float accum = 0.0; + +for (int i = 0; i < num_angles; ++i) { + float angle = (i + 2 * noise_vec.x) / float(num_angles) * TWO_PI; + + vec2 sample_dir = vec2(cos(angle), sin(angle)); + + // Find the tangent andle + float tangent_angle = acos(dot(vec3(sample_dir, 0), pixel_view_normal)) - 0.5 * M_PI + + tangent_bias; + + // Assume the horizon angle is the same as the tangent angle at the beginning + // of the ray + float horizon_angle = tangent_angle; + + vec3 last_diff = vec3(0); + + // Raymarch in the sample direction + for (int k = 0; k < num_ray_steps; ++k) { + + // Get new texture coordinate + vec2 texc = texcoord + + sample_dir * (k + 2.0 + 2 * noise_vec.y) / + num_ray_steps * pixel_size * sample_radius * kernel_scale * 0.3; + + // Fetch view pos at that position and compare it + vec3 view_pos = get_view_pos_at(texc); + vec3 diff = view_pos - pixel_view_pos; + + if(length(diff) < max_sample_distance) { + + // Compute actual angle + float sample_angle = atan(diff.z / length(diff.xy)); + + // Correct horizon angle + horizon_angle = max(horizon_angle, sample_angle); + last_diff = diff; + } + } + + // Now that we know the average horizon angle, add it to the result + // For that we simply take the angle-difference + float occlusion = saturate(sin(horizon_angle) - sin(tangent_angle)); + occlusion *= 1.0 / (1 + length(last_diff)); + accum += occlusion; +} + +// Normalize samples +accum /= num_angles; +result = 1 - accum; diff --git a/rpplugins/ao/shader/resolve_ao.frag.glsl b/rpplugins/ao/shader/resolve_ao.frag.glsl new file mode 100644 index 0000000..952967c --- /dev/null +++ b/rpplugins/ao/shader/resolve_ao.frag.glsl @@ -0,0 +1,56 @@ +/** + * + * RenderPipeline + * + * Copyright (c) 2014-2016 tobspr + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + */ + +#version 430 + +#pragma include "render_pipeline_base.inc.glsl" + +#define RS_KEEP_GOOD_DURATION float(GET_SETTING(ao, clip_length) * 1.3) +#define RS_USE_POSITION_TECHNIQUE 1 +#define RS_DISTANCE_SCALE 1.0 + +#pragma include "includes/temporal_resolve.inc.glsl" + +uniform sampler2D CurrentTex; +uniform sampler2D CombinedVelocity; +uniform sampler2D Previous_AmbientOcclusion; + +out vec4 result; + +void main() { + vec2 texcoord = get_texcoord(); + + #if GET_SETTING(ao, clip_length) < 1 + // No reprojection needed without temporal ao + result = textureLod(CurrentTex, texcoord, 0).xyz; + #else + vec2 velocity = textureLod(CombinedVelocity, texcoord, 0).xy; + vec2 last_coord = texcoord + velocity; + + result = resolve_temporal( + CurrentTex, Previous_AmbientOcclusion, texcoord, last_coord); + #endif +} diff --git a/rpplugins/ao/shader/small_scale_ao.frag.glsl b/rpplugins/ao/shader/small_scale_ao.frag.glsl new file mode 100644 index 0000000..4ddfd95 --- /dev/null +++ b/rpplugins/ao/shader/small_scale_ao.frag.glsl @@ -0,0 +1,123 @@ +/** + * + * RenderPipeline + * + * Copyright (c) 2014-2016 tobspr + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + */ + +#version 430 + +#pragma optionNV (unroll all) + +#pragma include "render_pipeline_base.inc.glsl" +#pragma include "includes/transforms.inc.glsl" +#pragma include "includes/noise.inc.glsl" +#pragma include "includes/poisson_disk.inc.glsl" + +out float result; + +uniform sampler2D DownscaledDepth; +uniform sampler2D AOResult; + +// use the extended gbuffer api +#define USE_GBUFFER_EXTENSIONS 1 +#pragma include "includes/gbuffer.inc.glsl" + +float get_linear_depth_at(vec2 coord) { + return textureLod(DownscaledDepth, coord, 0).x; +} + +void main() { + + ivec2 coord = ivec2(gl_FragCoord.xy); + + // Provide some variables to the kernel + vec2 screen_size = vec2(WINDOW_WIDTH, WINDOW_HEIGHT); + vec2 pixel_size = vec2(1.0) / screen_size; + vec2 texcoord = get_texcoord(); + float pixel_z = get_linear_depth_at(texcoord); + + // Merge with previous ao result + float prev_result = textureLod(AOResult, texcoord, 0).x; + + // Fade out small scale ao + if (pixel_z > 150.0) { + result = prev_result; + return; + } + + vec3 noise_vec = rand_rgb(coord % 4 + + 0.01 * (MainSceneData.frame_index % (GET_SETTING(ao, clip_length)))); + + vec3 pixel_view_normal = get_view_normal(texcoord); + vec3 pixel_view_pos = get_view_pos_at(texcoord); + + float kernel_scale = min(5.0, 10.0 / pixel_z); + const float sample_radius = 6.0; + + const int num_samples = 4; + const float bias = 0.0005 + 0.01 / kernel_scale; + float max_range = 0.2; + + float sample_offset = sample_radius * pixel_size.x * 30.0; + float range_accum = 0.0; + float accum = 0.0; + + sample_offset /= kernel_scale; + + for (int i = 0; i < num_samples; ++i) { + vec3 offset = poisson_3D_16[4 * i]; + // offset = mix(offset, noise_vec, 0.5); + offset = normalize(offset + noise_vec); + + // Flip offset in case it faces away from the normal + offset = face_forward(offset, pixel_view_normal); + + // Compute offset position in view space + vec3 offset_pos = pixel_view_pos + offset * sample_offset; + + // Project offset position to screen space + vec3 projected = view_to_screen(offset_pos); + + // Fetch the expected depth + float sample_depth = get_linear_depth_at(projected.xy); + // float sample_depth = get_linear_z_from_z(get_depth_at(projected.xy)); + + // Linearize both depths + float linz_a = get_linear_z_from_z(projected.z); + float linz_b = sample_depth; + + // Compare both depths by distance to find the AO factor + float modifier = step(distance(linz_a, linz_b), max_range); + range_accum += fma(modifier, 0.5, 0.5); + modifier *= step(linz_b + bias, linz_a); + accum += modifier; + } + + // Normalize samples + accum /= max(0.1, range_accum); + accum = 1 - accum; + accum = pow(accum, 5.0); + prev_result *= accum; + // prev_result = pow(accum, 9.0); + result = prev_result; +} diff --git a/rpplugins/ao/shader/ssao.kernel.glsl b/rpplugins/ao/shader/ssao.kernel.glsl new file mode 100644 index 0000000..e41567b --- /dev/null +++ b/rpplugins/ao/shader/ssao.kernel.glsl @@ -0,0 +1,83 @@ +/** + * + * RenderPipeline + * + * Copyright (c) 2014-2016 tobspr + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + */ + + +/* + +CryEngine SSAO - Screen Space Ambient Occlusion + +Samples the depth buffer in a hemisphere arround the current pixel to approximate +AO. + +*/ + +const float sample_radius = GET_SETTING(ao, ssao_sample_radius); +const float bias = GET_SETTING(ao, ssao_bias) * 0.5 / kernel_scale; +float max_range = GET_SETTING(ao, ssao_max_distance); + +float sample_offset = sample_radius * pixel_size.x * 30.0; +float range_accum = 0.0; +float accum = 0.0; + +// Make sure we have nice sampling coherency by scaling the kernel +sample_offset /= 0.8 * kernel_scale; + +START_ITERATE_SEQUENCE(ao, ssao_sequence, vec3 offset) + + offset = mix(offset, noise_vec, 0.5); + offset *= 0.6; + + // Flip offset in case it faces away from the normal + offset = face_forward(offset, pixel_view_normal); + + // Compute offset position in view space + vec3 offset_pos = pixel_view_pos + offset * sample_offset; + + // Project offset position to screen space + vec3 projected = view_to_screen(offset_pos); + + // Fetch the expected depth + float sample_depth = get_linear_depth_at(projected.xy); + + // Linearize both depths + float linz_a = get_linear_z_from_z(projected.z); + float linz_b = sample_depth; + + // Compare both depths by distance to find the AO factor + float modifier = step(distance(linz_a, linz_b), max_range * 0.2); + range_accum += fma(modifier, 0.5, 0.5); + modifier *= step(linz_b + bias, linz_a); + accum += modifier; + +END_ITERATE_SEQUENCE() + + +// normalize samples +accum /= max(0.1, range_accum); + +// Renormalize to match with the other techniques +accum *= 0.4; +result = 1 - accum; diff --git a/rpplugins/ao/shader/ssvo.kernel.glsl b/rpplugins/ao/shader/ssvo.kernel.glsl new file mode 100644 index 0000000..ec44af1 --- /dev/null +++ b/rpplugins/ao/shader/ssvo.kernel.glsl @@ -0,0 +1,100 @@ +/** + * + * RenderPipeline + * + * Copyright (c) 2014-2016 tobspr + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + */ + + +/* + +SSVO - Screen Space Volumetric Obscurance + +This algorithm casts rays to a sphere arround the current point in view space, +and approximates the spheres volume by using line intetrals. The percentage +of the spheres volume is then used to compute AO. + +*/ + + + +vec2 sphere_radius = GET_SETTING(ao, ssvo_sphere_radius) * pixel_size; +float max_depth_diff = GET_SETTING(ao, ssvo_max_distance) / kernel_scale; + +float accum = 0.0; +float pixel_linz = get_linear_z_from_z(pixel_depth); + +START_ITERATE_SEQUENCE(ao, ssvo_sequence, vec2 offset) + + offset = mix(offset, noise_vec.xy, 0.3); + + vec2 offc = offset * sphere_radius * 5.0 * kernel_scale; + + // Use paired samples, this enables us to hide depth buffer discontinuities + vec2 offcoord_a = texcoord + offc; + vec2 offcoord_b = texcoord - offc; + + // Compute the sphere height at the sample location + float sphere_height = sqrt(1 - dot(offset, offset)); + + // Get the depth at the sample locations, also + // make the depth linear, this enables us to compare them better + float depth_linz_a = get_linear_depth_at(offcoord_a); + float depth_linz_b = get_linear_depth_at(offcoord_b); + + // Clamp both differences to the maximum depth difference + float diff_a = (pixel_linz - depth_linz_a) / max_depth_diff; + float diff_b = (pixel_linz - depth_linz_b) / max_depth_diff; + + // Compute the line integrals of boths, this is simply the height of the + // line divided by the sphere height. However, we need to substract the + // sphere height once, since we didn't start at the sphere top, but at + // the sphere mid (since we took the depth of point p which is the center + // of the sphere). + float volume_a = (sphere_height - diff_a) / (2.0 * sphere_height); + float volume_b = (sphere_height - diff_b) / (2.0 * sphere_height); + + // Check if the volumes are valid + bool valid_a = diff_a <= sphere_height && diff_a >= -sphere_height; + bool valid_b = diff_b <= sphere_height && diff_b >= -sphere_height; + + // In case either the first or second sample is valid, we can weight them + if (valid_a || valid_b) { + + // Because we use paired samples, we can easily account for discontinuities: + // If a is invalid, we can take the inverse of b as value for a, and vice-versa. + // This works out quite well, even if not mathematically correct. + accum += valid_a ? volume_a : 1 - volume_b; + accum += valid_b ? volume_b : 1 - volume_a; + + // In case both samples are invalid, theres nothing we can do. Just increase + // the integral in this case. + } else { + accum += 1.0; + } + +END_ITERATE_SEQUENCE(); + +NORMALIZE_SEQUENCE(ao, ssvo_sequence, accum); + + +result = accum; diff --git a/rpplugins/ao/shader/ue4ao.kernel.glsl b/rpplugins/ao/shader/ue4ao.kernel.glsl new file mode 100644 index 0000000..49f88f3 --- /dev/null +++ b/rpplugins/ao/shader/ue4ao.kernel.glsl @@ -0,0 +1,95 @@ +/** + * + * RenderPipeline + * + * Copyright (c) 2014-2016 tobspr + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + */ + + + +/* + +UE4AO - Unreal Engine 4 AO + +This is an ambient occlusion technique proposed by Unreal Engine. It is very +similar to Alchemy AO, but uses paired samples to approximate the average +unocluded vector. + +*/ + +const float sample_radius = GET_SETTING(ao, ue4ao_sample_radius); +const float max_distance = GET_SETTING(ao, ue4ao_max_distance); + +float accum = 0.0; +float accum_count = 0.0; + +vec2 offset_scale = pixel_size * sample_radius * kernel_scale * 0.4; + +START_ITERATE_SEQUENCE(ao, ue4ao_sample_sequence, vec2 offset) + + offset = mix(offset, noise_vec.xy, 0.3); + vec2 offcoord = offset * offset_scale; + + // Get offset coordinates + vec2 texc_a = texcoord + offcoord; + vec2 texc_b = texcoord - offcoord; + + // Get view position at that offsets + vec3 off_pos_a = get_view_pos_at(texc_a); + vec3 off_pos_b = get_view_pos_at(texc_b); + + // Get the vector s-p to that sample positions + vec3 sample_vec_a = normalize(off_pos_a - pixel_view_pos); + vec3 sample_vec_b = normalize(off_pos_b - pixel_view_pos); + + // Get distances + float dist_a = distance(off_pos_a, pixel_view_pos) / max_distance; + float dist_b = distance(off_pos_b, pixel_view_pos) / max_distance; + + // Check if the samples are valid + float valid_a = step(dist_a - 1, 0.0); + float valid_b = step(dist_b - 1, 0.0); + + float angle_a = max(0, dot(sample_vec_a, pixel_view_normal)); + float angle_b = max(0, dot(sample_vec_b, pixel_view_normal)); + + // TODO: Avoid branching by every means + if (valid_a != valid_b) { + angle_a = mix(-angle_b, angle_a, valid_a); + angle_b = mix(angle_a, -angle_b, valid_b); + dist_a = mix(dist_b, dist_a, valid_a); + dist_b = mix(dist_a, dist_b, valid_b); + } + + // In case any sample is valid + if (valid_a > 0.5 || valid_b > 0.5) { + accum += (angle_a+angle_b) * 0.25 * (2 - (dist_a+dist_b)); + accum_count += 1.0; + } else { + accum_count += 0.5; + + } + +END_ITERATE_SEQUENCE(); + +accum /= max(1.0, accum_count); +result = 1 - accum; diff --git a/rpplugins/bloom/__init__.py b/rpplugins/bloom/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/rpplugins/bloom/bloom_stage.py b/rpplugins/bloom/bloom_stage.py new file mode 100644 index 0000000..e71a01b --- /dev/null +++ b/rpplugins/bloom/bloom_stage.py @@ -0,0 +1,123 @@ +""" + +RenderPipeline + +Copyright (c) 2014-2016 tobspr + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. + +""" + +from rplibs.six.moves import range # pylint: disable=import-error + +from panda3d.core import SamplerState, Vec4 + +from rpcore.globals import Globals +from rpcore.render_stage import RenderStage +from rpcore.image import Image + + +class BloomStage(RenderStage): + + required_pipes = ["ShadedScene"] + required_inputs = [] + + def __init__(self, pipeline): + RenderStage.__init__(self, pipeline) + self.num_mips = 6 + self.remove_fireflies = False + + @property + def produced_pipes(self): + return {"ShadedScene": self.target_apply.color_tex} + + def create(self): + + if self.remove_fireflies: + self.target_firefly = self.create_target("RemoveFireflies") + self.target_firefly.add_color_attachment(bits=16) + self.target_firefly.prepare_buffer() + + self.scene_target_img = Image.create_2d("BloomDownsample", 0, 0, "RGBA16") + self.scene_target_img.set_minfilter(SamplerState.FT_linear_mipmap_linear) + self.scene_target_img.set_magfilter(SamplerState.FT_linear) + self.scene_target_img.set_wrap_u(SamplerState.WM_clamp) + self.scene_target_img.set_wrap_v(SamplerState.WM_clamp) + self.scene_target_img.set_clear_color(Vec4(0.1, 0.0, 0.0, 1.0)) + self.scene_target_img.clear_image() + + self.target_extract = self.create_target("ExtractBrightSpots") + self.target_extract.prepare_buffer() + self.target_extract.set_shader_input("DestTex", self.scene_target_img, False, True, -1, 0) + + if self.remove_fireflies: + self.target_extract.set_shader_input("ShadedScene", self.target_firefly.color_tex, 1000) + + self.downsample_targets = [] + self.upsample_targets = [] + + # Downsample passes + for i in range(self.num_mips): + scale_multiplier = 2 ** (1 + i) + target = self.create_target("Downsample:Step-" + str(i)) + target.size = -scale_multiplier, -scale_multiplier + target.prepare_buffer() + target.set_shader_inputs( + sourceMip=i, + SourceTex=self.scene_target_img) + target.set_shader_input("DestTex", self.scene_target_img, False, True, -1, i + 1) + self.downsample_targets.append(target) + + # Upsample passes + for i in range(self.num_mips): + scale_multiplier = 2 ** (self.num_mips - i - 1) + target = self.create_target("Upsample:Step-" + str(i)) + target.size = -scale_multiplier, -scale_multiplier + target.prepare_buffer() + target.set_shader_inputs( + FirstUpsamplePass=(i==0), + sourceMip=(self.num_mips - i), + SourceTex=self.scene_target_img) + target.set_shader_input("DestTex", self.scene_target_img, + False, True, -1, self.num_mips - i - 1) + self.upsample_targets.append(target) + + self.target_apply = self.create_target("ApplyBloom") + self.target_apply.add_color_attachment(bits=16) + self.target_apply.prepare_buffer() + self.target_apply.set_shader_input("BloomTex", self.scene_target_img) + + def set_dimensions(self): + self.scene_target_img.set_x_size(Globals.resolution.x) + self.scene_target_img.set_y_size(Globals.resolution.y) + + def reload_shaders(self): + self.target_extract.shader = self.load_plugin_shader("extract_bright_spots.frag.glsl") + + if self.remove_fireflies: + self.target_firefly.shader = self.load_plugin_shader("remove_fireflies.frag.glsl") + self.target_apply.shader = self.load_plugin_shader("apply_bloom.frag.glsl") + + downsample_shader = self.load_plugin_shader("bloom_downsample.frag.glsl") + for target in self.downsample_targets: + target.shader = downsample_shader + + upsample_shader = self.load_plugin_shader("bloom_upsample.frag.glsl") + for target in self.upsample_targets: + target.shader = upsample_shader diff --git a/rpplugins/bloom/config.yaml b/rpplugins/bloom/config.yaml new file mode 100644 index 0000000..2968f30 --- /dev/null +++ b/rpplugins/bloom/config.yaml @@ -0,0 +1,42 @@ + +settings: !!omap + + - num_mipmaps: + type: int + range: [2, 10] + default: 8 + label: Mipmap count + description: > + Amount of mipmaps to use for downsampling the scene. A higher + amount of mipmaps will allow capturing wider blur radii. + + - bloom_strength: + type: float + range: [0.01, 10.0] + default: 1.0 + shader_runtime: true + label: Bloom Strength + description: > + Strength of the bloom, higher values will cause more bloom. Make sure + to not overuse this. + + - remove_fireflies: + type: bool + default: false + label: Remove fireflies + description: > + Attempts to reduce flickering by darkening very small bright spots. + This uses the Karis average to reduce often called "fireflies", which are very + bright pixels, by weighting them by their brightness. + + - lens_dirt_factor: + type: float + range: [0, 1] + default: 0.7 + shader_runtime: true + label: Lens dirt factor + description: > + Amount of lens dirt to blend the bloom with. A value of 0 means + no lens dirt, whereas a value of 1 means very intense lens dirt. + +daytime_settings: diff --git a/rpplugins/bloom/plugin.py b/rpplugins/bloom/plugin.py new file mode 100644 index 0000000..800195e --- /dev/null +++ b/rpplugins/bloom/plugin.py @@ -0,0 +1,48 @@ +""" + +RenderPipeline + +Copyright (c) 2014-2016 tobspr + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. + +""" + +from rpcore.loader import RPLoader +from rpcore.pluginbase.base_plugin import BasePlugin + +from .bloom_stage import BloomStage + + +class Plugin(BasePlugin): + + name = "Bloom" + author = "tobspr " + description = ("This plugin adds support for a technique called Bloom, which " + "makes very bright objects like the sun have a halo.") + version = "1.2" + + def on_stage_setup(self): + self._bloom_stage = self.create_stage(BloomStage) + self._bloom_stage.num_mips = self.get_setting("num_mipmaps") + self._bloom_stage.remove_fireflies = self.get_setting("remove_fireflies") + + def on_pipeline_created(self): + dirt_tex = RPLoader.load_texture(self.get_resource("lens_dirt.txo")) + self._bloom_stage.set_shader_input("LensDirtTex", dirt_tex) diff --git a/rpplugins/bloom/resources/SOURCE.txt b/rpplugins/bloom/resources/SOURCE.txt new file mode 100644 index 0000000..87ba1c2 --- /dev/null +++ b/rpplugins/bloom/resources/SOURCE.txt @@ -0,0 +1,2 @@ +Filter provided by UNIGINE +http://unigine.com/en/articles/procedural-content-generation2 diff --git a/rpplugins/bloom/resources/lens_dirt.ffxml b/rpplugins/bloom/resources/lens_dirt.ffxml new file mode 100644 index 0000000..6a7bedd --- /dev/null +++ b/rpplugins/bloom/resources/lens_dirt.ffxml @@ -0,0 +1,702 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + + + + + + + + + +
+ + + + + + + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + + + + + + + + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/rpplugins/bloom/resources/lens_dirt.png b/rpplugins/bloom/resources/lens_dirt.png new file mode 100644 index 0000000..c0b0528 Binary files /dev/null and b/rpplugins/bloom/resources/lens_dirt.png differ diff --git a/rpplugins/bloom/shader/apply_bloom.frag.glsl b/rpplugins/bloom/shader/apply_bloom.frag.glsl new file mode 100644 index 0000000..8d5382f --- /dev/null +++ b/rpplugins/bloom/shader/apply_bloom.frag.glsl @@ -0,0 +1,53 @@ +/** + * + * RenderPipeline + * + * Copyright (c) 2014-2016 tobspr + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + */ + +#version 430 + +#pragma include "render_pipeline_base.inc.glsl" +#pragma include "includes/color_spaces.inc.glsl" + +uniform sampler2D ShadedScene; +uniform sampler2D BloomTex; +uniform sampler2D LensDirtTex; + +out vec3 result; + +void main() { + vec2 texcoord = get_texcoord(); + + vec3 scene_result = textureLod(ShadedScene, texcoord, 0).xyz; + vec3 bloom_result = textureLod(BloomTex, texcoord, 0).xyz; + + // Apply dirt + vec3 lens_dirt = textureLod(LensDirtTex, texcoord, 0).xyz; + float base_dirt_factor = GET_SETTING(bloom, lens_dirt_factor); + vec3 dirt_factor = pow(lens_dirt, vec3(1.0)); + + bloom_result = mix(bloom_result, bloom_result * dirt_factor, base_dirt_factor); + + // Blend scene color and bloom color + result = scene_result + bloom_result; +} diff --git a/rpplugins/bloom/shader/bloom_downsample.frag.glsl b/rpplugins/bloom/shader/bloom_downsample.frag.glsl new file mode 100644 index 0000000..7466fb0 --- /dev/null +++ b/rpplugins/bloom/shader/bloom_downsample.frag.glsl @@ -0,0 +1,96 @@ +/** + * + * RenderPipeline + * + * Copyright (c) 2014-2016 tobspr + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + */ + +#version 430 + +#pragma include "render_pipeline_base.inc.glsl" + +uniform int sourceMip; +uniform sampler2D SourceTex; +uniform writeonly image2D RESTRICT DestTex; + +void main() { + ivec2 int_coord = ivec2(gl_FragCoord.xy); + vec2 parent_tex_size = vec2(textureSize(SourceTex, sourceMip).xy); + vec2 texel_size = 1.0 / parent_tex_size; + + // Compute the floating point coordinate pointing to the exact center of the + // parent texel center + vec2 flt_coord = vec2(int_coord + 0.5) / parent_tex_size * 2.0; + + // Filter the image, see: + // http://fs5.directupload.net/images/151213/qfnexcls.png + vec3 center_sample = textureLod(SourceTex, flt_coord, sourceMip).xyz; + + // inner samples (marked red) + vec3 sample_r_tl = textureLod( + SourceTex, flt_coord + vec2(-1, 1) * texel_size, sourceMip).xyz; + vec3 sample_r_tr = textureLod( + SourceTex, flt_coord + vec2(1, 1) * texel_size, sourceMip).xyz; + vec3 sample_r_bl = textureLod( + SourceTex, flt_coord + vec2(-1, -1) * texel_size, sourceMip).xyz; + vec3 sample_r_br = textureLod( + SourceTex, flt_coord + vec2(1, -1) * texel_size, sourceMip).xyz; + + // corner samples + vec3 sample_t = textureLod( + SourceTex, flt_coord + vec2(0, 2) * texel_size, sourceMip).xyz; + vec3 sample_r = textureLod( + SourceTex, flt_coord + vec2(2, 0) * texel_size, sourceMip).xyz; + vec3 sample_b = textureLod( + SourceTex, flt_coord + vec2(0, -2) * texel_size, sourceMip).xyz; + vec3 sample_l = textureLod( + SourceTex, flt_coord + vec2(-2, 0) * texel_size, sourceMip).xyz; + + // edge samples + vec3 sample_tl = textureLod( + SourceTex, flt_coord + vec2(-2, 2) * texel_size, sourceMip).xyz; + vec3 sample_tr = textureLod( + SourceTex, flt_coord + vec2(2, 2) * texel_size, sourceMip).xyz; + vec3 sample_bl = textureLod( + SourceTex, flt_coord + vec2(-2, -2) * texel_size, sourceMip).xyz; + vec3 sample_br = textureLod( + SourceTex, flt_coord + vec2(2, -2) * texel_size, sourceMip).xyz; + + vec3 kernel_sum_red = sample_r_tl + sample_r_tr + sample_r_bl + sample_r_br; + vec3 kernel_sum_yellow = sample_tl + sample_t + sample_l + center_sample; + vec3 kernel_sum_green = sample_tr + sample_t + sample_r + center_sample; + vec3 kernel_sum_purple = sample_bl + sample_b + sample_l + center_sample; + vec3 kernel_sum_blue = sample_br + sample_b + sample_r + center_sample; + + vec3 summed_kernel = kernel_sum_red * 0.5 + kernel_sum_yellow * 0.125 + + kernel_sum_green * 0.125 + kernel_sum_purple * 0.125 + + kernel_sum_blue * 0.125; + + // since every sub-kernel has 4 samples, normalize that + summed_kernel /= 4.0; + + // Decay + // summed_kernel *= 0.92; + summed_kernel *= 1.3; + + imageStore(DestTex, ivec2(gl_FragCoord.xy), vec4(summed_kernel, 0)); +} diff --git a/rpplugins/bloom/shader/bloom_upsample.frag.glsl b/rpplugins/bloom/shader/bloom_upsample.frag.glsl new file mode 100644 index 0000000..341b270 --- /dev/null +++ b/rpplugins/bloom/shader/bloom_upsample.frag.glsl @@ -0,0 +1,95 @@ +/** + * + * RenderPipeline + * + * Copyright (c) 2014-2016 tobspr + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + */ + +#version 430 + +#pragma include "render_pipeline_base.inc.glsl" + +uniform int sourceMip; +uniform sampler2D SourceTex; +uniform writeonly image2D RESTRICT DestTex; + +uniform sampler2D ShadedScene; +uniform sampler2D SumTex; + +uniform bool FirstUpsamplePass; + + +void main() { + vec2 source_size = vec2(textureSize(SourceTex, sourceMip).xy); + vec2 texcoord = (ivec2(gl_FragCoord.xy) + 0.5) / (2.0 * source_size); + vec3 summed = textureLod(SourceTex, texcoord, sourceMip + 1).xyz; + + if (FirstUpsamplePass) { + summed = vec3(0); + } + + vec3 mip_color = vec3(1); + + // Hardcoded mipmap colors for now, should make this adjustable at some point + switch(sourceMip) { + case 0: mip_color = vec3(0.214, 0.429, 0.497); break; + case 1: mip_color = vec3(0.964, 0.947, 0.991); break; + case 2: mip_color = vec3(0.982, 0.542, 0.542); break; + case 3: mip_color = vec3(0.301, 0.493, 1.000); break; + case 4: mip_color = vec3(0.456, 0.209, 0.167); break; + } + + // upsample texture + ivec2 coord = ivec2(gl_FragCoord.xy); + + vec2 flt_coord = vec2(coord) / (2.0 * source_size); + vec2 texel_size = 1.0 / source_size; + + vec3 source_sample = textureLod(SourceTex, flt_coord, sourceMip).xyz * 4; + + source_sample += textureLod( + SourceTex, flt_coord + vec2(0, 1) * texel_size, sourceMip).xyz * 2; + source_sample += textureLod( + SourceTex, flt_coord + vec2(0, -1) * texel_size, sourceMip).xyz * 2; + source_sample += textureLod( + SourceTex, flt_coord + vec2(1, 0) * texel_size, sourceMip).xyz * 2; + source_sample += textureLod( + SourceTex, flt_coord + vec2(-1, 0) * texel_size, sourceMip).xyz * 2; + + source_sample += textureLod( + SourceTex, flt_coord + vec2(-1, -1) * texel_size, sourceMip).xyz; + source_sample += textureLod( + SourceTex, flt_coord + vec2(1, -1) * texel_size, sourceMip).xyz; + source_sample += textureLod( + SourceTex, flt_coord + vec2(-1, 1) * texel_size, sourceMip).xyz; + source_sample += textureLod( + SourceTex, flt_coord + vec2(1, 1) * texel_size, sourceMip).xyz; + + source_sample /= 16.0; + source_sample *= mip_color; + + vec3 pass_result = summed + source_sample; + pass_result *= 0.5; + + vec4 old_data = texelFetch(SourceTex, coord, sourceMip - 1); + imageStore(DestTex, coord, old_data + vec4(pass_result, 0)); +} diff --git a/rpplugins/bloom/shader/extract_bright_spots.frag.glsl b/rpplugins/bloom/shader/extract_bright_spots.frag.glsl new file mode 100644 index 0000000..1bbb37c --- /dev/null +++ b/rpplugins/bloom/shader/extract_bright_spots.frag.glsl @@ -0,0 +1,53 @@ +/** + * + * RenderPipeline + * + * Copyright (c) 2014-2016 tobspr + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + */ + +#version 430 + +#pragma include "render_pipeline_base.inc.glsl" +#pragma include "includes/color_spaces.inc.glsl" + +uniform sampler2D ShadedScene; +uniform writeonly image2D RESTRICT DestTex; + +void main() { + vec2 texcoord = get_texcoord(); + ivec2 coord = ivec2(gl_FragCoord.xy); + + vec3 scene_color = textureLod(ShadedScene, texcoord, 0).xyz; + float luma = get_luminance(scene_color); + + // We don't use a threshold for blur, instead we perform the bloom everything, + // which is physically more correct + vec3 bloom_color = scene_color; + bloom_color *= GET_SETTING(bloom, bloom_strength) * 0.005; + bloom_color = clamp(bloom_color, vec3(0), vec3(25000.0)); + + #if DEBUG_MODE + bloom_color *= 0; + #endif + + imageStore(DestTex, coord, vec4(bloom_color, 0)); +} diff --git a/rpplugins/bloom/shader/remove_fireflies.frag.glsl b/rpplugins/bloom/shader/remove_fireflies.frag.glsl new file mode 100644 index 0000000..fdc39be --- /dev/null +++ b/rpplugins/bloom/shader/remove_fireflies.frag.glsl @@ -0,0 +1,70 @@ +/** + * + * RenderPipeline + * + * Copyright (c) 2014-2016 tobspr + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + */ + +#version 430 + +#pragma optionNV (unroll all) +#pragma include "render_pipeline_base.inc.glsl" +#pragma include "includes/gaussian_weights.inc.glsl" +#pragma include "includes/color_spaces.inc.glsl" + +uniform sampler2D ShadedScene; +out vec3 result; + +// Karis average +float get_weight(vec3 color, float weight) { + return weight / (1.0 + get_luminance(color)); +} + +void main() { + + vec2 texcoord = get_texcoord(); + + #if GET_SETTING(bloom, remove_fireflies) + float weights = 0.0; + vec3 accum = vec3(0); + const int filter_size = 2; + + vec2 texel_offs = vec2(1.0) / SCREEN_SIZE; + + // Find all surrounding pixels and weight them + for (int i = -filter_size; i <= filter_size; ++i) { + for (int j = -filter_size; j <= filter_size; ++j) { + vec3 color_sample = textureLod( + ShadedScene, texcoord + vec2(i, j) * texel_offs, 0).xyz; + float weight = get_weight( + color_sample, gaussian_weights_3[abs(i)] * gaussian_weights_3[abs(j)]); + accum += color_sample * weight; + weights += weight; + } + } + + accum /= max(0.01, weights); + result = accum; + #else + result = textureLod(ShadedScene, texcoord, 0).xyz; + #endif +} diff --git a/rpplugins/clouds/__init__.py b/rpplugins/clouds/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/rpplugins/clouds/apply_clouds_stage.py b/rpplugins/clouds/apply_clouds_stage.py new file mode 100644 index 0000000..094d973 --- /dev/null +++ b/rpplugins/clouds/apply_clouds_stage.py @@ -0,0 +1,71 @@ +""" + +RenderPipeline + +Copyright (c) 2014-2016 tobspr + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. + +""" + +from panda3d.core import Vec2 + +from rpcore.render_stage import RenderStage + + +class ApplyCloudsStage(RenderStage): + + """ This stage raymarchs the cloud voxel grid """ + + required_pipes = ["ShadedScene", "GBuffer"] + + def __init__(self, pipeline): + RenderStage.__init__(self, pipeline) + + @property + def produced_pipes(self): + return {"ShadedScene": self.target_apply_clouds.color_tex} + + def create(self): + self.render_target = self.create_target("RaymarchVoxels") + self.render_target.size = -2 + self.render_target.add_color_attachment(bits=16, alpha=True) + self.render_target.prepare_buffer() + + self.upscale_target = self.create_target("UpscaleTarget") + self.upscale_target.add_color_attachment(bits=16, alpha=True) + self.upscale_target.prepare_buffer() + self.upscale_target.set_shader_inputs( + upscaleWeights=Vec2(0.05, 0.2), + SourceTex=self.render_target.color_tex) + + self.target_apply_clouds = self.create_target("MergeWithScene") + self.target_apply_clouds.add_color_attachment(bits=16) + self.target_apply_clouds.prepare_buffer() + + self.target_apply_clouds.set_shader_input( + "CloudsTex", self.upscale_target.color_tex) + + def reload_shaders(self): + self.target_apply_clouds.shader = self.load_plugin_shader( + "apply_clouds.frag.glsl") + self.render_target.shader = self.load_plugin_shader( + "render_clouds.frag.glsl") + self.upscale_target.shader = self.load_plugin_shader( + "/$$rp/shader/bilateral_upscale.frag.glsl") diff --git a/rpplugins/clouds/cloud_voxel_stage.py b/rpplugins/clouds/cloud_voxel_stage.py new file mode 100644 index 0000000..2e1dab9 --- /dev/null +++ b/rpplugins/clouds/cloud_voxel_stage.py @@ -0,0 +1,86 @@ +""" + +RenderPipeline + +Copyright (c) 2014-2016 tobspr + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. + +""" + +from panda3d.core import SamplerState, Vec4 + +from rpcore.render_stage import RenderStage +from rpcore.image import Image + + +class CloudVoxelStage(RenderStage): + + """ This stage generates the volumetric cloud voxel grid """ + + required_pipes = ["ScatteringIBLDiffuse"] + + def __init__(self, pipeline): + RenderStage.__init__(self, pipeline) + self._voxel_res_xy = 256 + self._voxel_res_z = 32 + + @property + def produced_pipes(self): + return {"CloudVoxels": self._cloud_voxels} + + @property + def produced_defines(self): + return { + "CLOUD_RES_XY": self._voxel_res_xy, + "CLOUD_RES_Z": self._voxel_res_z + } + + def create(self): + # Construct the voxel texture + self._cloud_voxels = Image.create_3d( + "CloudVoxels", self._voxel_res_xy, self._voxel_res_xy, self._voxel_res_z, "RGBA8") + self._cloud_voxels.set_wrap_u(SamplerState.WM_repeat) + self._cloud_voxels.set_wrap_v(SamplerState.WM_repeat) + self._cloud_voxels.set_wrap_w(SamplerState.WM_border_color) + self._cloud_voxels.set_border_color(Vec4(0, 0, 0, 0)) + + # Construct the target which populates the voxel texture + self._grid_target = self.create_target("CreateVoxels") + self._grid_target.size = self._voxel_res_xy, self._voxel_res_xy + self._grid_target.prepare_buffer() + self._grid_target.quad.set_instance_count(self._voxel_res_z) + self._grid_target.set_shader_input("CloudVoxels", self._cloud_voxels) + + # Construct the target which shades the voxels + self._shade_target = self.create_target("ShadeVoxels") + self._shade_target.size = self._voxel_res_xy, self._voxel_res_xy + self._shade_target.prepare_buffer() + self._shade_target.quad.set_instance_count(self._voxel_res_z) + self._shade_target.set_shader_inputs( + CloudVoxels=self._cloud_voxels, + CloudVoxelsDest=self._cloud_voxels) + + def reload_shaders(self): + self._grid_target.shader = self.load_plugin_shader( + "/$$rp/shader/default_post_process_instanced.vert.glsl", + "generate_clouds.frag.glsl") + self._shade_target.shader = self.load_plugin_shader( + "/$$rp/shader/default_post_process_instanced.vert.glsl", + "shade_clouds.frag.glsl") diff --git a/rpplugins/clouds/config.yaml b/rpplugins/clouds/config.yaml new file mode 100644 index 0000000..0b26c76 --- /dev/null +++ b/rpplugins/clouds/config.yaml @@ -0,0 +1,35 @@ + +settings: !!omap + + # - cloud_decay: + # type: float + # range: [0.0, 10.0] + # default: 3.0 + # label: Cloud Decay + # description: > + # Controls how the cloud intensity decays to the top. + # shader_runtime: true + + - raymarch_steps: + type: int + range: [16, 256] + default: 160 + label: Raymarch Steps + shader_runtime: true + description: > + Controls how many steps should be taken through the cloud voxel grid + to integrate the cloud density. Higher values produce more accurate + result but also require more performance. + +daytime_settings: !!omap + + - cloud_brightness: + type: scalar + unit: percent + range: [0, 2] + default: 1.0 + logarithmic_factor: 2.0 + label: Cloud brightness + description: > + Brightness of all cloud layers, controlls how bright the clouds are. + A value of zero causes no clouds. diff --git a/rpplugins/clouds/plugin.py b/rpplugins/clouds/plugin.py new file mode 100644 index 0000000..944ba6c --- /dev/null +++ b/rpplugins/clouds/plugin.py @@ -0,0 +1,73 @@ +""" + +RenderPipeline + +Copyright (c) 2014-2016 tobspr + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. + +""" + +from panda3d.core import SamplerState + +from rpcore.loader import RPLoader +from rpcore.pluginbase.base_plugin import BasePlugin + +from .apply_clouds_stage import ApplyCloudsStage + +# Dynamic cloud generation is disabled for now +# from .cloud_voxel_stage import CloudVoxelStage + + +class Plugin(BasePlugin): + + name = "Volumetric Clouds" + author = "tobspr " + description = ("This Plugin adds support or volumetric, raytraced clouds. " + "Right now this is pretty unoptimized and may consum a lot " + "of performance.") + version = "alpha (!)" + required_plugins = ("scattering",) + + def on_stage_setup(self): + # self.generation_stage = self.create_stage(CloudVoxelStage) + self.apply_stage = self.create_stage(ApplyCloudsStage) + + def on_pipeline_created(self): + # High-res noise + noise1 = RPLoader.load_texture(self.get_resource("noise1-data.txo")) + noise1.set_wrap_u(SamplerState.WM_repeat) + noise1.set_wrap_v(SamplerState.WM_repeat) + noise1.set_wrap_w(SamplerState.WM_repeat) + noise1.set_minfilter(SamplerState.FT_linear_mipmap_linear) + self.apply_stage.set_shader_input("Noise1", noise1) + + # Low-res noise + noise2 = RPLoader.load_texture(self.get_resource("noise2-data.txo")) + noise2.set_wrap_u(SamplerState.WM_repeat) + noise2.set_wrap_v(SamplerState.WM_repeat) + noise2.set_wrap_w(SamplerState.WM_repeat) + noise2.set_minfilter(SamplerState.FT_linear_mipmap_linear) + self.apply_stage.set_shader_input("Noise2", noise2) + + # Weather tex + weather = RPLoader.load_texture(self.get_resource("weather_tex.png")) + weather.set_wrap_u(SamplerState.WM_repeat) + weather.set_wrap_v(SamplerState.WM_repeat) + self.apply_stage.set_shader_input("WeatherTex", weather) diff --git a/rpplugins/clouds/resources/generate_noise1.compute.glsl b/rpplugins/clouds/resources/generate_noise1.compute.glsl new file mode 100644 index 0000000..336c4db --- /dev/null +++ b/rpplugins/clouds/resources/generate_noise1.compute.glsl @@ -0,0 +1,58 @@ +/** + * + * RenderPipeline + * + * Copyright (c) 2014-2016 tobspr + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + */ + +#version 430 + +// Shader to generate the cloud noise textures + +layout (local_size_x = 8, local_size_y = 8, local_size_z = 4) in; +uniform writeonly image3D DestTex; + +const int tex_size = 128; + +#pragma include "noise.inc.glsl" + +void main() { + ivec3 coord = ivec3(gl_GlobalInvocationID.xyz); + vec3 flt_coord = coord / float(tex_size); + float fbm0 = fbm(flt_coord * 5); + + float worley = fbm_worley(flt_coord, 8, 0.7, 2, 0.2723424); + + float OldMin = -1.0; + float OldMax = 1.0; + float NewMin = worley * 0.5; + float NewMax = 1.0; + + float combined = NewMin + (((fbm0 - OldMin) / (OldMax - OldMin)) * (NewMax - NewMin)); + fbm0 = combined; + + float worley1 = sqrt(fbm_worley(flt_coord, 8, 0.6, 4, 0.164354)) * 1.0; + float worley2 = sqrt(fbm_worley(flt_coord, 16, 0.6, 3, 0.19123)) * 1.0; + float worley3 = sqrt(fbm_worley(flt_coord, 32, 0.4, 2, 0.2613)) * 1.0; + + imageStore(DestTex, coord, vec4(fbm0, worley1, worley2, worley3)); +} diff --git a/rpplugins/clouds/resources/generate_noise2.compute.glsl b/rpplugins/clouds/resources/generate_noise2.compute.glsl new file mode 100644 index 0000000..db5c1eb --- /dev/null +++ b/rpplugins/clouds/resources/generate_noise2.compute.glsl @@ -0,0 +1,48 @@ +/** + * + * RenderPipeline + * + * Copyright (c) 2014-2016 tobspr + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + */ + +#version 430 + +// Shader to generate the cloud noise textures + +layout (local_size_x = 8, local_size_y = 8, local_size_z = 4) in; +uniform writeonly image3D DestTex; + +const int tex_size = 32; + +#pragma include "noise.inc.glsl" + +void main() { + ivec3 coord = ivec3(gl_GlobalInvocationID.xyz); + vec3 flt_coord = coord / float(tex_size); + + float worley1 = sqrt(fbm_worley(flt_coord, 8, 0.6, 3, 0.76632)) * 1.0; + float worley2 = sqrt(fbm_worley(flt_coord, 8, 0.4, 3, 0.26386)) * 1.0; + float worley3 = sqrt(fbm_worley(flt_coord, 16, 0.4, 2, 0.64243)) * 1.0; + + // imageStore(DestTex, coord, vec4(worley1, worley2, worley3, 1)); + imageStore(DestTex, coord, vec4(worley1, worley2, worley3, 1)); +} diff --git a/rpplugins/clouds/resources/noise.inc.glsl b/rpplugins/clouds/resources/noise.inc.glsl new file mode 100644 index 0000000..f5fb255 --- /dev/null +++ b/rpplugins/clouds/resources/noise.inc.glsl @@ -0,0 +1,171 @@ + +// lint: skip-file + +vec3 mod289(vec3 x) { + return x - floor(x * (1.0 / 289.0)) * 289.0; +} + +vec4 mod289(vec4 x) { + return x - floor(x * (1.0 / 289.0)) * 289.0; +} + +vec4 permute(vec4 x) { + return mod289(((x*34.0)+1.0)*x); +} + +vec4 taylorInvSqrt(vec4 r) +{ + return 1.79284291400159 - 0.85373472095314 * r; +} + +vec3 fade(vec3 t) { + return t*t*t*(t*(t*6.0-15.0)+10.0); +} + + + +// Classic Perlin noise, periodic variant +float pnoise3D(vec3 P, vec3 rep) +{ + vec3 Pi0 = mod(floor(P), rep); // Integer part, modulo period + vec3 Pi1 = mod(Pi0 + vec3(1.0), rep); // Integer part + 1, mod period + Pi0 = mod289(Pi0); + Pi1 = mod289(Pi1); + vec3 Pf0 = fract(P); // Fractional part for interpolation + vec3 Pf1 = Pf0 - vec3(1.0); // Fractional part - 1.0 + vec4 ix = vec4(Pi0.x, Pi1.x, Pi0.x, Pi1.x); + vec4 iy = vec4(Pi0.yy, Pi1.yy); + vec4 iz0 = Pi0.zzzz; + vec4 iz1 = Pi1.zzzz; + + vec4 ixy = permute(permute(ix) + iy); + vec4 ixy0 = permute(ixy + iz0); + vec4 ixy1 = permute(ixy + iz1); + + vec4 gx0 = ixy0 * (1.0 / 7.0); + vec4 gy0 = fract(floor(gx0) * (1.0 / 7.0)) - 0.5; + gx0 = fract(gx0); + vec4 gz0 = vec4(0.5) - abs(gx0) - abs(gy0); + vec4 sz0 = step(gz0, vec4(0.0)); + gx0 -= sz0 * (step(0.0, gx0) - 0.5); + gy0 -= sz0 * (step(0.0, gy0) - 0.5); + + vec4 gx1 = ixy1 * (1.0 / 7.0); + vec4 gy1 = fract(floor(gx1) * (1.0 / 7.0)) - 0.5; + gx1 = fract(gx1); + vec4 gz1 = vec4(0.5) - abs(gx1) - abs(gy1); + vec4 sz1 = step(gz1, vec4(0.0)); + gx1 -= sz1 * (step(0.0, gx1) - 0.5); + gy1 -= sz1 * (step(0.0, gy1) - 0.5); + + vec3 g000 = vec3(gx0.x,gy0.x,gz0.x); + vec3 g100 = vec3(gx0.y,gy0.y,gz0.y); + vec3 g010 = vec3(gx0.z,gy0.z,gz0.z); + vec3 g110 = vec3(gx0.w,gy0.w,gz0.w); + vec3 g001 = vec3(gx1.x,gy1.x,gz1.x); + vec3 g101 = vec3(gx1.y,gy1.y,gz1.y); + vec3 g011 = vec3(gx1.z,gy1.z,gz1.z); + vec3 g111 = vec3(gx1.w,gy1.w,gz1.w); + + vec4 norm0 = taylorInvSqrt(vec4(dot(g000, g000), dot(g010, g010), dot(g100, g100), dot(g110, g110))); + g000 *= norm0.x; + g010 *= norm0.y; + g100 *= norm0.z; + g110 *= norm0.w; + vec4 norm1 = taylorInvSqrt(vec4(dot(g001, g001), dot(g011, g011), dot(g101, g101), dot(g111, g111))); + g001 *= norm1.x; + g011 *= norm1.y; + g101 *= norm1.z; + g111 *= norm1.w; + + float n000 = dot(g000, Pf0); + float n100 = dot(g100, vec3(Pf1.x, Pf0.yz)); + float n010 = dot(g010, vec3(Pf0.x, Pf1.y, Pf0.z)); + float n110 = dot(g110, vec3(Pf1.xy, Pf0.z)); + float n001 = dot(g001, vec3(Pf0.xy, Pf1.z)); + float n101 = dot(g101, vec3(Pf1.x, Pf0.y, Pf1.z)); + float n011 = dot(g011, vec3(Pf0.x, Pf1.yz)); + float n111 = dot(g111, Pf1); + + vec3 fade_xyz = fade(Pf0); + vec4 n_z = mix(vec4(n000, n100, n010, n110), vec4(n001, n101, n011, n111), fade_xyz.z); + vec2 n_yz = mix(n_z.xy, n_z.zw, fade_xyz.y); + float n_xyz = mix(n_yz.x, n_yz.y, fade_xyz.x); + return 2.2 * n_xyz; +} + + +float fbm(vec3 x) { + float v = 0.0; + float a = 0.5; + vec3 shift = vec3(0.954653); + float tile = 5.0; + for (int i = 0; i < 6; ++i) { + v += a * pnoise3D(x, vec3(tile)); + x = x * 2.0 + shift; + a *= 0.5; + tile *= 2.0; + } + return v; +} + +float rand(vec2 co){ + return abs(fract(sin(dot(co.xy ,vec2(12.9898,78.233))) * 43758.5453)) * 2 - 1; +} + + +// Returns the point in a given cell +vec3 worley_cell_point(ivec3 cell, int num_cells, float drop_rate, float seed) { + cell = cell % num_cells; + vec3 cell_base = vec3(cell) / num_cells; + float noise_x = rand(cell_base.xy + seed); + float noise_y = rand(cell_base.yx + seed); + float noise_z = rand(cell_base.zx + cell_base.yy + seed); + float drop_point = step(rand(cell.xy + cell.yx + cell.zx + cell.zz + seed) + 1e-7, drop_rate); + return cell_base + (0.5 + 1.0 * vec3(noise_x, noise_y, noise_z)) / num_cells + drop_point * vec3(1e9); +} + + +// Distance accross borders +float distance_border(vec3 a, vec3 b) { + float dx = min( abs(a.x - b.x), min(abs( a.x - 1.0 - b.x), abs(a.x + 1.0 - b.x))); + float dy = min( abs(a.y - b.y), min(abs( a.y - 1.0 - b.y), abs(a.y + 1.0 - b.y))); + float dz = min( abs(a.z - b.z), min(abs( a.z - 1.0 - b.z), abs(a.z + 1.0 - b.z))); + return length(vec3(dx, dy, dz)); +} + +// Performs worley noise by checking all adjacent cells +// and comparing the distance to their points +float worley_noise(vec3 coord, int num_cells, float drop_rate, float seed) { + coord = fract(coord); + ivec3 cell = ivec3(coord * num_cells); + float dist = 1.0; + + // Search in the surrounding 5x5 cell block + for (int x = 0; x < 5; x++) { + for (int y = 0; y < 5; y++) { + for (int z = 0; z < 5; z++) { + vec3 cell_point = worley_cell_point(cell + ivec3(x-2, y-2, z-2), num_cells, drop_rate, seed); + dist = min(dist, distance_border(cell_point, coord)); + } + } + } + dist /= length(vec3(1.0 / num_cells)); + dist = clamp(1.0 - dist, 0.0, 1.0); + return dist; +} + + +float fbm_worley(vec3 x, int num_tiles, float drop_rate, int octaves, float seed) { + seed *= 0.05; + float v = 0.0; + float a = 0.5; + vec3 shift = vec3(0.354653); + for (int i = 0; i < octaves; ++i) { + v += a * worley_noise(x, num_tiles, drop_rate, seed); + x = x * 2.0 + shift; + a *= 0.5; + // num_tiles = int(num_tiles * 1.5); + } + return v; +} diff --git a/rpplugins/clouds/resources/precompute.py b/rpplugins/clouds/resources/precompute.py new file mode 100644 index 0000000..afca20f --- /dev/null +++ b/rpplugins/clouds/resources/precompute.py @@ -0,0 +1,89 @@ +""" + +RenderPipeline + +Copyright (c) 2014-2016 tobspr + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. + +""" + +from __future__ import print_function, division + +import os +from os.path import dirname, realpath +from panda3d.core import * # noqa +from direct.showbase.ShowBase import ShowBase + + +class Application(ShowBase): + def __init__(self): + load_prc_file_data("", """ + textures-power-2 none + window-type offscreen + win-size 100 100 + gl-coordinate-system default + notify-level-display error + print-pipe-types #f + gl-version 4 3 + """) + + ShowBase.__init__(self) + + base_path = realpath(dirname(__file__)) + os.chdir(base_path) + + node = NodePath("") + w, h, d = 128, 128, 128 + + # High-Res 128^3 texture + print("Computing high-res noise") + voxel_grid = Texture("voxels") + voxel_grid.setup_3d_texture(w, h, d, Texture.T_unsigned_byte, Texture.F_rgba8) + cshader = Shader.load_compute(Shader.SL_GLSL, "generate_noise1.compute.glsl") + node.set_shader(cshader) + node.set_shader_input("DestTex", voxel_grid) + attr = node.get_attrib(ShaderAttrib) + self.graphicsEngine.dispatch_compute( + ((w + 7) // 8, (h + 7) // 8, (d + 3) // 4), attr, self.win.gsg) + self.graphicsEngine.extract_texture_data(voxel_grid, self.win.gsg) + + print("Writing data ..") + # voxel_grid.write(Filename.from_os_specific(join("result/", "#.png")), 0, 0, True, False) + voxel_grid.write("noise1-data.txo.pz") + + # Low-Res 32^3 texture + print("Computing low-res noise") + w, h, d = 32, 32, 32 + voxel_grid = Texture("voxels") + voxel_grid.setup_3d_texture(w, h, d, Texture.T_unsigned_byte, Texture.F_rgba8) + cshader = Shader.load_compute(Shader.SL_GLSL, "generate_noise2.compute.glsl") + node.set_shader(cshader) + node.set_shader_input("DestTex", voxel_grid) + attr = node.get_attrib(ShaderAttrib) + self.graphicsEngine.dispatch_compute( + ((w + 7) // 8, (h + 7) // 8, (d + 3) // 4), attr, self.win.gsg) + self.graphicsEngine.extract_texture_data(voxel_grid, self.win.gsg) + + print("Writing data ..") + # voxel_grid.write(Filename.from_os_specific(join("result2/", "#.png")), 0, 0, True, False) + voxel_grid.write("noise2-data.txo.pz") + + +Application() diff --git a/rpplugins/clouds/resources/weather_tex.png b/rpplugins/clouds/resources/weather_tex.png new file mode 100644 index 0000000..888c9e4 Binary files /dev/null and b/rpplugins/clouds/resources/weather_tex.png differ diff --git a/rpplugins/clouds/shader/apply_clouds.frag.glsl b/rpplugins/clouds/shader/apply_clouds.frag.glsl new file mode 100644 index 0000000..e64983c --- /dev/null +++ b/rpplugins/clouds/shader/apply_clouds.frag.glsl @@ -0,0 +1,47 @@ +/** + * + * RenderPipeline + * + * Copyright (c) 2014-2016 tobspr + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + */ + +#version 430 + +#pragma include "render_pipeline_base.inc.glsl" + +uniform sampler2D CloudsTex; +uniform sampler2D ShadedScene; +out vec4 result; + +void main() { + vec2 texcoord = get_texcoord(); + vec4 scene_color = textureLod(ShadedScene, texcoord, 0); + vec4 cloud_color = textureLod(CloudsTex, texcoord, 0); + + #if !DEBUG_MODE + result = scene_color * (1 - cloud_color.w) + cloud_color; + #else + result = scene_color; + #endif + + result.w = scene_color.w; +} diff --git a/rpplugins/clouds/shader/render_clouds.frag.glsl b/rpplugins/clouds/shader/render_clouds.frag.glsl new file mode 100644 index 0000000..e2e4665 --- /dev/null +++ b/rpplugins/clouds/shader/render_clouds.frag.glsl @@ -0,0 +1,224 @@ +/** + * + * RenderPipeline + * + * Copyright (c) 2014-2016 tobspr + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + */ + +#version 430 + +// Renders the clouds +// WORK IN PROGRESS - This shader is unfinished and not cleaned up yet. + +#define USE_TIME_OF_DAY 1 +#pragma include "render_pipeline_base.inc.glsl" + +#define USE_GBUFFER_EXTENSIONS +#pragma include "includes/gbuffer.inc.glsl" +#pragma include "includes/light_culling.inc.glsl" +#pragma include "includes/noise.inc.glsl" + +uniform sampler3D Noise1; +uniform sampler3D Noise2; +uniform sampler2D WeatherTex; + +out vec4 result; + +const float KM = 1000.0; +const float METER = 1.0; + +const float earth_radius = 6371.0 * KM; +const vec3 earth_mid = vec3(0, 0, -earth_radius); +const float cloud_start = earth_radius + 1.3 * KM; +const float cloud_end = earth_radius + 25.0 * KM; + + +float GetHeightFractionForPoint(vec3 inPosition, vec2 inCloudMinMax) +{ + float height_fraction = (inPosition.z - inCloudMinMax.x) / (inCloudMinMax.y - inCloudMinMax.x); + return saturate(height_fraction); +} + +float GetDensityHeightGradientForPoint(vec3 p, vec3 weatherData) { + // return saturate(20.0 * (1.0 - max(0, p.z / 0.3)) ); // XXX + // return p.z > 0.1 ? 0.0 : 1.0; + // return pow(p.z, 0.3); + return 1.0; +} + +float SampleCloudDensity(vec3 p, vec3 weather_data, float mip_level) +{ + + // float3 wind_direction = float3 (1.0 , 0.0 , 0.0) ; + // float cloud_speed = 10.0; + // float cloud_top_offset = 500.0; + // p += height_fraction * wind_direction * cloud_top_offset; + + vec4 low_frequency_noises = textureLod(Noise1, p * 0.6, mip_level); + float low_freq_FBM = (low_frequency_noises.g * 0.625) + + (low_frequency_noises.b * 0.25) + + (low_frequency_noises.a * 0.125); + + float base_cloud = max(0, square(low_frequency_noises.x * low_frequency_noises.y) - 0.07) ; + // base_cloud = pow(base_cloud, 10.0) * 10.0; + + // base_cloud *= max(0, low_frequency_noises.w * 1.4 - 0.2); + // base_cloud *= max(0, low_frequency_noises.z * 1.5 - 0.2); + + float density_height_gradient = GetDensityHeightGradientForPoint(p, weather_data); + base_cloud *= density_height_gradient; + + float cloud_coverage = weather_data.r; + + // base_cloud *= cloud_coverage; + + vec3 high_frequency_noises = textureLod(Noise2, p * 5.63534, mip_level).rgb; + + // float high_freq_FBM = (high_frequency_noises.r * 0.625); + // + (high_frequency_noises.g * 0.25) + // + (high_frequency_noises.b * 0.125); + + // base_cloud = mix(high_frequency_noises.y * base_cloud, 1, base_cloud); + + base_cloud -= high_frequency_noises.y * 0.23 * (1 - base_cloud); + // base_cloud *= 3.0; + base_cloud *= 125.0 * 256.0 / GET_SETTING(clouds, raymarch_steps); + + return saturate(base_cloud); +} + + +vec2 get_cloud_coord(vec3 pos) { + vec2 xy_coord = pos.xy / (cloud_end - cloud_start); + xy_coord.xy /= 1.0 + 0.1 * length(xy_coord); + // xy_coord.xy += 0.5; + // xy_coord *= 0.5; + return xy_coord; +} + +float HenyeyGreenstein(vec3 inLightVector, vec3 inViewVector, float inG) +{ + float cos_angle = dot(normalize(inLightVector), normalize(inViewVector)); + return ((1.0 - inG * inG) / pow((1.0 + inG * inG - 2.0 * inG * cos_angle), + 3.0 / 2.0)) / 4.0 * M_PI; +} + +void main() { + int num_samples = GET_SETTING(clouds, raymarch_steps); + // int num_samples = 256; + + vec2 texcoord = get_half_texcoord(); + vec3 wind_offs = vec3(0.2, 0.3, 0) * 0.052 * MainSceneData.frame_time; + + vec3 pos = get_gbuffer_position(GBuffer, texcoord); + vec3 ray_start = MainSceneData.camera_pos; + vec3 ray_dir = normalize(pos - ray_start); + + vec3 view_vector = normalize(MainSceneData.camera_pos - pos); + + if (!is_skybox(pos) || ray_dir.z < 0.0) { + result = vec4(0); + return; + } + + float t_low, t_high, tmp; + + Sphere earth_sphere; + earth_sphere.pos = earth_mid; + earth_sphere.radius = cloud_start; + bool rb = ray_sphere_intersection(earth_sphere, ray_start, ray_dir, t_low, tmp); + earth_sphere.radius = cloud_end; + bool rt = ray_sphere_intersection(earth_sphere, ray_start, ray_dir, t_high, tmp); + + if (t_low < 0.0) t_low = 0.0; + if (t_high < 0.0 || distance(t_high, t_low) < 0.01) { + result = vec4(0.2, 0, 0, 0); + return; + } + + // Get start and end in cloud space coordinates + vec3 trace_start = vec3(get_cloud_coord(ray_start + t_low * ray_dir), 0.0); + vec3 trace_end = vec3(get_cloud_coord(ray_start + t_high * ray_dir), 1.0); + trace_start += wind_offs; + trace_end += wind_offs; + + // trace_start.xyz += (noise*2.0-1.0) * 0.004; + vec3 trace_step = (trace_end - trace_start) / float(num_samples); + // trace_step.xyz += (noise*2.0-1.0) * 0.015 / num_samples; + + float density = 0.0; + float cloud_test = 0.0; + int zero_density_sample_count = 0; + float mip_level = 0; + + float jitter = abs(rand(ivec2(gl_FragCoord.xy))); + + vec3 p = trace_start + (1 + jitter) * trace_step; + + vec3 accum_color = vec3(0); + + vec3 sun_vector = get_sun_vector(); + + vec3 weather_data = texture(WeatherTex, p.xy).xyz; + for (int i = 0; i < num_samples - 1; ++i) + { + float sampled_density = SampleCloudDensity(p, weather_data, mip_level) * 0.2; + float sampled_sun_density = 0.0; + for (int k = 1; k < 3; ++k) { + sampled_sun_density += SampleCloudDensity( + p + sun_vector * 1.0 / 256.0 * k * k, weather_data, mip_level); + } + sampled_density *= (1 - density); + density += sampled_density; + accum_color += ((0.05 + 0.99 * p.z * p.z) * sampled_density * + (1.0 - sampled_sun_density / 3.0)); + + p += trace_step; + } + + float accum_weight = density; + + float light_samples = density * 1.0; + + float powder_sugar_effect = 1.0 - exp(- light_samples * 2.0); + float beers_law = exp(-light_samples); + float light_energy = 2.0 * beers_law * powder_sugar_effect; + + accum_color *= light_energy * 2.0; + accum_color *= vec3(HenyeyGreenstein(sun_vector, -view_vector, 0.2)) * 1.0; + + float sun_influence = pow(max(0, dot(ray_dir, sun_vector)), 25.0) + 0.0; + vec3 sun_color = sun_influence * 100.0 * TimeOfDay.scattering.sun_color; + + accum_color *= 1.0 + sun_color * max(0, 1 - 0.7 * density); + accum_color *= TimeOfDay.clouds.cloud_brightness * 20.0 * vec3(10, 10, 15); + accum_color *= TimeOfDay.scattering.sun_intensity / 150.0; + accum_color *= TimeOfDay.scattering.sun_color; + + + // Don't render clouds at obligue angles + float horizon = pow(saturate(ray_dir.z * 1.0), 0.1); + accum_color *= horizon; + accum_weight *= horizon; + + result = vec4(accum_color, accum_weight); +} diff --git a/rpplugins/color_correction/__init__.py b/rpplugins/color_correction/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/rpplugins/color_correction/auto_exposure_stage.py b/rpplugins/color_correction/auto_exposure_stage.py new file mode 100644 index 0000000..bd116c9 --- /dev/null +++ b/rpplugins/color_correction/auto_exposure_stage.py @@ -0,0 +1,114 @@ +""" + +RenderPipeline + +Copyright (c) 2014-2016 tobspr + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. + +""" + +from __future__ import division +from panda3d.core import Vec4 + +from rpcore.render_stage import RenderStage +from rpcore.globals import Globals +from rpcore.image import Image + + +class AutoExposureStage(RenderStage): + + required_pipes = ["ShadedScene"] + required_inputs = [] + + @property + def produced_pipes(self): + return {"ShadedScene": self.target_apply.color_tex, + "Exposure": self.tex_exposure} + + def create(self): + + # Create the target which converts the scene color to a luminance + self.target_lum = self.create_target("GetLuminance") + self.target_lum.size = -4 + self.target_lum.add_color_attachment(bits=(16, 0, 0, 0)) + self.target_lum.prepare_buffer() + + self.mip_targets = [] + + # Create the storage for the exposure, this stores the current and last + # frames exposure + # XXX: We have to use F_r16 instead of F_r32 because of a weird nvidia + # driver bug! However, 16 bits should be enough for sure. + self.tex_exposure = Image.create_buffer("ExposureStorage", 1, "R16") + self.tex_exposure.set_clear_color(Vec4(0.5)) + self.tex_exposure.clear_image() + + # Create the target which extracts the exposure from the average brightness + self.target_analyze = self.create_target("AnalyzeBrightness") + self.target_analyze.size = 1, 1 + self.target_analyze.prepare_buffer() + + self.target_analyze.set_shader_input("ExposureStorage", self.tex_exposure) + + # Create the target which applies the generated exposure to the scene + self.target_apply = self.create_target("ApplyExposure") + self.target_apply.add_color_attachment(bits=16) + self.target_apply.prepare_buffer() + self.target_apply.set_shader_input("Exposure", self.tex_exposure) + + def set_dimensions(self): + for old_target in self.mip_targets: + self.remove_target(old_target) + + wsize_x = (Globals.resolution.x + 3) // 4 + wsize_y = (Globals.resolution.y + 3) // 4 + + # Create the targets which downscale the luminance mipmaps + self.mip_targets = [] + last_tex = self.target_lum.color_tex + while wsize_x >= 4 or wsize_y >= 4: + wsize_x = (wsize_x + 3) // 4 + wsize_y = (wsize_y + 3) // 4 + + mip_target = self.create_target("DScaleLum:S" + str(wsize_x)) + mip_target.add_color_attachment(bits=(16, 0, 0, 0)) + mip_target.size = wsize_x, wsize_y + mip_target.sort = self.target_lum.sort + len(self.mip_targets) + mip_target.prepare_buffer() + mip_target.set_shader_input("SourceTex", last_tex) + self.mip_targets.append(mip_target) + last_tex = mip_target.color_tex + + self.target_analyze.set_shader_input("DownscaledTex", self.mip_targets[-1].color_tex) + + # Shaders might not have been loaded at this point + if hasattr(self, "mip_shader"): + for target in self.mip_targets: + target.shader = self.mip_shader + + def reload_shaders(self): + self.target_lum.shader = self.load_plugin_shader("generate_luminance.frag.glsl") + self.target_analyze.shader = self.load_plugin_shader("analyze_brightness.frag.glsl") + self.target_apply.shader = self.load_plugin_shader("apply_exposure.frag.glsl") + + # Keep shader as reference, required when resizing + self.mip_shader = self.load_plugin_shader("downscale_luminance.frag.glsl") + for target in self.mip_targets: + target.shader = self.mip_shader diff --git a/rpplugins/color_correction/color_correction_stage.py b/rpplugins/color_correction/color_correction_stage.py new file mode 100644 index 0000000..3468843 --- /dev/null +++ b/rpplugins/color_correction/color_correction_stage.py @@ -0,0 +1,45 @@ +""" + +RenderPipeline + +Copyright (c) 2014-2016 tobspr + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. + +""" + +from rpcore.render_stage import RenderStage + + +class ColorCorrectionStage(RenderStage): + + required_inputs = [] + required_pipes = ["ShadedScene"] + + @property + def produced_pipes(self): + return {"ShadedScene": self.target.color_tex} + + def create(self): + self.target = self.create_target("PostFX") + self.target.add_color_attachment(bits=16) + self.target.prepare_buffer() + + def reload_shaders(self): + self.target.shader = self.load_plugin_shader("post_fx.frag.glsl") diff --git a/rpplugins/color_correction/config.yaml b/rpplugins/color_correction/config.yaml new file mode 100644 index 0000000..64aeb7a --- /dev/null +++ b/rpplugins/color_correction/config.yaml @@ -0,0 +1,333 @@ + +name: Color Correction +author: tobspr +version: 1.0 +description: > + This plugin adds support for color correction, vignetting and chromatic + abberation. + +settings: !!omap + + - tonemap_operator: + type: enum + values: [optimized, reinhard, uncharted2, exponential, exponential2, none] + default: uncharted2 + label: Tonemap Operator + shader_runtime: true + description: > + This specifies the tonemapping operator, all operators implement + sRGB color correction as well, except for the none operator which + just passes through the color. None is just for reference, + and should not be used. + + # Reinhard Tonemapping settings + + - reinhard_version: + display_if: {tonemap_operator: "reinhard"} + type: enum + values: [rgb, luminance, white_preserve, luminosity] + default: rgb + shader_runtime: true + label: Reinhard Version + description: > + Choose between different versions of the Reinhard Operator. rgb performs + the operator on the rgb value, luminance on the brightness of the color. + white_preserve also uses the luma value, but tries to preserve the whites. + + # Exponential Tonemapping settings + + - exponential_factor: + display_if: {tonemap_operator: "exponential"} + type: float + range: [0.01, 5.0] + default: 1.0 + shader_runtime: true + label: Exponential factor + description: > + The factor for the exponential mapping. Assuming the factor is named + f, then the output color is computed with 1 - exp(-f*color). + + + # Uncharted 2 Tonemapping settings + + - uc2t_shoulder_strength: + display_if: {tonemap_operator: "uncharted2"} + type: float + range: [0.01, 1.0] + default: 0.22 + shader_runtime: true + label: UC2 Shoulder Strength + description: > + Shoulder Strength, controls the appearance of the bright parts + of the image (the last part of the color curve). + + - uc2t_linear_strength: + display_if: {tonemap_operator: "uncharted2"} + type: float + range: [0.01, 1.0] + default: 0.3 + shader_runtime: true + label: UC2 Linear Strength + description: > + Linear factor, higher values produce a more grayish image, while + lower values produce a more saturated image. + + - uc2t_linear_angle: + display_if: {tonemap_operator: "uncharted2"} + type: float + range: [0.01, 1.0] + default: 0.1 + shader_runtime: true + label: UC2 Linear Angle + description: > + Linear Angle, higher values produce a brighter but more grayish image, + lower values produce a more saturated image. + + + - uc2t_toe_strength: + display_if: {tonemap_operator: "uncharted2"} + type: float + range: [0.01, 1.0] + default: 0.2 + shader_runtime: true + label: UC2 Toe Strength + description: > + Toe Strength, controls the appearance of the dark parts of the image, + (the first part of the color curve). Higher values mean more dark + spots, while lower values will cut-off less dark values. + + - uc2t_toe_numerator: + display_if: {tonemap_operator: "uncharted2"} + type: float + range: [0.0001, 0.1] + default: 0.01 + shader_runtime: true + label: UC2 Toe Numerator + description: > + Toe Numerator, controls the appearance of the dark parts similar to + the toe strength. This is a bias, values below this setting are + completely dark. + + - uc2t_toe_denumerator: + display_if: {tonemap_operator: "uncharted2"} + type: float + range: [0.01, 1.0] + default: 0.3 + shader_runtime: true + label: UC2 Toe Denumerator + description: > + Toe Denumerator, controls the appearance of the dark parts similar to + the toe strength, but instead of cutting of the dark values it + makes them brighter. + + - uc2t_reference_white: + display_if: {tonemap_operator: "uncharted2"} + type: float + range: [0.1, 20.0] + default: 11.2 + shader_runtime: true + label: UC2 Reference White + description: > + Reference White, higher values will produce a darker image, and + vice-versa. This basically just scales the color linear inverse. + + + - vignette_strength: + type: float + range: [0.0, 1.0] + default: 0.35 + shader_runtime: true + label: Vignette Strength + description: > + Controls the strength of the vignette, which darkens the corners + of the image. A strength of 0 means no vignette, a strength of 1 + means a almost completely black vignette. + + - film_grain_strength: + type: float + range: [0.0, 1.0] + default: 0.125 + shader_runtime: true + label: Film Grain Strength + description: > + Controls the strength of the film grain, which simulates the inaccuracies + on a film. This is also useful to add some more details to textures, however + care to not overdo the effect. + + + # Color LUT + + - color_lut: + type: path + default: film_luts/default_lut.png + label: Color LUT + file_type: Color LUTs (*.png) + base_path: film_luts + runtime: true + description: > + Specifies a Color LUT (Look-Up-Table) to use. Have a look at the Render Pipeline + documentation for further information. + + # Chromatic aberration + + - use_chromatic_aberration: + type: bool + default: true + shader_runtime: true + label: Enable Chromatic Aberration + description: > + Enables chromatic aberration, a camera effect caused due to the + different refraction of the wavelengths through a lens. + + - chromatic_aberration_strength: + display_if: {use_chromatic_aberration: true} + type: float + range: [0.009, 2.0] + default: 0.5 + shader_runtime: true + label: Chromatic Aberration Strength + description: > + Strength of the chromatic abberation, you should not overdo this since + it can lead to very unrealistic results fast. + + - chromatic_aberration_samples: + display_if: {use_chromatic_aberration: true} + type: int + range: [1, 5] + default: 2 + shader_runtime: true + label: Chromatic Aberration Samples + description: > + Amount of samples to use for blurring the screen edges when using + chromatic abberation. A higher amount of samples produces a smoother + blur but also increases the performance cost by a lot. + + + # Automatic exposure settings + + - manual_camera_parameters: + type: bool + default: false + label: Manual camera parameters + description: > + When set to true, enables you to set camera parameters such as + ISO, shutter and f-stops. If set to false, the average scene + luminance will be used to compute the exposure. + + - min_exposure_value: + display_if: {manual_camera_parameters: false} + type: float + range: [0.0, 0.1] + default: 0.01 + label: Minimum Exposure + shader_runtime: true + description: > + The minimum exposure value, this prevents the automatic exposure from overfitting + on bright areas + + - max_exposure_value: + display_if: {manual_camera_parameters: false} + type: float + range: [0.0, 1.0] + default: 1.0 + shader_runtime: true + label: Maximum Exposure + description: > + The maximum exposure value, this prevents the automatic exposure from overfitting + on dark areas. + + - exposure_scale: + display_if: {manual_camera_parameters: false} + type: float + range: [0.0, 10.0] + default: 1.0 + label: Exposure Scale + shader_runtime: true + description: > + This is a fixed value which gets added to the average brightness of the + scene. A value greater 1 will increase the scene brightness, while a value + smaller than 1 will increase it. + + - brightness_adaption_rate: + display_if: {manual_camera_parameters: false} + type: float + range: [0.01, 5.0] + default: 3.6 + shader_runtime: true + label: Brightness Adaption Rate + description: > + Adaption rate when moving from dark to bright areas. + Usually faster (= higher) than the rate when moving from bright to dark areas. + + - darkness_adaption_rate: + display_if: {manual_camera_parameters: false} + type: float + range: [0.01, 5.0] + default: 0.7 + shader_runtime: true + label: Darkness Adaption Rate + description: > + Adaption rate when moving from bright to dark areas. + Usually slower (= smaller) than the rate when moving from dark to bright areas. + + + + # Sharpen filter + - use_sharpen: + type: bool + default: true + label: Sharpen Filter + description: > + Enables a sharpen filter, which tries to increase texture detail. + + - sharpen_strength: + display_if: {use_sharpen: true} + type: float + range: [0.0, 5.0] + default: 0.5 + shader_runtime: true + label: Sharpen Strength + description: > + Controls the strength of the sharpen filter. + + - sharpen_twice: + display_if: {use_sharpen: true} + type: bool + default: false + label: Double-Sharpen + description: > + If this setting is true, the sharpen filter will be executed twice, + for an even stronger sharpen effect. + + +daytime_settings: !!omap + + - camera_iso: + type: scalar + unit: none + default: 100 + range: [20, 4000] + label: Camera ISO + logarithmic_factor: 2.0 + description: > + ISO value of the camera. Only has effect with manual camera parameters. + + - camera_shutter: + type: scalar + unit: none + default: 125 + range: [1, 200] + label: Camera Shutter Speed + description: > + The shutter speed of the camera. A value of 125 means a shutter + speed of 1 / 125 seconds. Only has effect with manual camera parameters. + + - camera_aperture: + type: scalar + unit: none + default: 16 + range: [1, 32] + label: Camera Aperture + description: > + Camera aperture, a value of 16 means an aperture of f/16. + Only has effect with manual camera parameters. diff --git a/rpplugins/color_correction/manual_exposure_stage.py b/rpplugins/color_correction/manual_exposure_stage.py new file mode 100644 index 0000000..3859761 --- /dev/null +++ b/rpplugins/color_correction/manual_exposure_stage.py @@ -0,0 +1,47 @@ +""" + +RenderPipeline + +Copyright (c) 2014-2016 tobspr + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. + +""" + +from __future__ import division + +from rpcore.render_stage import RenderStage + + +class ManualExposureStage(RenderStage): + + required_pipes = ["ShadedScene"] + required_inputs = [] + + @property + def produced_pipes(self): + return {"ShadedScene": self.target.color_tex} + + def create(self): + self.target = self.create_target("ManualExposure") + self.target.add_color_attachment(bits=16) + self.target.prepare_buffer() + + def reload_shaders(self): + self.target.shader = self.load_plugin_shader("manual_exposure.frag.glsl") diff --git a/rpplugins/color_correction/plugin.py b/rpplugins/color_correction/plugin.py new file mode 100644 index 0000000..58482a6 --- /dev/null +++ b/rpplugins/color_correction/plugin.py @@ -0,0 +1,91 @@ +""" + +RenderPipeline + +Copyright (c) 2014-2016 tobspr + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. + +""" + +from panda3d.core import SamplerState + +# Load the plugin api +from rpcore.pluginbase.base_plugin import BasePlugin +from rpcore.loader import RPLoader + +from .color_correction_stage import ColorCorrectionStage +from .auto_exposure_stage import AutoExposureStage +from .manual_exposure_stage import ManualExposureStage +from .sharpen_stage import SharpenStage +from .tonemapping_stage import TonemappingStage + + +class Plugin(BasePlugin): + + name = "Color Correction" + author = "tobspr " + description = ("This plugin adds support for color correction, vignetting, " + "chromatic abberation and tonemapping. It also controls the " + "camera parameters.") + version = "1.4" + + def on_stage_setup(self): + self.stage = self.create_stage(ColorCorrectionStage) + self.tonemapping_stage = self.create_stage(TonemappingStage) + + if self.get_setting("use_sharpen"): + self.sharpen_stage = self.create_stage(SharpenStage) + self.sharpen_stage.sharpen_twice = self.get_setting("sharpen_twice") + + if not self.get_setting("manual_camera_parameters"): + self.exposure_stage = self.create_stage(AutoExposureStage) + else: + self.exposure_stage = self.create_stage(ManualExposureStage) # noqa # pylint: disable=redefined-variable-type + + def on_pipeline_created(self): + self.load_lut() + self.load_grain() + + def load_lut(self): + """ Loads the color correction lookup table (LUT) """ + lut_path = self.get_resource(self.get_setting("color_lut")) + lut = RPLoader.load_sliced_3d_texture(lut_path, 64) + lut.set_wrap_u(SamplerState.WM_clamp) + lut.set_wrap_v(SamplerState.WM_clamp) + lut.set_wrap_w(SamplerState.WM_clamp) + lut.set_minfilter(SamplerState.FT_linear) + lut.set_magfilter(SamplerState.FT_linear) + lut.set_anisotropic_degree(0) + self.tonemapping_stage.set_shader_input("ColorLUT", lut) + + def load_grain(self): + """ Loads the precomputed film grain """ + grain_tex = RPLoader.load_texture( + "/$$rp/data/film_grain/grain.txo") + grain_tex.set_minfilter(SamplerState.FT_linear) + grain_tex.set_magfilter(SamplerState.FT_linear) + grain_tex.set_wrap_u(SamplerState.WM_repeat) + grain_tex.set_wrap_v(SamplerState.WM_repeat) + grain_tex.set_anisotropic_degree(0) + self.stage.set_shader_input("PrecomputedGrain", grain_tex) + + def update_color_lut(self): + self.debug("Updating color lut ..") + self.load_lut() diff --git a/rpplugins/color_correction/resources/README.md b/rpplugins/color_correction/resources/README.md new file mode 100644 index 0000000..8905375 --- /dev/null +++ b/rpplugins/color_correction/resources/README.md @@ -0,0 +1,7 @@ + + +# Filmic resopnse curves + +The filmic curves were copied from blender and can be found in `datafiles/colormanagement/luts`. +It seems these luts are from http://opencolorio.org. + diff --git a/rpplugins/color_correction/resources/film_luts/agfa_advantix_100.png b/rpplugins/color_correction/resources/film_luts/agfa_advantix_100.png new file mode 100644 index 0000000..ef43e0c Binary files /dev/null and b/rpplugins/color_correction/resources/film_luts/agfa_advantix_100.png differ diff --git a/rpplugins/color_correction/resources/film_luts/agfa_advantix_200.png b/rpplugins/color_correction/resources/film_luts/agfa_advantix_200.png new file mode 100644 index 0000000..19aa25c Binary files /dev/null and b/rpplugins/color_correction/resources/film_luts/agfa_advantix_200.png differ diff --git a/rpplugins/color_correction/resources/film_luts/agfa_advantix_400.png b/rpplugins/color_correction/resources/film_luts/agfa_advantix_400.png new file mode 100644 index 0000000..a9c9cdb Binary files /dev/null and b/rpplugins/color_correction/resources/film_luts/agfa_advantix_400.png differ diff --git a/rpplugins/color_correction/resources/film_luts/agfa_agfachrome_ct_precisa_100.png b/rpplugins/color_correction/resources/film_luts/agfa_agfachrome_ct_precisa_100.png new file mode 100644 index 0000000..7038aea Binary files /dev/null and b/rpplugins/color_correction/resources/film_luts/agfa_agfachrome_ct_precisa_100.png differ diff --git a/rpplugins/color_correction/resources/film_luts/agfa_agfachrome_ct_precisa_200.png b/rpplugins/color_correction/resources/film_luts/agfa_agfachrome_ct_precisa_200.png new file mode 100644 index 0000000..6ba89a5 Binary files /dev/null and b/rpplugins/color_correction/resources/film_luts/agfa_agfachrome_ct_precisa_200.png differ diff --git a/rpplugins/color_correction/resources/film_luts/agfa_agfachrome_rsx2_050.png b/rpplugins/color_correction/resources/film_luts/agfa_agfachrome_rsx2_050.png new file mode 100644 index 0000000..f800419 Binary files /dev/null and b/rpplugins/color_correction/resources/film_luts/agfa_agfachrome_rsx2_050.png differ diff --git a/rpplugins/color_correction/resources/film_luts/agfa_agfachrome_rsx2_100.png b/rpplugins/color_correction/resources/film_luts/agfa_agfachrome_rsx2_100.png new file mode 100644 index 0000000..a279d44 Binary files /dev/null and b/rpplugins/color_correction/resources/film_luts/agfa_agfachrome_rsx2_100.png differ diff --git a/rpplugins/color_correction/resources/film_luts/agfa_agfachrome_rsx2_200.png b/rpplugins/color_correction/resources/film_luts/agfa_agfachrome_rsx2_200.png new file mode 100644 index 0000000..4933313 Binary files /dev/null and b/rpplugins/color_correction/resources/film_luts/agfa_agfachrome_rsx2_200.png differ diff --git a/rpplugins/color_correction/resources/film_luts/agfa_agfacolor_futura_100.png b/rpplugins/color_correction/resources/film_luts/agfa_agfacolor_futura_100.png new file mode 100644 index 0000000..7848718 Binary files /dev/null and b/rpplugins/color_correction/resources/film_luts/agfa_agfacolor_futura_100.png differ diff --git a/rpplugins/color_correction/resources/film_luts/agfa_agfacolor_futura_200.png b/rpplugins/color_correction/resources/film_luts/agfa_agfacolor_futura_200.png new file mode 100644 index 0000000..f400c02 Binary files /dev/null and b/rpplugins/color_correction/resources/film_luts/agfa_agfacolor_futura_200.png differ diff --git a/rpplugins/color_correction/resources/film_luts/agfa_agfacolor_futura_400.png b/rpplugins/color_correction/resources/film_luts/agfa_agfacolor_futura_400.png new file mode 100644 index 0000000..aa12b82 Binary files /dev/null and b/rpplugins/color_correction/resources/film_luts/agfa_agfacolor_futura_400.png differ diff --git a/rpplugins/color_correction/resources/film_luts/agfa_agfacolor_futura_ii_100.png b/rpplugins/color_correction/resources/film_luts/agfa_agfacolor_futura_ii_100.png new file mode 100644 index 0000000..aa2d7a6 Binary files /dev/null and b/rpplugins/color_correction/resources/film_luts/agfa_agfacolor_futura_ii_100.png differ diff --git a/rpplugins/color_correction/resources/film_luts/agfa_agfacolor_futura_ii_200.png b/rpplugins/color_correction/resources/film_luts/agfa_agfacolor_futura_ii_200.png new file mode 100644 index 0000000..dcbd15c Binary files /dev/null and b/rpplugins/color_correction/resources/film_luts/agfa_agfacolor_futura_ii_200.png differ diff --git a/rpplugins/color_correction/resources/film_luts/agfa_agfacolor_futura_ii_400.png b/rpplugins/color_correction/resources/film_luts/agfa_agfacolor_futura_ii_400.png new file mode 100644 index 0000000..961aa5a Binary files /dev/null and b/rpplugins/color_correction/resources/film_luts/agfa_agfacolor_futura_ii_400.png differ diff --git a/rpplugins/color_correction/resources/film_luts/agfa_agfacolor_hdc_100_plus.png b/rpplugins/color_correction/resources/film_luts/agfa_agfacolor_hdc_100_plus.png new file mode 100644 index 0000000..ff2e275 Binary files /dev/null and b/rpplugins/color_correction/resources/film_luts/agfa_agfacolor_hdc_100_plus.png differ diff --git a/rpplugins/color_correction/resources/film_luts/agfa_agfacolor_hdc_200_plus.png b/rpplugins/color_correction/resources/film_luts/agfa_agfacolor_hdc_200_plus.png new file mode 100644 index 0000000..c0073f1 Binary files /dev/null and b/rpplugins/color_correction/resources/film_luts/agfa_agfacolor_hdc_200_plus.png differ diff --git a/rpplugins/color_correction/resources/film_luts/agfa_agfacolor_hdc_400_plus.png b/rpplugins/color_correction/resources/film_luts/agfa_agfacolor_hdc_400_plus.png new file mode 100644 index 0000000..91d5952 Binary files /dev/null and b/rpplugins/color_correction/resources/film_luts/agfa_agfacolor_hdc_400_plus.png differ diff --git a/rpplugins/color_correction/resources/film_luts/agfa_agfacolor_optima_ii_100.png b/rpplugins/color_correction/resources/film_luts/agfa_agfacolor_optima_ii_100.png new file mode 100644 index 0000000..cf381a0 Binary files /dev/null and b/rpplugins/color_correction/resources/film_luts/agfa_agfacolor_optima_ii_100.png differ diff --git a/rpplugins/color_correction/resources/film_luts/agfa_agfacolor_optima_ii_200.png b/rpplugins/color_correction/resources/film_luts/agfa_agfacolor_optima_ii_200.png new file mode 100644 index 0000000..c3807cf Binary files /dev/null and b/rpplugins/color_correction/resources/film_luts/agfa_agfacolor_optima_ii_200.png differ diff --git a/rpplugins/color_correction/resources/film_luts/agfa_agfacolor_ultra_050.png b/rpplugins/color_correction/resources/film_luts/agfa_agfacolor_ultra_050.png new file mode 100644 index 0000000..86af83c Binary files /dev/null and b/rpplugins/color_correction/resources/film_luts/agfa_agfacolor_ultra_050.png differ diff --git a/rpplugins/color_correction/resources/film_luts/agfa_agfacolor_vista_100.png b/rpplugins/color_correction/resources/film_luts/agfa_agfacolor_vista_100.png new file mode 100644 index 0000000..934485d Binary files /dev/null and b/rpplugins/color_correction/resources/film_luts/agfa_agfacolor_vista_100.png differ diff --git a/rpplugins/color_correction/resources/film_luts/agfa_agfacolor_vista_200.png b/rpplugins/color_correction/resources/film_luts/agfa_agfacolor_vista_200.png new file mode 100644 index 0000000..4b7c7ba Binary files /dev/null and b/rpplugins/color_correction/resources/film_luts/agfa_agfacolor_vista_200.png differ diff --git a/rpplugins/color_correction/resources/film_luts/agfa_agfacolor_vista_400.png b/rpplugins/color_correction/resources/film_luts/agfa_agfacolor_vista_400.png new file mode 100644 index 0000000..9108cc2 Binary files /dev/null and b/rpplugins/color_correction/resources/film_luts/agfa_agfacolor_vista_400.png differ diff --git a/rpplugins/color_correction/resources/film_luts/agfa_agfacolor_vista_800.png b/rpplugins/color_correction/resources/film_luts/agfa_agfacolor_vista_800.png new file mode 100644 index 0000000..abd262a Binary files /dev/null and b/rpplugins/color_correction/resources/film_luts/agfa_agfacolor_vista_800.png differ diff --git a/rpplugins/color_correction/resources/film_luts/default_lut.png b/rpplugins/color_correction/resources/film_luts/default_lut.png new file mode 100644 index 0000000..1925cac Binary files /dev/null and b/rpplugins/color_correction/resources/film_luts/default_lut.png differ diff --git a/rpplugins/color_correction/resources/film_luts/fujifilm_f-125.png b/rpplugins/color_correction/resources/film_luts/fujifilm_f-125.png new file mode 100644 index 0000000..0932757 Binary files /dev/null and b/rpplugins/color_correction/resources/film_luts/fujifilm_f-125.png differ diff --git a/rpplugins/color_correction/resources/film_luts/fujifilm_f-250.png b/rpplugins/color_correction/resources/film_luts/fujifilm_f-250.png new file mode 100644 index 0000000..e7c23dd Binary files /dev/null and b/rpplugins/color_correction/resources/film_luts/fujifilm_f-250.png differ diff --git a/rpplugins/color_correction/resources/film_luts/fujifilm_f-400.png b/rpplugins/color_correction/resources/film_luts/fujifilm_f-400.png new file mode 100644 index 0000000..370ee14 Binary files /dev/null and b/rpplugins/color_correction/resources/film_luts/fujifilm_f-400.png differ diff --git a/rpplugins/color_correction/resources/film_luts/fujifilm_fci.png b/rpplugins/color_correction/resources/film_luts/fujifilm_fci.png new file mode 100644 index 0000000..08ff048 Binary files /dev/null and b/rpplugins/color_correction/resources/film_luts/fujifilm_fci.png differ diff --git a/rpplugins/color_correction/resources/film_luts/fujifilm_fp2900z.png b/rpplugins/color_correction/resources/film_luts/fujifilm_fp2900z.png new file mode 100644 index 0000000..7e07213 Binary files /dev/null and b/rpplugins/color_correction/resources/film_luts/fujifilm_fp2900z.png differ diff --git a/rpplugins/color_correction/resources/film_luts/kodak_dscs_3151.png b/rpplugins/color_correction/resources/film_luts/kodak_dscs_3151.png new file mode 100644 index 0000000..da7a168 Binary files /dev/null and b/rpplugins/color_correction/resources/film_luts/kodak_dscs_3151.png differ diff --git a/rpplugins/color_correction/resources/film_luts/kodak_dscs_3152.png b/rpplugins/color_correction/resources/film_luts/kodak_dscs_3152.png new file mode 100644 index 0000000..86409e0 Binary files /dev/null and b/rpplugins/color_correction/resources/film_luts/kodak_dscs_3152.png differ diff --git a/rpplugins/color_correction/resources/film_luts/kodak_dscs_3153.png b/rpplugins/color_correction/resources/film_luts/kodak_dscs_3153.png new file mode 100644 index 0000000..b325ebe Binary files /dev/null and b/rpplugins/color_correction/resources/film_luts/kodak_dscs_3153.png differ diff --git a/rpplugins/color_correction/resources/film_luts/kodak_dscs_3154.png b/rpplugins/color_correction/resources/film_luts/kodak_dscs_3154.png new file mode 100644 index 0000000..359f44a Binary files /dev/null and b/rpplugins/color_correction/resources/film_luts/kodak_dscs_3154.png differ diff --git a/rpplugins/color_correction/resources/film_luts/kodak_dscs_3155.png b/rpplugins/color_correction/resources/film_luts/kodak_dscs_3155.png new file mode 100644 index 0000000..e353977 Binary files /dev/null and b/rpplugins/color_correction/resources/film_luts/kodak_dscs_3155.png differ diff --git a/rpplugins/color_correction/resources/film_luts/kodak_dscs_3156.png b/rpplugins/color_correction/resources/film_luts/kodak_dscs_3156.png new file mode 100644 index 0000000..5d91a40 Binary files /dev/null and b/rpplugins/color_correction/resources/film_luts/kodak_dscs_3156.png differ diff --git a/rpplugins/color_correction/resources/film_luts/kodak_ektachrome_100.png b/rpplugins/color_correction/resources/film_luts/kodak_ektachrome_100.png new file mode 100644 index 0000000..cbb9f0e Binary files /dev/null and b/rpplugins/color_correction/resources/film_luts/kodak_ektachrome_100.png differ diff --git a/rpplugins/color_correction/resources/film_luts/kodak_ektachrome_100_plus.png b/rpplugins/color_correction/resources/film_luts/kodak_ektachrome_100_plus.png new file mode 100644 index 0000000..b1ab98e Binary files /dev/null and b/rpplugins/color_correction/resources/film_luts/kodak_ektachrome_100_plus.png differ diff --git a/rpplugins/color_correction/resources/film_luts/kodak_ektachrome_320t.png b/rpplugins/color_correction/resources/film_luts/kodak_ektachrome_320t.png new file mode 100644 index 0000000..9d79448 Binary files /dev/null and b/rpplugins/color_correction/resources/film_luts/kodak_ektachrome_320t.png differ diff --git a/rpplugins/color_correction/resources/film_luts/kodak_ektachrome_400x.png b/rpplugins/color_correction/resources/film_luts/kodak_ektachrome_400x.png new file mode 100644 index 0000000..9ad6efc Binary files /dev/null and b/rpplugins/color_correction/resources/film_luts/kodak_ektachrome_400x.png differ diff --git a/rpplugins/color_correction/resources/film_luts/kodak_ektachrome_64.png b/rpplugins/color_correction/resources/film_luts/kodak_ektachrome_64.png new file mode 100644 index 0000000..78dfe49 Binary files /dev/null and b/rpplugins/color_correction/resources/film_luts/kodak_ektachrome_64.png differ diff --git a/rpplugins/color_correction/resources/film_luts/kodak_ektachrome_64t.png b/rpplugins/color_correction/resources/film_luts/kodak_ektachrome_64t.png new file mode 100644 index 0000000..da95ba5 Binary files /dev/null and b/rpplugins/color_correction/resources/film_luts/kodak_ektachrome_64t.png differ diff --git a/rpplugins/color_correction/resources/film_luts/kodak_ektachrome_e100s.png b/rpplugins/color_correction/resources/film_luts/kodak_ektachrome_e100s.png new file mode 100644 index 0000000..e803692 Binary files /dev/null and b/rpplugins/color_correction/resources/film_luts/kodak_ektachrome_e100s.png differ diff --git a/rpplugins/color_correction/resources/film_luts/kodak_gold_100.png b/rpplugins/color_correction/resources/film_luts/kodak_gold_100.png new file mode 100644 index 0000000..d0cc582 Binary files /dev/null and b/rpplugins/color_correction/resources/film_luts/kodak_gold_100.png differ diff --git a/rpplugins/color_correction/resources/film_luts/kodak_gold_200.png b/rpplugins/color_correction/resources/film_luts/kodak_gold_200.png new file mode 100644 index 0000000..760fc72 Binary files /dev/null and b/rpplugins/color_correction/resources/film_luts/kodak_gold_200.png differ diff --git a/rpplugins/color_correction/resources/film_luts/kodak_kodachrome_200.png b/rpplugins/color_correction/resources/film_luts/kodak_kodachrome_200.png new file mode 100644 index 0000000..0b046ab Binary files /dev/null and b/rpplugins/color_correction/resources/film_luts/kodak_kodachrome_200.png differ diff --git a/rpplugins/color_correction/resources/film_luts/kodak_kodachrome_25.png b/rpplugins/color_correction/resources/film_luts/kodak_kodachrome_25.png new file mode 100644 index 0000000..f11819a Binary files /dev/null and b/rpplugins/color_correction/resources/film_luts/kodak_kodachrome_25.png differ diff --git a/rpplugins/color_correction/resources/film_luts/kodak_kodachrome_64.png b/rpplugins/color_correction/resources/film_luts/kodak_kodachrome_64.png new file mode 100644 index 0000000..147fbff Binary files /dev/null and b/rpplugins/color_correction/resources/film_luts/kodak_kodachrome_64.png differ diff --git a/rpplugins/color_correction/resources/film_luts/kodak_max_zoom_800.png b/rpplugins/color_correction/resources/film_luts/kodak_max_zoom_800.png new file mode 100644 index 0000000..8893752 Binary files /dev/null and b/rpplugins/color_correction/resources/film_luts/kodak_max_zoom_800.png differ diff --git a/rpplugins/color_correction/resources/film_luts/kodak_portra_100t.png b/rpplugins/color_correction/resources/film_luts/kodak_portra_100t.png new file mode 100644 index 0000000..31b39de Binary files /dev/null and b/rpplugins/color_correction/resources/film_luts/kodak_portra_100t.png differ diff --git a/rpplugins/color_correction/resources/film_luts/kodak_portra_160nc.png b/rpplugins/color_correction/resources/film_luts/kodak_portra_160nc.png new file mode 100644 index 0000000..48714c7 Binary files /dev/null and b/rpplugins/color_correction/resources/film_luts/kodak_portra_160nc.png differ diff --git a/rpplugins/color_correction/resources/film_luts/kodak_portra_160vc.png b/rpplugins/color_correction/resources/film_luts/kodak_portra_160vc.png new file mode 100644 index 0000000..c4361b5 Binary files /dev/null and b/rpplugins/color_correction/resources/film_luts/kodak_portra_160vc.png differ diff --git a/rpplugins/color_correction/resources/film_luts/kodak_portra_400nc.png b/rpplugins/color_correction/resources/film_luts/kodak_portra_400nc.png new file mode 100644 index 0000000..5ea57b7 Binary files /dev/null and b/rpplugins/color_correction/resources/film_luts/kodak_portra_400nc.png differ diff --git a/rpplugins/color_correction/resources/film_luts/kodak_portra_400vc.png b/rpplugins/color_correction/resources/film_luts/kodak_portra_400vc.png new file mode 100644 index 0000000..6ccbdb8 Binary files /dev/null and b/rpplugins/color_correction/resources/film_luts/kodak_portra_400vc.png differ diff --git a/rpplugins/color_correction/resources/film_luts/kodak_portra_800.png b/rpplugins/color_correction/resources/film_luts/kodak_portra_800.png new file mode 100644 index 0000000..94c50a0 Binary files /dev/null and b/rpplugins/color_correction/resources/film_luts/kodak_portra_800.png differ diff --git a/rpplugins/color_correction/resources/film_luts/saturation_lut.png b/rpplugins/color_correction/resources/film_luts/saturation_lut.png new file mode 100644 index 0000000..4f9865d Binary files /dev/null and b/rpplugins/color_correction/resources/film_luts/saturation_lut.png differ diff --git a/rpplugins/color_correction/resources/film_luts_raw/agfa_advantix_100.spi1d b/rpplugins/color_correction/resources/film_luts_raw/agfa_advantix_100.spi1d new file mode 100644 index 0000000..77ae66b --- /dev/null +++ b/rpplugins/color_correction/resources/film_luts_raw/agfa_advantix_100.spi1d @@ -0,0 +1,1030 @@ +Version 1 +From 0.0 1.0 +Length 1024 +Components 3 +{ + 0.0000000000 0.0000000000 0.0000000000 + 0.0099759204 0.0084230602 0.0063721500 + 0.0195903908 0.0165482908 0.0126159703 + 0.0281873904 0.0239386503 0.0183614101 + 0.0359400399 0.0306491107 0.0236731302 + 0.0429986902 0.0368482284 0.0286820605 + 0.0495699607 0.0426228605 0.0333807915 + 0.0556899793 0.0479997694 0.0378808789 + 0.0614735186 0.0531351306 0.0421144105 + 0.0669660494 0.0580130592 0.0461965613 + 0.0722220466 0.0627681389 0.0501793101 + 0.0772255808 0.0672829002 0.0540068410 + 0.0820826665 0.0715929568 0.0576650202 + 0.0867473707 0.0758115426 0.0612268411 + 0.0911795869 0.0799473077 0.0647046193 + 0.0954854265 0.0839523673 0.0681224987 + 0.0996826664 0.0878431126 0.0714934394 + 0.1037980989 0.0916301981 0.0747776777 + 0.1078191027 0.0953292921 0.0779552832 + 0.1117319018 0.0989396721 0.0810553879 + 0.1155693978 0.1024464965 0.0841333270 + 0.1193092018 0.1058896035 0.0871890634 + 0.1229984984 0.1092770025 0.0902054086 + 0.1266297996 0.1126255989 0.0931699723 + 0.1301828027 0.1159031019 0.0960779637 + 0.1336570978 0.1191100031 0.0989290774 + 0.1370528936 0.1222644001 0.1017358005 + 0.1403681934 0.1253843009 0.1045102030 + 0.1436405927 0.1284482032 0.1072589979 + 0.1468632966 0.1314789057 0.1099923998 + 0.1500498056 0.1344655007 0.1126931980 + 0.1531880051 0.1374220997 0.1153720021 + 0.1562644988 0.1403357983 0.1180130020 + 0.1593036950 0.1431988031 0.1206170022 + 0.1623243988 0.1460403949 0.1231862009 + 0.1653179973 0.1488437951 0.1257254034 + 0.1682834029 0.1516059935 0.1282379031 + 0.1712214053 0.1543526053 0.1307227015 + 0.1741254926 0.1570729017 0.1331889033 + 0.1769879013 0.1597575992 0.1356364042 + 0.1798096001 0.1624283046 0.1380718946 + 0.1825927943 0.1650680006 0.1404998004 + 0.1853370070 0.1676719934 0.1429184973 + 0.1880521029 0.1702331007 0.1453085989 + 0.1907549053 0.1727772951 0.1476781964 + 0.1934437007 0.1753048003 0.1500300020 + 0.1961088926 0.1777949929 0.1523580998 + 0.1987465024 0.1802501976 0.1546709985 + 0.2013590932 0.1826943010 0.1569592059 + 0.2039510012 0.1851214021 0.1592251062 + 0.2065189034 0.1875294000 0.1614681929 + 0.2090530992 0.1899122000 0.1636908054 + 0.2115564942 0.1922917962 0.1659017056 + 0.2140268981 0.1946634054 0.1680952013 + 0.2164652050 0.1970131993 0.1702757031 + 0.2188750952 0.1993432045 0.1724483967 + 0.2212729007 0.2016437054 0.1746093035 + 0.2236527056 0.2039304972 0.1767639965 + 0.2260089964 0.2062091976 0.1789053977 + 0.2283485979 0.2084756047 0.1810386926 + 0.2306748033 0.2107181996 0.1831596941 + 0.2329774946 0.2129396051 0.1852661967 + 0.2352634072 0.2151475996 0.1873624027 + 0.2375380993 0.2173521072 0.1894447953 + 0.2398073971 0.2195435017 0.1915135980 + 0.2420687973 0.2217237949 0.1935653985 + 0.2443214953 0.2238844931 0.1956079006 + 0.2465686053 0.2260320932 0.1976383030 + 0.2488050014 0.2281741947 0.1996645033 + 0.2510258853 0.2303086966 0.2016756982 + 0.2532328963 0.2324285060 0.2036695927 + 0.2554255128 0.2345477939 0.2056519985 + 0.2576034069 0.2366596013 0.2076213062 + 0.2597728968 0.2387540042 0.2095845044 + 0.2619242072 0.2408431023 0.2115366012 + 0.2640654147 0.2429351956 0.2134785950 + 0.2661896050 0.2450205982 0.2154116929 + 0.2682917118 0.2470878959 0.2173403054 + 0.2703784108 0.2491298020 0.2192642987 + 0.2724463940 0.2511504889 0.2211790979 + 0.2745001018 0.2531620860 0.2230885029 + 0.2765473127 0.2551639080 0.2249957025 + 0.2785851955 0.2571550012 0.2268918008 + 0.2806180120 0.2591302097 0.2287832946 + 0.2826406956 0.2611007094 0.2306707054 + 0.2846564949 0.2630642056 0.2325448990 + 0.2866632938 0.2650120854 0.2344118059 + 0.2886619866 0.2669439912 0.2362738997 + 0.2906560004 0.2688710988 0.2381276935 + 0.2926402986 0.2707965970 0.2399802953 + 0.2946187854 0.2727138996 0.2418286055 + 0.2965883017 0.2746171057 0.2436629981 + 0.2985542119 0.2765100896 0.2454881072 + 0.3005166948 0.2783927023 0.2473084927 + 0.3024731874 0.2802628875 0.2491195947 + 0.3044191897 0.2821266055 0.2509351969 + 0.3063541949 0.2839806080 0.2527473867 + 0.3082849979 0.2858333886 0.2545492053 + 0.3102098107 0.2876932919 0.2563391030 + 0.3121250868 0.2895553112 0.2581259906 + 0.3140304089 0.2914139032 0.2599045038 + 0.3159317076 0.2932642996 0.2616701126 + 0.3178148866 0.2951014042 0.2634266019 + 0.3196887970 0.2969211042 0.2651784122 + 0.3215618134 0.2987315953 0.2669197023 + 0.3234333992 0.3005411923 0.2686525881 + 0.3252997994 0.3023456931 0.2703748941 + 0.3271591067 0.3041403890 0.2720899880 + 0.3290081024 0.3059214950 0.2738001049 + 0.3308455050 0.3076925874 0.2755038142 + 0.3326750100 0.3094542027 0.2772029042 + 0.3345032036 0.3112052083 0.2788943052 + 0.3363313079 0.3129465878 0.2805776000 + 0.3381510079 0.3146811128 0.2822565138 + 0.3399673104 0.3164061010 0.2839331031 + 0.3417668045 0.3181275129 0.2856017947 + 0.3435564041 0.3198527992 0.2872670889 + 0.3453372121 0.3215794861 0.2889324129 + 0.3471119106 0.3233039975 0.2905947864 + 0.3488827050 0.3250232041 0.2922506928 + 0.3506490886 0.3267351091 0.2938998938 + 0.3524067998 0.3284330070 0.2955498099 + 0.3541550934 0.3301151097 0.2971960902 + 0.3558937907 0.3317880034 0.2988429070 + 0.3576247096 0.3334558010 0.3004919887 + 0.3593502939 0.3351208866 0.3021433949 + 0.3610683084 0.3367798030 0.3037939072 + 0.3627772033 0.3384372890 0.3054369092 + 0.3644764125 0.3400928974 0.3070757985 + 0.3661648929 0.3417460024 0.3087131977 + 0.3678394854 0.3433952034 0.3103514910 + 0.3695080876 0.3450438976 0.3119843006 + 0.3711709082 0.3466848135 0.3136082888 + 0.3728272021 0.3483184874 0.3152261972 + 0.3744739890 0.3499465883 0.3168402910 + 0.3761177063 0.3515641093 0.3184512854 + 0.3777532876 0.3531782925 0.3200559020 + 0.3793804944 0.3547908962 0.3216531873 + 0.3810012937 0.3564052880 0.3232400119 + 0.3826153874 0.3580116034 0.3248240948 + 0.3842233121 0.3596132994 0.3264040053 + 0.3858231008 0.3612110019 0.3279787004 + 0.3874185085 0.3627916873 0.3295400143 + 0.3890103102 0.3643645048 0.3310950100 + 0.3905987144 0.3659299016 0.3326450884 + 0.3921895027 0.3674801886 0.3341901898 + 0.3937751055 0.3690252006 0.3357275128 + 0.3953565061 0.3705663085 0.3372594118 + 0.3969357014 0.3721058071 0.3387841880 + 0.3985069990 0.3736424148 0.3403007984 + 0.4000718892 0.3751770854 0.3418123126 + 0.4016300142 0.3767110109 0.3433167934 + 0.4031783938 0.3782438040 0.3448176086 + 0.4047181010 0.3797756135 0.3463155031 + 0.4062578976 0.3813019097 0.3478057981 + 0.4077931046 0.3828235865 0.3492931128 + 0.4093224108 0.3843406141 0.3507778943 + 0.4108479917 0.3858481050 0.3522605002 + 0.4123688936 0.3873529136 0.3537409008 + 0.4138790071 0.3888536990 0.3552181125 + 0.4153836071 0.3903481066 0.3566935062 + 0.4168849885 0.3918395936 0.3581683934 + 0.4183782041 0.3933278024 0.3596439064 + 0.4198674858 0.3948136866 0.3611176014 + 0.4213511050 0.3962967098 0.3625896871 + 0.4228254855 0.3977732062 0.3640539050 + 0.4242956936 0.3992463946 0.3655144870 + 0.4257540107 0.4007085860 0.3669649065 + 0.4272057116 0.4021649063 0.3684150875 + 0.4286471903 0.4036136866 0.3698649108 + 0.4300779998 0.4050632119 0.3713107109 + 0.4315038025 0.4065128863 0.3727546930 + 0.4329301119 0.4079527855 0.3741905987 + 0.4343521893 0.4093911052 0.3756245971 + 0.4357595146 0.4108251035 0.3770546913 + 0.4371610880 0.4122549891 0.3784829080 + 0.4385559857 0.4136810899 0.3799099028 + 0.4399372935 0.4150992930 0.3813312054 + 0.4413124025 0.4165146947 0.3827508986 + 0.4426822960 0.4179250002 0.3841583133 + 0.4440504909 0.4193333089 0.3855640888 + 0.4454061091 0.4207299948 0.3869630098 + 0.4467600882 0.4221264124 0.3883576989 + 0.4481090903 0.4235222936 0.3897452950 + 0.4494557977 0.4249134958 0.3911296129 + 0.4507992864 0.4262988865 0.3925110102 + 0.4521391988 0.4276803136 0.3938843906 + 0.4534761906 0.4290586114 0.3952535987 + 0.4548082054 0.4304304123 0.3966163993 + 0.4561375976 0.4317994118 0.3979771137 + 0.4574612081 0.4331589937 0.3993296921 + 0.4587827027 0.4345161915 0.4006809890 + 0.4600965977 0.4358676076 0.4020248055 + 0.4614087045 0.4372180998 0.4033680856 + 0.4627130032 0.4385639131 0.4046998918 + 0.4640161991 0.4399093091 0.4060314000 + 0.4653095007 0.4412535131 0.4073561132 + 0.4666016996 0.4425976872 0.4086807072 + 0.4678846896 0.4439316094 0.4100016057 + 0.4691669047 0.4452649951 0.4113222957 + 0.4704379141 0.4465923905 0.4126363993 + 0.4717079103 0.4479196072 0.4139505923 + 0.4729768038 0.4492313862 0.4152606130 + 0.4742454886 0.4505420923 0.4165706038 + 0.4755127132 0.4518438876 0.4178735912 + 0.4767796993 0.4531444907 0.4191763997 + 0.4780431092 0.4544411004 0.4204703867 + 0.4793055058 0.4557369947 0.4217635989 + 0.4805589020 0.4570290148 0.4230574071 + 0.4818083942 0.4583194852 0.4243515134 + 0.4830555916 0.4596050978 0.4256447852 + 0.4843012094 0.4608877003 0.4269377887 + 0.4855448008 0.4621653855 0.4282276034 + 0.4867860973 0.4634382129 0.4295150936 + 0.4880253077 0.4647068083 0.4307982028 + 0.4892593920 0.4659673870 0.4320754111 + 0.4904916883 0.4672257006 0.4333496094 + 0.4917111993 0.4684731960 0.4346148968 + 0.4929307103 0.4697206914 0.4358800054 + 0.4941438138 0.4709604084 0.4371437132 + 0.4953565001 0.4722000062 0.4384073019 + 0.4965640903 0.4734326899 0.4396674931 + 0.4977697134 0.4746631980 0.4409270883 + 0.4989753962 0.4758923054 0.4421825111 + 0.5001811981 0.4771201015 0.4434351921 + 0.5013839006 0.4783450067 0.4446885884 + 0.5025752783 0.4795615971 0.4459435046 + 0.5037667155 0.4807780981 0.4471982121 + 0.5049498081 0.4819892943 0.4484477043 + 0.5061323047 0.4832003117 0.4496971965 + 0.5073093176 0.4844068885 0.4509449005 + 0.5084829926 0.4856112003 0.4521920085 + 0.5096563101 0.4868122041 0.4534366131 + 0.5108284950 0.4880064130 0.4546774030 + 0.5120006800 0.4892007113 0.4559176862 + 0.5131582022 0.4903838933 0.4571487904 + 0.5143144727 0.4915668964 0.4583798945 + 0.5154706240 0.4927465916 0.4596010149 + 0.5166264176 0.4939242899 0.4608170986 + 0.5177810192 0.4951008856 0.4620308876 + 0.5189288259 0.4962731004 0.4632383883 + 0.5200765729 0.4974452853 0.4644457996 + 0.5212227106 0.4986133873 0.4656499028 + 0.5223680139 0.4997802079 0.4668532908 + 0.5235089064 0.5009468198 0.4680534899 + 0.5246378779 0.5021128058 0.4692485034 + 0.5257669091 0.5032787919 0.4704434872 + 0.5268948078 0.5044375062 0.4716280997 + 0.5280222893 0.5055947900 0.4728116095 + 0.5291473866 0.5067505240 0.4739918113 + 0.5302665830 0.5079032779 0.4751670957 + 0.5313857794 0.5090559721 0.4763424098 + 0.5325024724 0.5101991296 0.4775088131 + 0.5336183906 0.5113397837 0.4786739051 + 0.5347307920 0.5124807954 0.4798345864 + 0.5358300209 0.5136229992 0.4809859991 + 0.5369291902 0.5147653222 0.4821374118 + 0.5380263925 0.5159034729 0.4832834005 + 0.5391222835 0.5170397162 0.4844275117 + 0.5402178764 0.5181757212 0.4855712950 + 0.5412973166 0.5193089843 0.4867131114 + 0.5423766971 0.5204423070 0.4878548086 + 0.5434548855 0.5215684772 0.4889939129 + 0.5445311069 0.5226852298 0.4901303053 + 0.5456073284 0.5238018036 0.4912666976 + 0.5466775894 0.5249150991 0.4923954010 + 0.5477457047 0.5260273814 0.4935226142 + 0.5488138199 0.5271393061 0.4946480095 + 0.5498805046 0.5282471776 0.4957635105 + 0.5509471893 0.5293549895 0.4968788922 + 0.5520086884 0.5304607153 0.4979912043 + 0.5530598164 0.5315629244 0.4990994930 + 0.5541110039 0.5326650143 0.5002077222 + 0.5551608205 0.5337625146 0.5013095140 + 0.5562096238 0.5348572731 0.5024083853 + 0.5572584271 0.5359520912 0.5035073161 + 0.5583010912 0.5370396972 0.5045971274 + 0.5593425035 0.5381262898 0.5056862831 + 0.5603839159 0.5392122269 0.5067744851 + 0.5614247918 0.5402883887 0.5078564286 + 0.5624656081 0.5413644910 0.5089381933 + 0.5635035038 0.5424379706 0.5100173950 + 0.5645298958 0.5435034037 0.5110903978 + 0.5655562878 0.5445687771 0.5121634007 + 0.5665822029 0.5456321836 0.5132340789 + 0.5676072836 0.5466927290 0.5143020749 + 0.5686323047 0.5477532148 0.5153701901 + 0.5696542859 0.5488079190 0.5164343715 + 0.5706726909 0.5498570204 0.5174958110 + 0.5716910958 0.5509061813 0.5185571909 + 0.5727097988 0.5519514084 0.5196129084 + 0.5737286210 0.5529940128 0.5206657052 + 0.5747473836 0.5540364981 0.5217186213 + 0.5757570863 0.5550705791 0.5227680802 + 0.5767611861 0.5561003089 0.5238164067 + 0.5777652264 0.5571299195 0.5248646736 + 0.5787636042 0.5581539273 0.5259051919 + 0.5797588229 0.5591753721 0.5269432068 + 0.5807541013 0.5601968765 0.5279811025 + 0.5817455053 0.5612133145 0.5290176272 + 0.5827348232 0.5622273088 0.5300536156 + 0.5837240219 0.5632413030 0.5310897231 + 0.5847098231 0.5642498732 0.5321198106 + 0.5856931806 0.5652555823 0.5331475139 + 0.5866767168 0.5662612915 0.5341752768 + 0.5876535177 0.5672615767 0.5351998806 + 0.5886247158 0.5682581067 0.5362228155 + 0.5895959735 0.5692545772 0.5372456908 + 0.5905644894 0.5702462792 0.5382614732 + 0.5915299058 0.5712330937 0.5392717719 + 0.5924953222 0.5722199082 0.5402820110 + 0.5934591889 0.5732024908 0.5412889123 + 0.5944200754 0.5741782784 0.5422912836 + 0.5953810215 0.5751540065 0.5432937741 + 0.5963401794 0.5761274099 0.5442951918 + 0.5972915292 0.5770921111 0.5452939868 + 0.5982427001 0.5780568123 0.5462927222 + 0.5991939902 0.5790212750 0.5472911000 + 0.6001344919 0.5799819231 0.5482859015 + 0.6010748744 0.5809425116 0.5492805839 + 0.6020153761 0.5819031000 0.5502753258 + 0.6029484272 0.5828554034 0.5512647033 + 0.6038792729 0.5838056803 0.5522533059 + 0.6048101783 0.5847560167 0.5532417893 + 0.6057401896 0.5857036710 0.5542263985 + 0.6066694856 0.5866494179 0.5552083850 + 0.6075987220 0.5875951052 0.5561903119 + 0.6085264087 0.5885378718 0.5571714044 + 0.6094487906 0.5894731283 0.5581504703 + 0.6103712916 0.5904083252 0.5591297150 + 0.6112936735 0.5913434029 0.5601087213 + 0.6122087836 0.5922747254 0.5610769987 + 0.6131231785 0.5932055712 0.5620452762 + 0.6140375733 0.5941365957 0.5630136132 + 0.6149482131 0.5950686932 0.5639781952 + 0.6158558130 0.5960016251 0.5649409294 + 0.6167634130 0.5969344974 0.5659034848 + 0.6176698804 0.5978664160 0.5668659210 + 0.6185709834 0.5987945795 0.5678272843 + 0.6194720864 0.5997229218 0.5687887073 + 0.6203731894 0.6006512046 0.5697500706 + 0.6212695241 0.6015707254 0.5707088709 + 0.6221640706 0.6024879217 0.5716670752 + 0.6230587959 0.6034051180 0.5726253986 + 0.6239500046 0.6043199897 0.5735797882 + 0.6248329878 0.6052303910 0.5745280981 + 0.6257159710 0.6061406732 0.5754765272 + 0.6265990138 0.6070510149 0.5764248967 + 0.6274775267 0.6079521179 0.5773686171 + 0.6283550262 0.6088513732 0.5783116817 + 0.6292325258 0.6097506881 0.5792549253 + 0.6301056147 0.6106485724 0.5801956058 + 0.6309671998 0.6115432978 0.5811319947 + 0.6318287253 0.6124380231 0.5820685029 + 0.6326903105 0.6133326292 0.5830048919 + 0.6335496902 0.6142238975 0.5839343071 + 0.6344081163 0.6151139736 0.5848619938 + 0.6352664828 0.6160039902 0.5857896805 + 0.6361234188 0.6168932915 0.5867152214 + 0.6369684935 0.6177780032 0.5876327753 + 0.6378136277 0.6186627150 0.5885503292 + 0.6386587024 0.6195474267 0.5894678831 + 0.6395034194 0.6204267144 0.5903825164 + 0.6403477788 0.6213008165 0.5912950039 + 0.6411921978 0.6221749187 0.5922073722 + 0.6420364976 0.6230490208 0.5931199193 + 0.6428722143 0.6239190102 0.5940275788 + 0.6437057257 0.6247882843 0.5949348211 + 0.6445392966 0.6256574988 0.5958420038 + 0.6453729868 0.6265254021 0.5967481732 + 0.6462082863 0.6273844838 0.5976504087 + 0.6470435858 0.6282436848 0.5985525846 + 0.6478788853 0.6291028261 0.5994548202 + 0.6487107873 0.6299602985 0.6003562212 + 0.6495367289 0.6308152080 0.6012567878 + 0.6503624916 0.6316699982 0.6021572948 + 0.6511883736 0.6325249076 0.6030578017 + 0.6520127058 0.6333740950 0.6039531827 + 0.6528357863 0.6342192888 0.6048460007 + 0.6536588073 0.6350646019 0.6057388186 + 0.6544818878 0.6359099150 0.6066315174 + 0.6552997231 0.6367524266 0.6075202823 + 0.6561157107 0.6375942230 0.6084082127 + 0.6569316983 0.6384360194 0.6092960835 + 0.6577478051 0.6392776966 0.6101840734 + 0.6585525870 0.6401113272 0.6110618114 + 0.6593559980 0.6409441233 0.6119391918 + 0.6601594090 0.6417768002 0.6128165722 + 0.6609628201 0.6426095963 0.6136940122 + 0.6617612243 0.6434395909 0.6145706177 + 0.6625593901 0.6442695856 0.6154471040 + 0.6633576155 0.6450996995 0.6163237095 + 0.6641554832 0.6459290981 0.6171987057 + 0.6649441123 0.6467508078 0.6180636287 + 0.6657326818 0.6475725174 0.6189286113 + 0.6665213108 0.6483941078 0.6197934747 + 0.6673098207 0.6492155790 0.6206579804 + 0.6680960059 0.6500353217 0.6215201020 + 0.6688820720 0.6508548856 0.6223822236 + 0.6696683168 0.6516745090 0.6232442856 + 0.6704540849 0.6524934769 0.6241046190 + 0.6712335944 0.6533043981 0.6249533296 + 0.6720131040 0.6541153789 0.6258019209 + 0.6727924943 0.6549263000 0.6266505718 + 0.6735720038 0.6557372212 0.6274989247 + 0.6743516922 0.6565400958 0.6283429265 + 0.6751313806 0.6573429704 0.6291869879 + 0.6759110093 0.6581459045 0.6300309896 + 0.6766906977 0.6589487791 0.6308749914 + 0.6774597764 0.6597450972 0.6317095160 + 0.6782273054 0.6605407000 0.6325436831 + 0.6789947748 0.6613361835 0.6333777905 + 0.6797623038 0.6621317863 0.6342120171 + 0.6805222034 0.6629223824 0.6350417733 + 0.6812793016 0.6637114286 0.6358706951 + 0.6820363998 0.6645004153 0.6366994977 + 0.6827934980 0.6652892828 0.6375284195 + 0.6835458279 0.6660748124 0.6383498907 + 0.6842942834 0.6668576002 0.6391670704 + 0.6850426793 0.6676403880 0.6399844289 + 0.6857910752 0.6684231758 0.6408016086 + 0.6865373254 0.6692041755 0.6416165233 + 0.6872786283 0.6699815989 0.6424279809 + 0.6880199909 0.6707590222 0.6432394981 + 0.6887614131 0.6715363860 0.6440510154 + 0.6895024776 0.6723132730 0.6448624134 + 0.6902387142 0.6730847955 0.6456729770 + 0.6909748912 0.6738561988 0.6464836001 + 0.6917111278 0.6746276021 0.6472942829 + 0.6924473047 0.6753990054 0.6481049061 + 0.6931800246 0.6761628985 0.6489096880 + 0.6939114928 0.6769244075 0.6497132778 + 0.6946430206 0.6776859164 0.6505168080 + 0.6953744888 0.6784474254 0.6513202786 + 0.6961029768 0.6792098284 0.6521201730 + 0.6968262792 0.6799734235 0.6529155970 + 0.6975495815 0.6807370782 0.6537110806 + 0.6982728839 0.6815006733 0.6545065045 + 0.6989961863 0.6822643876 0.6553019285 + 0.6997179985 0.6830213070 0.6560959816 + 0.7004398108 0.6837782264 0.6568900943 + 0.7011616230 0.6845350862 0.6576842070 + 0.7018833756 0.6852920055 0.6584783792 + 0.7026001811 0.6860477924 0.6592714190 + 0.7033123970 0.6868026257 0.6600636244 + 0.7040244937 0.6875573993 0.6608558893 + 0.7047367096 0.6883121729 0.6616480947 + 0.7054488063 0.6890667081 0.6624394059 + 0.7061572075 0.6898154020 0.6632227898 + 0.7068657279 0.6905639768 0.6640061736 + 0.7075741887 0.6913126707 0.6647896171 + 0.7082825899 0.6920614243 0.6655731201 + 0.7089877129 0.6928064823 0.6663510203 + 0.7096893191 0.6935483217 0.6671249866 + 0.7103909254 0.6942901015 0.6678988934 + 0.7110924125 0.6950318813 0.6686729193 + 0.7117940187 0.6957737207 0.6694468260 + 0.7124900222 0.6965091825 0.6702172756 + 0.7131854892 0.6972442269 0.6709877253 + 0.7138808966 0.6979792118 0.6717581749 + 0.7145763040 0.6987141967 0.6725286841 + 0.7152705789 0.6994475722 0.6732978225 + 0.7159615159 0.7001774907 0.6740645170 + 0.7166523933 0.7009072900 0.6748312116 + 0.7173433900 0.7016372085 0.6755979061 + 0.7180343270 0.7023670077 0.6763646007 + 0.7187235951 0.7030938864 0.6771286130 + 0.7194116116 0.7038189769 0.6778911948 + 0.7200996876 0.7045441866 0.6786538959 + 0.7207878232 0.7052692771 0.6794165969 + 0.7214757800 0.7059944272 0.6801792979 + 0.7221612930 0.7067067027 0.6809418201 + 0.7228463292 0.7074177265 0.6817042828 + 0.7235314250 0.7081285715 0.6824668050 + 0.7242164016 0.7088394761 0.6832293868 + 0.7249004245 0.7095499039 0.6839907765 + 0.7255744934 0.7102571726 0.6847469211 + 0.7262486219 0.7109643817 0.6855030060 + 0.7269226909 0.7116715908 0.6862590909 + 0.7275968194 0.7123787999 0.6870152950 + 0.7282711864 0.7130823135 0.6877691150 + 0.7289463878 0.7137774229 0.6885187030 + 0.7296215892 0.7144724131 0.6892682910 + 0.7302967906 0.7151675224 0.6900178790 + 0.7309719920 0.7158625722 0.6907675266 + 0.7316445112 0.7165569067 0.6915168762 + 0.7323129177 0.7172502875 0.6922662854 + 0.7329813838 0.7179437280 0.6930155754 + 0.7336499095 0.7186371088 0.6937649846 + 0.7343183160 0.7193304896 0.6945142746 + 0.7349863052 0.7200188041 0.6952630281 + 0.7356538177 0.7207021713 0.6960111856 + 0.7363212705 0.7213857174 0.6967594028 + 0.7369887829 0.7220690846 0.6975076199 + 0.7376562953 0.7227525711 0.6982558966 + 0.7383213043 0.7234362960 0.6990029812 + 0.7389839888 0.7241200805 0.6997492909 + 0.7396466136 0.7248039842 0.7004957199 + 0.7403091788 0.7254878879 0.7012420297 + 0.7409719229 0.7261717916 0.7019883990 + 0.7416300774 0.7268511057 0.7027307153 + 0.7422838807 0.7275264263 0.7034698725 + 0.7429378033 0.7282016873 0.7042092085 + 0.7435916066 0.7288768888 0.7049484849 + 0.7442454100 0.7295522094 0.7056878209 + 0.7448980212 0.7302259803 0.7064262033 + 0.7455489039 0.7308980823 0.7071638703 + 0.7461997867 0.7315703034 0.7079014778 + 0.7468507886 0.7322424054 0.7086392045 + 0.7475016713 0.7329145074 0.7093768120 + 0.7481493950 0.7335844040 0.7101135850 + 0.7487897873 0.7342495918 0.7108489275 + 0.7494302988 0.7349148989 0.7115842104 + 0.7500706911 0.7355802059 0.7123194933 + 0.7507110834 0.7362453938 0.7130547762 + 0.7513517141 0.7369098067 0.7137894034 + 0.7519931793 0.7375693917 0.7145212889 + 0.7526347041 0.7382289171 0.7152531743 + 0.7532762289 0.7388885021 0.7159851789 + 0.7539176941 0.7395480871 0.7167171240 + 0.7545592189 0.7402076125 0.7174490094 + 0.7551949024 0.7408636212 0.7181727290 + 0.7558298707 0.7415192723 0.7188962102 + 0.7564650178 0.7421751022 0.7196195722 + 0.7570999861 0.7428308129 0.7203431129 + 0.7577350736 0.7434865236 0.7210665941 + 0.7583732009 0.7441366911 0.7217879295 + 0.7590131760 0.7447838783 0.7225083709 + 0.7596532106 0.7454311252 0.7232288122 + 0.7602931261 0.7460783124 0.7239493132 + 0.7609331012 0.7467254996 0.7246696949 + 0.7615718842 0.7473719120 0.7253888845 + 0.7622076869 0.7480165958 0.7261058092 + 0.7628436089 0.7486613989 0.7268226743 + 0.7634794116 0.7493060827 0.7275395989 + 0.7641152740 0.7499508858 0.7282565236 + 0.7647510767 0.7505956888 0.7289733887 + 0.7653750777 0.7512348294 0.7296857238 + 0.7659978271 0.7518734932 0.7303978801 + 0.7666205168 0.7525122166 0.7311100960 + 0.7672433257 0.7531508803 0.7318223119 + 0.7678660154 0.7537896037 0.7325345278 + 0.7684878707 0.7544282079 0.7332416177 + 0.7691087723 0.7550666928 0.7339441776 + 0.7697296739 0.7557051778 0.7346469164 + 0.7703505754 0.7563437223 0.7353495955 + 0.7709714770 0.7569822073 0.7360522151 + 0.7715923786 0.7576206923 0.7367547154 + 0.7722045183 0.7582557797 0.7374516726 + 0.7728161812 0.7588909268 0.7381488085 + 0.7734280229 0.7595258951 0.7388458848 + 0.7740396857 0.7601609230 0.7395429015 + 0.7746515274 0.7607960105 0.7402399778 + 0.7752640843 0.7614319921 0.7409328818 + 0.7758777738 0.7620692253 0.7416213751 + 0.7764915824 0.7627063990 0.7423098087 + 0.7771053910 0.7633436918 0.7429983020 + 0.7777191997 0.7639809251 0.7436866760 + 0.7783328891 0.7646180987 0.7443752289 + 0.7789419293 0.7652487159 0.7450602055 + 0.7795497179 0.7658780217 0.7457447052 + 0.7801573873 0.7665072083 0.7464292049 + 0.7807651758 0.7671365142 0.7471137047 + 0.7813730240 0.7677657008 0.7477982044 + 0.7819799781 0.7683938742 0.7484809160 + 0.7825825810 0.7690163851 0.7491562963 + 0.7831851840 0.7696390152 0.7498317957 + 0.7837877870 0.7702615261 0.7505072951 + 0.7843903899 0.7708839774 0.7511827946 + 0.7849929929 0.7715066075 0.7518582940 + 0.7855939269 0.7721267939 0.7525311708 + 0.7861924767 0.7727441788 0.7532013059 + 0.7867910862 0.7733615041 0.7538713813 + 0.7873896956 0.7739788890 0.7545415163 + 0.7879884243 0.7745962143 0.7552115917 + 0.7885869741 0.7752135992 0.7558817267 + 0.7891780734 0.7758283019 0.7565454841 + 0.7897650003 0.7764415741 0.7572066784 + 0.7903518081 0.7770550251 0.7578678131 + 0.7909386158 0.7776682973 0.7585290074 + 0.7915254831 0.7782816291 0.7591902018 + 0.7921122909 0.7788950205 0.7598512769 + 0.7926985025 0.7795063257 0.7605091929 + 0.7932845950 0.7801172137 0.7611665130 + 0.7938706875 0.7807281017 0.7618237734 + 0.7944567800 0.7813388705 0.7624810934 + 0.7950428724 0.7819498181 0.7631384134 + 0.7956290245 0.7825607061 0.7637956738 + 0.7962080836 0.7831704021 0.7644450068 + 0.7967863083 0.7837799191 0.7650939226 + 0.7973645926 0.7843893766 0.7657428980 + 0.7979428768 0.7849990129 0.7663918138 + 0.7985212207 0.7856084704 0.7670407295 + 0.7990993857 0.7862181067 0.7676897049 + 0.7996805906 0.7868278027 0.7683331966 + 0.8002619147 0.7874376178 0.7689768076 + 0.8008431792 0.7880473733 0.7696204185 + 0.8014245033 0.7886571884 0.7702640295 + 0.8020058274 0.7892670035 0.7709075212 + 0.8025872111 0.7898766994 0.7715510726 + 0.8031632900 0.7904822826 0.7721858025 + 0.8037390113 0.7910876274 0.7728202939 + 0.8043146133 0.7916929126 0.7734547853 + 0.8048902750 0.7922981977 0.7740892768 + 0.8054659963 0.7929034829 0.7747238278 + 0.8060415983 0.7935088277 0.7753583193 + 0.8066141009 0.7941111922 0.7759894729 + 0.8071860075 0.7947131991 0.7766203284 + 0.8077577949 0.7953152061 0.7772511244 + 0.8083297014 0.7959172130 0.7778819203 + 0.8089016080 0.7965192199 0.7785127163 + 0.8094733953 0.7971212268 0.7791435122 + 0.8100445867 0.7977176905 0.7797755003 + 0.8106154203 0.7983120084 0.7804080248 + 0.8111861944 0.7989063859 0.7810403705 + 0.8117570281 0.7995008230 0.7816727757 + 0.8123278022 0.8000950813 0.7823051810 + 0.8128986955 0.8006895185 0.7829377055 + 0.8134648800 0.8012806177 0.7835683227 + 0.8140262961 0.8018686175 0.7841975093 + 0.8145877123 0.8024566174 0.7848265767 + 0.8151491284 0.8030446172 0.7854558229 + 0.8157104254 0.8036326170 0.7860850096 + 0.8162717819 0.8042206168 0.7867141962 + 0.8168334961 0.8048074245 0.7873411179 + 0.8173961043 0.8053904772 0.7879621983 + 0.8179587126 0.8059734702 0.7885832787 + 0.8185213208 0.8065565825 0.7892044187 + 0.8190839291 0.8071395755 0.7898254991 + 0.8196464181 0.8077226877 0.7904465795 + 0.8202090263 0.8083056808 0.7910677195 + 0.8207656741 0.8088853955 0.7916854024 + 0.8213217258 0.8094648123 0.7923029065 + 0.8218777776 0.8100442290 0.7929204702 + 0.8224338293 0.8106235862 0.7935379744 + 0.8229898214 0.8112030029 0.7941555977 + 0.8235458136 0.8117823005 0.7947731018 + 0.8241016269 0.8123605251 0.7953892946 + 0.8246573806 0.8129374981 0.7960044146 + 0.8252130747 0.8135144711 0.7966195941 + 0.8257688284 0.8140915036 0.7972347140 + 0.8263245225 0.8146684766 0.7978497744 + 0.8268802166 0.8152455091 0.7984648943 + 0.8274357915 0.8158224225 0.7990797758 + 0.8279883265 0.8163983822 0.7996929288 + 0.8285408020 0.8169744015 0.8003060222 + 0.8290932178 0.8175503016 0.8009191155 + 0.8296456933 0.8181263208 0.8015322089 + 0.8301981091 0.8187022805 0.8021453023 + 0.8307505846 0.8192781806 0.8027585149 + 0.8312999010 0.8198543191 0.8033677936 + 0.8318461776 0.8204303980 0.8039743900 + 0.8323925138 0.8210065961 0.8045809269 + 0.8329387903 0.8215826750 0.8051874042 + 0.8334850073 0.8221588731 0.8057940006 + 0.8340312839 0.8227350116 0.8064004779 + 0.8345776200 0.8233110905 0.8070070148 + 0.8351238966 0.8238831758 0.8076115251 + 0.8356701732 0.8244549036 0.8082157969 + 0.8362163901 0.8250266910 0.8088201880 + 0.8367627263 0.8255984783 0.8094245195 + 0.8373090029 0.8261703253 0.8100289106 + 0.8378552794 0.8267419934 0.8106333017 + 0.8383994102 0.8273130059 0.8112372160 + 0.8389375210 0.8278818130 0.8118401766 + 0.8394755125 0.8284506202 0.8124431968 + 0.8400135040 0.8290194273 0.8130462170 + 0.8405516148 0.8295882940 0.8136492968 + 0.8410896063 0.8301571012 0.8142523170 + 0.8416277170 0.8307259083 0.8148552775 + 0.8421646953 0.8312906027 0.8154578805 + 0.8427007198 0.8318520188 0.8160601258 + 0.8432368040 0.8324133754 0.8166623712 + 0.8437728882 0.8329747915 0.8172646761 + 0.8443089128 0.8335362077 0.8178669214 + 0.8448449969 0.8340976238 0.8184692264 + 0.8453810811 0.8346589208 0.8190714717 + 0.8459135294 0.8352158070 0.8196697235 + 0.8464447260 0.8357713223 0.8202667832 + 0.8469758034 0.8363267183 0.8208639026 + 0.8475070000 0.8368821740 0.8214610815 + 0.8480380774 0.8374376297 0.8220582008 + 0.8485692739 0.8379930854 0.8226553202 + 0.8491004705 0.8385484815 0.8232524991 + 0.8496297002 0.8390995860 0.8238487840 + 0.8501586914 0.8396500945 0.8244450092 + 0.8506876230 0.8402007222 0.8250411749 + 0.8512166142 0.8407511711 0.8256375194 + 0.8517454863 0.8413017988 0.8262336850 + 0.8522744775 0.8418524265 0.8268299103 + 0.8528034091 0.8424028754 0.8274261951 + 0.8533318043 0.8429502249 0.8280221224 + 0.8538600802 0.8434972763 0.8286179900 + 0.8543884158 0.8440443873 0.8292139173 + 0.8549165726 0.8445914984 0.8298097849 + 0.8554449081 0.8451387286 0.8304055929 + 0.8559731841 0.8456857800 0.8310015202 + 0.8565015197 0.8462328911 0.8315973878 + 0.8570210934 0.8467777967 0.8321936727 + 0.8575400710 0.8473225236 0.8327900171 + 0.8580591083 0.8478673100 0.8333863020 + 0.8585780859 0.8484120965 0.8339825869 + 0.8590971231 0.8489568233 0.8345788717 + 0.8596161008 0.8495016098 0.8351752162 + 0.8601350784 0.8500462770 0.8357715011 + 0.8606511950 0.8505902290 0.8363643289 + 0.8611670136 0.8511340022 0.8369567990 + 0.8616827726 0.8516777754 0.8375492096 + 0.8621984720 0.8522216082 0.8381416798 + 0.8627142906 0.8527653813 0.8387340903 + 0.8632301092 0.8533092141 0.8393266201 + 0.8637458086 0.8538529277 0.8399189711 + 0.8642572165 0.8543968201 0.8405116796 + 0.8647668958 0.8549407721 0.8411043286 + 0.8652765751 0.8554847240 0.8416969776 + 0.8657861948 0.8560286164 0.8422896862 + 0.8662958741 0.8565725088 0.8428823948 + 0.8668056130 0.8571164012 0.8434751034 + 0.8673152924 0.8576604128 0.8440678120 + 0.8678231835 0.8582047224 0.8446561098 + 0.8683292866 0.8587492704 0.8452408910 + 0.8688353896 0.8592939973 0.8458256721 + 0.8693414927 0.8598386049 0.8464105129 + 0.8698475957 0.8603832126 0.8469954133 + 0.8703536987 0.8609278798 0.8475801945 + 0.8708598018 0.8614724874 0.8481649756 + 0.8713654876 0.8620167971 0.8487496972 + 0.8718695045 0.8625596166 0.8493341804 + 0.8723735213 0.8631023765 0.8499186039 + 0.8728774786 0.8636453152 0.8505030870 + 0.8733814955 0.8641880751 0.8510875106 + 0.8738855124 0.8647310138 0.8516719937 + 0.8743895292 0.8652737737 0.8522564173 + 0.8748934865 0.8658165932 0.8528409004 + 0.8753938079 0.8663538098 0.8534224033 + 0.8758934140 0.8668900728 0.8540034890 + 0.8763929009 0.8674263954 0.8545845747 + 0.8768925071 0.8679627180 0.8551657796 + 0.8773921132 0.8684989810 0.8557469249 + 0.8778917193 0.8690353036 0.8563281298 + 0.8783912063 0.8695716262 0.8569092155 + 0.8788912296 0.8701056838 0.8574905992 + 0.8793917894 0.8706367016 0.8580724001 + 0.8798922896 0.8711677194 0.8586542010 + 0.8803929090 0.8716986179 0.8592360020 + 0.8808934093 0.8722295761 0.8598178029 + 0.8813939095 0.8727605939 0.8603996038 + 0.8818945289 0.8732916117 0.8609814048 + 0.8823950291 0.8738226295 0.8615632057 + 0.8828893900 0.8743497729 0.8621373773 + 0.8833830953 0.8748766780 0.8627110124 + 0.8838766813 0.8754035234 0.8632845879 + 0.8843703866 0.8759304285 0.8638582826 + 0.8848639727 0.8764572740 0.8644319177 + 0.8853576779 0.8769841194 0.8650054932 + 0.8858513236 0.8775110245 0.8655791879 + 0.8863434792 0.8780369163 0.8661512136 + 0.8868324161 0.8785607815 0.8667200804 + 0.8873211741 0.8790847063 0.8672890067 + 0.8878101110 0.8796085715 0.8678578734 + 0.8882989287 0.8801324964 0.8684269190 + 0.8887878060 0.8806564212 0.8689957857 + 0.8892766237 0.8811802864 0.8695647120 + 0.8897655010 0.8817042112 0.8701335788 + 0.8902524710 0.8822268844 0.8707010746 + 0.8907384276 0.8827490807 0.8712677956 + 0.8912243247 0.8832712173 0.8718345165 + 0.8917102218 0.8837932944 0.8724011779 + 0.8921961784 0.8843153715 0.8729678988 + 0.8926820755 0.8848375082 0.8735346794 + 0.8931679726 0.8853595853 0.8741014004 + 0.8936539292 0.8858817220 0.8746681213 + 0.8941388726 0.8864020705 0.8752362132 + 0.8946238160 0.8869222999 0.8758044243 + 0.8951086998 0.8874425292 0.8763725758 + 0.8955935836 0.8879626989 0.8769407272 + 0.8960784078 0.8884829283 0.8775088787 + 0.8965632915 0.8890030980 0.8780770898 + 0.8970481753 0.8895233274 0.8786453009 + 0.8975331187 0.8900429010 0.8792127967 + 0.8980188966 0.8905553818 0.8797736764 + 0.8985047936 0.8910679221 0.8803346753 + 0.8989905715 0.8915804029 0.8808956146 + 0.8994764090 0.8920928836 0.8814566135 + 0.8999621868 0.8926054239 0.8820174932 + 0.9004480243 0.8931179047 0.8825784922 + 0.9009338021 0.8936303854 0.8831393719 + 0.9014185071 0.8941423297 0.8836997151 + 0.9018970132 0.8946514130 0.8842570186 + 0.9023755193 0.8951604962 0.8848143816 + 0.9028540850 0.8956695795 0.8853718042 + 0.9033325911 0.8961787224 0.8859291077 + 0.9038110971 0.8966878057 0.8864864707 + 0.9042896032 0.8971968889 0.8870438933 + 0.9047682285 0.8977059722 0.8876011968 + 0.9052457213 0.8982139826 0.8881582022 + 0.9057186246 0.8987172842 0.8887138963 + 0.9061915278 0.8992205858 0.8892694712 + 0.9066643715 0.8997240067 0.8898251057 + 0.9071372747 0.9002273083 0.8903806806 + 0.9076101780 0.9007306099 0.8909363747 + 0.9080830812 0.9012339711 0.8914920092 + 0.9085559845 0.9017372727 0.8920475841 + 0.9090284705 0.9022399783 0.8926029801 + 0.9094979763 0.9027382135 0.8931568265 + 0.9099674821 0.9032363892 0.8937106133 + 0.9104369879 0.9037346244 0.8942644000 + 0.9109064937 0.9042328000 0.8948181868 + 0.9113758802 0.9047309756 0.8953719735 + 0.9118453860 0.9052292109 0.8959258795 + 0.9123148918 0.9057273865 0.8964797258 + 0.9127843976 0.9062256217 0.8970335126 + 0.9132521152 0.9067198038 0.8975815177 + 0.9137197137 0.9072139859 0.8981294036 + 0.9141873121 0.9077082276 0.8986774087 + 0.9146549106 0.9082024097 0.8992254138 + 0.9151225090 0.9086964726 0.8997734189 + 0.9155901074 0.9091907144 0.9003213048 + 0.9160577059 0.9096848965 0.9008693099 + 0.9165253043 0.9101790786 0.9014173150 + 0.9169932008 0.9106711745 0.9019637108 + 0.9174610972 0.9111626744 0.9025096893 + 0.9179289937 0.9116541147 0.9030556083 + 0.9183970094 0.9121456146 0.9036015868 + 0.9188649058 0.9126371145 0.9041476250 + 0.9193328023 0.9131284952 0.9046934843 + 0.9198008180 0.9136199951 0.9052395225 + 0.9202687144 0.9141113758 0.9057855010 + 0.9207351208 0.9146016240 0.9063286781 + 0.9211995006 0.9150900841 0.9068685770 + 0.9216638803 0.9155786037 0.9074085951 + 0.9221282005 0.9160671234 0.9079484940 + 0.9225925803 0.9165555835 0.9084883928 + 0.9230570197 0.9170441031 0.9090284109 + 0.9235213995 0.9175326228 0.9095683098 + 0.9239857793 0.9180210829 0.9101082087 + 0.9244499803 0.9185094237 0.9106479287 + 0.9249091148 0.9189893007 0.9111825824 + 0.9253680706 0.9194691777 0.9117174149 + 0.9258272052 0.9199491143 0.9122521281 + 0.9262862802 0.9204289913 0.9127867818 + 0.9267452955 0.9209089279 0.9133216143 + 0.9272043705 0.9213888049 0.9138563275 + 0.9276635051 0.9218686819 0.9143911004 + 0.9281225204 0.9223486781 0.9149258137 + 0.9285796285 0.9228286147 0.9154574275 + 0.9290350080 0.9233084917 0.9159867167 + 0.9294903278 0.9237884879 0.9165160060 + 0.9299457073 0.9242684245 0.9170452952 + 0.9304010868 0.9247484207 0.9175745845 + 0.9308564067 0.9252282977 0.9181038737 + 0.9313117862 0.9257081747 0.9186331034 + 0.9317672253 0.9261881709 0.9191623926 + 0.9322224855 0.9266681075 0.9196916819 + 0.9326751828 0.9271426201 0.9202163219 + 0.9331278205 0.9276170135 0.9207410216 + 0.9335802794 0.9280914068 0.9212656021 + 0.9340329170 0.9285659194 0.9217903018 + 0.9344854951 0.9290403128 0.9223148823 + 0.9349380732 0.9295147061 0.9228395224 + 0.9353907108 0.9299890995 0.9233642220 + 0.9358432293 0.9304634929 0.9238888025 + 0.9362943769 0.9309374094 0.9244117737 + 0.9367427230 0.9314103723 0.9249315858 + 0.9371910095 0.9318832755 0.9254513979 + 0.9376392961 0.9323561788 0.9259712100 + 0.9380875230 0.9328290820 0.9264910221 + 0.9385358095 0.9333021045 0.9270107746 + 0.9389840961 0.9337750077 0.9275305867 + 0.9394323230 0.9342479110 0.9280503988 + 0.9398806095 0.9347208738 0.9285702109 + 0.9403269887 0.9351912737 0.9290875196 + 0.9407718778 0.9356600046 0.9296032190 + 0.9412168264 0.9361286759 0.9301189184 + 0.9416617155 0.9365974069 0.9306346178 + 0.9421066046 0.9370660186 0.9311503172 + 0.9425514936 0.9375346899 0.9316660762 + 0.9429963827 0.9380034208 0.9321817756 + 0.9434412718 0.9384720922 0.9326974750 + 0.9438862205 0.9389408231 0.9332131743 + 0.9443271160 0.9394043088 0.9337257743 + 0.9447665811 0.9398661256 0.9342374206 + 0.9452061057 0.9403278232 0.9347491264 + 0.9456455708 0.9407895803 0.9352607131 + 0.9460850954 0.9412513971 0.9357724190 + 0.9465246201 0.9417132139 0.9362840056 + 0.9469640851 0.9421749711 0.9367957115 + 0.9474036098 0.9426367879 0.9373072982 + 0.9478430748 0.9430986047 0.9378190041 + 0.9482764006 0.9435576797 0.9383267164 + 0.9487082958 0.9440163970 0.9388335943 + 0.9491403103 0.9444751143 0.9393405914 + 0.9495722055 0.9449337125 0.9398475289 + 0.9500042200 0.9453923702 0.9403545260 + 0.9504361153 0.9458510280 0.9408614039 + 0.9508681297 0.9463096857 0.9413684011 + 0.9513000250 0.9467684031 0.9418752789 + 0.9517319202 0.9472270012 0.9423822761 + 0.9521591067 0.9476765990 0.9428793192 + 0.9525852203 0.9481241703 0.9433743954 + 0.9530112147 0.9485718012 0.9438694119 + 0.9534373283 0.9490193725 0.9443644881 + 0.9538633823 0.9494670033 0.9448595047 + 0.9542894959 0.9499145746 0.9453545809 + 0.9547154903 0.9503622055 0.9458495975 + 0.9551416039 0.9508097768 0.9463446736 + 0.9555677176 0.9512574077 0.9468396902 + 0.9559904933 0.9517037272 0.9473326802 + 0.9564120173 0.9521496296 0.9478248954 + 0.9568334818 0.9525954723 0.9483171105 + 0.9572550058 0.9530413151 0.9488093257 + 0.9576764703 0.9534872174 0.9493014812 + 0.9580979943 0.9539331198 0.9497936964 + 0.9585195184 0.9543790221 0.9502857924 + 0.9589411020 0.9548248053 0.9507780075 + 0.9593626261 0.9552707076 0.9512702227 + 0.9597812295 0.9557142258 0.9517591000 + 0.9601970911 0.9561554790 0.9522449970 + 0.9606130123 0.9565967917 0.9527308941 + 0.9610288739 0.9570381045 0.9532167912 + 0.9614447951 0.9574794769 0.9537026286 + 0.9618607163 0.9579207897 0.9541885257 + 0.9622765779 0.9583621025 0.9546744227 + 0.9626924992 0.9588034153 0.9551603198 + 0.9631084204 0.9592447281 0.9556462169 + 0.9635230899 0.9596858025 0.9561312199 + 0.9639335871 0.9601259232 0.9566131830 + 0.9643440843 0.9605661035 0.9570953250 + 0.9647545815 0.9610062838 0.9575772882 + 0.9651650786 0.9614465237 0.9580593705 + 0.9655756950 0.9618865848 0.9585415125 + 0.9659861922 0.9623268247 0.9590234756 + 0.9663966894 0.9627670050 0.9595056176 + 0.9668071866 0.9632071257 0.9599875808 + 0.9672178030 0.9636473060 0.9604697227 + 0.9676215053 0.9640840888 0.9609463215 + 0.9680240750 0.9645202756 0.9614219069 + 0.9684265852 0.9649565220 0.9618974924 + 0.9688292146 0.9653928280 0.9623731971 + 0.9692317247 0.9658290148 0.9628487825 + 0.9696341753 0.9662652016 0.9633244276 + 0.9700368047 0.9667013884 0.9638000727 + 0.9704393148 0.9671375751 0.9642757177 + 0.9708418846 0.9675738215 0.9647514224 + 0.9712424874 0.9680083990 0.9652252197 + 0.9716396928 0.9684401751 0.9656959176 + 0.9720370173 0.9688720703 0.9661666155 + 0.9724342227 0.9693039060 0.9666373730 + 0.9728314877 0.9697356820 0.9671080709 + 0.9732288122 0.9701675177 0.9675788283 + 0.9736260176 0.9705992937 0.9680495858 + 0.9740232825 0.9710311294 0.9685202837 + 0.9744204879 0.9714629054 0.9689909816 + 0.9748178124 0.9718946815 0.9694617987 + 0.9752097726 0.9723225832 0.9699270725 + 0.9756003022 0.9727494121 0.9703910947 + 0.9759908915 0.9731763005 0.9708551168 + 0.9763814807 0.9736031294 0.9713190794 + 0.9767721295 0.9740298986 0.9717831016 + 0.9771627188 0.9744567275 0.9722471833 + 0.9775531888 0.9748836160 0.9727112055 + 0.9779437780 0.9753103852 0.9731752276 + 0.9783344269 0.9757372141 0.9736391902 + 0.9787241220 0.9761633873 0.9741021991 + 0.9791072011 0.9765844941 0.9745585918 + 0.9794903994 0.9770057201 0.9750149846 + 0.9798734784 0.9774268866 0.9754713178 + 0.9802566767 0.9778481126 0.9759277105 + 0.9806398153 0.9782692194 0.9763841033 + 0.9810230136 0.9786903858 0.9768404961 + 0.9814060926 0.9791116118 0.9772968888 + 0.9817892909 0.9795327783 0.9777532220 + 0.9821724296 0.9799538851 0.9782096148 + 0.9825515747 0.9803730249 0.9786626101 + 0.9829235077 0.9807882905 0.9791095257 + 0.9832953811 0.9812036157 0.9795563221 + 0.9836673141 0.9816188812 0.9800031781 + 0.9840391874 0.9820342064 0.9804500937 + 0.9844111204 0.9824494720 0.9808968902 + 0.9847829938 0.9828647971 0.9813438058 + 0.9851549268 0.9832801223 0.9817907214 + 0.9855268002 0.9836953878 0.9822375178 + 0.9858986735 0.9841107130 0.9826843739 + 0.9862666130 0.9845234156 0.9831274152 + 0.9866302013 0.9849331975 0.9835664034 + 0.9869937897 0.9853429794 0.9840053916 + 0.9873573780 0.9857528210 0.9844443798 + 0.9877210259 0.9861627221 0.9848833084 + 0.9880846143 0.9865725040 0.9853222966 + 0.9884482026 0.9869822860 0.9857612848 + 0.9888117909 0.9873921275 0.9862002730 + 0.9891753793 0.9878020287 0.9866393209 + 0.9895390272 0.9882118106 0.9870783091 + 0.9898961782 0.9886143804 0.9875144958 + 0.9902471900 0.9890102744 0.9879482985 + 0.9905983210 0.9894062281 0.9883821011 + 0.9909493923 0.9898021221 0.9888159037 + 0.9913004041 0.9901980758 0.9892497063 + 0.9916514754 0.9905940294 0.9896833897 + 0.9920024872 0.9909899235 0.9901171923 + 0.9923536181 0.9913858175 0.9905509949 + 0.9927045703 0.9917817116 0.9909847975 + 0.9930557013 0.9921776056 0.9914186001 + 0.9934034944 0.9925646186 0.9918447733 + 0.9937471747 0.9929406047 0.9922618866 + 0.9940909147 0.9933164716 0.9926788807 + 0.9944345951 0.9936925173 0.9930958748 + 0.9947782755 0.9940683842 0.9935129881 + 0.9951220155 0.9944443703 0.9939299822 + 0.9954656959 0.9948204160 0.9943469763 + 0.9958093762 0.9951962829 0.9947639704 + 0.9961531162 0.9955723286 0.9951810837 + 0.9964967966 0.9959481955 0.9955980778 + 0.9968330860 0.9963219166 0.9960101843 + 0.9971498251 0.9966897964 0.9964091182 + 0.9974665046 0.9970576167 0.9968081117 + 0.9977831841 0.9974253774 0.9972071052 + 0.9980999231 0.9977931976 0.9976060987 + 0.9984164834 0.9981610179 0.9980050921 + 0.9987332225 0.9985287786 0.9984040856 + 0.9990499020 0.9988965988 0.9988030195 + 0.9993665814 0.9992644191 0.9992020130 + 0.9996833205 0.9996321797 0.9996010065 + 1.0000000000 1.0000000000 1.0000000000 +} diff --git a/rpplugins/color_correction/resources/film_luts_raw/agfa_advantix_200.spi1d b/rpplugins/color_correction/resources/film_luts_raw/agfa_advantix_200.spi1d new file mode 100644 index 0000000..7492b41 --- /dev/null +++ b/rpplugins/color_correction/resources/film_luts_raw/agfa_advantix_200.spi1d @@ -0,0 +1,1030 @@ +Version 1 +From 0.0 1.0 +Length 1024 +Components 3 +{ + 0.0000000000 0.0000000000 0.0000000000 + 0.0109453099 0.0095550315 0.0076129269 + 0.0205393303 0.0180988703 0.0146826003 + 0.0290690009 0.0255930703 0.0210563708 + 0.0365057997 0.0324602798 0.0267342404 + 0.0431397706 0.0389092602 0.0319225714 + 0.0493469499 0.0448722206 0.0368033797 + 0.0553121008 0.0504292287 0.0415878706 + 0.0610060990 0.0556044616 0.0463291109 + 0.0664596632 0.0604789183 0.0508504696 + 0.0717297420 0.0651700869 0.0551753603 + 0.0767887011 0.0697173625 0.0594077297 + 0.0815975219 0.0740136728 0.0635364205 + 0.0862075612 0.0781842917 0.0675580502 + 0.0907116681 0.0822909772 0.0713816136 + 0.0950955972 0.0863237828 0.0743237808 + 0.0993374512 0.0902062133 0.0773941725 + 0.1034374982 0.0940194428 0.0811215192 + 0.1073296964 0.0977483913 0.0852948874 + 0.1110906973 0.1014209017 0.0893627778 + 0.1147643998 0.1050138026 0.0926783979 + 0.1184094027 0.1085262001 0.0958950967 + 0.1220393032 0.1120131016 0.0990428701 + 0.1255874038 0.1154666021 0.1021654978 + 0.1290600002 0.1188692003 0.1052715033 + 0.1324646026 0.1222466975 0.1083573997 + 0.1358134001 0.1256064028 0.1113879010 + 0.1391503960 0.1289401054 0.1143847033 + 0.1424382031 0.1322277933 0.1173340008 + 0.1457035989 0.1354801953 0.1201964989 + 0.1489387006 0.1386919022 0.1230240986 + 0.1521472931 0.1418765932 0.1258170009 + 0.1553370059 0.1450258046 0.1285797060 + 0.1584853977 0.1481391937 0.1313088983 + 0.1615826935 0.1512455940 0.1340118051 + 0.1646398008 0.1543205976 0.1366993934 + 0.1676366031 0.1573432982 0.1393682063 + 0.1705628037 0.1603267044 0.1420211941 + 0.1734506935 0.1632660031 0.1446440071 + 0.1762887985 0.1661476046 0.1472647935 + 0.1791007072 0.1689998060 0.1498612016 + 0.1818982959 0.1718225926 0.1524337977 + 0.1846773028 0.1746128052 0.1549834013 + 0.1874344051 0.1773594022 0.1575088948 + 0.1901603937 0.1800664961 0.1600168049 + 0.1928523034 0.1827678978 0.1625131071 + 0.1955167055 0.1854266971 0.1649871022 + 0.1981182992 0.1880469024 0.1674250066 + 0.2006929070 0.1906183958 0.1698420942 + 0.2032330930 0.1931630969 0.1722377986 + 0.2057420015 0.1956868023 0.1746356040 + 0.2082346976 0.1981967986 0.1770364046 + 0.2106983960 0.2006848007 0.1794321984 + 0.2131627053 0.2031618059 0.1818124950 + 0.2156358063 0.2056335062 0.1841809005 + 0.2180998027 0.2080969065 0.1865282953 + 0.2205528021 0.2105540931 0.1888633072 + 0.2229813933 0.2129819989 0.1911772937 + 0.2253869027 0.2154051960 0.1934747994 + 0.2277887017 0.2178180069 0.1957782060 + 0.2301833928 0.2201987058 0.1980752051 + 0.2325472981 0.2225521058 0.2003640980 + 0.2348767966 0.2248626053 0.2026430070 + 0.2371928990 0.2271340042 0.2049131989 + 0.2394970059 0.2293829024 0.2071806937 + 0.2417781949 0.2316153049 0.2094416022 + 0.2440516949 0.2338470966 0.2117109001 + 0.2463241965 0.2360679954 0.2139746994 + 0.2485778928 0.2382649034 0.2162466943 + 0.2508257926 0.2404524982 0.2185126990 + 0.2530736923 0.2426279038 0.2207739949 + 0.2553015947 0.2447896004 0.2230270952 + 0.2575267851 0.2469552010 0.2252774984 + 0.2597568035 0.2491303980 0.2275131047 + 0.2619835138 0.2513048947 0.2297354937 + 0.2641938031 0.2534686029 0.2319502980 + 0.2663998902 0.2556251884 0.2341517955 + 0.2686052918 0.2577697039 0.2363480031 + 0.2708081007 0.2599022090 0.2385403067 + 0.2730022967 0.2620306909 0.2407180965 + 0.2751887143 0.2641496956 0.2428912967 + 0.2773590982 0.2662425041 0.2450589985 + 0.2795172036 0.2683148086 0.2472172976 + 0.2816726863 0.2703753114 0.2493720949 + 0.2838136852 0.2724193931 0.2515229881 + 0.2859255075 0.2744517922 0.2536627948 + 0.2880168855 0.2764849067 0.2557986081 + 0.2901124954 0.2785145044 0.2579297125 + 0.2922055125 0.2805334926 0.2600534856 + 0.2942928076 0.2825405896 0.2621644139 + 0.2963638008 0.2845480144 0.2642523944 + 0.2984221876 0.2865386903 0.2663209140 + 0.3004606962 0.2885077894 0.2683751881 + 0.3024761081 0.2904664874 0.2704192996 + 0.3044942915 0.2924236953 0.2724545002 + 0.3065181971 0.2943876982 0.2744720876 + 0.3085376918 0.2963528931 0.2764638066 + 0.3105514944 0.2983131111 0.2784410119 + 0.3125489056 0.3002620041 0.2804194987 + 0.3145506084 0.3021939993 0.2823942006 + 0.3165509105 0.3041042089 0.2843523026 + 0.3185442090 0.3060002923 0.2863051891 + 0.3205361962 0.3078896999 0.2882539034 + 0.3225252032 0.3097808063 0.2901889980 + 0.3245142996 0.3116734922 0.2921113074 + 0.3265058100 0.3135590851 0.2940278947 + 0.3284947872 0.3154321909 0.2959429026 + 0.3304775059 0.3173008859 0.2978521883 + 0.3324612975 0.3191635907 0.2997469008 + 0.3344404995 0.3210156858 0.3016290069 + 0.3364037871 0.3228532076 0.3035013080 + 0.3383480906 0.3246806860 0.3053658903 + 0.3402774930 0.3265039027 0.3072257042 + 0.3422003984 0.3283264935 0.3090836108 + 0.3441283107 0.3301435113 0.3109402061 + 0.3460584879 0.3319503963 0.3127999902 + 0.3479807973 0.3337503970 0.3146592081 + 0.3498908877 0.3355464935 0.3165098131 + 0.3517873883 0.3373399973 0.3183467984 + 0.3536739051 0.3391256034 0.3201710880 + 0.3555468917 0.3408975899 0.3219870925 + 0.3574047089 0.3426569104 0.3237960935 + 0.3592503965 0.3444055915 0.3255974948 + 0.3610936105 0.3461483121 0.3273890913 + 0.3629257977 0.3478848040 0.3291662931 + 0.3647486866 0.3496142030 0.3309336901 + 0.3665607870 0.3513360918 0.3326914012 + 0.3683531880 0.3530487120 0.3344373107 + 0.3701289892 0.3547559083 0.3361791968 + 0.3719004095 0.3564561903 0.3379172087 + 0.3736707866 0.3581486046 0.3396506011 + 0.3754306138 0.3598242104 0.3413727880 + 0.3771795928 0.3614909947 0.3430913985 + 0.3789179921 0.3631505966 0.3448042870 + 0.3806397915 0.3648028076 0.3465045989 + 0.3823508024 0.3664542139 0.3481892049 + 0.3840552866 0.3680998981 0.3498643935 + 0.3857525885 0.3697325885 0.3515287936 + 0.3874309957 0.3713547885 0.3531869948 + 0.3890962005 0.3729732037 0.3548409939 + 0.3907422125 0.3745886981 0.3564892113 + 0.3923803866 0.3761973083 0.3581174910 + 0.3940139115 0.3778007925 0.3597348928 + 0.3956401050 0.3793950975 0.3613364995 + 0.3972538114 0.3809765875 0.3629319072 + 0.3988597989 0.3825520873 0.3645235002 + 0.4004507959 0.3841212988 0.3661076128 + 0.4020316899 0.3856911063 0.3676817119 + 0.4036057889 0.3872612119 0.3692494035 + 0.4051836133 0.3888235986 0.3708040118 + 0.4067601860 0.3903797865 0.3723560870 + 0.4083349109 0.3919270039 0.3739052117 + 0.4099012911 0.3934660852 0.3754433095 + 0.4114632905 0.3950020969 0.3769756854 + 0.4130123854 0.3965331018 0.3784922063 + 0.4145576060 0.3980642855 0.3800047934 + 0.4160979986 0.3995954990 0.3815135956 + 0.4176265895 0.4011205137 0.3830150068 + 0.4191510081 0.4026427865 0.3845132887 + 0.4206664860 0.4041537941 0.3859997094 + 0.4221807122 0.4056634009 0.3874785900 + 0.4236926138 0.4071705043 0.3889462948 + 0.4251953065 0.4086725116 0.3904061019 + 0.4266924858 0.4101715982 0.3918620050 + 0.4281755090 0.4116598964 0.3933145106 + 0.4296549857 0.4131458998 0.3947649896 + 0.4311212897 0.4146251082 0.3962041140 + 0.4325863123 0.4161024094 0.3976391852 + 0.4340479076 0.4175755084 0.3990663886 + 0.4355044961 0.4190461934 0.4004910886 + 0.4369558096 0.4205146134 0.4019137025 + 0.4384000897 0.4219822884 0.4033333063 + 0.4398407042 0.4234496057 0.4047515988 + 0.4412648976 0.4249095023 0.4061658084 + 0.4426848888 0.4263676107 0.4075790942 + 0.4440922141 0.4278148115 0.4089758992 + 0.4454984963 0.4292607903 0.4103710055 + 0.4469017088 0.4306946993 0.4117515087 + 0.4483037889 0.4321266115 0.4131309986 + 0.4496976137 0.4335466921 0.4145058095 + 0.4510863125 0.4349648952 0.4158783853 + 0.4524526000 0.4363755882 0.4172433019 + 0.4538140893 0.4377841055 0.4186027944 + 0.4551594853 0.4391863942 0.4199478924 + 0.4565044940 0.4405857027 0.4212876856 + 0.4578481019 0.4419767857 0.4226151109 + 0.4591886997 0.4433653951 0.4239403903 + 0.4605211020 0.4447469115 0.4252606928 + 0.4618496001 0.4461270869 0.4265792966 + 0.4631653130 0.4475035965 0.4278936982 + 0.4644770026 0.4488789141 0.4292060137 + 0.4657723904 0.4502497017 0.4305118024 + 0.4670655131 0.4516187906 0.4318155944 + 0.4683431089 0.4529778957 0.4331100881 + 0.4696202874 0.4543359876 0.4344033897 + 0.4708895981 0.4556787014 0.4356841147 + 0.4721587896 0.4570212960 0.4369646907 + 0.4734266996 0.4583550096 0.4382334054 + 0.4746944010 0.4596883059 0.4395017922 + 0.4759570956 0.4610117078 0.4407595098 + 0.4772185087 0.4623329043 0.4420154095 + 0.4784702957 0.4636422098 0.4432603121 + 0.4797168970 0.4649454951 0.4445005059 + 0.4809587896 0.4662468135 0.4457359910 + 0.4821954966 0.4675458074 0.4469672143 + 0.4834313095 0.4688419104 0.4481967986 + 0.4846647084 0.4701308012 0.4494228959 + 0.4858981073 0.4714190066 0.4506483972 + 0.4871313870 0.4726983011 0.4518673122 + 0.4883646965 0.4739777148 0.4530862868 + 0.4895890951 0.4752514064 0.4542964995 + 0.4908111989 0.4765237868 0.4555051029 + 0.4920256138 0.4777913094 0.4567083120 + 0.4932329953 0.4790548086 0.4579074085 + 0.4944368899 0.4803156853 0.4591037929 + 0.4956291020 0.4815686941 0.4602927864 + 0.4968214035 0.4828216136 0.4614818096 + 0.4980075061 0.4840664864 0.4626607001 + 0.4991930127 0.4853107929 0.4638391137 + 0.5003730059 0.4865506887 0.4650115073 + 0.5015485883 0.4877873063 0.4661796987 + 0.5027217269 0.4890219867 0.4673461020 + 0.5038836002 0.4902490973 0.4685058892 + 0.5050454736 0.4914762080 0.4696657956 + 0.5061964989 0.4927015007 0.4708235860 + 0.5073444247 0.4939264953 0.4719808996 + 0.5084874034 0.4951480031 0.4731355011 + 0.5096216798 0.4963639975 0.4742859006 + 0.5107560754 0.4975799024 0.4754363894 + 0.5118848085 0.4987801015 0.4765751958 + 0.5130128860 0.4999789000 0.4777132869 + 0.5141406059 0.5011754036 0.4788497090 + 0.5152677298 0.5023689270 0.4799841046 + 0.5163947940 0.5035623908 0.4811184108 + 0.5175107121 0.5047491193 0.4822545052 + 0.5186256170 0.5059353709 0.4833906889 + 0.5197319984 0.5071169734 0.4845212996 + 0.5208250284 0.5082917213 0.4856444001 + 0.5219178796 0.5094662905 0.4867675006 + 0.5230032802 0.5106360912 0.4878782928 + 0.5240870118 0.5118049979 0.4889872968 + 0.5251713991 0.5129719973 0.4900952876 + 0.5262575746 0.5141333938 0.4912008941 + 0.5273438096 0.5152949095 0.4923065007 + 0.5284274220 0.5164546967 0.4934087098 + 0.5295094252 0.5176134706 0.4945091903 + 0.5305913091 0.5187724233 0.4956094921 + 0.5316656828 0.5199283957 0.4966976941 + 0.5327398181 0.5210844874 0.4977858961 + 0.5338104963 0.5222364068 0.4988707900 + 0.5348731279 0.5233796239 0.4999495149 + 0.5359356999 0.5245227814 0.5010282993 + 0.5369876027 0.5256589055 0.5021041036 + 0.5380324721 0.5267904997 0.5031781197 + 0.5390774012 0.5279220939 0.5042521954 + 0.5401139259 0.5290479064 0.5053207278 + 0.5411491990 0.5301730037 0.5063884854 + 0.5421838760 0.5312972069 0.5074563026 + 0.5432150960 0.5324152112 0.5085229278 + 0.5442463160 0.5335332751 0.5095896125 + 0.5452744961 0.5346456170 0.5106530786 + 0.5462962985 0.5357465148 0.5117110014 + 0.5473181009 0.5368474126 0.5127688050 + 0.5483338237 0.5379434228 0.5138180852 + 0.5493434072 0.5390350223 0.5148600936 + 0.5503531098 0.5401265025 0.5159021020 + 0.5513597131 0.5412139297 0.5169410706 + 0.5523648262 0.5422992110 0.5179787278 + 0.5533698201 0.5433844924 0.5190163255 + 0.5543758273 0.5444642901 0.5200524926 + 0.5553820729 0.5455427170 0.5210883021 + 0.5563883185 0.5466210246 0.5221241713 + 0.5573911071 0.5476927161 0.5231577754 + 0.5583932996 0.5487633944 0.5241910815 + 0.5593954921 0.5498341918 0.5252243876 + 0.5603914857 0.5508939028 0.5262517929 + 0.5613868237 0.5519527793 0.5272789001 + 0.5623821020 0.5530115962 0.5283061266 + 0.5633684993 0.5540567040 0.5293180943 + 0.5643541813 0.5551009178 0.5303297043 + 0.5653399229 0.5561451912 0.5313413143 + 0.5663121939 0.5571808219 0.5323446989 + 0.5672833920 0.5582157969 0.5333477259 + 0.5682544708 0.5592507124 0.5343508124 + 0.5692139864 0.5602828264 0.5353485942 + 0.5701718926 0.5613144040 0.5363458991 + 0.5711297989 0.5623461008 0.5373433232 + 0.5720816255 0.5633695126 0.5383352041 + 0.5730317831 0.5643910170 0.5393260717 + 0.5739821196 0.5654125810 0.5403169990 + 0.5749322176 0.5664225817 0.5413028002 + 0.5758821964 0.5674279928 0.5422866940 + 0.5768321753 0.5684334040 0.5432707071 + 0.5777807832 0.5694364905 0.5442500114 + 0.5787283182 0.5704377294 0.5452260971 + 0.5796757936 0.5714389086 0.5462023020 + 0.5806186795 0.5724375248 0.5471749902 + 0.5815541744 0.5734320879 0.5481427908 + 0.5824897289 0.5744267106 0.5491107106 + 0.5834230781 0.5754204988 0.5500766039 + 0.5843461156 0.5764102936 0.5510352850 + 0.5852690935 0.5774000883 0.5519940257 + 0.5861920714 0.5783898830 0.5529527068 + 0.5871120095 0.5793784857 0.5539078116 + 0.5880315900 0.5803670287 0.5548627973 + 0.5889511108 0.5813555121 0.5558177829 + 0.5898649096 0.5823364258 0.5567662120 + 0.5907754898 0.5833132267 0.5577116013 + 0.5916861296 0.5842900872 0.5586568713 + 0.5925920010 0.5852631927 0.5595967174 + 0.5934880972 0.5862287879 0.5605269074 + 0.5943841934 0.5871945024 0.5614570975 + 0.5952801704 0.5881602168 0.5623872280 + 0.5961638093 0.5891243815 0.5633127093 + 0.5970469713 0.5900886059 0.5642381907 + 0.5979301929 0.5910527110 0.5651637912 + 0.5988095999 0.5920161009 0.5660883784 + 0.5996860862 0.5929788947 0.5670126081 + 0.6005626917 0.5939416885 0.5679367781 + 0.6014385223 0.5949037075 0.5688589215 + 0.6023102999 0.5958616734 0.5697726011 + 0.6031820774 0.5968198180 0.5706862211 + 0.6040539145 0.5977777839 0.5715999007 + 0.6049264073 0.5987269282 0.5725020766 + 0.6057993174 0.5996723175 0.5734000802 + 0.6066721082 0.6006177068 0.5742980838 + 0.6075447202 0.6015614271 0.5751948953 + 0.6084157825 0.6024988294 0.5760878921 + 0.6092870235 0.6034362912 0.5769808888 + 0.6101580858 0.6043736935 0.5778738856 + 0.6110234261 0.6053066254 0.5787655711 + 0.6118857265 0.6062374115 0.5796566010 + 0.6127480268 0.6071680784 0.5805476904 + 0.6136096716 0.6080988050 0.5814384818 + 0.6144647002 0.6090288162 0.5823276043 + 0.6153196096 0.6099588275 0.5832166076 + 0.6161745191 0.6108887196 0.5841056705 + 0.6170253158 0.6118140221 0.5849937797 + 0.6178714037 0.6127341986 0.5858809948 + 0.6187174916 0.6136543751 0.5867682099 + 0.6195635796 0.6145746112 0.5876554251 + 0.6203994155 0.6154835820 0.5885332227 + 0.6212329268 0.6163904071 0.5894092917 + 0.6220663786 0.6172971725 0.5902854204 + 0.6228989959 0.6182032228 0.5911598206 + 0.6237251759 0.6191043854 0.5920251012 + 0.6245512962 0.6200054884 0.5928903818 + 0.6253774762 0.6209065914 0.5937557220 + 0.6262025833 0.6218063831 0.5946201086 + 0.6270262003 0.6227043867 0.5954833031 + 0.6278496981 0.6236023903 0.5963464975 + 0.6286731958 0.6245002747 0.5972098112 + 0.6294925809 0.6253930926 0.5980716944 + 0.6303092837 0.6262826920 0.5989329815 + 0.6311259866 0.6271722913 0.5997943282 + 0.6319425702 0.6280620098 0.6006556153 + 0.6327558756 0.6289452910 0.6015126705 + 0.6335682273 0.6298272014 0.6023688912 + 0.6343805790 0.6307089925 0.6032251716 + 0.6351928711 0.6315909028 0.6040813923 + 0.6360028982 0.6324610710 0.6049261093 + 0.6368128061 0.6333307028 0.6057704091 + 0.6376225948 0.6342003942 0.6066148281 + 0.6384323835 0.6350694895 0.6074587703 + 0.6392394900 0.6359295249 0.6082984209 + 0.6400464773 0.6367895007 0.6091380715 + 0.6408535838 0.6376495957 0.6099777222 + 0.6416608095 0.6385089159 0.6108170748 + 0.6424685717 0.6393631101 0.6116548777 + 0.6432763934 0.6402173042 0.6124926805 + 0.6440842748 0.6410714984 0.6133304834 + 0.6448920965 0.6419250965 0.6141679883 + 0.6456990838 0.6427741051 0.6150038242 + 0.6465060711 0.6436231136 0.6158394814 + 0.6473131776 0.6444721222 0.6166753173 + 0.6481201053 0.6453201771 0.6175107956 + 0.6489260197 0.6461594105 0.6183446050 + 0.6497318745 0.6469987035 0.6191784739 + 0.6505379081 0.6478378773 0.6200122833 + 0.6513438821 0.6486768723 0.6208459735 + 0.6521543264 0.6495088935 0.6216778159 + 0.6529647112 0.6503409147 0.6225095987 + 0.6537752151 0.6511728764 0.6233413219 + 0.6545855999 0.6520048976 0.6241731048 + 0.6553974152 0.6528308988 0.6250030994 + 0.6562091708 0.6536563039 0.6258329153 + 0.6570211053 0.6544817090 0.6266627908 + 0.6578329206 0.6553071141 0.6274926066 + 0.6586399078 0.6561266780 0.6283208728 + 0.6594451070 0.6569445133 0.6291487813 + 0.6602504253 0.6577622890 0.6299766898 + 0.6610556841 0.6585801244 0.6308044791 + 0.6618577242 0.6593968868 0.6316313744 + 0.6626570225 0.6602129936 0.6324573755 + 0.6634563208 0.6610292196 0.6332834959 + 0.6642554998 0.6618453264 0.6341096163 + 0.6650528908 0.6626601815 0.6349341869 + 0.6658458114 0.6634724140 0.6357557178 + 0.6666386127 0.6642845869 0.6365773082 + 0.6674314737 0.6650968194 0.6373988986 + 0.6682242751 0.6659088731 0.6382200718 + 0.6690135002 0.6667075753 0.6390303969 + 0.6698027849 0.6675063968 0.6398407221 + 0.6705920100 0.6683050990 0.6406509876 + 0.6713812947 0.6691039205 0.6414613128 + 0.6721655726 0.6698979139 0.6422684193 + 0.6729472876 0.6706895828 0.6430739760 + 0.6737290025 0.6714811921 0.6438794732 + 0.6745107174 0.6722728014 0.6446850896 + 0.6752899885 0.6730641127 0.6454901099 + 0.6760625243 0.6738544703 0.6462938786 + 0.6768351197 0.6746450067 0.6470977068 + 0.6776077151 0.6754354239 0.6479014158 + 0.6783801913 0.6762257814 0.6487051845 + 0.6791486740 0.6770142913 0.6495074034 + 0.6799163222 0.6778023839 0.6503092051 + 0.6806839705 0.6785904765 0.6511111259 + 0.6814516187 0.6793786287 0.6519129872 + 0.6822186708 0.6801651120 0.6527122855 + 0.6829848289 0.6809486747 0.6535074115 + 0.6837509274 0.6817322969 0.6543024778 + 0.6845170856 0.6825159192 0.6550976038 + 0.6852831841 0.6832996011 0.6558926105 + 0.6860461235 0.6840777993 0.6566833258 + 0.6868082881 0.6848548055 0.6574732065 + 0.6875705123 0.6856318712 0.6582630873 + 0.6883326769 0.6864088774 0.6590530276 + 0.6890928745 0.6871842146 0.6598421931 + 0.6898465157 0.6879535913 0.6606296897 + 0.6905999780 0.6887230277 0.6614171863 + 0.6913534999 0.6894924045 0.6622046828 + 0.6921070814 0.6902617812 0.6629921794 + 0.6928570271 0.6910268068 0.6637781858 + 0.6936045885 0.6917887926 0.6645631790 + 0.6943520904 0.6925508976 0.6653482914 + 0.6950995922 0.6933128834 0.6661332846 + 0.6958470941 0.6940749884 0.6669183969 + 0.6965919733 0.6948326826 0.6677011847 + 0.6973364949 0.6955900192 0.6684839129 + 0.6980810761 0.6963472962 0.6692665815 + 0.6988255978 0.6971045136 0.6700494289 + 0.6995682716 0.6978610754 0.6708310843 + 0.7003021240 0.6986145973 0.6716089249 + 0.7010359168 0.6993680000 0.6723867059 + 0.7017697096 0.7001215219 0.6731644869 + 0.7025035024 0.7008749247 0.6739423871 + 0.7032322884 0.7016248107 0.6747155190 + 0.7039532065 0.7023693919 0.6754820943 + 0.7046741843 0.7031139731 0.6762487292 + 0.7053951025 0.7038586140 0.6770153046 + 0.7061160207 0.7046031952 0.6777818799 + 0.7068319917 0.7053433061 0.6785455942 + 0.7075439095 0.7060800195 0.6793071032 + 0.7082558870 0.7068166137 0.6800686717 + 0.7089678049 0.7075533271 0.6808302999 + 0.7096797824 0.7082899213 0.6815918088 + 0.7103822827 0.7090213895 0.6823518276 + 0.7110798955 0.7097504139 0.6831110120 + 0.7117773890 0.7104794979 0.6838701963 + 0.7124750018 0.7112085223 0.6846293807 + 0.7131726146 0.7119374871 0.6853885055 + 0.7138615251 0.7126597166 0.6861459017 + 0.7145469785 0.7133795023 0.6869027019 + 0.7152324915 0.7140992880 0.6876593828 + 0.7159180045 0.7148190141 0.6884161830 + 0.7166035175 0.7155387998 0.6891729236 + 0.7172850966 0.7162548900 0.6899223924 + 0.7179651856 0.7169696093 0.6906694770 + 0.7186452150 0.7176843286 0.6914165020 + 0.7193253040 0.7183991075 0.6921635866 + 0.7200053930 0.7191138268 0.6929106116 + 0.7206829190 0.7198268175 0.6936489940 + 0.7213590145 0.7205389738 0.6943836808 + 0.7220352292 0.7212511897 0.6951184273 + 0.7227113843 0.7219635248 0.6958531141 + 0.7233875990 0.7226756811 0.6965876818 + 0.7240635753 0.7233844995 0.6973186731 + 0.7247393727 0.7240908146 0.6980472207 + 0.7254152894 0.7247970104 0.6987757087 + 0.7260912061 0.7255033255 0.6995041966 + 0.7267671227 0.7262095809 0.7002326846 + 0.7274426818 0.7269139290 0.7009603977 + 0.7281178832 0.7276154757 0.7016872168 + 0.7287930846 0.7283170223 0.7024139762 + 0.7294682860 0.7290186286 0.7031407952 + 0.7301434875 0.7297201157 0.7038676143 + 0.7308180928 0.7304204106 0.7045934200 + 0.7314903736 0.7311158776 0.7053160071 + 0.7321627140 0.7318114042 0.7060384750 + 0.7328349948 0.7325068116 0.7067610025 + 0.7335072160 0.7332022786 0.7074834704 + 0.7341794968 0.7338978052 0.7082059979 + 0.7348482013 0.7345873117 0.7089205980 + 0.7355166078 0.7352764010 0.7096347213 + 0.7361850142 0.7359654903 0.7103487849 + 0.7368534207 0.7366545796 0.7110629082 + 0.7375218272 0.7373437285 0.7117769718 + 0.7381889820 0.7380310297 0.7124879956 + 0.7388554215 0.7387169003 0.7131969929 + 0.7395219207 0.7394028902 0.7139061093 + 0.7401883006 0.7400888205 0.7146151066 + 0.7408546805 0.7407748103 0.7153242230 + 0.7415205836 0.7414584756 0.7160325050 + 0.7421839833 0.7421336770 0.7167384028 + 0.7428473830 0.7428088784 0.7174441814 + 0.7435107827 0.7434840798 0.7181500793 + 0.7441741824 0.7441592813 0.7188559771 + 0.7448375821 0.7448344827 0.7195618749 + 0.7454971075 0.7455040216 0.7202640772 + 0.7461552024 0.7461715937 0.7209653258 + 0.7468132973 0.7468392849 0.7216665149 + 0.7474713922 0.7475069761 0.7223677039 + 0.7481294870 0.7481747270 0.7230688930 + 0.7487857938 0.7488409877 0.7237700820 + 0.7494363785 0.7495033741 0.7244712114 + 0.7500869036 0.7501658797 0.7251722813 + 0.7507374883 0.7508283854 0.7258734107 + 0.7513880730 0.7514907718 0.7265745997 + 0.7520385981 0.7521532774 0.7272757292 + 0.7526834011 0.7528085709 0.7279723287 + 0.7533255816 0.7534605861 0.7286670804 + 0.7539677024 0.7541127205 0.7293617725 + 0.7546098828 0.7547647953 0.7300565839 + 0.7552520037 0.7554169297 0.7307513952 + 0.7558938861 0.7560682893 0.7314453721 + 0.7565317750 0.7567108870 0.7321308851 + 0.7571697235 0.7573534250 0.7328165174 + 0.7578076124 0.7579960227 0.7335019708 + 0.7584453821 0.7586385012 0.7341874838 + 0.7590832710 0.7592810988 0.7348731160 + 0.7597208023 0.7599217296 0.7355561256 + 0.7603574991 0.7605590820 0.7362353206 + 0.7609941959 0.7611966133 0.7369145155 + 0.7616308928 0.7618340254 0.7375937104 + 0.7622675896 0.7624713778 0.7382730246 + 0.7629042864 0.7631089091 0.7389522195 + 0.7635387778 0.7637441754 0.7396275997 + 0.7641718984 0.7643783092 0.7403010130 + 0.7648050189 0.7650123835 0.7409744263 + 0.7654381990 0.7656465173 0.7416477799 + 0.7660713196 0.7662805915 0.7423211932 + 0.7667044997 0.7669147253 0.7429946065 + 0.7673382759 0.7675452828 0.7436637878 + 0.7679721713 0.7681750059 0.7443320155 + 0.7686061263 0.7688047290 0.7450003028 + 0.7692400217 0.7694345117 0.7456685901 + 0.7698739767 0.7700641751 0.7463368773 + 0.7705078721 0.7706940174 0.7470052242 + 0.7711389065 0.7713199258 0.7476691008 + 0.7717695832 0.7719454765 0.7483327985 + 0.7724003792 0.7725712061 0.7489963770 + 0.7730311155 0.7731968164 0.7496600747 + 0.7736619115 0.7738224864 0.7503237724 + 0.7742925882 0.7744480968 0.7509874105 + 0.7749173045 0.7750692964 0.7516471148 + 0.7755420208 0.7756903768 0.7523068786 + 0.7761667967 0.7763115764 0.7529665828 + 0.7767915130 0.7769327760 0.7536262870 + 0.7774162292 0.7775539160 0.7542861104 + 0.7780408859 0.7781749964 0.7549456954 + 0.7786604166 0.7787933946 0.7556020021 + 0.7792798281 0.7794117928 0.7562583089 + 0.7798992991 0.7800301909 0.7569146156 + 0.7805187106 0.7806485891 0.7575709224 + 0.7811381817 0.7812669873 0.7582271099 + 0.7817575932 0.7818853855 0.7588834167 + 0.7823737264 0.7824988961 0.7595390081 + 0.7829896212 0.7831121087 0.7601945996 + 0.7836055160 0.7837253213 0.7608501911 + 0.7842214108 0.7843385935 0.7615057826 + 0.7848373055 0.7849518061 0.7621613741 + 0.7854532003 0.7855650187 0.7628170848 + 0.7860642076 0.7861744165 0.7634735703 + 0.7866740227 0.7867829204 0.7641304135 + 0.7872837782 0.7873914242 0.7647870779 + 0.7878935933 0.7879999876 0.7654439211 + 0.7885034084 0.7886084914 0.7661007047 + 0.7891132236 0.7892169952 0.7667574286 + 0.7897166014 0.7898225784 0.7674102187 + 0.7903156877 0.7904263735 0.7680606842 + 0.7909148932 0.7910302281 0.7687112093 + 0.7915139794 0.7916340232 0.7693616748 + 0.7921131849 0.7922376990 0.7700121999 + 0.7927122712 0.7928414941 0.7706627250 + 0.7933096290 0.7934436202 0.7713115215 + 0.7939032912 0.7940425277 0.7719575763 + 0.7944970131 0.7946413755 0.7726035714 + 0.7950906157 0.7952402830 0.7732496262 + 0.7956842780 0.7958391905 0.7738956809 + 0.7962778807 0.7964379787 0.7745416760 + 0.7968716025 0.7970368862 0.7751876712 + 0.7974594831 0.7976313829 0.7758299112 + 0.7980473042 0.7982258797 0.7764720917 + 0.7986351848 0.7988204956 0.7771142721 + 0.7992231250 0.7994149923 0.7777565122 + 0.7998108864 0.8000094891 0.7783988118 + 0.8003988266 0.8006039858 0.7790409923 + 0.8009812832 0.8011956811 0.7796803117 + 0.8015602231 0.8017855287 0.7803177834 + 0.8021391034 0.8023753166 0.7809553146 + 0.8027181029 0.8029651046 0.7815927267 + 0.8032969832 0.8035550117 0.7822301984 + 0.8038759232 0.8041447997 0.7828677297 + 0.8044546247 0.8047344089 0.7835052013 + 0.8050318956 0.8053227067 0.7841426134 + 0.8056092262 0.8059110045 0.7847800851 + 0.8061863780 0.8064993024 0.7854174972 + 0.8067637086 0.8070874810 0.7860549092 + 0.8073409200 0.8076757789 0.7866923213 + 0.8079181910 0.8082640767 0.7873297930 + 0.8084933162 0.8088514805 0.7879632711 + 0.8090668917 0.8094381094 0.7885943055 + 0.8096404076 0.8100247979 0.7892252803 + 0.8102139831 0.8106114864 0.7898563147 + 0.8107876182 0.8111981750 0.7904872894 + 0.8113610744 0.8117849231 0.7911183238 + 0.8119347095 0.8123714924 0.7917492986 + 0.8125054836 0.8129528761 0.7923681736 + 0.8130763173 0.8135340810 0.7929869890 + 0.8136469722 0.8141154051 0.7936058044 + 0.8142176867 0.8146966100 0.7942246199 + 0.8147884011 0.8152778745 0.7948433757 + 0.8153591752 0.8158590794 0.7954621911 + 0.8159289956 0.8164386749 0.7960788012 + 0.8164964914 0.8170142770 0.7966904044 + 0.8170641065 0.8175899982 0.7973020077 + 0.8176316023 0.8181656003 0.7979136109 + 0.8181990981 0.8187412024 0.7985252142 + 0.8187667131 0.8193169236 0.7991368175 + 0.8193342090 0.8198925257 0.7997484207 + 0.8198990226 0.8204675913 0.8003578782 + 0.8204612136 0.8210421801 0.8009656072 + 0.8210235238 0.8216167092 0.8015732765 + 0.8215857744 0.8221912980 0.8021810055 + 0.8221480846 0.8227658868 0.8027886748 + 0.8227102757 0.8233404756 0.8033962846 + 0.8232725859 0.8239151239 0.8040040135 + 0.8238356113 0.8244882822 0.8046082258 + 0.8243988156 0.8250607848 0.8052108884 + 0.8249620795 0.8256334066 0.8058137298 + 0.8255254030 0.8262060285 0.8064163923 + 0.8260886073 0.8267785907 0.8070191145 + 0.8266518712 0.8273512125 0.8076218963 + 0.8272151947 0.8279237747 0.8082246184 + 0.8277786970 0.8284941912 0.8088231087 + 0.8283423185 0.8290640712 0.8094205856 + 0.8289058208 0.8296340108 0.8100181222 + 0.8294693828 0.8302038908 0.8106155992 + 0.8300330043 0.8307737708 0.8112130761 + 0.8305966258 0.8313437104 0.8118106127 + 0.8311601877 0.8319135904 0.8124080896 + 0.8317217827 0.8324813843 0.8130018115 + 0.8322829008 0.8330487013 0.8135946989 + 0.8328440189 0.8336160779 0.8141875863 + 0.8334051967 0.8341833949 0.8147805929 + 0.8339663148 0.8347507119 0.8153734803 + 0.8345274925 0.8353180885 0.8159664273 + 0.8350886106 0.8358854055 0.8165593743 + 0.8356444836 0.8364486098 0.8171482086 + 0.8361988068 0.8370106220 0.8177357912 + 0.8367530704 0.8375725746 0.8183234930 + 0.8373072743 0.8381345868 0.8189110756 + 0.8378615975 0.8386965990 0.8194987178 + 0.8384159207 0.8392586112 0.8200864196 + 0.8389701247 0.8398206234 0.8206740022 + 0.8395189047 0.8403776884 0.8212596774 + 0.8400645256 0.8409320712 0.8218443990 + 0.8406100273 0.8414863944 0.8224290013 + 0.8411555290 0.8420407176 0.8230137229 + 0.8417009711 0.8425949812 0.8235983253 + 0.8422465920 0.8431493044 0.8241829872 + 0.8427920938 0.8437036276 0.8247675896 + 0.8433353901 0.8442538977 0.8253523707 + 0.8438755870 0.8447986245 0.8259375095 + 0.8444157243 0.8453432918 0.8265225291 + 0.8449559212 0.8458880186 0.8271076083 + 0.8454961181 0.8464328051 0.8276926279 + 0.8460361958 0.8469774723 0.8282775879 + 0.8465763927 0.8475221992 0.8288627267 + 0.8471155763 0.8480662107 0.8294473290 + 0.8476483226 0.8486049771 0.8300294876 + 0.8481810093 0.8491439223 0.8306117058 + 0.8487136960 0.8496826887 0.8311939836 + 0.8492463827 0.8502215743 0.8317762017 + 0.8497790098 0.8507604003 0.8323584199 + 0.8503116965 0.8512992859 0.8329406977 + 0.8508443832 0.8518381119 0.8335229158 + 0.8513737917 0.8523707986 0.8341016769 + 0.8519021273 0.8529015183 0.8346794844 + 0.8524304032 0.8534322977 0.8352572918 + 0.8529587984 0.8539630175 0.8358352184 + 0.8534870744 0.8544937968 0.8364130259 + 0.8540154099 0.8550245762 0.8369907737 + 0.8545438051 0.8555552959 0.8375687003 + 0.8550698757 0.8560833931 0.8381444216 + 0.8555914164 0.8566060066 0.8387160897 + 0.8561128974 0.8571285009 0.8392876983 + 0.8566343784 0.8576511145 0.8398594260 + 0.8571557999 0.8581736088 0.8404310942 + 0.8576772809 0.8586962223 0.8410027027 + 0.8581988215 0.8592187166 0.8415743709 + 0.8587203026 0.8597412705 0.8421459794 + 0.8592392802 0.8602582812 0.8427104950 + 0.8597577810 0.8607739806 0.8432731032 + 0.8602762222 0.8612896800 0.8438357711 + 0.8607946038 0.8618053198 0.8443984985 + 0.8613131046 0.8623210192 0.8449612260 + 0.8618314862 0.8628365993 0.8455238938 + 0.8623499274 0.8633522987 0.8460866213 + 0.8628677130 0.8638666272 0.8466476202 + 0.8633821011 0.8643746972 0.8472021222 + 0.8638964891 0.8648828864 0.8477566242 + 0.8644108772 0.8653910756 0.8483110070 + 0.8649253249 0.8658993244 0.8488655090 + 0.8654397130 0.8664075136 0.8494200110 + 0.8659541011 0.8669157028 0.8499745131 + 0.8664684892 0.8674237728 0.8505288959 + 0.8669798970 0.8679283857 0.8510808945 + 0.8674882054 0.8684291840 0.8516303897 + 0.8679965138 0.8689299822 0.8521798849 + 0.8685047030 0.8694307804 0.8527294993 + 0.8690130115 0.8699315786 0.8532789946 + 0.8695213199 0.8704324961 0.8538284898 + 0.8700296283 0.8709332943 0.8543781042 + 0.8705378771 0.8714340925 0.8549275994 + 0.8710486889 0.8719300032 0.8554750085 + 0.8715605140 0.8724238873 0.8560217023 + 0.8720722795 0.8729178905 0.8565683961 + 0.8725841045 0.8734118938 0.8571150899 + 0.8730959892 0.8739058971 0.8576617837 + 0.8736078143 0.8743997812 0.8582084775 + 0.8741195798 0.8748937845 0.8587551713 + 0.8746314049 0.8753877878 0.8593019247 + 0.8751448989 0.8758807182 0.8598421812 + 0.8756586909 0.8763734102 0.8603816032 + 0.8761724830 0.8768661022 0.8609210253 + 0.8766862750 0.8773587942 0.8614603877 + 0.8772001266 0.8778516054 0.8619998097 + 0.8777137995 0.8783442974 0.8625391722 + 0.8782275915 0.8788369894 0.8630785942 + 0.8787413836 0.8793296814 0.8636180162 + 0.8792527914 0.8798214793 0.8641535044 + 0.8797639012 0.8803130984 0.8646888137 + 0.8802750111 0.8808047771 0.8652241230 + 0.8807861209 0.8812963963 0.8657593727 + 0.8812971711 0.8817880154 0.8662946820 + 0.8818082809 0.8822796941 0.8668299913 + 0.8823193908 0.8827713132 0.8673651814 + 0.8828305006 0.8832629919 0.8679004908 + 0.8833349943 0.8837479949 0.8684350252 + 0.8838387132 0.8842322826 0.8689693809 + 0.8843423724 0.8847165108 0.8695037961 + 0.8848459721 0.8852007985 0.8700382113 + 0.8853496909 0.8856850863 0.8705726266 + 0.8858534098 0.8861693144 0.8711069822 + 0.8863570094 0.8866536021 0.8716413975 + 0.8868607283 0.8871377707 0.8721758127 + 0.8873574734 0.8876165152 0.8727089167 + 0.8878520727 0.8880935907 0.8732416034 + 0.8883467913 0.8885707259 0.8737742901 + 0.8888415098 0.8890478015 0.8743069768 + 0.8893362284 0.8895248771 0.8748397231 + 0.8898308873 0.8900020123 0.8753722906 + 0.8903254867 0.8904790878 0.8759049773 + 0.8908202052 0.8909561038 0.8764377236 + 0.8913139105 0.8914325833 0.8769698739 + 0.8918069005 0.8919085860 0.8775017858 + 0.8922998905 0.8923845291 0.8780336976 + 0.8927928805 0.8928604722 0.8785656095 + 0.8932858706 0.8933364749 0.8790975213 + 0.8937789202 0.8938124776 0.8796293736 + 0.8942717910 0.8942884207 0.8801612258 + 0.8947647810 0.8947644234 0.8806930780 + 0.8952565789 0.8952397108 0.8812240958 + 0.8957449198 0.8957130909 0.8817527890 + 0.8962332010 0.8961864710 0.8822814226 + 0.8967214823 0.8966599107 0.8828101158 + 0.8972098231 0.8971332908 0.8833386898 + 0.8976982236 0.8976066709 0.8838673830 + 0.8981865048 0.8980801105 0.8843960762 + 0.8986747861 0.8985534906 0.8849247098 + 0.8991631269 0.8990268707 0.8854534030 + 0.8996483088 0.8994984031 0.8859789968 + 0.9001330137 0.8999695182 0.8865042925 + 0.9006177187 0.9004406929 0.8870295882 + 0.9011024833 0.9009119272 0.8875548244 + 0.9015871882 0.9013829827 0.8880801201 + 0.9020720124 0.9018542171 0.8886054158 + 0.9025567174 0.9023253918 0.8891307116 + 0.9030414224 0.9027965069 0.8896560073 + 0.9035236239 0.9032670856 0.8901805878 + 0.9040020704 0.9037368894 0.8907042146 + 0.9044805169 0.9042065740 0.8912279010 + 0.9049589038 0.9046763182 0.8917515278 + 0.9054374099 0.9051461220 0.8922752142 + 0.9059157968 0.9056158066 0.8927989006 + 0.9063943028 0.9060856104 0.8933225274 + 0.9068726897 0.9065552950 0.8938462138 + 0.9073510766 0.9070249796 0.8943697810 + 0.9078236818 0.9074894190 0.8948928118 + 0.9082950950 0.9079527259 0.8954156041 + 0.9087665081 0.9084160924 0.8959383965 + 0.9092379808 0.9088793993 0.8964611888 + 0.9097093940 0.9093427062 0.8969839811 + 0.9101808071 0.9098060727 0.8975067735 + 0.9106522202 0.9102693796 0.8980296254 + 0.9111235738 0.9107328057 0.8985524178 + 0.9115946293 0.9111946225 0.8990744948 + 0.9120634794 0.9116498828 0.8995931745 + 0.9125325084 0.9121053219 0.9001119137 + 0.9130014181 0.9125605822 0.9006305933 + 0.9134703875 0.9130159020 0.9011492729 + 0.9139392972 0.9134712219 0.9016680717 + 0.9144083261 0.9139264822 0.9021868110 + 0.9148771763 0.9143819213 0.9027054906 + 0.9153460860 0.9148371816 0.9032241702 + 0.9158136249 0.9152905941 0.9037396908 + 0.9162790179 0.9157413840 0.9042512178 + 0.9167444706 0.9161921740 0.9047626257 + 0.9172099233 0.9166430235 0.9052739739 + 0.9176753163 0.9170938134 0.9057853818 + 0.9181408286 0.9175446033 0.9062967896 + 0.9186062217 0.9179953933 0.9068081975 + 0.9190716743 0.9184461832 0.9073196054 + 0.9195371270 0.9188969731 0.9078310132 + 0.9200031161 0.9193475842 0.9083387852 + 0.9204695225 0.9197980165 0.9088441133 + 0.9209359288 0.9202483892 0.9093493223 + 0.9214022756 0.9206988215 0.9098545909 + 0.9218686819 0.9211491942 0.9103597999 + 0.9223350883 0.9215996265 0.9108651280 + 0.9228014946 0.9220499992 0.9113702774 + 0.9232679009 0.9225003719 0.9118756056 + 0.9237343073 0.9229508042 0.9123808146 + 0.9242020249 0.9234021902 0.9128848910 + 0.9246705174 0.9238542914 0.9133883119 + 0.9251390100 0.9243063927 0.9138916731 + 0.9256075025 0.9247584939 0.9143949747 + 0.9260761142 0.9252105951 0.9148983955 + 0.9265446067 0.9256626964 0.9154018164 + 0.9270130992 0.9261147976 0.9159051776 + 0.9274815917 0.9265668988 0.9164085984 + 0.9279500842 0.9270188808 0.9169120193 + 0.9284178019 0.9274703264 0.9174153209 + 0.9288849235 0.9279211760 0.9179183841 + 0.9293519855 0.9283720851 0.9184216261 + 0.9298191071 0.9288229942 0.9189246893 + 0.9302862883 0.9292739034 0.9194278121 + 0.9307534099 0.9297246933 0.9199309945 + 0.9312204719 0.9301756024 0.9204341173 + 0.9316875935 0.9306265116 0.9209372997 + 0.9321547151 0.9310774207 0.9214404225 + 0.9326195121 0.9315286279 0.9219434857 + 0.9330815077 0.9319801927 0.9224464893 + 0.9335433841 0.9324318767 0.9229494929 + 0.9340053797 0.9328835011 0.9234524965 + 0.9344673753 0.9333351254 0.9239555001 + 0.9349293113 0.9337866902 0.9244585037 + 0.9353913069 0.9342383146 0.9249615073 + 0.9358531833 0.9346899986 0.9254645109 + 0.9363151789 0.9351416230 0.9259675145 + 0.9367759228 0.9355927110 0.9264699817 + 0.9372317791 0.9360417128 0.9269704819 + 0.9376876950 0.9364907742 0.9274709225 + 0.9381436706 0.9369398952 0.9279714227 + 0.9385995865 0.9373890162 0.9284719229 + 0.9390555024 0.9378380775 0.9289724231 + 0.9395114183 0.9382871985 0.9294728041 + 0.9399673939 0.9387362003 0.9299733043 + 0.9404233098 0.9391853213 0.9304738045 + 0.9408792257 0.9396343827 0.9309743047 + 0.9413326979 0.9400802255 0.9314733744 + 0.9417858124 0.9405254722 0.9319723248 + 0.9422389865 0.9409707785 0.9324712157 + 0.9426921010 0.9414162040 0.9329702258 + 0.9431452155 0.9418615103 0.9334691167 + 0.9435983896 0.9423068166 0.9339680076 + 0.9440515041 0.9427521229 0.9344670177 + 0.9445046186 0.9431974292 0.9349659085 + 0.9449576735 0.9436427951 0.9354647994 + 0.9454091787 0.9440872073 0.9359622002 + 0.9458584785 0.9445304871 0.9364575744 + 0.9463077784 0.9449738860 0.9369530082 + 0.9467570186 0.9454172254 0.9374483824 + 0.9472063184 0.9458606243 0.9379438162 + 0.9476556182 0.9463039041 0.9384390712 + 0.9481049180 0.9467471838 0.9389345050 + 0.9485542178 0.9471905828 0.9394298792 + 0.9490035176 0.9476339221 0.9399253130 + 0.9494526982 0.9480772018 0.9404206872 + 0.9498931766 0.9485139847 0.9409106970 + 0.9503325224 0.9489501119 0.9413999915 + 0.9507718086 0.9493861198 0.9418894053 + 0.9512112141 0.9498221874 0.9423786998 + 0.9516505003 0.9502581954 0.9428679943 + 0.9520899057 0.9506943226 0.9433574080 + 0.9525291920 0.9511302710 0.9438467026 + 0.9529684782 0.9515663981 0.9443361163 + 0.9534078836 0.9520024061 0.9448254108 + 0.9538437128 0.9524362087 0.9453141093 + 0.9542688131 0.9528629184 0.9458007216 + 0.9546939135 0.9532896280 0.9462872744 + 0.9551190138 0.9537162185 0.9467738867 + 0.9555441141 0.9541429281 0.9472606182 + 0.9559692144 0.9545695782 0.9477471709 + 0.9563943148 0.9549962878 0.9482337832 + 0.9568194747 0.9554229975 0.9487203956 + 0.9572445750 0.9558497071 0.9492071271 + 0.9576696754 0.9562764168 0.9496936798 + 0.9580900073 0.9567002058 0.9501780868 + 0.9585055113 0.9571210742 0.9506604075 + 0.9589208961 0.9575420022 0.9511427283 + 0.9593364000 0.9579628110 0.9516249895 + 0.9597519040 0.9583836794 0.9521073103 + 0.9601672888 0.9588046074 0.9525895715 + 0.9605827928 0.9592254758 0.9530717731 + 0.9609982967 0.9596462846 0.9535540938 + 0.9614136815 0.9600672126 0.9540364146 + 0.9618291855 0.9604880810 0.9545186758 + 0.9622408748 0.9609053731 0.9549967051 + 0.9626505971 0.9613206983 0.9554721713 + 0.9630602002 0.9617360234 0.9559476972 + 0.9634698033 0.9621512294 0.9564232826 + 0.9638794065 0.9625664949 0.9568988085 + 0.9642891288 0.9629818201 0.9573743939 + 0.9646986723 0.9633970857 0.9578499198 + 0.9651082754 0.9638124108 0.9583255053 + 0.9655178785 0.9642276168 0.9588009715 + 0.9659274817 0.9646428823 0.9592764974 + 0.9663329720 0.9650545716 0.9597474933 + 0.9667364955 0.9654644728 0.9602164030 + 0.9671400189 0.9658744931 0.9606851935 + 0.9675434828 0.9662843943 0.9611539841 + 0.9679470062 0.9666942954 0.9616228938 + 0.9683504105 0.9671043158 0.9620916843 + 0.9687538743 0.9675142169 0.9625605941 + 0.9691573977 0.9679241776 0.9630293846 + 0.9695609212 0.9683340788 0.9634981751 + 0.9699643850 0.9687440991 0.9639670849 + 0.9703654051 0.9691501260 0.9644325972 + 0.9707646966 0.9695534706 0.9648959041 + 0.9711639881 0.9699568748 0.9653592706 + 0.9715632796 0.9703602791 0.9658225775 + 0.9719626904 0.9707638025 0.9662858844 + 0.9723619819 0.9711672068 0.9667493105 + 0.9727612734 0.9715706110 0.9672126174 + 0.9731606841 0.9719740748 0.9676759839 + 0.9735599756 0.9723774791 0.9681392908 + 0.9739593267 0.9727808833 0.9686025977 + 0.9743570089 0.9731823802 0.9690620899 + 0.9747526050 0.9735813141 0.9695165157 + 0.9751480818 0.9739801884 0.9699708223 + 0.9755436778 0.9743791223 0.9704251289 + 0.9759392142 0.9747779965 0.9708794951 + 0.9763348103 0.9751768708 0.9713338017 + 0.9767302871 0.9755758047 0.9717881083 + 0.9771258235 0.9759746790 0.9722424746 + 0.9775214195 0.9763736725 0.9726967812 + 0.9779168963 0.9767726064 0.9731512070 + 0.9783114195 0.9771707058 0.9736040235 + 0.9786989093 0.9775642753 0.9740474820 + 0.9790863991 0.9779577851 0.9744911194 + 0.9794738889 0.9783512950 0.9749345779 + 0.9798614979 0.9787448049 0.9753780961 + 0.9802489877 0.9791383147 0.9758216143 + 0.9806364775 0.9795318246 0.9762650728 + 0.9810240269 0.9799252748 0.9767085910 + 0.9814115167 0.9803189039 0.9771521091 + 0.9817990065 0.9807124138 0.9775956273 + 0.9821864963 0.9811059237 0.9780392051 + 0.9825655818 0.9814931750 0.9784761071 + 0.9829416275 0.9818782210 0.9789105058 + 0.9833174944 0.9822633266 0.9793450236 + 0.9836934805 0.9826483130 0.9797794819 + 0.9840694070 0.9830332994 0.9802138805 + 0.9844453931 0.9834184051 0.9806483984 + 0.9848213196 0.9838033915 0.9810829163 + 0.9851973057 0.9841883779 0.9815173149 + 0.9855731726 0.9845734239 0.9819517732 + 0.9859492183 0.9849585295 0.9823862910 + 0.9863222241 0.9853414297 0.9828186035 + 0.9866843820 0.9857168794 0.9832429886 + 0.9870467186 0.9860923290 0.9836674929 + 0.9874088764 0.9864677191 0.9840919971 + 0.9877712131 0.9868432283 0.9845165014 + 0.9881333709 0.9872186184 0.9849410057 + 0.9884957075 0.9875940084 0.9853653908 + 0.9888579249 0.9879695177 0.9857898951 + 0.9892202020 0.9883449078 0.9862143993 + 0.9895824194 0.9887202978 0.9866389036 + 0.9899446964 0.9890956879 0.9870632887 + 0.9902951717 0.9894627929 0.9874807000 + 0.9906374216 0.9898239970 0.9878932238 + 0.9909796119 0.9901852012 0.9883056283 + 0.9913218021 0.9905464053 0.9887179732 + 0.9916639924 0.9909076095 0.9891303778 + 0.9920061827 0.9912688136 0.9895427823 + 0.9923483729 0.9916298985 0.9899551868 + 0.9926906228 0.9919911027 0.9903675914 + 0.9930328131 0.9923523068 0.9907801151 + 0.9933750033 0.9927135110 0.9911925197 + 0.9937171936 0.9930747151 0.9916049242 + 0.9940317869 0.9934129715 0.9920030236 + 0.9943410754 0.9937469959 0.9923985004 + 0.9946504831 0.9940810204 0.9927939177 + 0.9949597716 0.9944151044 0.9931892753 + 0.9952691793 0.9947491288 0.9935848117 + 0.9955785275 0.9950830936 0.9939802289 + 0.9958878160 0.9954171181 0.9943757057 + 0.9961972237 0.9957510829 0.9947711229 + 0.9965065122 0.9960851073 0.9951664805 + 0.9968159199 0.9964190722 0.9955620170 + 0.9971252084 0.9967530966 0.9959573746 + 0.9973875284 0.9970490932 0.9963253736 + 0.9976487160 0.9973441958 0.9966928959 + 0.9979100227 0.9976391792 0.9970602989 + 0.9981712103 0.9979342818 0.9974278212 + 0.9984325171 0.9982293844 0.9977952838 + 0.9986937046 0.9985244870 0.9981626868 + 0.9989550114 0.9988195896 0.9985302091 + 0.9992161989 0.9991146922 0.9988976121 + 0.9994775057 0.9994097948 0.9992650747 + 0.9997386932 0.9997048974 0.9996324778 + 1.0000000000 1.0000000000 1.0000000000 +} diff --git a/rpplugins/color_correction/resources/film_luts_raw/agfa_advantix_400.spi1d b/rpplugins/color_correction/resources/film_luts_raw/agfa_advantix_400.spi1d new file mode 100644 index 0000000..289bffe --- /dev/null +++ b/rpplugins/color_correction/resources/film_luts_raw/agfa_advantix_400.spi1d @@ -0,0 +1,1030 @@ +Version 1 +From 0.0 1.0 +Length 1024 +Components 3 +{ + 0.0000000000 0.0000000000 0.0000000000 + 0.0077106012 0.0070298198 0.0049559241 + 0.0147110997 0.0133244200 0.0095438547 + 0.0209813993 0.0190351103 0.0137957605 + 0.0266668592 0.0242017098 0.0177728795 + 0.0318832099 0.0289859492 0.0215300098 + 0.0367198400 0.0334706604 0.0251365695 + 0.0412060991 0.0377071798 0.0285660401 + 0.0454186983 0.0417603701 0.0318240002 + 0.0495144203 0.0456782803 0.0349723399 + 0.0534897000 0.0494300202 0.0380599014 + 0.0572170094 0.0530248806 0.0410333909 + 0.0607506298 0.0564629287 0.0438579209 + 0.0642050877 0.0597890504 0.0466150604 + 0.0676248968 0.0630782619 0.0493207090 + 0.0709792525 0.0663433895 0.0519826487 + 0.0742666870 0.0695055276 0.0545649193 + 0.0774300173 0.0725333989 0.0570865013 + 0.0805151016 0.0754740685 0.0595324002 + 0.0835210085 0.0783350095 0.0619145297 + 0.0864818692 0.0811579376 0.0642616600 + 0.0894213691 0.0839637592 0.0665879101 + 0.0923196077 0.0867140666 0.0689035431 + 0.0951313078 0.0894301310 0.0712108612 + 0.0978739634 0.0921017230 0.0734841302 + 0.1005603969 0.0947171375 0.0757039636 + 0.1032031998 0.0972908884 0.0778791532 + 0.1058200002 0.0998220220 0.0800394490 + 0.1084190011 0.1023029983 0.0821614563 + 0.1110042036 0.1047497019 0.0842550322 + 0.1135606021 0.1071517989 0.0863265395 + 0.1160767004 0.1095222011 0.0883673579 + 0.1185398027 0.1118747965 0.0903817788 + 0.1209601983 0.1141934991 0.0923686922 + 0.1233263016 0.1164946035 0.0943281874 + 0.1256539971 0.1187560037 0.0962788835 + 0.1279318035 0.1210196018 0.0982189104 + 0.1301839054 0.1232483014 0.1001423001 + 0.1324169934 0.1254474968 0.1020568013 + 0.1346450001 0.1275981963 0.1039576009 + 0.1368439049 0.1297464967 0.1058444977 + 0.1390296966 0.1318780035 0.1077136993 + 0.1412141025 0.1339951009 0.1095665023 + 0.1433850974 0.1361036003 0.1114090011 + 0.1455492973 0.1381817013 0.1132375002 + 0.1476995945 0.1402491927 0.1150472015 + 0.1498260051 0.1422760040 0.1168475971 + 0.1519210935 0.1442877054 0.1186361015 + 0.1539843976 0.1462759972 0.1204114035 + 0.1560284048 0.1482367963 0.1221595034 + 0.1580577046 0.1501837969 0.1238816977 + 0.1600770950 0.1520957053 0.1255871058 + 0.1620800942 0.1539966017 0.1272871047 + 0.1640495956 0.1559009999 0.1289671063 + 0.1659898013 0.1577883065 0.1306212991 + 0.1679138988 0.1596692055 0.1322596073 + 0.1698164046 0.1615532041 0.1338987052 + 0.1716932058 0.1634092033 0.1355329007 + 0.1735651940 0.1652536988 0.1371469051 + 0.1754256934 0.1670915931 0.1387543976 + 0.1772599965 0.1689036936 0.1403618008 + 0.1790851951 0.1707046032 0.1419776976 + 0.1808962971 0.1724977046 0.1435960978 + 0.1826874018 0.1742753983 0.1452053040 + 0.1844758987 0.1760344952 0.1468037963 + 0.1862519979 0.1777956039 0.1483945996 + 0.1880110949 0.1795548946 0.1499821991 + 0.1897681952 0.1812911928 0.1515644044 + 0.1915334016 0.1830188930 0.1531336010 + 0.1933026016 0.1847521067 0.1546926945 + 0.1950711012 0.1864724010 0.1562453955 + 0.1968317926 0.1881736070 0.1577879936 + 0.1985855997 0.1898707002 0.1593212038 + 0.2003341019 0.1915744990 0.1608411968 + 0.2020726055 0.1932611018 0.1623475999 + 0.2038006037 0.1949308962 0.1638498008 + 0.2055211961 0.1965949982 0.1653402001 + 0.2072315067 0.1982464939 0.1668276936 + 0.2089259028 0.1998752952 0.1683100015 + 0.2106073052 0.2014864981 0.1697766036 + 0.2122824937 0.2030902952 0.1712321937 + 0.2139520049 0.2046858966 0.1726851016 + 0.2156112045 0.2062691003 0.1741385013 + 0.2172587067 0.2078413963 0.1755896062 + 0.2189002037 0.2094067931 0.1770340055 + 0.2205414027 0.2109739035 0.1784697026 + 0.2221654058 0.2125506997 0.1799007058 + 0.2237752974 0.2141104043 0.1813267022 + 0.2253734022 0.2156585008 0.1827555001 + 0.2269579023 0.2172029018 0.1841821969 + 0.2285311073 0.2187507004 0.1856049001 + 0.2301028073 0.2203052938 0.1870242953 + 0.2316679060 0.2218398005 0.1884412020 + 0.2332272977 0.2233646065 0.1898476034 + 0.2347781956 0.2248875052 0.1912508011 + 0.2363210022 0.2264139950 0.1926520020 + 0.2378583997 0.2279502004 0.1940511018 + 0.2393900007 0.2294773012 0.1954436004 + 0.2409213930 0.2309951931 0.1968320012 + 0.2424533069 0.2325080037 0.1982160956 + 0.2439856976 0.2340212017 0.1995960027 + 0.2455042005 0.2355341017 0.2009744048 + 0.2470149994 0.2370381951 0.2023515999 + 0.2485187054 0.2385327965 0.2037250996 + 0.2500135005 0.2400144935 0.2050911933 + 0.2515035868 0.2414941937 0.2064488977 + 0.2529886961 0.2429734021 0.2078043073 + 0.2544668913 0.2444527000 0.2091580927 + 0.2559421062 0.2459246963 0.2105102986 + 0.2574181855 0.2473870963 0.2118566930 + 0.2588958144 0.2488387972 0.2131976932 + 0.2603701949 0.2502841949 0.2145289928 + 0.2618409991 0.2517311871 0.2158571929 + 0.2633078098 0.2531799972 0.2171828002 + 0.2647666931 0.2546122968 0.2185021937 + 0.2662197948 0.2560352981 0.2198203057 + 0.2676647902 0.2574462891 0.2211371064 + 0.2690947056 0.2588512003 0.2224553972 + 0.2705186903 0.2602562904 0.2237727940 + 0.2719335854 0.2616656125 0.2250885069 + 0.2733449936 0.2630712092 0.2264019996 + 0.2747541964 0.2644746006 0.2277133018 + 0.2761535943 0.2658649981 0.2290149033 + 0.2775473893 0.2672511041 0.2303117961 + 0.2789311111 0.2686300874 0.2316035926 + 0.2803080976 0.2700101137 0.2328924984 + 0.2816820145 0.2713905871 0.2341804951 + 0.2830528915 0.2727720141 0.2354660928 + 0.2844218910 0.2741498053 0.2367486060 + 0.2857857049 0.2755183876 0.2380257994 + 0.2871482074 0.2768800855 0.2393009067 + 0.2885094881 0.2782357037 0.2405748963 + 0.2898694873 0.2795907855 0.2418427020 + 0.2912288904 0.2809456885 0.2431090027 + 0.2925894856 0.2822988927 0.2443675995 + 0.2939479947 0.2836497128 0.2456243038 + 0.2952952981 0.2849884033 0.2468754947 + 0.2966383994 0.2863219976 0.2481230944 + 0.2979727983 0.2876453102 0.2493657023 + 0.2993055880 0.2889670134 0.2506079078 + 0.3006362915 0.2902868092 0.2518497109 + 0.3019703031 0.2916113138 0.2530942857 + 0.3033066094 0.2929391861 0.2543402910 + 0.3046467900 0.2942663133 0.2555767894 + 0.3059892058 0.2955929935 0.2568103075 + 0.3073258102 0.2969133854 0.2580339909 + 0.3086602092 0.2982315123 0.2592557073 + 0.3099907041 0.2995441854 0.2604722977 + 0.3113198876 0.3008551896 0.2616879940 + 0.3126456141 0.3021624088 0.2629038990 + 0.3139702082 0.3034684956 0.2641198039 + 0.3152804971 0.3047659099 0.2653389871 + 0.3165856004 0.3060601950 0.2665588856 + 0.3178817928 0.3073394001 0.2677814960 + 0.3191738129 0.3086116910 0.2690047026 + 0.3204653859 0.3098776937 0.2702280879 + 0.3217566907 0.3111397028 0.2714515030 + 0.3230504096 0.3124023974 0.2726680934 + 0.3243465126 0.3136656880 0.2738803029 + 0.3256357014 0.3149282932 0.2750887871 + 0.3269129992 0.3161900043 0.2762930095 + 0.3281877041 0.3174473047 0.2774964869 + 0.3294523060 0.3186891079 0.2786985040 + 0.3307167888 0.3199306130 0.2799009085 + 0.3319742084 0.3211612105 0.2811062932 + 0.3332315981 0.3223916888 0.2823117077 + 0.3344798982 0.3236224949 0.2835228145 + 0.3357258141 0.3248533905 0.2847346067 + 0.3369632959 0.3260852993 0.2859402895 + 0.3381935060 0.3273181915 0.2871426940 + 0.3394210935 0.3285504878 0.2883437872 + 0.3406409919 0.3297812939 0.2895427942 + 0.3418608904 0.3310121894 0.2907412052 + 0.3430762887 0.3322376013 0.2919301987 + 0.3442913890 0.3334628046 0.2931191921 + 0.3455013931 0.3346853852 0.2943033874 + 0.3467079103 0.3359062970 0.2954855859 + 0.3479113877 0.3371267021 0.2966673970 + 0.3491044044 0.3383455873 0.2978483140 + 0.3502975106 0.3395645022 0.2990292907 + 0.3514811993 0.3407759070 0.3002046943 + 0.3526628017 0.3419859111 0.3013797998 + 0.3538405001 0.3431887925 0.3025487959 + 0.3550119102 0.3443804085 0.3037114143 + 0.3561832011 0.3455719948 0.3048739135 + 0.3573499024 0.3467567861 0.3060263097 + 0.3585161865 0.3479408920 0.3071787059 + 0.3596819937 0.3491263092 0.3083275855 + 0.3608472049 0.3503136933 0.3094730973 + 0.3620123863 0.3515009880 0.3106186092 + 0.3631744087 0.3526912928 0.3117532134 + 0.3643358946 0.3538821042 0.3128874004 + 0.3654957116 0.3550710082 0.3140192926 + 0.3666515052 0.3562552929 0.3151476085 + 0.3678072095 0.3574396968 0.3162758946 + 0.3689568043 0.3586226106 0.3174037933 + 0.3701032996 0.3598049879 0.3185315132 + 0.3712497056 0.3609873056 0.3196595907 + 0.3723874092 0.3621698916 0.3207899034 + 0.3735251129 0.3633525968 0.3219203055 + 0.3746606112 0.3645330071 0.3230482042 + 0.3757919073 0.3657091856 0.3241730034 + 0.3769231141 0.3668855131 0.3252978027 + 0.3780477941 0.3680585921 0.3264195919 + 0.3791683912 0.3692297041 0.3275401890 + 0.3802889884 0.3704009056 0.3286607862 + 0.3814114928 0.3715662062 0.3297694921 + 0.3825342059 0.3727307022 0.3308778107 + 0.3836567998 0.3738948107 0.3319844902 + 0.3847779036 0.3750543892 0.3330835998 + 0.3858990073 0.3762139976 0.3341825902 + 0.3870202899 0.3773706853 0.3352803886 + 0.3881419003 0.3785190880 0.3363755047 + 0.3892636001 0.3796674013 0.3374705911 + 0.3903855085 0.3808118105 0.3385663033 + 0.3915078044 0.3819499016 0.3396627009 + 0.3926301897 0.3830879927 0.3407590091 + 0.3937473893 0.3842205107 0.3418577909 + 0.3948588073 0.3853465915 0.3429583013 + 0.3959701955 0.3864727020 0.3440589011 + 0.3970786929 0.3875936866 0.3451572061 + 0.3981842995 0.3887099922 0.3462541997 + 0.3992899954 0.3898262978 0.3473511934 + 0.4003950953 0.3909426928 0.3484469056 + 0.4014996886 0.3920593858 0.3495419025 + 0.4026043117 0.3931761086 0.3506368995 + 0.4037061036 0.3942928016 0.3517259955 + 0.4048052132 0.3954096138 0.3528110087 + 0.4059042931 0.3965264857 0.3538959920 + 0.4069995880 0.3976393044 0.3549771905 + 0.4080899060 0.3987472057 0.3560549915 + 0.4091801047 0.3998549879 0.3571327925 + 0.4102692008 0.4009611905 0.3582096994 + 0.4113557935 0.4020644128 0.3592854142 + 0.4124422967 0.4031674862 0.3603610098 + 0.4135288894 0.4042702019 0.3614374101 + 0.4146164060 0.4053708017 0.3625159860 + 0.4157038033 0.4064713120 0.3635945916 + 0.4167912900 0.4075717926 0.3646731079 + 0.4178684056 0.4086636007 0.3657506108 + 0.4189451039 0.4097551107 0.3668282032 + 0.4200218916 0.4108465910 0.3679057062 + 0.4210911095 0.4119307995 0.3689739108 + 0.4221575856 0.4130122960 0.3700402081 + 0.4232240021 0.4140937924 0.3711063862 + 0.4242891967 0.4151681066 0.3721705079 + 0.4253528118 0.4162335992 0.3732328117 + 0.4264163971 0.4172990918 0.3742950857 + 0.4274801910 0.4183638096 0.3753553033 + 0.4285458922 0.4194228053 0.3764078021 + 0.4296115041 0.4204818010 0.3774603903 + 0.4306772053 0.4215407968 0.3785130084 + 0.4317356944 0.4225960970 0.3795596957 + 0.4327917993 0.4236500859 0.3806053102 + 0.4338479042 0.4247041941 0.3816510141 + 0.4349010885 0.4257571995 0.3826957047 + 0.4359481037 0.4268082976 0.3837392926 + 0.4369950891 0.4278593957 0.3847829103 + 0.4380421042 0.4289104939 0.3858264983 + 0.4390830994 0.4299480021 0.3868727982 + 0.4401232004 0.4309833944 0.3879191875 + 0.4411633015 0.4320186973 0.3889656067 + 0.4421998858 0.4330511987 0.3900116980 + 0.4432297945 0.4340781868 0.3910571933 + 0.4442596138 0.4351052940 0.3921026886 + 0.4452894926 0.4361324012 0.3931482136 + 0.4463081956 0.4371604025 0.3941898048 + 0.4473238885 0.4381886125 0.3952310085 + 0.4483394921 0.4392169118 0.3962720931 + 0.4493534863 0.4402456880 0.3973116875 + 0.4503594041 0.4412770867 0.3983471990 + 0.4513652921 0.4423084855 0.3993827105 + 0.4523712099 0.4433399141 0.4004181027 + 0.4533743858 0.4443711936 0.4014500976 + 0.4543752968 0.4454025030 0.4024800062 + 0.4553762078 0.4464336932 0.4035097957 + 0.4563770890 0.4474649131 0.4045395851 + 0.4573712051 0.4484929144 0.4055626094 + 0.4583637118 0.4495202899 0.4065848887 + 0.4593561888 0.4505476058 0.4076071978 + 0.4603483975 0.4515748024 0.4086290896 + 0.4613364041 0.4525992870 0.4096485972 + 0.4623242915 0.4536238015 0.4106681049 + 0.4633122981 0.4546484053 0.4116876125 + 0.4642986953 0.4556727111 0.4127076864 + 0.4652802050 0.4566963017 0.4137291908 + 0.4662617147 0.4577200115 0.4147506952 + 0.4672433138 0.4587436914 0.4157721996 + 0.4682214856 0.4597648084 0.4167939126 + 0.4691945910 0.4607819021 0.4178156853 + 0.4701677859 0.4617989957 0.4188374877 + 0.4711408913 0.4628162086 0.4198592901 + 0.4721117914 0.4638265073 0.4208815098 + 0.4730801880 0.4648295045 0.4219039977 + 0.4740486145 0.4658325016 0.4229264855 + 0.4750168920 0.4668354988 0.4239490926 + 0.4759812951 0.4678359032 0.4249672890 + 0.4769417942 0.4688338935 0.4259825051 + 0.4779022932 0.4698317945 0.4269978106 + 0.4788627923 0.4708298147 0.4280130863 + 0.4798217118 0.4718261063 0.4290243089 + 0.4807789028 0.4728206098 0.4300324917 + 0.4817360938 0.4738149941 0.4310407043 + 0.4826933146 0.4748094976 0.4320487976 + 0.4836510122 0.4758031070 0.4330525994 + 0.4846090972 0.4767954051 0.4340521097 + 0.4855673015 0.4777877033 0.4350515008 + 0.4865255058 0.4787800014 0.4360510111 + 0.4874827862 0.4797681868 0.4370489120 + 0.4884381890 0.4807466865 0.4380441904 + 0.4893935025 0.4817250967 0.4390394986 + 0.4903487861 0.4827035964 0.4400348067 + 0.4913035929 0.4836812913 0.4410301149 + 0.4922530055 0.4846526980 0.4420258105 + 0.4932022989 0.4856241941 0.4430215061 + 0.4941517115 0.4865956008 0.4440171123 + 0.4951010942 0.4875670969 0.4450128078 + 0.4960469902 0.4885401130 0.4460073113 + 0.4969922900 0.4895133078 0.4470018148 + 0.4979375899 0.4904865026 0.4479962885 + 0.4988828897 0.4914596975 0.4489907026 + 0.4998261929 0.4924297035 0.4499832988 + 0.5007678866 0.4933972061 0.4509747922 + 0.5017095804 0.4943645895 0.4519664049 + 0.5026512146 0.4953320920 0.4529578984 + 0.5035929084 0.4962972105 0.4539453983 + 0.5045344830 0.4972535968 0.4549227953 + 0.5054761767 0.4982098937 0.4559001923 + 0.5064178109 0.4991663098 0.4568775892 + 0.5073593855 0.5001226068 0.4578549862 + 0.5082985759 0.5010713935 0.4588257968 + 0.5092371106 0.5020182133 0.4597955048 + 0.5101755261 0.5029649734 0.4607652128 + 0.5111140013 0.5039117932 0.4617348909 + 0.5120512843 0.5048583150 0.4627009034 + 0.5129861832 0.5058041811 0.4636611938 + 0.5139210224 0.5067501068 0.4646215141 + 0.5148558021 0.5076960921 0.4655818045 + 0.5157907009 0.5086420178 0.4665420949 + 0.5167201161 0.5095835924 0.4674983025 + 0.5176479220 0.5105239153 0.4684537053 + 0.5185757279 0.5114641786 0.4694091976 + 0.5195034742 0.5124045014 0.4703646004 + 0.5204296112 0.5133435726 0.4713194966 + 0.5213472843 0.5142772794 0.4722726047 + 0.5222650766 0.5152109265 0.4732257128 + 0.5231828094 0.5161445141 0.4741787910 + 0.5241004825 0.5170782208 0.4751318991 + 0.5250151753 0.5180053115 0.4760791957 + 0.5259271264 0.5189262033 0.4770225883 + 0.5268388987 0.5198469758 0.4779661000 + 0.5277506709 0.5207679272 0.4789094925 + 0.5286625028 0.5216888189 0.4798529148 + 0.5295729041 0.5226063132 0.4807907045 + 0.5304828882 0.5235229135 0.4817276001 + 0.5313928723 0.5244395137 0.4826645851 + 0.5323029160 0.5253561139 0.4836015105 + 0.5332129002 0.5262727141 0.4845381975 + 0.5341181159 0.5271934867 0.4854718149 + 0.5350232720 0.5281143188 0.4864053130 + 0.5359284282 0.5290349722 0.4873388112 + 0.5368335843 0.5299558043 0.4882723987 + 0.5377376080 0.5308768749 0.4892036915 + 0.5386344790 0.5318000913 0.4901269078 + 0.5395315289 0.5327231884 0.4910500944 + 0.5404284000 0.5336464047 0.4919733107 + 0.5413252711 0.5345695019 0.4928965867 + 0.5422213078 0.5354900956 0.4938173890 + 0.5431140065 0.5364019871 0.4947327971 + 0.5440065861 0.5373138785 0.4956482053 + 0.5448992848 0.5382258296 0.4965636134 + 0.5457919240 0.5391377211 0.4974789023 + 0.5466845036 0.5400484800 0.4983932078 + 0.5475770235 0.5409557223 0.4993050992 + 0.5484694839 0.5418627858 0.5002170205 + 0.5493621230 0.5427699089 0.5011289120 + 0.5502545834 0.5436770916 0.5020408034 + 0.5511453748 0.5445848703 0.5029529929 + 0.5520284176 0.5454956889 0.5038657784 + 0.5529114008 0.5464066267 0.5047786236 + 0.5537943244 0.5473175049 0.5056914091 + 0.5546773076 0.5482283235 0.5066043139 + 0.5555598140 0.5491390228 0.5075178146 + 0.5564333797 0.5500462055 0.5084359050 + 0.5573070049 0.5509535074 0.5093541145 + 0.5581805706 0.5518608093 0.5102722049 + 0.5590541959 0.5527679920 0.5111904144 + 0.5599278212 0.5536752939 0.5121085048 + 0.5607947707 0.5545750260 0.5130286813 + 0.5616607070 0.5554735065 0.5139490962 + 0.5625265837 0.5563721061 0.5148693919 + 0.5633925200 0.5572705865 0.5157896876 + 0.5642585158 0.5581691265 0.5167099833 + 0.5651180744 0.5590634942 0.5176302195 + 0.5659735799 0.5599551201 0.5185502172 + 0.5668290257 0.5608466268 0.5194702148 + 0.5676844120 0.5617381930 0.5203902125 + 0.5685399175 0.5626296997 0.5213103294 + 0.5693951845 0.5635216832 0.5222290158 + 0.5702500939 0.5644145012 0.5231453776 + 0.5711050034 0.5653073788 0.5240616798 + 0.5719599128 0.5662003160 0.5249779820 + 0.5728148222 0.5670931935 0.5258942842 + 0.5736696720 0.5679860711 0.5268107057 + 0.5745213032 0.5688735843 0.5277202725 + 0.5753722787 0.5697603226 0.5286294222 + 0.5762233734 0.5706470013 0.5295385122 + 0.5770744085 0.5715336800 0.5304474831 + 0.5779255033 0.5724204183 0.5313565731 + 0.5787749290 0.5733029842 0.5322644114 + 0.5796216726 0.5741786957 0.5331705213 + 0.5804684758 0.5750545263 0.5340765715 + 0.5813153982 0.5759302974 0.5349826813 + 0.5821622014 0.5768060088 0.5358887911 + 0.5830090046 0.5776817799 0.5367949009 + 0.5838500261 0.5785498023 0.5377020240 + 0.5846896768 0.5794162750 0.5386093259 + 0.5855293870 0.5802826881 0.5395165086 + 0.5863690972 0.5811491013 0.5404236913 + 0.5872088075 0.5820155144 0.5413309932 + 0.5880478024 0.5828816295 0.5422391295 + 0.5888836980 0.5837466121 0.5431495905 + 0.5897195935 0.5846114755 0.5440601110 + 0.5905554891 0.5854765177 0.5449705720 + 0.5913913250 0.5863415003 0.5458810925 + 0.5922272205 0.5872064233 0.5467916131 + 0.5930604935 0.5880705118 0.5476971865 + 0.5938909054 0.5889335871 0.5485988855 + 0.5947213173 0.5897967815 0.5495005250 + 0.5955516100 0.5906599164 0.5504022241 + 0.5963820219 0.5915231109 0.5513038039 + 0.5972123742 0.5923861861 0.5522055030 + 0.5980378985 0.5932421088 0.5531039834 + 0.5988610983 0.5940948129 0.5540016294 + 0.5996842980 0.5949473977 0.5548992157 + 0.6005076170 0.5958001018 0.5557969213 + 0.6013308167 0.5966528058 0.5566945076 + 0.6021540761 0.5975055099 0.5575920939 + 0.6029741764 0.5983492136 0.5584818721 + 0.6037936807 0.5991911888 0.5593709946 + 0.6046133041 0.6000332236 0.5602599978 + 0.6054328084 0.6008751988 0.5611490011 + 0.6062523127 0.6017171144 0.5620381236 + 0.6070718765 0.6025590897 0.5629271269 + 0.6078854203 0.6033985019 0.5638099909 + 0.6086981297 0.6042374969 0.5646926761 + 0.6095107794 0.6050766110 0.5655754209 + 0.6103236079 0.6059157252 0.5664582253 + 0.6111363173 0.6067547202 0.5673409104 + 0.6119490266 0.6075937748 0.5682235956 + 0.6127572060 0.6084339023 0.5691041946 + 0.6135646105 0.6092742085 0.5699847937 + 0.6143720150 0.6101143956 0.5708652735 + 0.6151794195 0.6109547019 0.5717458725 + 0.6159867048 0.6117950082 0.5726264119 + 0.6167941093 0.6126351953 0.5735070109 + 0.6175978780 0.6134642959 0.5743842125 + 0.6184005141 0.6142898798 0.5752606988 + 0.6192030907 0.6151155829 0.5761371851 + 0.6200057268 0.6159412265 0.5770136714 + 0.6208083034 0.6167668104 0.5778902173 + 0.6216108799 0.6175925136 0.5787667036 + 0.6224128008 0.6184120178 0.5796405077 + 0.6232140064 0.6192271113 0.5805128217 + 0.6240152717 0.6200422049 0.5813850760 + 0.6248164773 0.6208572984 0.5822573900 + 0.6256178021 0.6216725111 0.5831297040 + 0.6264191270 0.6224876046 0.5840020180 + 0.6272190213 0.6233018041 0.5848723054 + 0.6280159950 0.6241139770 0.5857393146 + 0.6288130879 0.6249262094 0.5866062045 + 0.6296101213 0.6257383823 0.5874732137 + 0.6304070950 0.6265506148 0.5883401036 + 0.6312041283 0.6273627877 0.5892071128 + 0.6320011020 0.6281750202 0.5900738835 + 0.6327958107 0.6289898753 0.5909329057 + 0.6335904002 0.6298049092 0.5917918086 + 0.6343849897 0.6306200027 0.5926507711 + 0.6351795197 0.6314349771 0.5935097933 + 0.6359741092 0.6322500706 0.5943686962 + 0.6367686987 0.6330651045 0.5952277184 + 0.6375622153 0.6338756084 0.5960803032 + 0.6383545995 0.6346815228 0.5969281793 + 0.6391469836 0.6354873776 0.5977761149 + 0.6399394870 0.6362932920 0.5986239910 + 0.6407318711 0.6370993257 0.5994718075 + 0.6415243745 0.6379051805 0.6003196836 + 0.6423168182 0.6387110949 0.6011673212 + 0.6431099176 0.6395062804 0.6020082235 + 0.6439030766 0.6403012276 0.6028491259 + 0.6446962953 0.6410961151 0.6036899090 + 0.6454893947 0.6418910027 0.6045308113 + 0.6462826133 0.6426858902 0.6053715944 + 0.6470757127 0.6434808969 0.6062124968 + 0.6478682160 0.6442744732 0.6070520878 + 0.6486594081 0.6450660229 0.6078900099 + 0.6494506001 0.6458573937 0.6087278128 + 0.6502417922 0.6466488242 0.6095656753 + 0.6510329843 0.6474401951 0.6104035974 + 0.6518241763 0.6482316852 0.6112414002 + 0.6526154280 0.6490231156 0.6120793223 + 0.6534075141 0.6498171091 0.6129179001 + 0.6542003155 0.6506124735 0.6137567759 + 0.6549929976 0.6514077783 0.6145955920 + 0.6557856798 0.6522032022 0.6154345274 + 0.6565784216 0.6529986262 0.6162734032 + 0.6573712230 0.6537939906 0.6171122789 + 0.6581639051 0.6545892954 0.6179510951 + 0.6589608788 0.6553863287 0.6187928915 + 0.6597586274 0.6561836004 0.6196351051 + 0.6605563164 0.6569808125 0.6204771996 + 0.6613541245 0.6577780843 0.6213192940 + 0.6621518135 0.6585754156 0.6221613884 + 0.6629495025 0.6593726873 0.6230034828 + 0.6637473106 0.6601698995 0.6238455772 + 0.6645362973 0.6609578133 0.6246849895 + 0.6653249264 0.6617453098 0.6255244017 + 0.6661134958 0.6625326872 0.6263638139 + 0.6669020057 0.6633201241 0.6272032261 + 0.6676905751 0.6641076207 0.6280425787 + 0.6684792042 0.6648949981 0.6288819909 + 0.6692677736 0.6656824946 0.6297214031 + 0.6700507998 0.6664658785 0.6305593252 + 0.6708337069 0.6672493219 0.6313971877 + 0.6716166139 0.6680325866 0.6322351098 + 0.6723995209 0.6688159108 0.6330729723 + 0.6731824279 0.6695992947 0.6339108944 + 0.6739652157 0.6703826189 0.6347488165 + 0.6747481227 0.6711658835 0.6355866790 + 0.6755290031 0.6719505191 0.6364173889 + 0.6763095856 0.6727352142 0.6372476220 + 0.6770902276 0.6735200286 0.6380779147 + 0.6778709292 0.6743047237 0.6389080882 + 0.6786515117 0.6750894189 0.6397383809 + 0.6794320941 0.6758741140 0.6405686140 + 0.6802126765 0.6766588092 0.6413989067 + 0.6809899211 0.6774402261 0.6422249079 + 0.6817654967 0.6782202721 0.6430497169 + 0.6825411916 0.6790003181 0.6438744068 + 0.6833168864 0.6797804236 0.6446992159 + 0.6840925813 0.6805605292 0.6455240250 + 0.6848682761 0.6813405156 0.6463487148 + 0.6856439710 0.6821206212 0.6471735239 + 0.6864163876 0.6828963161 0.6479974985 + 0.6871845126 0.6836665869 0.6488205791 + 0.6879525781 0.6844369173 0.6496437788 + 0.6887208223 0.6852071881 0.6504669189 + 0.6894888878 0.6859775186 0.6512901187 + 0.6902570128 0.6867477894 0.6521131992 + 0.6910251975 0.6875181198 0.6529363990 + 0.6917930245 0.6882880926 0.6537595987 + 0.6925569773 0.6890543103 0.6545832753 + 0.6933209896 0.6898205280 0.6554070115 + 0.6940848827 0.6905866861 0.6562306881 + 0.6948488951 0.6913527846 0.6570544243 + 0.6956127882 0.6921190023 0.6578781009 + 0.6963768005 0.6928852201 0.6587017775 + 0.6971408129 0.6936513782 0.6595255136 + 0.6979042888 0.6944183111 0.6603466868 + 0.6986675262 0.6951858997 0.6611664891 + 0.6994307041 0.6959534287 0.6619862914 + 0.7001938820 0.6967208982 0.6628060937 + 0.7009570003 0.6974884272 0.6636258960 + 0.7017201781 0.6982558966 0.6644456983 + 0.7024834156 0.6990234852 0.6652655005 + 0.7032464743 0.6997908950 0.6660854220 + 0.7040007114 0.7005546093 0.6669068933 + 0.7047548890 0.7013183832 0.6677284837 + 0.7055091262 0.7020820975 0.6685500145 + 0.7062633038 0.7028458118 0.6693716049 + 0.7070174813 0.7036095262 0.6701930761 + 0.7077717185 0.7043731809 0.6710147262 + 0.7085258961 0.7051368952 0.6718361974 + 0.7092772126 0.7058975101 0.6726554036 + 0.7100226283 0.7066521049 0.6734707952 + 0.7107681036 0.7074066997 0.6742863059 + 0.7115135789 0.7081612945 0.6751016974 + 0.7122589946 0.7089158893 0.6759172082 + 0.7130045295 0.7096704841 0.6767325997 + 0.7137500048 0.7104250789 0.6775481105 + 0.7144954205 0.7111796737 0.6783635020 + 0.7152379155 0.7119320035 0.6791734099 + 0.7159780264 0.7126826048 0.6799798012 + 0.7167180777 0.7134332061 0.6807861924 + 0.7174581885 0.7141839266 0.6815925837 + 0.7181981802 0.7149345279 0.6823989749 + 0.7189382911 0.7156851292 0.6832054257 + 0.7196784019 0.7164356709 0.6840116978 + 0.7204185128 0.7171862721 0.6848180890 + 0.7211552262 0.7179378271 0.6856207252 + 0.7218902111 0.7186897993 0.6864218116 + 0.7226251960 0.7194417119 0.6872228980 + 0.7233601809 0.7201936841 0.6880239844 + 0.7240952253 0.7209457159 0.6888250709 + 0.7248302102 0.7216976285 0.6896262169 + 0.7255653143 0.7224496007 0.6904273033 + 0.7263002992 0.7232015729 0.6912283897 + 0.7270305157 0.7239469290 0.6920284033 + 0.7277582884 0.7246891260 0.6928278804 + 0.7284861803 0.7254313231 0.6936274767 + 0.7292140722 0.7261735201 0.6944270134 + 0.7299419045 0.7269157171 0.6952266097 + 0.7306697965 0.7276579142 0.6960262060 + 0.7313976884 0.7284001708 0.6968256831 + 0.7321255803 0.7291424274 0.6976252794 + 0.7328494787 0.7298778892 0.6984261870 + 0.7335705757 0.7306084037 0.6992279887 + 0.7342916727 0.7313389778 0.7000297904 + 0.7350128293 0.7320696115 0.7008314729 + 0.7357339263 0.7328001857 0.7016332746 + 0.7364550233 0.7335308194 0.7024350762 + 0.7371760011 0.7342612743 0.7032368183 + 0.7378970981 0.7349919081 0.7040386200 + 0.7386168838 0.7357206941 0.7048401237 + 0.7393341064 0.7364463806 0.7056412101 + 0.7400513887 0.7371721268 0.7064422965 + 0.7407686710 0.7378978729 0.7072433829 + 0.7414860129 0.7386236191 0.7080445290 + 0.7422032952 0.7393493056 0.7088456154 + 0.7429205775 0.7400749922 0.7096467018 + 0.7436379194 0.7408006787 0.7104477882 + 0.7443552017 0.7415264249 0.7112485170 + 0.7450708747 0.7422525287 0.7120447159 + 0.7457867265 0.7429785728 0.7128409147 + 0.7465025187 0.7437046766 0.7136371136 + 0.7472183108 0.7444307804 0.7144333720 + 0.7479341030 0.7451568842 0.7152295709 + 0.7486497760 0.7458829880 0.7160258293 + 0.7493656278 0.7466090918 0.7168220282 + 0.7500814199 0.7473351955 0.7176182270 + 0.7507966161 0.7480586171 0.7184088230 + 0.7515113950 0.7487803102 0.7191962004 + 0.7522261739 0.7495018840 0.7199836969 + 0.7529410124 0.7502235770 0.7207711935 + 0.7536557913 0.7509452105 0.7215585709 + 0.7543706298 0.7516667843 0.7223461270 + 0.7550854087 0.7523884773 0.7231336236 + 0.7558001876 0.7531101108 0.7239210010 + 0.7565147281 0.7538313270 0.7247081995 + 0.7572231293 0.7545434237 0.7254921198 + 0.7579314709 0.7552555203 0.7262759805 + 0.7586399913 0.7559676766 0.7270599008 + 0.7593483925 0.7566797733 0.7278438807 + 0.7600567937 0.7573919296 0.7286278009 + 0.7607651949 0.7581040263 0.7294117212 + 0.7614735961 0.7588161826 0.7301957011 + 0.7621819973 0.7595282793 0.7309796214 + 0.7628899217 0.7602388263 0.7317612767 + 0.7635970116 0.7609465122 0.7325400710 + 0.7643041015 0.7616543174 0.7333188057 + 0.7650110722 0.7623620033 0.7340976000 + 0.7657182217 0.7630698085 0.7348762751 + 0.7664251924 0.7637774944 0.7356551290 + 0.7671322823 0.7644852996 0.7364339232 + 0.7678393126 0.7651931047 0.7372125983 + 0.7685464025 0.7659007907 0.7379913926 + 0.7692546248 0.7666099072 0.7387691736 + 0.7699635029 0.7673199773 0.7395464182 + 0.7706725001 0.7680299878 0.7403236032 + 0.7713813782 0.7687399983 0.7411009073 + 0.7720903158 0.7694501281 0.7418780923 + 0.7727993131 0.7701600790 0.7426552773 + 0.7735081911 0.7708700895 0.7434325814 + 0.7742171884 0.7715802193 0.7442098260 + 0.7749261260 0.7722902298 0.7449870110 + 0.7756347060 0.7730041146 0.7457646132 + 0.7763432264 0.7737196088 0.7465423942 + 0.7770516276 0.7744352221 0.7473201156 + 0.7777600884 0.7751507163 0.7480978966 + 0.7784684896 0.7758663297 0.7488756180 + 0.7791770101 0.7765818238 0.7496532798 + 0.7798854709 0.7772973776 0.7504311204 + 0.7805938721 0.7780128717 0.7512087822 + 0.7813023925 0.7787284851 0.7519865036 + 0.7820088267 0.7794386744 0.7527605891 + 0.7827143073 0.7801463008 0.7535331249 + 0.7834197283 0.7808538079 0.7543057203 + 0.7841252089 0.7815613151 0.7550783157 + 0.7848305702 0.7822688818 0.7558507919 + 0.7855361104 0.7829763889 0.7566233873 + 0.7862414718 0.7836840153 0.7573959231 + 0.7869470119 0.7843915224 0.7581685185 + 0.7876523733 0.7850990295 0.7589409947 + 0.7883579135 0.7858042717 0.7597122192 + 0.7890635133 0.7865074277 0.7604821920 + 0.7897689939 0.7872105837 0.7612522244 + 0.7904744744 0.7879136801 0.7620223165 + 0.7911800146 0.7886168957 0.7627922893 + 0.7918856144 0.7893199921 0.7635623813 + 0.7925910950 0.7900232077 0.7643324137 + 0.7932965755 0.7907263041 0.7651025057 + 0.7940021753 0.7914295197 0.7658724785 + 0.7947084904 0.7921326756 0.7666410804 + 0.7954170704 0.7928364277 0.7674059868 + 0.7961258292 0.7935400009 0.7681708932 + 0.7968344092 0.7942435741 0.7689357996 + 0.7975429893 0.7949472070 0.7697008252 + 0.7982516885 0.7956508994 0.7704656720 + 0.7989603281 0.7963544726 0.7712305784 + 0.7996690273 0.7970581055 0.7719954848 + 0.8003776073 0.7977616787 0.7727603912 + 0.8010861874 0.7984653115 0.7735252976 + 0.8017868996 0.7991653085 0.7742831707 + 0.8024861813 0.7998644710 0.7750402093 + 0.8031854033 0.8005638123 0.7757971287 + 0.8038846254 0.8012630939 0.7765541077 + 0.8045839071 0.8019623756 0.7773110271 + 0.8052831292 0.8026615977 0.7780680060 + 0.8059822917 0.8033608794 0.7788249850 + 0.8066815734 0.8040602207 0.7795819044 + 0.8073807955 0.8047593832 0.7803388834 + 0.8080779910 0.8054556251 0.7810941935 + 0.8087708950 0.8061454892 0.7818467021 + 0.8094639182 0.8068354130 0.7825992703 + 0.8101568222 0.8075252175 0.7833517790 + 0.8108497262 0.8082150817 0.7841042876 + 0.8115425706 0.8089050055 0.7848567963 + 0.8122354746 0.8095948100 0.7856093049 + 0.8129284978 0.8102846742 0.7863618135 + 0.8136214018 0.8109744787 0.7871143222 + 0.8143143058 0.8116644025 0.7878667712 + 0.8150073290 0.8123514056 0.7886186838 + 0.8157002926 0.8130369186 0.7893702984 + 0.8163931966 0.8137224913 0.7901219130 + 0.8170862198 0.8144080043 0.7908735275 + 0.8177791834 0.8150935173 0.7916250229 + 0.8184722066 0.8157790899 0.7923765779 + 0.8191652298 0.8164646029 0.7931281924 + 0.8198580742 0.8171501160 0.7938798070 + 0.8205510974 0.8178356886 0.7946314216 + 0.8212441206 0.8185212016 0.7953829765 + 0.8219397068 0.8192058802 0.7961322069 + 0.8226357102 0.8198903799 0.7968811989 + 0.8233315945 0.8205748796 0.7976301908 + 0.8240275979 0.8212594986 0.7983791828 + 0.8247236013 0.8219439983 0.7991281748 + 0.8254194856 0.8226286173 0.7998772264 + 0.8261154890 0.8233131170 0.8006262183 + 0.8268113732 0.8239976168 0.8013753295 + 0.8275073767 0.8246821761 0.8021243215 + 0.8282033801 0.8253666759 0.8028733134 + 0.8288903832 0.8260424733 0.8036262989 + 0.8295770884 0.8267179132 0.8043792844 + 0.8302637935 0.8273934126 0.8051323295 + 0.8309504986 0.8280689120 0.8058853149 + 0.8316372037 0.8287442923 0.8066383004 + 0.8323239088 0.8294197917 0.8073912859 + 0.8330106735 0.8300951719 0.8081442714 + 0.8336973786 0.8307706714 0.8088973165 + 0.8343840837 0.8314461708 0.8096503019 + 0.8350707889 0.8321216106 0.8104032874 + 0.8357518911 0.8327894211 0.8111593127 + 0.8364323974 0.8334565163 0.8119155765 + 0.8371130228 0.8341234922 0.8126717806 + 0.8377935290 0.8347905874 0.8134279847 + 0.8384740949 0.8354576230 0.8141843081 + 0.8391546011 0.8361247182 0.8149405122 + 0.8398352265 0.8367916942 0.8156967759 + 0.8405156732 0.8374587893 0.8164529800 + 0.8411962986 0.8381258249 0.8172091842 + 0.8418768048 0.8387929201 0.8179655075 + 0.8425561786 0.8394573927 0.8187175989 + 0.8432351947 0.8401209712 0.8194684982 + 0.8439140916 0.8407846093 0.8202192783 + 0.8445931077 0.8414481878 0.8209701180 + 0.8452720046 0.8421118259 0.8217208982 + 0.8459510207 0.8427755237 0.8224717975 + 0.8466299176 0.8434391022 0.8232225776 + 0.8473088741 0.8441026807 0.8239734173 + 0.8479878902 0.8447663188 0.8247241974 + 0.8486667871 0.8454298973 0.8254750967 + 0.8493432999 0.8460934162 0.8262230754 + 0.8500158787 0.8467569947 0.8269672990 + 0.8506883979 0.8474205136 0.8277115226 + 0.8513609767 0.8480839729 0.8284556866 + 0.8520336151 0.8487474918 0.8291999102 + 0.8527061939 0.8494110107 0.8299440742 + 0.8533787727 0.8500745296 0.8306882977 + 0.8540514112 0.8507381082 0.8314325809 + 0.8547239900 0.8514016271 0.8321768045 + 0.8553965092 0.8520650864 0.8329210281 + 0.8560690880 0.8527286053 0.8336651921 + 0.8567318916 0.8533846140 0.8344091177 + 0.8573938012 0.8540399075 0.8351529241 + 0.8580557108 0.8546953201 0.8358967900 + 0.8587176204 0.8553506136 0.8366405964 + 0.8593795896 0.8560060263 0.8373845220 + 0.8600414991 0.8566613197 0.8381283879 + 0.8607034087 0.8573166728 0.8388721943 + 0.8613653183 0.8579720259 0.8396161199 + 0.8620272875 0.8586273789 0.8403599262 + 0.8626891971 0.8592826724 0.8411037922 + 0.8633491993 0.8599355817 0.8418468833 + 0.8640050292 0.8605830073 0.8425887227 + 0.8646607995 0.8612304926 0.8433305025 + 0.8653166294 0.8618779778 0.8440722823 + 0.8659723997 0.8625254035 0.8448141217 + 0.8666282296 0.8631728888 0.8455559015 + 0.8672839999 0.8638203740 0.8462976813 + 0.8679397702 0.8644677997 0.8470395207 + 0.8685956001 0.8651152849 0.8477811813 + 0.8692513704 0.8657627106 0.8485230207 + 0.8699072003 0.8664101958 0.8492648005 + 0.8705629706 0.8670558929 0.8500074148 + 0.8712186813 0.8677002788 0.8507503867 + 0.8718745112 0.8683447242 0.8514934778 + 0.8725302219 0.8689891100 0.8522366285 + 0.8731859922 0.8696334958 0.8529797196 + 0.8738417029 0.8702778220 0.8537226915 + 0.8744974732 0.8709222078 0.8544657826 + 0.8751531839 0.8715665936 0.8552088737 + 0.8758090138 0.8722109795 0.8559520245 + 0.8764647841 0.8728554249 0.8566949964 + 0.8771204948 0.8734998107 0.8574380875 + 0.8777772188 0.8741462231 0.8581804037 + 0.8784344792 0.8747938275 0.8589221835 + 0.8790916800 0.8754413128 0.8596640825 + 0.8797490001 0.8760887980 0.8604059219 + 0.8804062009 0.8767364025 0.8611478209 + 0.8810635209 0.8773838878 0.8618897200 + 0.8817207217 0.8780313730 0.8626314998 + 0.8823779225 0.8786789775 0.8633733988 + 0.8830351830 0.8793265224 0.8641152978 + 0.8836923838 0.8799740076 0.8648570776 + 0.8843497038 0.8806216121 0.8655989766 + 0.8850082159 0.8812701106 0.8663362861 + 0.8856676221 0.8819192052 0.8670710921 + 0.8863270283 0.8825684190 0.8678058982 + 0.8869863749 0.8832175136 0.8685407043 + 0.8876457810 0.8838667274 0.8692755103 + 0.8883051276 0.8845158219 0.8700103164 + 0.8889644742 0.8851649165 0.8707451224 + 0.8896238804 0.8858140707 0.8714798093 + 0.8902832866 0.8864632249 0.8722146153 + 0.8909426928 0.8871123791 0.8729494214 + 0.8916019797 0.8877614737 0.8736842275 + 0.8922591805 0.8884071708 0.8744199872 + 0.8929132223 0.8890480995 0.8751569986 + 0.8935672045 0.8896890879 0.8758940101 + 0.8942213058 0.8903300166 0.8766310811 + 0.8948752880 0.8909708858 0.8773680925 + 0.8955293298 0.8916118145 0.8781051040 + 0.8961833119 0.8922526836 0.8788421750 + 0.8968374133 0.8928936124 0.8795791864 + 0.8974913955 0.8935344815 0.8803161979 + 0.8981453776 0.8941755295 0.8810533285 + 0.8987994194 0.8948163986 0.8817902803 + 0.8994534016 0.8954570889 0.8825269938 + 0.9001063704 0.8960943818 0.8832603097 + 0.9007593989 0.8967316747 0.8839936852 + 0.9014124274 0.8973690271 0.8847270012 + 0.9020653963 0.8980063200 0.8854603171 + 0.9027184248 0.8986436129 0.8861935735 + 0.9033715129 0.8992809057 0.8869268894 + 0.9040244818 0.8999181986 0.8876603246 + 0.9046775103 0.9005554914 0.8883935809 + 0.9053304791 0.9011927843 0.8891268969 + 0.9059835076 0.9018300772 0.8898602128 + 0.9066364765 0.9024674296 0.8905935287 + 0.9072905779 0.9031060934 0.8913232088 + 0.9079453945 0.9037460089 0.8920502067 + 0.9086002707 0.9043858051 0.8927773237 + 0.9092550874 0.9050256014 0.8935043216 + 0.9099100232 0.9056653976 0.8942313790 + 0.9105647802 0.9063051939 0.8949583769 + 0.9112197161 0.9069449902 0.8956853747 + 0.9118745923 0.9075847864 0.8964124918 + 0.9125294089 0.9082245827 0.8971394897 + 0.9131842852 0.9088644981 0.8978664875 + 0.9138391018 0.9095042944 0.8985936046 + 0.9144939780 0.9101440907 0.8993206024 + 0.9151384234 0.9107882977 0.9000440240 + 0.9157816768 0.9114329815 0.9007670879 + 0.9164249897 0.9120777249 0.9014902115 + 0.9170683026 0.9127225280 0.9022132754 + 0.9177114964 0.9133672118 0.9029362798 + 0.9183548093 0.9140118957 0.9036594033 + 0.9189981222 0.9146565795 0.9043825269 + 0.9196413755 0.9153013229 0.9051055908 + 0.9202846885 0.9159461260 0.9058287144 + 0.9209278822 0.9165908098 0.9065517783 + 0.9215711951 0.9172354937 0.9072747827 + 0.9222133756 0.9178792834 0.9079968929 + 0.9228429198 0.9185125828 0.9087103009 + 0.9234725237 0.9191460013 0.9094237089 + 0.9241020083 0.9197793007 0.9101369977 + 0.9247316122 0.9204127192 0.9108504057 + 0.9253610969 0.9210460186 0.9115636945 + 0.9259907007 0.9216793776 0.9122771025 + 0.9266201854 0.9223126769 0.9129905105 + 0.9272497892 0.9229460955 0.9137037992 + 0.9278793931 0.9235793948 0.9144172072 + 0.9285088778 0.9242128134 0.9151304960 + 0.9291384816 0.9248461723 0.9158439040 + 0.9297673106 0.9254785180 0.9165560007 + 0.9303902984 0.9261021018 0.9172585011 + 0.9310132265 0.9267256856 0.9179610014 + 0.9316362143 0.9273493290 0.9186636209 + 0.9322590828 0.9279729128 0.9193661213 + 0.9328820705 0.9285964966 0.9200686216 + 0.9335051179 0.9292201996 0.9207711816 + 0.9341279864 0.9298437834 0.9214736819 + 0.9347509742 0.9304674268 0.9221761823 + 0.9353739023 0.9310910106 0.9228788018 + 0.9359968901 0.9317145944 0.9235813022 + 0.9366198182 0.9323381782 0.9242838025 + 0.9372428060 0.9329618216 0.9249864221 + 0.9378637075 0.9335851073 0.9256830812 + 0.9384844899 0.9342085123 0.9263797998 + 0.9391052723 0.9348317981 0.9270763993 + 0.9397261143 0.9354550838 0.9277731180 + 0.9403468966 0.9360784292 0.9284697175 + 0.9409676790 0.9367017150 0.9291663170 + 0.9415885210 0.9373250008 0.9298629761 + 0.9422093034 0.9379482865 0.9305595756 + 0.9428302050 0.9385716915 0.9312562943 + 0.9434509873 0.9391949773 0.9319528937 + 0.9440718293 0.9398183227 0.9326494932 + 0.9446926117 0.9404416084 0.9333462119 + 0.9453073740 0.9410626292 0.9340357780 + 0.9459190965 0.9416825175 0.9347218871 + 0.9465308189 0.9423022866 0.9354081154 + 0.9471424818 0.9429221749 0.9360942245 + 0.9477542043 0.9435420036 0.9367803931 + 0.9483659267 0.9441617727 0.9374665022 + 0.9489775896 0.9447817206 0.9381526709 + 0.9495893121 0.9454014897 0.9388387799 + 0.9502009749 0.9460213780 0.9395250082 + 0.9508126974 0.9466412067 0.9402111173 + 0.9514244199 0.9472610950 0.9408972859 + 0.9520360827 0.9478809237 0.9415833950 + 0.9526458979 0.9484993815 0.9422674179 + 0.9532474279 0.9491121769 0.9429422021 + 0.9538488984 0.9497249126 0.9436171055 + 0.9544504285 0.9503375888 0.9442920089 + 0.9550518990 0.9509503245 0.9449669123 + 0.9556534290 0.9515630007 0.9456418157 + 0.9562548995 0.9521757960 0.9463167191 + 0.9568564296 0.9527884722 0.9469915032 + 0.9574579000 0.9534012079 0.9476664066 + 0.9580594897 0.9540138841 0.9483413100 + 0.9586610198 0.9546266794 0.9490162134 + 0.9592624903 0.9552394152 0.9496911168 + 0.9598640203 0.9558520913 0.9503659010 + 0.9604597092 0.9564607143 0.9510350823 + 0.9610503912 0.9570658207 0.9516996741 + 0.9616411924 0.9576709270 0.9523642063 + 0.9622319937 0.9582759738 0.9530286789 + 0.9628227949 0.9588810802 0.9536932111 + 0.9634134769 0.9594861865 0.9543578029 + 0.9640042782 0.9600912929 0.9550222754 + 0.9645950794 0.9606963992 0.9556868076 + 0.9651858211 0.9613015056 0.9563512802 + 0.9657766223 0.9619066119 0.9570158720 + 0.9663674235 0.9625117183 0.9576804042 + 0.9669582248 0.9631168246 0.9583448768 + 0.9675489068 0.9637219906 0.9590094090 + 0.9681262970 0.9643182158 0.9596667290 + 0.9686986208 0.9649111032 0.9603213072 + 0.9692708254 0.9655039907 0.9609760046 + 0.9698430896 0.9660969973 0.9616305828 + 0.9704154134 0.9666898847 0.9622852206 + 0.9709876776 0.9672827721 0.9629399180 + 0.9715598822 0.9678757191 0.9635944963 + 0.9721322060 0.9684687257 0.9642490745 + 0.9727045298 0.9690616131 0.9649037719 + 0.9732767940 0.9696545005 0.9655584097 + 0.9738491178 0.9702473879 0.9662129879 + 0.9744213223 0.9708403945 0.9668676853 + 0.9749935865 0.9714332819 0.9675223231 + 0.9755455256 0.9720122814 0.9681680202 + 0.9760900736 0.9725863934 0.9688106179 + 0.9766348004 0.9731606245 0.9694532156 + 0.9771794081 0.9737346768 0.9700958729 + 0.9777240753 0.9743087888 0.9707384706 + 0.9782686830 0.9748830199 0.9713811278 + 0.9788134098 0.9754570723 0.9720237255 + 0.9793580174 0.9760311842 0.9726663828 + 0.9799026251 0.9766052961 0.9733089805 + 0.9804472923 0.9771795273 0.9739515781 + 0.9809919000 0.9777535796 0.9745941758 + 0.9815366268 0.9783276916 0.9752368927 + 0.9820811749 0.9789019227 0.9758794904 + 0.9826055765 0.9794644713 0.9765092134 + 0.9831150770 0.9800186753 0.9771293998 + 0.9836245775 0.9805728197 0.9777497053 + 0.9841340184 0.9811270237 0.9783700109 + 0.9846435189 0.9816811085 0.9789903164 + 0.9851529002 0.9822353125 0.9796106219 + 0.9856624007 0.9827893972 0.9802309275 + 0.9861719012 0.9833436012 0.9808511138 + 0.9866812825 0.9838976860 0.9814714193 + 0.9871907830 0.9844518900 0.9820917249 + 0.9877002239 0.9850059748 0.9827119708 + 0.9882097244 0.9855601788 0.9833322763 + 0.9887192249 0.9861143231 0.9839525223 + 0.9892141223 0.9866619110 0.9845647812 + 0.9896609783 0.9871875048 0.9851508737 + 0.9901077747 0.9877132177 0.9857370853 + 0.9905545712 0.9882388115 0.9863231778 + 0.9910014272 0.9887645245 0.9869092703 + 0.9914482832 0.9892901182 0.9874954224 + 0.9918950796 0.9898157716 0.9880815148 + 0.9923418760 0.9903414249 0.9886677265 + 0.9927887917 0.9908670783 0.9892538190 + 0.9932355881 0.9913926721 0.9898399115 + 0.9936823845 0.9919183850 0.9904260039 + 0.9941291809 0.9924439788 0.9910122156 + 0.9945760965 0.9929696918 0.9915983081 + 0.9950228930 0.9934952855 0.9921844006 + 0.9954037070 0.9939768910 0.9927504063 + 0.9957572818 0.9944401979 0.9933080077 + 0.9961109161 0.9949035048 0.9938657284 + 0.9964643717 0.9953668118 0.9944233894 + 0.9968180060 0.9958301187 0.9949809909 + 0.9971715212 0.9962934256 0.9955387115 + 0.9975250959 0.9967567921 0.9960963130 + 0.9978786111 0.9972200990 0.9966539741 + 0.9982321858 0.9976834059 0.9972116947 + 0.9985858202 0.9981467128 0.9977692962 + 0.9989392757 0.9986100197 0.9983270168 + 0.9992929101 0.9990733862 0.9988846779 + 0.9996464252 0.9995366931 0.9994422793 + 1.0000000000 1.0000000000 1.0000000000 +} diff --git a/rpplugins/color_correction/resources/film_luts_raw/agfa_agfachrome_ct_precisa_100.spi1d b/rpplugins/color_correction/resources/film_luts_raw/agfa_agfachrome_ct_precisa_100.spi1d new file mode 100644 index 0000000..f4f64ae --- /dev/null +++ b/rpplugins/color_correction/resources/film_luts_raw/agfa_agfachrome_ct_precisa_100.spi1d @@ -0,0 +1,1030 @@ +Version 1 +From 0.0 1.0 +Length 1024 +Components 3 +{ + 0.0000000000 0.0000000000 0.0000000000 + 0.0005381406 0.0002651573 0.0005448886 + 0.0011811421 0.0005488236 0.0011236490 + 0.0018776740 0.0008598516 0.0017561211 + 0.0026023439 0.0012074891 0.0024572650 + 0.0033602889 0.0015991570 0.0032185989 + 0.0041644410 0.0020365941 0.0040284242 + 0.0050217710 0.0025163409 0.0048902789 + 0.0059333672 0.0030300061 0.0058214129 + 0.0069048190 0.0035676421 0.0068372628 + 0.0079441704 0.0041191741 0.0079477550 + 0.0090618078 0.0046778312 0.0091583403 + 0.0102658896 0.0052411938 0.0104663204 + 0.0115583995 0.0058102822 0.0118661895 + 0.0129291601 0.0063874712 0.0133533198 + 0.0143661099 0.0069762110 0.0149256596 + 0.0158517305 0.0075797332 0.0165787991 + 0.0173796508 0.0082016559 0.0183057394 + 0.0189530998 0.0088431826 0.0200976301 + 0.0205809996 0.0095067294 0.0219422299 + 0.0222787503 0.0101926001 0.0238327999 + 0.0240615793 0.0109011699 0.0257611796 + 0.0259451196 0.0116325803 0.0277215205 + 0.0279377103 0.0123844100 0.0297172107 + 0.0300485604 0.0131573398 0.0317482613 + 0.0322753713 0.0139512103 0.0338172801 + 0.0346145704 0.0147648398 0.0359307416 + 0.0370622911 0.0155985896 0.0380884185 + 0.0396122485 0.0164521597 0.0402955301 + 0.0422580615 0.0173262991 0.0425595492 + 0.0449894518 0.0182192009 0.0448740013 + 0.0477931984 0.0191300903 0.0472489484 + 0.0506595708 0.0200600196 0.0496853888 + 0.0535767302 0.0210082103 0.0521829911 + 0.0565305017 0.0219749697 0.0547407605 + 0.0595083982 0.0229592193 0.0573574007 + 0.0624992885 0.0239622109 0.0600296818 + 0.0654954314 0.0249828305 0.0627512708 + 0.0684895366 0.0260199904 0.0655123070 + 0.0714772493 0.0270722192 0.0683010966 + 0.0744543299 0.0281406008 0.0711084977 + 0.0774153098 0.0292240307 0.0739231929 + 0.0803605914 0.0303211194 0.0767356381 + 0.0832905099 0.0314316712 0.0795454979 + 0.0862074494 0.0325558111 0.0823479816 + 0.0891113579 0.0336936004 0.0851310268 + 0.0919999331 0.0348446108 0.0878951326 + 0.0948731005 0.0360087790 0.0906417519 + 0.0977329016 0.0371854194 0.0933719203 + 0.1005818024 0.0383735187 0.0960813016 + 0.1034189016 0.0395741388 0.0987711623 + 0.1062425002 0.0407866500 0.1014439017 + 0.1090549007 0.0420108810 0.1041020006 + 0.1118552014 0.0432458110 0.1067482978 + 0.1146425009 0.0444907583 0.1093854010 + 0.1174186990 0.0457457118 0.1120164022 + 0.1201832965 0.0470101312 0.1146423966 + 0.1229387969 0.0482850000 0.1172647029 + 0.1256874949 0.0495695882 0.1198822036 + 0.1284302026 0.0508622415 0.1224958971 + 0.1311666965 0.0521623604 0.1251043975 + 0.1338986009 0.0534698404 0.1277081966 + 0.1366281956 0.0547848493 0.1303080022 + 0.1393581927 0.0561086796 0.1329074055 + 0.1420904994 0.0574397892 0.1355095953 + 0.1448286027 0.0587780997 0.1381137967 + 0.1475744992 0.0601234213 0.1407177001 + 0.1503286064 0.0614760891 0.1433234960 + 0.1530916989 0.0628349632 0.1459300071 + 0.1558624953 0.0642008483 0.1485393941 + 0.1586423963 0.0655714497 0.1511545032 + 0.1614302993 0.0669477507 0.1537750065 + 0.1642321050 0.0683294088 0.1563979983 + 0.1670460999 0.0697180778 0.1590255052 + 0.1698731035 0.0711119920 0.1616581976 + 0.1727122962 0.0725102201 0.1642964929 + 0.1755629927 0.0739143416 0.1669408977 + 0.1784220040 0.0753230676 0.1695916951 + 0.1812902987 0.0767354220 0.1722505987 + 0.1841648072 0.0781524777 0.1749189049 + 0.1870469004 0.0795728117 0.1775977015 + 0.1899344027 0.0809954405 0.1802870035 + 0.1928229034 0.0824212879 0.1829870939 + 0.1957139969 0.0838513300 0.1856992990 + 0.1986058056 0.0852848813 0.1884211004 + 0.2014966011 0.0867218077 0.1911548972 + 0.2043849975 0.0881616324 0.1939021051 + 0.2072687000 0.0896041170 0.1966606975 + 0.2101463974 0.0910492018 0.1994311064 + 0.2130181938 0.0924970210 0.2022143006 + 0.2158842981 0.0939473733 0.2050091028 + 0.2187419981 0.0953999087 0.2078166008 + 0.2215912044 0.0968550667 0.2106339931 + 0.2244296968 0.0983112976 0.2134619057 + 0.2272589952 0.0997681171 0.2162988037 + 0.2300810069 0.1012267023 0.2191399932 + 0.2328950018 0.1026865989 0.2219882011 + 0.2356988937 0.1041480973 0.2248430997 + 0.2384911031 0.1056120992 0.2277006060 + 0.2412708998 0.1070773974 0.2305589020 + 0.2440378964 0.1085444018 0.2334149033 + 0.2467941940 0.1100130007 0.2362655997 + 0.2495391071 0.1114827022 0.2391107976 + 0.2522701919 0.1129537970 0.2419497073 + 0.2549884021 0.1144248024 0.2447791994 + 0.2576946914 0.1158969998 0.2475973070 + 0.2603886127 0.1173700988 0.2504028082 + 0.2630693913 0.1188448966 0.2531929910 + 0.2657378018 0.1203223020 0.2559669018 + 0.2683930099 0.1218004972 0.2587235868 + 0.2710328996 0.1232801974 0.2614609897 + 0.2736578882 0.1247610003 0.2641791999 + 0.2762688994 0.1262425929 0.2668775022 + 0.2788653970 0.1277254969 0.2695545852 + 0.2814469934 0.1292095035 0.2722114921 + 0.2840158045 0.1306941062 0.2748483121 + 0.2865726054 0.1321794987 0.2774635851 + 0.2891159058 0.1336652040 0.2800571024 + 0.2916449904 0.1351507008 0.2826282978 + 0.2941609025 0.1366363019 0.2851763070 + 0.2966657877 0.1381220967 0.2877005935 + 0.2991599143 0.1396085024 0.2902010083 + 0.3016422093 0.1410955936 0.2926791906 + 0.3041135073 0.1425838023 0.2951335907 + 0.3065750003 0.1440730989 0.2975631058 + 0.3090234101 0.1455630064 0.2999700010 + 0.3114587069 0.1470534056 0.3023560941 + 0.3138816059 0.1485445052 0.3047226965 + 0.3162932098 0.1500363946 0.3070712090 + 0.3186948001 0.1515289992 0.3094022870 + 0.3210870028 0.1530221999 0.3117175996 + 0.3234694898 0.1545169055 0.3140189052 + 0.3258418143 0.1560124010 0.3163051009 + 0.3282003999 0.1575089991 0.3185760975 + 0.3305430114 0.1590068042 0.3208332956 + 0.3328739107 0.1605062932 0.3230775893 + 0.3351961970 0.1620068997 0.3253093064 + 0.3375113010 0.1635068059 0.3275283873 + 0.3398194909 0.1650066972 0.3297384977 + 0.3421204984 0.1665070057 0.3319405913 + 0.3444133997 0.1680078954 0.3341340125 + 0.3466998041 0.1695086062 0.3363187015 + 0.3489798009 0.1710103005 0.3384949863 + 0.3512539864 0.1725132018 0.3406594098 + 0.3535234928 0.1740172058 0.3428128064 + 0.3557898104 0.1755214930 0.3449561894 + 0.3580540121 0.1770250052 0.3470906913 + 0.3603161871 0.1785289049 0.3492175043 + 0.3625768125 0.1800335944 0.3513374031 + 0.3648355901 0.1815388054 0.3534527123 + 0.3670929074 0.1830437034 0.3555639982 + 0.3693490922 0.1845479012 0.3576712012 + 0.3716045022 0.1860512048 0.3597705066 + 0.3738591969 0.1875541955 0.3618609011 + 0.3761132061 0.1890579015 0.3639445007 + 0.3783670068 0.1905619055 0.3660219014 + 0.3806206882 0.1920655966 0.3680920899 + 0.3828743994 0.1935691983 0.3701565862 + 0.3851284981 0.1950726956 0.3722172081 + 0.3873830140 0.1965761930 0.3742741942 + 0.3896380961 0.1980797052 0.3763268888 + 0.3918941915 0.1995833069 0.3783758879 + 0.3941515088 0.2010867000 0.3804208040 + 0.3964098990 0.2025887072 0.3824599087 + 0.3986696899 0.2040902972 0.3844920993 + 0.4009316862 0.2055917978 0.3865205944 + 0.4031954110 0.2070932984 0.3885455132 + 0.4054606855 0.2085942030 0.3905645013 + 0.4077295065 0.2100944966 0.3925797045 + 0.4100005031 0.2115938962 0.3945915103 + 0.4122735858 0.2130924016 0.3965987861 + 0.4145509005 0.2145905048 0.3986020982 + 0.4168311954 0.2160879970 0.4006024003 + 0.4191139042 0.2175852060 0.4025978148 + 0.4213995934 0.2190822959 0.4045889080 + 0.4236867130 0.2205785960 0.4065766037 + 0.4259749949 0.2220751941 0.4085580111 + 0.4282661080 0.2235720009 0.4105337858 + 0.4305579960 0.2250701934 0.4125058055 + 0.4328506887 0.2265686989 0.4144718051 + 0.4351426959 0.2280676961 0.4164347947 + 0.4374347031 0.2295663953 0.4183954895 + 0.4397264123 0.2310650051 0.4203527868 + 0.4420182109 0.2325633019 0.4223093092 + 0.4443092942 0.2340615988 0.4242646992 + 0.4465988874 0.2355599999 0.4262180924 + 0.4488858879 0.2370588928 0.4281705916 + 0.4511714876 0.2385578007 0.4301216900 + 0.4534544051 0.2400566041 0.4320701063 + 0.4557343125 0.2415551990 0.4340169132 + 0.4580109119 0.2430536002 0.4359580874 + 0.4602797031 0.2445522994 0.4378975034 + 0.4625451863 0.2460512072 0.4398345947 + 0.4648033977 0.2475509942 0.4417698979 + 0.4670571089 0.2490514964 0.4437046945 + 0.4693068862 0.2505528927 0.4456391931 + 0.4715498090 0.2520549893 0.4475742877 + 0.4737902880 0.2535574138 0.4495103061 + 0.4760245085 0.2550598979 0.4514476955 + 0.4782535136 0.2565625906 0.4533854127 + 0.4804762006 0.2580656111 0.4553222060 + 0.4826883078 0.2595695853 0.4572581053 + 0.4848966897 0.2610749006 0.4591920078 + 0.4870918095 0.2625809908 0.4611235857 + 0.4892837107 0.2640874088 0.4630536139 + 0.4914664030 0.2655943036 0.4649797976 + 0.4936434031 0.2671012878 0.4669052064 + 0.4958145916 0.2686108947 0.4688282013 + 0.4979768991 0.2701208889 0.4707511067 + 0.5001357198 0.2716321051 0.4726733863 + 0.5022798777 0.2731435895 0.4745965004 + 0.5044208765 0.2746556997 0.4765200913 + 0.5065475702 0.2761682868 0.4784458876 + 0.5086696744 0.2776814103 0.4803726077 + 0.5107814074 0.2791965902 0.4822996855 + 0.5128856897 0.2807131112 0.4842267036 + 0.5149818063 0.2822310030 0.4861502945 + 0.5170682073 0.2837496102 0.4880726039 + 0.5191485882 0.2852681875 0.4899899960 + 0.5212162137 0.2867869139 0.4919058979 + 0.5232796073 0.2883065045 0.4938189983 + 0.5253279209 0.2898262143 0.4957309067 + 0.5273739100 0.2913483083 0.4976414144 + 0.5294030905 0.2928704917 0.4995503128 + 0.5314307809 0.2943947911 0.5014581084 + 0.5334423184 0.2959192097 0.5033627748 + 0.5354515910 0.2974444032 0.5052657723 + 0.5374450088 0.2989695966 0.5071659088 + 0.5394350290 0.3004952967 0.5090647936 + 0.5414085984 0.3020209074 0.5109593868 + 0.5433781743 0.3035480082 0.5128529072 + 0.5453327894 0.3050751090 0.5147392750 + 0.5472834110 0.3066017032 0.5166242719 + 0.5492209792 0.3081282973 0.5185018182 + 0.5511540174 0.3096539080 0.5203778148 + 0.5530723929 0.3111793995 0.5222443938 + 0.5549861789 0.3127050102 0.5241091847 + 0.5568844080 0.3142305911 0.5259639025 + 0.5587790012 0.3157570958 0.5278167129 + 0.5606595278 0.3172838092 0.5296614766 + 0.5625373721 0.3188110888 0.5315043926 + 0.5644009113 0.3203384876 0.5333400965 + 0.5662627816 0.3218651116 0.5351735950 + 0.5681079030 0.3233912885 0.5369982123 + 0.5699527264 0.3249165118 0.5388190746 + 0.5717802048 0.3264403939 0.5406309962 + 0.5736076832 0.3279637098 0.5424374938 + 0.5754187703 0.3294858932 0.5442360044 + 0.5772284269 0.3310078979 0.5460273027 + 0.5790212750 0.3325291872 0.5478109121 + 0.5808100104 0.3340505064 0.5495834947 + 0.5825855732 0.3355714083 0.5513505936 + 0.5843548179 0.3370923996 0.5531036854 + 0.5861145854 0.3386130035 0.5548539758 + 0.5878657103 0.3401334882 0.5565863252 + 0.5896102190 0.3416540027 0.5583184958 + 0.5913426280 0.3431744874 0.5600315928 + 0.5930718184 0.3446949124 0.5617440939 + 0.5947852731 0.3462150991 0.5634422898 + 0.5964987874 0.3477351069 0.5651364923 + 0.5981938243 0.3492532969 0.5668197274 + 0.5998880863 0.3507714868 0.5684949160 + 0.6015682220 0.3522872925 0.5701624751 + 0.6032432914 0.3538025916 0.5718169212 + 0.6049085855 0.3553164005 0.5734683275 + 0.6065642238 0.3568288088 0.5750986934 + 0.6082149148 0.3583407104 0.5767289996 + 0.6098505855 0.3598510027 0.5783388019 + 0.6114861965 0.3613612056 0.5799455047 + 0.6131017208 0.3628711998 0.5815384984 + 0.6147162914 0.3643811047 0.5831218958 + 0.6163176894 0.3658905029 0.5846983194 + 0.6179122925 0.3673991859 0.5862581134 + 0.6195003986 0.3689076900 0.5878177881 + 0.6210765243 0.3704144955 0.5893548727 + 0.6226522923 0.3719212115 0.5908914208 + 0.6242104173 0.3734270036 0.5924147964 + 0.6257684827 0.3749324977 0.5939309001 + 0.6273151040 0.3764374852 0.5954414010 + 0.6288558245 0.3779416084 0.5969383121 + 0.6303917170 0.3794457912 0.5984352231 + 0.6319159865 0.3809471130 0.5999152064 + 0.6334401965 0.3824482858 0.6013936996 + 0.6349474788 0.3839477897 0.6028618217 + 0.6364527941 0.3854453862 0.6043204069 + 0.6379473805 0.3869430125 0.6057764888 + 0.6394302845 0.3884387910 0.6072123051 + 0.6409124732 0.3899345100 0.6086481214 + 0.6423766017 0.3914293945 0.6100676060 + 0.6438407898 0.3929235041 0.6114792824 + 0.6452940702 0.3944176137 0.6128858924 + 0.6467397809 0.3959099948 0.6142745018 + 0.6481837034 0.3974024057 0.6156631708 + 0.6496129036 0.3988932073 0.6170371175 + 0.6510421038 0.4003823996 0.6184059978 + 0.6524606943 0.4018715918 0.6197704077 + 0.6538727880 0.4033572972 0.6211217046 + 0.6552829146 0.4048427939 0.6224728823 + 0.6566761136 0.4063270986 0.6238120794 + 0.6580693126 0.4078091085 0.6251469254 + 0.6594510078 0.4092912078 0.6264786720 + 0.6608237028 0.4107702971 0.6277983785 + 0.6621962786 0.4122484028 0.6291180253 + 0.6635506153 0.4137260914 0.6304268837 + 0.6649050117 0.4152004123 0.6317300200 + 0.6662514806 0.4166747928 0.6330316067 + 0.6675873995 0.4181470871 0.6343147755 + 0.6689231992 0.4196172953 0.6355978847 + 0.6702443957 0.4210875034 0.6368724108 + 0.6715623736 0.4225546122 0.6381372809 + 0.6728767753 0.4240212142 0.6394020915 + 0.6741765738 0.4254870117 0.6406546235 + 0.6754763126 0.4269487858 0.6419048905 + 0.6767659187 0.4284105897 0.6431524754 + 0.6780474782 0.4298701882 0.6443892717 + 0.6793289781 0.4313269854 0.6456261277 + 0.6805943847 0.4327838123 0.6468564272 + 0.6818578839 0.4342373013 0.6480810046 + 0.6831179857 0.4356895089 0.6493057013 + 0.6843643785 0.4371415973 0.6505178809 + 0.6856108904 0.4385890961 0.6517279744 + 0.6868489981 0.4400365055 0.6529359818 + 0.6880782843 0.4414829910 0.6541314721 + 0.6893076897 0.4429262877 0.6553270221 + 0.6905233264 0.4443696141 0.6565173864 + 0.6917344928 0.4458107948 0.6577004194 + 0.6929457188 0.4472492039 0.6588833928 + 0.6941388845 0.4486874938 0.6600583196 + 0.6953321099 0.4501225054 0.6612290740 + 0.6965216994 0.4515551925 0.6623998284 + 0.6976982951 0.4529877901 0.6635617018 + 0.6988748908 0.4544155896 0.6647223234 + 0.7000442743 0.4558416903 0.6658821106 + 0.7012037039 0.4572679102 0.6670321822 + 0.7023630142 0.4586881995 0.6681821942 + 0.7035111785 0.4601078033 0.6693289876 + 0.7046517730 0.4615274072 0.6704663038 + 0.7057924271 0.4629419148 0.6716036797 + 0.7069209814 0.4643563032 0.6727368832 + 0.7080454230 0.4657703936 0.6738638878 + 0.7091699243 0.4671806991 0.6749910116 + 0.7102797031 0.4685910046 0.6761143208 + 0.7113872766 0.4700005949 0.6772344112 + 0.7124949098 0.4714061916 0.6783545017 + 0.7135862708 0.4728117883 0.6794689894 + 0.7146772146 0.4742164910 0.6805803180 + 0.7157673240 0.4756168127 0.6816917062 + 0.7168418169 0.4770171046 0.6827973723 + 0.7179161906 0.4784162939 0.6839008927 + 0.7189890146 0.4798108041 0.6850042939 + 0.7200477719 0.4812051952 0.6861020923 + 0.7211065292 0.4825986028 0.6871982217 + 0.7221630812 0.4839865863 0.6882944107 + 0.7232058048 0.4853746891 0.6893844008 + 0.7242485285 0.4867616892 0.6904730201 + 0.7252889872 0.4881420135 0.6915615797 + 0.7263165712 0.4895223975 0.6926428080 + 0.7273442149 0.4909023046 0.6937221885 + 0.7283703089 0.4922760129 0.6948016882 + 0.7293847203 0.4936496913 0.6958737969 + 0.7303991914 0.4950233996 0.6969439983 + 0.7314124703 0.4963918030 0.6980140805 + 0.7324116230 0.4977600873 0.6990771294 + 0.7334107161 0.4991284013 0.7001376152 + 0.7344096899 0.5004916787 0.7011982203 + 0.7353922725 0.5018543005 0.7022535801 + 0.7363749146 0.5032168031 0.7033064961 + 0.7373574972 0.5045748949 0.7043594122 + 0.7383249998 0.5059313178 0.7054070830 + 0.7392910719 0.5072876811 0.7064511180 + 0.7402572036 0.5086405277 0.7074950933 + 0.7412112951 0.5099905133 0.7085348964 + 0.7421622276 0.5113404989 0.7095698714 + 0.7431129813 0.5126873255 0.7106049061 + 0.7440556288 0.5140289068 0.7116366029 + 0.7449935079 0.5153704286 0.7126612067 + 0.7459315062 0.5167104006 0.7136859298 + 0.7468624711 0.5180423856 0.7147092223 + 0.7477856874 0.5193743110 0.7157247066 + 0.7487087846 0.5207061768 0.7167401910 + 0.7496278286 0.5220301747 0.7177556157 + 0.7505353093 0.5233532786 0.7187631726 + 0.7514427900 0.5246765018 0.7197703123 + 0.7523496747 0.5259947777 0.7207775116 + 0.7532436848 0.5273103714 0.7217786908 + 0.7541376948 0.5286259055 0.7227776051 + 0.7550317049 0.5299391747 0.7237765789 + 0.7559167743 0.5312479138 0.7247710824 + 0.7567995787 0.5325565934 0.7257605791 + 0.7576823831 0.5338652730 0.7267500758 + 0.7585588098 0.5351672173 0.7277382016 + 0.7594292164 0.5364691019 0.7287198901 + 0.7602995038 0.5377709866 0.7297015786 + 0.7611671090 0.5390685201 0.7306833863 + 0.7620239258 0.5403637290 0.7316588759 + 0.7628808022 0.5416588783 0.7326335907 + 0.7637376189 0.5429524183 0.7336083055 + 0.7645832896 0.5442410111 0.7345783710 + 0.7654271722 0.5455294847 0.7355446815 + 0.7662711740 0.5468180776 0.7365108728 + 0.7671089768 0.5481011868 0.7374755144 + 0.7679408789 0.5493832231 0.7384330034 + 0.7687727213 0.5506651998 0.7393903732 + 0.7696030140 0.5519440174 0.7403479218 + 0.7704212070 0.5532178879 0.7412980795 + 0.7712393999 0.5544918776 0.7422463894 + 0.7720575929 0.5557658076 0.7431948185 + 0.7728673816 0.5570312142 0.7441394925 + 0.7736734152 0.5582960248 0.7450783849 + 0.7744793892 0.5595608950 0.7460172772 + 0.7752828002 0.5608223081 0.7469562292 + 0.7760779858 0.5620794296 0.7478839755 + 0.7768731713 0.5633366108 0.7488111258 + 0.7776684761 0.5645936728 0.7497382164 + 0.7784557939 0.5658441782 0.7506607175 + 0.7792407274 0.5670942068 0.7515779138 + 0.7800256014 0.5683441162 0.7524952292 + 0.7808077931 0.5695917010 0.7534124255 + 0.7815821767 0.5708349943 0.7543212175 + 0.7823565006 0.5720782280 0.7552297115 + 0.7831308246 0.5733215213 0.7561380863 + 0.7838966846 0.5745599866 0.7570431232 + 0.7846595049 0.5757972002 0.7579433918 + 0.7854222059 0.5770342946 0.7588437200 + 0.7861832976 0.5782706141 0.7597439885 + 0.7869359851 0.5795021057 0.7606366277 + 0.7876886725 0.5807337165 0.7615280747 + 0.7884414196 0.5819652081 0.7624195814 + 0.7891888022 0.5831941962 0.7633082867 + 0.7899320722 0.5844206810 0.7641898990 + 0.7906754017 0.5856472254 0.7650715113 + 0.7914186716 0.5868737102 0.7659531236 + 0.7921544909 0.5880939960 0.7668281794 + 0.7928900123 0.5893129706 0.7676998973 + 0.7936254144 0.5905321240 0.7685714960 + 0.7943581939 0.5917500257 0.7694430947 + 0.7950845957 0.5929607153 0.7703047991 + 0.7958109975 0.5941714048 0.7711665034 + 0.7965373993 0.5953819752 0.7720282078 + 0.7972583771 0.5965896845 0.7728871703 + 0.7979758978 0.5977926850 0.7737402916 + 0.7986934781 0.5989956856 0.7745934725 + 0.7994109988 0.6001986861 0.7754465938 + 0.8001213074 0.6013975143 0.7762938142 + 0.8008307815 0.6025936007 0.7771372199 + 0.8015401959 0.6037898064 0.7779806256 + 0.8022487164 0.6049858928 0.7788239121 + 0.8029516935 0.6061770916 0.7796577811 + 0.8036546707 0.6073670983 0.7804902196 + 0.8043577075 0.6085572243 0.7813224792 + 0.8050580025 0.6097472906 0.7821539044 + 0.8057534099 0.6109319925 0.7829759717 + 0.8064488769 0.6121168137 0.7837980986 + 0.8071444035 0.6133015156 0.7846202254 + 0.8078358769 0.6144853234 0.7854393721 + 0.8085243106 0.6156625152 0.7862510085 + 0.8092126846 0.6168397069 0.7870625854 + 0.8099011183 0.6180168986 0.7878742218 + 0.8105850816 0.6191921234 0.7886819839 + 0.8112673163 0.6203610897 0.7894849777 + 0.8119494915 0.6215299964 0.7902880907 + 0.8126317859 0.6226990223 0.7910910845 + 0.8133102059 0.6238657236 0.7918882966 + 0.8139879704 0.6250272989 0.7926809788 + 0.8146657944 0.6261889935 0.7934737802 + 0.8153436184 0.6273506284 0.7942665815 + 0.8160151243 0.6285101175 0.7950521708 + 0.8166863918 0.6296654940 0.7958343029 + 0.8173575997 0.6308208108 0.7966163754 + 0.8180288076 0.6319761872 0.7973985076 + 0.8186935186 0.6331295967 0.7981728911 + 0.8193582296 0.6342797279 0.7989445925 + 0.8200228810 0.6354296803 0.7997162938 + 0.8206874728 0.6365796924 0.8004879951 + 0.8213469982 0.6377279162 0.8012521267 + 0.8220065236 0.6388722062 0.8020138741 + 0.8226659894 0.6400164962 0.8027758002 + 0.8233252764 0.6411607862 0.8035376072 + 0.8239793777 0.6423032880 0.8042908907 + 0.8246334791 0.6434404850 0.8050416708 + 0.8252875805 0.6445778012 0.8057923913 + 0.8259416819 0.6457151175 0.8065431714 + 0.8265889883 0.6468511820 0.8072862029 + 0.8272364140 0.6479817033 0.8080263734 + 0.8278837204 0.6491122246 0.8087667227 + 0.8285310864 0.6502428055 0.8095068932 + 0.8291730285 0.6513730288 0.8102409840 + 0.8298146129 0.6524980068 0.8109720945 + 0.8304561973 0.6536229849 0.8117030859 + 0.8310977817 0.6547480226 0.8124341965 + 0.8317347765 0.6558730006 0.8131592870 + 0.8323708773 0.6569942236 0.8138797283 + 0.8330070972 0.6581149101 0.8146002293 + 0.8336431980 0.6592354774 0.8153206110 + 0.8342744112 0.6603562236 0.8160365224 + 0.8349034786 0.6614738107 0.8167462945 + 0.8355324864 0.6625900865 0.8174561262 + 0.8361616135 0.6637063026 0.8181658983 + 0.8367878199 0.6648225188 0.8188729882 + 0.8374114037 0.6659368873 0.8195725083 + 0.8380349278 0.6670492291 0.8202719092 + 0.8386585116 0.6681613922 0.8209714293 + 0.8392807245 0.6692736149 0.8216704130 + 0.8399001956 0.6703848839 0.8223608732 + 0.8405197263 0.6714920998 0.8230513930 + 0.8411391973 0.6725993156 0.8237419128 + 0.8417584896 0.6737064719 0.8244323730 + 0.8423752785 0.6748136878 0.8251157999 + 0.8429921865 0.6759157181 0.8257976770 + 0.8436089754 0.6770169139 0.8264794946 + 0.8442258835 0.6781182289 0.8271613717 + 0.8448395133 0.6792194843 0.8278384805 + 0.8454523087 0.6803181767 0.8285114765 + 0.8460649848 0.6814149022 0.8291844726 + 0.8466777802 0.6825116277 0.8298574090 + 0.8472878933 0.6836082935 0.8305279016 + 0.8478950858 0.6847041845 0.8311896920 + 0.8485022783 0.6857963204 0.8318514228 + 0.8491094708 0.6868883967 0.8325132132 + 0.8497161865 0.6879804730 0.8331748843 + 0.8503192067 0.6890726089 0.8338286281 + 0.8509222865 0.6901617050 0.8344811201 + 0.8515254259 0.6912497878 0.8351336718 + 0.8521285057 0.6923378110 0.8357862830 + 0.8527284265 0.6934258938 0.8364341855 + 0.8533272147 0.6945127249 0.8370773792 + 0.8539260030 0.6955966949 0.8377205729 + 0.8545249104 0.6966806054 0.8383638859 + 0.8551219106 0.6977645755 0.8390063047 + 0.8557152152 0.6988484859 0.8396390080 + 0.8563085794 0.6999288797 0.8402717710 + 0.8569018841 0.7010084987 0.8409044743 + 0.8574953079 0.7020881176 0.8415372968 + 0.8580844998 0.7031677961 0.8421642184 + 0.8586729765 0.7042456865 0.8427875042 + 0.8592615724 0.7053195238 0.8434109092 + 0.8598501086 0.7063934207 0.8440341949 + 0.8604366779 0.7074673176 0.8446565270 + 0.8610199094 0.7085412145 0.8452715874 + 0.8616030812 0.7096114159 0.8458867073 + 0.8621863723 0.7106803060 0.8465017080 + 0.8627696037 0.7117491961 0.8471168280 + 0.8633472919 0.7128180265 0.8477255702 + 0.8639240861 0.7138860226 0.8483303189 + 0.8645008206 0.7149490118 0.8489350080 + 0.8650774956 0.7160121202 0.8495395780 + 0.8656529784 0.7170751095 0.8501440287 + 0.8662251234 0.7181380987 0.8507388234 + 0.8667972088 0.7191970944 0.8513334990 + 0.8673692942 0.7202522755 0.8519282937 + 0.8679413795 0.7213075161 0.8525230885 + 0.8685104251 0.7223626971 0.8531140089 + 0.8690779209 0.7234178782 0.8536998034 + 0.8696454167 0.7244672775 0.8542855978 + 0.8702129126 0.7255154848 0.8548712730 + 0.8707802892 0.7265638113 0.8554571271 + 0.8713405132 0.7276120186 0.8560361862 + 0.8719006181 0.7286595702 0.8566132784 + 0.8724607825 0.7297024131 0.8571904898 + 0.8730208874 0.7307453156 0.8577675819 + 0.8735787272 0.7317880988 0.8583437204 + 0.8741317987 0.7328310013 0.8589094877 + 0.8746848106 0.7338718176 0.8594753146 + 0.8752378821 0.7349092960 0.8600410819 + 0.8757908940 0.7359467745 0.8606069088 + 0.8763406873 0.7369843125 0.8611692190 + 0.8768883944 0.7380216718 0.8617258072 + 0.8774359822 0.7390558720 0.8622822762 + 0.8779836893 0.7400876284 0.8628388047 + 0.8785312772 0.7411193848 0.8633952737 + 0.8790736198 0.7421510816 0.8639466763 + 0.8796147704 0.7431827784 0.8644946814 + 0.8801559806 0.7442104220 0.8650428057 + 0.8806971908 0.7452365756 0.8655908108 + 0.8812381029 0.7462627888 0.8661388159 + 0.8817703724 0.7472890019 0.8666791916 + 0.8823025823 0.7483152151 0.8672177196 + 0.8828349113 0.7493349910 0.8677561879 + 0.8833671212 0.7503538132 0.8682947159 + 0.8838980198 0.7513726950 0.8688331842 + 0.8844233751 0.7523915172 0.8693615198 + 0.8849487901 0.7534103990 0.8698894978 + 0.8854740858 0.7544203997 0.8704175949 + 0.8859995008 0.7554299831 0.8709455729 + 0.8865231276 0.7564396262 0.8714727163 + 0.8870428205 0.7574492097 0.8719913960 + 0.8875625134 0.7584586740 0.8725100160 + 0.8880822062 0.7594599128 0.8730286956 + 0.8886018991 0.7604610920 0.8735473752 + 0.8891186714 0.7614622712 0.8740645051 + 0.8896307945 0.7624635100 0.8745744824 + 0.8901429176 0.7634646297 0.8750844002 + 0.8906549811 0.7644580007 0.8755943179 + 0.8911671042 0.7654513717 0.8761042953 + 0.8916761875 0.7664448023 0.8766121268 + 0.8921812177 0.7674381733 0.8771117926 + 0.8926861882 0.7684317231 0.8776115179 + 0.8931912184 0.7694169879 0.8781113029 + 0.8936961889 0.7704021931 0.8786110282 + 0.8941987157 0.7713873982 0.8791092038 + 0.8946977854 0.7723724842 0.8796014190 + 0.8951969147 0.7733576894 0.8800935745 + 0.8956959844 0.7743353844 0.8805857897 + 0.8961951137 0.7753123045 0.8810780048 + 0.8966916800 0.7762892246 0.8815690279 + 0.8971840739 0.7772660851 0.8820533156 + 0.8976764083 0.7782430053 0.8825377226 + 0.8981688023 0.7792145014 0.8830221295 + 0.8986610770 0.7801843882 0.8835064173 + 0.8991513848 0.7811542749 0.8839902282 + 0.8996360898 0.7821242809 0.8844659925 + 0.9001209140 0.7830942273 0.8849416971 + 0.9006056190 0.7840591073 0.8854175210 + 0.9010903835 0.7850208879 0.8858932257 + 0.9015741944 0.7859826088 0.8863689899 + 0.9020525813 0.7869443893 0.8868358731 + 0.9025310278 0.7879061103 0.8873022199 + 0.9030094147 0.7888634801 0.8877685070 + 0.9034878016 0.7898142934 0.8882347941 + 0.9039661884 0.7907652259 0.8887010813 + 0.9044383764 0.7917159796 0.8891620040 + 0.9049103856 0.7926669121 0.8896213174 + 0.9053822756 0.7936159968 0.8900805712 + 0.9058542848 0.7945556045 0.8905398846 + 0.9063262939 0.7954952717 0.8909991980 + 0.9067928195 0.7964348793 0.8914546967 + 0.9072574973 0.7973746061 0.8919070959 + 0.9077221751 0.7983142138 0.8923594952 + 0.9081869125 0.7992444038 0.8928118944 + 0.9086515903 0.8001731038 0.8932642937 + 0.9091123939 0.8011018038 0.8937140107 + 0.9095693231 0.8020305037 0.8941572905 + 0.9100260735 0.8029590845 0.8946006894 + 0.9104830027 0.8038828969 0.8950440288 + 0.9109398127 0.8048021793 0.8954873085 + 0.9113954902 0.8057215214 0.8959305882 + 0.9118455052 0.8066408038 0.8963645101 + 0.9122955799 0.8075600863 0.8967983127 + 0.9127457142 0.8084779978 0.8972321153 + 0.9131957889 0.8093873858 0.8976659179 + 0.9136459231 0.8102967739 0.8980997205 + 0.9140903950 0.8112062812 0.8985280991 + 0.9145337939 0.8121157289 0.8989533782 + 0.9149773121 0.8130251169 0.8993787169 + 0.9154207110 0.8139269948 0.8998039961 + 0.9158641100 0.8148258924 0.9002293944 + 0.9163044095 0.8157246709 0.9006530046 + 0.9167405963 0.8166236281 0.9010717869 + 0.9171767831 0.8175224066 0.9014906287 + 0.9176130295 0.8184180260 0.9019094110 + 0.9180492163 0.8193030953 0.9023281932 + 0.9184855223 0.8201882243 0.9027469754 + 0.9189139009 0.8210734129 0.9031597972 + 0.9193422794 0.8219584823 0.9035711884 + 0.9197707772 0.8228436112 0.9039825797 + 0.9201992154 0.8237193823 0.9043939710 + 0.9206275940 0.8245916963 0.9048054814 + 0.9210522175 0.8254640102 0.9052137733 + 0.9214730859 0.8263362050 0.9056159854 + 0.9218940139 0.8272085190 0.9060181975 + 0.9223148823 0.8280786276 0.9064204097 + 0.9227359295 0.8289378285 0.9068226218 + 0.9231567979 0.8297969103 0.9072247744 + 0.9235706925 0.8306559920 0.9076194763 + 0.9239845872 0.8315150738 0.9080122113 + 0.9243984222 0.8323742747 0.9084050059 + 0.9248123169 0.8332263231 0.9087976813 + 0.9252260923 0.8340724111 0.9091904759 + 0.9256373048 0.8349186182 0.9095817208 + 0.9260444045 0.8357648253 0.9099674821 + 0.9264515042 0.8366109729 0.9103533030 + 0.9268587232 0.8374571204 0.9107391834 + 0.9272658229 0.8382914066 0.9111250043 + 0.9276729822 0.8391243219 0.9115108252 + 0.9280738831 0.8399571776 0.9118928909 + 0.9284729958 0.8407900929 0.9122726917 + 0.9288722277 0.8416228890 0.9126523733 + 0.9292714000 0.8424531221 0.9130321145 + 0.9296705723 0.8432716131 0.9134117961 + 0.9300686717 0.8440901041 0.9137915969 + 0.9304581881 0.8449085951 0.9141638279 + 0.9308475852 0.8457270861 0.9145355821 + 0.9312371016 0.8465456963 0.9149073958 + 0.9316264987 0.8473572731 0.9152792096 + 0.9320160151 0.8481602073 0.9156510234 + 0.9324020743 0.8489630818 0.9160208702 + 0.9327831268 0.8497660160 0.9163845181 + 0.9331640005 0.8505688906 0.9167479873 + 0.9335449934 0.8513718247 0.9171115160 + 0.9339259863 0.8521640897 0.9174751043 + 0.9343069196 0.8529503942 0.9178385735 + 0.9346833229 0.8537368178 0.9181991816 + 0.9350569844 0.8545231819 0.9185562730 + 0.9354307055 0.8553094864 0.9189134836 + 0.9358044267 0.8560959101 0.9192706943 + 0.9361780882 0.8568696976 0.9196279049 + 0.9365519285 0.8576403260 0.9199851155 + 0.9369189143 0.8584108949 0.9203380942 + 0.9372844100 0.8591815233 0.9206891060 + 0.9376500249 0.8599520922 0.9210399985 + 0.9380155802 0.8607226014 0.9213908911 + 0.9383810759 0.8614792228 0.9217417836 + 0.9387466908 0.8622341156 0.9220927954 + 0.9391040802 0.8629890084 0.9224383831 + 0.9394611716 0.8637439013 0.9227827191 + 0.9398183227 0.8644987941 0.9231269956 + 0.9401754141 0.8652538061 0.9234712720 + 0.9405325055 0.8659942150 0.9238156080 + 0.9408891797 0.8667339087 0.9241598845 + 0.9412378073 0.8674736023 0.9244983196 + 0.9415863752 0.8682132959 0.9248359799 + 0.9419351220 0.8689528704 0.9251735806 + 0.9422836900 0.8696926236 0.9255113006 + 0.9426323175 0.8704177737 0.9258490205 + 0.9429801106 0.8711423278 0.9261866808 + 0.9433202147 0.8718668222 0.9265180230 + 0.9436603189 0.8725913167 0.9268490076 + 0.9440004230 0.8733158112 0.9271798730 + 0.9443404078 0.8740403056 0.9275109172 + 0.9446805120 0.8747491241 0.9278417826 + 0.9450199008 0.8754562736 0.9281728268 + 0.9453521967 0.8761636019 0.9284992814 + 0.9456846118 0.8768708110 0.9288254976 + 0.9460169077 0.8775780797 0.9291517138 + 0.9463492036 0.8782854080 0.9294778705 + 0.9466814995 0.8789795041 0.9298040867 + 0.9470136166 0.8796706796 0.9301303029 + 0.9473391175 0.8803619146 0.9304519296 + 0.9476644993 0.8810532093 0.9307729006 + 0.9479898810 0.8817443848 0.9310938716 + 0.9483153224 0.8824356198 0.9314149022 + 0.9486407042 0.8831164241 0.9317358732 + 0.9489660859 0.8837922215 0.9320567846 + 0.9492859244 0.8844680190 0.9323734045 + 0.9496051073 0.8851438165 0.9326885939 + 0.9499244094 0.8858196735 0.9330039024 + 0.9502437115 0.8864954710 0.9333190918 + 0.9505628943 0.8871642947 0.9336344004 + 0.9508821964 0.8878256083 0.9339495897 + 0.9511961937 0.8884869218 0.9342616200 + 0.9515085220 0.8891481161 0.9345716238 + 0.9518209100 0.8898094296 0.9348815084 + 0.9521332979 0.8904706836 0.9351915121 + 0.9524456263 0.8911284804 0.9355015159 + 0.9527580142 0.8917747736 0.9358114004 + 0.9530653954 0.8924211264 0.9361190200 + 0.9533687830 0.8930674195 0.9364230037 + 0.9536721706 0.8937137723 0.9367269874 + 0.9539756179 0.8943601251 0.9370309711 + 0.9542790055 0.8950064182 0.9373350739 + 0.9545822740 0.8956375122 0.9376391172 + 0.9548830986 0.8962674737 0.9379425049 + 0.9551774263 0.8968974948 0.9382423162 + 0.9554716945 0.8975275159 0.9385421276 + 0.9557660222 0.8981574774 0.9388418794 + 0.9560602903 0.8987876177 0.9391416907 + 0.9563546181 0.8994089961 0.9394415021 + 0.9566488862 0.9000241756 0.9397413135 + 0.9569364190 0.9006392956 0.9400386810 + 0.9572235942 0.9012544751 0.9403355718 + 0.9575108886 0.9018695951 0.9406325221 + 0.9577981830 0.9024847746 0.9409294128 + 0.9580854177 0.9030973911 0.9412263036 + 0.9583727121 0.9036974907 0.9415231943 + 0.9586551785 0.9042975903 0.9418178201 + 0.9589346051 0.9048978090 0.9421097040 + 0.9592139721 0.9054979086 0.9424015880 + 0.9594933987 0.9060980082 0.9426935911 + 0.9597727060 0.9066982269 0.9429854751 + 0.9600520730 0.9072868228 0.9432774782 + 0.9603300095 0.9078708291 0.9435690045 + 0.9606015086 0.9084547758 0.9438548088 + 0.9608730078 0.9090389013 0.9441404939 + 0.9611443877 0.9096229076 0.9444261789 + 0.9614158869 0.9102069139 0.9447119236 + 0.9616873264 0.9107877016 0.9449977279 + 0.9619588256 0.9113559127 0.9452834129 + 0.9622257948 0.9119240046 0.9455662966 + 0.9624909163 0.9124920964 0.9458472729 + 0.9627560973 0.9130601883 0.9461283088 + 0.9630212784 0.9136283994 0.9464092255 + 0.9632865191 0.9141964912 0.9466902018 + 0.9635517001 0.9147549272 0.9469711781 + 0.9638155103 0.9153077006 0.9472519755 + 0.9640734196 0.9158604145 0.9475296736 + 0.9643313289 0.9164131880 0.9478074908 + 0.9645891786 0.9169659019 0.9480851889 + 0.9648472071 0.9175186753 0.9483630061 + 0.9651051164 0.9180713296 0.9486407042 + 0.9653630257 0.9186087847 0.9489185214 + 0.9656159282 0.9191462994 0.9491940737 + 0.9658656120 0.9196838140 0.9494674206 + 0.9661152959 0.9202213287 0.9497408271 + 0.9663649201 0.9207587838 0.9500141144 + 0.9666146040 0.9212962985 0.9502874017 + 0.9668642879 0.9218286872 0.9505608082 + 0.9671139121 0.9223511219 0.9508340955 + 0.9673559070 0.9228736162 0.9511033893 + 0.9675977230 0.9233959913 0.9513720870 + 0.9678394198 0.9239184856 0.9516407251 + 0.9680811763 0.9244409204 0.9519094229 + 0.9683228731 0.9249634147 0.9521780014 + 0.9685646892 0.9254769087 0.9524466991 + 0.9688041806 0.9259846210 0.9527146220 + 0.9690378904 0.9264922738 0.9529792070 + 0.9692716002 0.9269999862 0.9532437921 + 0.9695051908 0.9275076985 0.9535083771 + 0.9697389007 0.9280154109 0.9537730217 + 0.9699726105 0.9285231233 0.9540376067 + 0.9702062011 0.9290189743 0.9543021917 + 0.9704347849 0.9295123816 0.9545649290 + 0.9706588984 0.9300057292 0.9548249841 + 0.9708830118 0.9304990172 0.9550849795 + 0.9711070061 0.9309923053 0.9553450942 + 0.9713311195 0.9314855933 0.9556052089 + 0.9715551734 0.9319790006 0.9558652043 + 0.9717792273 0.9324582815 0.9561253190 + 0.9719976187 0.9329372048 0.9563831091 + 0.9722136855 0.9334161282 0.9566395879 + 0.9724298716 0.9338951111 0.9568961263 + 0.9726459980 0.9343739748 0.9571526051 + 0.9728621840 0.9348528981 0.9574090838 + 0.9730783105 0.9353309274 0.9576656222 + 0.9732944965 0.9357969165 0.9579221010 + 0.9735053778 0.9362627864 0.9581764936 + 0.9737156034 0.9367287159 0.9584304094 + 0.9739257097 0.9371945858 0.9586842060 + 0.9741358161 0.9376605749 0.9589381218 + 0.9743459821 0.9381265044 0.9591919184 + 0.9745560884 0.9385910034 0.9594457746 + 0.9747661948 0.9390441179 0.9596995711 + 0.9749692082 0.9394972920 0.9599508047 + 0.9751719236 0.9399505258 0.9602015018 + 0.9753745198 0.9404035807 0.9604521990 + 0.9755771160 0.9408568144 0.9607028961 + 0.9757797718 0.9413099289 0.9609535933 + 0.9759824276 0.9417619109 0.9612042904 + 0.9761850238 0.9422025084 0.9614549875 + 0.9763807058 0.9426429868 0.9617013931 + 0.9765762091 0.9430835843 0.9619473219 + 0.9767717123 0.9435241818 0.9621930718 + 0.9769670963 0.9439647198 0.9624388814 + 0.9771625996 0.9444053173 0.9626846910 + 0.9773581028 0.9448456168 0.9629306197 + 0.9775536060 0.9452726245 0.9631764293 + 0.9777433276 0.9456995726 0.9634190798 + 0.9779326916 0.9461265802 0.9636611938 + 0.9781219959 0.9465535879 0.9639033079 + 0.9783114195 0.9469807148 0.9641454220 + 0.9785007238 0.9474077225 0.9643874764 + 0.9786900878 0.9478346705 0.9646295905 + 0.9788795114 0.9482499957 0.9648717046 + 0.9790633917 0.9486637115 0.9651131034 + 0.9792463183 0.9490774870 0.9653542042 + 0.9794291854 0.9494913220 0.9655953050 + 0.9796121716 0.9499049783 0.9658364058 + 0.9797950983 0.9503188133 0.9660773873 + 0.9799780846 0.9507325888 0.9663184881 + 0.9801610112 0.9511371255 0.9665595889 + 0.9803391099 0.9515374899 0.9667994976 + 0.9805151224 0.9519379735 0.9670386910 + 0.9806911945 0.9523383975 0.9672778249 + 0.9808672071 0.9527388215 0.9675168991 + 0.9810432196 0.9531391859 0.9677560925 + 0.9812191725 0.9535397291 0.9679952264 + 0.9813953042 0.9539344907 0.9682343006 + 0.9815682173 0.9543222785 0.9684708714 + 0.9817377925 0.9547100067 0.9687036872 + 0.9819074273 0.9550976753 0.9689365029 + 0.9820770025 0.9554854035 0.9691691995 + 0.9822465777 0.9558731914 0.9694020152 + 0.9824162722 0.9562609196 0.9696347713 + 0.9825859070 0.9566473961 0.9698675871 + 0.9827542901 0.9570254087 0.9700998068 + 0.9829186797 0.9574033022 0.9703279734 + 0.9830831289 0.9577813148 0.9705563188 + 0.9832473993 0.9581593275 0.9707846045 + 0.9834117889 0.9585372210 0.9710127711 + 0.9835761786 0.9589151740 0.9712411165 + 0.9837405086 0.9592931867 0.9714694023 + 0.9839048982 0.9596645832 0.9716976285 + 0.9840624928 0.9600340128 0.9719249010 + 0.9842191935 0.9604033232 0.9721521139 + 0.9843758941 0.9607725739 0.9723792076 + 0.9845327139 0.9611418843 0.9726063013 + 0.9846894145 0.9615113139 0.9728333950 + 0.9848461747 0.9618806243 0.9730604887 + 0.9850028753 0.9622468948 0.9732875824 + 0.9851561785 0.9626067877 0.9735137820 + 0.9853060246 0.9629666209 0.9737386107 + 0.9854558110 0.9633265138 0.9739633799 + 0.9856055975 0.9636862874 0.9741883278 + 0.9857553840 0.9640461802 0.9744130969 + 0.9859051704 0.9644060135 0.9746379256 + 0.9860550165 0.9647659063 0.9748628139 + 0.9862046242 0.9651184082 0.9750875831 + 0.9863498807 0.9654694200 0.9753091931 + 0.9864953160 0.9658203125 0.9755306840 + 0.9866406918 0.9661713243 0.9757522941 + 0.9867861271 0.9665222168 0.9759737849 + 0.9869315028 0.9668732285 0.9761952758 + 0.9870768785 0.9672241211 0.9764168859 + 0.9872221947 0.9675728083 0.9766383767 + 0.9873657823 0.9679149985 0.9768583179 + 0.9875077009 0.9682573080 0.9770764112 + 0.9876495004 0.9685994983 0.9772945046 + 0.9877914190 0.9689416885 0.9775127172 + 0.9879332781 0.9692839980 0.9777308106 + 0.9880751967 0.9696261883 0.9779489040 + 0.9882171154 0.9699683785 0.9781669974 + 0.9883589745 0.9703047872 0.9783850908 + 0.9884964824 0.9706377983 0.9786008000 + 0.9886338115 0.9709706903 0.9788162708 + 0.9887710214 0.9713037014 0.9790318012 + 0.9889082909 0.9716365933 0.9792472720 + 0.9890456200 0.9719696045 0.9794626832 + 0.9891828895 0.9723024964 0.9796782136 + 0.9893202186 0.9726355076 0.9798936844 + 0.9894558191 0.9729598761 0.9801084995 + 0.9895876050 0.9732838273 0.9803212285 + 0.9897193909 0.9736077189 0.9805338979 + 0.9898512959 0.9739316106 0.9807466865 + 0.9899830818 0.9742555022 0.9809594154 + 0.9901149273 0.9745793939 0.9811722040 + 0.9902467728 0.9749032855 0.9813848734 + 0.9903786182 0.9752253294 0.9815976024 + 0.9905071855 0.9755398035 0.9818084240 + 0.9906337261 0.9758542180 0.9820175767 + 0.9907602072 0.9761685729 0.9822267890 + 0.9908868074 0.9764831066 0.9824360013 + 0.9910132885 0.9767975211 0.9826452732 + 0.9911398292 0.9771118760 0.9828544855 + 0.9912663102 0.9774262905 0.9830636978 + 0.9913927913 0.9777371883 0.9832729101 + 0.9915155768 0.9780421257 0.9834790230 + 0.9916377068 0.9783470035 0.9836843014 + 0.9917597771 0.9786518812 0.9838895798 + 0.9918819070 0.9789568782 0.9840949774 + 0.9920039177 0.9792618155 0.9843003154 + 0.9921259880 0.9795666933 0.9845055938 + 0.9922481179 0.9798716903 0.9847108722 + 0.9923701286 0.9801716208 0.9849162102 + 0.9924876094 0.9804664850 0.9851183891 + 0.9926049709 0.9807614088 0.9853205085 + 0.9927225113 0.9810562730 0.9855225086 + 0.9928399920 0.9813511968 0.9857246280 + 0.9929574132 0.9816461205 0.9859266281 + 0.9930748940 0.9819409847 0.9861286879 + 0.9931923747 0.9822359085 0.9863306880 + 0.9933093190 0.9825251102 0.9865326285 + 0.9934214950 0.9828099012 0.9867315292 + 0.9935336709 0.9830945730 0.9869303703 + 0.9936459064 0.9833794236 0.9871293902 + 0.9937580824 0.9836640954 0.9873282909 + 0.9938703179 0.9839488864 0.9875271916 + 0.9939824939 0.9842336178 0.9877260923 + 0.9940947890 0.9845184088 0.9879251122 + 0.9942061901 0.9847974181 0.9881235957 + 0.9943130016 0.9850715995 0.9883189201 + 0.9944198132 0.9853457808 0.9885141253 + 0.9945265055 0.9856200814 0.9887093902 + 0.9946333170 0.9858943224 0.9889047146 + 0.9947401285 0.9861685038 0.9890999198 + 0.9948468804 0.9864426851 0.9892951846 + 0.9949536920 0.9867169261 0.9894905090 + 0.9950599074 0.9869858027 0.9896854758 + 0.9951617718 0.9872484803 0.9898774028 + 0.9952635765 0.9875112176 0.9900693297 + 0.9953655005 0.9877738953 0.9902613163 + 0.9954673052 0.9880366921 0.9904531837 + 0.9955692291 0.9882994294 0.9906451106 + 0.9956709743 0.9885621071 0.9908369780 + 0.9957728982 0.9888247848 0.9910290241 + 0.9958745837 0.9890835881 0.9912208915 + 0.9959716201 0.9893341064 0.9914097786 + 0.9960685968 0.9895846844 0.9915987253 + 0.9961655736 0.9898352027 0.9917874932 + 0.9962626100 0.9900857210 0.9919763803 + 0.9963595867 0.9903361797 0.9921653271 + 0.9964566231 0.9905868173 0.9923540950 + 0.9965535998 0.9908372760 0.9925429821 + 0.9966505766 0.9910866022 0.9927319288 + 0.9967427254 0.9913256764 0.9929165244 + 0.9968339205 0.9915646911 0.9931002259 + 0.9969251752 0.9918038249 0.9932839274 + 0.9970163703 0.9920428991 0.9934676290 + 0.9971076846 0.9922819138 0.9936512709 + 0.9971988797 0.9925209880 0.9938349724 + 0.9972901940 0.9927601218 0.9940186739 + 0.9973813891 0.9929991961 0.9942023754 + 0.9974687099 0.9932283759 0.9943823218 + 0.9975535870 0.9934555292 0.9945598245 + 0.9976384044 0.9936826825 0.9947373271 + 0.9977232814 0.9939097762 0.9949148297 + 0.9978080988 0.9941369891 0.9950922728 + 0.9978929758 0.9943640828 0.9952697754 + 0.9979777932 0.9945911765 0.9954472780 + 0.9980626702 0.9948183894 0.9956247807 + 0.9981455207 0.9950395823 0.9958003759 + 0.9982240796 0.9952540994 0.9959719181 + 0.9983025789 0.9954686761 0.9961432815 + 0.9983811975 0.9956831932 0.9963148236 + 0.9984596968 0.9958978295 0.9964861870 + 0.9985383153 0.9961122870 0.9966577291 + 0.9986168146 0.9963269234 0.9968290925 + 0.9986953735 0.9965413809 0.9970005751 + 0.9987738729 0.9967551827 0.9971719980 + 0.9988479018 0.9969543219 0.9973402023 + 0.9989216924 0.9971534014 0.9975082278 + 0.9989954233 0.9973524213 0.9976761937 + 0.9990692139 0.9975515008 0.9978441000 + 0.9991430044 0.9977505803 0.9980121255 + 0.9992166758 0.9979497194 0.9981800914 + 0.9992905259 0.9981487989 0.9983481169 + 0.9993643165 0.9983478785 0.9985160232 + 0.9994363785 0.9985377789 0.9986823797 + 0.9995067716 0.9987205863 0.9988471270 + 0.9995772839 0.9989033937 0.9990118146 + 0.9996476769 0.9990860820 0.9991765022 + 0.9997181892 0.9992688894 0.9993411899 + 0.9997885823 0.9994516969 0.9995058775 + 0.9998590946 0.9996345043 0.9996706247 + 0.9999294877 0.9998171926 0.9998353124 + 1.0000000000 1.0000000000 1.0000000000 +} diff --git a/rpplugins/color_correction/resources/film_luts_raw/agfa_agfachrome_ct_precisa_200.spi1d b/rpplugins/color_correction/resources/film_luts_raw/agfa_agfachrome_ct_precisa_200.spi1d new file mode 100644 index 0000000..99b9598 --- /dev/null +++ b/rpplugins/color_correction/resources/film_luts_raw/agfa_agfachrome_ct_precisa_200.spi1d @@ -0,0 +1,1030 @@ +Version 1 +From 0.0 1.0 +Length 1024 +Components 3 +{ + 0.0000000000 0.0000000000 0.0000000000 + 0.0002699328 0.0001753761 0.0002523783 + 0.0005516693 0.0003570581 0.0005202319 + 0.0008440902 0.0005450998 0.0008039851 + 0.0011470990 0.0007395549 0.0011026140 + 0.0014597330 0.0009404911 0.0014156949 + 0.0017813731 0.0011476850 0.0017421190 + 0.0021126880 0.0013612730 0.0020805011 + 0.0024531030 0.0015815590 0.0024294229 + 0.0028031650 0.0018088090 0.0027884119 + 0.0031638411 0.0020427699 0.0031579121 + 0.0035372649 0.0022836919 0.0035393820 + 0.0039257319 0.0025316810 0.0039346260 + 0.0043312181 0.0027867940 0.0043465500 + 0.0047563538 0.0030489860 0.0047766608 + 0.0052017048 0.0033181130 0.0052262088 + 0.0056667780 0.0035944311 0.0056956508 + 0.0061506722 0.0038782239 0.0061842999 + 0.0066511780 0.0041694939 0.0066920272 + 0.0071674078 0.0044688610 0.0072181849 + 0.0076976968 0.0047760759 0.0077622221 + 0.0082411859 0.0050910199 0.0083242692 + 0.0087973205 0.0054136459 0.0089058857 + 0.0093660019 0.0057440512 0.0095065739 + 0.0099473577 0.0060824021 0.0101279598 + 0.0105416896 0.0064286222 0.0107696000 + 0.0111480197 0.0067824679 0.0114314295 + 0.0117668100 0.0071440842 0.0121141002 + 0.0123977298 0.0075133010 0.0128158899 + 0.0130404802 0.0078901956 0.0135375699 + 0.0136951199 0.0082744109 0.0142785497 + 0.0143617000 0.0086660404 0.0150373597 + 0.0150401201 0.0090650087 0.0158140305 + 0.0157300606 0.0094716744 0.0166073292 + 0.0164318401 0.0098855980 0.0174160805 + 0.0171449091 0.0103072198 0.0182415899 + 0.0178689398 0.0107360203 0.0190821793 + 0.0186050907 0.0111725898 0.0199379697 + 0.0193527602 0.0116162105 0.0208086297 + 0.0201126505 0.0120675396 0.0216945801 + 0.0208839308 0.0125266099 0.0225958191 + 0.0216670800 0.0129928002 0.0235118493 + 0.0224615298 0.0134667596 0.0244435798 + 0.0232677106 0.0139479404 0.0253902208 + 0.0240852199 0.0144363800 0.0263507906 + 0.0249137003 0.0149327302 0.0273268502 + 0.0257528108 0.0154370395 0.0283182394 + 0.0266024694 0.0159486309 0.0293240100 + 0.0274628494 0.0164675806 0.0303431805 + 0.0283344202 0.0169943292 0.0313761793 + 0.0292166006 0.0175288208 0.0324220508 + 0.0301091801 0.0180700701 0.0334794186 + 0.0310120601 0.0186186992 0.0345463790 + 0.0319244787 0.0191750694 0.0356225707 + 0.0328475386 0.0197390206 0.0367073193 + 0.0337808393 0.0203102101 0.0377987213 + 0.0347246900 0.0208885409 0.0388945192 + 0.0356788710 0.0214745607 0.0399941206 + 0.0366426483 0.0220674798 0.0410979390 + 0.0376164615 0.0226682406 0.0422052182 + 0.0386001393 0.0232766997 0.0433141701 + 0.0395945087 0.0238917898 0.0444252789 + 0.0405988395 0.0245153997 0.0455389805 + 0.0416126810 0.0251462702 0.0466558412 + 0.0426358394 0.0257849507 0.0477751605 + 0.0436693914 0.0264302809 0.0488959402 + 0.0447117910 0.0270844605 0.0500185490 + 0.0457648709 0.0277455002 0.0511438698 + 0.0468259901 0.0284139998 0.0522733182 + 0.0478970297 0.0290895496 0.0534073599 + 0.0489763990 0.0297721792 0.0545452908 + 0.0500655286 0.0304632597 0.0556870997 + 0.0511628389 0.0311617199 0.0568346418 + 0.0522699915 0.0318679288 0.0579884015 + 0.0533850715 0.0325823203 0.0591484793 + 0.0545096211 0.0333043113 0.0603141114 + 0.0556424297 0.0340342708 0.0614848994 + 0.0567837097 0.0347718298 0.0626629367 + 0.0579337105 0.0355160087 0.0638478696 + 0.0590906888 0.0362669006 0.0650385097 + 0.0602574088 0.0370258093 0.0662359372 + 0.0614334010 0.0377927385 0.0674390867 + 0.0626170933 0.0385673605 0.0686485395 + 0.0638106465 0.0393497609 0.0698641911 + 0.0650118366 0.0401403792 0.0710861981 + 0.0662213415 0.0409397595 0.0723134726 + 0.0674379617 0.0417471118 0.0735469386 + 0.0686631873 0.0425618887 0.0747859776 + 0.0698976368 0.0433834791 0.0760307387 + 0.0711404011 0.0442118682 0.0772804022 + 0.0723914728 0.0450474396 0.0785348937 + 0.0736518502 0.0458911397 0.0797948688 + 0.0749201477 0.0467427112 0.0810601711 + 0.0761969313 0.0476017408 0.0823324025 + 0.0774813071 0.0484685600 0.0836096331 + 0.0787731186 0.0493434109 0.0848924294 + 0.0800740421 0.0502262115 0.0861801729 + 0.0813831016 0.0511168912 0.0874729678 + 0.0827006921 0.0520157702 0.0887702629 + 0.0840270668 0.0529231317 0.0900717899 + 0.0853607282 0.0538391396 0.0913778096 + 0.0867023394 0.0547635406 0.0926876292 + 0.0880530998 0.0556963496 0.0940016583 + 0.0894121006 0.0566373095 0.0953195170 + 0.0907792076 0.0575862303 0.0966407433 + 0.0921551064 0.0585427284 0.0979649574 + 0.0935385600 0.0595068783 0.0992923602 + 0.0949299335 0.0604788885 0.1006235033 + 0.0963296816 0.0614589490 0.1019582972 + 0.0977364033 0.0624472797 0.1032961980 + 0.0991507098 0.0634440780 0.1046369970 + 0.1005733013 0.0644495711 0.1059795022 + 0.1020032987 0.0654638633 0.1073246971 + 0.1034407988 0.0664867088 0.1086725965 + 0.1048860997 0.0675178468 0.1100225002 + 0.1063387021 0.0685571134 0.1113744006 + 0.1077983007 0.0696041286 0.1127282009 + 0.1092654988 0.0706589893 0.1140839010 + 0.1107404977 0.0717224628 0.1154410988 + 0.1122227013 0.0727944970 0.1168001965 + 0.1137126014 0.0738748014 0.1181621030 + 0.1152106971 0.0749634504 0.1195268035 + 0.1167161986 0.0760605484 0.1208942011 + 0.1182283014 0.0771661699 0.1222644001 + 0.1197486967 0.0782803968 0.1236374006 + 0.1212769002 0.0794033334 0.1250136942 + 0.1228116006 0.0805374980 0.1263937950 + 0.1243539006 0.0816816911 0.1277772933 + 0.1259036064 0.0828360692 0.1291648000 + 0.1274601966 0.0840003714 0.1305564940 + 0.1290239990 0.0851741210 0.1319530010 + 0.1305951029 0.0863568485 0.1333540976 + 0.1321730018 0.0875512436 0.1347596943 + 0.1337587982 0.0887546614 0.1361702979 + 0.1353518963 0.0899670422 0.1375872940 + 0.1369515061 0.0911882967 0.1390096992 + 0.1385575980 0.0924183726 0.1404386014 + 0.1401696056 0.0936605185 0.1418738067 + 0.1417876929 0.0949114934 0.1433147937 + 0.1434136033 0.0961711928 0.1447637975 + 0.1450462937 0.0974395201 0.1462194026 + 0.1466850936 0.0987184718 0.1476815939 + 0.1483296007 0.1000078022 0.1491505057 + 0.1499803066 0.1013054997 0.1506260037 + 0.1516395956 0.1026116982 0.1521109045 + 0.1533043981 0.1039282009 0.1536028981 + 0.1549746990 0.1052552983 0.1551018059 + 0.1566507071 0.1065905988 0.1566075981 + 0.1583354026 0.1079339013 0.1581221074 + 0.1600269973 0.1092884988 0.1596440971 + 0.1617241949 0.1106527001 0.1611728072 + 0.1634269953 0.1120247021 0.1627078950 + 0.1651381999 0.1134048030 0.1642509997 + 0.1668564975 0.1147963032 0.1658020020 + 0.1685802042 0.1161947995 0.1673590988 + 0.1703090966 0.1176000983 0.1689217985 + 0.1720459014 0.1190157980 0.1704941988 + 0.1737886965 0.1204395965 0.1720733941 + 0.1755366027 0.1218703017 0.1736585945 + 0.1772904992 0.1233104020 0.1752517074 + 0.1790520996 0.1247609034 0.1768528074 + 0.1808187962 0.1262181997 0.1784588993 + 0.1825904995 0.1276842058 0.1800702065 + 0.1843689978 0.1291611046 0.1816917062 + 0.1861528009 0.1306443959 0.1833177954 + 0.1879408062 0.1321358979 0.1849482954 + 0.1897339970 0.1336382031 0.1865873039 + 0.1915318966 0.1351462007 0.1882306933 + 0.1933335066 0.1366620958 0.1898781061 + 0.1951407045 0.1381859928 0.1915331036 + 0.1969527006 0.1397145987 0.1931923032 + 0.1987676024 0.1412506998 0.1948550940 + 0.2005867958 0.1427935958 0.1965250969 + 0.2024096996 0.1443406940 0.1981987059 + 0.2042354047 0.1458964050 0.1998753995 + 0.2060655951 0.1474573016 0.2015592009 + 0.2078990936 0.1490225941 0.2032458931 + 0.2097346038 0.1505970955 0.2049356997 + 0.2115736008 0.1521753073 0.2066316009 + 0.2134155929 0.1537598073 0.2083299011 + 0.2152598053 0.1553504020 0.2100317031 + 0.2171059996 0.1569440067 0.2117380053 + 0.2189532965 0.1585451961 0.2134467959 + 0.2208018005 0.1601499021 0.2151606977 + 0.2226525992 0.1617594957 0.2168776989 + 0.2245036960 0.1633763015 0.2185973972 + 0.2263543010 0.1649962068 0.2203236967 + 0.2282046974 0.1666252017 0.2220526040 + 0.2300550044 0.1682582051 0.2237869948 + 0.2319052964 0.1698971987 0.2255263031 + 0.2337547988 0.1715423018 0.2272689044 + 0.2356023043 0.1731901020 0.2290178984 + 0.2374480069 0.1748462021 0.2307692021 + 0.2392929047 0.1765045971 0.2325260937 + 0.2411359996 0.1781698018 0.2342863977 + 0.2429780960 0.1798388958 0.2360495031 + 0.2448175997 0.1815121025 0.2378188968 + 0.2466558963 0.1831911057 0.2395901978 + 0.2484931946 0.1848724037 0.2413679063 + 0.2503274083 0.1865603030 0.2431481034 + 0.2521604002 0.1882493943 0.2449326068 + 0.2539891005 0.1899435967 0.2467211932 + 0.2558167875 0.1916399002 0.2485122979 + 0.2576422989 0.1933400929 0.2503088117 + 0.2594659925 0.1950432062 0.2521066070 + 0.2612882853 0.1967488974 0.2539105117 + 0.2631081939 0.1984582990 0.2557164133 + 0.2649275064 0.2001695931 0.2575275898 + 0.2667450905 0.2018844932 0.2593415976 + 0.2685621977 0.2036001980 0.2611587942 + 0.2703767121 0.2053194046 0.2629804015 + 0.2721900046 0.2070389986 0.2648043931 + 0.2740012109 0.2087621987 0.2666332126 + 0.2758114934 0.2104858011 0.2684633136 + 0.2776210010 0.2122109979 0.2703008056 + 0.2794296145 0.2139367014 0.2721393108 + 0.2812376916 0.2156637013 0.2739846110 + 0.2830449939 0.2173916996 0.2758311927 + 0.2848519981 0.2191213071 0.2776845992 + 0.2866581082 0.2208511978 0.2795400918 + 0.2884640992 0.2225816995 0.2814018130 + 0.2902691066 0.2243124992 0.2832661867 + 0.2920739949 0.2260437012 0.2851360142 + 0.2938778102 0.2277746946 0.2870089114 + 0.2956816852 0.2295051962 0.2888864875 + 0.2974855900 0.2312353998 0.2907676995 + 0.2992897928 0.2329653054 0.2926534116 + 0.3010956943 0.2346948981 0.2945432067 + 0.3029015958 0.2364241928 0.2964377999 + 0.3047079146 0.2381531000 0.2983360887 + 0.3065148890 0.2398813963 0.3002381921 + 0.3083240986 0.2416097969 0.3021444976 + 0.3101342022 0.2433384061 0.3040550947 + 0.3119468987 0.2450670004 0.3059692979 + 0.3137601912 0.2467954010 0.3078877032 + 0.3155752122 0.2485236973 0.3098101914 + 0.3173910081 0.2502520084 0.3117381930 + 0.3192102015 0.2519801855 0.3136689961 + 0.3210298121 0.2537078857 0.3156045079 + 0.3228524923 0.2554357052 0.3175427020 + 0.3246755004 0.2571632862 0.3194876015 + 0.3265027106 0.2588908970 0.3214339018 + 0.3283298910 0.2606168985 0.3233856857 + 0.3301618993 0.2623426914 0.3253385127 + 0.3319939077 0.2640664876 0.3272993863 + 0.3338311017 0.2657895982 0.3292602003 + 0.3356688917 0.2675099969 0.3312292099 + 0.3375113904 0.2692281902 0.3331983089 + 0.3393552005 0.2709451020 0.3351751864 + 0.3412027955 0.2726595998 0.3371534944 + 0.3430523872 0.2743734121 0.3391371071 + 0.3449051976 0.2760832906 0.3411231935 + 0.3467617035 0.2777931094 0.3431136012 + 0.3486200869 0.2795000076 0.3451083899 + 0.3504830897 0.2812066078 0.3471060097 + 0.3523468077 0.2829105854 0.3491097093 + 0.3542161882 0.2846131921 0.3511143029 + 0.3560855985 0.2863143981 0.3531267047 + 0.3579610884 0.2880134881 0.3551391065 + 0.3598372936 0.2897121012 0.3571586907 + 0.3617183864 0.2914075851 0.3591794968 + 0.3636018932 0.2931031883 0.3612056077 + 0.3654884994 0.2947953939 0.3632349968 + 0.3673790991 0.2964870930 0.3652678132 + 0.3692705929 0.2981764078 0.3673068881 + 0.3711664081 0.2998636067 0.3693464100 + 0.3730623126 0.3015499115 0.3713943064 + 0.3749629855 0.3032326996 0.3734421134 + 0.3768644929 0.3049154878 0.3754970133 + 0.3787690997 0.3065958023 0.3775540888 + 0.3806760013 0.3082754910 0.3796147108 + 0.3825837970 0.3099536002 0.3816798031 + 0.3844941854 0.3116297126 0.3837456107 + 0.3864046037 0.3133055866 0.3858197927 + 0.3883185983 0.3149785995 0.3878938854 + 0.3902328908 0.3166514933 0.3899737000 + 0.3921490908 0.3183214962 0.3920556009 + 0.3940671086 0.3199898005 0.3941405118 + 0.3959853053 0.3216570020 0.3962311149 + 0.3979054987 0.3233199120 0.3983218074 + 0.3998256922 0.3249827921 0.4004194140 + 0.4017480910 0.3266434073 0.4025174975 + 0.4036712050 0.3283031881 0.4046190977 + 0.4055953920 0.3299618959 0.4067240059 + 0.4075216949 0.3316178024 0.4088292122 + 0.4094479978 0.3332735896 0.4109373987 + 0.4113749862 0.3349258900 0.4130455852 + 0.4133020043 0.3365769982 0.4151561856 + 0.4152295887 0.3382270932 0.4172683954 + 0.4171578884 0.3398742974 0.4193809032 + 0.4190863073 0.3415214121 0.4214954972 + 0.4210152924 0.3431650996 0.4236100912 + 0.4229443073 0.3448075950 0.4257256985 + 0.4248732030 0.3464492857 0.4278419018 + 0.4268017113 0.3480867147 0.4299578965 + 0.4287301898 0.3497239947 0.4320721030 + 0.4306586087 0.3513588905 0.4341863096 + 0.4325869977 0.3529917896 0.4362998903 + 0.4345157146 0.3546248078 0.4384129047 + 0.4364447892 0.3562546968 0.4405260086 + 0.4383738935 0.3578845859 0.4426352084 + 0.4403015971 0.3595128059 0.4447444081 + 0.4422290921 0.3611381054 0.4468516111 + 0.4441559017 0.3627632856 0.4489555061 + 0.4460807145 0.3643858135 0.4510594904 + 0.4480054975 0.3660072088 0.4531568885 + 0.4499278963 0.3676283956 0.4552522898 + 0.4518488944 0.3692458868 0.4573468864 + 0.4537698925 0.3708634973 0.4594365954 + 0.4556883872 0.3724792004 0.4615261853 + 0.4576067924 0.3740915060 0.4636127055 + 0.4595240057 0.3757036924 0.4656955898 + 0.4614388943 0.3773143888 0.4677784145 + 0.4633539021 0.3789240122 0.4698548019 + 0.4652644098 0.3805336058 0.4719296098 + 0.4671730101 0.3821412027 0.4740034938 + 0.4690816104 0.3837484121 0.4760693014 + 0.4709844887 0.3853549957 0.4781351089 + 0.4728874862 0.3869574070 0.4801965058 + 0.4747886956 0.3885596991 0.4822503924 + 0.4766854942 0.3901604116 0.4843043983 + 0.4785822928 0.3917576969 0.4863505065 + 0.4804754853 0.3933550119 0.4883921146 + 0.4823656976 0.3949500024 0.4904336035 + 0.4842557907 0.3965430856 0.4924621880 + 0.4861414135 0.3981361091 0.4944886863 + 0.4880256951 0.3997269869 0.4965141118 + 0.4899098873 0.4013170898 0.4985252917 + 0.4917871952 0.4029071927 0.5005366206 + 0.4936642945 0.4044938982 0.5025439262 + 0.4955402911 0.4060800970 0.5045402050 + 0.4974110126 0.4076662064 0.5065364838 + 0.4992815852 0.4092473984 0.5085269213 + 0.5011492968 0.4108285904 0.5105090141 + 0.5030111074 0.4124091864 0.5124911070 + 0.5048729181 0.4139845073 0.5144640207 + 0.5067303777 0.4155597985 0.5164294839 + 0.5085831881 0.4171343148 0.5183951259 + 0.5104359984 0.4187046885 0.5203496218 + 0.5122830272 0.4202750921 0.5222988129 + 0.5141261816 0.4218446016 0.5242480040 + 0.5159693956 0.4234111905 0.5261831284 + 0.5178055763 0.4249776900 0.5281137824 + 0.5196387768 0.4265432060 0.5300444961 + 0.5214719176 0.4281054139 0.5319601893 + 0.5232948065 0.4296675026 0.5338729024 + 0.5251145959 0.4312283099 0.5357854962 + 0.5269343853 0.4327852130 0.5376809239 + 0.5287426114 0.4343419969 0.5395737290 + 0.5305480957 0.4358971119 0.5414664745 + 0.5323536992 0.4374468029 0.5433425903 + 0.5341475010 0.4389964044 0.5452167988 + 0.5359390974 0.4405452907 0.5470908880 + 0.5377306938 0.4420902133 0.5489476919 + 0.5395104885 0.4436351061 0.5508022904 + 0.5412878990 0.4451794922 0.5526568890 + 0.5430654287 0.4467185140 0.5544949174 + 0.5448313951 0.4482575059 0.5563300848 + 0.5465946794 0.4497964978 0.5581651926 + 0.5483580828 0.4513302147 0.5599843860 + 0.5501095057 0.4528639913 0.5617994070 + 0.5518571138 0.4543977976 0.5636144876 + 0.5536047220 0.4559254944 0.5654160976 + 0.5553417206 0.4574523866 0.5672122836 + 0.5570737123 0.4589793086 0.5690084100 + 0.5588057041 0.4605017900 0.5707932711 + 0.5605282187 0.4620226920 0.5725706816 + 0.5622438788 0.4635435939 0.5743482113 + 0.5639594793 0.4650601149 0.5761160254 + 0.5656672716 0.4665732086 0.5778731108 + 0.5673655272 0.4680863023 0.5796301961 + 0.5690636039 0.4695965946 0.5813813806 + 0.5707573295 0.4711019993 0.5831196904 + 0.5724400282 0.4726073146 0.5848580003 + 0.5741227269 0.4741115868 0.5865939260 + 0.5758035779 0.4756088853 0.5883123875 + 0.5774692297 0.4771062136 0.5900310278 + 0.5791348219 0.4786033928 0.5917496085 + 0.5808004737 0.4800952971 0.5934519768 + 0.5824471116 0.4815863073 0.5951527953 + 0.5840917230 0.4830772877 0.5968536139 + 0.5857362747 0.4845638871 0.5985416770 + 0.5873677135 0.4860475063 0.6002234817 + 0.5889924765 0.4875310957 0.6019052863 + 0.5906172991 0.4890125990 0.6035785079 + 0.5922335982 0.4904884994 0.6052387953 + 0.5938374996 0.4919644892 0.6068990827 + 0.5954412818 0.4934403896 0.6085569859 + 0.5970427990 0.4949091077 0.6101952791 + 0.5986260176 0.4963772893 0.6118335128 + 0.6002092957 0.4978454113 0.6134716868 + 0.6017925143 0.4993087053 0.6150943041 + 0.6033605933 0.5007681847 0.6167126298 + 0.6049249768 0.5022277236 0.6183308959 + 0.6064894199 0.5036858916 0.6199414134 + 0.6080433726 0.5051380992 0.6215417981 + 0.6095849872 0.5065904260 0.6231423020 + 0.6111266017 0.5080425739 0.6247416735 + 0.6126660705 0.5094881058 0.6263244748 + 0.6141831875 0.5109314919 0.6279072762 + 0.6157003045 0.5123748183 0.6294900775 + 0.6172174215 0.5138152242 0.6310620904 + 0.6187192798 0.5152488947 0.6326283813 + 0.6202139854 0.5166826248 0.6341947913 + 0.6217088103 0.5181162953 0.6357573271 + 0.6231973767 0.5195432901 0.6373063922 + 0.6246680021 0.5209690928 0.6388555169 + 0.6261385083 0.5223947763 0.6404047012 + 0.6276090741 0.5238174796 0.6419379711 + 0.6290594935 0.5252338052 0.6434664130 + 0.6305047870 0.5266500711 0.6449947953 + 0.6319500804 0.5280663967 0.6465178728 + 0.6333882213 0.5294749737 0.6480270028 + 0.6348105073 0.5308814049 0.6495360136 + 0.6362327933 0.5322877169 0.6510450244 + 0.6376551986 0.5336924195 0.6525406241 + 0.6390563250 0.5350908041 0.6540316939 + 0.6404522061 0.5364891887 0.6555228233 + 0.6418480873 0.5378875732 0.6570094824 + 0.6432371140 0.5392802954 0.6584786177 + 0.6446061730 0.5406693816 0.6599478126 + 0.6459752917 0.5420585871 0.6614168882 + 0.6473444104 0.5434476733 0.6628721952 + 0.6486949921 0.5448269844 0.6643189788 + 0.6500368714 0.5462061763 0.6657658219 + 0.6513789296 0.5475854874 0.6672123075 + 0.6527189016 0.5489618182 0.6686396003 + 0.6540355086 0.5503323078 0.6700670123 + 0.6553521156 0.5517029166 0.6714943051 + 0.6566687822 0.5530735254 0.6729140878 + 0.6579744816 0.5544376969 0.6743212938 + 0.6592665911 0.5557985902 0.6757284999 + 0.6605587006 0.5571594238 0.6771355867 + 0.6618508101 0.5585203171 0.6785268188 + 0.6631215811 0.5598711967 0.6799110770 + 0.6643863916 0.5612214804 0.6812955141 + 0.6656513214 0.5625717044 0.6826797724 + 0.6669138074 0.5639197826 0.6840425730 + 0.6681522131 0.5652583241 0.6854054928 + 0.6693906784 0.5665968060 0.6867682934 + 0.6706290841 0.5679352880 0.6881262064 + 0.6718584895 0.5692687035 0.6894711256 + 0.6730719805 0.5705946088 0.6908161044 + 0.6742855906 0.5719205737 0.6921610236 + 0.6754990816 0.5732464790 0.6934955716 + 0.6766976118 0.5745657086 0.6948205233 + 0.6778864264 0.5758802891 0.6961454153 + 0.6790751815 0.5771949291 0.6974701881 + 0.6802639961 0.5785095096 0.6987801194 + 0.6814342141 0.5798168182 0.7000842094 + 0.6826003194 0.5811215043 0.7013882995 + 0.6837664843 0.5824263096 0.7026923895 + 0.6849324703 0.5837309957 0.7039760947 + 0.6860750914 0.5850257874 0.7052575946 + 0.6872177124 0.5863190889 0.7065389752 + 0.6883602142 0.5876123905 0.7078195214 + 0.6894991994 0.5889056921 0.7090789080 + 0.6906188130 0.5901870728 0.7103384137 + 0.6917384267 0.5914680958 0.7115979195 + 0.6928580999 0.5927491188 0.7128540874 + 0.6939715147 0.5940297246 0.7140920162 + 0.6950684190 0.5952988863 0.7153298855 + 0.6961653829 0.5965679884 0.7165678144 + 0.6972624063 0.5978370905 0.7178003192 + 0.6983522773 0.5991057754 0.7190150023 + 0.6994295716 0.6003659964 0.7202296853 + 0.7005069852 0.6016262770 0.7214444280 + 0.7015843987 0.6028864980 0.7226526737 + 0.7026544809 0.6041461825 0.7238447070 + 0.7037143707 0.6053941250 0.7250366807 + 0.7047743201 0.6066418886 0.7262287140 + 0.7058342099 0.6078897119 0.7274144888 + 0.7068858743 0.6091374755 0.7285851836 + 0.7079268098 0.6103718877 0.7297558784 + 0.7089678049 0.6116061807 0.7309266925 + 0.7100088000 0.6128405929 0.7320916057 + 0.7110424042 0.6140750051 0.7332413197 + 0.7120658159 0.6152967215 0.7343909740 + 0.7130892277 0.6165174842 0.7355408072 + 0.7141125798 0.6177383065 0.7366862297 + 0.7151290178 0.6189591289 0.7378168106 + 0.7161335945 0.6201689839 0.7389473915 + 0.7171381712 0.6213768125 0.7400779128 + 0.7181428075 0.6225845218 0.7412056923 + 0.7191423774 0.6237921715 0.7423154712 + 0.7201297879 0.6249904037 0.7434253097 + 0.7211171985 0.6261842847 0.7445352077 + 0.7221046090 0.6273781061 0.7456446886 + 0.7230893970 0.6285719872 0.7467349768 + 0.7240619063 0.6297590733 0.7478252053 + 0.7250344753 0.6309399009 0.7489154935 + 0.7260071039 0.6321207285 0.7500057817 + 0.7269790769 0.6333013773 0.7510781288 + 0.7279344797 0.6344782710 0.7521474957 + 0.7288898826 0.6356462836 0.7532169223 + 0.7298454046 0.6368141770 0.7542862296 + 0.7308008075 0.6379821897 0.7553424835 + 0.7317430973 0.6391494274 0.7563924789 + 0.7326831222 0.6403048038 0.7574424148 + 0.7336230874 0.6414602995 0.7584924102 + 0.7345631123 0.6426156759 0.7595331073 + 0.7354928851 0.6437711120 0.7605624795 + 0.7364168167 0.6449149251 0.7615919113 + 0.7373406291 0.6460554004 0.7626212835 + 0.7382645011 0.6471958160 0.7636470795 + 0.7391830087 0.6483362913 0.7646576166 + 0.7400926948 0.6494706273 0.7656682134 + 0.7410023808 0.6505978703 0.7666786909 + 0.7419121861 0.6517251134 0.7676892877 + 0.7428205013 0.6528524160 0.7686821818 + 0.7437157035 0.6539782882 0.7696729898 + 0.7446109056 0.6550930738 0.7706639171 + 0.7455059886 0.6562079191 0.7716547251 + 0.7464011908 0.6573228240 0.7726355195 + 0.7472869158 0.6584376097 0.7736086249 + 0.7481697798 0.6595439911 0.7745816708 + 0.7490527034 0.6606470942 0.7755547166 + 0.7499356270 0.6617503166 0.7765241265 + 0.7508131862 0.6628534198 0.7774782777 + 0.7516831756 0.6639522910 0.7784324884 + 0.7525532246 0.6650412083 0.7793866992 + 0.7534232140 0.6661300063 0.7803409100 + 0.7542930841 0.6672189236 0.7812796831 + 0.7551512122 0.6683077216 0.7822145224 + 0.7560092807 0.6693845987 0.7831493020 + 0.7568672895 0.6704590917 0.7840840816 + 0.7577254176 0.6715335846 0.7850121260 + 0.7585778236 0.6726080775 0.7859280109 + 0.7594259977 0.6736781001 0.7868438959 + 0.7602741718 0.6747391224 0.7877597809 + 0.7611225247 0.6758000851 0.7886756063 + 0.7619696856 0.6768611073 0.7895761728 + 0.7628092766 0.6779221892 0.7904745936 + 0.7636489272 0.6789721251 0.7913730145 + 0.7644885182 0.6800191998 0.7922713757 + 0.7653279901 0.6810662746 0.7931637764 + 0.7661625743 0.6821134090 0.7940455079 + 0.7669938803 0.6831572056 0.7949272990 + 0.7678251266 0.6841893792 0.7958090901 + 0.7686563730 0.6852216721 0.7966908813 + 0.7694870234 0.6862540245 0.7975584865 + 0.7703074813 0.6872861981 0.7984229922 + 0.7711278796 0.6883111000 0.7992874980 + 0.7719483972 0.6893314123 0.8001520038 + 0.7727687955 0.6903517246 0.8010128736 + 0.7735849023 0.6913719773 0.8018617034 + 0.7743961811 0.6923922896 0.8027104735 + 0.7752075195 0.6934009790 0.8035593033 + 0.7760187984 0.6944093704 0.8044080734 + 0.7768300772 0.6954177022 0.8052453995 + 0.7776347995 0.6964259744 0.8060749173 + 0.7784383893 0.6974307895 0.8069043756 + 0.7792420983 0.6984261274 0.8077338934 + 0.7800456882 0.6994215250 0.8085634708 + 0.7808480263 0.7004168034 0.8093764186 + 0.7816452980 0.7014120817 0.8101881146 + 0.7824425101 0.7024009228 0.8109998107 + 0.7832397819 0.7033842802 0.8118115067 + 0.7840369940 0.7043675780 0.8126195073 + 0.7848305702 0.7053508759 0.8134146929 + 0.7856206894 0.7063342929 0.8142098188 + 0.7864106894 0.7073084712 0.8150050044 + 0.7872008085 0.7082800269 0.8158001900 + 0.7879908085 0.7092515826 0.8165881038 + 0.7887749076 0.7102231979 0.8173683882 + 0.7895570993 0.7111946940 0.8181486726 + 0.7903392911 0.7121539712 0.8189290166 + 0.7911216021 0.7131130099 0.8197093010 + 0.7919037938 0.7140719891 0.8204782009 + 0.7926781774 0.7150310278 0.8212423921 + 0.7934526205 0.7159885168 0.8220065832 + 0.7942268848 0.7169361115 0.8227707148 + 0.7950013280 0.7178837061 0.8235349059 + 0.7957745194 0.7188313007 0.8242856860 + 0.7965422273 0.7197788954 0.8250346184 + 0.7973099947 0.7207238078 0.8257834911 + 0.7980777025 0.7216603756 0.8265324831 + 0.7988454103 0.7225970030 0.8272811770 + 0.7996107936 0.7235335708 0.8280162215 + 0.8003711104 0.7244701982 0.8287512064 + 0.8011314869 0.7254031897 0.8294863105 + 0.8018918037 0.7263281941 0.8302212954 + 0.8026521206 0.7272531986 0.8309546113 + 0.8034093976 0.7281782031 0.8316739798 + 0.8041626811 0.7291032076 0.8323932886 + 0.8049159050 0.7300242186 0.8331127167 + 0.8056691885 0.7309377193 0.8338320851 + 0.8064224124 0.7318512201 0.8345488906 + 0.8071724772 0.7327647209 0.8352528811 + 0.8079192042 0.7336782217 0.8359568715 + 0.8086658716 0.7345883250 0.8366609216 + 0.8094125986 0.7354918122 0.8373649120 + 0.8101593256 0.7363952994 0.8380662799 + 0.8109018803 0.7372987270 0.8387560248 + 0.8116406798 0.7382022142 0.8394458294 + 0.8123794198 0.7391029000 0.8401355147 + 0.8131181002 0.7399963737 0.8408252001 + 0.8138568997 0.7408899069 0.8415125012 + 0.8145921826 0.7417833805 0.8421863914 + 0.8153241277 0.7426769137 0.8428602815 + 0.8160558939 0.7435685992 0.8435341716 + 0.8167877793 0.7444524765 0.8442081809 + 0.8175196052 0.7453362942 0.8448808789 + 0.8182482719 0.7462201118 0.8455417156 + 0.8189728260 0.7471039295 0.8462024927 + 0.8196973205 0.7479872704 0.8468633294 + 0.8204218745 0.7488632202 0.8475239873 + 0.8211464286 0.7497389913 0.8481848240 + 0.8218685985 0.7506148219 0.8488330841 + 0.8225861192 0.7514907122 0.8494811058 + 0.8233035207 0.7523664832 0.8501291275 + 0.8240209222 0.7532342076 0.8507772088 + 0.8247383833 0.7541006804 0.8514251709 + 0.8254544139 0.7549670935 0.8520622849 + 0.8261637092 0.7558336258 0.8526970744 + 0.8268730044 0.7567000985 0.8533319831 + 0.8275822997 0.7575604916 0.8539667726 + 0.8282917142 0.7584174871 0.8546016216 + 0.8290010095 0.7592746019 0.8552286029 + 0.8297007084 0.7601317167 0.8558509946 + 0.8304002881 0.7609887719 0.8564733267 + 0.8310999274 0.7618423104 0.8570957184 + 0.8317995071 0.7626898289 0.8577179909 + 0.8324990869 0.7635374069 0.8583357930 + 0.8331922293 0.7643849850 0.8589463234 + 0.8338832855 0.7652326226 0.8595567942 + 0.8345744014 0.7660794258 0.8601673245 + 0.8352655172 0.7669159770 0.8607777953 + 0.8359565735 0.7677527070 0.8613868952 + 0.8366435170 0.7685893774 0.8619840145 + 0.8373258710 0.7694259882 0.8625810146 + 0.8380082846 0.7702627182 0.8631780744 + 0.8386908174 0.7710928917 0.8637751937 + 0.8393731713 0.7719206214 0.8643721938 + 0.8400542736 0.7727481723 0.8649600148 + 0.8407285213 0.7735759020 0.8655449748 + 0.8414027095 0.7744035721 0.8661299944 + 0.8420767784 0.7752280831 0.8667150140 + 0.8427510262 0.7760459781 0.8672999740 + 0.8434252143 0.7768638730 0.8678801060 + 0.8440936804 0.7776817083 0.8684527278 + 0.8447608948 0.7784996033 0.8690252900 + 0.8454279900 0.7793174982 0.8695979118 + 0.8460950851 0.7801278830 0.8701705933 + 0.8467621803 0.7809370756 0.8707432151 + 0.8474255204 0.7817463875 0.8713021278 + 0.8480827212 0.7825555801 0.8718606830 + 0.8487399817 0.7833648920 0.8724194169 + 0.8493973017 0.7841700912 0.8729780912 + 0.8500545025 0.7849687934 0.8735368252 + 0.8507118225 0.7857673764 0.8740890026 + 0.8513603806 0.7865660787 0.8746353984 + 0.8520085216 0.7873647213 0.8751817942 + 0.8526566029 0.7881634235 0.8757281899 + 0.8533046842 0.7889544964 0.8762745857 + 0.8539528251 0.7897443175 0.8768208027 + 0.8545969129 0.7905340195 0.8773562908 + 0.8552358747 0.7913237810 0.8778917789 + 0.8558748960 0.7921136022 0.8784273267 + 0.8565139174 0.7929015756 0.8789628148 + 0.8571529984 0.7936850786 0.8794983029 + 0.8577920198 0.7944685817 0.8800281882 + 0.8584234118 0.7952520847 0.8805518150 + 0.8590539098 0.7960355878 0.8810753822 + 0.8596845269 0.7968190908 0.8815988898 + 0.8603150845 0.7975977063 0.8821225166 + 0.8609455824 0.7983735204 0.8826460838 + 0.8615739942 0.7991493940 0.8831595778 + 0.8621975183 0.7999252081 0.8836715221 + 0.8628209829 0.8007010818 0.8841834068 + 0.8634445071 0.8014768958 0.8846952915 + 0.8640679121 0.8022441268 0.8852071762 + 0.8646913767 0.8030110002 0.8857167959 + 0.8653084040 0.8037779927 0.8862178922 + 0.8659222722 0.8045449257 0.8867189884 + 0.8665362000 0.8053117990 0.8872202039 + 0.8671500087 0.8060764074 0.8877213001 + 0.8677638769 0.8068339229 0.8882223964 + 0.8683776855 0.8075914979 0.8887180090 + 0.8689824939 0.8083490133 0.8892086744 + 0.8695871234 0.8091065288 0.8896992803 + 0.8701918125 0.8098639846 0.8901900053 + 0.8707963824 0.8106179833 0.8906806111 + 0.8714010715 0.8113679886 0.8911712766 + 0.8720031977 0.8121181130 0.8916537166 + 0.8725978732 0.8128681183 0.8921337724 + 0.8731927276 0.8136181831 0.8926138878 + 0.8737874031 0.8143681884 0.8930941224 + 0.8743820786 0.8151124716 0.8935741782 + 0.8749768734 0.8158538938 0.8940542936 + 0.8755673170 0.8165953159 0.8945251107 + 0.8761531115 0.8173366785 0.8949958086 + 0.8767387867 0.8180781007 0.8954666257 + 0.8773245811 0.8188195229 0.8959373236 + 0.8779103756 0.8195531964 0.8964080215 + 0.8784961104 0.8202847838 0.8968774080 + 0.8790776134 0.8210164905 0.8973398209 + 0.8796569109 0.8217481971 0.8978022933 + 0.8802360892 0.8224797845 0.8982647061 + 0.8808153272 0.8232114911 0.8987271786 + 0.8813946247 0.8239343166 0.8991895914 + 0.8819738030 0.8246560097 0.8996490836 + 0.8825464845 0.8253775835 0.9001011252 + 0.8831173182 0.8260992765 0.9005531073 + 0.8836882114 0.8268209100 0.9010050893 + 0.8842589855 0.8275426030 0.9014570713 + 0.8848298192 0.8282570243 0.9019091725 + 0.8854007125 0.8289706707 0.9023581147 + 0.8859637976 0.8296844959 0.9028012753 + 0.8865255713 0.8303982019 0.9032443762 + 0.8870874047 0.8311120272 0.9036875963 + 0.8876491785 0.8318256736 0.9041308165 + 0.8882110119 0.8325313926 0.9045739174 + 0.8887729049 0.8332362771 0.9050139785 + 0.8893269897 0.8339412212 0.9054486752 + 0.8898801208 0.8346461058 0.9058833718 + 0.8904331923 0.8353509903 0.9063181281 + 0.8909863234 0.8360558152 0.9067528248 + 0.8915393949 0.8367524147 0.9071875215 + 0.8920925260 0.8374475837 0.9076195955 + 0.8926386237 0.8381426930 0.9080467224 + 0.8931834102 0.8388378024 0.9084736705 + 0.8937283158 0.8395329118 0.9089006782 + 0.8942731023 0.8402280211 0.9093278050 + 0.8948178887 0.8409171104 0.9097548127 + 0.8953627944 0.8416041136 0.9101794958 + 0.8958991170 0.8422911167 0.9105970263 + 0.8964328766 0.8429781199 0.9110143781 + 0.8969668150 0.8436651230 0.9114319086 + 0.8975006938 0.8443520069 0.9118493795 + 0.8980345130 0.8450348973 0.9122667909 + 0.8985683918 0.8457146883 0.9126836061 + 0.8990967870 0.8463944197 0.9130951166 + 0.8996223211 0.8470742106 0.9135065079 + 0.9001477957 0.8477538824 0.9139180183 + 0.9006732702 0.8484336734 0.9143294096 + 0.9011988044 0.8491110206 0.9147409201 + 0.9017242789 0.8497840166 0.9151523113 + 0.9022449851 0.8504568934 0.9155570269 + 0.9027605057 0.8511298895 0.9159610868 + 0.9032760859 0.8518028259 0.9163653255 + 0.9037916064 0.8524758220 0.9167693853 + 0.9043071270 0.8531479836 0.9171736240 + 0.9048225880 0.8538120985 0.9175776839 + 0.9053356051 0.8544760942 0.9179764986 + 0.9058414102 0.8551402092 0.9183728099 + 0.9063470960 0.8558042049 0.9187691808 + 0.9068529010 0.8564683199 0.9191656113 + 0.9073585868 0.8571323156 0.9195619226 + 0.9078643918 0.8577905893 0.9199582934 + 0.9083700776 0.8584470749 0.9203512073 + 0.9088681936 0.8591036201 0.9207388759 + 0.9093660712 0.8597599864 0.9211267233 + 0.9098640084 0.8604164720 0.9215145111 + 0.9103618860 0.8610730171 0.9219022989 + 0.9108597040 0.8617268205 0.9222900271 + 0.9113575816 0.8623763919 0.9226773977 + 0.9118500948 0.8630260229 0.9230594039 + 0.9123396277 0.8636757135 0.9234412909 + 0.9128291011 0.8643252850 0.9238231778 + 0.9133185744 0.8649749160 0.9242051840 + 0.9138082266 0.8656246066 0.9245870709 + 0.9142976999 0.8662685156 0.9249690771 + 0.9147847295 0.8669123054 0.9253469110 + 0.9152647257 0.8675560951 0.9257227182 + 0.9157447815 0.8681998849 0.9260985255 + 0.9162247777 0.8688436747 0.9264742732 + 0.9167048931 0.8694875240 0.9268500805 + 0.9171848893 0.8701276183 0.9272258282 + 0.9176650047 0.8707640171 0.9275999069 + 0.9181361198 0.8714004159 0.9279679060 + 0.9186053276 0.8720368147 0.9283359051 + 0.9190744758 0.8726732135 0.9287039042 + 0.9195436835 0.8733096123 0.9290717840 + 0.9200128913 0.8739460111 0.9294397831 + 0.9204820991 0.8745772839 0.9298077822 + 0.9209483862 0.8752083778 0.9301705956 + 0.9214088917 0.8758394122 0.9305313826 + 0.9218693972 0.8764705062 0.9308922291 + 0.9223300219 0.8771016002 0.9312530160 + 0.9227905273 0.8777326941 0.9316139221 + 0.9232509732 0.8783612251 0.9319747090 + 0.9237114787 0.8789854050 0.9323344231 + 0.9241648912 0.8796095848 0.9326891899 + 0.9246163964 0.8802338243 0.9330438972 + 0.9250679016 0.8808580041 0.9333986044 + 0.9255194068 0.8814823031 0.9337533712 + 0.9259709120 0.8821064830 0.9341080785 + 0.9264224172 0.8827261925 0.9344627857 + 0.9268720150 0.8833442926 0.9348145723 + 0.9273136854 0.8839623928 0.9351639152 + 0.9277552962 0.8845806122 0.9355133176 + 0.9281969070 0.8851987123 0.9358627200 + 0.9286385775 0.8858168125 0.9362121224 + 0.9290801883 0.8864346743 0.9365615249 + 0.9295219183 0.8870465755 0.9369109273 + 0.9299585223 0.8876584768 0.9372549057 + 0.9303908944 0.8882703781 0.9375984073 + 0.9308233261 0.8888823986 0.9379419088 + 0.9312556982 0.8894942999 0.9382852912 + 0.9316880703 0.8901062012 0.9386287928 + 0.9321205020 0.8907166123 0.9389722943 + 0.9325528741 0.8913230896 0.9393147826 + 0.9329783916 0.8919296265 0.9396532178 + 0.9334024787 0.8925361037 0.9399914742 + 0.9338266850 0.8931425214 0.9403297901 + 0.9342507720 0.8937489986 0.9406682253 + 0.9346749187 0.8943554759 0.9410064816 + 0.9350991249 0.8949587941 0.9413447976 + 0.9355226159 0.8955584764 0.9416810870 + 0.9359377027 0.8961580992 0.9420145154 + 0.9363527894 0.8967577815 0.9423478842 + 0.9367679954 0.8973575234 0.9426813126 + 0.9371830821 0.8979572058 0.9430146813 + 0.9375982285 0.8985568881 0.9433481097 + 0.9380133748 0.8991538286 0.9436814785 + 0.9384260774 0.8997489214 0.9440121055 + 0.9388316274 0.9003438950 0.9443405271 + 0.9392371178 0.9009389877 0.9446688890 + 0.9396426082 0.9015340805 0.9449973106 + 0.9400480986 0.9021291733 0.9453257918 + 0.9404535890 0.9027243257 0.9456542134 + 0.9408590794 0.9033153057 0.9459825754 + 0.9412612915 0.9039043784 0.9463074803 + 0.9416580200 0.9044935107 0.9466307759 + 0.9420546293 0.9050825834 0.9469540715 + 0.9424512982 0.9056717157 0.9472774267 + 0.9428480268 0.9062607884 0.9476007223 + 0.9432446957 0.9068499207 0.9479240179 + 0.9436413050 0.9074342251 0.9482473135 + 0.9440346956 0.9080166221 0.9485682845 + 0.9444236755 0.9085990191 0.9488884807 + 0.9448127151 0.9091812968 0.9492086768 + 0.9452018142 0.9097636938 0.9495288730 + 0.9455907941 0.9103459716 0.9498491287 + 0.9459797740 0.9109284282 0.9501693249 + 0.9463688135 0.9115049839 0.9504894018 + 0.9467542171 0.9120786190 0.9508066773 + 0.9471350908 0.9126523137 0.9511228800 + 0.9475159049 0.9132260084 0.9514390826 + 0.9478967786 0.9137995839 0.9517552853 + 0.9482775927 0.9143732786 0.9520714879 + 0.9486585259 0.9149469733 0.9523876905 + 0.9490392804 0.9155157208 0.9527038932 + 0.9494168162 0.9160807729 0.9530172944 + 0.9497889876 0.9166458845 0.9533293247 + 0.9501612782 0.9172109962 0.9536414146 + 0.9505335093 0.9177759886 0.9539533854 + 0.9509056807 0.9183411002 0.9542654753 + 0.9512779117 0.9189062119 0.9545776248 + 0.9516502023 0.9194672704 0.9548895955 + 0.9520196915 0.9200227857 0.9551991820 + 0.9523826241 0.9205783010 0.9555068016 + 0.9527454972 0.9211338162 0.9558144808 + 0.9531083703 0.9216892719 0.9561221004 + 0.9534713030 0.9222447872 0.9564297199 + 0.9538341761 0.9228003025 0.9567372799 + 0.9541971087 0.9233545065 0.9570448995 + 0.9545590878 0.9239031076 0.9573509097 + 0.9549140930 0.9244517088 0.9576539993 + 0.9552692175 0.9250003099 0.9579570889 + 0.9556242228 0.9255489111 0.9582601786 + 0.9559792876 0.9260975122 0.9585633278 + 0.9563344121 0.9266461134 0.9588664174 + 0.9566894174 0.9271947145 0.9591695070 + 0.9570444822 0.9277390838 0.9594715834 + 0.9573910236 0.9282829762 0.9597675800 + 0.9577363729 0.9288269877 0.9600635767 + 0.9580819011 0.9293709993 0.9603595734 + 0.9584273100 0.9299150109 0.9606556296 + 0.9587727785 0.9304590225 0.9609516859 + 0.9591181874 0.9310029745 0.9612476826 + 0.9594637156 0.9315435290 0.9615436792 + 0.9598045945 0.9320815802 0.9618365765 + 0.9601426125 0.9326195717 0.9621289968 + 0.9604806900 0.9331576824 0.9624214172 + 0.9608187079 0.9336956739 0.9627137780 + 0.9611567259 0.9342337847 0.9630060792 + 0.9614946842 0.9347717762 0.9632984996 + 0.9618327022 0.9353088737 0.9635909200 + 0.9621691108 0.9358416200 0.9638820887 + 0.9625008702 0.9363743067 0.9641720057 + 0.9628326893 0.9369069934 0.9644619226 + 0.9631645083 0.9374396801 0.9647517800 + 0.9634963274 0.9379724264 0.9650416970 + 0.9638280272 0.9385051131 0.9653316140 + 0.9641597867 0.9390376806 0.9656215906 + 0.9644916058 0.9395660162 0.9659113288 + 0.9648177028 0.9400926828 0.9661973715 + 0.9651427865 0.9406192899 0.9664834738 + 0.9654678702 0.9411458969 0.9667695761 + 0.9657930136 0.9416726232 0.9670556784 + 0.9661180973 0.9421991706 0.9673417807 + 0.9664431810 0.9427258968 0.9676278830 + 0.9667683244 0.9432511926 0.9679139853 + 0.9670909047 0.9437717795 0.9681978226 + 0.9674093723 0.9442923069 0.9684798121 + 0.9677278996 0.9448127747 0.9687616825 + 0.9680464268 0.9453333020 0.9690436721 + 0.9683648944 0.9458538294 0.9693257213 + 0.9686834216 0.9463744164 0.9696077108 + 0.9690018892 0.9468948841 0.9698897004 + 0.9693204165 0.9474115968 0.9701715708 + 0.9696332216 0.9479261041 0.9704506993 + 0.9699448943 0.9484406114 0.9707298279 + 0.9702566266 0.9489551187 0.9710088968 + 0.9705682993 0.9494696259 0.9712880254 + 0.9708799720 0.9499840140 0.9715670943 + 0.9711917043 0.9504985213 0.9718461037 + 0.9715033770 0.9510130286 0.9721251726 + 0.9718133807 0.9515205026 0.9724026918 + 0.9721180201 0.9520277977 0.9726777077 + 0.9724227190 0.9525352120 0.9729527831 + 0.9727274179 0.9530425072 0.9732279181 + 0.9730321169 0.9535499215 0.9735029936 + 0.9733366966 0.9540572166 0.9737780094 + 0.9736413956 0.9545645118 0.9740530849 + 0.9739460945 0.9550700188 0.9743282199 + 0.9742460847 0.9555702209 0.9745998979 + 0.9745427966 0.9560704231 0.9748703837 + 0.9748393893 0.9565706849 0.9751409292 + 0.9751361012 0.9570708871 0.9754114747 + 0.9754328132 0.9575710893 0.9756820202 + 0.9757294059 0.9580712914 0.9759525061 + 0.9760261178 0.9585716128 0.9762231112 + 0.9763227105 0.9590680003 0.9764935970 + 0.9766126275 0.9595606923 0.9767600298 + 0.9769014120 0.9600533843 0.9770264030 + 0.9771901965 0.9605460167 0.9772928953 + 0.9774789214 0.9610387087 0.9775593281 + 0.9777677059 0.9615312815 0.9778257012 + 0.9780563712 0.9620239735 0.9780920744 + 0.9783452153 0.9625167251 0.9783586264 + 0.9786334038 0.9630044103 0.9786242247 + 0.9789144993 0.9634895921 0.9788866043 + 0.9791955948 0.9639747143 0.9791489840 + 0.9794766903 0.9644598961 0.9794114232 + 0.9797577858 0.9649450779 0.9796738029 + 0.9800388813 0.9654303193 0.9799361825 + 0.9803199768 0.9659153819 0.9801986217 + 0.9806010723 0.9664006233 0.9804610014 + 0.9808804989 0.9668791294 0.9807218909 + 0.9811537862 0.9673554897 0.9809799790 + 0.9814270735 0.9678319097 0.9812381268 + 0.9817004204 0.9683082104 0.9814962745 + 0.9819737077 0.9687845707 0.9817544222 + 0.9822469950 0.9692608714 0.9820125103 + 0.9825202823 0.9697372913 0.9822705984 + 0.9827936292 0.9702135921 0.9825286865 + 0.9830644727 0.9706823230 0.9827851057 + 0.9833294749 0.9711489081 0.9830390811 + 0.9835945964 0.9716154933 0.9832929969 + 0.9838597178 0.9720820785 0.9835469723 + 0.9841247201 0.9725487232 0.9838010073 + 0.9843897820 0.9730151892 0.9840549231 + 0.9846549034 0.9734817743 0.9843088984 + 0.9849199057 0.9739484191 0.9845628142 + 0.9851824045 0.9744058847 0.9848148823 + 0.9854390025 0.9748603106 0.9850642085 + 0.9856956005 0.9753146768 0.9853134751 + 0.9859521985 0.9757689834 0.9855628014 + 0.9862087965 0.9762234092 0.9858121276 + 0.9864653945 0.9766777754 0.9860615134 + 0.9867219925 0.9771322012 0.9863107800 + 0.9869785905 0.9775866270 0.9865601063 + 0.9872329831 0.9780325890 0.9868078232 + 0.9874812961 0.9784740806 0.9870523810 + 0.9877294898 0.9789155126 0.9872971177 + 0.9879776835 0.9793568850 0.9875416756 + 0.9882258773 0.9797983170 0.9877864122 + 0.9884740710 0.9802396894 0.9880310297 + 0.9887223244 0.9806811213 0.9882757068 + 0.9889705777 0.9811224937 0.9885203242 + 0.9892175198 0.9815559983 0.9887641072 + 0.9894570708 0.9819805026 0.9890046716 + 0.9896966815 0.9824051261 0.9892451763 + 0.9899362922 0.9828295708 0.9894858003 + 0.9901759028 0.9832541943 0.9897264242 + 0.9904153943 0.9836786985 0.9899669886 + 0.9906550050 0.9841033220 0.9902076125 + 0.9908946157 0.9845278263 0.9904481769 + 0.9911342263 0.9849482775 0.9906886220 + 0.9913660884 0.9853556752 0.9909231067 + 0.9915975928 0.9857630134 0.9911575913 + 0.9918292165 0.9861702919 0.9913920760 + 0.9920607805 0.9865776896 0.9916266203 + 0.9922922850 0.9869850278 0.9918611050 + 0.9925239086 0.9873923063 0.9920955896 + 0.9927554727 0.9877997041 0.9923300743 + 0.9929869771 0.9882069826 0.9925646186 + 0.9932109714 0.9885931015 0.9927943945 + 0.9934319258 0.9889774919 0.9930227995 + 0.9936528206 0.9893618226 0.9932510853 + 0.9938737154 0.9897462130 0.9934794903 + 0.9940946102 0.9901306033 0.9937078953 + 0.9943153858 0.9905149937 0.9939361811 + 0.9945362806 0.9908993840 0.9941645861 + 0.9947571754 0.9912837744 0.9943928719 + 0.9949743152 0.9916560054 0.9946191907 + 0.9951854944 0.9920184016 0.9948425293 + 0.9953966737 0.9923807979 0.9950658083 + 0.9956079125 0.9927430749 0.9952890873 + 0.9958190918 0.9931054711 0.9955124259 + 0.9960302711 0.9934678078 0.9957357049 + 0.9962415099 0.9938302040 0.9959589839 + 0.9964526892 0.9941924810 0.9961823225 + 0.9966639280 0.9945517778 0.9964054823 + 0.9968671203 0.9948847890 0.9966220856 + 0.9970703125 0.9952176809 0.9968386292 + 0.9972733855 0.9955506921 0.9970551729 + 0.9974765778 0.9958835840 0.9972717166 + 0.9976797104 0.9962165952 0.9974883199 + 0.9978829026 0.9965494871 0.9977048039 + 0.9980860949 0.9968824983 0.9979214072 + 0.9982892275 0.9972153902 0.9981380105 + 0.9984850287 0.9975339174 0.9983490109 + 0.9986743927 0.9978420734 0.9985553026 + 0.9988638163 0.9981504083 0.9987617135 + 0.9990531802 0.9984586835 0.9989681244 + 0.9992424846 0.9987668991 0.9991744757 + 0.9994319081 0.9990751743 0.9993808866 + 0.9996212721 0.9993835092 0.9995871782 + 0.9998105764 0.9996917248 0.9997935891 + 1.0000000000 1.0000000000 1.0000000000 +} diff --git a/rpplugins/color_correction/resources/film_luts_raw/agfa_agfachrome_rsx2_050.spi1d b/rpplugins/color_correction/resources/film_luts_raw/agfa_agfachrome_rsx2_050.spi1d new file mode 100644 index 0000000..42a32ac --- /dev/null +++ b/rpplugins/color_correction/resources/film_luts_raw/agfa_agfachrome_rsx2_050.spi1d @@ -0,0 +1,1030 @@ +Version 1 +From 0.0 1.0 +Length 1024 +Components 3 +{ + 0.0000000000 0.0000000000 0.0000000000 + 0.0010793300 0.0004914269 0.0009736730 + 0.0023187911 0.0010802930 0.0021354880 + 0.0036931380 0.0018072630 0.0034938811 + 0.0052456409 0.0026662690 0.0050411709 + 0.0070081931 0.0036067569 0.0068641612 + 0.0090551702 0.0045785471 0.0090099405 + 0.0114011699 0.0055691102 0.0114547899 + 0.0139678400 0.0065905452 0.0141683398 + 0.0166869499 0.0076627559 0.0171185602 + 0.0195989702 0.0088004395 0.0202584993 + 0.0228006691 0.0100080501 0.0235486198 + 0.0263756197 0.0112880496 0.0269760005 + 0.0303584095 0.0126401298 0.0305433907 + 0.0347159505 0.0140636303 0.0342755318 + 0.0393988304 0.0155540602 0.0381953716 + 0.0443377309 0.0171071608 0.0423245206 + 0.0494562984 0.0187185593 0.0466708317 + 0.0546695217 0.0203871392 0.0512099490 + 0.0599117801 0.0221128706 0.0559065714 + 0.0651446804 0.0238924101 0.0607012585 + 0.0703425035 0.0257253498 0.0655229613 + 0.0754935667 0.0276135001 0.0703299269 + 0.0806027427 0.0295511000 0.0750854388 + 0.0856716335 0.0315340608 0.0797831416 + 0.0907013789 0.0335622691 0.0844218433 + 0.0956865475 0.0356292501 0.0890035927 + 0.1006257012 0.0377341881 0.0935301632 + 0.1055174991 0.0398772992 0.0980233997 + 0.1103760004 0.0420543700 0.1024931967 + 0.1152203977 0.0442650095 0.1069511026 + 0.1200542971 0.0465072691 0.1114012972 + 0.1248871982 0.0487757288 0.1158443019 + 0.1297339052 0.0510716997 0.1202880964 + 0.1346120983 0.0533953197 0.1247389987 + 0.1395314038 0.0557426214 0.1292016953 + 0.1444949955 0.0581145883 0.1336800009 + 0.1495019048 0.0605066083 0.1381773949 + 0.1545559019 0.0629175901 0.1426994056 + 0.1596433967 0.0653483421 0.1472471952 + 0.1647536010 0.0677959695 0.1518259943 + 0.1698786020 0.0702603534 0.1564404070 + 0.1750122011 0.0727384463 0.1610952020 + 0.1801480949 0.0752333701 0.1657952070 + 0.1852789968 0.0777411908 0.1705430001 + 0.1903969944 0.0802624598 0.1753392965 + 0.1954903007 0.0827964321 0.1801753938 + 0.2005587071 0.0853414088 0.1850488037 + 0.2055945992 0.0878966674 0.1899594069 + 0.2105983049 0.0904616788 0.1949048936 + 0.2155726999 0.0930357873 0.1998749971 + 0.2205152959 0.0956183821 0.2048487961 + 0.2254346013 0.0982099175 0.2098221034 + 0.2303334028 0.1008104980 0.2147811055 + 0.2352052927 0.1034198999 0.2197100967 + 0.2400625050 0.1060379967 0.2246035039 + 0.2449066043 0.1086636037 0.2294571996 + 0.2497355938 0.1112938970 0.2342610061 + 0.2545413971 0.1139284000 0.2390076965 + 0.2593365014 0.1165691987 0.2436912954 + 0.2641316950 0.1192142963 0.2483087927 + 0.2689233124 0.1218615994 0.2528623939 + 0.2737050056 0.1245130002 0.2573607862 + 0.2784807086 0.1271678954 0.2618094981 + 0.2832559049 0.1298251003 0.2662059069 + 0.2880277932 0.1324838996 0.2705568075 + 0.2927958071 0.1351446956 0.2748655975 + 0.2975589931 0.1378072053 0.2791439891 + 0.3023168147 0.1404704005 0.2833940089 + 0.3070589006 0.1431359947 0.2876232862 + 0.3117862940 0.1458034068 0.2918379009 + 0.3165079057 0.1484730989 0.2960408032 + 0.3212226927 0.1511427015 0.3002305925 + 0.3259240985 0.1538105011 0.3044033051 + 0.3306060135 0.1564781964 0.3085659146 + 0.3352772892 0.1591459066 0.3127256930 + 0.3399353027 0.1618131995 0.3168801963 + 0.3445748985 0.1644778997 0.3210279047 + 0.3491897881 0.1671431065 0.3251653910 + 0.3537842929 0.1698081940 0.3292970955 + 0.3583635986 0.1724765003 0.3334251940 + 0.3629280031 0.1751464009 0.3375486135 + 0.3674629927 0.1778157055 0.3416658044 + 0.3719677031 0.1804865003 0.3457753956 + 0.3764384985 0.1831578016 0.3498772979 + 0.3808833957 0.1858278960 0.3539676964 + 0.3853051066 0.1885012984 0.3580411971 + 0.3896934986 0.1911745965 0.3620963991 + 0.3940488100 0.1938498020 0.3661319017 + 0.3983697891 0.1965274960 0.3701558113 + 0.4026510119 0.1992076039 0.3741641045 + 0.4068988860 0.2018887997 0.3781496882 + 0.4111185968 0.2045747042 0.3821138144 + 0.4153113961 0.2072620988 0.3860580921 + 0.4194692075 0.2099498957 0.3899829984 + 0.4235900044 0.2126414031 0.3938888013 + 0.4276776910 0.2153348029 0.3977788091 + 0.4317341149 0.2180286050 0.4016534090 + 0.4357563853 0.2207237929 0.4055137932 + 0.4397394061 0.2234221995 0.4093612134 + 0.4436829090 0.2261236012 0.4131959975 + 0.4475947022 0.2288268059 0.4170176983 + 0.4514735937 0.2315322012 0.4208177924 + 0.4553222954 0.2342423052 0.4245958030 + 0.4591388106 0.2369553000 0.4283536971 + 0.4629189968 0.2396683991 0.4320934117 + 0.4666629136 0.2423831969 0.4358170927 + 0.4703747034 0.2451013029 0.4395225048 + 0.4740515947 0.2478200942 0.4432024956 + 0.4776928127 0.2505406141 0.4468582869 + 0.4813019931 0.2532635927 0.4504924119 + 0.4848793149 0.2559860945 0.4541029930 + 0.4884204865 0.2587074935 0.4576902092 + 0.4919295907 0.2614302039 0.4612514973 + 0.4954057038 0.2641544044 0.4647876918 + 0.4988467097 0.2668786943 0.4682984054 + 0.5022568703 0.2696047127 0.4717861116 + 0.5056318045 0.2723301053 0.4752514064 + 0.5089687109 0.2750515938 0.4786919951 + 0.5122699738 0.2777692974 0.4821071923 + 0.5155354738 0.2804855108 0.4855000973 + 0.5187671781 0.2832008898 0.4888701141 + 0.5219681263 0.2859140933 0.4922114909 + 0.5251352191 0.2886242867 0.4955233037 + 0.5282660127 0.2913315892 0.4988074899 + 0.5313646197 0.2940349877 0.5020601749 + 0.5344318151 0.2967323065 0.5052834749 + 0.5374667048 0.2994225919 0.5084816217 + 0.5404701233 0.3021079004 0.5116459131 + 0.5434368849 0.3047888875 0.5147755146 + 0.5463718176 0.3074640036 0.5178748965 + 0.5492841005 0.3101322055 0.5209411979 + 0.5521711707 0.3127948046 0.5239753127 + 0.5550354123 0.3154520094 0.5269787908 + 0.5578734875 0.3181014955 0.5299521089 + 0.5606822968 0.3207401037 0.5328952074 + 0.5634636283 0.3233641088 0.5358104110 + 0.5662226081 0.3259783983 0.5386914015 + 0.5689582229 0.3285818994 0.5415412784 + 0.5716739893 0.3311730921 0.5443618894 + 0.5743725896 0.3337512016 0.5471563935 + 0.5770525932 0.3363159001 0.5499269962 + 0.5797128081 0.3388671875 0.5526747704 + 0.5823537707 0.3414067030 0.5553982854 + 0.5849738717 0.3439315856 0.5580946207 + 0.5875731707 0.3464401960 0.5607615709 + 0.5901582241 0.3489316106 0.5634018183 + 0.5927311778 0.3514032960 0.5660176277 + 0.5952929258 0.3538616896 0.5686088800 + 0.5978369713 0.3563053906 0.5711727738 + 0.6003630161 0.3587335050 0.5737162828 + 0.6028745770 0.3611412942 0.5762403011 + 0.6053730249 0.3635332882 0.5787448287 + 0.6078591943 0.3659127057 0.5812224150 + 0.6103302240 0.3682799935 0.5836719275 + 0.6127892733 0.3706313074 0.5861017108 + 0.6152378917 0.3729673922 0.5885127783 + 0.6176773906 0.3752928078 0.5909010768 + 0.6201043725 0.3776082993 0.5932654738 + 0.6225174069 0.3799093068 0.5956128240 + 0.6249200106 0.3821944892 0.5979433060 + 0.6273151040 0.3844664991 0.6002511978 + 0.6296957135 0.3867239058 0.6025369167 + 0.6320651174 0.3889622986 0.6048055887 + 0.6344231963 0.3911905885 0.6070576906 + 0.6367667913 0.3934093118 0.6092873216 + 0.6390994787 0.3956130147 0.6115016937 + 0.6414197087 0.3978062868 0.6137034297 + 0.6437255740 0.3999901116 0.6158903241 + 0.6460139155 0.4021590948 0.6180559993 + 0.6482884288 0.4043118060 0.6202107072 + 0.6505498290 0.4064539969 0.6223551035 + 0.6527922750 0.4085829854 0.6244797111 + 0.6550189853 0.4106990099 0.6265919805 + 0.6572331190 0.4128079116 0.6286922097 + 0.6594275832 0.4149076939 0.6307719946 + 0.6616020799 0.4169962108 0.6328415275 + 0.6637635827 0.4190776944 0.6349012256 + 0.6659076214 0.4211486876 0.6369373202 + 0.6680328250 0.4232074916 0.6389623880 + 0.6701455712 0.4252586961 0.6409782171 + 0.6722385287 0.4272964001 0.6429752111 + 0.6743144989 0.4293248057 0.6449599862 + 0.6763777733 0.4313467145 0.6469345093 + 0.6784113050 0.4333539903 0.6488881707 + 0.6804267764 0.4353561103 0.6508327723 + 0.6824293137 0.4373523891 0.6527665854 + 0.6844047904 0.4393377006 0.6546779871 + 0.6863657236 0.4413183928 0.6565799713 + 0.6883090734 0.4432905018 0.6584674120 + 0.6902278066 0.4452567101 0.6603385806 + 0.6921337247 0.4472194016 0.6622003913 + 0.6940143704 0.4491713941 0.6640378833 + 0.6958734989 0.4511190057 0.6658635736 + 0.6977202296 0.4530585110 0.6676772237 + 0.6995369792 0.4549886882 0.6694694161 + 0.7013437748 0.4569143951 0.6712527871 + 0.7031323910 0.4588277936 0.6730164886 + 0.7048978806 0.4607372880 0.6747667193 + 0.7066525817 0.4626379907 0.6765061021 + 0.7083770037 0.4645319879 0.6782280803 + 0.7100898027 0.4664215147 0.6799430251 + 0.7117800713 0.4683004022 0.6816384196 + 0.7134491205 0.4701760113 0.6833207011 + 0.7151061296 0.4720404148 0.6849896908 + 0.7167317271 0.4739001989 0.6866384149 + 0.7183483839 0.4757528007 0.6882799864 + 0.7199388742 0.4775973856 0.6898952723 + 0.7215155959 0.4794372022 0.6915025711 + 0.7230750918 0.4812653959 0.6930922270 + 0.7246130705 0.4830907881 0.6946684122 + 0.7261415124 0.4849025011 0.6962333918 + 0.7276425958 0.4867109954 0.6977772713 + 0.7291371226 0.4885095954 0.6993148923 + 0.7306033969 0.4903028011 0.7008234859 + 0.7320588231 0.4920882881 0.7023267150 + 0.7334914207 0.4938659966 0.7038077712 + 0.7349091768 0.4956378937 0.7052788138 + 0.7363126278 0.4973995984 0.7067326903 + 0.7376976013 0.4991573095 0.7081738710 + 0.7390735745 0.5009049773 0.7096043229 + 0.7404264212 0.5026509166 0.7110185027 + 0.7417743206 0.5043882728 0.7124254107 + 0.7430984974 0.5061246753 0.7138100863 + 0.7444195151 0.5078502297 0.7151901722 + 0.7457147241 0.5095742941 0.7165504098 + 0.7470049858 0.5112900138 0.7179082036 + 0.7482746840 0.5130041242 0.7192432284 + 0.7495390773 0.5147119164 0.7205743194 + 0.7507901192 0.5164154172 0.7218819857 + 0.7520323992 0.5181065202 0.7231845856 + 0.7532587051 0.5197932720 0.7244688272 + 0.7544769049 0.5214695930 0.7257465124 + 0.7556836009 0.5231422782 0.7270067930 + 0.7568811178 0.5248072147 0.7282580733 + 0.7580674291 0.5264676809 0.7294902802 + 0.7592449188 0.5281187296 0.7307134867 + 0.7604126930 0.5297662020 0.7319198847 + 0.7615684271 0.5314055085 0.7331190705 + 0.7627115250 0.5330424905 0.7343053818 + 0.7638474703 0.5346732140 0.7354832292 + 0.7649760246 0.5363014936 0.7366452217 + 0.7660958171 0.5379210711 0.7378004193 + 0.7672052979 0.5395383835 0.7389414907 + 0.7683075070 0.5411432981 0.7400768995 + 0.7693994045 0.5427473187 0.7411974072 + 0.7704840899 0.5443403125 0.7423136234 + 0.7715560198 0.5459334254 0.7434149981 + 0.7726234198 0.5475159883 0.7445133924 + 0.7736793756 0.5490983725 0.7455939054 + 0.7747321129 0.5506709218 0.7466735840 + 0.7757707238 0.5522418022 0.7477390766 + 0.7768080235 0.5538048148 0.7488046288 + 0.7778319120 0.5553649068 0.7498521805 + 0.7788556814 0.5569189787 0.7508987784 + 0.7798684835 0.5584686995 0.7519304156 + 0.7808806896 0.5600128770 0.7529587746 + 0.7818831801 0.5615490079 0.7539767027 + 0.7828834057 0.5630828738 0.7549896240 + 0.7838739753 0.5646088123 0.7559961081 + 0.7848594189 0.5661345124 0.7569965720 + 0.7858390212 0.5676507950 0.7579910159 + 0.7868121266 0.5691671968 0.7589733005 + 0.7877818942 0.5706741810 0.7599534988 + 0.7887430787 0.5721786022 0.7609199286 + 0.7897034883 0.5736780763 0.7618862987 + 0.7906509042 0.5751733780 0.7628408074 + 0.7915983796 0.5766646862 0.7637941837 + 0.7925338149 0.5781458020 0.7647387981 + 0.7934665084 0.5796269774 0.7656794190 + 0.7943943739 0.5810970068 0.7666130066 + 0.7953184843 0.5825669765 0.7675375938 + 0.7962388992 0.5840300918 0.7684599161 + 0.7971503735 0.5854902267 0.7693706155 + 0.7980619073 0.5869455934 0.7702813148 + 0.7989597917 0.5883936286 0.7711808085 + 0.7998577952 0.5898411870 0.7720786929 + 0.8007482290 0.5912801027 0.7729684114 + 0.8016350865 0.5927190185 0.7738516927 + 0.8025193214 0.5941507220 0.7747313976 + 0.8033987880 0.5955792069 0.7755991817 + 0.8042780757 0.5970045924 0.7764670849 + 0.8051458001 0.5984227061 0.7773265839 + 0.8060135841 0.5998408794 0.7781848907 + 0.8068729043 0.6012483835 0.7790384293 + 0.8077275753 0.6026548743 0.7798873782 + 0.8085805774 0.6040555239 0.7807345986 + 0.8094288707 0.6054502726 0.7815697193 + 0.8102772236 0.6068443060 0.7824047208 + 0.8111171126 0.6082274914 0.7832310796 + 0.8119553924 0.6096106768 0.7840542197 + 0.8127890825 0.6109865904 0.7848746181 + 0.8136162758 0.6123577952 0.7856888771 + 0.8144435287 0.6137276292 0.7865030766 + 0.8152586222 0.6150876284 0.7873069048 + 0.8160732985 0.6164476275 0.7881088853 + 0.8168833852 0.6178010106 0.7889056802 + 0.8176890016 0.6191505790 0.7896941900 + 0.8184943795 0.6204990745 0.7904825807 + 0.8192909956 0.6218383908 0.7912638187 + 0.8200876117 0.6231778264 0.7920442224 + 0.8208791018 0.6245108843 0.7928205132 + 0.8216655254 0.6258392930 0.7935903072 + 0.8224520087 0.6271675229 0.7943601012 + 0.8232241869 0.6284862757 0.7951198816 + 0.8239961267 0.6298050880 0.7958778739 + 0.8247646093 0.6311200261 0.7966322899 + 0.8255286217 0.6324295998 0.7973783016 + 0.8262926936 0.6337392926 0.7981241941 + 0.8270503879 0.6350398064 0.7988656759 + 0.8278068900 0.6363382936 0.7996054888 + 0.8285604119 0.6376342773 0.8003445864 + 0.8293051124 0.6389204264 0.8010787964 + 0.8300496936 0.6402065158 0.8018130064 + 0.8307862282 0.6414867043 0.8025422096 + 0.8315181732 0.6427623034 0.8032668829 + 0.8322501779 0.6440379024 0.8039916158 + 0.8329762220 0.6453067064 0.8047072291 + 0.8337022066 0.6465746760 0.8054215908 + 0.8344250917 0.6478404999 0.8061349988 + 0.8351423144 0.6490973830 0.8068444729 + 0.8358594775 0.6503543854 0.8075541258 + 0.8365702033 0.6516067982 0.8082594872 + 0.8372778296 0.6528545022 0.8089613914 + 0.8379853964 0.6541022062 0.8096632957 + 0.8386828899 0.6553429961 0.8103563190 + 0.8393800855 0.6565815210 0.8110477924 + 0.8400756717 0.6578201056 0.8117380738 + 0.8407658935 0.6590459943 0.8124209046 + 0.8414561749 0.6602718234 0.8131036758 + 0.8421434164 0.6614953279 0.8137840033 + 0.8428274989 0.6627100110 0.8144602180 + 0.8435115814 0.6639245749 0.8151363730 + 0.8441904783 0.6651350260 0.8158075213 + 0.8448675871 0.6663392186 0.8164752126 + 0.8455445766 0.6675434113 0.8171430230 + 0.8462108970 0.6687409282 0.8178033233 + 0.8468765020 0.6699336171 0.8184620142 + 0.8475412130 0.6711263061 0.8191205859 + 0.8481993079 0.6723105907 0.8197690845 + 0.8488574028 0.6734917164 0.8204175830 + 0.8495146036 0.6746727824 0.8210650086 + 0.8501691818 0.6758468151 0.8217062950 + 0.8508237004 0.6770195961 0.8223475218 + 0.8514751196 0.6781923771 0.8229870796 + 0.8521217108 0.6793540716 0.8236224055 + 0.8527683020 0.6805154085 0.8242577910 + 0.8534088731 0.6816763878 0.8248903751 + 0.8540437818 0.6828271747 0.8255187869 + 0.8546788096 0.6839780807 0.8261471987 + 0.8553087115 0.6851279736 0.8267704844 + 0.8559352756 0.6862679720 0.8273885846 + 0.8565620184 0.6874079108 0.8280068040 + 0.8571853042 0.6885467172 0.8286191225 + 0.8578070998 0.6896767020 0.8292267919 + 0.8584287763 0.6908066869 0.8298345208 + 0.8590450287 0.6919351220 0.8304392099 + 0.8596587777 0.6930524111 0.8310418725 + 0.8602727056 0.6941698194 0.8316444755 + 0.8608806729 0.6952862144 0.8322427273 + 0.8614864945 0.6963943839 0.8328379989 + 0.8620923162 0.6975026727 0.8334332705 + 0.8626918793 0.6986103058 0.8340228796 + 0.8632891774 0.6997066736 0.8346086740 + 0.8638864756 0.7008031011 0.8351945281 + 0.8644778132 0.7018995285 0.8357760906 + 0.8650662899 0.7029855251 0.8363544941 + 0.8656548858 0.7040715218 0.8369328976 + 0.8662387133 0.7051573992 0.8375086188 + 0.8668196201 0.7062337995 0.8380817771 + 0.8674005866 0.7073091269 0.8386549950 + 0.8679792285 0.7083843946 0.8392254114 + 0.8685559034 0.7094525099 0.8397920728 + 0.8691325784 0.7105184197 0.8403587937 + 0.8697057962 0.7115843296 0.8409234285 + 0.8702744246 0.7126430273 0.8414832950 + 0.8708429933 0.7136971951 0.8420432806 + 0.8714082241 0.7147514820 0.8426018953 + 0.8719649911 0.7158018947 0.8431546092 + 0.8725218773 0.7168475986 0.8437072039 + 0.8730772734 0.7178933024 0.8442596197 + 0.8736236095 0.7189357281 0.8448042274 + 0.8741698265 0.7199681997 0.8453487754 + 0.8747161031 0.7210006714 0.8458935022 + 0.8752585053 0.7220329046 0.8464329243 + 0.8758007288 0.7230560184 0.8469712138 + 0.8763428926 0.7240790725 0.8475095034 + 0.8768798113 0.7251021862 0.8480458260 + 0.8774148822 0.7261161804 0.8485807776 + 0.8779498935 0.7271276116 0.8491157293 + 0.8784800172 0.7281389832 0.8496479988 + 0.8790047765 0.7291454077 0.8501759768 + 0.8795297146 0.7301467061 0.8507040143 + 0.8800523281 0.7311478853 0.8512308002 + 0.8805670738 0.7321473956 0.8517482877 + 0.8810818791 0.7331386805 0.8522657752 + 0.8815966845 0.7341300249 0.8527832031 + 0.8821054101 0.7351213098 0.8532953858 + 0.8826135993 0.7361055017 0.8538061976 + 0.8831217885 0.7370883822 0.8543171287 + 0.8836262226 0.7380713820 0.8548266292 + 0.8841279745 0.7390490174 0.8553346992 + 0.8846297860 0.7400209904 0.8558428288 + 0.8851295710 0.7409930229 0.8563500047 + 0.8856232762 0.7419641018 0.8568516970 + 0.8861169815 0.7429267764 0.8573533893 + 0.8866106868 0.7438895106 0.8578552008 + 0.8870999217 0.7448523045 0.8583500981 + 0.8875883818 0.7458072901 0.8588429093 + 0.8880769014 0.7467586994 0.8593356013 + 0.8885614872 0.7477099895 0.8598263264 + 0.8890416026 0.7486596704 0.8603129983 + 0.8895217776 0.7496036887 0.8607997894 + 0.8900015950 0.7505478263 0.8612865806 + 0.8904702067 0.7514917850 0.8617706895 + 0.8909388185 0.7524288297 0.8622545004 + 0.8914073706 0.7533634901 0.8627383709 + 0.8918703794 0.7542982101 0.8632197976 + 0.8923289776 0.7552309036 0.8636981845 + 0.8927875757 0.7561575770 0.8641765714 + 0.8932459950 0.7570843101 0.8646550179 + 0.8937010765 0.7580109239 0.8651264906 + 0.8941562176 0.7589309812 0.8655977249 + 0.8946112990 0.7598484159 0.8660690188 + 0.8950629830 0.7607657909 0.8665379882 + 0.8955119848 0.7616819739 0.8670043945 + 0.8959609866 0.7625917792 0.8674706817 + 0.8964099884 0.7635017037 0.8679370880 + 0.8968498707 0.7644115090 0.8683987260 + 0.8972896934 0.7653169036 0.8688598871 + 0.8977295756 0.7662187219 0.8693211079 + 0.8981648088 0.7671204805 0.8697806001 + 0.8985937238 0.7680222988 0.8702368736 + 0.8990225792 0.7689167857 0.8706930876 + 0.8994513750 0.7698106766 0.8711493015 + 0.8998739719 0.7707046270 0.8716015220 + 0.9002950788 0.7715961933 0.8720520139 + 0.9007161260 0.7724819183 0.8725025058 + 0.9011359811 0.7733675241 0.8729526997 + 0.9015498161 0.7742530704 0.8733996153 + 0.9019635916 0.7751324177 0.8738464713 + 0.9023774266 0.7760072947 0.8742935061 + 0.9027864933 0.7768821716 0.8747376800 + 0.9031909108 0.7777572274 0.8751780987 + 0.9035953283 0.7786241174 0.8756185174 + 0.9039996862 0.7794898748 0.8760588169 + 0.9043973088 0.7803558111 0.8764961958 + 0.9047932029 0.7812201977 0.8769323230 + 0.9051890969 0.7820760012 0.8773683906 + 0.9055845737 0.7829318047 0.8778045177 + 0.9059756994 0.7837876081 0.8782365918 + 0.9063668251 0.7846404910 0.8786684871 + 0.9067577720 0.7854884267 0.8791003823 + 0.9071465731 0.7863361835 0.8795318007 + 0.9075301886 0.7871841192 0.8799616098 + 0.9079139233 0.7880274057 0.8803914189 + 0.9082974792 0.7888671756 0.8808211088 + 0.9086759090 0.7897068858 0.8812487721 + 0.9090495110 0.7905467153 0.8816735744 + 0.9094231129 0.7913808823 0.8820983171 + 0.9097967148 0.7922129035 0.8825231194 + 0.9101623893 0.7930449247 0.8829430938 + 0.9105246067 0.7938770056 0.8833600283 + 0.9108868241 0.7947024107 0.8837769032 + 0.9112489223 0.7955265045 0.8841937780 + 0.9116070271 0.7963507175 0.8846076131 + 0.9119641185 0.7971748710 0.8850203753 + 0.9123213291 0.7979897261 0.8854331970 + 0.9126784801 0.7988039255 0.8858460188 + 0.9130293131 0.7996181846 0.8862584829 + 0.9133797288 0.8004323244 0.8866708279 + 0.9137300849 0.8012365103 0.8870831728 + 0.9140803218 0.8020406961 0.8874955773 + 0.9144240022 0.8028448224 0.8879050016 + 0.9147678018 0.8036485910 0.8883141279 + 0.9151114821 0.8044434786 0.8887231946 + 0.9154546857 0.8052384853 0.8891323209 + 0.9157909155 0.8060333729 0.8895354867 + 0.9161270857 0.8068280220 0.8899384737 + 0.9164631963 0.8076159954 0.8903415799 + 0.9167991281 0.8084039092 0.8907446265 + 0.9171310067 0.8091918826 0.8911405206 + 0.9174628854 0.8099797964 0.8915362954 + 0.9177948236 0.8107593060 0.8919320703 + 0.9181262851 0.8115388155 0.8923279047 + 0.9184517860 0.8123183250 0.8927236199 + 0.9187772870 0.8130977750 0.8931193948 + 0.9191027880 0.8138713241 0.8935151100 + 0.9194281101 0.8146445751 0.8939108253 + 0.9197450280 0.8154178262 0.8943054080 + 0.9200618863 0.8161910176 0.8946998715 + 0.9203788042 0.8169561028 0.8950942755 + 0.9206957221 0.8177195787 0.8954887986 + 0.9210032225 0.8184831738 0.8958798051 + 0.9213100076 0.8192468286 0.8962702751 + 0.9216167927 0.8200044036 0.8966606855 + 0.9219235778 0.8207594752 0.8970510960 + 0.9222257137 0.8215147257 0.8974366188 + 0.9225267172 0.8222697973 0.8978202939 + 0.9228277206 0.8230199218 0.8982040286 + 0.9231287837 0.8237658143 0.8985875845 + 0.9234266877 0.8245115876 0.8989667892 + 0.9237229824 0.8252574205 0.8993425965 + 0.9240192771 0.8260008097 0.8997182846 + 0.9243155718 0.8267393112 0.9000940919 + 0.9246088266 0.8274778128 0.9004687071 + 0.9248985052 0.8282163143 0.9008412957 + 0.9251881242 0.8289538026 0.9012138844 + 0.9254776835 0.8296815753 0.9015864730 + 0.9257658720 0.8304092884 0.9019587040 + 0.9260491729 0.8311371207 0.9023287296 + 0.9263325930 0.8318648934 0.9026985765 + 0.9266158938 0.8325855732 0.9030684829 + 0.9268993139 0.8333047032 0.9034383893 + 0.9271755219 0.8340237737 0.9038041234 + 0.9274516106 0.8347429037 0.9041693807 + 0.9277275801 0.8354570270 0.9045346975 + 0.9280037284 0.8361662030 0.9048998952 + 0.9282758236 0.8368754983 0.9052616954 + 0.9285460711 0.8375847936 0.9056211710 + 0.9288163185 0.8382927775 0.9059805870 + 0.9290866256 0.8389946818 0.9063401222 + 0.9293550253 0.8396965861 0.9066985846 + 0.9296200871 0.8403984904 0.9070546031 + 0.9298850894 0.8411002755 0.9074106216 + 0.9301502109 0.8417940140 0.9077665210 + 0.9304152131 0.8424854279 0.9081224799 + 0.9306733012 0.8431769013 0.9084752798 + 0.9309315085 0.8438683152 0.9088277817 + 0.9311895967 0.8445565104 0.9091802239 + 0.9314476848 0.8452389836 0.9095327258 + 0.9317021966 0.8459215164 0.9098836184 + 0.9319543242 0.8466041088 0.9102330208 + 0.9322063923 0.8472865820 0.9105823040 + 0.9324585199 0.8479604125 0.9109317064 + 0.9327095151 0.8486334085 0.9112808108 + 0.9329549074 0.8493062854 0.9116259813 + 0.9332001805 0.8499792814 0.9119712710 + 0.9334455132 0.8506484032 0.9123165011 + 0.9336907864 0.8513122201 0.9126616716 + 0.9339326024 0.8519759774 0.9130048156 + 0.9341726899 0.8526396751 0.9133464098 + 0.9344127178 0.8533034921 0.9136881232 + 0.9346528053 0.8539575934 0.9140297771 + 0.9348924756 0.8546106219 0.9143710732 + 0.9351304173 0.8552635908 0.9147090912 + 0.9353682995 0.8559166193 0.9150471091 + 0.9356061816 0.8565670252 0.9153851271 + 0.9358440042 0.8572118878 0.9157230854 + 0.9360798001 0.8578568101 0.9160578847 + 0.9363142848 0.8585017920 0.9163900018 + 0.9365487099 0.8591467142 0.9167221189 + 0.9367831945 0.8597838283 0.9170541763 + 0.9370173812 0.8604179025 0.9173862934 + 0.9372467995 0.8610520959 0.9177129269 + 0.9374760985 0.8616862893 0.9180392027 + 0.9377055168 0.8623197079 0.9183654785 + 0.9379348159 0.8629447818 0.9186918139 + 0.9381616116 0.8635699153 0.9190167785 + 0.9383847117 0.8641949892 0.9193391204 + 0.9386078119 0.8648201227 0.9196614027 + 0.9388309717 0.8654413819 0.9199838042 + 0.9390540719 0.8660572171 0.9203060865 + 0.9392737150 0.8666728735 0.9206275940 + 0.9394921064 0.8672885895 0.9209488034 + 0.9397104979 0.8679043055 0.9212698936 + 0.9399290085 0.8685140014 0.9215909839 + 0.9401472211 0.8691210151 0.9219120741 + 0.9403619170 0.8697279096 0.9222300053 + 0.9405764937 0.8703348041 0.9225476980 + 0.9407910705 0.8709418178 0.9228653908 + 0.9410057068 0.8715392947 0.9231832027 + 0.9412195086 0.8721361756 0.9234995842 + 0.9414315224 0.8727331161 0.9238117933 + 0.9416434169 0.8733298779 0.9241240025 + 0.9418553114 0.8739258051 0.9244362116 + 0.9420672059 0.8745154738 0.9247483015 + 0.9422771931 0.8751052022 0.9250574112 + 0.9424853921 0.8756948113 0.9253627062 + 0.9426935911 0.8762844801 0.9256678820 + 0.9429017901 0.8768712878 0.9259731174 + 0.9431099892 0.8774514198 0.9262782931 + 0.9433146119 0.8780314922 0.9265810847 + 0.9435176253 0.8786115050 0.9268823862 + 0.9437206984 0.8791915774 0.9271836877 + 0.9439237118 0.8797677755 0.9274849892 + 0.9441267252 0.8803384900 0.9277862906 + 0.9443246126 0.8809092045 0.9280866981 + 0.9445216060 0.8814799190 0.9283868074 + 0.9447184801 0.8820505738 0.9286869168 + 0.9449154735 0.8826171756 0.9289870262 + 0.9451124072 0.8831797242 0.9292870760 + 0.9453071952 0.8837422132 0.9295849204 + 0.9455018044 0.8843047023 0.9298822880 + 0.9456964731 0.8848671913 0.9301797152 + 0.9458910823 0.8854259849 0.9304770827 + 0.9460856915 0.8859816194 0.9307745099 + 0.9462794065 0.8865371943 0.9310675263 + 0.9464730024 0.8870928288 0.9313601851 + 0.9466665983 0.8876484036 0.9316527843 + 0.9468601942 0.8881986141 0.9319455028 + 0.9470537901 0.8887439966 0.9322381020 + 0.9472450018 0.8892894983 0.9325249791 + 0.9474362731 0.8898350000 0.9328114986 + 0.9476274848 0.8903805017 0.9330980182 + 0.9478188157 0.8909212947 0.9333845973 + 0.9480100870 0.8914574981 0.9336711168 + 0.9481977224 0.8919935822 0.9339528084 + 0.9483852983 0.8925297856 0.9342340231 + 0.9485728741 0.8930659294 0.9345152974 + 0.9487605095 0.8935987949 0.9347965121 + 0.9489480853 0.8941270709 0.9350777864 + 0.9491310716 0.8946554065 0.9353563786 + 0.9493138194 0.8951836824 0.9356346726 + 0.9494963884 0.8957120180 0.9359129071 + 0.9496790767 0.8962380290 0.9361910820 + 0.9498617053 0.8967580795 0.9364693165 + 0.9500396848 0.8972783089 0.9367458224 + 0.9502165914 0.8977984190 0.9370216727 + 0.9503934979 0.8983185291 0.9372975230 + 0.9505705237 0.8988376260 0.9375733733 + 0.9507473707 0.8993477821 0.9378492832 + 0.9509227872 0.8998581171 0.9381229877 + 0.9510974288 0.9003683925 0.9383950830 + 0.9512720704 0.9008787274 0.9386672974 + 0.9514467120 0.9013890028 0.9389393926 + 0.9516214132 0.9018915892 0.9392116070 + 0.9517948031 0.9023934007 0.9394819140 + 0.9519668818 0.9028952718 0.9397495985 + 0.9521389008 0.9033970833 0.9400172234 + 0.9523109794 0.9038988948 0.9402849078 + 0.9524831176 0.9043961763 0.9405525923 + 0.9526547790 0.9048910141 0.9408199191 + 0.9528251886 0.9053859115 0.9410852790 + 0.9529957175 0.9058806896 0.9413505793 + 0.9531661868 0.9063755274 0.9416159987 + 0.9533365965 0.9068669081 0.9418812990 + 0.9535071254 0.9073519111 0.9421467185 + 0.9536749721 0.9078369141 0.9424085021 + 0.9538426995 0.9083219171 0.9426698089 + 0.9540104866 0.9088069201 0.9429311156 + 0.9541782141 0.9092918038 0.9431924224 + 0.9543460011 0.9097663760 0.9434537292 + 0.9545125961 0.9102410078 0.9437128901 + 0.9546784759 0.9107155800 0.9439705014 + 0.9548444748 0.9111902118 0.9442281127 + 0.9550104141 0.9116647840 0.9444857240 + 0.9551764131 0.9121345878 0.9447432160 + 0.9553416967 0.9126017094 0.9449998140 + 0.9555050135 0.9130687118 0.9452524781 + 0.9556683898 0.9135357141 0.9455052018 + 0.9558317065 0.9140027165 0.9457579255 + 0.9559950233 0.9144682884 0.9460105896 + 0.9561583996 0.9149281979 0.9462631941 + 0.9563187957 0.9153881073 0.9465129972 + 0.9564787745 0.9158478975 0.9467620254 + 0.9566386938 0.9163078070 0.9470111132 + 0.9567986727 0.9167675972 0.9472600818 + 0.9569585919 0.9172213078 0.9475091100 + 0.9571176767 0.9176725745 0.9477577806 + 0.9572752714 0.9181237817 0.9480059147 + 0.9574329257 0.9185751081 0.9482539892 + 0.9575905800 0.9190263152 0.9485020041 + 0.9577481747 0.9194753766 0.9487500787 + 0.9579058290 0.9199153781 0.9489980936 + 0.9580608010 0.9203554988 0.9492439032 + 0.9582154751 0.9207956195 0.9494892955 + 0.9583702087 0.9212356210 0.9497346878 + 0.9585248828 0.9216756821 0.9499800801 + 0.9586796165 0.9221099019 0.9502254725 + 0.9588336945 0.9225407243 0.9504696131 + 0.9589865208 0.9229714274 0.9507107139 + 0.9591394067 0.9234021902 0.9509518147 + 0.9592921734 0.9238328934 0.9511927962 + 0.9594451189 0.9242635965 0.9514338970 + 0.9595978856 0.9246863127 0.9516749978 + 0.9597501755 0.9251089096 0.9519119263 + 0.9599022865 0.9255316257 0.9521470070 + 0.9600545168 0.9259542823 0.9523820877 + 0.9602066278 0.9263768792 0.9526172280 + 0.9603586793 0.9267967939 0.9528523088 + 0.9605106115 0.9272115231 0.9530869722 + 0.9606612921 0.9276261926 0.9533157945 + 0.9608119726 0.9280409217 0.9535444975 + 0.9609627128 0.9284554720 0.9537733197 + 0.9611135125 0.9288702011 0.9540020227 + 0.9612641931 0.9292793870 0.9542307854 + 0.9614138007 0.9296854138 0.9544587135 + 0.9615620971 0.9300913811 0.9546853900 + 0.9617102742 0.9304975271 0.9549120069 + 0.9618585706 0.9309034944 0.9551386237 + 0.9620069265 0.9313095808 0.9553651810 + 0.9621551037 0.9317073822 0.9555919170 + 0.9623023272 0.9321041703 0.9558166265 + 0.9624490738 0.9325010180 0.9560402036 + 0.9625958204 0.9328979254 0.9562637806 + 0.9627425075 0.9332947135 0.9564874768 + 0.9628893137 0.9336907268 0.9567111135 + 0.9630360007 0.9340782762 0.9569346905 + 0.9631810784 0.9344660044 0.9571558833 + 0.9633259177 0.9348536134 0.9573767185 + 0.9634708166 0.9352412820 0.9575974941 + 0.9636157155 0.9356290102 0.9578183293 + 0.9637606144 0.9360147715 0.9580391049 + 0.9639053941 0.9363946915 0.9582598209 + 0.9640493989 0.9367746115 0.9584767222 + 0.9641934037 0.9371545911 0.9586936831 + 0.9643375278 0.9375345111 0.9589105844 + 0.9644814730 0.9379143715 0.9591274858 + 0.9646254778 0.9382917881 0.9593443871 + 0.9647691846 0.9386643171 0.9595605731 + 0.9649112821 0.9390369058 0.9597727060 + 0.9650534987 0.9394093752 0.9599847794 + 0.9651957154 0.9397819042 0.9601967931 + 0.9653378725 0.9401543736 0.9604089260 + 0.9654800296 0.9405236244 0.9606209993 + 0.9656214714 0.9408878088 0.9608321786 + 0.9657613039 0.9412518740 0.9610404968 + 0.9659010172 0.9416161180 0.9612486959 + 0.9660406709 0.9419801831 0.9614568949 + 0.9661805034 0.9423443079 0.9616652131 + 0.9663202167 0.9427043796 0.9618734121 + 0.9664595127 0.9430581927 0.9620807767 + 0.9665976763 0.9434120059 0.9622855186 + 0.9667360187 0.9437658191 0.9624903202 + 0.9668741822 0.9441195726 0.9626950026 + 0.9670125246 0.9444733858 0.9628996849 + 0.9671506882 0.9448243976 0.9631044865 + 0.9672883153 0.9451701045 0.9633080959 + 0.9674242139 0.9455156922 0.9635080099 + 0.9675601125 0.9458613992 0.9637079835 + 0.9676958919 0.9462071061 0.9639078975 + 0.9678317904 0.9465526938 0.9641078115 + 0.9679676890 0.9468963742 0.9643077254 + 0.9681032896 0.9472342134 0.9645069838 + 0.9682378173 0.9475718737 0.9647027254 + 0.9683722854 0.9479095936 0.9648982882 + 0.9685068130 0.9482473135 0.9650939703 + 0.9686412811 0.9485850930 0.9652895927 + 0.9687758088 0.9489220977 0.9654852748 + 0.9689102173 0.9492530823 0.9656807780 + 0.9690427184 0.9495840073 0.9658718705 + 0.9691752791 0.9499149919 0.9660630822 + 0.9693077803 0.9502459764 0.9662541747 + 0.9694404006 0.9505769014 0.9664453864 + 0.9695729017 0.9509078860 0.9666364789 + 0.9697054029 0.9512314796 0.9668276906 + 0.9698356986 0.9515542984 0.9670159221 + 0.9699656963 0.9518771172 0.9672036171 + 0.9700956941 0.9521998763 0.9673913717 + 0.9702258110 0.9525226951 0.9675791264 + 0.9703558087 0.9528455138 0.9677668214 + 0.9704858065 0.9531627893 0.9679545164 + 0.9706159830 0.9534772038 0.9681413770 + 0.9707463980 0.9537916780 0.9683275819 + 0.9708768129 0.9541060925 0.9685139060 + 0.9710071087 0.9544205070 0.9687001705 + 0.9711375237 0.9547349215 0.9688864946 + 0.9712678790 0.9550464153 0.9690728188 + 0.9713981152 0.9553524256 0.9692583084 + 0.9715282917 0.9556583166 0.9694423079 + 0.9716584086 0.9559643269 0.9696264267 + 0.9717885256 0.9562702775 0.9698104262 + 0.9719185829 0.9565762281 0.9699944854 + 0.9720488191 0.9568821788 0.9701784849 + 0.9721788168 0.9571802020 0.9703624845 + 0.9723080993 0.9574782252 0.9705430865 + 0.9724375010 0.9577761292 0.9707236886 + 0.9725667834 0.9580740929 0.9709041715 + 0.9726961255 0.9583721161 0.9710847735 + 0.9728254080 0.9586700201 0.9712653756 + 0.9729546905 0.9589635134 0.9714459181 + 0.9730840921 0.9592537880 0.9716234803 + 0.9732134938 0.9595441222 0.9717993140 + 0.9733428955 0.9598343968 0.9719752073 + 0.9734724164 0.9601246715 0.9721509814 + 0.9736018181 0.9604150057 0.9723268151 + 0.9737312198 0.9607043862 0.9725025892 + 0.9738605022 0.9609869719 0.9726774096 + 0.9739891887 0.9612696767 0.9728478789 + 0.9741178751 0.9615523219 0.9730182886 + 0.9742466211 0.9618350267 0.9731886983 + 0.9743753076 0.9621176124 0.9733592272 + 0.9745039940 0.9624003172 0.9735295773 + 0.9746326804 0.9626781940 0.9737001061 + 0.9747601748 0.9629530907 0.9738674760 + 0.9748873115 0.9632279873 0.9740337133 + 0.9750145078 0.9635028839 0.9742000103 + 0.9751415849 0.9637778997 0.9743661880 + 0.9752687216 0.9640527964 0.9745324254 + 0.9753959179 0.9643273950 0.9746986032 + 0.9755228162 0.9645949006 0.9748641849 + 0.9756492972 0.9648625255 0.9750267267 + 0.9757757187 0.9651299715 0.9751893282 + 0.9759021997 0.9653975964 0.9753518105 + 0.9760286212 0.9656651020 0.9755142927 + 0.9761551023 0.9659326077 0.9756767750 + 0.9762815237 0.9661971927 0.9758393764 + 0.9764071703 0.9664574862 0.9760001898 + 0.9765323997 0.9667177796 0.9761596918 + 0.9766576290 0.9669780731 0.9763193130 + 0.9767829180 0.9672384262 0.9764788151 + 0.9769080877 0.9674987793 0.9766383767 + 0.9770333171 0.9677590728 0.9767978787 + 0.9771584868 0.9680131078 0.9769575000 + 0.9772819877 0.9682648778 0.9771137238 + 0.9774054885 0.9685167074 0.9772697091 + 0.9775289297 0.9687684774 0.9774256945 + 0.9776523709 0.9690203071 0.9775816798 + 0.9777758121 0.9692721963 0.9777377248 + 0.9778991938 0.9695239067 0.9778935909 + 0.9780225158 0.9697673917 0.9780486822 + 0.9781451225 0.9700108767 0.9782000184 + 0.9782677889 0.9702544212 0.9783512950 + 0.9783903956 0.9704979062 0.9785025716 + 0.9785130024 0.9707413912 0.9786539078 + 0.9786357284 0.9709848166 0.9788051844 + 0.9787582755 0.9712265730 0.9789565802 + 0.9788810015 0.9714620709 0.9791055918 + 0.9790037870 0.9716976881 0.9792516828 + 0.9791265130 0.9719331861 0.9793978930 + 0.9792491794 0.9721686840 0.9795439839 + 0.9793720245 0.9724041820 0.9796900749 + 0.9794946909 0.9726397991 0.9798362255 + 0.9796174765 0.9728724957 0.9799823761 + 0.9797399044 0.9731004834 0.9801260829 + 0.9798622727 0.9733284712 0.9802682996 + 0.9799845815 0.9735565186 0.9804103971 + 0.9801068902 0.9737845063 0.9805526137 + 0.9802291989 0.9740126133 0.9806947708 + 0.9803515077 0.9742406011 0.9808369875 + 0.9804738164 0.9744648933 0.9809792042 + 0.9805954099 0.9746851921 0.9811189175 + 0.9807168245 0.9749054909 0.9812576771 + 0.9808381200 0.9751256704 0.9813964963 + 0.9809594750 0.9753460288 0.9815353155 + 0.9810807705 0.9755662084 0.9816740751 + 0.9812021852 0.9757865071 0.9818128943 + 0.9813234806 0.9760035872 0.9819517136 + 0.9814447761 0.9762178063 0.9820870757 + 0.9815660119 0.9764320254 0.9822216034 + 0.9816873074 0.9766461849 0.9823560715 + 0.9818086028 0.9768604040 0.9824907184 + 0.9819297791 0.9770746231 0.9826251864 + 0.9820510745 0.9772887230 0.9827597737 + 0.9821723104 0.9774991870 0.9828943014 + 0.9822927713 0.9777060151 0.9830257893 + 0.9824131727 0.9779127240 0.9831566215 + 0.9825335145 0.9781193733 0.9832873940 + 0.9826539159 0.9783260822 0.9834182262 + 0.9827741981 0.9785327911 0.9835489988 + 0.9828945994 0.9787396193 0.9836797714 + 0.9830150008 0.9789426923 0.9838104844 + 0.9831339717 0.9791409969 0.9839380980 + 0.9832527041 0.9793391824 0.9840646982 + 0.9833713174 0.9795374274 0.9841911793 + 0.9834899902 0.9797356725 0.9843177795 + 0.9836087227 0.9799339175 0.9844443798 + 0.9837273955 0.9801321030 0.9845709205 + 0.9838461280 0.9803280830 0.9846975207 + 0.9839642048 0.9805182219 0.9848210216 + 0.9840821028 0.9807084203 0.9849429727 + 0.9841998816 0.9808984995 0.9850649834 + 0.9843177795 0.9810886979 0.9851869941 + 0.9844356775 0.9812787771 0.9853090048 + 0.9845535755 0.9814689755 0.9854310155 + 0.9846714139 0.9816585183 0.9855529070 + 0.9847885966 0.9818410873 0.9856733084 + 0.9849051237 0.9820237756 0.9857919216 + 0.9850217104 0.9822065234 0.9859105945 + 0.9851381779 0.9823890924 0.9860293269 + 0.9852548242 0.9825717807 0.9861479998 + 0.9853712916 0.9827544093 0.9862666130 + 0.9854878783 0.9829370975 0.9863852859 + 0.9856039286 0.9831125140 0.9865033031 + 0.9857186079 0.9832866192 0.9866192937 + 0.9858332872 0.9834606051 0.9867352843 + 0.9859480262 0.9836345911 0.9868512750 + 0.9860628247 0.9838085771 0.9869673252 + 0.9861775041 0.9839826226 0.9870833158 + 0.9862921834 0.9841566086 0.9871993065 + 0.9864069223 0.9843258858 0.9873152971 + 0.9865176082 0.9844909906 0.9874280095 + 0.9866282940 0.9846559763 0.9875406027 + 0.9867389202 0.9848210812 0.9876531959 + 0.9868496060 0.9849861264 0.9877659082 + 0.9869602919 0.9851511717 0.9878785014 + 0.9870709777 0.9853162169 0.9879910946 + 0.9871817231 0.9854801893 0.9881036878 + 0.9872913957 0.9856383204 0.9882147908 + 0.9874005914 0.9857963920 0.9883249998 + 0.9875099063 0.9859545231 0.9884350896 + 0.9876191020 0.9861125946 0.9885452986 + 0.9877284169 0.9862707257 0.9886553884 + 0.9878376126 0.9864287972 0.9887655973 + 0.9879468083 0.9865869284 0.9888756871 + 0.9880558252 0.9867392778 0.9889851809 + 0.9881638288 0.9868894815 0.9890925288 + 0.9882717133 0.9870396852 0.9891998172 + 0.9883797169 0.9871898890 0.9893071055 + 0.9884877205 0.9873400927 0.9894143939 + 0.9885957241 0.9874902964 0.9895216227 + 0.9887037277 0.9876403809 0.9896289110 + 0.9888116717 0.9877886772 0.9897361994 + 0.9889186025 0.9879299998 0.9898411036 + 0.9890251756 0.9880713820 0.9899451733 + 0.9891318083 0.9882127047 0.9900494218 + 0.9892383814 0.9883540869 0.9901534915 + 0.9893450141 0.9884954095 0.9902576804 + 0.9894515276 0.9886367917 0.9903618097 + 0.9895581007 0.9887781143 0.9904659986 + 0.9896646142 0.9889159203 0.9905695915 + 0.9897707105 0.9890518188 0.9906715155 + 0.9898768067 0.9891877174 0.9907733798 + 0.9899830222 0.9893234968 0.9908754230 + 0.9900891185 0.9894593954 0.9909772873 + 0.9901952147 0.9895952940 0.9910792112 + 0.9903013110 0.9897311926 0.9911811948 + 0.9904074073 0.9898669720 0.9912831187 + 0.9905129075 0.9899997115 0.9913834929 + 0.9906179905 0.9901322722 0.9914830923 + 0.9907230139 0.9902650118 0.9915826917 + 0.9908280969 0.9903976917 0.9916822910 + 0.9909331799 0.9905303121 0.9917818904 + 0.9910383224 0.9906629920 0.9918814898 + 0.9911434054 0.9907956719 0.9919810891 + 0.9912484288 0.9909266829 0.9920806885 + 0.9913520217 0.9910547137 0.9921786189 + 0.9914554954 0.9911826849 0.9922763705 + 0.9915590286 0.9913107157 0.9923741817 + 0.9916625023 0.9914388061 0.9924721122 + 0.9917659760 0.9915667772 0.9925699234 + 0.9918695092 0.9916948080 0.9926676750 + 0.9919729829 0.9918227792 0.9927656054 + 0.9920759201 0.9919472933 0.9928627014 + 0.9921774268 0.9920694232 0.9929581881 + 0.9922788739 0.9921916127 0.9930536151 + 0.9923803806 0.9923136830 0.9931489825 + 0.9924818873 0.9924358726 0.9932444096 + 0.9925833941 0.9925580025 0.9933397770 + 0.9926849008 0.9926801920 0.9934352040 + 0.9927864075 0.9928023219 0.9935305715 + 0.9928867221 0.9929195046 0.9936246276 + 0.9929860234 0.9930353165 0.9937170148 + 0.9930852056 0.9931510091 0.9938094020 + 0.9931843877 0.9932668209 0.9939017892 + 0.9932836294 0.9933825731 0.9939941764 + 0.9933828115 0.9934983850 0.9940866828 + 0.9934821129 0.9936141968 0.9941791296 + 0.9935812950 0.9937298894 0.9942715168 + 0.9936792254 0.9938406944 0.9943618178 + 0.9937763214 0.9939510822 0.9944508076 + 0.9938734174 0.9940614104 0.9945397973 + 0.9939705729 0.9941716790 0.9946289062 + 0.9940677285 0.9942820072 0.9947178960 + 0.9941648245 0.9943923950 0.9948070049 + 0.9942619801 0.9945027232 0.9948959947 + 0.9943590760 0.9946129918 0.9949849844 + 0.9944550991 0.9947180152 0.9950715899 + 0.9945507050 0.9948229194 0.9951571822 + 0.9946463108 0.9949277043 0.9952427745 + 0.9947419167 0.9950326085 0.9953284264 + 0.9948375225 0.9951373935 0.9954140186 + 0.9949331284 0.9952422976 0.9954996109 + 0.9950286150 0.9953472018 0.9955852032 + 0.9951242208 0.9954519868 0.9956707954 + 0.9952185154 0.9955508113 0.9957543015 + 0.9953123927 0.9956492782 0.9958369732 + 0.9954062104 0.9957479239 0.9959197044 + 0.9955000281 0.9958463907 0.9960023761 + 0.9955939054 0.9959449172 0.9960849881 + 0.9956877232 0.9960435033 0.9961677194 + 0.9957814813 0.9961420298 0.9962503910 + 0.9958754182 0.9962404966 0.9963331223 + 0.9959679842 0.9963330030 0.9964141846 + 0.9960600734 0.9964246750 0.9964945912 + 0.9961522818 0.9965164065 0.9965748787 + 0.9962443709 0.9966081977 0.9966552854 + 0.9963365197 0.9966999292 0.9967356920 + 0.9964286089 0.9967916012 0.9968159795 + 0.9965208173 0.9968832731 0.9968963861 + 0.9966129065 0.9969750047 0.9969767928 + 0.9967035055 0.9970617890 0.9970558882 + 0.9967930913 0.9971467853 0.9971340895 + 0.9968826771 0.9972319007 0.9972122908 + 0.9969723821 0.9973170161 0.9972904921 + 0.9970620275 0.9974020123 0.9973688126 + 0.9971516132 0.9974871278 0.9974470139 + 0.9972411990 0.9975721240 0.9975252151 + 0.9973307848 0.9976571798 0.9976034164 + 0.9974188805 0.9977390170 0.9976804852 + 0.9975048900 0.9978179932 0.9977560043 + 0.9975908995 0.9978969097 0.9978315234 + 0.9976769090 0.9979758263 0.9979069233 + 0.9977629185 0.9980546832 0.9979823828 + 0.9978489280 0.9981337190 0.9980579019 + 0.9979348779 0.9982125759 0.9981334209 + 0.9980208874 0.9982914925 0.9982088208 + 0.9981061220 0.9983687997 0.9982838035 + 0.9981874228 0.9984411001 0.9983559251 + 0.9982687831 0.9985135198 0.9984279871 + 0.9983500838 0.9985858202 0.9985002279 + 0.9984313846 0.9986581802 0.9985722899 + 0.9985126853 0.9987304807 0.9986444116 + 0.9985939860 0.9988029003 0.9987164736 + 0.9986754060 0.9988752007 0.9987885952 + 0.9987567067 0.9989476204 0.9988607764 + 0.9988334179 0.9990134835 0.9989299178 + 0.9989092946 0.9990788102 0.9989984035 + 0.9989851117 0.9991440773 0.9990668893 + 0.9990609884 0.9992092848 0.9991354942 + 0.9991368055 0.9992746115 0.9992039800 + 0.9992126822 0.9993398786 0.9992725253 + 0.9992886186 0.9994050860 0.9993410707 + 0.9993643761 0.9994704127 0.9994096160 + 0.9994376898 0.9995324016 0.9994766712 + 0.9995080233 0.9995908141 0.9995421171 + 0.9995782971 0.9996492863 0.9996075034 + 0.9996485710 0.9997076988 0.9996728897 + 0.9997189045 0.9997661710 0.9997382760 + 0.9997891784 0.9998245835 0.9998037815 + 0.9998593926 0.9998831153 0.9998692274 + 0.9999297261 0.9999415278 0.9999346137 + 1.0000000000 1.0000000000 1.0000000000 +} diff --git a/rpplugins/color_correction/resources/film_luts_raw/agfa_agfachrome_rsx2_100.spi1d b/rpplugins/color_correction/resources/film_luts_raw/agfa_agfachrome_rsx2_100.spi1d new file mode 100644 index 0000000..545776f --- /dev/null +++ b/rpplugins/color_correction/resources/film_luts_raw/agfa_agfachrome_rsx2_100.spi1d @@ -0,0 +1,1030 @@ +Version 1 +From 0.0 1.0 +Length 1024 +Components 3 +{ + 0.0000000000 0.0000000000 0.0000000000 + 0.0005538157 0.0002576292 0.0005585101 + 0.0012096640 0.0005333599 0.0011604551 + 0.0019140980 0.0008360103 0.0018323910 + 0.0026460199 0.0011740130 0.0025799151 + 0.0034157911 0.0015541241 0.0033877229 + 0.0042393408 0.0019793189 0.0042505912 + 0.0051223529 0.0024463851 0.0051805871 + 0.0060673542 0.0029475561 0.0061999368 + 0.0070817620 0.0034730800 0.0073256488 + 0.0081761600 0.0040138708 0.0085633332 + 0.0093593132 0.0045639272 0.0099106664 + 0.0106341401 0.0051191631 0.0113591403 + 0.0119961500 0.0056801899 0.0129020195 + 0.0134347901 0.0062479940 0.0145361200 + 0.0149379000 0.0068263910 0.0162581895 + 0.0164953694 0.0074195368 0.0180597696 + 0.0181045309 0.0080307238 0.0199336000 + 0.0197760705 0.0086633833 0.0218689796 + 0.0215226207 0.0093178684 0.0238573793 + 0.0233605802 0.0099947192 0.0258926600 + 0.0253009591 0.0106952796 0.0279722493 + 0.0273566395 0.0114182802 0.0300974604 + 0.0295376405 0.0121626100 0.0322676599 + 0.0318443291 0.0129287997 0.0344865993 + 0.0342735499 0.0137156500 0.0367620103 + 0.0368162692 0.0145225199 0.0390981287 + 0.0394631997 0.0153492000 0.0414960496 + 0.0422021896 0.0161942504 0.0439662300 + 0.0450241007 0.0170577895 0.0465124287 + 0.0479182489 0.0179391392 0.0491312891 + 0.0508695506 0.0188368801 0.0518258400 + 0.0538671017 0.0197515395 0.0545928814 + 0.0569038987 0.0206836108 0.0574216582 + 0.0599653386 0.0216330998 0.0603049994 + 0.0630441532 0.0226011295 0.0632309094 + 0.0661331788 0.0235872995 0.0661824495 + 0.0692235529 0.0245907698 0.0691514686 + 0.0723131001 0.0256121606 0.0721308514 + 0.0753963515 0.0266514607 0.0751067922 + 0.0784699991 0.0277084205 0.0780698285 + 0.0815294310 0.0287822001 0.0810127109 + 0.0845746398 0.0298725795 0.0839387029 + 0.0876072496 0.0309803504 0.0868489370 + 0.0906234607 0.0321053714 0.0897342712 + 0.0936240926 0.0332451016 0.0925956666 + 0.0966099873 0.0343989693 0.0954437479 + 0.0995746925 0.0355678201 0.0982764736 + 0.1025210023 0.0367507786 0.1010928974 + 0.1054513976 0.0379455499 0.1038966030 + 0.1083656028 0.0391518585 0.1066884995 + 0.1112613007 0.0403695591 0.1094719023 + 0.1141443029 0.0415982008 0.1122469977 + 0.1170163006 0.0428373106 0.1150157973 + 0.1198785976 0.0440876000 0.1177795008 + 0.1227298006 0.0453483313 0.1205397025 + 0.1255751997 0.0466196500 0.1232986972 + 0.1284184009 0.0479020402 0.1260581017 + 0.1312606931 0.0491929315 0.1288186014 + 0.1341048926 0.0504931509 0.1315809935 + 0.1369509995 0.0518033691 0.1343457997 + 0.1397999972 0.0531228185 0.1371127963 + 0.1426569968 0.0544515885 0.1398842931 + 0.1455242038 0.0557879396 0.1426624060 + 0.1484020054 0.0571304597 0.1454472989 + 0.1512925029 0.0584798306 0.1482387930 + 0.1541953981 0.0598362610 0.1510369033 + 0.1571146995 0.0612012111 0.1538417041 + 0.1600483954 0.0625731573 0.1566565037 + 0.1629952043 0.0639522225 0.1594796926 + 0.1659574062 0.0653370395 0.1623144001 + 0.1689333022 0.0667286515 0.1651574969 + 0.1719211042 0.0681272000 0.1680109054 + 0.1749179959 0.0695317611 0.1708731055 + 0.1779257059 0.0709433332 0.1737474054 + 0.1809400022 0.0723603070 0.1766321063 + 0.1839601994 0.0737829134 0.1795291007 + 0.1869864017 0.0752107576 0.1824384034 + 0.1900130957 0.0766445100 0.1853630990 + 0.1930415034 0.0780834034 0.1883013994 + 0.1960687935 0.0795266330 0.1912554055 + 0.1990925074 0.0809739381 0.1942231059 + 0.2021104991 0.0824264735 0.1972043961 + 0.2051243931 0.0838834122 0.2002002001 + 0.2081328928 0.0853442401 0.2032063007 + 0.2111341059 0.0868088603 0.2062257975 + 0.2141271979 0.0882768705 0.2092570961 + 0.2171119004 0.0897474736 0.2122993022 + 0.2200873941 0.0912210122 0.2153486013 + 0.2230526060 0.0926979184 0.2184022963 + 0.2260069996 0.0941769183 0.2214571983 + 0.2289530039 0.0956579819 0.2245126069 + 0.2318878025 0.0971412882 0.2275668979 + 0.2348102033 0.0986268297 0.2306147963 + 0.2377181053 0.1001135036 0.2336523980 + 0.2406145036 0.1016011015 0.2366762012 + 0.2435014993 0.1030898988 0.2396847010 + 0.2463797927 0.1045792028 0.2426739931 + 0.2492484003 0.1060694978 0.2456423044 + 0.2521043122 0.1075616032 0.2485859990 + 0.2549489141 0.1090551987 0.2515046895 + 0.2577804029 0.1105502024 0.2543984056 + 0.2605997920 0.1120468974 0.2572653890 + 0.2634068131 0.1135445982 0.2601054013 + 0.2662003040 0.1150436029 0.2629188001 + 0.2689799964 0.1165440977 0.2657040954 + 0.2717454135 0.1180453971 0.2684625983 + 0.2744967043 0.1195472032 0.2711946964 + 0.2772313952 0.1210499033 0.2738988996 + 0.2799471915 0.1225532964 0.2765769064 + 0.2826446891 0.1240585968 0.2792299092 + 0.2853254974 0.1255660951 0.2818576992 + 0.2879889011 0.1270741969 0.2844642103 + 0.2906337082 0.1285829991 0.2870489955 + 0.2932612002 0.1300923973 0.2896148860 + 0.2958734035 0.1316034049 0.2921622097 + 0.2984699905 0.1331169009 0.2946906090 + 0.3010497093 0.1346320063 0.2972028852 + 0.3036122024 0.1361477971 0.2996973991 + 0.3061597049 0.1376651973 0.3021731079 + 0.3086943924 0.1391835958 0.3046326041 + 0.3112165928 0.1407034993 0.3070755005 + 0.3137254119 0.1422256976 0.3095063865 + 0.3162207901 0.1437488943 0.3119274080 + 0.3187038004 0.1452739984 0.3143393993 + 0.3211764991 0.1468010992 0.3167423904 + 0.3236395121 0.1483293027 0.3191359937 + 0.3260940909 0.1498585939 0.3215200901 + 0.3285394907 0.1513891965 0.3238947988 + 0.3309769928 0.1529217958 0.3262606859 + 0.3334091902 0.1544554979 0.3286187053 + 0.3358364105 0.1559904069 0.3309695125 + 0.3382585049 0.1575258970 0.3333117962 + 0.3406754136 0.1590621024 0.3356468081 + 0.3430868983 0.1606000960 0.3379752934 + 0.3454923034 0.1621384025 0.3402976096 + 0.3478921950 0.1636777073 0.3426141143 + 0.3502902091 0.1652178019 0.3449253142 + 0.3526883125 0.1667584032 0.3472313881 + 0.3550874889 0.1682990938 0.3495286107 + 0.3574880064 0.1698389053 0.3518162966 + 0.3598900139 0.1713789999 0.3540945053 + 0.3622936904 0.1729196012 0.3563635945 + 0.3646990955 0.1744605005 0.3586243987 + 0.3671062887 0.1760009974 0.3608759940 + 0.3695152998 0.1775424033 0.3631196022 + 0.3719266951 0.1790847033 0.3653568029 + 0.3743407130 0.1806277931 0.3675884008 + 0.3767570853 0.1821713001 0.3698143959 + 0.3791759014 0.1837140024 0.3720313013 + 0.3815971911 0.1852564067 0.3742407858 + 0.3840225041 0.1867990047 0.3764427900 + 0.3864507079 0.1883427054 0.3786371052 + 0.3888813853 0.1898857057 0.3808222115 + 0.3913142085 0.1914276034 0.3829993010 + 0.3937469125 0.1929681003 0.3851706088 + 0.3961795866 0.1945082992 0.3873367906 + 0.3986124098 0.1960480064 0.3894971013 + 0.4010451138 0.1975871027 0.3916527927 + 0.4034779072 0.1991253942 0.3938055933 + 0.4059106112 0.2006641030 0.3959555924 + 0.4083434045 0.2022033036 0.3980999887 + 0.4107761085 0.2037439942 0.4002406001 + 0.4132089019 0.2052841932 0.4023782909 + 0.4156416953 0.2068233937 0.4045133889 + 0.4180744886 0.2083608955 0.4066438079 + 0.4205071926 0.2098989934 0.4087715149 + 0.4229399860 0.2114374042 0.4108966887 + 0.4253725111 0.2129762024 0.4130181968 + 0.4278020859 0.2145155072 0.4151366949 + 0.4302271903 0.2160546035 0.4172526896 + 0.4326483905 0.2175924033 0.4193654954 + 0.4350630045 0.2191300988 0.4214769900 + 0.4374726117 0.2206678987 0.4235875905 + 0.4398784041 0.2222069055 0.4256978929 + 0.4422785044 0.2237454951 0.4278069139 + 0.4446738958 0.2252838016 0.4299151003 + 0.4470661879 0.2268211991 0.4320223033 + 0.4494529963 0.2283589989 0.4341273010 + 0.4518359900 0.2298974991 0.4362305105 + 0.4542163014 0.2314366996 0.4383283854 + 0.4565913081 0.2329763025 0.4404241145 + 0.4589622915 0.2345169932 0.4425179958 + 0.4613293111 0.2360569984 0.4446097016 + 0.4636883140 0.2375967056 0.4467011988 + 0.4660438001 0.2391356975 0.4487924874 + 0.4683940113 0.2406754941 0.4508841932 + 0.4707357883 0.2422166020 0.4529756010 + 0.4730732143 0.2437583953 0.4550662041 + 0.4754005075 0.2453003973 0.4571551979 + 0.4777207971 0.2468425930 0.4592432082 + 0.4800347984 0.2483848035 0.4613265097 + 0.4823366106 0.2499269992 0.4634082913 + 0.4846338928 0.2514702976 0.4654878080 + 0.4869211912 0.2530143857 0.4675660133 + 0.4892016053 0.2545599937 0.4696435928 + 0.4914767146 0.2561056912 0.4717212021 + 0.4937387109 0.2576513886 0.4737991989 + 0.4959957898 0.2591978014 0.4758777916 + 0.4982388020 0.2607448995 0.4779537022 + 0.5004736185 0.2622939944 0.4800283015 + 0.5026996136 0.2638441026 0.4820936918 + 0.5049133897 0.2653951943 0.4841566086 + 0.5071231127 0.2669464946 0.4862132072 + 0.5093185902 0.2684977949 0.4882662892 + 0.5115088224 0.2700498998 0.4903163016 + 0.5136851072 0.2716039121 0.4923604131 + 0.5158513188 0.2731583118 0.4944027960 + 0.5180078149 0.2747133076 0.4964390099 + 0.5201510191 0.2762692869 0.4984740913 + 0.5222893953 0.2778258026 0.5005058050 + 0.5244101286 0.2793847024 0.5025345087 + 0.5265269279 0.2809442878 0.5045595765 + 0.5286250114 0.2825047970 0.5065774918 + 0.5307167768 0.2840653062 0.5085912943 + 0.5327941179 0.2856262922 0.5105962753 + 0.5348628163 0.2871873975 0.5125992894 + 0.5369216204 0.2887484133 0.5145884752 + 0.5389689207 0.2903096974 0.5165752769 + 0.5410090089 0.2918717861 0.5185478926 + 0.5430334806 0.2934342027 0.5205165744 + 0.5450525880 0.2949968874 0.5224738717 + 0.5470547080 0.2965593040 0.5244258046 + 0.5490540862 0.2981210053 0.5263680816 + 0.5510348082 0.2996825874 0.5283023715 + 0.5530139804 0.3012439907 0.5302276015 + 0.5549759865 0.3028059006 0.5321443081 + 0.5569360852 0.3043687046 0.5340541005 + 0.5588794947 0.3059312105 0.5359538794 + 0.5608198047 0.3074932992 0.5378476977 + 0.5627439022 0.3090555072 0.5397273898 + 0.5646646023 0.3106175959 0.5416002274 + 0.5665714145 0.3121803999 0.5434591770 + 0.5684738755 0.3137443066 0.5453127027 + 0.5703607798 0.3153086901 0.5471491814 + 0.5722435713 0.3168740869 0.5489794016 + 0.5741115808 0.3184395134 0.5507919192 + 0.5759764910 0.3200049996 0.5525978208 + 0.5778291225 0.3215703964 0.5543872118 + 0.5796784163 0.3231351078 0.5561701059 + 0.5815119147 0.3246999085 0.5579361916 + 0.5833426714 0.3262651861 0.5596947074 + 0.5851539969 0.3278304935 0.5614392757 + 0.5869635940 0.3293960094 0.5631760955 + 0.5887479186 0.3309614956 0.5649011731 + 0.5905321836 0.3325259984 0.5666179061 + 0.5922917128 0.3340902925 0.5683240891 + 0.5940505266 0.3356544077 0.5700199008 + 0.5957903862 0.3372184038 0.5717071891 + 0.5975276232 0.3387834132 0.5733817816 + 0.5992469788 0.3403491974 0.5750491023 + 0.6009606719 0.3419148922 0.5766983032 + 0.6026608944 0.3434804976 0.5783439875 + 0.6043530107 0.3450458050 0.5799701810 + 0.6060341001 0.3466094136 0.5815963149 + 0.6077030897 0.3481729925 0.5831990242 + 0.6093657017 0.3497354984 0.5848017931 + 0.6110138893 0.3512978852 0.5863847136 + 0.6126598120 0.3528620899 0.5879638195 + 0.6142886281 0.3544270992 0.5895280838 + 0.6159173846 0.3559925854 0.5910843015 + 0.6175265908 0.3575589955 0.5926306248 + 0.6191338897 0.3591251969 0.5941641927 + 0.6207273006 0.3606910110 0.5956931114 + 0.6223142743 0.3622567058 0.5972054005 + 0.6238920093 0.3638209105 0.5987178087 + 0.6254580021 0.3653847873 0.6002131104 + 0.6270201802 0.3669480979 0.6017081141 + 0.6285654902 0.3685106933 0.6031907797 + 0.6301108003 0.3700729907 0.6046687961 + 0.6316359043 0.3716341853 0.6061378717 + 0.6331589222 0.3731954098 0.6075956225 + 0.6346688867 0.3747552931 0.6090502143 + 0.6361703277 0.3763149977 0.6104860902 + 0.6376655102 0.3778744936 0.6119219065 + 0.6391450763 0.3794336915 0.6133409142 + 0.6406247020 0.3809930086 0.6147564054 + 0.6420868039 0.3825530112 0.6161623001 + 0.6435478926 0.3841128945 0.6175583005 + 0.6449993253 0.3856733143 0.6189519763 + 0.6464440227 0.3872339129 0.6203303933 + 0.6478844881 0.3887940943 0.6217089295 + 0.6493095756 0.3903535903 0.6230769157 + 0.6507347226 0.3919129968 0.6244416833 + 0.6521434188 0.3934705853 0.6258000135 + 0.6535484791 0.3950277865 0.6271470785 + 0.6549462080 0.3965846002 0.6284943223 + 0.6563327909 0.3981403112 0.6298246980 + 0.6577193737 0.3996961117 0.6311542988 + 0.6590902805 0.4012506902 0.6324747205 + 0.6604607105 0.4028050900 0.6337866187 + 0.6618214250 0.4043591022 0.6350975037 + 0.6631729007 0.4059123993 0.6363947988 + 0.6645237207 0.4074656069 0.6376919746 + 0.6658543944 0.4090178013 0.6389808059 + 0.6671850085 0.4105696082 0.6402636170 + 0.6685047150 0.4121212065 0.6415452957 + 0.6698150039 0.4136717916 0.6428160071 + 0.6711249948 0.4152224064 0.6440867186 + 0.6724179983 0.4167717099 0.6453511119 + 0.6737111211 0.4183202982 0.6466106772 + 0.6749945283 0.4198687077 0.6478698850 + 0.6762676239 0.4214153886 0.6491171122 + 0.6775407195 0.4229620993 0.6503642201 + 0.6787930131 0.4245072901 0.6516051292 + 0.6800435781 0.4260506034 0.6528393030 + 0.6812877059 0.4275940061 0.6540734768 + 0.6825190187 0.4291338921 0.6552976966 + 0.6837502718 0.4306730926 0.6565207243 + 0.6849684715 0.4322116971 0.6577410102 + 0.6861820817 0.4337471128 0.6589547992 + 0.6873937249 0.4352824986 0.6601685882 + 0.6885895133 0.4368155897 0.6613742113 + 0.6897851825 0.4383459091 0.6625760198 + 0.6909723282 0.4398762882 0.6637775898 + 0.6921495199 0.4414024055 0.6649709940 + 0.6933267117 0.4429270029 0.6661643982 + 0.6944912076 0.4444515109 0.6673536897 + 0.6956524253 0.4459707141 0.6685358882 + 0.6968116164 0.4474897981 0.6697182059 + 0.6979551911 0.4490073919 0.6708937287 + 0.6990987062 0.4505204856 0.6720660925 + 0.7002366185 0.4520334899 0.6732385159 + 0.7013661265 0.4535439909 0.6744014025 + 0.7024955750 0.4550516903 0.6755638719 + 0.7036141753 0.4565593898 0.6767243743 + 0.7047271729 0.4580627978 0.6778780818 + 0.7058401704 0.4595640898 0.6790319085 + 0.7069379091 0.4610654116 0.6801804900 + 0.7080339789 0.4625608921 0.6813232899 + 0.7091283202 0.4640552998 0.6824662089 + 0.7102094293 0.4655497074 0.6836034060 + 0.7112904191 0.4670377970 0.6847382784 + 0.7123653293 0.4685258865 0.6858730912 + 0.7134271860 0.4700129926 0.6869965792 + 0.7144889832 0.4714944065 0.6881188154 + 0.7155439258 0.4729757905 0.6892403960 + 0.7165915966 0.4744558036 0.6903538108 + 0.7176393867 0.4759314060 0.6914672256 + 0.7186779976 0.4774070978 0.6925780177 + 0.7197117209 0.4788806140 0.6936802268 + 0.7207453847 0.4803498089 0.6947823763 + 0.7217658758 0.4818190932 0.6958813071 + 0.7227824926 0.4832853973 0.6969739795 + 0.7237992287 0.4847474098 0.6980667114 + 0.7248027921 0.4862093031 0.6991550922 + 0.7258046269 0.4876680970 0.7002385855 + 0.7268064022 0.4891225100 0.7013220787 + 0.7277902961 0.4905770123 0.7024012804 + 0.7287734151 0.4920283854 0.7034770250 + 0.7297564149 0.4934760034 0.7045525908 + 0.7307261825 0.4949235916 0.7056220770 + 0.7316960096 0.4963681996 0.7066873908 + 0.7326653004 0.4978089035 0.7077527046 + 0.7336220741 0.4992494881 0.7088124752 + 0.7345790267 0.5006874204 0.7098689079 + 0.7355352044 0.5021209121 0.7109252810 + 0.7364767194 0.5035544038 0.7119749784 + 0.7374181151 0.5049852133 0.7130206823 + 0.7383592725 0.5064104795 0.7140665054 + 0.7392876148 0.5078356862 0.7151080966 + 0.7402158976 0.5092589259 0.7161473036 + 0.7411442995 0.5106753111 0.7171863914 + 0.7420564294 0.5120915771 0.7182205915 + 0.7429682016 0.5135068893 0.7192509770 + 0.7438799143 0.5149142742 0.7202814221 + 0.7447810173 0.5163217187 0.7213069797 + 0.7456809878 0.5177291036 0.7223277092 + 0.7465808988 0.5191293955 0.7233483791 + 0.7474709153 0.5205295086 0.7243651152 + 0.7483584285 0.5219296217 0.7253757119 + 0.7492460012 0.5233250260 0.7263864279 + 0.7501245141 0.5247194171 0.7273939848 + 0.7509989738 0.5261136889 0.7283943295 + 0.7518733740 0.5275031924 0.7293944955 + 0.7527413964 0.5288894773 0.7303934097 + 0.7536038756 0.5302758813 0.7313838005 + 0.7544664145 0.5316587090 0.7323741913 + 0.7553241849 0.5330361724 0.7333645821 + 0.7561736703 0.5344135761 0.7343451977 + 0.7570232749 0.5357897282 0.7353253961 + 0.7578713298 0.5371581912 0.7363057137 + 0.7587116957 0.5385265946 0.7372794151 + 0.7595521212 0.5398949981 0.7382512093 + 0.7603924870 0.5412554741 0.7392228842 + 0.7612221837 0.5426148176 0.7401890755 + 0.7620512247 0.5439741015 0.7411506772 + 0.7628800869 0.5453277230 0.7421122789 + 0.7637022138 0.5466768742 0.7430707216 + 0.7645211220 0.5480260849 0.7440214753 + 0.7653400898 0.5493733883 0.7449724078 + 0.7661545873 0.5507144928 0.7459229827 + 0.7669628859 0.5520555973 0.7468630075 + 0.7677711844 0.5533967018 0.7478029132 + 0.7685785890 0.5547322035 0.7487428784 + 0.7693775296 0.5560668111 0.7496752143 + 0.7701764107 0.5574014783 0.7506042719 + 0.7709752917 0.5587329865 0.7515335083 + 0.7717691064 0.5600612760 0.7524588108 + 0.7725613713 0.5613896251 0.7533779740 + 0.7733535767 0.5627173781 0.7542970777 + 0.7741429806 0.5640394092 0.7552161217 + 0.7749279737 0.5653614998 0.7561244965 + 0.7757130265 0.5666834712 0.7570329905 + 0.7764979005 0.5680016279 0.7579414248 + 0.7772737145 0.5693175197 0.7588419914 + 0.7780495286 0.5706332922 0.7597380877 + 0.7788252831 0.5719478130 0.7606341243 + 0.7795972228 0.5732557178 0.7615277767 + 0.7803664207 0.5745636225 0.7624130845 + 0.7811354995 0.5758715272 0.7632983923 + 0.7819035053 0.5771726966 0.7641837001 + 0.7826650143 0.5784705877 0.7650598884 + 0.7834265232 0.5797685981 0.7659333944 + 0.7841879725 0.5810651779 0.7668067813 + 0.7849435806 0.5823537111 0.7676774859 + 0.7856963277 0.5836421847 0.7685415745 + 0.7864488959 0.5849307179 0.7694056034 + 0.7872005105 0.5862150788 0.7702696919 + 0.7879469991 0.5874965787 0.7711244226 + 0.7886934876 0.5887780190 0.7719767094 + 0.7894400954 0.5900595188 0.7728291154 + 0.7901812196 0.5913344026 0.7736784220 + 0.7909191251 0.5926094055 0.7745192051 + 0.7916570902 0.5938844085 0.7753601074 + 0.7923948169 0.5951570272 0.7762010098 + 0.7931283116 0.5964260101 0.7770338058 + 0.7938618064 0.5976949930 0.7778633237 + 0.7945951819 0.5989639759 0.7786927223 + 0.7953253984 0.6002289057 0.7795209885 + 0.7960519195 0.6014925241 0.7803397775 + 0.7967783809 0.6027560830 0.7811586857 + 0.7975050211 0.6040192842 0.7819775939 + 0.7982237935 0.6052780151 0.7827903032 + 0.7989413142 0.6065366864 0.7835965753 + 0.7996588945 0.6077952981 0.7844029069 + 0.8003752232 0.6090512276 0.7852091789 + 0.8010866046 0.6103022099 0.7860053778 + 0.8017979860 0.6115530729 0.7867997289 + 0.8025094271 0.6128041148 0.7875940204 + 0.8032175899 0.6140497923 0.7883868217 + 0.8039227128 0.6152924895 0.7891716957 + 0.8046277761 0.6165351868 0.7899566293 + 0.8053328991 0.6177778244 0.7907415032 + 0.8060317039 0.6190140843 0.7915207148 + 0.8067288995 0.6202492118 0.7922930717 + 0.8074262142 0.6214843988 0.7930656075 + 0.8081231117 0.6227191091 0.7938380241 + 0.8088151813 0.6239476204 0.7946025133 + 0.8095073104 0.6251760125 0.7953637838 + 0.8101993799 0.6264044046 0.7961249948 + 0.8108897805 0.6276314855 0.7968863249 + 0.8115760088 0.6288539171 0.7976366878 + 0.8122622967 0.6300764084 0.7983863950 + 0.8129485250 0.6312987804 0.7991361022 + 0.8136305213 0.6325194240 0.7998843193 + 0.8143079281 0.6337367296 0.8006227016 + 0.8149852753 0.6349539161 0.8013610244 + 0.8156628013 0.6361712217 0.8020994067 + 0.8163372278 0.6373847723 0.8028339744 + 0.8170101047 0.6385943294 0.8035594225 + 0.8176829219 0.6398037076 0.8042848110 + 0.8183556795 0.6410130858 0.8050101995 + 0.8190233111 0.6422181129 0.8057312965 + 0.8196895123 0.6434193850 0.8064466119 + 0.8203555942 0.6446207166 0.8071619272 + 0.8210217953 0.6458219290 0.8078771830 + 0.8216826916 0.6470190883 0.8085857034 + 0.8223428726 0.6482132077 0.8092882037 + 0.8230029941 0.6494073272 0.8099907041 + 0.8236631751 0.6506013870 0.8106932044 + 0.8243181705 0.6517918706 0.8113890290 + 0.8249729872 0.6529797912 0.8120803833 + 0.8256276846 0.6541677117 0.8127716780 + 0.8262825012 0.6553556919 0.8134629726 + 0.8269299865 0.6565406919 0.8141471148 + 0.8275772929 0.6577234864 0.8148270845 + 0.8282247186 0.6589062214 0.8155071139 + 0.8288720250 0.6600890160 0.8161870837 + 0.8295140862 0.6612688899 0.8168601990 + 0.8301560879 0.6624459028 0.8175293803 + 0.8307980895 0.6636229157 0.8181986213 + 0.8314400911 0.6647999287 0.8188679218 + 0.8320763707 0.6659740210 0.8195297122 + 0.8327124119 0.6671438217 0.8201869130 + 0.8333482742 0.6683136821 0.8208439946 + 0.8339843154 0.6694836020 0.8215011954 + 0.8346142769 0.6706516147 0.8221533895 + 0.8352434039 0.6718149185 0.8228014708 + 0.8358724713 0.6729781032 0.8234496117 + 0.8365015984 0.6741414070 0.8240976930 + 0.8371255994 0.6753039956 0.8247407079 + 0.8377479911 0.6764618754 0.8253772855 + 0.8383705020 0.6776198149 0.8260139823 + 0.8389930129 0.6787776947 0.8266506195 + 0.8396112919 0.6799355149 0.8272842765 + 0.8402273059 0.6810882092 0.8279114962 + 0.8408433199 0.6822404265 0.8285385966 + 0.8414592743 0.6833925843 0.8291658163 + 0.8420726061 0.6845448017 0.8297916055 + 0.8426827788 0.6856936216 0.8304092884 + 0.8432930112 0.6868407726 0.8310269713 + 0.8439031839 0.6879879832 0.8316445947 + 0.8445109129 0.6891351938 0.8322622776 + 0.8451119065 0.6902797818 0.8328717947 + 0.8457129002 0.6914209127 0.8334808946 + 0.8463138938 0.6925619245 0.8340898752 + 0.8469148278 0.6937029958 0.8346989155 + 0.8475095034 0.6948431730 0.8353011012 + 0.8481041789 0.6959772110 0.8359006047 + 0.8486989141 0.6971111894 0.8364999890 + 0.8492935896 0.6982452273 0.8370993733 + 0.8498833179 0.6993792057 0.8376960158 + 0.8504714966 0.7005075812 0.8382890224 + 0.8510596156 0.7016344070 0.8388819098 + 0.8516476750 0.7027612925 0.8394749165 + 0.8522318006 0.7038881183 0.8400666118 + 0.8528108001 0.7050123215 0.8406503797 + 0.8533899188 0.7061328888 0.8412342072 + 0.8539689779 0.7072533965 0.8418179154 + 0.8545476198 0.7083739042 0.8424016833 + 0.8551219106 0.7094944119 0.8429775238 + 0.8556962013 0.7106081247 0.8435510993 + 0.8562703729 0.7117217183 0.8441246748 + 0.8568447232 0.7128353715 0.8446984291 + 0.8574144244 0.7139490843 0.8452690244 + 0.8579822183 0.7150586843 0.8458353281 + 0.8585500717 0.7161651254 0.8464015722 + 0.8591179252 0.7172715068 0.8469678760 + 0.8596833944 0.7183778286 0.8475341201 + 0.8602436185 0.7194836736 0.8480933905 + 0.8608037233 0.7205830812 0.8486527205 + 0.8613638282 0.7216826081 0.8492119908 + 0.8619239926 0.7227820158 0.8497712016 + 0.8624796271 0.7238814235 0.8503255248 + 0.8630344272 0.7249767780 0.8508757949 + 0.8635892272 0.7260689139 0.8514261246 + 0.8641440272 0.7271611094 0.8519762754 + 0.8646966219 0.7282531857 0.8525258899 + 0.8652452826 0.7293453217 0.8530645967 + 0.8657941222 0.7304283977 0.8536034226 + 0.8663427830 0.7315114737 0.8541421890 + 0.8668915033 0.7325944901 0.8546810150 + 0.8674352169 0.7336776257 0.8552160859 + 0.8679779172 0.7347571850 0.8557479978 + 0.8685206771 0.7358316183 0.8562799096 + 0.8690633774 0.7369059920 0.8568118811 + 0.8696042895 0.7379804254 0.8573437929 + 0.8701401949 0.7390547991 0.8578673005 + 0.8706761003 0.7401224971 0.8583906293 + 0.8712120056 0.7411879897 0.8589140177 + 0.8717479110 0.7422536016 0.8594372869 + 0.8722802997 0.7433190942 0.8599570990 + 0.8728110194 0.7443835735 0.8604711294 + 0.8733416796 0.7454379797 0.8609851003 + 0.8738722801 0.7464923263 0.8614990711 + 0.8744028211 0.7475466728 0.8620131016 + 0.8749272823 0.7486010790 0.8625208735 + 0.8754518032 0.7496516109 0.8630263805 + 0.8759763241 0.7506958246 0.8635318875 + 0.8765007854 0.7517400980 0.8640373945 + 0.8770225048 0.7527843118 0.8645426035 + 0.8775386810 0.7538285851 0.8650417924 + 0.8780549765 0.7548667789 0.8655411005 + 0.8785712123 0.7559013963 0.8660402894 + 0.8790875077 0.7569360733 0.8665394783 + 0.8796002269 0.7579708099 0.8670362830 + 0.8801108003 0.7590054870 0.8675283790 + 0.8806213737 0.7600315213 0.8680204153 + 0.8811320066 0.7610560060 0.8685125113 + 0.8816425800 0.7620804906 0.8690046072 + 0.8821474910 0.7631049156 0.8694908023 + 0.8826515079 0.7641292214 0.8699728847 + 0.8831555247 0.7651435733 0.8704550266 + 0.8836596012 0.7661579251 0.8709372282 + 0.8841630220 0.7671722770 0.8714193106 + 0.8846591115 0.7681866288 0.8718963265 + 0.8851552010 0.7691996098 0.8723719716 + 0.8856512904 0.7702046037 0.8728476167 + 0.8861473799 0.7712097168 0.8733233213 + 0.8866416812 0.7722147703 0.8737990260 + 0.8871303201 0.7732198238 0.8742687106 + 0.8876188993 0.7742217779 0.8747382164 + 0.8881074786 0.7752138972 0.8752077222 + 0.8885961771 0.7762060761 0.8756772876 + 0.8890824914 0.7771981955 0.8761461973 + 0.8895648718 0.7781903744 0.8766090274 + 0.8900471926 0.7791786194 0.8770719171 + 0.8905295730 0.7801573277 0.8775346875 + 0.8910118937 0.7811360955 0.8779975772 + 0.8914917707 0.7821148038 0.8784590960 + 0.8919684887 0.7830935121 0.8789139986 + 0.8924452066 0.7840679288 0.8793689013 + 0.8929218054 0.7850319743 0.8798238039 + 0.8933985233 0.7859961987 0.8802787066 + 0.8938719034 0.7869604230 0.8807321787 + 0.8943415880 0.7879245877 0.8811805248 + 0.8948113918 0.7888851762 0.8816288114 + 0.8952810764 0.7898358107 0.8820770979 + 0.8957508206 0.7907865047 0.8825255036 + 0.8962174058 0.7917371988 0.8829724789 + 0.8966804147 0.7926878929 0.8834149837 + 0.8971434832 0.7936357856 0.8838574886 + 0.8976066113 0.7945719957 0.8843001127 + 0.8980696201 0.7955083251 0.8847426176 + 0.8985310793 0.7964445949 0.8851838708 + 0.8989905119 0.7973809242 0.8856199980 + 0.8994498253 0.7983161807 0.8860560060 + 0.8999091983 0.7992392778 0.8864920735 + 0.9003685713 0.8001623750 0.8869280815 + 0.9008257985 0.8010855913 0.8873633742 + 0.9012789726 0.8020086884 0.8877922297 + 0.9017320871 0.8029319048 0.8882209063 + 0.9021853209 0.8038424253 0.8886497021 + 0.9026384950 0.8047516942 0.8890783787 + 0.9030898213 0.8056610227 0.8895071149 + 0.9035350084 0.8065704107 0.8899301887 + 0.9039803147 0.8074796796 0.8903532028 + 0.9044255018 0.8083794117 0.8907762170 + 0.9048708081 0.8092753291 0.8911991119 + 0.9053156972 0.8101711869 0.8916221261 + 0.9057556987 0.8110671043 0.8920407891 + 0.9061955810 0.8119630218 0.8924584985 + 0.9066355824 0.8128508925 0.8928763270 + 0.9070755839 0.8137295842 0.8932939768 + 0.9075155854 0.8146083951 0.8937116861 + 0.9079490900 0.8154872060 0.8941258192 + 0.9083815813 0.8163658977 0.8945375085 + 0.9088140726 0.8172419071 0.8949491978 + 0.9092466235 0.8181051016 0.8953608274 + 0.9096791148 0.8189684153 0.8957725167 + 0.9101070166 0.8198316097 0.8961812854 + 0.9105319977 0.8206949234 0.8965846896 + 0.9109569192 0.8215581179 0.8969882131 + 0.9113819003 0.8224077821 0.8973916173 + 0.9118068218 0.8232551813 0.8977950215 + 0.9122298956 0.8241025209 0.8981981874 + 0.9126486778 0.8249498010 0.8985965848 + 0.9130674005 0.8257970810 0.8989951015 + 0.9134861827 0.8266378045 0.8993936181 + 0.9139049053 0.8274710178 0.8997920156 + 0.9143236279 0.8283041716 0.9001904726 + 0.9147337079 0.8291373849 0.9005855918 + 0.9151433706 0.8299707174 0.9009795189 + 0.9155529737 0.8308032155 0.9013733864 + 0.9159626961 0.8316221237 0.9017671943 + 0.9163724184 0.8324409723 0.9021611214 + 0.9167771935 0.8332599998 0.9025527239 + 0.9171783924 0.8340789080 0.9029397964 + 0.9175795913 0.8348978758 0.9033269286 + 0.9179807901 0.8357083797 0.9037140012 + 0.9183819294 0.8365128040 0.9041010737 + 0.9187824130 0.8373172879 0.9044882059 + 0.9191781282 0.8381217718 0.9048687220 + 0.9195739031 0.8389261961 0.9052485824 + 0.9199696779 0.8397294283 0.9056286216 + 0.9203655124 0.8405168056 0.9060084820 + 0.9207612276 0.8413041234 0.9063884020 + 0.9211524725 0.8420915008 0.9067658186 + 0.9215413928 0.8428788185 0.9071398973 + 0.9219303727 0.8436661959 0.9075140953 + 0.9223194122 0.8444454074 0.9078881741 + 0.9227082729 0.8452168703 0.9082623720 + 0.9230962992 0.8459883928 0.9086365104 + 0.9234783053 0.8467599750 0.9090055227 + 0.9238603711 0.8475314975 0.9093741179 + 0.9242423773 0.8483030796 0.9097427130 + 0.9246245027 0.8490607738 0.9101111889 + 0.9250065088 0.8498172760 0.9104797840 + 0.9253851175 0.8505737185 0.9108464122 + 0.9257611036 0.8513301015 0.9112095237 + 0.9261372089 0.8520866036 0.9115725756 + 0.9265131950 0.8528388739 0.9119356871 + 0.9268891811 0.8535797000 0.9122989178 + 0.9272652864 0.8543204069 0.9126620293 + 0.9276344180 0.8550611734 0.9130206108 + 0.9280033708 0.8558018804 0.9133777022 + 0.9283723235 0.8565427065 0.9137349129 + 0.9287412763 0.8572751880 0.9140920043 + 0.9291102290 0.8580012918 0.9144490957 + 0.9294773936 0.8587272763 0.9148054719 + 0.9298406839 0.8594533801 0.9151548147 + 0.9302039742 0.8601794839 0.9155040979 + 0.9305673838 0.8609055877 0.9158533812 + 0.9309306741 0.8616189957 0.9162026048 + 0.9312940240 0.8623296022 0.9165518880 + 0.9316536784 0.8630402088 0.9168993831 + 0.9320111275 0.8637508750 0.9172441959 + 0.9323683977 0.8644614816 0.9175890088 + 0.9327257872 0.8651716709 0.9179338217 + 0.9330831170 0.8658667207 0.9182785153 + 0.9334405065 0.8665615916 0.9186233282 + 0.9337912798 0.8672565818 0.9189655781 + 0.9341409802 0.8679515123 0.9193063974 + 0.9344906211 0.8686465025 0.9196472168 + 0.9348403215 0.8693385124 0.9199880958 + 0.9351899028 0.8700178266 0.9203289151 + 0.9355393052 0.8706970811 0.9206697941 + 0.9358832836 0.8713763952 0.9210057259 + 0.9362273216 0.8720557094 0.9213408232 + 0.9365713000 0.8727350235 0.9216758013 + 0.9369152188 0.8734096289 0.9220108986 + 0.9372591972 0.8740733862 0.9223458767 + 0.9376019835 0.8747370839 0.9226809740 + 0.9379401803 0.8754009008 0.9230101109 + 0.9382783771 0.8760647178 0.9233391881 + 0.9386165738 0.8767284155 0.9236683846 + 0.9389547706 0.8773869276 0.9239975214 + 0.9392930269 0.8780362010 0.9243265986 + 0.9396293163 0.8786854148 0.9246553183 + 0.9399607778 0.8793346882 0.9249799252 + 0.9402924180 0.8799839020 0.9253045917 + 0.9406239986 0.8806331754 0.9256293178 + 0.9409555793 0.8812769055 0.9259539247 + 0.9412871003 0.8819113970 0.9262785912 + 0.9416161776 0.8825458288 0.9266026020 + 0.9419407248 0.8831803203 0.9269232750 + 0.9422652125 0.8838148117 0.9272438884 + 0.9425897002 0.8844493032 0.9275646210 + 0.9429141283 0.8850783110 0.9278851748 + 0.9432386160 0.8856968284 0.9282059073 + 0.9435608983 0.8863152862 0.9285259247 + 0.9438794255 0.8869338036 0.9288429022 + 0.9441977739 0.8875523210 0.9291598797 + 0.9445161819 0.8881707191 0.9294769168 + 0.9448347092 0.8887856007 0.9297938943 + 0.9451531172 0.8893899918 0.9301108718 + 0.9454690218 0.8899943829 0.9304273725 + 0.9457793236 0.8905987740 0.9307404160 + 0.9460895061 0.8912032247 0.9310532808 + 0.9463998079 0.8918076158 0.9313663244 + 0.9467099905 0.8924102783 0.9316793084 + 0.9470202923 0.8930001259 0.9319922924 + 0.9473289847 0.8935899734 0.9323049784 + 0.9476320744 0.8941798210 0.9326118827 + 0.9479352236 0.8947697282 0.9329187870 + 0.9482381940 0.8953595161 0.9332256913 + 0.9485412836 0.8959493041 0.9335324764 + 0.9488443136 0.8965260983 0.9338393807 + 0.9491471052 0.8971018195 0.9341462851 + 0.9494447708 0.8976774812 0.9344497919 + 0.9497426152 0.8982532024 0.9347528815 + 0.9500402808 0.8988289833 0.9350559711 + 0.9503381252 0.8994047046 0.9353591204 + 0.9506357908 0.8999707103 0.9356622100 + 0.9509335756 0.9005324244 0.9359652996 + 0.9512249827 0.9010940790 0.9362673163 + 0.9515153766 0.9016557932 0.9365687966 + 0.9518058896 0.9022175074 0.9368702769 + 0.9520962834 0.9027792215 0.9371718764 + 0.9523866773 0.9033352137 0.9374734163 + 0.9526770711 0.9038825035 0.9377748966 + 0.9529634118 0.9044299126 0.9380748272 + 0.9532471895 0.9049773216 0.9383726716 + 0.9535309076 0.9055246711 0.9386705756 + 0.9538146257 0.9060720801 0.9389684796 + 0.9540982842 0.9066187143 0.9392663836 + 0.9543820024 0.9071521163 0.9395642877 + 0.9546641707 0.9076855183 0.9398614168 + 0.9549428821 0.9082189202 0.9401535988 + 0.9552217126 0.9087523222 0.9404457808 + 0.9555004835 0.9092857242 0.9407380819 + 0.9557793140 0.9098191261 0.9410303235 + 0.9560580850 0.9103447795 0.9413226247 + 0.9563369155 0.9108663797 0.9416148067 + 0.9566090703 0.9113880992 0.9419016838 + 0.9568811059 0.9119098186 0.9421873093 + 0.9571530819 0.9124314785 0.9424728751 + 0.9574251175 0.9129531980 0.9427586198 + 0.9576970935 0.9134721160 0.9430441856 + 0.9579691291 0.9139804244 0.9433298111 + 0.9582366943 0.9144887924 0.9436146021 + 0.9585008025 0.9149972200 0.9438980818 + 0.9587647915 0.9155055285 0.9441816807 + 0.9590288997 0.9160138965 0.9444652200 + 0.9592928886 0.9165222049 0.9447486997 + 0.9595569968 0.9170212150 0.9450322986 + 0.9598206282 0.9175164104 0.9453157783 + 0.9600790739 0.9180114865 0.9455965161 + 0.9603375793 0.9185066223 0.9458770156 + 0.9605960846 0.9190018177 0.9461575150 + 0.9608544707 0.9194968939 0.9464380145 + 0.9611129761 0.9199900031 0.9467185140 + 0.9613714814 0.9204719067 0.9469990134 + 0.9616270065 0.9209538102 0.9472776055 + 0.9618802071 0.9214357138 0.9475535154 + 0.9621335268 0.9219176173 0.9478294253 + 0.9623867273 0.9223995209 0.9481052756 + 0.9626399875 0.9228814244 0.9483813047 + 0.9628931880 0.9233567119 0.9486572146 + 0.9631463885 0.9238265157 0.9489331245 + 0.9633926153 0.9242962003 0.9492051005 + 0.9636389017 0.9247658849 0.9494764805 + 0.9638851285 0.9252356887 0.9497479796 + 0.9641314149 0.9257053733 0.9500194192 + 0.9643775821 0.9261751771 0.9502907991 + 0.9646239281 0.9266350865 0.9505621791 + 0.9648674726 0.9270936847 0.9508329034 + 0.9651070237 0.9275522232 0.9511013031 + 0.9653465152 0.9280108213 0.9513697028 + 0.9655861259 0.9284693003 0.9516382217 + 0.9658256173 0.9289278984 0.9519066215 + 0.9660651088 0.9293845296 0.9521750212 + 0.9663046002 0.9298309088 0.9524434209 + 0.9665402174 0.9302772880 0.9527102113 + 0.9667741060 0.9307237267 0.9529756904 + 0.9670081139 0.9311701059 0.9532412291 + 0.9672421217 0.9316164851 0.9535068274 + 0.9674760103 0.9320629239 0.9537723064 + 0.9677100182 0.9325053096 0.9540377855 + 0.9679439068 0.9329410195 0.9543033838 + 0.9681721926 0.9333767891 0.9545660019 + 0.9684002995 0.9338126183 0.9548282027 + 0.9686284065 0.9342483282 0.9550904036 + 0.9688565135 0.9346840978 0.9553526044 + 0.9690846205 0.9351198077 0.9556146860 + 0.9693127275 0.9355502129 0.9558768868 + 0.9695394039 0.9359760880 0.9561389089 + 0.9697601199 0.9364020228 0.9563990831 + 0.9699807763 0.9368280172 0.9566591978 + 0.9702014923 0.9372538924 0.9569193125 + 0.9704222083 0.9376798272 0.9571794271 + 0.9706429243 0.9381058216 0.9574394822 + 0.9708635807 0.9385251999 0.9576995969 + 0.9710816145 0.9389411807 0.9579588175 + 0.9712945223 0.9393572211 0.9582151175 + 0.9715074897 0.9397732019 0.9584714174 + 0.9717203975 0.9401893020 0.9587277770 + 0.9719334245 0.9406052828 0.9589840770 + 0.9721462727 0.9410213232 0.9592403769 + 0.9723592997 0.9414290190 0.9594966769 + 0.9725701809 0.9418333769 0.9597517252 + 0.9727786779 0.9422376752 0.9600039721 + 0.9729871154 0.9426419735 0.9602563977 + 0.9731954932 0.9430463910 0.9605087042 + 0.9734039903 0.9434506893 0.9607610106 + 0.9736124277 0.9438549876 0.9610133767 + 0.9738209248 0.9442532063 0.9612656832 + 0.9740266800 0.9446488023 0.9615169764 + 0.9742298126 0.9450443983 0.9617664814 + 0.9744328260 0.9454399943 0.9620159864 + 0.9746358991 0.9458355904 0.9622653723 + 0.9748389721 0.9462311864 0.9625148773 + 0.9750419855 0.9466267824 0.9627643824 + 0.9752451181 0.9470162988 0.9630138874 + 0.9754452705 0.9474024177 0.9632629156 + 0.9756422043 0.9477884769 0.9635112882 + 0.9758390784 0.9481745958 0.9637596011 + 0.9760360122 0.9485607743 0.9640079737 + 0.9762328863 0.9489468932 0.9642562866 + 0.9764298201 0.9493330121 0.9645047188 + 0.9766266942 0.9497143030 0.9647529721 + 0.9768214822 0.9500910044 0.9650006294 + 0.9770131111 0.9504678249 0.9652460814 + 0.9772046208 0.9508445859 0.9654915929 + 0.9773961902 0.9512214065 0.9657371044 + 0.9775878191 0.9515982270 0.9659826159 + 0.9777793884 0.9519749284 0.9662281275 + 0.9779708982 0.9523478746 0.9664735794 + 0.9781610966 0.9527137876 0.9667181969 + 0.9783474207 0.9530795813 0.9669579864 + 0.9785336852 0.9534453750 0.9671977758 + 0.9787198901 0.9538112879 0.9674376845 + 0.9789062142 0.9541770816 0.9676774740 + 0.9790924191 0.9545428753 0.9679173231 + 0.9792786837 0.9549077153 0.9681571126 + 0.9794644713 0.9552628994 0.9683969021 + 0.9796441793 0.9556182027 0.9686303735 + 0.9798238873 0.9559733868 0.9688637257 + 0.9800035954 0.9563286901 0.9690970182 + 0.9801833034 0.9566838741 0.9693303108 + 0.9803630114 0.9570391774 0.9695636034 + 0.9805427194 0.9573944807 0.9697968960 + 0.9807224274 0.9577432275 0.9700301886 + 0.9808962941 0.9580901861 0.9702622294 + 0.9810687900 0.9584373236 0.9704936147 + 0.9812414050 0.9587844014 0.9707251191 + 0.9814139009 0.9591314793 0.9709565043 + 0.9815865159 0.9594786167 0.9711880088 + 0.9817590117 0.9598256946 0.9714193940 + 0.9819316268 0.9601699710 0.9716508985 + 0.9821007848 0.9605106115 0.9718813896 + 0.9822667241 0.9608513117 0.9721106887 + 0.9824326038 0.9611920118 0.9723399878 + 0.9825986028 0.9615327120 0.9725692868 + 0.9827644825 0.9618732929 0.9727985859 + 0.9829304218 0.9622139931 0.9730278850 + 0.9830964208 0.9625545144 0.9732571840 + 0.9832617044 0.9628877044 0.9734864235 + 0.9834232926 0.9632207751 0.9737125039 + 0.9835848212 0.9635540247 0.9739385843 + 0.9837464094 0.9638870955 0.9741647243 + 0.9839078784 0.9642202258 0.9743908048 + 0.9840695262 0.9645534158 0.9746168852 + 0.9842309952 0.9648864865 0.9748430252 + 0.9843925834 0.9652161002 0.9750691056 + 0.9845516086 0.9655424953 0.9752932191 + 0.9847096205 0.9658688903 0.9755160809 + 0.9848675132 0.9661952853 0.9757388830 + 0.9850255251 0.9665216804 0.9759618044 + 0.9851834178 0.9668480754 0.9761847258 + 0.9853413105 0.9671744704 0.9764075875 + 0.9854993224 0.9675009251 0.9766303897 + 0.9856563210 0.9678199291 0.9768530726 + 0.9858093262 0.9681388736 0.9770743251 + 0.9859623909 0.9684578776 0.9772955179 + 0.9861153960 0.9687768817 0.9775167704 + 0.9862685204 0.9690958858 0.9777380228 + 0.9864215255 0.9694147706 0.9779592156 + 0.9865745902 0.9697337747 0.9781805277 + 0.9867275953 0.9700502753 0.9784017205 + 0.9868773222 0.9703627229 0.9786214232 + 0.9870250225 0.9706751704 0.9788399935 + 0.9871727824 0.9709876180 0.9790586233 + 0.9873206019 0.9713000059 0.9792770743 + 0.9874683022 0.9716125131 0.9794957042 + 0.9876161218 0.9719249010 0.9797142744 + 0.9877638221 0.9722372890 0.9799329042 + 0.9879115224 0.9725446105 0.9801514149 + 0.9880549908 0.9728497267 0.9803667068 + 0.9881983995 0.9731547832 0.9805818200 + 0.9883419275 0.9734600186 0.9807968736 + 0.9884853959 0.9737650752 0.9810119867 + 0.9886289239 0.9740701914 0.9812270999 + 0.9887723923 0.9743754268 0.9814422131 + 0.9889158010 0.9746804833 0.9816573262 + 0.9890578985 0.9749789238 0.9818714261 + 0.9891973138 0.9752771854 0.9820829034 + 0.9893366098 0.9755755067 0.9822943211 + 0.9894760251 0.9758738279 0.9825057983 + 0.9896153212 0.9761720896 0.9827172160 + 0.9897546768 0.9764702916 0.9829286933 + 0.9898939729 0.9767686129 0.9831401110 + 0.9900333881 0.9770656824 0.9833515882 + 0.9901698232 0.9773573279 0.9835612774 + 0.9903042912 0.9776489139 0.9837695956 + 0.9904388189 0.9779404998 0.9839779139 + 0.9905732870 0.9782320857 0.9841861725 + 0.9907078147 0.9785236716 0.9843944907 + 0.9908422828 0.9788153172 0.9846028090 + 0.9909768105 0.9791069031 0.9848111272 + 0.9911112785 0.9793964028 0.9850193858 + 0.9912419915 0.9796813726 0.9852252007 + 0.9913715720 0.9799662828 0.9854300022 + 0.9915010929 0.9802513123 0.9856348038 + 0.9916306734 0.9805362821 0.9858396053 + 0.9917603135 0.9808213115 0.9860445261 + 0.9918898940 0.9811062813 0.9862493277 + 0.9920194745 0.9813911915 0.9864541292 + 0.9921491146 0.9816734791 0.9866588712 + 0.9922748208 0.9819514751 0.9868602157 + 0.9923998713 0.9822294712 0.9870607853 + 0.9925251007 0.9825075269 0.9872614145 + 0.9926502705 0.9827854037 0.9874619842 + 0.9927754998 0.9830633998 0.9876626730 + 0.9929007292 0.9833413959 0.9878633022 + 0.9930258989 0.9836193919 0.9880638719 + 0.9931511283 0.9838947058 0.9882645011 + 0.9932720065 0.9841657877 0.9884613156 + 0.9933925867 0.9844368100 0.9886577129 + 0.9935132861 0.9847078919 0.9888541102 + 0.9936339855 0.9849789739 0.9890506268 + 0.9937546849 0.9852501154 0.9892470241 + 0.9938753247 0.9855211973 0.9894434214 + 0.9939960241 0.9857922196 0.9896398187 + 0.9941167235 0.9860610962 0.9898362160 + 0.9942330122 0.9863253832 0.9900293946 + 0.9943491220 0.9865897298 0.9902222157 + 0.9944652915 0.9868540168 0.9904149771 + 0.9945814013 0.9871183038 0.9906079173 + 0.9946975112 0.9873827100 0.9908006787 + 0.9948136210 0.9876469970 0.9909934998 + 0.9949297905 0.9879112840 0.9911863804 + 0.9950459003 0.9881742001 0.9913792014 + 0.9951578975 0.9884313941 0.9915676117 + 0.9952692986 0.9886885881 0.9917551875 + 0.9953806996 0.9889457822 0.9919428229 + 0.9954922199 0.9892029762 0.9921303988 + 0.9956036210 0.9894601703 0.9923179746 + 0.9957150221 0.9897174239 0.9925056100 + 0.9958264232 0.9899746180 0.9926931858 + 0.9959378242 0.9902316928 0.9928808212 + 0.9960461259 0.9904808998 0.9930642247 + 0.9961531758 0.9907299876 0.9932457209 + 0.9962602854 0.9909791946 0.9934272766 + 0.9963673949 0.9912282825 0.9936087728 + 0.9964745045 0.9914774895 0.9937903285 + 0.9965816140 0.9917266965 0.9939718843 + 0.9966887236 0.9919757843 0.9941533804 + 0.9967958927 0.9922249913 0.9943349957 + 0.9969006181 0.9924687147 0.9945136905 + 0.9970030785 0.9927104712 0.9946895838 + 0.9971057177 0.9929522276 0.9948654771 + 0.9972081780 0.9931939840 0.9950413704 + 0.9973108172 0.9934358001 0.9952173233 + 0.9974133968 0.9936776161 0.9953930974 + 0.9975159168 0.9939193726 0.9955689907 + 0.9976184964 0.9941611886 0.9957448840 + 0.9977198839 0.9943996072 0.9959198236 + 0.9978176951 0.9946330786 0.9960914254 + 0.9979155064 0.9948667288 0.9962630868 + 0.9980133176 0.9951003194 0.9964346886 + 0.9981111288 0.9953339100 0.9966062903 + 0.9982089996 0.9955673814 0.9967778921 + 0.9983068109 0.9958009720 0.9969494939 + 0.9984046221 0.9960346222 0.9971210957 + 0.9985023737 0.9962679744 0.9972926974 + 0.9985945225 0.9964916110 0.9974582791 + 0.9986860156 0.9967151880 0.9976230860 + 0.9987773895 0.9969388843 0.9977878928 + 0.9988688827 0.9971625209 0.9979526997 + 0.9989603162 0.9973860979 0.9981175065 + 0.9990518093 0.9976096749 0.9982821941 + 0.9991431832 0.9978333116 0.9984470010 + 0.9992346764 0.9980568886 0.9986118078 + 0.9993227720 0.9982761145 0.9987711906 + 0.9994074702 0.9984915853 0.9989247918 + 0.9994921088 0.9987071157 0.9990783930 + 0.9995768070 0.9989225864 0.9992319942 + 0.9996613860 0.9991381168 0.9993855953 + 0.9997460842 0.9993535280 0.9995391965 + 0.9998307228 0.9995689988 0.9996927977 + 0.9999154210 0.9997845292 0.9998463988 + 1.0000000000 1.0000000000 1.0000000000 +} diff --git a/rpplugins/color_correction/resources/film_luts_raw/agfa_agfachrome_rsx2_200.spi1d b/rpplugins/color_correction/resources/film_luts_raw/agfa_agfachrome_rsx2_200.spi1d new file mode 100644 index 0000000..5f1a0e1 --- /dev/null +++ b/rpplugins/color_correction/resources/film_luts_raw/agfa_agfachrome_rsx2_200.spi1d @@ -0,0 +1,1030 @@ +Version 1 +From 0.0 1.0 +Length 1024 +Components 3 +{ + 0.0000000000 0.0000000000 0.0000000000 + 0.0002336452 0.0003066142 0.0001923408 + 0.0004746285 0.0006284252 0.0003908366 + 0.0007228691 0.0009574692 0.0005960183 + 0.0009798091 0.0012926980 0.0008084249 + 0.0012458910 0.0016348250 0.0010286780 + 0.0015215250 0.0019854531 0.0012572890 + 0.0018074480 0.0023458831 0.0014948760 + 0.0021044740 0.0027179900 0.0017418840 + 0.0024123720 0.0031044651 0.0019987100 + 0.0027316429 0.0035080169 0.0022662929 + 0.0030628759 0.0039312281 0.0025448580 + 0.0034068460 0.0043767700 0.0028348130 + 0.0037631821 0.0048452052 0.0031369999 + 0.0041319309 0.0053377128 0.0034519250 + 0.0045133741 0.0058530779 0.0037802891 + 0.0049079140 0.0063888212 0.0041218149 + 0.0053149262 0.0069422242 0.0044763028 + 0.0057351599 0.0075108381 0.0048436122 + 0.0061681862 0.0080922469 0.0052233832 + 0.0066139381 0.0086847479 0.0056158421 + 0.0070730280 0.0092877084 0.0060206670 + 0.0075457580 0.0099003958 0.0064372532 + 0.0080318721 0.0105231302 0.0068652900 + 0.0085307229 0.0111563997 0.0073052440 + 0.0090426058 0.0118005900 0.0077564488 + 0.0095678763 0.0124572096 0.0082195234 + 0.0101060299 0.0131261898 0.0086938078 + 0.0106565999 0.0138081899 0.0091797709 + 0.0112196403 0.0145026296 0.0096775433 + 0.0117950998 0.0152096897 0.0101859104 + 0.0123830596 0.0159296691 0.0107057104 + 0.0129827997 0.0166616905 0.0112374704 + 0.0135938600 0.0174061507 0.0117801595 + 0.0142163001 0.0181632899 0.0123338196 + 0.0148505196 0.0189326294 0.0128991101 + 0.0154959997 0.0197145808 0.0134759704 + 0.0161525905 0.0205079298 0.0140651399 + 0.0168197099 0.0213135108 0.0146654900 + 0.0174975600 0.0221296605 0.0152769703 + 0.0181858800 0.0229572095 0.0159003101 + 0.0188853294 0.0237958394 0.0165352002 + 0.0195957199 0.0246469099 0.0171822291 + 0.0203166995 0.0255084708 0.0178419799 + 0.0210479405 0.0263805594 0.0185129102 + 0.0217893906 0.0272626597 0.0191952903 + 0.0225410797 0.0281556007 0.0198900104 + 0.0233031102 0.0290594995 0.0205974299 + 0.0240752809 0.0299743302 0.0213165600 + 0.0248574503 0.0308989193 0.0220477208 + 0.0256489795 0.0318339504 0.0227914508 + 0.0264505297 0.0327800512 0.0235488601 + 0.0272613708 0.0337377489 0.0243192408 + 0.0280819293 0.0347075686 0.0251018200 + 0.0289116092 0.0356889293 0.0258964691 + 0.0297506806 0.0366821997 0.0267038904 + 0.0305987895 0.0376874991 0.0275248494 + 0.0314561911 0.0387053117 0.0283588003 + 0.0323230512 0.0397350118 0.0292057395 + 0.0331984907 0.0407753289 0.0300664101 + 0.0340828784 0.0418274291 0.0309393499 + 0.0349764302 0.0428918488 0.0318249315 + 0.0358787291 0.0439687595 0.0327227190 + 0.0367900617 0.0450573303 0.0336325206 + 0.0377106704 0.0461591706 0.0345553607 + 0.0386387706 0.0472715795 0.0354900099 + 0.0395760499 0.0483947694 0.0364381485 + 0.0405212790 0.0495291613 0.0373984985 + 0.0414749682 0.0506746694 0.0383732207 + 0.0424371511 0.0518323407 0.0393615104 + 0.0434069186 0.0530007891 0.0403636508 + 0.0443847999 0.0541807003 0.0413801111 + 0.0453707203 0.0553707816 0.0424091816 + 0.0463633984 0.0565719493 0.0434532799 + 0.0473654494 0.0577826984 0.0445101783 + 0.0483737215 0.0590048917 0.0455798395 + 0.0493897311 0.0602366105 0.0466651618 + 0.0504129082 0.0614794008 0.0477640294 + 0.0514423698 0.0627331585 0.0488768108 + 0.0524802990 0.0639974698 0.0500062406 + 0.0535254516 0.0652740896 0.0511502102 + 0.0545772910 0.0665622428 0.0523082986 + 0.0556361787 0.0678606406 0.0534805804 + 0.0567024983 0.0691716820 0.0546686798 + 0.0577750802 0.0704934299 0.0558703691 + 0.0588535815 0.0718252510 0.0570854694 + 0.0599400401 0.0731683001 0.0583138093 + 0.0610331818 0.0745219514 0.0595557392 + 0.0621325709 0.0758863464 0.0608114190 + 0.0632396191 0.0772613883 0.0620787703 + 0.0643534884 0.0786459073 0.0633573383 + 0.0654745772 0.0800427720 0.0646468624 + 0.0666032135 0.0814517811 0.0659470782 + 0.0677386299 0.0828704983 0.0672577098 + 0.0688809007 0.0843003020 0.0685787722 + 0.0700303987 0.0857396796 0.0699099898 + 0.0711864233 0.0871883109 0.0712488964 + 0.0723488331 0.0886481106 0.0725946799 + 0.0735196322 0.0901157334 0.0739471167 + 0.0746975020 0.0915923566 0.0753060281 + 0.0758822709 0.0930788666 0.0766710714 + 0.0770741701 0.0945737883 0.0780422911 + 0.0782730505 0.0960773528 0.0794199184 + 0.0794789493 0.0975896269 0.0808036402 + 0.0806913823 0.0991091728 0.0821929798 + 0.0819104165 0.1006359980 0.0835875571 + 0.0831365734 0.1021701992 0.0849873573 + 0.0843702182 0.1037115976 0.0863918066 + 0.0856113136 0.1052597985 0.0878000185 + 0.0868599117 0.1068146974 0.0892115831 + 0.0881158933 0.1083773971 0.0906265825 + 0.0893787891 0.1099461019 0.0920447111 + 0.0906486213 0.1115209982 0.0934653208 + 0.0919253081 0.1131021008 0.0948884189 + 0.0932083800 0.1146880984 0.0963144898 + 0.0944980532 0.1162792966 0.0977434963 + 0.0957952365 0.1178762987 0.0991748795 + 0.0970996320 0.1194792986 0.1006093025 + 0.0984100029 0.1210874990 0.1020475999 + 0.0997272208 0.1226997972 0.1034903973 + 0.1010518000 0.1243164986 0.1049363986 + 0.1023814976 0.1259384006 0.1063854992 + 0.1037181988 0.1275652051 0.1078381985 + 0.1050620005 0.1291960031 0.1092941016 + 0.1064110026 0.1308314055 0.1107527018 + 0.1077655032 0.1324710995 0.1122142971 + 0.1091263965 0.1341142952 0.1136794984 + 0.1104935035 0.1357623935 0.1151480004 + 0.1118659005 0.1374143958 0.1166194007 + 0.1132436991 0.1390711069 0.1180943996 + 0.1146290004 0.1407306939 0.1195726022 + 0.1160207018 0.1423933059 0.1210533977 + 0.1174174026 0.1440594047 0.1225365996 + 0.1188201010 0.1457290053 0.1240229011 + 0.1202287003 0.1474035978 0.1255117059 + 0.1216425970 0.1490814984 0.1270032972 + 0.1230617985 0.1507631987 0.1284980029 + 0.1244878024 0.1524486989 0.1299961060 + 0.1259191930 0.1541378051 0.1314983070 + 0.1273557991 0.1558293998 0.1330049038 + 0.1287976056 0.1575267017 0.1345154941 + 0.1302458048 0.1592278928 0.1360293031 + 0.1317003965 0.1609317958 0.1375454962 + 0.1331606060 0.1626382023 0.1390648037 + 0.1346260011 0.1643474996 0.1405864060 + 0.1360958070 0.1660612971 0.1421104968 + 0.1375721991 0.1677768975 0.1436379999 + 0.1390544027 0.1694948971 0.1451703012 + 0.1405413002 0.1712158024 0.1467055976 + 0.1420325041 0.1729404032 0.1482436061 + 0.1435298026 0.1746671945 0.1497846991 + 0.1450331062 0.1763962060 0.1513286978 + 0.1465408057 0.1781273931 0.1528747976 + 0.1480524987 0.1798599064 0.1544229984 + 0.1495707035 0.1815944016 0.1559745967 + 0.1510937959 0.1833305955 0.1575296074 + 0.1526214033 0.1850683987 0.1590874940 + 0.1541541964 0.1868094057 0.1606484950 + 0.1556929052 0.1885517985 0.1622128040 + 0.1572359949 0.1902959049 0.1637787968 + 0.1587835997 0.1920423061 0.1653465927 + 0.1603381932 0.1937911958 0.1669193059 + 0.1618963927 0.1955417991 0.1684942991 + 0.1634581983 0.1972939074 0.1700717062 + 0.1650260985 0.1990482062 0.1716526002 + 0.1665998995 0.2008040994 0.1732358932 + 0.1681773067 0.2025613040 0.1748213023 + 0.1697590947 0.2043205053 0.1764107943 + 0.1713462025 0.2060810030 0.1780031025 + 0.1729367971 0.2078423053 0.1795973927 + 0.1745319068 0.2096049935 0.1811943948 + 0.1761319935 0.2113689035 0.1827940941 + 0.1777352989 0.2131334990 0.1843959987 + 0.1793437004 0.2148993015 0.1860031039 + 0.1809576005 0.2166654021 0.1876126975 + 0.1825744063 0.2184319943 0.1892254949 + 0.1841952056 0.2201997042 0.1908413023 + 0.1858201027 0.2219685018 0.1924591959 + 0.1874478012 0.2237378955 0.1940806955 + 0.1890821010 0.2255074978 0.1957052946 + 0.1907189935 0.2272779942 0.1973316073 + 0.1923578978 0.2290489972 0.1989613026 + 0.1940028965 0.2308211029 0.2005929053 + 0.1956506073 0.2325938940 0.2022265941 + 0.1973026991 0.2343678027 0.2038643956 + 0.1989585012 0.2361426055 0.2055034935 + 0.2006161064 0.2379177958 0.2071447968 + 0.2022790015 0.2396938056 0.2087884992 + 0.2039445937 0.2414696068 0.2104344964 + 0.2056134939 0.2432450950 0.2120838016 + 0.2072867006 0.2450218946 0.2137342989 + 0.2089617997 0.2467985004 0.2153877020 + 0.2106418014 0.2485740930 0.2170425951 + 0.2123246044 0.2503491044 0.2186993957 + 0.2140112072 0.2521235943 0.2203588933 + 0.2157005966 0.2538985014 0.2220194936 + 0.2173911929 0.2556734085 0.2236841023 + 0.2190874964 0.2574481070 0.2253499031 + 0.2207852006 0.2592217922 0.2270195931 + 0.2224867046 0.2609946132 0.2286913991 + 0.2241905034 0.2627679110 0.2303657979 + 0.2258961946 0.2645412982 0.2320432961 + 0.2276054025 0.2663162053 0.2337222993 + 0.2293156981 0.2680906057 0.2354062945 + 0.2310317010 0.2698636949 0.2370913029 + 0.2327484041 0.2716363966 0.2387810051 + 0.2344674021 0.2734088004 0.2404720038 + 0.2361883968 0.2751807868 0.2421665043 + 0.2379122972 0.2769527137 0.2438628972 + 0.2396381944 0.2787235081 0.2455617040 + 0.2413652986 0.2804942131 0.2472631931 + 0.2430955023 0.2822644114 0.2489665002 + 0.2448267043 0.2840346992 0.2506738007 + 0.2465613037 0.2858053148 0.2523826063 + 0.2482964993 0.2875756919 0.2540957928 + 0.2500359118 0.2893457115 0.2558099031 + 0.2517758012 0.2911148965 0.2575285137 + 0.2535183132 0.2928834856 0.2592475116 + 0.2552621961 0.2946512997 0.2609696984 + 0.2570098937 0.2964186966 0.2626922131 + 0.2587589920 0.2981835902 0.2644180059 + 0.2605102956 0.2999480069 0.2661443055 + 0.2622630894 0.3017111123 0.2678734958 + 0.2640174031 0.3034740984 0.2696034908 + 0.2657730877 0.3052338064 0.2713379860 + 0.2675299048 0.3069935143 0.2730731964 + 0.2692880034 0.3087523878 0.2748118937 + 0.2710470855 0.3105109930 0.2765515149 + 0.2728081942 0.3122670054 0.2782951891 + 0.2745707035 0.3140225112 0.2800396085 + 0.2763350904 0.3157748878 0.2817870975 + 0.2781007886 0.3175269067 0.2835353911 + 0.2798672915 0.3192762136 0.2852882147 + 0.2816343009 0.3210250139 0.2870416045 + 0.2834017873 0.3227711022 0.2887994945 + 0.2851698101 0.3245170116 0.2905577123 + 0.2869389057 0.3262611926 0.2923206985 + 0.2887091935 0.3280051947 0.2940837145 + 0.2904804051 0.3297472894 0.2958520949 + 0.2922525108 0.3314892948 0.2976205945 + 0.2940253913 0.3332268000 0.2993935049 + 0.2957994938 0.3349643052 0.3011670113 + 0.2975736856 0.3366967142 0.3029440939 + 0.2993479967 0.3384287953 0.3047224879 + 0.3011221886 0.3401573896 0.3065038025 + 0.3028964102 0.3418853879 0.3082869947 + 0.3046706915 0.3436118066 0.3100728095 + 0.3064466119 0.3453375995 0.3118613958 + 0.3082225025 0.3470619917 0.3136520088 + 0.3099983037 0.3487856984 0.3154470026 + 0.3117741942 0.3505071998 0.3172427118 + 0.3135501146 0.3522264063 0.3190433085 + 0.3153258860 0.3539440036 0.3208439052 + 0.3171015978 0.3556582034 0.3226490021 + 0.3188770115 0.3573715091 0.3244544864 + 0.3206518888 0.3590804040 0.3262634873 + 0.3224261105 0.3607892990 0.3280740976 + 0.3241997957 0.3624913990 0.3298870027 + 0.3259718120 0.3641934097 0.3317027092 + 0.3277438879 0.3658939898 0.3335191905 + 0.3295131028 0.3675940931 0.3353388011 + 0.3312822878 0.3692927063 0.3371585011 + 0.3330504000 0.3709900975 0.3389824033 + 0.3348180056 0.3726865053 0.3408068120 + 0.3365843892 0.3743805885 0.3426336944 + 0.3383488953 0.3760747015 0.3444621861 + 0.3401131928 0.3777655959 0.3462921977 + 0.3418753147 0.3794564903 0.3481256962 + 0.3436372876 0.3811435997 0.3499591947 + 0.3453963101 0.3828293979 0.3517968059 + 0.3471544981 0.3845128119 0.3536345959 + 0.3489103913 0.3861933053 0.3554756045 + 0.3506639004 0.3878732026 0.3573186994 + 0.3524166942 0.3895485103 0.3591623902 + 0.3541651070 0.3912237883 0.3610084951 + 0.3559136093 0.3928934932 0.3628545105 + 0.3576560915 0.3945614994 0.3647046089 + 0.3593969047 0.3962261975 0.3665556014 + 0.3611347079 0.3978857994 0.3684079945 + 0.3628677130 0.3995453119 0.3702622950 + 0.3646006882 0.4011983871 0.3721165955 + 0.3663268089 0.4028514922 0.3739753067 + 0.3680528998 0.4045008123 0.3758341074 + 0.3697755039 0.4061478078 0.3776954114 + 0.3714954853 0.4077934027 0.3795588911 + 0.3732145131 0.4094338119 0.3814226985 + 0.3749260008 0.4110741019 0.3832913041 + 0.3766376078 0.4127109051 0.3851599097 + 0.3783437908 0.4143466055 0.3870306909 + 0.3800471127 0.4159803092 0.3889032900 + 0.3817487061 0.4176093936 0.3907761872 + 0.3834415078 0.4192385077 0.3926539123 + 0.3851343989 0.4208612144 0.3945316970 + 0.3868206143 0.4224824905 0.3964118063 + 0.3885033131 0.4241017103 0.3982942104 + 0.3901846111 0.4257161915 0.4001766145 + 0.3918552995 0.4273307025 0.4020617008 + 0.3935258985 0.4289397895 0.4039469957 + 0.3951900005 0.4305475056 0.4058333039 + 0.3968490958 0.4321533144 0.4077214003 + 0.3985081911 0.4337531030 0.4096095860 + 0.4001541138 0.4353528917 0.4114991128 + 0.4017998874 0.4369482994 0.4133890867 + 0.4034416974 0.4385415018 0.4152793884 + 0.4050774872 0.4401341975 0.4171707928 + 0.4067131877 0.4417211115 0.4190622866 + 0.4083409905 0.4433079958 0.4209538102 + 0.4099667072 0.4448912144 0.4228455126 + 0.4115909040 0.4464702904 0.4247371852 + 0.4132077098 0.4480494857 0.4266293049 + 0.4148243964 0.4496214092 0.4285216033 + 0.4164358974 0.4511919916 0.4304136932 + 0.4180422127 0.4527612031 0.4323050082 + 0.4196484983 0.4543245137 0.4341962934 + 0.4212470949 0.4558877945 0.4360859990 + 0.4228439927 0.4574449062 0.4379737973 + 0.4244396091 0.4589962959 0.4398615062 + 0.4260253906 0.4605476856 0.4417462945 + 0.4276112020 0.4620890021 0.4436298907 + 0.4291928113 0.4636281133 0.4455133975 + 0.4307680130 0.4651657939 0.4473905861 + 0.4323433042 0.4666922987 0.4492675066 + 0.4339112937 0.4682187140 0.4511435032 + 0.4354755878 0.4697411060 0.4530152977 + 0.4370399117 0.4712564051 0.4548870921 + 0.4385950863 0.4727717042 0.4567565024 + 0.4401490986 0.4742799997 0.4586217105 + 0.4417021871 0.4757837057 0.4604870081 + 0.4432457983 0.4772874117 0.4623486996 + 0.4447894096 0.4787816107 0.4642075896 + 0.4463303983 0.4802734852 0.4660665095 + 0.4478640854 0.4817655087 0.4679197073 + 0.4493978918 0.4832465053 0.4697704017 + 0.4509268105 0.4847275019 0.4716210961 + 0.4524492919 0.4862065911 0.4734647870 + 0.4539718032 0.4876767099 0.4753069878 + 0.4554879069 0.4891467094 0.4771490991 + 0.4569990933 0.4906134903 0.4789814949 + 0.4585103989 0.4920732081 0.4808132052 + 0.4600146115 0.4935329854 0.4826447070 + 0.4615156949 0.4949879050 0.4844656885 + 0.4630168080 0.4964365065 0.4862866998 + 0.4645102024 0.4978851080 0.4881069064 + 0.4660013914 0.4993262887 0.4899150133 + 0.4674926102 0.5007606745 0.4917230010 + 0.4689762890 0.5021951795 0.4935297966 + 0.4704585075 0.5036209226 0.4953246117 + 0.4719407856 0.5050408244 0.4971193969 + 0.4734140933 0.5064607263 0.4989126027 + 0.4748862982 0.5078724027 0.5006924868 + 0.4763585031 0.5092796087 0.5024725199 + 0.4778222144 0.5106868744 0.5042511225 + 0.4792849123 0.5120872855 0.5060155988 + 0.4807476103 0.5134844184 0.5077801943 + 0.4822027981 0.5148816109 0.5095440149 + 0.4836570024 0.5162711740 0.5112923980 + 0.4851112962 0.5176569819 0.5130407214 + 0.4865578115 0.5190427899 0.5147891045 + 0.4880031049 0.5204212070 0.5165216923 + 0.4894483984 0.5217952728 0.5182538033 + 0.4908877909 0.5231695175 0.5199859738 + 0.4923256934 0.5245352983 0.5217025876 + 0.4937636852 0.5258951783 0.5234171748 + 0.4951958060 0.5272551179 0.5251318216 + 0.4966256022 0.5286077261 0.5268319845 + 0.4980554879 0.5299531221 0.5285276771 + 0.4994794130 0.5312983990 0.5302234888 + 0.5008996129 0.5326380134 0.5319082141 + 0.5023198128 0.5339689255 0.5335860848 + 0.5037351847 0.5352998972 0.5352638960 + 0.5051453114 0.5366278887 0.5369331837 + 0.5065554976 0.5379484296 0.5385919213 + 0.5079630017 0.5392689109 0.5402505994 + 0.5093650222 0.5405880809 0.5419046879 + 0.5107669234 0.5418984890 0.5435451269 + 0.5121678710 0.5432088971 0.5451855063 + 0.5135623813 0.5445193052 0.5468252897 + 0.5149568915 0.5458185077 0.5484473109 + 0.5163514018 0.5471168756 0.5500692725 + 0.5177388787 0.5484153032 0.5516912937 + 0.5191257000 0.5497050881 0.5532999039 + 0.5205125213 0.5509917140 0.5549045801 + 0.5218951702 0.5522782803 0.5565093756 + 0.5232759118 0.5535587072 0.5581051707 + 0.5246565938 0.5548328757 0.5596920252 + 0.5260347128 0.5561071038 0.5612788200 + 0.5274087787 0.5573784113 0.5628618002 + 0.5287830234 0.5586404800 0.5644289255 + 0.5301563144 0.5599024892 0.5659958720 + 0.5315235257 0.5611644983 0.5675628781 + 0.5328906178 0.5624132752 0.5691115856 + 0.5342578292 0.5636613965 0.5706571937 + 0.5356180072 0.5649095178 0.5722029209 + 0.5369765162 0.5661481023 0.5737379193 + 0.5383349061 0.5673810840 0.5752621889 + 0.5396882296 0.5686141849 0.5767865181 + 0.5410351157 0.5698431134 0.5783087015 + 0.5423818827 0.5710616112 0.5798140168 + 0.5437278748 0.5722801089 0.5813193917 + 0.5450633168 0.5734986067 0.5828247070 + 0.5463985801 0.5747051239 0.5843166113 + 0.5477339029 0.5759106278 0.5858026743 + 0.5490639210 0.5771160126 0.5872887969 + 0.5503911972 0.5783153772 0.5887703896 + 0.5517184138 0.5795091987 0.5902382731 + 0.5530437827 0.5807030201 0.5917062759 + 0.5543630123 0.5818957090 0.5931742191 + 0.5556821823 0.5830773115 0.5946282744 + 0.5570014119 0.5842589140 0.5960785151 + 0.5583145022 0.5854403973 0.5975285769 + 0.5596256852 0.5866149068 0.5989735723 + 0.5609369278 0.5877853036 0.6004049778 + 0.5622456074 0.5889558196 0.6018365026 + 0.5635476112 0.5901247263 0.6032679081 + 0.5648496151 0.5912854075 0.6046854854 + 0.5661516786 0.5924460888 0.6060982943 + 0.5674464703 0.5936068296 0.6075112224 + 0.5687389970 0.5947598219 0.6089211702 + 0.5700315237 0.5959085226 0.6103187799 + 0.5713216066 0.5970572233 0.6117163897 + 0.5726023912 0.5982046723 0.6131139994 + 0.5738831758 0.5993419886 0.6145017743 + 0.5751640201 0.6004794240 0.6158828735 + 0.5764371753 0.6016166806 0.6172639728 + 0.5777059793 0.6027488708 0.6186450720 + 0.5789747834 0.6038765907 0.6200103164 + 0.5802434087 0.6050041914 0.6213750243 + 0.5815005898 0.6061319113 0.6227397919 + 0.5827577710 0.6072487235 0.6240993142 + 0.5840150714 0.6083645821 0.6254476905 + 0.5852677822 0.6094806194 0.6267961860 + 0.5865132213 0.6105933189 0.6281446218 + 0.5877586007 0.6116985083 0.6294825077 + 0.5890039802 0.6128035784 0.6308146119 + 0.5902428031 0.6139087081 0.6321465969 + 0.5914788842 0.6150081754 0.6334787011 + 0.5927150249 0.6161044836 0.6347957253 + 0.5939509869 0.6172006726 0.6361116171 + 0.5951772928 0.6182969809 0.6374276280 + 0.5964037180 0.6193832159 0.6387404799 + 0.5976300240 0.6204687953 0.6400408745 + 0.5988535881 0.6215543151 0.6413413882 + 0.6000704169 0.6226378083 0.6426417828 + 0.6012871861 0.6237139106 0.6439359188 + 0.6025038958 0.6247900128 0.6452212930 + 0.6037154794 0.6258659959 0.6465067267 + 0.6049222946 0.6269382238 0.6477921009 + 0.6061292291 0.6280059218 0.6490674019 + 0.6073359847 0.6290736794 0.6503365040 + 0.6085358262 0.6301413774 0.6516057253 + 0.6097332239 0.6311997175 0.6528748274 + 0.6109305024 0.6322535872 0.6541312933 + 0.6121277809 0.6333073974 0.6553844810 + 0.6133171916 0.6343613267 0.6566376090 + 0.6145057082 0.6354042292 0.6578906775 + 0.6156942844 0.6364452839 0.6591296792 + 0.6168823242 0.6374865174 0.6603674293 + 0.6180605888 0.6385275126 0.6616051793 + 0.6192389727 0.6395580769 0.6628425717 + 0.6204174161 0.6405887008 0.6640645266 + 0.6215937734 0.6416193247 0.6652863026 + 0.6227611899 0.6426482201 0.6665081978 + 0.6239284873 0.6436666846 0.6677287817 + 0.6250959039 0.6446852088 0.6689363122 + 0.6262605190 0.6457036138 0.6701437831 + 0.6274175048 0.6467195749 0.6713513136 + 0.6285744905 0.6477273107 0.6725571752 + 0.6297314763 0.6487351060 0.6737517118 + 0.6308856010 0.6497427821 0.6749461889 + 0.6320332289 0.6507480741 0.6761407256 + 0.6331807971 0.6517474055 0.6773335934 + 0.6343284249 0.6527466774 0.6785153151 + 0.6354721785 0.6537461281 0.6796969175 + 0.6366078854 0.6547424197 0.6808785796 + 0.6377437115 0.6557319760 0.6820589900 + 0.6388794184 0.6567215919 0.6832273006 + 0.6400116086 0.6577112079 0.6843956113 + 0.6411356926 0.6586982012 0.6855639219 + 0.6422597766 0.6596792936 0.6867318153 + 0.6433839202 0.6606603861 0.6878877878 + 0.6445053220 0.6616414785 0.6890437007 + 0.6456189752 0.6626203060 0.6901996732 + 0.6467326283 0.6635925174 0.6913555861 + 0.6478462815 0.6645647883 0.6925013065 + 0.6489577889 0.6655369997 0.6936463118 + 0.6500586867 0.6665074825 0.6947911978 + 0.6511597037 0.6674702168 0.6959362030 + 0.6522606015 0.6684328914 0.6970707774 + 0.6533609033 0.6693956256 0.6982029080 + 0.6544495821 0.6703575850 0.6993349791 + 0.6555382013 0.6713106036 0.7004671097 + 0.6566268206 0.6722635031 0.7015910149 + 0.6577154994 0.6732165217 0.7027103901 + 0.6587942839 0.6741694212 0.7038298249 + 0.6598721147 0.6751123071 0.7049492002 + 0.6609498858 0.6760544181 0.7060629129 + 0.6620277166 0.6769965291 0.7071694732 + 0.6630986929 0.6779385805 0.7082760930 + 0.6641669869 0.6788738966 0.7093827128 + 0.6652354002 0.6798070073 0.7104861736 + 0.6663036942 0.6807401180 0.7115777731 + 0.6673663259 0.6816732287 0.7126693726 + 0.6684231162 0.6826019287 0.7137609124 + 0.6694800258 0.6835269928 0.7148525119 + 0.6705368161 0.6844519973 0.7159308791 + 0.6715909839 0.6853770018 0.7170084119 + 0.6726369262 0.6862993240 0.7180858254 + 0.6736826897 0.6872149706 0.7191632986 + 0.6747285724 0.6881306171 0.7202311158 + 0.6757745147 0.6890463233 0.7212930918 + 0.6768103838 0.6899619102 0.7223551869 + 0.6778457165 0.6908699870 0.7234172225 + 0.6788811088 0.6917781234 0.7244750261 + 0.6799163818 0.6926862001 0.7255222797 + 0.6809443235 0.6935942769 0.7265697122 + 0.6819676161 0.6944952011 0.7276170254 + 0.6829909086 0.6953927279 0.7286642790 + 0.6840142012 0.6962900758 0.7296993136 + 0.6850343943 0.6971876025 0.7307329774 + 0.6860457063 0.6980822086 0.7317667007 + 0.6870568991 0.6989707947 0.7328004241 + 0.6880680919 0.6998593807 0.7338271141 + 0.6890792847 0.7007479072 0.7348465919 + 0.6900807023 0.7016364932 0.7358661294 + 0.6910803914 0.7025167942 0.7368856072 + 0.6920800805 0.7033964992 0.7379044890 + 0.6930798888 0.7042762041 0.7389112711 + 0.6940743923 0.7051559091 0.7399181128 + 0.6950619221 0.7060313225 0.7409247756 + 0.6960492730 0.7069025040 0.7419316173 + 0.6970368028 0.7077736855 0.7429320216 + 0.6980242133 0.7086449862 0.7439273000 + 0.6990013719 0.7095158100 0.7449225783 + 0.6999779940 0.7103791833 0.7459179163 + 0.7009546757 0.7112424970 0.7469127774 + 0.7019312978 0.7121058106 0.7478963733 + 0.7029024959 0.7129691243 0.7488800287 + 0.7038668990 0.7138271928 0.7498636246 + 0.7048313022 0.7146809101 0.7508472204 + 0.7057957053 0.7155346870 0.7518255115 + 0.7067601085 0.7163884044 0.7527979016 + 0.7077146769 0.7172421217 0.7537702918 + 0.7086681128 0.7180885077 0.7547428012 + 0.7096214890 0.7189350128 0.7557151914 + 0.7105749846 0.7197813988 0.7566773891 + 0.7115257978 0.7206279039 0.7576380968 + 0.7124705911 0.7214711905 0.7585988045 + 0.7134153843 0.7223104835 0.7595595121 + 0.7143602967 0.7231497169 0.7605171204 + 0.7153050900 0.7239890099 0.7614648938 + 0.7162432075 0.7248281837 0.7624126077 + 0.7171782255 0.7256616950 0.7633603811 + 0.7181131840 0.7264938951 0.7643082142 + 0.7190482020 0.7273260951 0.7652475238 + 0.7199829817 0.7281581759 0.7661802173 + 0.7209094167 0.7289890051 0.7671129107 + 0.7218356729 0.7298128009 0.7680456042 + 0.7227619886 0.7306365967 0.7689781785 + 0.7236883044 0.7314602733 0.7698999047 + 0.7246115804 0.7322841287 0.7708194852 + 0.7255285978 0.7331035137 0.7717391849 + 0.7264454961 0.7339180708 0.7726588249 + 0.7273623943 0.7347326875 0.7735773921 + 0.7282792926 0.7355474234 0.7744857073 + 0.7291893959 0.7363619804 0.7753940225 + 0.7300944924 0.7371708155 0.7763022780 + 0.7309995890 0.7379775047 0.7772104740 + 0.7319046855 0.7387843132 0.7781155109 + 0.7328097820 0.7395910025 0.7790126801 + 0.7337058783 0.7403978109 0.7799099088 + 0.7345998287 0.7411972284 0.7808070779 + 0.7354937196 0.7419964075 0.7817043066 + 0.7363876104 0.7427955866 0.7825965285 + 0.7372813821 0.7435948253 0.7834830880 + 0.7381641269 0.7443925738 0.7843697071 + 0.7390465736 0.7451831102 0.7852563262 + 0.7399291992 0.7459737062 0.7861428261 + 0.7408117056 0.7467643023 0.7870228291 + 0.7416930199 0.7475548983 0.7878980041 + 0.7425662875 0.7483425736 0.7887732983 + 0.7434394956 0.7491239905 0.7896485925 + 0.7443128228 0.7499054074 0.7905238867 + 0.7451859713 0.7506868243 0.7913916707 + 0.7460573912 0.7514681220 0.7922559977 + 0.7469223738 0.7522463202 0.7931203246 + 0.7477872968 0.7530199885 0.7939847112 + 0.7486522794 0.7537937164 0.7948489785 + 0.7495173216 0.7545673847 0.7957043052 + 0.7503795028 0.7553411126 0.7965561152 + 0.7512350082 0.7561119795 0.7974079251 + 0.7520905733 0.7568801045 0.7982596755 + 0.7529460788 0.7576481104 0.7991114855 + 0.7538017035 0.7584161758 0.7999551296 + 0.7546544075 0.7591843009 0.8007956147 + 0.7555009127 0.7599483728 0.8016362190 + 0.7563472986 0.7607088089 0.8024767041 + 0.7571938038 0.7614691854 0.8033173084 + 0.7580403090 0.7622296810 0.8041502237 + 0.7588834763 0.7629901171 0.8049796820 + 0.7597190142 0.7637473941 0.8058090806 + 0.7605543733 0.7645015717 0.8066385984 + 0.7613899112 0.7652558088 0.8074679971 + 0.7622252703 0.7660099864 0.8082910180 + 0.7630584836 0.7667642236 0.8091096282 + 0.7638840079 0.7675157189 0.8099281788 + 0.7647094131 0.7682638764 0.8107469082 + 0.7655348778 0.7690120935 0.8115655184 + 0.7663604021 0.7697603106 0.8123788834 + 0.7671846151 0.7705085278 0.8131868243 + 0.7680001259 0.7712538242 0.8139945865 + 0.7688155174 0.7719941139 0.8148024082 + 0.7696310282 0.7727344036 0.8156102896 + 0.7704464197 0.7734745741 0.8164144754 + 0.7712618113 0.7742149234 0.8172109723 + 0.7720686793 0.7749537230 0.8180075288 + 0.7728753090 0.7756870985 0.8188040257 + 0.7736818790 0.7764205933 0.8196005225 + 0.7744885087 0.7771540284 0.8203955889 + 0.7752950788 0.7778875232 0.8211801052 + 0.7760956287 0.7786207199 0.8219646215 + 0.7768943906 0.7793480754 0.8227490783 + 0.7776932120 0.7800753713 0.8235335946 + 0.7784920931 0.7808027864 0.8243181109 + 0.7792909145 0.7815300822 0.8250932097 + 0.7800844908 0.7822574973 0.8258666992 + 0.7808738947 0.7829779983 0.8266401887 + 0.7816631794 0.7836970091 0.8274136782 + 0.7824525833 0.7844160795 0.8281872272 + 0.7832419872 0.7851350904 0.8289542198 + 0.7840290070 0.7858542204 0.8297163248 + 0.7848097086 0.7865694761 0.8304784298 + 0.7855904102 0.7872818112 0.8312404752 + 0.7863711119 0.7879942060 0.8320025802 + 0.7871518135 0.7887064815 0.8327620029 + 0.7879325151 0.7894188166 0.8335124850 + 0.7887042761 0.7901296020 0.8342630267 + 0.7894756794 0.7908356786 0.8350133896 + 0.7902470231 0.7915416956 0.8357638717 + 0.7910184264 0.7922477126 0.8365142941 + 0.7917898297 0.7929537892 0.8372542858 + 0.7925562859 0.7936598063 0.8379924893 + 0.7933195829 0.7943586707 0.8387306929 + 0.7940828800 0.7950568199 0.8394688964 + 0.7948461771 0.7957547903 0.8402070999 + 0.7956094146 0.7964528203 0.8409410715 + 0.7963712811 0.7971509099 0.8416694999 + 0.7971267104 0.7978456020 0.8423978090 + 0.7978820801 0.7985368967 0.8431261182 + 0.7986375093 0.7992283106 0.8438544273 + 0.7993928790 0.7999196053 0.8445827961 + 0.8001483083 0.8006108999 0.8453016281 + 0.8008971810 0.8013020158 0.8460199237 + 0.8016437292 0.8019875288 0.8467382789 + 0.8023902178 0.8026731014 0.8474565744 + 0.8031367064 0.8033586144 0.8481749296 + 0.8038831949 0.8040441275 0.8488876224 + 0.8046274781 0.8047297001 0.8495929837 + 0.8053646088 0.8054109216 0.8502982855 + 0.8061016798 0.8060886264 0.8510035872 + 0.8068388104 0.8067662716 0.8517088890 + 0.8075758815 0.8074440956 0.8524143100 + 0.8083130121 0.8081218004 0.8531094790 + 0.8090445995 0.8087993860 0.8538032770 + 0.8097738028 0.8094710708 0.8544970751 + 0.8105030060 0.8101428747 0.8551908731 + 0.8112320900 0.8108146191 0.8558846712 + 0.8119612932 0.8114864230 0.8565754890 + 0.8126897216 0.8121581078 0.8572577834 + 0.8134108782 0.8128275275 0.8579400778 + 0.8141322136 0.8134937882 0.8586223722 + 0.8148534298 0.8141601086 0.8593047261 + 0.8155747056 0.8148264885 0.8599870801 + 0.8162959218 0.8154928088 0.8606625199 + 0.8170127273 0.8161591887 0.8613334894 + 0.8177244067 0.8168199062 0.8620045781 + 0.8184360266 0.8174793124 0.8626756072 + 0.8191475868 0.8181387782 0.8633465767 + 0.8198593259 0.8187981844 0.8640176058 + 0.8205708861 0.8194577098 0.8646782041 + 0.8212757707 0.8201162815 0.8653377891 + 0.8219788074 0.8207699060 0.8659973145 + 0.8226817846 0.8214235902 0.8666567802 + 0.8233848214 0.8220772147 0.8673163056 + 0.8240877986 0.8227308989 0.8679741025 + 0.8247904181 0.8233845234 0.8686218858 + 0.8254855275 0.8240357041 0.8692697287 + 0.8261805177 0.8246836066 0.8699175119 + 0.8268756270 0.8253313899 0.8705654144 + 0.8275706172 0.8259792924 0.8712131977 + 0.8282657266 0.8266270757 0.8718574047 + 0.8289580941 0.8272749782 0.8724951744 + 0.8296430111 0.8279188275 0.8731331229 + 0.8303279281 0.8285604715 0.8737708926 + 0.8310129046 0.8292021751 0.8744087219 + 0.8316978216 0.8298439980 0.8750464916 + 0.8323826790 0.8304857016 0.8756781816 + 0.8330640197 0.8311274052 0.8763042092 + 0.8337404132 0.8317648768 0.8769301176 + 0.8344169259 0.8324015141 0.8775560260 + 0.8350933194 0.8330382109 0.8781819940 + 0.8357697725 0.8336749077 0.8788079023 + 0.8364462256 0.8343114853 0.8794273734 + 0.8371186256 0.8349481821 0.8800430298 + 0.8377876878 0.8355782032 0.8806586266 + 0.8384569287 0.8362079859 0.8812742233 + 0.8391259909 0.8368378282 0.8818897009 + 0.8397951722 0.8374676704 0.8825052977 + 0.8404642940 0.8380975127 0.8831139207 + 0.8411294222 0.8387269974 0.8837190270 + 0.8417921066 0.8393514752 0.8843241930 + 0.8424547911 0.8399760127 0.8849294186 + 0.8431175947 0.8406004906 0.8855345249 + 0.8437802792 0.8412250876 0.8861396909 + 0.8444430232 0.8418496251 0.8867368102 + 0.8451002240 0.8424736261 0.8873301148 + 0.8457545042 0.8430926204 0.8879234195 + 0.8464089036 0.8437114954 0.8885167241 + 0.8470631838 0.8443304896 0.8891100287 + 0.8477175832 0.8449494839 0.8897033930 + 0.8483719230 0.8455684781 0.8902897239 + 0.8490217924 0.8461869955 0.8908721209 + 0.8496690989 0.8468005061 0.8914545178 + 0.8503165245 0.8474140167 0.8920369148 + 0.8509638906 0.8480275869 0.8926193118 + 0.8516113162 0.8486410975 0.8932017088 + 0.8522586823 0.8492546082 0.8937774897 + 0.8529011011 0.8498679996 0.8943479061 + 0.8535398841 0.8504769206 0.8949182034 + 0.8541787267 0.8510857821 0.8954886198 + 0.8548175097 0.8516947031 0.8960589767 + 0.8554562926 0.8523036242 0.8966292739 + 0.8560950756 0.8529124260 0.8971949220 + 0.8567304015 0.8535212874 0.8977534175 + 0.8573613763 0.8541247249 0.8983119130 + 0.8579922915 0.8547276258 0.8988704085 + 0.8586232066 0.8553304076 0.8994289041 + 0.8592541814 0.8559333086 0.8999875188 + 0.8598850965 0.8565362096 0.9005435705 + 0.8605139852 0.8571389914 0.9010909200 + 0.8611372113 0.8577383757 0.9016382098 + 0.8617604971 0.8583366275 0.9021854997 + 0.8623837829 0.8589348197 0.9027327895 + 0.8630070090 0.8595330119 0.9032800794 + 0.8636302948 0.8601312041 0.9038274288 + 0.8642532229 0.8607293963 0.9043639898 + 0.8648697734 0.8613250852 0.9049003124 + 0.8654863834 0.8619186878 0.9054365158 + 0.8661028743 0.8625122905 0.9059727192 + 0.8667194843 0.8631058931 0.9065089822 + 0.8673360944 0.8636994958 0.9070451856 + 0.8679525852 0.8642930984 0.9075742960 + 0.8685629964 0.8648849130 0.9080997705 + 0.8691716194 0.8654721975 0.9086254239 + 0.8697801828 0.8660594225 0.9091508985 + 0.8703888059 0.8666465878 0.9096763730 + 0.8709974289 0.8672338128 0.9102020264 + 0.8716059923 0.8678210974 0.9107244015 + 0.8722118735 0.8684083223 0.9112399817 + 0.8728144169 0.8689904809 0.9117556214 + 0.8734169006 0.8695725203 0.9122712016 + 0.8740193844 0.8701543808 0.9127867818 + 0.8746219277 0.8707364202 0.9133024216 + 0.8752244115 0.8713182807 0.9138180017 + 0.8758262992 0.8719003201 0.9143245220 + 0.8764201999 0.8724784851 0.9148302078 + 0.8770139813 0.8730542064 0.9153358936 + 0.8776078820 0.8736298084 0.9158415794 + 0.8782017827 0.8742055297 0.9163473248 + 0.8787956834 0.8747810721 0.9168530107 + 0.8793895245 0.8753566742 0.9173536897 + 0.8799785972 0.8759317994 0.9178488255 + 0.8805649877 0.8765037060 0.9183437824 + 0.8811513186 0.8770756721 0.9188389182 + 0.8817375898 0.8776475787 0.9193338752 + 0.8823239207 0.8782194853 0.9198290110 + 0.8829101920 0.8787915111 0.9203240275 + 0.8834956288 0.8793634176 0.9208073020 + 0.8840755820 0.8799321055 0.9212900996 + 0.8846555948 0.8804993033 0.9217727780 + 0.8852356076 0.8810665011 0.9222555757 + 0.8858155012 0.8816336989 0.9227383137 + 0.8863955140 0.8822008967 0.9232211113 + 0.8869755268 0.8827680945 0.9236993790 + 0.8875501156 0.8833345771 0.9241709113 + 0.8881211281 0.8838980198 0.9246425033 + 0.8886920810 0.8844614029 0.9251139760 + 0.8892630935 0.8850247264 0.9255855083 + 0.8898339868 0.8855881095 0.9260569811 + 0.8904049993 0.8861514926 0.9265285134 + 0.8909760118 0.8867148161 0.9269909859 + 0.8915405869 0.8872753978 0.9274508953 + 0.8921051025 0.8878340125 0.9279108047 + 0.8926696777 0.8883925080 0.9283707142 + 0.8932343125 0.8889510036 0.9288306236 + 0.8937988281 0.8895096183 0.9292904735 + 0.8943634033 0.8900681138 0.9297493100 + 0.8949252963 0.8906266093 0.9301987886 + 0.8954825997 0.8911815286 0.9306483269 + 0.8960399032 0.8917360902 0.9310978055 + 0.8965970874 0.8922907114 0.9315472841 + 0.8971543908 0.8928452730 0.9319968224 + 0.8977115750 0.8933998942 0.9324463010 + 0.8982688785 0.8939545751 0.9328917265 + 0.8988218904 0.8945080042 0.9333304167 + 0.8993726969 0.8950576782 0.9337691069 + 0.8999235034 0.8956074119 0.9342077971 + 0.9004741907 0.8961570859 0.9346464872 + 0.9010249972 0.8967068791 0.9350851774 + 0.9015758038 0.8972566128 0.9355239272 + 0.9021266103 0.8978062868 0.9359565973 + 0.9026709199 0.8983541131 0.9363852739 + 0.9032143950 0.8988997936 0.9368138909 + 0.9037579298 0.8994455934 0.9372426271 + 0.9043012857 0.8999912739 0.9376713037 + 0.9048448205 0.9005370736 0.9380999207 + 0.9053882957 0.9010828733 0.9385285974 + 0.9059311748 0.9016286135 0.9389498234 + 0.9064669013 0.9021710157 0.9393684864 + 0.9070025086 0.9027118087 0.9397872090 + 0.9075381160 0.9032527208 0.9402059913 + 0.9080737829 0.9037935138 0.9406247139 + 0.9086093903 0.9043343067 0.9410433769 + 0.9091449976 0.9048752189 0.9414622188 + 0.9096794724 0.9054160118 0.9418721199 + 0.9102091789 0.9059522748 0.9422804713 + 0.9107388258 0.9064875841 0.9426888824 + 0.9112684727 0.9070228934 0.9430974126 + 0.9117981791 0.9075582027 0.9435058236 + 0.9123278856 0.9080935121 0.9439141750 + 0.9128574729 0.9086288214 0.9443227053 + 0.9133856893 0.9091640115 0.9447216988 + 0.9139096141 0.9096950293 0.9451196194 + 0.9144334793 0.9102253914 0.9455175996 + 0.9149574041 0.9107558727 0.9459155798 + 0.9154813290 0.9112864137 0.9463135004 + 0.9160053134 0.9118168950 0.9467114806 + 0.9165291786 0.9123473763 0.9471095204 + 0.9170514941 0.9128779173 0.9474971890 + 0.9175698161 0.9134051800 0.9478837252 + 0.9180880785 0.9139323235 0.9482702017 + 0.9186064005 0.9144592881 0.9486566782 + 0.9191247225 0.9149863720 0.9490432143 + 0.9196429849 0.9155133963 0.9494296908 + 0.9201613069 0.9160404801 0.9498162270 + 0.9206780195 0.9165676236 0.9501945972 + 0.9211896062 0.9170905948 0.9505711794 + 0.9217011929 0.9176132083 0.9509478807 + 0.9222127795 0.9181358814 0.9513245225 + 0.9227244258 0.9186584949 0.9517011046 + 0.9232360721 0.9191811085 0.9520776868 + 0.9237477183 0.9197037220 0.9524543881 + 0.9242582917 0.9202262759 0.9528239965 + 0.9247623086 0.9207435846 0.9531905055 + 0.9252662063 0.9212597013 0.9535570741 + 0.9257702231 0.9217758179 0.9539235830 + 0.9262741804 0.9222918749 0.9542900920 + 0.9267780781 0.9228079915 0.9546567202 + 0.9272820950 0.9233241081 0.9550232291 + 0.9277861118 0.9238402247 0.9553844929 + 0.9282817841 0.9243530035 0.9557405710 + 0.9287772179 0.9248641133 0.9560965896 + 0.9292725921 0.9253752828 0.9564527273 + 0.9297680259 0.9258863926 0.9568088055 + 0.9302634001 0.9263976216 0.9571648836 + 0.9307587743 0.9269086719 0.9575210214 + 0.9312543273 0.9274199009 0.9578741193 + 0.9317451715 0.9279295206 0.9582188725 + 0.9322345853 0.9284372926 0.9585636258 + 0.9327239990 0.9289451241 0.9589083791 + 0.9332134724 0.9294528961 0.9592531919 + 0.9337028861 0.9299607277 0.9595978856 + 0.9341922998 0.9304684997 0.9599426985 + 0.9346817136 0.9309763908 0.9602873921 + 0.9351692200 0.9314835072 0.9606251121 + 0.9356545210 0.9319880009 0.9609624743 + 0.9361398220 0.9324923754 0.9612998962 + 0.9366251230 0.9329968095 0.9616371989 + 0.9371104240 0.9335011840 0.9619746208 + 0.9375957251 0.9340056181 0.9623119235 + 0.9380810261 0.9345099926 0.9626492858 + 0.9385657907 0.9350144267 0.9629824758 + 0.9390466809 0.9355158210 0.9633126855 + 0.9395276904 0.9360166192 0.9636428952 + 0.9400085807 0.9365174174 0.9639731050 + 0.9404894710 0.9370182157 0.9643033147 + 0.9409704804 0.9375190735 0.9646335244 + 0.9414513707 0.9380198717 0.9649637938 + 0.9419323206 0.9385207295 0.9652928710 + 0.9424098134 0.9390196800 0.9656162262 + 0.9428859949 0.9395166039 0.9659395218 + 0.9433621168 0.9400135279 0.9662628770 + 0.9438381791 0.9405103922 0.9665861726 + 0.9443143010 0.9410073757 0.9669095278 + 0.9447904825 0.9415042996 0.9672328234 + 0.9452666044 0.9420012236 0.9675561190 + 0.9457414746 0.9424980879 0.9678742886 + 0.9462127090 0.9429908991 0.9681897759 + 0.9466838837 0.9434838295 0.9685053229 + 0.9471551180 0.9439765811 0.9688206911 + 0.9476262927 0.9444695115 0.9691361785 + 0.9480975270 0.9449623227 0.9694517255 + 0.9485687017 0.9454551935 0.9697672129 + 0.9490398765 0.9459481239 0.9700819254 + 0.9495072961 0.9464387894 0.9703902006 + 0.9499732256 0.9469273090 0.9706984162 + 0.9504390955 0.9474158287 0.9710066915 + 0.9509050846 0.9479044080 0.9713149071 + 0.9513710141 0.9483929276 0.9716231823 + 0.9518368840 0.9488813877 0.9719315171 + 0.9523028135 0.9493700266 0.9722396731 + 0.9527680874 0.9498584867 0.9725440741 + 0.9532285929 0.9503428936 0.9728444219 + 0.9536892176 0.9508270025 0.9731448293 + 0.9541497827 0.9513109922 0.9734451175 + 0.9546102881 0.9517951012 0.9737455249 + 0.9550709128 0.9522790909 0.9740458727 + 0.9555314183 0.9527631998 0.9743462205 + 0.9559919834 0.9532471895 0.9746466279 + 0.9564499259 0.9537299275 0.9749407768 + 0.9569048285 0.9542092085 0.9752337933 + 0.9573596716 0.9546884894 0.9755266905 + 0.9578146935 0.9551678896 0.9758195877 + 0.9582695961 0.9556471705 0.9761124849 + 0.9587244987 0.9561265111 0.9764053822 + 0.9591794014 0.9566057920 0.9766982794 + 0.9596344233 0.9570850730 0.9769905806 + 0.9600849748 0.9575614929 0.9772747159 + 0.9605342150 0.9580358863 0.9775587916 + 0.9609832764 0.9585102797 0.9778429270 + 0.9614325166 0.9589846134 0.9781271219 + 0.9618816972 0.9594590068 0.9784111977 + 0.9623308778 0.9599334002 0.9786952734 + 0.9627801180 0.9604076743 0.9789794087 + 0.9632292986 0.9608821273 0.9792611003 + 0.9636726975 0.9613522291 0.9795362949 + 0.9641159773 0.9618213773 0.9798114896 + 0.9645593166 0.9622905850 0.9800866246 + 0.9650024772 0.9627596736 0.9803618193 + 0.9654458165 0.9632288814 0.9806370139 + 0.9658889771 0.9636980891 0.9809120893 + 0.9663323164 0.9641671777 0.9811872840 + 0.9667748213 0.9646363854 0.9814590812 + 0.9672120214 0.9651002288 0.9817258716 + 0.9676492214 0.9655638933 0.9819926023 + 0.9680864215 0.9660276175 0.9822592735 + 0.9685236216 0.9664912820 0.9825260043 + 0.9689608216 0.9669550061 0.9827927947 + 0.9693980217 0.9674186110 0.9830595255 + 0.9698352218 0.9678822756 0.9833261967 + 0.9702709913 0.9683455825 0.9835889935 + 0.9707019925 0.9688035250 0.9838470817 + 0.9711331129 0.9692615271 0.9841052890 + 0.9715641141 0.9697194099 0.9843633771 + 0.9719951153 0.9701772928 0.9846215248 + 0.9724261165 0.9706352949 0.9848796725 + 0.9728571177 0.9710931778 0.9851378202 + 0.9732881188 0.9715511799 0.9853959084 + 0.9737175703 0.9720084071 0.9856500030 + 0.9741421938 0.9724602103 0.9858992100 + 0.9745668173 0.9729120135 0.9861484170 + 0.9749915004 0.9733638167 0.9863975048 + 0.9754161239 0.9738156199 0.9866467118 + 0.9758406878 0.9742674232 0.9868959188 + 0.9762653112 0.9747192860 0.9871451259 + 0.9766899943 0.9751710892 0.9873942733 + 0.9771133065 0.9756222963 0.9876399040 + 0.9775314927 0.9760677218 0.9878798723 + 0.9779496789 0.9765130877 0.9881199002 + 0.9783678055 0.9769583941 0.9883599281 + 0.9787859917 0.9774038196 0.9885998964 + 0.9792041779 0.9778491855 0.9888399243 + 0.9796224236 0.9782946110 0.9890798926 + 0.9800404906 0.9787399769 0.9893199205 + 0.9804580808 0.9791854024 0.9895578027 + 0.9808694720 0.9796236753 0.9897894263 + 0.9812808037 0.9800621271 0.9900208712 + 0.9816921949 0.9805004001 0.9902524948 + 0.9821035862 0.9809387922 0.9904841185 + 0.9825149179 0.9813771248 0.9907156825 + 0.9829263091 0.9818153977 0.9909471869 + 0.9833377004 0.9822537899 0.9911788106 + 0.9837489724 0.9826921225 0.9914098978 + 0.9841541052 0.9831243157 0.9916322827 + 0.9845585823 0.9835553169 0.9918547273 + 0.9849629998 0.9839861989 0.9920771718 + 0.9853674769 0.9844172001 0.9922996163 + 0.9857718945 0.9848480821 0.9925220013 + 0.9861763716 0.9852790833 0.9927443862 + 0.9865807891 0.9857100248 0.9929667711 + 0.9869853258 0.9861410260 0.9931892157 + 0.9873846173 0.9865669012 0.9934051037 + 0.9877814054 0.9869893789 0.9936192036 + 0.9881781936 0.9874119759 0.9938333035 + 0.9885749817 0.9878345132 0.9940474033 + 0.9889718294 0.9882571101 0.9942615032 + 0.9893686175 0.9886797071 0.9944754839 + 0.9897654057 0.9891021848 0.9946895838 + 0.9901620746 0.9895247817 0.9949036837 + 0.9905560017 0.9899445772 0.9951136112 + 0.9909446836 0.9903581738 0.9953181148 + 0.9913333058 0.9907717705 0.9955226779 + 0.9917219281 0.9911854267 0.9957271814 + 0.9921104908 0.9915990233 0.9959316850 + 0.9924991727 0.9920125008 0.9961361885 + 0.9928877950 0.9924260974 0.9963408113 + 0.9932764173 0.9928396940 0.9965453148 + 0.9936649799 0.9932532907 0.9967495203 + 0.9940438867 0.9936568141 0.9969443083 + 0.9944224954 0.9940596223 0.9971390963 + 0.9948012233 0.9944624901 0.9973340034 + 0.9951797724 0.9948652983 0.9975287914 + 0.9955583811 0.9952681065 0.9977235794 + 0.9959369898 0.9956709146 0.9979184270 + 0.9963155985 0.9960737824 0.9981132150 + 0.9966943264 0.9964765906 0.9983080029 + 0.9970666766 0.9968733788 0.9984989166 + 0.9974333048 0.9972642064 0.9986864924 + 0.9977999926 0.9976549745 0.9988741875 + 0.9981666803 0.9980459213 0.9990618229 + 0.9985333085 0.9984366894 0.9992493987 + 0.9988999963 0.9988275170 0.9994370937 + 0.9992666841 0.9992182851 0.9996247292 + 0.9996333122 0.9996091723 0.9998124242 + 1.0000000000 1.0000000000 1.0000000000 +} diff --git a/rpplugins/color_correction/resources/film_luts_raw/agfa_agfacolor_futura_100.spi1d b/rpplugins/color_correction/resources/film_luts_raw/agfa_agfacolor_futura_100.spi1d new file mode 100644 index 0000000..348d8f1 --- /dev/null +++ b/rpplugins/color_correction/resources/film_luts_raw/agfa_agfacolor_futura_100.spi1d @@ -0,0 +1,1030 @@ +Version 1 +From 0.0 1.0 +Length 1024 +Components 3 +{ + 0.0000000000 0.0000000000 0.0000000000 + 0.0187414307 0.0199415907 0.0138841104 + 0.0330222212 0.0346524492 0.0255766194 + 0.0449542291 0.0472631715 0.0357697308 + 0.0556400903 0.0585798696 0.0450413786 + 0.0654912964 0.0689996779 0.0536506996 + 0.0747707486 0.0787579194 0.0617258511 + 0.0836306289 0.0879753232 0.0693477094 + 0.0921674594 0.0967618302 0.0766232982 + 0.1004453003 0.1051589996 0.0835988298 + 0.1085427999 0.1132052019 0.0902485028 + 0.1164767966 0.1209279969 0.0966249332 + 0.1242111027 0.1283497959 0.1027311981 + 0.1316560954 0.1354517043 0.1085847020 + 0.1387570053 0.1422473937 0.1142328009 + 0.1455107033 0.1487720013 0.1196969002 + 0.1519546062 0.1550467014 0.1249829978 + 0.1581331939 0.1611181051 0.1301161945 + 0.1640816927 0.1669937074 0.1350999027 + 0.1698216051 0.1726770997 0.1399576068 + 0.1753643006 0.1782052964 0.1447027028 + 0.1807104945 0.1835688949 0.1493282020 + 0.1858936995 0.1887871027 0.1538430005 + 0.1909191012 0.1938627958 0.1582642943 + 0.1958166957 0.1988143027 0.1625947952 + 0.2005814016 0.2036329061 0.1668373942 + 0.2052128017 0.2083510011 0.1709935963 + 0.2097522020 0.2129525989 0.1750802994 + 0.2141969949 0.2174569964 0.1790975928 + 0.2185294926 0.2218813002 0.1830428988 + 0.2227485031 0.2262317985 0.1869215071 + 0.2268646061 0.2304809988 0.1907352060 + 0.2308858931 0.2346275002 0.1944852024 + 0.2348421067 0.2386894971 0.1981807947 + 0.2387396991 0.2426760942 0.2018260062 + 0.2425788045 0.2466064990 0.2054218054 + 0.2463494986 0.2504898012 0.2089662999 + 0.2500706017 0.2543140054 0.2124685943 + 0.2537479997 0.2580659986 0.2159260958 + 0.2573781013 0.2617495954 0.2193453014 + 0.2609572113 0.2653856874 0.2227171957 + 0.2644815147 0.2689718008 0.2260479033 + 0.2679471076 0.2725043893 0.2293380946 + 0.2713502049 0.2759802938 0.2325894982 + 0.2746953070 0.2793953121 0.2358044982 + 0.2779825926 0.2827470899 0.2389748991 + 0.2812089920 0.2860386968 0.2421178967 + 0.2843785882 0.2892819047 0.2452265024 + 0.2875038087 0.2924897075 0.2482994944 + 0.2905904055 0.2956646979 0.2513419092 + 0.2936390042 0.2988075912 0.2543503046 + 0.2966530025 0.3019191027 0.2573288083 + 0.2996253073 0.3050011992 0.2602812052 + 0.3025568128 0.3080531061 0.2632032037 + 0.3054536879 0.3110767007 0.2660993040 + 0.3083193004 0.3140729070 0.2689616978 + 0.3111566007 0.3170422912 0.2717953026 + 0.3139680028 0.3199853003 0.2746086121 + 0.3167569935 0.3229024112 0.2773948908 + 0.3195263147 0.3257946074 0.2801466882 + 0.3222785890 0.3286626935 0.2828755975 + 0.3250167072 0.3315044045 0.2855885029 + 0.3277421892 0.3343142867 0.2882772982 + 0.3304488063 0.3370938897 0.2909384072 + 0.3331305087 0.3398444057 0.2935771048 + 0.3357870877 0.3425664902 0.2961899042 + 0.3384202123 0.3452622890 0.2987827063 + 0.3410323858 0.3479284048 0.3013578057 + 0.3436256051 0.3505629897 0.3039124906 + 0.3462015092 0.3531686962 0.3064478934 + 0.3487611115 0.3557462096 0.3089591861 + 0.3513003886 0.3582991958 0.3114418983 + 0.3538151979 0.3608300984 0.3139019012 + 0.3563049138 0.3633398116 0.3163512051 + 0.3587693870 0.3658294976 0.3187870085 + 0.3612132072 0.3682993948 0.3212068081 + 0.3636367023 0.3707447946 0.3236055970 + 0.3660412133 0.3731693029 0.3259812891 + 0.3684293032 0.3755750954 0.3283393085 + 0.3708001971 0.3779630959 0.3306787014 + 0.3731575906 0.3803366125 0.3330000043 + 0.3754999042 0.3826906979 0.3352980912 + 0.3778310120 0.3850283921 0.3375810087 + 0.3801496029 0.3873493969 0.3398480117 + 0.3824588060 0.3896577060 0.3421055973 + 0.3847584128 0.3919534981 0.3443531990 + 0.3870503008 0.3942336142 0.3465890884 + 0.3893356919 0.3964999914 0.3488120139 + 0.3916150033 0.3987481892 0.3510178924 + 0.3938865066 0.4009808004 0.3532077074 + 0.3961476088 0.4031977952 0.3553779125 + 0.3983986080 0.4054017067 0.3575282991 + 0.4006389976 0.4075945020 0.3596653938 + 0.4028654993 0.4097732902 0.3617888093 + 0.4050788879 0.4119321108 0.3638970852 + 0.4072808027 0.4140745103 0.3659907877 + 0.4094718099 0.4162018001 0.3680689037 + 0.4116508067 0.4183138907 0.3701283038 + 0.4138199985 0.4204131961 0.3721699119 + 0.4159773886 0.4225000143 0.3741934001 + 0.4181219041 0.4245725870 0.3761979938 + 0.4202522039 0.4266324937 0.3781862855 + 0.4223701060 0.4286797941 0.3801617920 + 0.4244759083 0.4307178855 0.3821251094 + 0.4265703857 0.4327476919 0.3840759993 + 0.4286541939 0.4347653985 0.3860141933 + 0.4307268858 0.4367690086 0.3879393041 + 0.4327893853 0.4387587011 0.3898504972 + 0.4348411858 0.4407365918 0.3917472959 + 0.4368841052 0.4427039027 0.3936302960 + 0.4389176071 0.4446617961 0.3954991102 + 0.4409425855 0.4466080964 0.3973535895 + 0.4429590106 0.4485442936 0.3991936147 + 0.4449672103 0.4504688084 0.4010188878 + 0.4469676912 0.4523817897 0.4028322101 + 0.4489580095 0.4542838037 0.4046368897 + 0.4509370923 0.4561766982 0.4064337909 + 0.4529055953 0.4580585063 0.4082230031 + 0.4548639059 0.4599294066 0.4100044966 + 0.4568125904 0.4617907107 0.4117785990 + 0.4587523937 0.4636436999 0.4135451913 + 0.4606837034 0.4654872119 0.4153045118 + 0.4626069963 0.4673207998 0.4170565009 + 0.4645206034 0.4691432118 0.4188013971 + 0.4664235115 0.4709551036 0.4205392003 + 0.4683176875 0.4727576971 0.4222700000 + 0.4702025950 0.4745520949 0.4239938855 + 0.4720798135 0.4763393104 0.4257110059 + 0.4739468098 0.4781185091 0.4274213910 + 0.4758000970 0.4798890054 0.4291251004 + 0.4776405096 0.4816485941 0.4308224022 + 0.4794681072 0.4833956063 0.4325130880 + 0.4812825918 0.4851314127 0.4341974854 + 0.4830833077 0.4868572056 0.4358755946 + 0.4848699868 0.4885736108 0.4375469983 + 0.4866446853 0.4902822077 0.4392102063 + 0.4884060025 0.4919806123 0.4408645928 + 0.4901559949 0.4936690032 0.4425103962 + 0.4918906093 0.4953497946 0.4441474974 + 0.4936125875 0.4970211089 0.4457770884 + 0.4953204989 0.4986830056 0.4473989010 + 0.4970144928 0.5003349185 0.4490132928 + 0.4986953139 0.5019772053 0.4506205916 + 0.5003637075 0.5036125779 0.4522204101 + 0.5020195842 0.5052385926 0.4538131952 + 0.5036631227 0.5068594813 0.4553956985 + 0.5052949190 0.5084728003 0.4569694102 + 0.5069147944 0.5100775957 0.4585345089 + 0.5085229874 0.5116732717 0.4600914121 + 0.5101199746 0.5132597089 0.4616405070 + 0.5117021203 0.5148342848 0.4631803036 + 0.5132743120 0.5164015293 0.4647122920 + 0.5148364902 0.5179616809 0.4662373960 + 0.5163900852 0.5195158124 0.4677560031 + 0.5179367065 0.5210649967 0.4692681134 + 0.5194708109 0.5226017237 0.4707722962 + 0.5209966898 0.5241310000 0.4722703099 + 0.5225142241 0.5256524086 0.4737617075 + 0.5240231752 0.5271654725 0.4752461910 + 0.5255233049 0.5286697149 0.4767219126 + 0.5270152092 0.5301663876 0.4781898856 + 0.5284978151 0.5316576958 0.4796513021 + 0.5299711823 0.5331442952 0.4811064899 + 0.5314347148 0.5346261263 0.4825553000 + 0.5328863859 0.5360969901 0.4839963913 + 0.5343297124 0.5375598073 0.4854325056 + 0.5357651711 0.5390148759 0.4868634939 + 0.5371924043 0.5404617190 0.4882858992 + 0.5386118293 0.5419015884 0.4897007942 + 0.5400264859 0.5433354974 0.4911100864 + 0.5414369702 0.5447630286 0.4925136864 + 0.5428367853 0.5461803079 0.4939090908 + 0.5442283750 0.5475915074 0.4952997863 + 0.5456125736 0.5489966869 0.4966861010 + 0.5469890237 0.5503935814 0.4980660975 + 0.5483577847 0.5517833829 0.4994400144 + 0.5497220755 0.5531684160 0.5008088946 + 0.5510820746 0.5545488000 0.5021709800 + 0.5524330139 0.5559220910 0.5035272837 + 0.5537772775 0.5572903156 0.5048794746 + 0.5551130772 0.5586516261 0.5062263012 + 0.5564405918 0.5600048900 0.5075680017 + 0.5577619076 0.5613521934 0.5089064837 + 0.5590745807 0.5626906157 0.5102406740 + 0.5603765249 0.5640223026 0.5115708113 + 0.5616722703 0.5653495193 0.5128980279 + 0.5629596710 0.5666700006 0.5142201185 + 0.5642386079 0.5679866076 0.5155370831 + 0.5655131936 0.5692998171 0.5168507099 + 0.5667812824 0.5706049204 0.5181574225 + 0.5680419207 0.5719022155 0.5194594264 + 0.5692980289 0.5731946230 0.5207582712 + 0.5705438852 0.5744786859 0.5220487118 + 0.5717846751 0.5757588148 0.5233348012 + 0.5730205774 0.5770344734 0.5246167183 + 0.5742480159 0.5783056021 0.5258914828 + 0.5754718184 0.5795726776 0.5271635056 + 0.5766893029 0.5808308721 0.5284305811 + 0.5778992176 0.5820825100 0.5296934247 + 0.5791049004 0.5833303928 0.5309540033 + 0.5802994967 0.5845699906 0.5322073102 + 0.5814914107 0.5858064890 0.5334576964 + 0.5826792121 0.5870373845 0.5347031951 + 0.5838587284 0.5882629156 0.5359424949 + 0.5850344896 0.5894858837 0.5371791124 + 0.5861983895 0.5906990170 0.5384079218 + 0.5873590708 0.5919092894 0.5396336913 + 0.5885140896 0.5931131840 0.5408535004 + 0.5896620154 0.5943115950 0.5420675278 + 0.5908060074 0.5955064297 0.5432779789 + 0.5919439793 0.5966913104 0.5444819927 + 0.5930796266 0.5978732705 0.5456839800 + 0.5942065120 0.5990452170 0.5468795896 + 0.5953297019 0.6002144217 0.5480728745 + 0.5964481235 0.6013793945 0.5492628813 + 0.5975626111 0.6025397182 0.5504478812 + 0.5986750126 0.6036971211 0.5516301990 + 0.5997776985 0.6048492789 0.5528064966 + 0.6008782983 0.6060000062 0.5539814234 + 0.6019700170 0.6071417928 0.5551493764 + 0.6030591130 0.6082807779 0.5563148260 + 0.6041415930 0.6094110012 0.5574722886 + 0.6052209735 0.6105381846 0.5586267710 + 0.6062965989 0.6116611958 0.5597772002 + 0.6073693037 0.6127799749 0.5609225035 + 0.6084402800 0.6138954759 0.5620642900 + 0.6095039845 0.6150087714 0.5632020831 + 0.6105654836 0.6161211729 0.5643385053 + 0.6116194725 0.6172274947 0.5654675961 + 0.6126726270 0.6183326840 0.5665956140 + 0.6137179732 0.6194270253 0.5677173734 + 0.6147624254 0.6205205917 0.5688384175 + 0.6157985926 0.6216076016 0.5699521899 + 0.6168330908 0.6226931810 0.5710644722 + 0.6178600788 0.6237692833 0.5721685290 + 0.6188859940 0.6248437166 0.5732709169 + 0.6199086905 0.6259111166 0.5743672848 + 0.6209291220 0.6269769073 0.5754616857 + 0.6219440103 0.6280378103 0.5765504241 + 0.6229550838 0.6290960908 0.5776373744 + 0.6239585876 0.6301478148 0.5787205100 + 0.6249598265 0.6311972737 0.5798012018 + 0.6259567142 0.6322420239 0.5808768868 + 0.6269508004 0.6332836747 0.5819506049 + 0.6279395223 0.6343185902 0.5830199718 + 0.6289266944 0.6353514194 0.5840864778 + 0.6299108863 0.6363787055 0.5851466060 + 0.6308935285 0.6374046803 0.5862044096 + 0.6318724751 0.6384266019 0.5872561932 + 0.6328493953 0.6394464970 0.5883064270 + 0.6338198781 0.6404585242 0.5893509984 + 0.6347895861 0.6414691806 0.5903946757 + 0.6357561946 0.6424723268 0.5914332867 + 0.6367220879 0.6434748769 0.5924714208 + 0.6376814246 0.6444696784 0.5935050249 + 0.6386405826 0.6454644799 0.5945385098 + 0.6395891905 0.6464499831 0.5955650806 + 0.6405377984 0.6474351883 0.5965915918 + 0.6414811015 0.6484122276 0.5976113081 + 0.6424236894 0.6493877172 0.5986298919 + 0.6433591843 0.6503596902 0.5996431708 + 0.6442922950 0.6513301134 0.6006544828 + 0.6452214122 0.6522970200 0.6016616821 + 0.6461476088 0.6532608867 0.6026659012 + 0.6470720768 0.6542214155 0.6036679745 + 0.6479939222 0.6551764011 0.6046671867 + 0.6489133239 0.6561300755 0.6056650281 + 0.6498240829 0.6570777893 0.6066576838 + 0.6507347226 0.6580253839 0.6076505184 + 0.6516370177 0.6589658856 0.6086354852 + 0.6525393128 0.6599062085 0.6096205115 + 0.6534368992 0.6608443856 0.6105999947 + 0.6543331146 0.6617819071 0.6115779877 + 0.6552255750 0.6627163291 0.6125519276 + 0.6561149955 0.6636475921 0.6135221124 + 0.6570025086 0.6645767093 0.6144911051 + 0.6578854918 0.6654986143 0.6154568195 + 0.6587684155 0.6664205790 0.6164224744 + 0.6596441269 0.6673378944 0.6173813939 + 0.6605197787 0.6682549715 0.6183400750 + 0.6613910794 0.6691666245 0.6192939878 + 0.6622604132 0.6700754762 0.6202455163 + 0.6631278992 0.6709814072 0.6211943030 + 0.6639922857 0.6718816757 0.6221385002 + 0.6648563147 0.6727818251 0.6230823994 + 0.6657119989 0.6736767888 0.6240196228 + 0.6665678024 0.6745718122 0.6249567270 + 0.6674181819 0.6754602790 0.6258906126 + 0.6682661772 0.6763452888 0.6268228889 + 0.6691122055 0.6772282124 0.6277527809 + 0.6699538231 0.6781055927 0.6286767125 + 0.6707953811 0.6789829731 0.6296005249 + 0.6716330051 0.6798558831 0.6305189133 + 0.6724700928 0.6807280779 0.6314365268 + 0.6733044982 0.6815952063 0.6323506832 + 0.6741359830 0.6824558973 0.6332612038 + 0.6749671102 0.6833165288 0.6341714263 + 0.6757913828 0.6841681004 0.6350759864 + 0.6766155958 0.6850196719 0.6359806061 + 0.6774365902 0.6858676076 0.6368827224 + 0.6782553792 0.6867125034 0.6377828121 + 0.6790735126 0.6875569224 0.6386821270 + 0.6798856854 0.6883959174 0.6395736933 + 0.6806979775 0.6892347932 0.6404653192 + 0.6815052032 0.6900711060 0.6413521171 + 0.6823093295 0.6909055114 0.6422356963 + 0.6831128001 0.6917393804 0.6431186795 + 0.6839104891 0.6925656199 0.6439942718 + 0.6847081780 0.6933919191 0.6448698044 + 0.6855018735 0.6942142844 0.6457418203 + 0.6862921715 0.6950333118 0.6466106772 + 0.6870825291 0.6958522201 0.6474797130 + 0.6878690720 0.6966655254 0.6483433247 + 0.6886556149 0.6974784732 0.6492068768 + 0.6894404888 0.6982899904 0.6500678062 + 0.6902230978 0.6990988851 0.6509246230 + 0.6910058260 0.6999077797 0.6517813802 + 0.6917819977 0.7007126808 0.6526325941 + 0.6925566792 0.7015163898 0.6534823179 + 0.6933307052 0.7023192048 0.6543310285 + 0.6941010952 0.7031159997 0.6551743746 + 0.6948714852 0.7039129138 0.6560177207 + 0.6956394911 0.7047072053 0.6568580866 + 0.6964054704 0.7054989934 0.6576957107 + 0.6971715093 0.7062907815 0.6585332751 + 0.6979302764 0.7070775032 0.6593660116 + 0.6986879110 0.7078630924 0.6601977944 + 0.6994447112 0.7086477280 0.6610285044 + 0.7001975179 0.7094256878 0.6618531942 + 0.7009503245 0.7102035880 0.6626778245 + 0.7017009258 0.7109789848 0.6634991765 + 0.7024487853 0.7117509246 0.6643164158 + 0.7031968236 0.7125229239 0.6651335955 + 0.7039384246 0.7132899761 0.6659477949 + 0.7046775222 0.7140548825 0.6667606831 + 0.7054166198 0.7148197889 0.6675736904 + 0.7061507106 0.7155792713 0.6683797836 + 0.7068846226 0.7163382769 0.6691855788 + 0.7076175213 0.7170966268 0.6699900031 + 0.7083460093 0.7178505063 0.6707876921 + 0.7090746164 0.7186043859 0.6715853810 + 0.7098006010 0.7193557024 0.6723811030 + 0.7105224729 0.7201020122 0.6731733084 + 0.7112444043 0.7208483219 0.6739653945 + 0.7119640112 0.7215924263 0.6747537851 + 0.7126817703 0.7223345041 0.6755387783 + 0.7133995891 0.7230767012 0.6763237715 + 0.7141135931 0.7238159776 0.6771062016 + 0.7148258090 0.7245538831 0.6778873205 + 0.7155380249 0.7252917290 0.6786683798 + 0.7162464857 0.7260233164 0.6794440746 + 0.7169541717 0.7267531157 0.6802182794 + 0.7176619172 0.7274829149 0.6809926033 + 0.7183669209 0.7282087207 0.6817620993 + 0.7190716863 0.7289338708 0.6825309992 + 0.7197765708 0.7296590209 0.6832998991 + 0.7204757929 0.7303797007 0.6840652823 + 0.7211748958 0.7311002016 0.6848304868 + 0.7218738794 0.7318205833 0.6855955124 + 0.7225683928 0.7325310707 0.6863517165 + 0.7232629061 0.7332416177 0.6871078014 + 0.7239571810 0.7339518070 0.6878635883 + 0.7246487141 0.7346547842 0.6886121035 + 0.7253403068 0.7353578210 0.6893606782 + 0.7260314226 0.7360606194 0.6901090145 + 0.7267171741 0.7367588282 0.6908516884 + 0.7274029255 0.7374569178 0.6915943027 + 0.7280883789 0.7381548882 0.6923367977 + 0.7287694812 0.7388454080 0.6930751204 + 0.7294505239 0.7395359278 0.6938133836 + 0.7301315069 0.7402263880 0.6945515871 + 0.7308093905 0.7409111261 0.6952871084 + 0.7314873934 0.7415956259 0.6960226297 + 0.7321652770 0.7422801256 0.6967579722 + 0.7328376770 0.7429602146 0.6974878907 + 0.7335097790 0.7436398268 0.6982172132 + 0.7341818213 0.7443194985 0.6989465952 + 0.7348498106 0.7449948192 0.6996716261 + 0.7355170250 0.7456691861 0.7003955841 + 0.7361841202 0.7463434935 0.7011196017 + 0.7368490100 0.7470148206 0.7018402219 + 0.7375128865 0.7476845980 0.7025592923 + 0.7381768227 0.7483543754 0.7032784224 + 0.7388374209 0.7490217090 0.7039942741 + 0.7394952774 0.7496867180 0.7047075033 + 0.7401531935 0.7503517270 0.7054206133 + 0.7408087254 0.7510150075 0.7061315775 + 0.7414602041 0.7516747713 0.7068389058 + 0.7421118021 0.7523347139 0.7075461149 + 0.7427623868 0.7529938221 0.7082526088 + 0.7434083819 0.7536479831 0.7089549899 + 0.7440543175 0.7543023229 0.7096574903 + 0.7447003126 0.7549564838 0.7103599906 + 0.7453430295 0.7556046247 0.7110564113 + 0.7459853888 0.7562519908 0.7117524743 + 0.7466279268 0.7568994761 0.7124484777 + 0.7472671270 0.7575436831 0.7131392956 + 0.7479048967 0.7581862807 0.7138277888 + 0.7485427260 0.7588288784 0.7145162225 + 0.7491782904 0.7594693899 0.7152029276 + 0.7498108149 0.7601066232 0.7158870101 + 0.7504433990 0.7607436776 0.7165712118 + 0.7510756254 0.7613803744 0.7172548175 + 0.7517048120 0.7620109916 0.7179335952 + 0.7523341179 0.7626414895 0.7186123133 + 0.7529633045 0.7632719874 0.7192909718 + 0.7535892129 0.7638990879 0.7199658751 + 0.7542141080 0.7645248771 0.7206395268 + 0.7548390031 0.7651507258 0.7213131785 + 0.7554618716 0.7657744884 0.7219849825 + 0.7560818791 0.7663950920 0.7226539254 + 0.7567018270 0.7670155764 0.7233228087 + 0.7573217154 0.7676361799 0.7239916921 + 0.7579385042 0.7682504058 0.7246547937 + 0.7585554123 0.7688643932 0.7253178954 + 0.7591722012 0.7694783807 0.7259808779 + 0.7597867250 0.7700899839 0.7266423702 + 0.7603995204 0.7706995010 0.7273027897 + 0.7610123158 0.7713090181 0.7279632092 + 0.7616242766 0.7719178796 0.7286229730 + 0.7622311115 0.7725210786 0.7292783856 + 0.7628380060 0.7731242776 0.7299337983 + 0.7634449005 0.7737274170 0.7305892110 + 0.7640485764 0.7743269205 0.7312399149 + 0.7646508217 0.7749242187 0.7318879962 + 0.7652528882 0.7755215168 0.7325360775 + 0.7658544779 0.7761185169 0.7331836224 + 0.7664529085 0.7767131925 0.7338275909 + 0.7670513988 0.7773079872 0.7344716191 + 0.7676498294 0.7779027224 0.7351155877 + 0.7682449222 0.7784941196 0.7357556820 + 0.7688378096 0.7790830731 0.7363932133 + 0.7694306970 0.7796722054 0.7370308042 + 0.7700235248 0.7802610993 0.7376680970 + 0.7706120014 0.7808436155 0.7383009791 + 0.7712004781 0.7814261913 0.7389338017 + 0.7717890739 0.7820088267 0.7395666242 + 0.7723761201 0.7825897932 0.7401980758 + 0.7729613185 0.7831684947 0.7408279777 + 0.7735465169 0.7837471962 0.7414578199 + 0.7741317749 0.7843258977 0.7420876026 + 0.7747126818 0.7849006057 0.7427113056 + 0.7752926946 0.7854743004 0.7433335781 + 0.7758728266 0.7860481143 0.7439559102 + 0.7764521241 0.7866209745 0.7445772886 + 0.7770282030 0.7871890068 0.7451937795 + 0.7776042223 0.7877569795 0.7458102703 + 0.7781801820 0.7883250117 0.7464267015 + 0.7787547708 0.7888916135 0.7470412850 + 0.7793279290 0.7894564271 0.7476536036 + 0.7799009085 0.7900211811 0.7482659817 + 0.7804740071 0.7905859947 0.7488783002 + 0.7810425162 0.7911475897 0.7494871020 + 0.7816095948 0.7917081714 0.7500947714 + 0.7821766734 0.7922688127 0.7507023811 + 0.7827436924 0.7928293943 0.7513099909 + 0.7833052278 0.7933837771 0.7519133091 + 0.7838668227 0.7939382195 0.7525165081 + 0.7844284177 0.7944926023 0.7531198263 + 0.7849892974 0.7950457931 0.7537218928 + 0.7855485082 0.7955945134 0.7543202043 + 0.7861077189 0.7961432934 0.7549185157 + 0.7866668105 0.7966920733 0.7555168867 + 0.7872235775 0.7972388268 0.7561128139 + 0.7877774239 0.7977824807 0.7567057014 + 0.7883312106 0.7983261943 0.7572985291 + 0.7888849974 0.7988699079 0.7578914165 + 0.7894352078 0.7994105816 0.7584812045 + 0.7899829745 0.7999492288 0.7590687871 + 0.7905306816 0.8004878163 0.7596564889 + 0.7910785079 0.8010262847 0.7602441907 + 0.7916234732 0.8015617132 0.7608277798 + 0.7921676040 0.8020955920 0.7614096999 + 0.7927116752 0.8026295900 0.7619916797 + 0.7932558060 0.8031635284 0.7625735998 + 0.7937961221 0.8036941886 0.7631514072 + 0.7943354845 0.8042240739 0.7637282014 + 0.7948749065 0.8047538996 0.7643049955 + 0.7954143286 0.8052837849 0.7648817897 + 0.7959489822 0.8058102131 0.7654550076 + 0.7964830995 0.8063359261 0.7660276294 + 0.7970170975 0.8068616986 0.7666001916 + 0.7975512147 0.8073874712 0.7671728134 + 0.7980824709 0.8079090118 0.7677428126 + 0.7986134887 0.8084300160 0.7683125138 + 0.7991445065 0.8089510202 0.7688822150 + 0.7996755242 0.8094719052 0.7694519162 + 0.8002029061 0.8099884987 0.7700183988 + 0.8007299900 0.8105044961 0.7705844045 + 0.8012570143 0.8110203743 0.7711504102 + 0.8017840981 0.8115363717 0.7717164755 + 0.8023071289 0.8120499849 0.7722783089 + 0.8028293848 0.8125631213 0.7728394866 + 0.8033518195 0.8130761981 0.7734007239 + 0.8038741946 0.8135892749 0.7739619017 + 0.8043946028 0.8140997291 0.7745202780 + 0.8049145937 0.8146092296 0.7750778794 + 0.8054345250 0.8151187897 0.7756354809 + 0.8059545159 0.8156284094 0.7761932015 + 0.8064721823 0.8161345720 0.7767478228 + 0.8069888949 0.8166393042 0.7773010731 + 0.8075056076 0.8171439767 0.7778543830 + 0.8080223203 0.8176487088 0.7784076929 + 0.8085361123 0.8181504011 0.7789580226 + 0.8090476990 0.8186495900 0.7795059085 + 0.8095592856 0.8191487789 0.7800536752 + 0.8100708723 0.8196480274 0.7806016207 + 0.8105810881 0.8201459050 0.7811478972 + 0.8110890985 0.8206415176 0.7816914916 + 0.8115971088 0.8211370707 0.7822352052 + 0.8121051788 0.8216326833 0.7827789187 + 0.8126127720 0.8221275210 0.7833216786 + 0.8131183982 0.8226181865 0.7838603854 + 0.8136240244 0.8231089115 0.7843990922 + 0.8141295910 0.8235995770 0.7849379182 + 0.8146352172 0.8240903020 0.7854766250 + 0.8151367903 0.8245751858 0.7860131264 + 0.8156381249 0.8250597119 0.7865493894 + 0.8161394000 0.8255441785 0.7870855927 + 0.8166406751 0.8260285854 0.7876219153 + 0.8171395063 0.8265116215 0.7881566286 + 0.8176370263 0.8269937038 0.7886903286 + 0.8181344867 0.8274759054 0.7892240882 + 0.8186320066 0.8279579878 0.7897579074 + 0.8191282749 0.8284389973 0.7902898192 + 0.8196223974 0.8289175034 0.7908182740 + 0.8201165795 0.8293960094 0.7913469076 + 0.8206107020 0.8298745155 0.7918754220 + 0.8211048245 0.8303530216 0.7924038768 + 0.8215956092 0.8308256269 0.7929295897 + 0.8220863938 0.8312981129 0.7934553027 + 0.8225771785 0.8317705989 0.7939808965 + 0.8230679035 0.8322430849 0.7945066094 + 0.8235569000 0.8327139020 0.7950305939 + 0.8240448236 0.8331835866 0.7955533862 + 0.8245326281 0.8336532116 0.7960761786 + 0.8250204921 0.8341228962 0.7965989709 + 0.8255078197 0.8345921040 0.7971209884 + 0.8259931803 0.8350595236 0.7976391912 + 0.8264786005 0.8355268240 0.7981575131 + 0.8269640207 0.8359941840 0.7986757159 + 0.8274493814 0.8364614844 0.7991939783 + 0.8279315829 0.8369246721 0.7997112274 + 0.8284127116 0.8373864293 0.8002278805 + 0.8288937807 0.8378480077 0.8007447124 + 0.8293749094 0.8383095860 0.8012614250 + 0.8298550248 0.8387699723 0.8017773032 + 0.8303318024 0.8392266035 0.8022907972 + 0.8308085799 0.8396831751 0.8028041720 + 0.8312854171 0.8401398063 0.8033176064 + 0.8317621946 0.8405963778 0.8038309813 + 0.8322365880 0.8410515785 0.8043408990 + 0.8327100277 0.8415061831 0.8048493266 + 0.8331834078 0.8419607878 0.8053576946 + 0.8336567879 0.8424153924 0.8058661222 + 0.8341296911 0.8428695202 0.8063743114 + 0.8345996737 0.8433197737 0.8068807125 + 0.8350697160 0.8437700868 0.8073871136 + 0.8355396986 0.8442202806 0.8078935146 + 0.8360096812 0.8446705937 0.8083999157 + 0.8364778757 0.8451184034 0.8089042902 + 0.8369445801 0.8455640078 0.8094068766 + 0.8374112248 0.8460094929 0.8099095225 + 0.8378779292 0.8464550972 0.8104121089 + 0.8383445144 0.8469007015 0.8109146953 + 0.8388080001 0.8473442197 0.8114140034 + 0.8392711878 0.8477873802 0.8119127750 + 0.8397343159 0.8482306004 0.8124117255 + 0.8401975036 0.8486738801 0.8129106164 + 0.8406596780 0.8491165042 0.8134090900 + 0.8411186934 0.8495569229 0.8139066100 + 0.8415778279 0.8499972224 0.8144040108 + 0.8420367837 0.8504375815 0.8149014711 + 0.8424957991 0.8508778811 0.8153988719 + 0.8429536819 0.8513162136 0.8158944249 + 0.8434103727 0.8517522812 0.8163877130 + 0.8438671231 0.8521882892 0.8168810010 + 0.8443238139 0.8526242971 0.8173742890 + 0.8447803855 0.8530603051 0.8178675771 + 0.8452352881 0.8534938097 0.8183590770 + 0.8456894159 0.8539261818 0.8188499212 + 0.8461434841 0.8543586731 0.8193408251 + 0.8465976715 0.8547911048 0.8198316097 + 0.8470517993 0.8552235961 0.8203225136 + 0.8475030065 0.8556535244 0.8208127022 + 0.8479539752 0.8560830951 0.8213027716 + 0.8484050035 0.8565127254 0.8217929006 + 0.8488559723 0.8569422960 0.8222830892 + 0.8493067026 0.8573716283 0.8227729201 + 0.8497545719 0.8577967286 0.8232586980 + 0.8502025008 0.8582218885 0.8237444758 + 0.8506504297 0.8586469889 0.8242303133 + 0.8510982990 0.8590722084 0.8247160912 + 0.8515453935 0.8594967723 0.8252013922 + 0.8519896269 0.8599187732 0.8256844878 + 0.8524339199 0.8603408933 0.8261677027 + 0.8528780937 0.8607628942 0.8266509175 + 0.8533223867 0.8611850142 0.8271340728 + 0.8537651896 0.8616067171 0.8276169896 + 0.8542045951 0.8620272875 0.8280991912 + 0.8546440005 0.8624479175 0.8285813928 + 0.8550834060 0.8628684878 0.8290637136 + 0.8555228114 0.8632891178 0.8295459151 + 0.8559610844 0.8637089133 0.8300266862 + 0.8563969135 0.8641266227 0.8305044770 + 0.8568326831 0.8645442724 0.8309822083 + 0.8572685122 0.8649619818 0.8314598799 + 0.8577042818 0.8653796911 0.8319376707 + 0.8581392765 0.8657960892 0.8324145079 + 0.8585724831 0.8662096262 0.8328894973 + 0.8590056896 0.8666229844 0.8333644271 + 0.8594390154 0.8670365214 0.8338394165 + 0.8598722219 0.8674498796 0.8343142867 + 0.8603044152 0.8678625226 0.8347889185 + 0.8607339263 0.8682723045 0.8352627158 + 0.8611633778 0.8686822057 0.8357365131 + 0.8615928888 0.8690921068 0.8362103105 + 0.8620223999 0.8695020080 0.8366839886 + 0.8624514937 0.8699113727 0.8371570110 + 0.8628783822 0.8703184128 0.8376260996 + 0.8633052707 0.8707253933 0.8380951881 + 0.8637322187 0.8711323142 0.8385642767 + 0.8641591072 0.8715392947 0.8390334249 + 0.8645859957 0.8719462156 0.8395023942 + 0.8650113940 0.8723505139 0.8399685025 + 0.8654367924 0.8727548122 0.8404346704 + 0.8658621907 0.8731591105 0.8409007788 + 0.8662877083 0.8735634089 0.8413670063 + 0.8667131066 0.8739677072 0.8418331146 + 0.8671352863 0.8743693829 0.8422979712 + 0.8675571084 0.8747707009 0.8427627087 + 0.8679788709 0.8751720190 0.8432275057 + 0.8684006929 0.8755732775 0.8436921835 + 0.8688225150 0.8759745955 0.8441569209 + 0.8692411780 0.8763734102 0.8446184993 + 0.8696581721 0.8767709136 0.8450784087 + 0.8700752854 0.8771684170 0.8455383182 + 0.8704923987 0.8775659204 0.8459982276 + 0.8709095120 0.8779633045 0.8464580774 + 0.8713259101 0.8783591986 0.8469166756 + 0.8717415929 0.8787525892 0.8473734260 + 0.8721572757 0.8791459799 0.8478301764 + 0.8725730181 0.8795393705 0.8482869267 + 0.8729887009 0.8799328208 0.8487436175 + 0.8734040856 0.8803259134 0.8492001295 + 0.8738173246 0.8807154894 0.8496552110 + 0.8742303848 0.8811051250 0.8501102924 + 0.8746436238 0.8814948201 0.8505653739 + 0.8750568032 0.8818843961 0.8510203958 + 0.8754699230 0.8822739720 0.8514754772 + 0.8758795857 0.8826612830 0.8519273996 + 0.8762881756 0.8830478191 0.8523783088 + 0.8766967058 0.8834341764 0.8528292179 + 0.8771052957 0.8838207126 0.8532801270 + 0.8775138855 0.8842071891 0.8537309766 + 0.8779212236 0.8845927715 0.8541811705 + 0.8783264160 0.8849766850 0.8546299934 + 0.8787316084 0.8853605986 0.8550788760 + 0.8791368008 0.8857445121 0.8555276990 + 0.8795419931 0.8861284852 0.8559765816 + 0.8799471855 0.8865123987 0.8564254045 + 0.8803501725 0.8868942857 0.8568723798 + 0.8807529807 0.8872759938 0.8573192954 + 0.8811559081 0.8876577020 0.8577662110 + 0.8815587163 0.8880394101 0.8582130075 + 0.8819615841 0.8884211183 0.8586599231 + 0.8823627830 0.8888016939 0.8591055274 + 0.8827620745 0.8891807795 0.8595495224 + 0.8831614256 0.8895599842 0.8599935174 + 0.8835607171 0.8899391294 0.8604375124 + 0.8839600086 0.8903182745 0.8608815074 + 0.8843594193 0.8906974196 0.8613255024 + 0.8847563863 0.8910734057 0.8617683053 + 0.8851532936 0.8914492130 0.8622109294 + 0.8855502009 0.8918249011 0.8626536131 + 0.8859471083 0.8922005892 0.8630962968 + 0.8863440156 0.8925762773 0.8635389805 + 0.8867403865 0.8929507732 0.8639808893 + 0.8871359229 0.8933228850 0.8644214272 + 0.8875315189 0.8936949968 0.8648619056 + 0.8879269958 0.8940669894 0.8653023839 + 0.8883224726 0.8944391012 0.8657429218 + 0.8887181282 0.8948112130 0.8661834002 + 0.8891111016 0.8951818943 0.8666223288 + 0.8895033002 0.8955522180 0.8670606017 + 0.8898953795 0.8959224224 0.8674988747 + 0.8902875781 0.8962926865 0.8679373264 + 0.8906797171 0.8966628909 0.8683755994 + 0.8910716176 0.8970329762 0.8688138723 + 0.8914600015 0.8974004984 0.8692520857 + 0.8918483853 0.8977680802 0.8696902990 + 0.8922368288 0.8981356025 0.8701285124 + 0.8926252127 0.8985031247 0.8705667257 + 0.8930135965 0.8988707066 0.8710048795 + 0.8934013844 0.8992366195 0.8714421988 + 0.8937880993 0.8995997906 0.8718780279 + 0.8941748738 0.8999629021 0.8723136783 + 0.8945615888 0.9003260732 0.8727493882 + 0.8949483037 0.9006891847 0.8731852174 + 0.8953350782 0.9010522962 0.8736209273 + 0.8957204819 0.9014136791 0.8740552068 + 0.8961051106 0.9017738104 0.8744884133 + 0.8964896798 0.9021338820 0.8749216795 + 0.8968743086 0.9024940729 0.8753550053 + 0.8972588778 0.9028542042 0.8757882714 + 0.8976435065 0.9032142758 0.8762215972 + 0.8980247974 0.9035729766 0.8766545057 + 0.8984053731 0.9039313197 0.8770872951 + 0.8987858891 0.9042896032 0.8775202036 + 0.8991664052 0.9046478868 0.8779529929 + 0.8995469809 0.9050061703 0.8783857822 + 0.8999274969 0.9053645134 0.8788185716 + 0.9003065825 0.9057202935 0.8792489171 + 0.9006856084 0.9060758948 0.8796789050 + 0.9010645747 0.9064316154 0.8801090121 + 0.9014436007 0.9067872167 0.8805390000 + 0.9018226862 0.9071428180 0.8809691072 + 0.9022015929 0.9074983001 0.8813989758 + 0.9025796056 0.9078509808 0.8818262815 + 0.9029576182 0.9082037210 0.8822537065 + 0.9033355713 0.9085562825 0.8826810122 + 0.9037135839 0.9089090228 0.8831083179 + 0.9040915966 0.9092617035 0.8835356236 + 0.9044691920 0.9096143246 0.8839628100 + 0.9048432708 0.9099658132 0.8843894005 + 0.9052175283 0.9103173018 0.8848158717 + 0.9055917263 0.9106687903 0.8852424026 + 0.9059658051 0.9110202789 0.8856688738 + 0.9063400030 0.9113718867 0.8860954046 + 0.9067137241 0.9117231965 0.8865216970 + 0.9070836902 0.9120727777 0.8869451284 + 0.9074537754 0.9124222994 0.8873686194 + 0.9078238010 0.9127718210 0.8877919912 + 0.9081938267 0.9131214023 0.8882154822 + 0.9085637927 0.9134709239 0.8886389732 + 0.9089336991 0.9138203263 0.8890622854 + 0.9093015790 0.9141662121 0.8894826770 + 0.9096695185 0.9145120978 0.8899031281 + 0.9100373983 0.9148579836 0.8903235197 + 0.9104052782 0.9152039289 0.8907439113 + 0.9107732177 0.9155496955 0.8911643028 + 0.9111409783 0.9158955812 0.8915846944 + 0.9115064740 0.9162393212 0.8920040727 + 0.9118716717 0.9165828228 0.8924233913 + 0.9122369885 0.9169263244 0.8928427100 + 0.9126023054 0.9172698259 0.8932620287 + 0.9129676223 0.9176133275 0.8936812282 + 0.9133328795 0.9179568291 0.8941004872 + 0.9136958122 0.9182993770 0.8945177794 + 0.9140580297 0.9186418056 0.8949344754 + 0.9144203067 0.9189841151 0.8953511715 + 0.9147825837 0.9193264842 0.8957679868 + 0.9151449203 0.9196687937 0.8961846828 + 0.9155071974 0.9200112224 0.8966013789 + 0.9158688188 0.9203519225 0.8970177174 + 0.9162300825 0.9206913710 0.8974336982 + 0.9165912867 0.9210308790 0.8978497982 + 0.9169526100 0.9213703871 0.8982657790 + 0.9173138142 0.9217098951 0.8986818790 + 0.9176750779 0.9220494032 0.8990979195 + 0.9180358052 0.9223874211 0.8995137215 + 0.9183956981 0.9227225184 0.8999291062 + 0.9187554717 0.9230574965 0.9003444910 + 0.9191153049 0.9233925939 0.9007598758 + 0.9194750786 0.9237275720 0.9011753201 + 0.9198349118 0.9240627289 0.9015907049 + 0.9201946259 0.9243977070 0.9020060897 + 0.9205502868 0.9247310162 0.9024195075 + 0.9209061265 0.9250643253 0.9028329253 + 0.9212617874 0.9253975749 0.9032462835 + 0.9216175079 0.9257308841 0.9036595821 + 0.9219732285 0.9260641932 0.9040730000 + 0.9223288894 0.9263975024 0.9044864178 + 0.9226825833 0.9267300963 0.9049000144 + 0.9230353236 0.9270622730 0.9053136706 + 0.9233880043 0.9273945093 0.9057273865 + 0.9237406850 0.9277268052 0.9061412215 + 0.9240934253 0.9280589819 0.9065548778 + 0.9244461060 0.9283912182 0.9069685936 + 0.9247984290 0.9287226796 0.9073820710 + 0.9251496196 0.9290521741 0.9077947140 + 0.9255006909 0.9293817282 0.9082072973 + 0.9258518219 0.9297111034 0.9086199999 + 0.9262030125 0.9300405979 0.9090325832 + 0.9265540838 0.9303699732 0.9094452858 + 0.9269052744 0.9306995273 0.9098579288 + 0.9272540808 0.9310278296 0.9102687240 + 0.9276024103 0.9313557148 0.9106789231 + 0.9279507995 0.9316835999 0.9110891223 + 0.9282991290 0.9320114851 0.9114993215 + 0.9286473989 0.9323393106 0.9119095206 + 0.9289957285 0.9326671958 0.9123197198 + 0.9293431044 0.9329950809 0.9127299190 + 0.9296882153 0.9333226085 0.9131399989 + 0.9300333858 0.9336500764 0.9135500789 + 0.9303784966 0.9339777231 0.9139602184 + 0.9307237267 0.9343051910 0.9143702984 + 0.9310687780 0.9346327782 0.9147803783 + 0.9314138889 0.9349603057 0.9151905179 + 0.9317582250 0.9352865219 0.9155995846 + 0.9321020246 0.9356120825 0.9160081744 + 0.9324458241 0.9359377027 0.9164168239 + 0.9327896833 0.9362632036 0.9168254733 + 0.9331334829 0.9365888238 0.9172341228 + 0.9334774017 0.9369143844 0.9176427126 + 0.9338210821 0.9372398257 0.9180511236 + 0.9341632128 0.9375618100 0.9184569716 + 0.9345054030 0.9378839135 0.9188628197 + 0.9348474741 0.9382058978 0.9192686081 + 0.9351897240 0.9385280013 0.9196743965 + 0.9355319142 0.9388499856 0.9200801849 + 0.9358739853 0.9391720891 0.9204859734 + 0.9362149835 0.9394931793 0.9208915830 + 0.9365543127 0.9398130178 0.9212968946 + 0.9368935823 0.9401326776 0.9217022061 + 0.9372329116 0.9404523969 0.9221073985 + 0.9375721216 0.9407721162 0.9225127101 + 0.9379113913 0.9410918951 0.9229180217 + 0.9382507205 0.9414116144 0.9233232737 + 0.9385885000 0.9417304993 0.9237279296 + 0.9389253855 0.9420490861 0.9241321087 + 0.9392623901 0.9423676133 0.9245362282 + 0.9395993948 0.9426862001 0.9249404073 + 0.9399363995 0.9430047274 0.9253445864 + 0.9402732849 0.9433231950 0.9257488251 + 0.9406102896 0.9436417818 0.9261528850 + 0.9409458041 0.9439579844 0.9265553951 + 0.9412810802 0.9442737103 0.9269576073 + 0.9416162968 0.9445894957 0.9273598194 + 0.9419515729 0.9449052811 0.9277619720 + 0.9422867894 0.9452211261 0.9281641841 + 0.9426221251 0.9455367923 0.9285663962 + 0.9429572821 0.9458525777 0.9289686084 + 0.9432895780 0.9461655021 0.9293698072 + 0.9436218739 0.9464783072 0.9297710061 + 0.9439542890 0.9467911720 0.9301720858 + 0.9442865849 0.9471039772 0.9305732846 + 0.9446190000 0.9474169016 0.9309744835 + 0.9449512959 0.9477298260 0.9313756824 + 0.9452832937 0.9480425119 0.9317768216 + 0.9456123710 0.9483544827 0.9321771860 + 0.9459415078 0.9486665130 0.9325776100 + 0.9462705851 0.9489784837 0.9329779148 + 0.9465997815 0.9492905140 0.9333782792 + 0.9469289184 0.9496024847 0.9337787032 + 0.9472579956 0.9499145150 0.9341790080 + 0.9475868940 0.9502264261 0.9345791936 + 0.9479146004 0.9505373836 0.9349784255 + 0.9482423067 0.9508484006 0.9353774786 + 0.9485700130 0.9511592984 0.9357767105 + 0.9488977194 0.9514703155 0.9361758232 + 0.9492254257 0.9517812729 0.9365749955 + 0.9495530128 0.9520921707 0.9369741082 + 0.9498804808 0.9524028897 0.9373731017 + 0.9502063990 0.9527112842 0.9377706051 + 0.9505323172 0.9530196786 0.9381682277 + 0.9508581758 0.9533280730 0.9385656714 + 0.9511839747 0.9536365271 0.9389632940 + 0.9515098929 0.9539449215 0.9393607974 + 0.9518358111 0.9542533755 0.9397584200 + 0.9521614909 0.9545617104 0.9401558042 + 0.9524834752 0.9548670053 0.9405503869 + 0.9528055191 0.9551724195 0.9409449100 + 0.9531275034 0.9554777741 0.9413394928 + 0.9534494281 0.9557831883 0.9417340159 + 0.9537714124 0.9560886025 0.9421285987 + 0.9540933967 0.9563940167 0.9425231218 + 0.9544153214 0.9566993117 0.9429177046 + 0.9547337890 0.9570021033 0.9433081746 + 0.9550518990 0.9573044777 0.9436982870 + 0.9553700089 0.9576069117 0.9440883994 + 0.9556879997 0.9579092860 0.9444785118 + 0.9560061097 0.9582117200 0.9448686242 + 0.9563242197 0.9585140944 0.9452586770 + 0.9566423297 0.9588165283 0.9456487894 + 0.9569590092 0.9591178298 0.9460378289 + 0.9572750926 0.9594184756 0.9464262128 + 0.9575912952 0.9597193003 0.9468145967 + 0.9579073787 0.9600200057 0.9472030997 + 0.9582235217 0.9603207707 0.9475914836 + 0.9585396051 0.9606214762 0.9479799271 + 0.9588558078 0.9609223008 0.9483683705 + 0.9591705203 0.9612216949 0.9487560987 + 0.9594833255 0.9615195990 0.9491428137 + 0.9597961903 0.9618173838 0.9495295882 + 0.9601091146 0.9621152878 0.9499164224 + 0.9604219198 0.9624130726 0.9503030777 + 0.9607347846 0.9627109766 0.9506899118 + 0.9610477090 0.9630088210 0.9510766864 + 0.9613602757 0.9633063078 0.9514631033 + 0.9616711140 0.9636015296 0.9518467784 + 0.9619820118 0.9638965726 0.9522305727 + 0.9622929096 0.9641916752 0.9526143074 + 0.9626036882 0.9644867778 0.9529979825 + 0.9629145861 0.9647819996 0.9533817768 + 0.9632254839 0.9650771022 0.9537655115 + 0.9635363817 0.9653722048 0.9541491866 + 0.9638459086 0.9656658769 0.9545314908 + 0.9641550183 0.9659590721 0.9549131989 + 0.9644640088 0.9662523866 0.9552949071 + 0.9647731185 0.9665455818 0.9556766152 + 0.9650822282 0.9668387771 0.9560583234 + 0.9653912783 0.9671319723 0.9564399719 + 0.9657003284 0.9674252272 0.9568217993 + 0.9660084844 0.9677178264 0.9572029114 + 0.9663146734 0.9680086970 0.9575825930 + 0.9666209221 0.9682996869 0.9579622746 + 0.9669271111 0.9685906768 0.9583420157 + 0.9672331810 0.9688816071 0.9587218165 + 0.9675394297 0.9691725969 0.9591014981 + 0.9678456187 0.9694635272 0.9594811797 + 0.9681518078 0.9697545171 0.9598609209 + 0.9684557915 0.9700437784 0.9602388740 + 0.9687592983 0.9703326225 0.9606165290 + 0.9690628052 0.9706214070 0.9609941244 + 0.9693661928 0.9709103107 0.9613717198 + 0.9696696997 0.9711990952 0.9617493153 + 0.9699732065 0.9714879990 0.9621269107 + 0.9702767134 0.9717767835 0.9625045061 + 0.9705796242 0.9720652103 0.9628816247 + 0.9708809853 0.9723523855 0.9632573724 + 0.9711824059 0.9726396203 0.9636331797 + 0.9714838266 0.9729267955 0.9640089273 + 0.9717851281 0.9732139707 0.9643846750 + 0.9720864892 0.9735012054 0.9647604227 + 0.9723879099 0.9737883806 0.9651361704 + 0.9726892710 0.9740756154 0.9655119181 + 0.9729892015 0.9743614793 0.9658862948 + 0.9732881188 0.9746463895 0.9662597179 + 0.9735869765 0.9749314189 0.9666332006 + 0.9738860130 0.9752163291 0.9670066237 + 0.9741848707 0.9755012989 0.9673801064 + 0.9744839072 0.9757863283 0.9677535295 + 0.9747828245 0.9760711789 0.9681270123 + 0.9750816822 0.9763562083 0.9685003757 + 0.9753785133 0.9766384959 0.9688717127 + 0.9756751060 0.9769206047 0.9692428708 + 0.9759716988 0.9772025943 0.9696140289 + 0.9762682915 0.9774847031 0.9699851871 + 0.9765648842 0.9777666926 0.9703562856 + 0.9768614173 0.9780488014 0.9707275033 + 0.9771580100 0.9783307910 0.9710986018 + 0.9774541855 0.9786124229 0.9714694023 + 0.9777483940 0.9788916707 0.9718384147 + 0.9780427217 0.9791710973 0.9722074270 + 0.9783368707 0.9794504046 0.9725763798 + 0.9786310792 0.9797297120 0.9729453921 + 0.9789252877 0.9800090194 0.9733144045 + 0.9792196155 0.9802883267 0.9736832976 + 0.9795138240 0.9805675745 0.9740523100 + 0.9798069000 0.9808459282 0.9744206071 + 0.9800981283 0.9811221957 0.9747872949 + 0.9803891778 0.9813985825 0.9751541018 + 0.9806804061 0.9816750288 0.9755209088 + 0.9809715152 0.9819512963 0.9758877158 + 0.9812626839 0.9822276831 0.9762545228 + 0.9815537930 0.9825041294 0.9766213298 + 0.9818450212 0.9827803969 0.9769880772 + 0.9821346998 0.9830551147 0.9773538113 + 0.9824227095 0.9833278060 0.9777181149 + 0.9827107191 0.9836006165 0.9780824780 + 0.9829987288 0.9838733077 0.9784469008 + 0.9832866788 0.9841461182 0.9788112044 + 0.9835746884 0.9844188094 0.9791756272 + 0.9838626981 0.9846916199 0.9795399904 + 0.9841507077 0.9849643111 0.9799042940 + 0.9844372869 0.9852353930 0.9802669287 + 0.9847224951 0.9855049849 0.9806277156 + 0.9850078225 0.9857745171 0.9809886217 + 0.9852930903 0.9860441089 0.9813495278 + 0.9855784178 0.9863135815 0.9817103148 + 0.9858636856 0.9865831733 0.9820712209 + 0.9861490130 0.9868527055 0.9824320078 + 0.9864342213 0.9871222973 0.9827929139 + 0.9867178798 0.9873905778 0.9831522703 + 0.9869999886 0.9876576066 0.9835103154 + 0.9872819781 0.9879245758 0.9838681817 + 0.9875640869 0.9881917238 0.9842262268 + 0.9878461957 0.9884586930 0.9845842123 + 0.9881281853 0.9887257218 0.9849420786 + 0.9884102941 0.9889926910 0.9853001237 + 0.9886924028 0.9892597795 0.9856579900 + 0.9889730811 0.9895253778 0.9860141873 + 0.9892522097 0.9897891879 0.9863678813 + 0.9895312190 0.9900529981 0.9867215753 + 0.9898102283 0.9903168082 0.9870752096 + 0.9900891781 0.9905806184 0.9874289036 + 0.9903681874 0.9908443093 0.9877825975 + 0.9906473160 0.9911081195 0.9881362915 + 0.9909263253 0.9913719296 0.9884899259 + 0.9912045002 0.9916349053 0.9888418913 + 0.9914805293 0.9918959737 0.9891892076 + 0.9917563796 0.9921571016 0.9895365238 + 0.9920324087 0.9924181104 0.9898838997 + 0.9923083782 0.9926791787 0.9902312160 + 0.9925844073 0.9929403067 0.9905784726 + 0.9928603768 0.9932013154 0.9909257889 + 0.9931364059 0.9934623837 0.9912732244 + 0.9934120178 0.9937232733 0.9916203022 + 0.9936820865 0.9939817786 0.9919636250 + 0.9939520955 0.9942402244 0.9923068881 + 0.9942222238 0.9944987297 0.9926502705 + 0.9944921732 0.9947571754 0.9929935932 + 0.9947623014 0.9950156212 0.9933369756 + 0.9950323105 0.9952741265 0.9936802983 + 0.9953023791 0.9955325723 0.9940236211 + 0.9955723882 0.9957910180 0.9943670034 + 0.9958366156 0.9960443974 0.9947049022 + 0.9960989952 0.9962962866 0.9950411916 + 0.9963614941 0.9965482950 0.9953776002 + 0.9966238737 0.9968001842 0.9957138896 + 0.9968863726 0.9970520735 0.9960501790 + 0.9971488714 0.9973040223 0.9963865876 + 0.9974113107 0.9975559115 0.9967228770 + 0.9976738095 0.9978078008 0.9970592260 + 0.9979344010 0.9980559945 0.9973912239 + 0.9981926084 0.9982990026 0.9977173209 + 0.9984508157 0.9985420108 0.9980434179 + 0.9987090230 0.9987850189 0.9983695149 + 0.9989671707 0.9990280271 0.9986956120 + 0.9992253780 0.9992709756 0.9990217090 + 0.9994835854 0.9995139837 0.9993478060 + 0.9997417927 0.9997569919 0.9996739030 + 1.0000000000 1.0000000000 1.0000000000 +} diff --git a/rpplugins/color_correction/resources/film_luts_raw/agfa_agfacolor_futura_200.spi1d b/rpplugins/color_correction/resources/film_luts_raw/agfa_agfacolor_futura_200.spi1d new file mode 100644 index 0000000..373a91e --- /dev/null +++ b/rpplugins/color_correction/resources/film_luts_raw/agfa_agfacolor_futura_200.spi1d @@ -0,0 +1,1030 @@ +Version 1 +From 0.0 1.0 +Length 1024 +Components 3 +{ + 0.0000000000 0.0000000000 0.0000000000 + 0.0190759301 0.0202765409 0.0141122499 + 0.0335491784 0.0352048501 0.0259871501 + 0.0456284918 0.0479410589 0.0363161191 + 0.0564305596 0.0593791306 0.0456890501 + 0.0664090514 0.0698935464 0.0543796085 + 0.0757837966 0.0797363967 0.0625370890 + 0.0847331807 0.0890476108 0.0702239573 + 0.0933608115 0.0979082435 0.0775574669 + 0.1017175987 0.1063619033 0.0845922306 + 0.1099015996 0.1144784987 0.0912967026 + 0.1179269999 0.1222776026 0.0977132320 + 0.1257234961 0.1297329068 0.1038620025 + 0.1332069039 0.1368501037 0.1097526997 + 0.1403385997 0.1436758041 0.1154337972 + 0.1471385062 0.1502327025 0.1209276021 + 0.1536355019 0.1565580070 0.1262387037 + 0.1598660052 0.1626631021 0.1313958019 + 0.1658526063 0.1685642004 0.1363987029 + 0.1715987027 0.1742689013 0.1412739009 + 0.1771457046 0.1798011959 0.1460293978 + 0.1825121045 0.1851902008 0.1506731957 + 0.1877036989 0.1904155016 0.1552059054 + 0.1927496940 0.1955112070 0.1596464962 + 0.1976590008 0.2004680932 0.1639927030 + 0.2024216950 0.2053215951 0.1682489067 + 0.2070800066 0.2100495994 0.1724233031 + 0.2116314024 0.2146542072 0.1765283942 + 0.2160694003 0.2191715986 0.1805596054 + 0.2203907967 0.2236115038 0.1845162958 + 0.2246263027 0.2279452980 0.1884078979 + 0.2287762016 0.2321790010 0.1922432035 + 0.2328651994 0.2363519073 0.1960130930 + 0.2368912995 0.2404530942 0.1997288018 + 0.2408396006 0.2444870025 0.2033921927 + 0.2446998060 0.2484596968 0.2069972008 + 0.2484990954 0.2523579001 0.2105585039 + 0.2522394061 0.2561706901 0.2140689939 + 0.2559157014 0.2599090934 0.2175384015 + 0.2595242858 0.2635894120 0.2209592015 + 0.2630606890 0.2672078013 0.2243333012 + 0.2665264904 0.2707605064 0.2276653051 + 0.2699350119 0.2742443085 0.2309532017 + 0.2732954025 0.2776700854 0.2342132032 + 0.2766172886 0.2810553908 0.2374293953 + 0.2799009979 0.2844128013 0.2406121045 + 0.2831490934 0.2877435088 0.2437624931 + 0.2863624096 0.2910458148 0.2468758970 + 0.2895404994 0.2943179011 0.2499558926 + 0.2926771045 0.2975485921 0.2530024946 + 0.2957693934 0.3007347882 0.2560170889 + 0.2988215983 0.3038783967 0.2590034902 + 0.3018361032 0.3069826961 0.2619606853 + 0.3048140109 0.3100473881 0.2648896873 + 0.3077591062 0.3130752146 0.2677848041 + 0.3106676936 0.3160668910 0.2706494033 + 0.3135369122 0.3190228045 0.2734929919 + 0.3163697124 0.3219431043 0.2763096094 + 0.3191707134 0.3248273134 0.2790902853 + 0.3219430149 0.3276773989 0.2818470001 + 0.3246892989 0.3305040896 0.2845870852 + 0.3274120092 0.3333109021 0.2873024046 + 0.3301134109 0.3360993862 0.2899892926 + 0.3327957988 0.3388687074 0.2926526964 + 0.3354612887 0.3416137993 0.2952902913 + 0.3381122947 0.3443362117 0.2979075015 + 0.3407450020 0.3470380008 0.3005059063 + 0.3433603942 0.3497211039 0.3030832112 + 0.3459551930 0.3523826003 0.3056401014 + 0.3485282063 0.3550176919 0.3081726134 + 0.3510803878 0.3576203883 0.3106764853 + 0.3536134064 0.3601945937 0.3131647110 + 0.3561300039 0.3627431095 0.3156422973 + 0.3586291075 0.3652668893 0.3181054890 + 0.3611052930 0.3677676916 0.3205488920 + 0.3635632992 0.3702487946 0.3229709864 + 0.3660041094 0.3727082908 0.3253682852 + 0.3684245944 0.3751434982 0.3277472854 + 0.3708260059 0.3775567114 0.3301078975 + 0.3732075989 0.3799484968 0.3324497938 + 0.3755733967 0.3823226094 0.3347747028 + 0.3779214025 0.3846783042 0.3370811045 + 0.3802560866 0.3870177865 0.3393734097 + 0.3825756013 0.3893364966 0.3416540921 + 0.3848834038 0.3916386962 0.3439235091 + 0.3871786892 0.3939253986 0.3461782932 + 0.3894636929 0.3961988091 0.3484173119 + 0.3917393088 0.3984617889 0.3506391943 + 0.3940058053 0.4007127881 0.3528397083 + 0.3962653875 0.4029492140 0.3550203145 + 0.3985182941 0.4051673114 0.3571819961 + 0.4007658064 0.4073692858 0.3593285978 + 0.4030055106 0.4095577896 0.3614608049 + 0.4052354097 0.4117330909 0.3635764122 + 0.4074552953 0.4138962030 0.3656741083 + 0.4096668959 0.4160450995 0.3677546084 + 0.4118706882 0.4181813896 0.3698169887 + 0.4140650928 0.4203011096 0.3718580902 + 0.4162524045 0.4224058986 0.3738800883 + 0.4184325933 0.4244979024 0.3758884072 + 0.4206056893 0.4265781939 0.3778842986 + 0.4227721095 0.4286450148 0.3798668981 + 0.4249303937 0.4306966066 0.3818354011 + 0.4270783961 0.4327369034 0.3837904930 + 0.4292162061 0.4347665906 0.3857319951 + 0.4313440025 0.4367870986 0.3876594007 + 0.4334617853 0.4388001859 0.3895725906 + 0.4355661869 0.4407989085 0.3914704919 + 0.4376563132 0.4427832961 0.3933526874 + 0.4397337139 0.4447549880 0.3952197134 + 0.4417980909 0.4467160106 0.3970730901 + 0.4438503087 0.4486671090 0.3989152014 + 0.4458903074 0.4506083131 0.4007458985 + 0.4479185045 0.4525383115 0.4025672972 + 0.4499352872 0.4544585049 0.4043807089 + 0.4519383013 0.4563668966 0.4061861932 + 0.4539265931 0.4582642913 0.4079838991 + 0.4559009075 0.4601486921 0.4097737968 + 0.4578616917 0.4620200992 0.4115560949 + 0.4598096013 0.4638800919 0.4133307934 + 0.4617452919 0.4657298028 0.4150981009 + 0.4636693895 0.4675683081 0.4168579876 + 0.4655824006 0.4693951011 0.4186106920 + 0.4674822092 0.4712128043 0.4203560948 + 0.4693683088 0.4730215073 0.4220944047 + 0.4712423086 0.4748198092 0.4238258004 + 0.4731037021 0.4766085148 0.4255501926 + 0.4749540985 0.4783886969 0.4272677004 + 0.4767911136 0.4801594913 0.4289785922 + 0.4786145985 0.4819203913 0.4306828082 + 0.4804255068 0.4836716056 0.4323804080 + 0.4822244942 0.4854123890 0.4340715110 + 0.4840112031 0.4871422946 0.4357562065 + 0.4857847989 0.4888612926 0.4374346137 + 0.4875457883 0.4905700088 0.4391067922 + 0.4892955124 0.4922698140 0.4407728910 + 0.4910339117 0.4939587116 0.4424329102 + 0.4927617908 0.4956364036 0.4440839887 + 0.4944767952 0.4973056912 0.4457261860 + 0.4961803854 0.4989677966 0.4473606944 + 0.4978719950 0.5006220937 0.4489873052 + 0.4995515049 0.5022668839 0.4506061971 + 0.5012195706 0.5039017200 0.4522179067 + 0.5028777719 0.5055288076 0.4538218975 + 0.5045251250 0.5071460009 0.4554184973 + 0.5061631799 0.5087574124 0.4570069015 + 0.5077912807 0.5103607774 0.4585888088 + 0.5094099045 0.5119572282 0.4601627886 + 0.5110192895 0.5135468245 0.4617280960 + 0.5126187801 0.5151286721 0.4632849991 + 0.5142037272 0.5166985989 0.4648320079 + 0.5157784224 0.5182607174 0.4663707018 + 0.5173432231 0.5198156238 0.4679018855 + 0.5188995004 0.5213642120 0.4694260061 + 0.5204483271 0.5229077935 0.4709433019 + 0.5219827294 0.5244423747 0.4724520147 + 0.5235059857 0.5259712934 0.4739539921 + 0.5250201821 0.5274928212 0.4754489958 + 0.5265259743 0.5290061235 0.4769366086 + 0.5280231833 0.5305104256 0.4784151018 + 0.5295122862 0.5320072174 0.4798853099 + 0.5309923887 0.5334973931 0.4813486040 + 0.5324633718 0.5349810123 0.4828054905 + 0.5339248180 0.5364567041 0.4842553139 + 0.5353744030 0.5379219055 0.4856970906 + 0.5368158221 0.5393791795 0.4871335924 + 0.5382496715 0.5408291221 0.4885646999 + 0.5396752954 0.5422707796 0.4899865091 + 0.5410915017 0.5437059999 0.4914005101 + 0.5425012708 0.5451353788 0.4928086102 + 0.5439049006 0.5465584993 0.4942106903 + 0.5452982187 0.5479696989 0.4956040084 + 0.5466837883 0.5493730903 0.4969924986 + 0.5480626225 0.5507693291 0.4983761907 + 0.5494338274 0.5521574020 0.4997530878 + 0.5507962704 0.5535387993 0.5011236072 + 0.5521531105 0.5549157858 0.5024887919 + 0.5535033941 0.5562884808 0.5038468242 + 0.5548453927 0.5576546192 0.5051984787 + 0.5561814904 0.5590159297 0.5065459013 + 0.5575097203 0.5603706837 0.5078874826 + 0.5588302016 0.5617178082 0.5092235804 + 0.5601449013 0.5630592704 0.5105562210 + 0.5614513755 0.5643923283 0.5118840933 + 0.5627481937 0.5657188892 0.5132076144 + 0.5640394092 0.5670406818 0.5145276785 + 0.5653225780 0.5683544874 0.5158423781 + 0.5665981770 0.5696623921 0.5171517730 + 0.5678697228 0.5709664226 0.5184581280 + 0.5691354275 0.5722628236 0.5197597146 + 0.5703939795 0.5735521913 0.5210576057 + 0.5716482997 0.5748370290 0.5223528743 + 0.5728936195 0.5761141777 0.5236395001 + 0.5741339922 0.5773866773 0.5249217153 + 0.5753698945 0.5786542892 0.5261995196 + 0.5765981078 0.5799149871 0.5274701118 + 0.5778229833 0.5811718106 0.5287377834 + 0.5790420771 0.5824205279 0.5300002098 + 0.5802537799 0.5836634040 0.5312584043 + 0.5814616084 0.5849028826 0.5325140953 + 0.5826593041 0.5861350894 0.5337622166 + 0.5838543773 0.5873640776 0.5350074172 + 0.5850455165 0.5885868073 0.5362474918 + 0.5862290263 0.5898029804 0.5374835134 + 0.5874090195 0.5910161138 0.5387175083 + 0.5885779858 0.5922204852 0.5399456024 + 0.5897439718 0.5934225917 0.5411707163 + 0.5909047127 0.5946190953 0.5423896909 + 0.5920587778 0.5958110094 0.5436031222 + 0.5932093859 0.5969995856 0.5448129773 + 0.5943543911 0.5981795192 0.5460162163 + 0.5954970121 0.5993567109 0.5472174883 + 0.5966315269 0.6005250812 0.5484123826 + 0.5977625847 0.6016913056 0.5496050715 + 0.5988891721 0.6028537154 0.5507941842 + 0.6000123024 0.6040124297 0.5519784093 + 0.6011335254 0.6051688194 0.5531598926 + 0.6022430062 0.6063209176 0.5543354154 + 0.6033499241 0.6074718833 0.5555096269 + 0.6044468284 0.6086149812 0.5566766262 + 0.6055412292 0.6097556949 0.5578411222 + 0.6066293716 0.6108884811 0.5589979887 + 0.6077128053 0.6120188832 0.5601516962 + 0.6087905169 0.6131458282 0.5613011718 + 0.6098622084 0.6142669916 0.5624457002 + 0.6109300256 0.6153838038 0.5635867715 + 0.6119914055 0.6164928079 0.5647237897 + 0.6130506992 0.6175984740 0.5658593178 + 0.6141037941 0.6186978221 0.5669875741 + 0.6151558757 0.6197956800 0.5681148171 + 0.6162015200 0.6208844185 0.5692356229 + 0.6172462106 0.6219723821 0.5703557730 + 0.6182832122 0.6230551004 0.5714685917 + 0.6193187833 0.6241365075 0.5725799799 + 0.6203479767 0.6252096891 0.5736833215 + 0.6213756204 0.6262813807 0.5747848749 + 0.6223981977 0.6273471713 0.5758804083 + 0.6234180927 0.6284117103 0.5769739151 + 0.6244314909 0.6294723749 0.5780618191 + 0.6254416108 0.6305295229 0.5791479945 + 0.6264446974 0.6315774918 0.5802301764 + 0.6274456978 0.6326224804 0.5813099742 + 0.6284427047 0.6336600184 0.5823848248 + 0.6294364929 0.6346951723 0.5834575295 + 0.6304243207 0.6357244849 0.5845260024 + 0.6314088106 0.6367521286 0.5855916739 + 0.6323868036 0.6377754211 0.5866507888 + 0.6333630085 0.6387977004 0.5877078176 + 0.6343346238 0.6398169994 0.5887587070 + 0.6353039742 0.6408346295 0.5898079872 + 0.6362662911 0.6418454051 0.5908517241 + 0.6372275949 0.6428552270 0.5918945074 + 0.6381838918 0.6438586712 0.5929322243 + 0.6391395926 0.6448618770 0.5939694047 + 0.6400895119 0.6458585262 0.5950021148 + 0.6410393715 0.6468551755 0.5960347056 + 0.6419798732 0.6478437781 0.5970602036 + 0.6429203153 0.6488320827 0.5980855227 + 0.6438559890 0.6498137116 0.5991042852 + 0.6447910070 0.6507939100 0.6001219749 + 0.6457198262 0.6517695189 0.6011344194 + 0.6466463208 0.6527429819 0.6021447182 + 0.6475692987 0.6537116170 0.6031510234 + 0.6484898925 0.6546760798 0.6041542292 + 0.6494089961 0.6556367874 0.6051554084 + 0.6503260732 0.6565908790 0.6061536074 + 0.6512408853 0.6575438976 0.6071500778 + 0.6521478295 0.6584920287 0.6081401706 + 0.6530545950 0.6594399810 0.6091303229 + 0.6539540291 0.6603807807 0.6101105809 + 0.6548532844 0.6613214016 0.6110907793 + 0.6557484865 0.6622567177 0.6120656133 + 0.6566426754 0.6631903052 0.6130387783 + 0.6575334072 0.6641204953 0.6140081286 + 0.6584212780 0.6650474072 0.6149740219 + 0.6593077183 0.6659724116 0.6159386039 + 0.6601902246 0.6668912768 0.6168997884 + 0.6610727906 0.6678102016 0.6178609729 + 0.6619489789 0.6687254906 0.6188141704 + 0.6628252268 0.6696406007 0.6197673082 + 0.6636962295 0.6705511212 0.6207141280 + 0.6645649076 0.6714593172 0.6216580272 + 0.6654312015 0.6723641157 0.6225993037 + 0.6662933826 0.6732622981 0.6235358715 + 0.6671553850 0.6741604805 0.6244724989 + 0.6680101156 0.6750528216 0.6254026294 + 0.6688649058 0.6759452224 0.6263327003 + 0.6697137952 0.6768317819 0.6272596717 + 0.6705600023 0.6777151823 0.6281852722 + 0.6714038253 0.6785969138 0.6291080713 + 0.6722424030 0.6794738173 0.6300241947 + 0.6730809212 0.6803507209 0.6309403181 + 0.6739163995 0.6812239885 0.6318492293 + 0.6747515202 0.6820967197 0.6327571273 + 0.6755837798 0.6829648018 0.6336619854 + 0.6764129996 0.6838271022 0.6345633268 + 0.6772418022 0.6846892834 0.6354644895 + 0.6780627966 0.6855434775 0.6363605261 + 0.6788836718 0.6863977909 0.6372565031 + 0.6797022223 0.6872488260 0.6381502748 + 0.6805189848 0.6880972981 0.6390423775 + 0.6813352108 0.6889454126 0.6399337053 + 0.6821470261 0.6897872090 0.6408177018 + 0.6829589009 0.6906291246 0.6417016983 + 0.6837666035 0.6914675236 0.6425812244 + 0.6845718026 0.6923034191 0.6434577703 + 0.6853765249 0.6931388974 0.6443338990 + 0.6861765981 0.6939678788 0.6452031136 + 0.6869766116 0.6947969794 0.6460722089 + 0.6877734065 0.6956220865 0.6469382048 + 0.6885675192 0.6964433789 0.6478012800 + 0.6893616915 0.6972646713 0.6486644149 + 0.6901482940 0.6980792880 0.6495230198 + 0.6909348965 0.6988936067 0.6503813863 + 0.6917189956 0.6997050047 0.6512373090 + 0.6924995184 0.7005112767 0.6520892978 + 0.6932801008 0.7013177276 0.6529412866 + 0.6940550804 0.7021173239 0.6537883878 + 0.6948289275 0.7029148936 0.6546339989 + 0.6956019998 0.7037113905 0.6554787755 + 0.6963722706 0.7045007944 0.6563187242 + 0.6971424818 0.7052903175 0.6571586132 + 0.6979110241 0.7060778737 0.6579942703 + 0.6986778975 0.7068635225 0.6588261724 + 0.6994447112 0.7076489925 0.6596580148 + 0.7002053261 0.7084293962 0.6604819894 + 0.7009649873 0.7092086077 0.6613044739 + 0.7017238736 0.7099866867 0.6621260047 + 0.7024794817 0.7107571959 0.6629421115 + 0.7032350898 0.7115277052 0.6637582183 + 0.7039889097 0.7122963071 0.6645715833 + 0.7047405839 0.7130622268 0.6653813124 + 0.7054923177 0.7138280869 0.6661911011 + 0.7062383890 0.7145891786 0.6669985056 + 0.7069823742 0.7153481245 0.6678047180 + 0.7077264190 0.7161070108 0.6686109900 + 0.7084659934 0.7168573141 0.6694114208 + 0.7092055082 0.7176067829 0.6702113748 + 0.7099441886 0.7183555961 0.6710103154 + 0.7106792927 0.7190998197 0.6718034148 + 0.7114142776 0.7198439837 0.6725963950 + 0.7121458054 0.7205855846 0.6733878255 + 0.7128710747 0.7213221788 0.6741760969 + 0.7135964036 0.7220587134 0.6749644876 + 0.7143177986 0.7227926850 0.6757488847 + 0.7150359154 0.7235242128 0.6765298843 + 0.7157539725 0.7242556214 0.6773108244 + 0.7164688706 0.7249854207 0.6780883074 + 0.7171823978 0.7257142067 0.6788641214 + 0.7178958058 0.7264429927 0.6796398163 + 0.7186031938 0.7271656990 0.6804109812 + 0.7193090916 0.7278866172 0.6811808944 + 0.7200149894 0.7286074758 0.6819508076 + 0.7207157016 0.7293236852 0.6827170253 + 0.7214158773 0.7300391793 0.6834827065 + 0.7221161127 0.7307546735 0.6842483878 + 0.7228116989 0.7314674258 0.6850115061 + 0.7235072255 0.7321798801 0.6857745051 + 0.7242025733 0.7328923941 0.6865373254 + 0.7248927951 0.7335966825 0.6872922182 + 0.7255830169 0.7343010902 0.6880471110 + 0.7262728810 0.7350053191 0.6888017058 + 0.7269589901 0.7357040048 0.6895499825 + 0.7276450992 0.7364026904 0.6902983785 + 0.7283307910 0.7371011972 0.6910464764 + 0.7290124297 0.7377966046 0.6917898059 + 0.7296938896 0.7384920120 0.6925331950 + 0.7303751707 0.7391871810 0.6932764053 + 0.7310516238 0.7398741841 0.6940135956 + 0.7317278981 0.7405611873 0.6947507858 + 0.7324042916 0.7412481904 0.6954879761 + 0.7330766916 0.7419282198 0.6962195039 + 0.7337490916 0.7426078916 0.6969509721 + 0.7344214916 0.7432876229 0.6976823807 + 0.7350897193 0.7439622879 0.6984075904 + 0.7357577085 0.7446364164 0.6991322041 + 0.7364255786 0.7453106046 0.6998566985 + 0.7370892763 0.7459799051 0.7005770206 + 0.7377521992 0.7466480136 0.7012962103 + 0.7384151220 0.7473161221 0.7020155191 + 0.7390751839 0.7479804158 0.7027320862 + 0.7397342920 0.7486426830 0.7034475207 + 0.7403932810 0.7493051291 0.7041630149 + 0.7410498261 0.7499645948 0.7048757076 + 0.7417044044 0.7506214976 0.7055861950 + 0.7423589826 0.7512784004 0.7062966228 + 0.7430117130 0.7519339919 0.7070053816 + 0.7436612844 0.7525870800 0.7077112794 + 0.7443109155 0.7532402277 0.7084171772 + 0.7449595928 0.7538927794 0.7091221809 + 0.7456040978 0.7545416951 0.7098222971 + 0.7462486029 0.7551906109 0.7105224729 + 0.7468931079 0.7558395267 0.7112227082 + 0.7475314736 0.7564836144 0.7119165063 + 0.7481697202 0.7571272850 0.7126098871 + 0.7488077879 0.7577710152 0.7133032084 + 0.7494426966 0.7584123015 0.7139921784 + 0.7500761151 0.7590525150 0.7146791220 + 0.7507095933 0.7596926093 0.7153660059 + 0.7513409257 0.7603306770 0.7160515785 + 0.7519693971 0.7609655261 0.7167350054 + 0.7525979280 0.7616001964 0.7174183130 + 0.7532256842 0.7622345090 0.7181012034 + 0.7538480163 0.7628622055 0.7187789083 + 0.7544702888 0.7634899020 0.7194564939 + 0.7550926208 0.7641175985 0.7201341987 + 0.7557113767 0.7647429705 0.7208058834 + 0.7563291788 0.7653676867 0.7214756012 + 0.7569469213 0.7659922838 0.7221453786 + 0.7575628161 0.7666150928 0.7228131890 + 0.7581757903 0.7672348022 0.7234779000 + 0.7587887049 0.7678545117 0.7241426110 + 0.7594016790 0.7684742212 0.7248072028 + 0.7600086927 0.7690863013 0.7254648209 + 0.7606157064 0.7696982026 0.7261223197 + 0.7612227201 0.7703102231 0.7267798185 + 0.7618271708 0.7709196210 0.7274342179 + 0.7624298930 0.7715268731 0.7280861735 + 0.7630326152 0.7721343040 0.7287383080 + 0.7636346817 0.7727413177 0.7293899059 + 0.7642328143 0.7733443975 0.7300382853 + 0.7648310065 0.7739474177 0.7306867242 + 0.7654290795 0.7745504975 0.7313351035 + 0.7660248876 0.7751491070 0.7319790125 + 0.7666196227 0.7757449746 0.7326202989 + 0.7672141790 0.7763409019 0.7332617044 + 0.7678084970 0.7769364119 0.7339023948 + 0.7684006095 0.7775282860 0.7345390916 + 0.7689927816 0.7781202197 0.7351757288 + 0.7695848942 0.7787120938 0.7358123064 + 0.7701737285 0.7793018818 0.7364459038 + 0.7707604170 0.7798901200 0.7370774150 + 0.7713471055 0.7804782987 0.7377089858 + 0.7719334960 0.7810664773 0.7383404970 + 0.7725152969 0.7816480994 0.7389686704 + 0.7730969787 0.7822297812 0.7395969033 + 0.7736787200 0.7828114033 0.7402251959 + 0.7742595077 0.7833915949 0.7408527136 + 0.7748392820 0.7839698792 0.7414792776 + 0.7754191160 0.7845481038 0.7421059012 + 0.7759987712 0.7851263285 0.7427325845 + 0.7765746117 0.7857019901 0.7433542013 + 0.7771494985 0.7862771749 0.7439746261 + 0.7777243853 0.7868523002 0.7445951104 + 0.7782984972 0.7874264121 0.7452148199 + 0.7788689733 0.7879943252 0.7458307743 + 0.7794395089 0.7885621190 0.7464467883 + 0.7800099254 0.7891299725 0.7470628023 + 0.7805796862 0.7896950841 0.7476773858 + 0.7811487913 0.7902569175 0.7482905984 + 0.7817177773 0.7908186913 0.7489038110 + 0.7822868824 0.7913805246 0.7495170236 + 0.7828525901 0.7919393182 0.7501246929 + 0.7834174037 0.7924969792 0.7507306933 + 0.7839820981 0.7930546999 0.7513365746 + 0.7845466733 0.7936124206 0.7519425154 + 0.7851064205 0.7941638231 0.7525429130 + 0.7856659889 0.7947151065 0.7531433105 + 0.7862256169 0.7952665091 0.7537437081 + 0.7867845893 0.7958167791 0.7543430924 + 0.7873414755 0.7963629961 0.7549396157 + 0.7878984809 0.7969092727 0.7555360198 + 0.7884554267 0.7974554896 0.7561324835 + 0.7890108228 0.7980003953 0.7567269802 + 0.7895640731 0.7985432744 0.7573187947 + 0.7901175022 0.7990862727 0.7579106092 + 0.7906708121 0.7996292114 0.7585024834 + 0.7912214994 0.8001691103 0.7590919137 + 0.7917703986 0.8007066250 0.7596797943 + 0.7923192978 0.8012441993 0.7602676153 + 0.7928681970 0.8017817140 0.7608553767 + 0.7934157252 0.8023154140 0.7614399195 + 0.7939624786 0.8028475046 0.7620229721 + 0.7945094109 0.8033794761 0.7626060843 + 0.7950562239 0.8039115071 0.7631891966 + 0.7956007123 0.8044400811 0.7637678981 + 0.7961447239 0.8049678206 0.7643455863 + 0.7966886163 0.8054953814 0.7649232745 + 0.7972326279 0.8060231209 0.7655010223 + 0.7977703810 0.8065471053 0.7660744786 + 0.7983074784 0.8070703745 0.7666473985 + 0.7988445759 0.8075938225 0.7672201991 + 0.7993816733 0.8081170917 0.7677931190 + 0.7999145985 0.8086366057 0.7683627009 + 0.8004472256 0.8091554046 0.7689319849 + 0.8009796739 0.8096743226 0.7695012093 + 0.8015123010 0.8101931810 0.7700704932 + 0.8020427823 0.8107082248 0.7706354260 + 0.8025730848 0.8112226129 0.7711998224 + 0.8031035066 0.8117371202 0.7717642188 + 0.8036338091 0.8122515082 0.7723286152 + 0.8041588068 0.8127616048 0.7728883028 + 0.8046830297 0.8132709265 0.7734473944 + 0.8052071929 0.8137801886 0.7740064263 + 0.8057314754 0.8142895103 0.7745653987 + 0.8062517047 0.8147963285 0.7751224041 + 0.8067709208 0.8153023124 0.7756788135 + 0.8072901964 0.8158082962 0.7762352824 + 0.8078094125 0.8163142800 0.7767916918 + 0.8083264232 0.8168172836 0.7773452997 + 0.8088424802 0.8173186779 0.7778974771 + 0.8093585968 0.8178201914 0.7784497142 + 0.8098745942 0.8183215857 0.7790020108 + 0.8103876710 0.8188199997 0.7795510292 + 0.8108984828 0.8193156123 0.7800974250 + 0.8114091754 0.8198112845 0.7806438208 + 0.8119199872 0.8203068972 0.7811902165 + 0.8124291897 0.8208017945 0.7817354202 + 0.8129357100 0.8212953806 0.7822787166 + 0.8134422898 0.8217890263 0.7828220129 + 0.8139489293 0.8222826719 0.7833654284 + 0.8144549727 0.8227757812 0.7839078903 + 0.8149591088 0.8232660890 0.7844464779 + 0.8154631853 0.8237565160 0.7849851251 + 0.8159673810 0.8242468238 0.7855237722 + 0.8164715171 0.8247371912 0.7860624194 + 0.8169714212 0.8252223730 0.7865952253 + 0.8174710274 0.8257070780 0.7871276140 + 0.8179705739 0.8261917830 0.7876598835 + 0.8184702992 0.8266764879 0.7881922722 + 0.8189675808 0.8271585107 0.7887222767 + 0.8194637895 0.8276389241 0.7892510891 + 0.8199599981 0.8281193972 0.7897799015 + 0.8204562068 0.8285998106 0.7903087139 + 0.8209517002 0.8290792108 0.7908356786 + 0.8214461803 0.8295565248 0.7913593054 + 0.8219406009 0.8300337791 0.7918829918 + 0.8224350214 0.8305110931 0.7924066186 + 0.8229293823 0.8309884071 0.7929303050 + 0.8234202266 0.8314602971 0.7934505939 + 0.8239108920 0.8319321275 0.7939708829 + 0.8244016767 0.8324038982 0.7944911718 + 0.8248924017 0.8328756094 0.7950115204 + 0.8253806829 0.8333445787 0.7955307961 + 0.8258677125 0.8338115215 0.7960494757 + 0.8263546228 0.8342785239 0.7965682149 + 0.8268414736 0.8347455263 0.7970868945 + 0.8273276091 0.8352121115 0.7976047993 + 0.8278108239 0.8356773257 0.7981191874 + 0.8282939792 0.8361424804 0.7986335754 + 0.8287771940 0.8366076946 0.7991480827 + 0.8292604089 0.8370729089 0.7996624708 + 0.8297402859 0.8375352025 0.8001754284 + 0.8302192092 0.8379961848 0.8006876707 + 0.8306980133 0.8384572864 0.8012000918 + 0.8311768770 0.8389183879 0.8017123938 + 0.8316546082 0.8393784761 0.8022242785 + 0.8321290016 0.8398349881 0.8027346134 + 0.8326033950 0.8402916193 0.8032448888 + 0.8330777884 0.8407480717 0.8037552834 + 0.8335521817 0.8412047029 0.8042656183 + 0.8340237737 0.8416597843 0.8047726750 + 0.8344941735 0.8421143293 0.8052784204 + 0.8349646926 0.8425686955 0.8057842255 + 0.8354352117 0.8430231810 0.8062899113 + 0.8359050751 0.8434774280 0.8067952991 + 0.8363721967 0.8439291716 0.8072986007 + 0.8368391991 0.8443809748 0.8078019023 + 0.8373062015 0.8448328972 0.8083050847 + 0.8377732038 0.8452847004 0.8088083863 + 0.8382382989 0.8457334042 0.8093103766 + 0.8387017846 0.8461793065 0.8098112941 + 0.8391653895 0.8466250896 0.8103122711 + 0.8396288753 0.8470708728 0.8108131886 + 0.8400924206 0.8475167751 0.8113141060 + 0.8405531049 0.8479586244 0.8118106723 + 0.8410136104 0.8483998775 0.8123067021 + 0.8414739966 0.8488411903 0.8128026724 + 0.8419345021 0.8492823839 0.8132987022 + 0.8423944116 0.8497232199 0.8137940764 + 0.8428521752 0.8501616716 0.8142873049 + 0.8433101177 0.8506001830 0.8147805929 + 0.8437680006 0.8510386944 0.8152738214 + 0.8442258835 0.8514773250 0.8157669902 + 0.8446823955 0.8519136906 0.8162589073 + 0.8451377153 0.8523477912 0.8167495131 + 0.8455929160 0.8527818918 0.8172399998 + 0.8460481763 0.8532159925 0.8177304864 + 0.8465033770 0.8536500931 0.8182210922 + 0.8469561934 0.8540809155 0.8187078834 + 0.8474081755 0.8545101881 0.8191933036 + 0.8478600979 0.8549395800 0.8196786046 + 0.8483120203 0.8553689718 0.8201640248 + 0.8487640023 0.8557983041 0.8206493258 + 0.8492118716 0.8562254906 0.8211318851 + 0.8496595025 0.8566523790 0.8216142058 + 0.8501071930 0.8570793867 0.8220965266 + 0.8505548239 0.8575062752 0.8225787878 + 0.8510020971 0.8579329848 0.8230608106 + 0.8514466286 0.8583570123 0.8235400915 + 0.8518909812 0.8587809801 0.8240194917 + 0.8523355126 0.8592050076 0.8244987726 + 0.8527799249 0.8596289754 0.8249781132 + 0.8532239199 0.8600522280 0.8254566789 + 0.8536661863 0.8604717851 0.8259320855 + 0.8541085124 0.8608914018 0.8264076114 + 0.8545507789 0.8613110185 0.8268830180 + 0.8549929857 0.8617305756 0.8273584843 + 0.8554344177 0.8621492982 0.8278334141 + 0.8558735251 0.8625652790 0.8283066154 + 0.8563125134 0.8629813194 0.8287798166 + 0.8567516208 0.8633973002 0.8292530179 + 0.8571907282 0.8638132811 0.8297262788 + 0.8576285839 0.8642284870 0.8301985264 + 0.8580638766 0.8646416068 0.8306686282 + 0.8584992886 0.8650546074 0.8311386704 + 0.8589347005 0.8654677272 0.8316087127 + 0.8593699932 0.8658807874 0.8320788145 + 0.8598045707 0.8662930727 0.8325483799 + 0.8602377176 0.8667033911 0.8330168724 + 0.8606708050 0.8671137094 0.8334854245 + 0.8611038923 0.8675240874 0.8339539170 + 0.8615369797 0.8679344058 0.8344224095 + 0.8619691730 0.8683441877 0.8348909020 + 0.8623989820 0.8687524796 0.8353595138 + 0.8628287911 0.8691607118 0.8358281255 + 0.8632586002 0.8695690036 0.8362966180 + 0.8636884093 0.8699771762 0.8367652297 + 0.8641173840 0.8703852892 0.8372331858 + 0.8645430207 0.8707920909 0.8376984000 + 0.8649684787 0.8711990118 0.8381634951 + 0.8653941154 0.8716058731 0.8386287093 + 0.8658195734 0.8720127940 0.8390939236 + 0.8662450910 0.8724194765 0.8395590186 + 0.8666694164 0.8728235960 0.8400223255 + 0.8670938015 0.8732277155 0.8404856920 + 0.8675181866 0.8736317754 0.8409489989 + 0.8679425120 0.8740358949 0.8414124250 + 0.8683668971 0.8744400144 0.8418756723 + 0.8687893152 0.8748406172 0.8423389196 + 0.8692114949 0.8752405047 0.8428019881 + 0.8696336746 0.8756405115 0.8432651758 + 0.8700559139 0.8760403991 0.8437283039 + 0.8704780936 0.8764404058 0.8441913724 + 0.8708974123 0.8768380880 0.8446521759 + 0.8713154197 0.8772345781 0.8451117277 + 0.8717334867 0.8776311278 0.8455712199 + 0.8721514940 0.8780276179 0.8460307717 + 0.8725695014 0.8784241080 0.8464903235 + 0.8729861975 0.8788195252 0.8469489813 + 0.8734011054 0.8792132139 0.8474063873 + 0.8738160133 0.8796069026 0.8478639126 + 0.8742309213 0.8800007105 0.8483213782 + 0.8746458292 0.8803943992 0.8487787843 + 0.8750604987 0.8807877898 0.8492361903 + 0.8754733205 0.8811789751 0.8496932983 + 0.8758860230 0.8815701008 0.8501502872 + 0.8762987852 0.8819612265 0.8506072760 + 0.8767116070 0.8823524117 0.8510643244 + 0.8771244287 0.8827434778 0.8515213132 + 0.8775348067 0.8831323981 0.8519753814 + 0.8779444098 0.8835206032 0.8524286151 + 0.8783540726 0.8839088082 0.8528817892 + 0.8787636757 0.8842970133 0.8533350229 + 0.8791733980 0.8846852183 0.8537881970 + 0.8795822263 0.8850721121 0.8542405963 + 0.8799896836 0.8854566216 0.8546915054 + 0.8803973198 0.8858410716 0.8551424742 + 0.8808047771 0.8862255812 0.8555933833 + 0.8812122941 0.8866102099 0.8560442924 + 0.8816198111 0.8869947195 0.8564953208 + 0.8820263147 0.8873755932 0.8569455743 + 0.8824326992 0.8877562284 0.8573958874 + 0.8828390837 0.8881369233 0.8578462005 + 0.8832455277 0.8885174990 0.8582963943 + 0.8836519122 0.8888980746 0.8587467074 + 0.8840569258 0.8892776966 0.8591951728 + 0.8844602108 0.8896561861 0.8596414924 + 0.8848636150 0.8900346160 0.8600878119 + 0.8852669001 0.8904129863 0.8605340719 + 0.8856703043 0.8907914162 0.8609802723 + 0.8860735893 0.8911697865 0.8614265919 + 0.8864722848 0.8915463090 0.8618707061 + 0.8868706226 0.8919227123 0.8623145819 + 0.8872690201 0.8922989964 0.8627585173 + 0.8876674175 0.8926753998 0.8632022738 + 0.8880656958 0.8930518031 0.8636462092 + 0.8884631991 0.8934273124 0.8640897870 + 0.8888590932 0.8938013911 0.8645328283 + 0.8892549872 0.8941754103 0.8649758101 + 0.8896508813 0.8945494294 0.8654187918 + 0.8900468946 0.8949235082 0.8658617735 + 0.8904427886 0.8952975273 0.8663048148 + 0.8908371925 0.8956699967 0.8667446971 + 0.8912311792 0.8960419893 0.8671836257 + 0.8916252255 0.8964139223 0.8676224947 + 0.8920192122 0.8967859149 0.8680614233 + 0.8924131989 0.8971577883 0.8685001731 + 0.8928068876 0.8975296021 0.8689389229 + 0.8931970000 0.8978990912 0.8693752289 + 0.8935871124 0.8982686996 0.8698114753 + 0.8939772844 0.8986381888 0.8702477813 + 0.8943673968 0.8990076780 0.8706840873 + 0.8947576284 0.8993772268 0.8711203933 + 0.8951466084 0.8997455835 0.8715562820 + 0.8955339193 0.9001119733 0.8719915152 + 0.8959211707 0.9004784226 0.8724268079 + 0.8963084817 0.9008446932 0.8728619814 + 0.8966959119 0.9012110829 0.8732972145 + 0.8970832229 0.9015774131 0.8737323880 + 0.8974692822 0.9019417763 0.8741655946 + 0.8978548050 0.9023047090 0.8745973706 + 0.8982402086 0.9026677012 0.8750292063 + 0.8986256123 0.9030305743 0.8754611015 + 0.8990110755 0.9033935070 0.8758928776 + 0.8993964791 0.9037564993 0.8763247132 + 0.8997789025 0.9041181207 0.8767552972 + 0.9001606107 0.9044793248 0.8771855831 + 0.9005421996 0.9048405290 0.8776159286 + 0.9009239078 0.9052016735 0.8780462146 + 0.9013054967 0.9055628777 0.8784765005 + 0.9016872048 0.9059240818 0.8789067864 + 0.9020649195 0.9062829018 0.8793358207 + 0.9024425149 0.9066416025 0.8797646165 + 0.9028201103 0.9070003033 0.8801934719 + 0.9031975865 0.9073588848 0.8806223869 + 0.9035751820 0.9077175856 0.8810513020 + 0.9039525986 0.9080762267 0.8814799786 + 0.9043281078 0.9084306955 0.8819060922 + 0.9047036171 0.9087852836 0.8823322058 + 0.9050791264 0.9091398716 0.8827583194 + 0.9054545760 0.9094944000 0.8831843734 + 0.9058300853 0.9098489881 0.8836104274 + 0.9062054157 0.9102032781 0.8840364814 + 0.9065783024 0.9105550051 0.8844619989 + 0.9069511890 0.9109066725 0.8848875165 + 0.9073241949 0.9112585187 0.8853129148 + 0.9076970816 0.9116101861 0.8857383728 + 0.9080700874 0.9119619131 0.8861638904 + 0.9084427953 0.9123135209 0.8865892291 + 0.9088128209 0.9126635194 0.8870128989 + 0.9091827869 0.9130135179 0.8874365091 + 0.9095528126 0.9133635163 0.8878601789 + 0.9099227786 0.9137135148 0.8882837892 + 0.9102928042 0.9140635133 0.8887075186 + 0.9106627107 0.9144133925 0.8891310096 + 0.9110317826 0.9147610068 0.8895515203 + 0.9114007950 0.9151085019 0.8899719119 + 0.9117698073 0.9154561162 0.8903924227 + 0.9121388793 0.9158036113 0.8908128738 + 0.9125078917 0.9161511064 0.8912333250 + 0.9128769040 0.9164987206 0.8916537762 + 0.9132447243 0.9168428779 0.8920732737 + 0.9136124253 0.9171867967 0.8924927115 + 0.9139801264 0.9175307751 0.8929122090 + 0.9143477082 0.9178748131 0.8933315873 + 0.9147154093 0.9182186723 0.8937510848 + 0.9150831103 0.9185627103 0.8941705227 + 0.9154474735 0.9189047813 0.8945881724 + 0.9158111215 0.9192463756 0.8950055242 + 0.9161747098 0.9195880294 0.8954226971 + 0.9165382981 0.9199296236 0.8958399296 + 0.9169018865 0.9202712178 0.8962571025 + 0.9172654748 0.9206128120 0.8966743946 + 0.9176265001 0.9209533930 0.8970903158 + 0.9179857969 0.9212933183 0.8975052834 + 0.9183449745 0.9216331244 0.8979204297 + 0.9187042117 0.9219729900 0.8983353972 + 0.9190635085 0.9223129153 0.8987504244 + 0.9194226861 0.9226527810 0.8991655111 + 0.9197812080 0.9229915738 0.8995802999 + 0.9201380014 0.9233281016 0.8999949098 + 0.9204949141 0.9236646891 0.9004095197 + 0.9208517075 0.9240012169 0.9008241296 + 0.9212086201 0.9243378043 0.9012386799 + 0.9215654135 0.9246743917 0.9016532898 + 0.9219222069 0.9250109196 0.9020677805 + 0.9222760797 0.9253453016 0.9024798870 + 0.9226300716 0.9256798029 0.9028918743 + 0.9229841232 0.9260141850 0.9033039808 + 0.9233379960 0.9263486862 0.9037160873 + 0.9236919880 0.9266831279 0.9041281939 + 0.9240459800 0.9270175099 0.9045401812 + 0.9243978262 0.9273512959 0.9049506783 + 0.9247484803 0.9276847839 0.9053602219 + 0.9250993133 0.9280182719 0.9057698250 + 0.9254500270 0.9283518195 0.9061794281 + 0.9258008003 0.9286853075 0.9065889716 + 0.9261515141 0.9290186763 0.9069985747 + 0.9265019298 0.9293516278 0.9074079990 + 0.9268512726 0.9296824932 0.9078168273 + 0.9272007942 0.9300134182 0.9082257152 + 0.9275501966 0.9303442836 0.9086344838 + 0.9278995991 0.9306753278 0.9090433121 + 0.9282490015 0.9310061932 0.9094521999 + 0.9285985231 0.9313371181 0.9098610282 + 0.9289464951 0.9316648245 0.9102689028 + 0.9292942286 0.9319915771 0.9106765985 + 0.9296419024 0.9323183894 0.9110842943 + 0.9299895763 0.9326452017 0.9114919901 + 0.9303374290 0.9329720736 0.9118996859 + 0.9306851029 0.9332988858 0.9123073816 + 0.9310320020 0.9336249232 0.9127150178 + 0.9313766956 0.9339488745 0.9131222963 + 0.9317213893 0.9342728257 0.9135295749 + 0.9320660830 0.9345967770 0.9139369130 + 0.9324107766 0.9349207878 0.9143441916 + 0.9327554703 0.9352446795 0.9147515297 + 0.9331002235 0.9355686903 0.9151586890 + 0.9334433079 0.9358913898 0.9155651927 + 0.9337856770 0.9362136126 0.9159712195 + 0.9341281056 0.9365357757 0.9163771868 + 0.9344704747 0.9368579984 0.9167832136 + 0.9348127842 0.9371802211 0.9171893001 + 0.9351552129 0.9375023842 0.9175953269 + 0.9354975224 0.9378244281 0.9180011749 + 0.9358382225 0.9381431937 0.9184055924 + 0.9361788034 0.9384620786 0.9188100100 + 0.9365195036 0.9387809038 0.9192144275 + 0.9368602037 0.9390997291 0.9196187854 + 0.9372009039 0.9394186139 0.9200232029 + 0.9375416040 0.9397373796 0.9204276204 + 0.9378811121 0.9400548935 0.9208316207 + 0.9382188916 0.9403703213 0.9212350845 + 0.9385566115 0.9406856894 0.9216386080 + 0.9388942719 0.9410011172 0.9220420718 + 0.9392319918 0.9413164854 0.9224454761 + 0.9395697117 0.9416319132 0.9228489995 + 0.9399074912 0.9419472814 0.9232525229 + 0.9402431250 0.9422618151 0.9236547947 + 0.9405775070 0.9425758123 0.9240565896 + 0.9409120083 0.9428898096 0.9244583249 + 0.9412463903 0.9432038069 0.9248600006 + 0.9415808916 0.9435179234 0.9252616763 + 0.9419152737 0.9438319206 0.9256634116 + 0.9422497749 0.9441459179 0.9260650873 + 0.9425830245 0.9444586039 0.9264650941 + 0.9429159760 0.9447709918 0.9268646836 + 0.9432489872 0.9450834990 0.9272642732 + 0.9435819983 0.9453958869 0.9276639223 + 0.9439150095 0.9457083941 0.9280635118 + 0.9442480206 0.9460207820 0.9284631014 + 0.9445809722 0.9463332891 0.9288625717 + 0.9449120760 0.9466425776 0.9292607903 + 0.9452432990 0.9469519854 0.9296590090 + 0.9455745220 0.9472612739 0.9300572276 + 0.9459056258 0.9475706816 0.9304553866 + 0.9462367892 0.9478800297 0.9308536053 + 0.9465680122 0.9481893778 0.9312518239 + 0.9468988180 0.9484986067 0.9316499233 + 0.9472268820 0.9488059878 0.9320474863 + 0.9475550056 0.9491134286 0.9324449897 + 0.9478831887 0.9494208097 0.9328426123 + 0.9482113123 0.9497281909 0.9332401156 + 0.9485393763 0.9500355721 0.9336376190 + 0.9488674998 0.9503430128 0.9340351820 + 0.9491953254 0.9506502748 0.9344326854 + 0.9495210052 0.9509568214 0.9348298907 + 0.9498466849 0.9512634277 0.9352269769 + 0.9501724243 0.9515699744 0.9356241822 + 0.9504981041 0.9518765211 0.9360213876 + 0.9508237839 0.9521831274 0.9364185929 + 0.9511495233 0.9524896741 0.9368157983 + 0.9514749050 0.9527959824 0.9372128248 + 0.9517980814 0.9531002045 0.9376080036 + 0.9521211982 0.9534044266 0.9380033016 + 0.9524443150 0.9537085891 0.9383985996 + 0.9527673721 0.9540126920 0.9387937784 + 0.9530906081 0.9543169141 0.9391890764 + 0.9534137249 0.9546210766 0.9395843744 + 0.9537366033 0.9549251795 0.9399794936 + 0.9540542960 0.9552258849 0.9403715134 + 0.9543719888 0.9555265903 0.9407635927 + 0.9546896815 0.9558274150 0.9411556125 + 0.9550073743 0.9561281204 0.9415475726 + 0.9553251266 0.9564288259 0.9419395924 + 0.9556428790 0.9567294717 0.9423316717 + 0.9559605718 0.9570301771 0.9427236915 + 0.9562745094 0.9573286772 0.9431132078 + 0.9565880895 0.9576269984 0.9435023069 + 0.9569017291 0.9579253197 0.9438915253 + 0.9572151899 0.9582235813 0.9442806244 + 0.9575288296 0.9585217834 0.9446697831 + 0.9578424096 0.9588201046 0.9450588822 + 0.9581558704 0.9591184258 0.9454481006 + 0.9584683776 0.9594156742 0.9458364844 + 0.9587804079 0.9597126842 0.9462245703 + 0.9590924978 0.9600095749 0.9466127157 + 0.9594045281 0.9603065252 0.9470008016 + 0.9597164989 0.9606034756 0.9473888874 + 0.9600285888 0.9609004259 0.9477769732 + 0.9603406191 0.9611973166 0.9481651187 + 0.9606512785 0.9614930749 0.9485527873 + 0.9609603882 0.9617875218 0.9489399791 + 0.9612696171 0.9620819092 0.9493271708 + 0.9615787268 0.9623762965 0.9497144818 + 0.9618877769 0.9626706839 0.9501016736 + 0.9621970057 0.9629650712 0.9504889250 + 0.9625061154 0.9632595181 0.9508761168 + 0.9628148079 0.9635536075 0.9512630105 + 0.9631211162 0.9638456106 0.9516479969 + 0.9634273052 0.9641376138 0.9520329833 + 0.9637334943 0.9644294977 0.9524180293 + 0.9640396833 0.9647215009 0.9528030157 + 0.9643458724 0.9650135040 0.9531880021 + 0.9646521211 0.9653053880 0.9535729885 + 0.9649583101 0.9655973911 0.9539579153 + 0.9652628899 0.9658880830 0.9543418884 + 0.9655668736 0.9661784768 0.9547253847 + 0.9658709168 0.9664688110 0.9551090002 + 0.9661749005 0.9667590857 0.9554926157 + 0.9664788246 0.9670494199 0.9558761120 + 0.9667828083 0.9673396945 0.9562597275 + 0.9670867920 0.9676300287 0.9566432834 + 0.9673900008 0.9679197073 0.9570264220 + 0.9676913023 0.9682080150 0.9574084878 + 0.9679926038 0.9684962034 0.9577906132 + 0.9682939053 0.9687843919 0.9581726789 + 0.9685953259 0.9690726995 0.9585548043 + 0.9688966274 0.9693608880 0.9589369297 + 0.9691979289 0.9696490765 0.9593191147 + 0.9694991708 0.9699373841 0.9597011805 + 0.9697983861 0.9702233076 0.9600812197 + 0.9700970054 0.9705085158 0.9604607821 + 0.9703956246 0.9707937837 0.9608402848 + 0.9706941843 0.9710791111 0.9612197876 + 0.9709929228 0.9713643789 0.9615994096 + 0.9712914824 0.9716497064 0.9619789124 + 0.9715901017 0.9719349742 0.9623584151 + 0.9718881845 0.9722197056 0.9627375007 + 0.9721844792 0.9725024104 0.9631149769 + 0.9724807143 0.9727851152 0.9634925127 + 0.9727770090 0.9730678201 0.9638699889 + 0.9730733037 0.9733504057 0.9642475247 + 0.9733694792 0.9736331105 0.9646250010 + 0.9736657739 0.9739158154 0.9650024772 + 0.9739621282 0.9741985202 0.9653798938 + 0.9742565155 0.9744799733 0.9657559991 + 0.9745497704 0.9747607112 0.9661310911 + 0.9748430252 0.9750415087 0.9665063024 + 0.9751362801 0.9753221869 0.9668813944 + 0.9754294753 0.9756029248 0.9672564864 + 0.9757227898 0.9758836031 0.9676316977 + 0.9760159850 0.9761644006 0.9680067897 + 0.9763092995 0.9764450788 0.9683818817 + 0.9765990973 0.9767239094 0.9687542915 + 0.9768885970 0.9770026207 0.9691264033 + 0.9771782160 0.9772812128 0.9694985747 + 0.9774677157 0.9775598049 0.9698706865 + 0.9777572751 0.9778385162 0.9702427983 + 0.9780467749 0.9781171083 0.9706150293 + 0.9783363938 0.9783958197 0.9709870815 + 0.9786252975 0.9786741138 0.9713587761 + 0.9789113998 0.9789509177 0.9717280865 + 0.9791973829 0.9792277217 0.9720973969 + 0.9794834852 0.9795044065 0.9724667072 + 0.9797695279 0.9797812104 0.9728360176 + 0.9800555110 0.9800580144 0.9732053280 + 0.9803416133 0.9803346992 0.9735746980 + 0.9806275964 0.9806115031 0.9739440084 + 0.9809123874 0.9808875918 0.9743121266 + 0.9811949134 0.9811623096 0.9746779799 + 0.9814773798 0.9814370275 0.9750438929 + 0.9817599058 0.9817116857 0.9754099250 + 0.9820423722 0.9819864035 0.9757757783 + 0.9823248982 0.9822611213 0.9761416912 + 0.9826074243 0.9825357795 0.9765076041 + 0.9828898907 0.9828104973 0.9768735170 + 0.9831706285 0.9830839038 0.9772381186 + 0.9834492803 0.9833558202 0.9776011109 + 0.9837279916 0.9836276770 0.9779641032 + 0.9840067029 0.9838995934 0.9783270955 + 0.9842854738 0.9841713905 0.9786900282 + 0.9845641851 0.9844433069 0.9790530205 + 0.9848428965 0.9847152233 0.9794160128 + 0.9851216078 0.9849870801 0.9797790051 + 0.9853982925 0.9852576256 0.9801405072 + 0.9856731296 0.9855268002 0.9805005789 + 0.9859479070 0.9857959747 0.9808607101 + 0.9862228036 0.9860652089 0.9812209010 + 0.9864975810 0.9863345027 0.9815809727 + 0.9867724180 0.9866036773 0.9819411039 + 0.9870471954 0.9868729115 0.9823011756 + 0.9873220921 0.9871420860 0.9826613069 + 0.9875941277 0.9874101877 0.9830198288 + 0.9878634810 0.9876769781 0.9833766818 + 0.9881328940 0.9879438281 0.9837337136 + 0.9884023070 0.9882106781 0.9840906262 + 0.9886716008 0.9884775281 0.9844474792 + 0.9889410138 0.9887443185 0.9848043919 + 0.9892104268 0.9890111089 0.9851613045 + 0.9894797802 0.9892780185 0.9855182171 + 0.9897462130 0.9895430803 0.9858739972 + 0.9900087714 0.9898058772 0.9862282276 + 0.9902712703 0.9900686741 0.9865823984 + 0.9905338287 0.9903314710 0.9869366288 + 0.9907963276 0.9905943274 0.9872906804 + 0.9910588264 0.9908571243 0.9876449108 + 0.9913213849 0.9911199212 0.9879990816 + 0.9915838838 0.9913827181 0.9883533120 + 0.9918448925 0.9916440845 0.9887064099 + 0.9921017885 0.9919016957 0.9890565872 + 0.9923588037 0.9921593070 0.9894067049 + 0.9926156998 0.9924169779 0.9897568822 + 0.9928725958 0.9926745892 0.9901071191 + 0.9931296110 0.9929322004 0.9904572964 + 0.9933865070 0.9931898713 0.9908074141 + 0.9936434031 0.9934474826 0.9911575913 + 0.9939001203 0.9937049747 0.9915075898 + 0.9941518903 0.9939597249 0.9918552041 + 0.9944037795 0.9942144156 0.9922026992 + 0.9946557283 0.9944692254 0.9925501943 + 0.9949074984 0.9947239161 0.9928978086 + 0.9951593876 0.9949786067 0.9932453036 + 0.9954112172 0.9952334166 0.9935927987 + 0.9956631064 0.9954881072 0.9939404130 + 0.9959149957 0.9957427979 0.9942879081 + 0.9961606860 0.9959961772 0.9946306944 + 0.9964045882 0.9962491989 0.9949722290 + 0.9966484904 0.9965021014 0.9953135848 + 0.9968923926 0.9967551231 0.9956551194 + 0.9971364141 0.9970080256 0.9959965944 + 0.9973803163 0.9972609878 0.9963380098 + 0.9976242185 0.9975138903 0.9966794848 + 0.9978681207 0.9977669120 0.9970210195 + 0.9981089234 0.9980177283 0.9973577261 + 0.9983453155 0.9982655048 0.9976879954 + 0.9985817075 0.9985132813 0.9980183244 + 0.9988179803 0.9987609982 0.9983485937 + 0.9990543723 0.9990087748 0.9986789227 + 0.9992908239 0.9992566109 0.9990090728 + 0.9995272160 0.9995043874 0.9993394017 + 0.9997636080 0.9997522235 0.9996696711 + 1.0000000000 1.0000000000 1.0000000000 +} diff --git a/rpplugins/color_correction/resources/film_luts_raw/agfa_agfacolor_futura_400.spi1d b/rpplugins/color_correction/resources/film_luts_raw/agfa_agfacolor_futura_400.spi1d new file mode 100644 index 0000000..030a8fb --- /dev/null +++ b/rpplugins/color_correction/resources/film_luts_raw/agfa_agfacolor_futura_400.spi1d @@ -0,0 +1,1030 @@ +Version 1 +From 0.0 1.0 +Length 1024 +Components 3 +{ + 0.0000000000 0.0000000000 0.0000000000 + 0.0189804304 0.0202203300 0.0141742602 + 0.0334178284 0.0351021588 0.0260934699 + 0.0454768315 0.0478549302 0.0364666395 + 0.0562601797 0.0592830218 0.0458958298 + 0.0662030578 0.0697968081 0.0546298996 + 0.0755658001 0.0796677694 0.0628222525 + 0.0844966397 0.0889748707 0.0705531687 + 0.0930858031 0.0978165492 0.0779282674 + 0.1014240980 0.1062681973 0.0849699080 + 0.1095660999 0.1143971011 0.0916869491 + 0.1175450981 0.1221864969 0.0981442481 + 0.1253249943 0.1296440959 0.1043419018 + 0.1328340024 0.1367834061 0.1102854982 + 0.1399984062 0.1436239928 0.1160039008 + 0.1468109936 0.1502085030 0.1215291023 + 0.1533181965 0.1565480977 0.1268731952 + 0.1595371962 0.1626639962 0.1320544034 + 0.1655108929 0.1685764045 0.1370812953 + 0.1712646037 0.1742939055 0.1419793069 + 0.1768248975 0.1798332930 0.1467563957 + 0.1822118014 0.1852239966 0.1514313072 + 0.1874231994 0.1904760003 0.1559925973 + 0.1924864948 0.1955907047 0.1604602933 + 0.1974117011 0.2005726993 0.1648356020 + 0.2021995932 0.2054260969 0.1691132933 + 0.2068601996 0.2101702988 0.1733085066 + 0.2114142030 0.2148002982 0.1774341017 + 0.2158668935 0.2193187028 0.1814931035 + 0.2202159017 0.2237484008 0.1854856014 + 0.2244572043 0.2280993015 0.1894098967 + 0.2285912931 0.2323631048 0.1932736933 + 0.2326336950 0.2365342975 0.1970842034 + 0.2366016954 0.2406188995 0.2008334994 + 0.2405177951 0.2446300983 0.2045322061 + 0.2443760037 0.2485861927 0.2081629038 + 0.2481773049 0.2524932921 0.2117401063 + 0.2519231141 0.2563455105 0.2152681053 + 0.2556205094 0.2601292133 0.2187464982 + 0.2592709064 0.2638446987 0.2221813947 + 0.2628698945 0.2674998045 0.2255706042 + 0.2664135993 0.2711037993 0.2289170027 + 0.2698990107 0.2746542096 0.2322203964 + 0.2733238041 0.2781482935 0.2354855984 + 0.2766858041 0.2815822065 0.2387184948 + 0.2799929976 0.2849547863 0.2419216931 + 0.2832500935 0.2882680893 0.2450876981 + 0.2864542007 0.2915301919 0.2482271940 + 0.2896077931 0.2947526872 0.2513332069 + 0.2927064896 0.2979423106 0.2543987930 + 0.2957524955 0.3010992110 0.2574329972 + 0.2987526953 0.3042244911 0.2604371011 + 0.3017115891 0.3073199987 0.2634117007 + 0.3046318889 0.3103852868 0.2663584054 + 0.3075189888 0.3134222031 0.2692733109 + 0.3103761971 0.3164314032 0.2721604109 + 0.3132067025 0.3194135129 0.2750195861 + 0.3160125911 0.3223691881 0.2778514028 + 0.3187975883 0.3252983987 0.2806541920 + 0.3215644956 0.3282026947 0.2834334970 + 0.3243156970 0.3310827017 0.2861855924 + 0.3270539045 0.3339388072 0.2889156938 + 0.3297814131 0.3367714882 0.2916230857 + 0.3325003982 0.3395748138 0.2943058908 + 0.3352132142 0.3423477113 0.2969624102 + 0.3379161954 0.3450841904 0.2995971143 + 0.3405976892 0.3477846980 0.3022120893 + 0.3432567120 0.3504517972 0.3048096895 + 0.3458822072 0.3530882001 0.3073847890 + 0.3484756052 0.3556962013 0.3099358082 + 0.3510380089 0.3582764864 0.3124623895 + 0.3535713851 0.3608322144 0.3149712980 + 0.3560791910 0.3633658886 0.3174606860 + 0.3585632145 0.3658784032 0.3199287057 + 0.3610230982 0.3683710098 0.3223791122 + 0.3634631932 0.3708465993 0.3248122036 + 0.3658835888 0.3732995093 0.3272255063 + 0.3682858050 0.3757315874 0.3296200931 + 0.3706724048 0.3781447113 0.3319934905 + 0.3730427027 0.3805387020 0.3343470097 + 0.3754003942 0.3829126954 0.3366861939 + 0.3777439892 0.3852662146 0.3390057981 + 0.3800773025 0.3876036108 0.3413096070 + 0.3823992014 0.3899244070 0.3435958922 + 0.3847126067 0.3922333121 0.3458688855 + 0.3870173991 0.3945314884 0.3481296897 + 0.3893153071 0.3968203068 0.3503778875 + 0.3916071951 0.3991019130 0.3526121080 + 0.3938935995 0.4013710022 0.3548285067 + 0.3961760998 0.4036257863 0.3570280075 + 0.3984551132 0.4058659971 0.3592115045 + 0.4007292092 0.4080862999 0.3613776863 + 0.4029959142 0.4102860093 0.3635272980 + 0.4052543938 0.4124661088 0.3656620979 + 0.4075042903 0.4146254957 0.3677802980 + 0.4097425938 0.4167692065 0.3698835075 + 0.4119692147 0.4188987911 0.3719711006 + 0.4141839147 0.4210126996 0.3740384877 + 0.4163868129 0.4231149852 0.3760899901 + 0.4185790122 0.4252065122 0.3781270981 + 0.4207611978 0.4272862077 0.3801490963 + 0.4229308069 0.4293535054 0.3821552098 + 0.4250904024 0.4314081967 0.3841435015 + 0.4272392094 0.4334529042 0.3861171901 + 0.4293777943 0.4354852140 0.3880780041 + 0.4315068126 0.4375067949 0.3900259137 + 0.4336226881 0.4395155013 0.3919605017 + 0.4357245862 0.4415121973 0.3938809931 + 0.4378120899 0.4434967041 0.3957869112 + 0.4398863018 0.4454723895 0.3976789117 + 0.4419437051 0.4474394917 0.3995566964 + 0.4439849854 0.4493967891 0.4014219940 + 0.4460108876 0.4513399899 0.4032762945 + 0.4480217993 0.4532704055 0.4051195979 + 0.4500184953 0.4551894069 0.4069514871 + 0.4520016015 0.4570955932 0.4087724090 + 0.4539715946 0.4589887857 0.4105815887 + 0.4559291005 0.4608702958 0.4123832881 + 0.4578745961 0.4627414048 0.4141762853 + 0.4598087966 0.4646035135 0.4159627855 + 0.4617320895 0.4664578140 0.4177407026 + 0.4636450112 0.4683054090 0.4195122123 + 0.4655455053 0.4701451063 0.4212754071 + 0.4674327075 0.4719766080 0.4230324030 + 0.4693084955 0.4737985134 0.4247812033 + 0.4711722136 0.4756115079 0.4265238941 + 0.4730255902 0.4774144888 0.4282588065 + 0.4748682976 0.4792071879 0.4299876094 + 0.4766997099 0.4809884131 0.4317089021 + 0.4785183072 0.4827584922 0.4334239960 + 0.4803259969 0.4845187962 0.4351322055 + 0.4821228087 0.4862686992 0.4368340969 + 0.4839096963 0.4880078137 0.4385294914 + 0.4856866896 0.4897367954 0.4402182996 + 0.4874519110 0.4914573133 0.4419007897 + 0.4892069101 0.4931693077 0.4435743093 + 0.4909515083 0.4948728085 0.4452398121 + 0.4926868081 0.4965651035 0.4468953907 + 0.4944101870 0.4982514977 0.4485433102 + 0.4961231947 0.4999290109 0.4501810968 + 0.4978268147 0.5015965104 0.4518086910 + 0.4995205998 0.5032545924 0.4534263909 + 0.5012040734 0.5049039721 0.4550347030 + 0.5028777719 0.5065457225 0.4566338062 + 0.5045427084 0.5081775188 0.4582231045 + 0.5061982274 0.5097963214 0.4598028064 + 0.5078454018 0.5114061832 0.4613744020 + 0.5094835758 0.5130059123 0.4629381895 + 0.5111126900 0.5145952106 0.4644944072 + 0.5127326846 0.5161756873 0.4660434127 + 0.5143399239 0.5177451968 0.4675836861 + 0.5159363747 0.5193077922 0.4691169858 + 0.5175241828 0.5208638906 0.4706437886 + 0.5191026926 0.5224146247 0.4721643925 + 0.5206707716 0.5239610076 0.4736790955 + 0.5222259164 0.5254994035 0.4751864076 + 0.5237668157 0.5270283818 0.4766879082 + 0.5252965093 0.5285490751 0.4781832099 + 0.5268157721 0.5300623775 0.4796718955 + 0.5283229947 0.5315675139 0.4811522961 + 0.5298194885 0.5330659151 0.4826253057 + 0.5313063860 0.5345565081 0.4840922058 + 0.5327833891 0.5360388160 0.4855529070 + 0.5342487097 0.5375118852 0.4870058000 + 0.5357007980 0.5389770865 0.4884487092 + 0.5371450782 0.5404356718 0.4898858070 + 0.5385817885 0.5418878198 0.4913172126 + 0.5400090218 0.5433310866 0.4927395880 + 0.5414276123 0.5447692871 0.4941565096 + 0.5428383946 0.5462031960 0.4955680966 + 0.5442407131 0.5476328731 0.4969739914 + 0.5456290841 0.5490533710 0.4983738065 + 0.5470101833 0.5504671931 0.4997689128 + 0.5483844876 0.5518745184 0.5011597872 + 0.5497499108 0.5532733202 0.5025461912 + 0.5511074066 0.5546665788 0.5039262772 + 0.5524582863 0.5560551286 0.5053020120 + 0.5538002253 0.5574359298 0.5066723824 + 0.5551335216 0.5588095188 0.5080367923 + 0.5564607978 0.5601773858 0.5093978047 + 0.5577800274 0.5615364909 0.5107548833 + 0.5590916276 0.5628885031 0.5121051073 + 0.5603979826 0.5642359853 0.5134513974 + 0.5616976023 0.5655778050 0.5147926211 + 0.5629879832 0.5669124126 0.5161284208 + 0.5642735958 0.5682426095 0.5174611807 + 0.5655525923 0.5695660710 0.5187898874 + 0.5668237805 0.5708814859 0.5201147199 + 0.5680909753 0.5721923113 0.5214365721 + 0.5693522096 0.5734962225 0.5227527022 + 0.5706079006 0.5747932792 0.5240650773 + 0.5718598962 0.5760861039 0.5253748298 + 0.5731037259 0.5773720741 0.5266771913 + 0.5743418932 0.5786536932 0.5279759169 + 0.5755749941 0.5799306035 0.5292711258 + 0.5768011808 0.5811964869 0.5305575132 + 0.5780242085 0.5824581981 0.5318406820 + 0.5792413950 0.5837122202 0.5331183076 + 0.5804504156 0.5849606991 0.5343890190 + 0.5816553235 0.5862060785 0.5356559753 + 0.5828509927 0.5874449015 0.5369136930 + 0.5840438008 0.5886800289 0.5381681919 + 0.5852320194 0.5899084210 0.5394172072 + 0.5864148736 0.5911297202 0.5406591892 + 0.5875951052 0.5923475027 0.5418981910 + 0.5887641907 0.5935558081 0.5431274176 + 0.5899302959 0.5947611928 0.5443540215 + 0.5910912156 0.5959597826 0.5455750823 + 0.5922474265 0.5971537828 0.5467911959 + 0.5934010148 0.5983446836 0.5480040908 + 0.5945463777 0.5995286107 0.5492113233 + 0.5956892967 0.6007102132 0.5504168272 + 0.5968241096 0.6018840075 0.5516167283 + 0.5979555845 0.6030550003 0.5528140068 + 0.5990828276 0.6042217016 0.5540074110 + 0.6002063751 0.6053854227 0.5551959872 + 0.6013283134 0.6065471768 0.5563817024 + 0.6024429202 0.6077020764 0.5575634837 + 0.6035555005 0.6088551879 0.5587441921 + 0.6046581268 0.6099976897 0.5599179268 + 0.6057583094 0.6111379862 0.5610895753 + 0.6068522930 0.6122714281 0.5622550845 + 0.6079434156 0.6134017706 0.5634173751 + 0.6090310216 0.6145281196 0.5645756125 + 0.6101149917 0.6156514287 0.5657300949 + 0.6111965775 0.6167725921 0.5668820143 + 0.6122707725 0.6178879738 0.5680285096 + 0.6133425236 0.6190009117 0.5691730976 + 0.6144058704 0.6201071143 0.5703091025 + 0.6154682040 0.6212120056 0.5714436173 + 0.6165214777 0.6223102212 0.5725712180 + 0.6175739169 0.6234076023 0.5736979842 + 0.6186174750 0.6244966984 0.5748155117 + 0.6196597815 0.6255844831 0.5759319067 + 0.6206961274 0.6266639233 0.5770416856 + 0.6217305064 0.6277418733 0.5781496763 + 0.6227589250 0.6288138032 0.5792517066 + 0.6237844825 0.6298843026 0.5803521276 + 0.6248034835 0.6309509873 0.5814481974 + 0.6258192062 0.6320158839 0.5825421214 + 0.6268281937 0.6330764294 0.5836308002 + 0.6278346777 0.6341344714 0.5847169161 + 0.6288362145 0.6351872087 0.5857974887 + 0.6298360229 0.6362372041 0.5868756175 + 0.6308323741 0.6372811794 0.5879486203 + 0.6318262815 0.6383233070 0.5890188813 + 0.6328150034 0.6393606067 0.5900835991 + 0.6338009238 0.6403964162 0.5911462903 + 0.6347796917 0.6414275765 0.5922037959 + 0.6357566714 0.6424568295 0.5932598710 + 0.6367279887 0.6434782147 0.5943114161 + 0.6376978755 0.6444982290 0.5953620076 + 0.6386622190 0.6455100775 0.5964084864 + 0.6396257281 0.6465215087 0.5974544287 + 0.6405826807 0.6475260854 0.5984926224 + 0.6415395737 0.6485307217 0.5995308161 + 0.6424885988 0.6495286226 0.6005603075 + 0.6434376836 0.6505261064 0.6015896797 + 0.6443789005 0.6515172720 0.6026117206 + 0.6453189850 0.6525071859 0.6036325097 + 0.6462522745 0.6534914970 0.6046487093 + 0.6471831799 0.6544733047 0.6056631207 + 0.6481100917 0.6554508209 0.6066738963 + 0.6490340829 0.6564248204 0.6076821089 + 0.6499556899 0.6573960781 0.6086879969 + 0.6508737803 0.6583626866 0.6096904278 + 0.6517899036 0.6593278050 0.6106911898 + 0.6526989937 0.6602864265 0.6116858125 + 0.6536079049 0.6612449884 0.6126803160 + 0.6545088291 0.6621980071 0.6136667728 + 0.6554095745 0.6631507874 0.6146532297 + 0.6563045979 0.6640974879 0.6156343222 + 0.6571980119 0.6650422812 0.6166138053 + 0.6580873132 0.6659818292 0.6175904274 + 0.6589732170 0.6669161916 0.6185643077 + 0.6598567963 0.6678487062 0.6195365787 + 0.6607350707 0.6687750220 0.6205043793 + 0.6616132259 0.6697012782 0.6214722991 + 0.6624845862 0.6706203818 0.6224306226 + 0.6633558869 0.6715393066 0.6233887076 + 0.6642240882 0.6724529266 0.6243417859 + 0.6650909781 0.6733639836 0.6252925992 + 0.6659563780 0.6742721200 0.6262406707 + 0.6668195128 0.6751747727 0.6271843910 + 0.6676822901 0.6760774255 0.6281278729 + 0.6685385704 0.6769707799 0.6290643811 + 0.6693950295 0.6778641939 0.6300008297 + 0.6702473760 0.6787514091 0.6309322119 + 0.6710978150 0.6796351075 0.6318609715 + 0.6719467044 0.6805168986 0.6327874064 + 0.6727918983 0.6813933253 0.6337075233 + 0.6736372113 0.6822696924 0.6346276999 + 0.6744775772 0.6831405163 0.6355414987 + 0.6753175259 0.6840105057 0.6364545226 + 0.6761547923 0.6848769188 0.6373646855 + 0.6769893765 0.6857391000 0.6382718086 + 0.6778236032 0.6866012216 0.6391788125 + 0.6786518097 0.6874572039 0.6400815248 + 0.6794800162 0.6883131862 0.6409841180 + 0.6803044081 0.6891654730 0.6418827176 + 0.6811261177 0.6900150180 0.6427782774 + 0.6819474101 0.6908640862 0.6436731815 + 0.6827651858 0.6917092800 0.6445615292 + 0.6835830212 0.6925545931 0.6454498768 + 0.6843972206 0.6933962703 0.6463342905 + 0.6852092743 0.6942355037 0.6472160816 + 0.6860206127 0.6950742006 0.6480973959 + 0.6868252754 0.6959053874 0.6489725709 + 0.6876299977 0.6967365742 0.6498478055 + 0.6884319782 0.6975647807 0.6507201195 + 0.6892318130 0.6983901858 0.6515899897 + 0.6900315285 0.6992155910 0.6524599791 + 0.6908273101 0.7000362873 0.6533246040 + 0.6916229725 0.7008566856 0.6541891098 + 0.6924160719 0.7016751170 0.6550511122 + 0.6932054162 0.7024903297 0.6559094191 + 0.6939945817 0.7033056021 0.6567676067 + 0.6947793961 0.7041168213 0.6576201916 + 0.6955630183 0.7049267292 0.6584712863 + 0.6963458061 0.7057358027 0.6593216062 + 0.6971247196 0.7065396905 0.6601678133 + 0.6979035139 0.7073435187 0.6610140204 + 0.6986786723 0.7081443071 0.6618571877 + 0.6994504929 0.7089418769 0.6626976728 + 0.7002223134 0.7097393870 0.6635380983 + 0.7009885907 0.7105317712 0.6643719077 + 0.7017540932 0.7113230824 0.6652045250 + 0.7025185823 0.7121133804 0.6660360098 + 0.7032787204 0.7128974795 0.6668620110 + 0.7040386796 0.7136815786 0.6676880717 + 0.7047963738 0.7144626975 0.6685119271 + 0.7055510879 0.7152395248 0.6693329811 + 0.7063059211 0.7160161734 0.6701539755 + 0.7070568204 0.7167897224 0.6709715724 + 0.7078062296 0.7175614834 0.6717876792 + 0.7085556984 0.7183333039 0.6726037860 + 0.7092993855 0.7191014290 0.6734123826 + 0.7100430131 0.7198691964 0.6742205024 + 0.7107855082 0.7206360102 0.6750273705 + 0.7115231752 0.7213973999 0.6758279204 + 0.7122610211 0.7221586704 0.6766282916 + 0.7129974961 0.7229182124 0.6774265170 + 0.7137318254 0.7236738801 0.6782206893 + 0.7144662142 0.7244296074 0.6790148020 + 0.7151979804 0.7251828909 0.6798056960 + 0.7159276009 0.7259337902 0.6805936098 + 0.7166572809 0.7266848087 0.6813815832 + 0.7173827887 0.7274302840 0.6821650267 + 0.7181063890 0.7281727791 0.6829462051 + 0.7188299894 0.7289153934 0.6837273836 + 0.7195504904 0.7296513915 0.6845042706 + 0.7202703953 0.7303856015 0.6852802038 + 0.7209903002 0.7311198115 0.6860560775 + 0.7217056751 0.7318493724 0.6868286729 + 0.7224205732 0.7325783968 0.6876009703 + 0.7231354713 0.7333073020 0.6883733273 + 0.7238441706 0.7340301275 0.6891400218 + 0.7245526910 0.7347525954 0.6899065971 + 0.7252612114 0.7354750037 0.6906729937 + 0.7259656787 0.7361903191 0.6914319992 + 0.7266703248 0.7369055152 0.6921910048 + 0.7273744941 0.7376205921 0.6929497123 + 0.7280738950 0.7383303046 0.6937026978 + 0.7287732959 0.7390400171 0.6944558024 + 0.7294721007 0.7397493720 0.6952087283 + 0.7301635146 0.7404522896 0.6959573030 + 0.7308549285 0.7411552072 0.6967059970 + 0.7315459847 0.7418580055 0.6974545121 + 0.7322310805 0.7425541878 0.6981990933 + 0.7329162955 0.7432504296 0.6989436150 + 0.7336012721 0.7439466119 0.6996881962 + 0.7342811823 0.7446365952 0.7004261017 + 0.7349609733 0.7453263998 0.7011638284 + 0.7356408238 0.7460162044 0.7019016147 + 0.7363131046 0.7467001081 0.7026333809 + 0.7369849086 0.7473831773 0.7033646703 + 0.7376567125 0.7480663061 0.7040959001 + 0.7383230925 0.7487441897 0.7048221231 + 0.7389885187 0.7494208217 0.7055472136 + 0.7396538258 0.7500973940 0.7062721848 + 0.7403153777 0.7507699132 0.7069926858 + 0.7409753799 0.7514402866 0.7077111006 + 0.7416353822 0.7521107197 0.7084295154 + 0.7422909141 0.7527776957 0.7091451287 + 0.7429429293 0.7534415126 0.7098584771 + 0.7435948253 0.7541053891 0.7105718851 + 0.7442438006 0.7547671199 0.7112827897 + 0.7448878288 0.7554246187 0.7119894028 + 0.7455319166 0.7560821176 0.7126960754 + 0.7461751103 0.7567387223 0.7134013772 + 0.7468137741 0.7573903203 0.7140998244 + 0.7474524975 0.7580417991 0.7147980928 + 0.7480912209 0.7586933970 0.7154964209 + 0.7487258911 0.7593389750 0.7161883712 + 0.7493603826 0.7599840760 0.7168800235 + 0.7499948740 0.7606291771 0.7175716162 + 0.7506251931 0.7612702250 0.7182598114 + 0.7512537837 0.7619091272 0.7189463973 + 0.7518823147 0.7625480294 0.7196329236 + 0.7525088191 0.7631847262 0.7203181982 + 0.7531324029 0.7638177872 0.7210013866 + 0.7537561059 0.7644509077 0.7216845751 + 0.7543792725 0.7650834918 0.7223674059 + 0.7549992204 0.7657102942 0.7230455279 + 0.7556189895 0.7663369775 0.7237235904 + 0.7562388778 0.7669637203 0.7244017124 + 0.7568544745 0.7675850987 0.7250748277 + 0.7574688792 0.7682043910 0.7257462144 + 0.7580832839 0.7688236833 0.7264177203 + 0.7586959004 0.7694402933 0.7270871997 + 0.7593057752 0.7700520158 0.7277535200 + 0.7599158287 0.7706636190 0.7284198999 + 0.7605257034 0.7712752819 0.7290862799 + 0.7611322999 0.7718833089 0.7297480106 + 0.7617387772 0.7724912167 0.7304096818 + 0.7623453736 0.7730990052 0.7310714126 + 0.7629489899 0.7737038136 0.7317304015 + 0.7635505795 0.7743061781 0.7323871851 + 0.7641521096 0.7749084830 0.7330440283 + 0.7647531033 0.7755101919 0.7337000966 + 0.7653506994 0.7761059999 0.7343516946 + 0.7659481764 0.7767019272 0.7350031734 + 0.7665457726 0.7772976756 0.7356547117 + 0.7671412826 0.7778910995 0.7363024950 + 0.7677358985 0.7784829140 0.7369480133 + 0.7683303952 0.7790747881 0.7375935912 + 0.7689242959 0.7796661258 0.7382383943 + 0.7695142031 0.7802531719 0.7388777137 + 0.7701042295 0.7808402181 0.7395170927 + 0.7706941962 0.7814273238 0.7401564121 + 0.7712818980 0.7820110917 0.7407931089 + 0.7718682289 0.7825924754 0.7414278984 + 0.7724546194 0.7831739187 0.7420626879 + 0.7730407715 0.7837553024 0.7426972985 + 0.7736244798 0.7843334079 0.7433282137 + 0.7742081881 0.7849115729 0.7439591289 + 0.7747918963 0.7854897976 0.7445899844 + 0.7753731012 0.7860661745 0.7452182174 + 0.7759513855 0.7866402864 0.7458429933 + 0.7765296102 0.7872143984 0.7464678288 + 0.7771078944 0.7877886295 0.7470927238 + 0.7776818871 0.7883577943 0.7477130294 + 0.7782551050 0.7889257073 0.7483323216 + 0.7788282037 0.7894936800 0.7489516139 + 0.7794010043 0.7900611162 0.7495700717 + 0.7799720764 0.7906246781 0.7501844764 + 0.7805430889 0.7911882997 0.7507988214 + 0.7811141014 0.7917519212 0.7514132261 + 0.7816827893 0.7923139930 0.7520251870 + 0.7822489142 0.7928743958 0.7526345253 + 0.7828149796 0.7934347987 0.7532438040 + 0.7833812237 0.7939952016 0.7538530827 + 0.7839428782 0.7945516706 0.7544584870 + 0.7845032215 0.7951068282 0.7550626993 + 0.7850636244 0.7956619859 0.7556669116 + 0.7856239080 0.7962170839 0.7562711239 + 0.7861807942 0.7967674732 0.7568696141 + 0.7867377996 0.7973179221 0.7574681044 + 0.7872946858 0.7978683114 0.7580665946 + 0.7878506184 0.7984176874 0.7586637139 + 0.7884032726 0.7989639044 0.7592564225 + 0.7889561057 0.7995100021 0.7598490119 + 0.7895088196 0.8000562191 0.7604417205 + 0.7900593281 0.8006005883 0.7610327005 + 0.7906069756 0.8011425138 0.7616212964 + 0.7911546826 0.8016844988 0.7622098923 + 0.7917025089 0.8022264242 0.7627984881 + 0.7922484875 0.8027654886 0.7633846998 + 0.7927935123 0.8033025861 0.7639691830 + 0.7933384180 0.8038396239 0.7645537257 + 0.7938833833 0.8043767214 0.7651382089 + 0.7944257855 0.8049103022 0.7657201290 + 0.7949671745 0.8054423928 0.7663009763 + 0.7955086827 0.8059744239 0.7668818831 + 0.7960500717 0.8065065145 0.7674626708 + 0.7965880036 0.8070362210 0.7680410743 + 0.7971251011 0.8075652122 0.7686188221 + 0.7976623178 0.8080940843 0.7691965103 + 0.7981994152 0.8086230755 0.7697743177 + 0.7987347245 0.8091489077 0.7703492045 + 0.7992696762 0.8096740842 0.7709236741 + 0.7998046875 0.8101993203 0.7714982033 + 0.8003398180 0.8107244968 0.7720727921 + 0.8008722067 0.8112462759 0.7726444006 + 0.8014042974 0.8117675781 0.7732155919 + 0.8019365072 0.8122889996 0.7737869024 + 0.8024685979 0.8128103018 0.7743582129 + 0.8029965162 0.8133283257 0.7749258876 + 0.8035238981 0.8138456941 0.7754932046 + 0.8040512204 0.8143631816 0.7760605216 + 0.8045786023 0.8148807287 0.7766278982 + 0.8051033020 0.8153948188 0.7771916986 + 0.8056275249 0.8159083128 0.7777550220 + 0.8061518073 0.8164218068 0.7783182859 + 0.8066759706 0.8169354200 0.7788816094 + 0.8071985841 0.8174456954 0.7794430852 + 0.8077207208 0.8179551959 0.7800040841 + 0.8082427979 0.8184646964 0.7805652022 + 0.8087648749 0.8189740777 0.7811262012 + 0.8092843294 0.8194804788 0.7816848159 + 0.8098024726 0.8199853897 0.7822422981 + 0.8103206158 0.8204901814 0.7827997208 + 0.8108388186 0.8209950924 0.7833572030 + 0.8113549948 0.8214983940 0.7839121819 + 0.8118696213 0.8220003843 0.7844650149 + 0.8123841882 0.8225023746 0.7850177884 + 0.8128988147 0.8230044842 0.7855706811 + 0.8134121895 0.8235049844 0.7861223817 + 0.8139237761 0.8240029812 0.7866721749 + 0.8144353032 0.8245009780 0.7872220874 + 0.8149467707 0.8249989152 0.7877719998 + 0.8154575229 0.8254960775 0.7883214951 + 0.8159641027 0.8259888887 0.7888690233 + 0.8164708018 0.8264816999 0.7894164920 + 0.8169775009 0.8269745111 0.7899640203 + 0.8174842000 0.8274673223 0.7905114889 + 0.8179872036 0.8279569149 0.7910552025 + 0.8184900284 0.8284462094 0.7915986776 + 0.8189927936 0.8289356232 0.7921422124 + 0.8194956779 0.8294249177 0.7926856279 + 0.8199970126 0.8299115896 0.7932267785 + 0.8204975128 0.8303967714 0.7937667966 + 0.8209980130 0.8308820128 0.7943068743 + 0.8214985728 0.8313671947 0.7948468924 + 0.8219977021 0.8318507075 0.7953858972 + 0.8224940896 0.8323307037 0.7959229946 + 0.8229905963 0.8328106999 0.7964602113 + 0.8234871030 0.8332906961 0.7969973087 + 0.8239834905 0.8337706923 0.7975344062 + 0.8244758844 0.8342465758 0.7980670929 + 0.8249682188 0.8347225189 0.7985997200 + 0.8254604936 0.8351984024 0.7991324067 + 0.8259528875 0.8356742859 0.7996649742 + 0.8264433146 0.8361485004 0.8001952767 + 0.8269324899 0.8366215229 0.8007240295 + 0.8274217248 0.8370944858 0.8012526035 + 0.8279109001 0.8375675082 0.8017812967 + 0.8283994198 0.8380396962 0.8023093939 + 0.8288854957 0.8385075927 0.8028346896 + 0.8293715119 0.8389754891 0.8033601046 + 0.8298575878 0.8394433856 0.8038854003 + 0.8303436041 0.8399114013 0.8044108152 + 0.8308259249 0.8403760791 0.8049324751 + 0.8313068748 0.8408395052 0.8054528832 + 0.8317878842 0.8413029909 0.8059732914 + 0.8322690129 0.8417664170 0.8064936996 + 0.8327487707 0.8422294855 0.8070130944 + 0.8332253098 0.8426914215 0.8075290918 + 0.8337017894 0.8431531787 0.8080450892 + 0.8341782093 0.8436151147 0.8085610867 + 0.8346546888 0.8440768719 0.8090770841 + 0.8351281881 0.8445361853 0.8095903993 + 0.8356006742 0.8449943066 0.8101025224 + 0.8360731006 0.8454524279 0.8106147051 + 0.8365455270 0.8459104896 0.8111268878 + 0.8370172977 0.8463678956 0.8116385937 + 0.8374856114 0.8468207121 0.8121470809 + 0.8379539847 0.8472735286 0.8126556277 + 0.8384222984 0.8477262855 0.8131639957 + 0.8388906121 0.8481791019 0.8136724830 + 0.8393570185 0.8486301899 0.8141798973 + 0.8398215771 0.8490794897 0.8146862984 + 0.8402863145 0.8495287895 0.8151926994 + 0.8407509923 0.8499780893 0.8156991005 + 0.8412157297 0.8504275084 0.8162055016 + 0.8416776061 0.8508747816 0.8167092800 + 0.8421391249 0.8513218760 0.8172127008 + 0.8426007032 0.8517689705 0.8177161217 + 0.8430622220 0.8522161245 0.8182194829 + 0.8435230851 0.8526622057 0.8187221289 + 0.8439813852 0.8531038761 0.8192216754 + 0.8444396853 0.8535456061 0.8197212219 + 0.8448979855 0.8539872766 0.8202207088 + 0.8453562856 0.8544290066 0.8207201958 + 0.8458127975 0.8548687100 0.8212186098 + 0.8462672830 0.8553062081 0.8217157722 + 0.8467218876 0.8557437062 0.8222129941 + 0.8471763730 0.8561813235 0.8227102160 + 0.8476309180 0.8566188216 0.8232073784 + 0.8480827212 0.8570545912 0.8237022758 + 0.8485333920 0.8574895859 0.8241963983 + 0.8489841223 0.8579246998 0.8246904016 + 0.8494347930 0.8583598137 0.8251844049 + 0.8498855233 0.8587948084 0.8256785274 + 0.8503341079 0.8592264056 0.8261687160 + 0.8507825136 0.8596577048 0.8266587257 + 0.8512309790 0.8600888848 0.8271486163 + 0.8516793847 0.8605201840 0.8276385069 + 0.8521276116 0.8609511256 0.8281282187 + 0.8525732756 0.8613770008 0.8286157250 + 0.8530188799 0.8618029952 0.8291031122 + 0.8534644842 0.8622288704 0.8295904994 + 0.8539102077 0.8626548052 0.8300778866 + 0.8543549776 0.8630800843 0.8305646181 + 0.8547968268 0.8635025024 0.8310487270 + 0.8552384973 0.8639248013 0.8315327764 + 0.8556802869 0.8643472195 0.8320168257 + 0.8561220169 0.8647695184 0.8325008750 + 0.8565629721 0.8651912212 0.8329836726 + 0.8570019007 0.8656111956 0.8334634900 + 0.8574408293 0.8660312295 0.8339433074 + 0.8578798175 0.8664512038 0.8344230056 + 0.8583186865 0.8668712974 0.8349028230 + 0.8587570786 0.8672900796 0.8353816867 + 0.8591942787 0.8677062988 0.8358588219 + 0.8596314788 0.8681225181 0.8363357782 + 0.8600686789 0.8685386777 0.8368129134 + 0.8605058789 0.8689548969 0.8372899294 + 0.8609418869 0.8693702221 0.8377658725 + 0.8613752723 0.8697832823 0.8382393718 + 0.8618087173 0.8701964021 0.8387128711 + 0.8622421026 0.8706095219 0.8391863704 + 0.8626756072 0.8710225224 0.8396599889 + 0.8631076813 0.8714349866 0.8401322961 + 0.8635362983 0.8718457222 0.8406013846 + 0.8639649153 0.8722563982 0.8410704136 + 0.8643935919 0.8726670146 0.8415395021 + 0.8648222089 0.8730776906 0.8420084715 + 0.8652505279 0.8734877110 0.8424770832 + 0.8656774759 0.8738945723 0.8429431915 + 0.8661044836 0.8743014932 0.8434094191 + 0.8665313721 0.8747084141 0.8438755274 + 0.8669583797 0.8751152754 0.8443416953 + 0.8673852086 0.8755220175 0.8448076844 + 0.8678094745 0.8759253025 0.8452700973 + 0.8682336807 0.8763285875 0.8457326293 + 0.8686580062 0.8767318726 0.8461951017 + 0.8690822124 0.8771352172 0.8466575146 + 0.8695064783 0.8775385022 0.8471199870 + 0.8699274063 0.8779397011 0.8475784063 + 0.8703479767 0.8783406019 0.8480362296 + 0.8707684875 0.8787413836 0.8484939933 + 0.8711889982 0.8791422844 0.8489518762 + 0.8716096282 0.8795431852 0.8494096994 + 0.8720285892 0.8799425960 0.8498654962 + 0.8724468946 0.8803411722 0.8503202796 + 0.8728652000 0.8807398081 0.8507750034 + 0.8732835054 0.8811385036 0.8512297869 + 0.8737016916 0.8815370798 0.8516845107 + 0.8741189241 0.8819342852 0.8521381021 + 0.8745344281 0.8823292851 0.8525899053 + 0.8749498725 0.8827242255 0.8530418277 + 0.8753653765 0.8831192255 0.8534936905 + 0.8757808805 0.8835142255 0.8539454937 + 0.8761960268 0.8839088082 0.8543971181 + 0.8766077161 0.8842998147 0.8548464775 + 0.8770195246 0.8846908212 0.8552958965 + 0.8774312735 0.8850818872 0.8557451963 + 0.8778430223 0.8854728937 0.8561946154 + 0.8782547712 0.8858640194 0.8566439748 + 0.8786643744 0.8862522244 0.8570917845 + 0.8790733814 0.8866394758 0.8575391173 + 0.8794823885 0.8870269060 0.8579865098 + 0.8798913956 0.8874142170 0.8584337831 + 0.8803004026 0.8878015280 0.8588811159 + 0.8807088137 0.8881875873 0.8593277931 + 0.8811159730 0.8885713816 0.8597732186 + 0.8815233111 0.8889551759 0.8602187037 + 0.8819304705 0.8893390298 0.8606641293 + 0.8823376894 0.8897228837 0.8611094952 + 0.8827450275 0.8901066780 0.8615549803 + 0.8831487894 0.8904874921 0.8620001078 + 0.8835523725 0.8908680081 0.8624451160 + 0.8839560151 0.8912485242 0.8628901243 + 0.8843594790 0.8916289806 0.8633351922 + 0.8847631216 0.8920094967 0.8637802005 + 0.8851652741 0.8923885822 0.8642246723 + 0.8855656981 0.8927659988 0.8646684289 + 0.8859661818 0.8931434155 0.8651121855 + 0.8863667250 0.8935207725 0.8655558825 + 0.8867670894 0.8938981891 0.8659995794 + 0.8871675730 0.8942756057 0.8664432764 + 0.8875674009 0.8946498036 0.8668851256 + 0.8879672289 0.8950238228 0.8673267961 + 0.8883669972 0.8953977823 0.8677684069 + 0.8887668848 0.8957718015 0.8682100177 + 0.8891667128 0.8961458206 0.8686516881 + 0.8895655274 0.8965191841 0.8690931201 + 0.8899627924 0.8968914151 0.8695340753 + 0.8903599977 0.8972637057 0.8699750900 + 0.8907573223 0.8976359963 0.8704161048 + 0.8911545873 0.8980082870 0.8708571196 + 0.8915517926 0.8983805776 0.8712980747 + 0.8919457793 0.8987510800 0.8717380166 + 0.8923385739 0.8991209269 0.8721774817 + 0.8927314281 0.8994907141 0.8726168871 + 0.8931242824 0.8998606205 0.8730564117 + 0.8935170770 0.9002304077 0.8734958768 + 0.8939098120 0.9006000161 0.8739352226 + 0.8943005800 0.9009667039 0.8743724227 + 0.8946915269 0.9013332725 0.8748096228 + 0.8950822949 0.9017000198 0.8752468228 + 0.8954731822 0.9020665884 0.8756840229 + 0.8958641291 0.9024332762 0.8761211038 + 0.8962544203 0.9027994275 0.8765580058 + 0.8966438174 0.9031645060 0.8769943714 + 0.8970330954 0.9035295844 0.8774306774 + 0.8974224925 0.9038947225 0.8778669834 + 0.8978118896 0.9042598009 0.8783034086 + 0.8982012868 0.9046249986 0.8787397146 + 0.8985881209 0.9049890041 0.8791750073 + 0.8989732862 0.9053522944 0.8796095848 + 0.8993585110 0.9057155848 0.8800442219 + 0.8997436762 0.9060788751 0.8804787993 + 0.9001290202 0.9064422250 0.8809133768 + 0.9005141854 0.9068055153 0.8813480139 + 0.9008963704 0.9071661234 0.8817806840 + 0.9012778997 0.9075260162 0.8822128177 + 0.9016594291 0.9078859091 0.8826448917 + 0.9020408988 0.9082458019 0.8830770850 + 0.9024224281 0.9086055756 0.8835092187 + 0.9028040171 0.9089655280 0.8839412928 + 0.9031841755 0.9093214869 0.8843724132 + 0.9035643935 0.9096773267 0.8848034739 + 0.9039446115 0.9100331068 0.8852344751 + 0.9043248892 0.9103888273 0.8856655955 + 0.9047051072 0.9107446074 0.8860967159 + 0.9050850868 0.9111003280 0.8865275979 + 0.9054622054 0.9114549756 0.8869568110 + 0.9058393240 0.9118096828 0.8873859048 + 0.9062163830 0.9121643901 0.8878151178 + 0.9065935016 0.9125190973 0.8882442117 + 0.9069706202 0.9128738046 0.8886734247 + 0.9073473811 0.9132283926 0.8891022801 + 0.9077209830 0.9135813117 0.8895288110 + 0.9080945849 0.9139341712 0.8899552226 + 0.9084683061 0.9142870903 0.8903816938 + 0.9088419080 0.9146400094 0.8908082247 + 0.9092155099 0.9149929285 0.8912346959 + 0.9095889926 0.9153456092 0.8916611075 + 0.9099609852 0.9156950712 0.8920863271 + 0.9103329778 0.9160447121 0.8925114870 + 0.9107050896 0.9163941741 0.8929367065 + 0.9110770822 0.9167438149 0.8933618069 + 0.9114490747 0.9170932770 0.8937870264 + 0.9118210077 0.9174427986 0.8942121863 + 0.9121910930 0.9177901149 0.8946360946 + 0.9125611782 0.9181374907 0.8950601220 + 0.9129313231 0.9184848070 0.8954840899 + 0.9133014083 0.9188321233 0.8959079981 + 0.9136714935 0.9191794991 0.8963320255 + 0.9140415788 0.9195268154 0.8967558742 + 0.9144073725 0.9198731780 0.8971791863 + 0.9147729278 0.9202194810 0.8976023793 + 0.9151384234 0.9205657840 0.8980255723 + 0.9155039787 0.9209120274 0.8984488845 + 0.9158694744 0.9212582707 0.8988720775 + 0.9162350893 0.9216045737 0.8992952704 + 0.9165984988 0.9219489098 0.8997182250 + 0.9169613123 0.9222924709 0.9001411200 + 0.9173241854 0.9226362109 0.9005638957 + 0.9176871181 0.9229798913 0.9009867907 + 0.9180498719 0.9233235121 0.9014096856 + 0.9184128046 0.9236671925 0.9018325210 + 0.9187752008 0.9240090251 0.9022544026 + 0.9191372991 0.9243493080 0.9026756287 + 0.9194992781 0.9246897101 0.9030967951 + 0.9198613763 0.9250301123 0.9035180211 + 0.9202234149 0.9253705144 0.9039391875 + 0.9205855131 0.9257107973 0.9043604136 + 0.9209464192 0.9260510802 0.9047812223 + 0.9213050008 0.9263911247 0.9052013159 + 0.9216637015 0.9267311096 0.9056212902 + 0.9220224023 0.9270710945 0.9060413241 + 0.9223809838 0.9274110794 0.9064614177 + 0.9227396846 0.9277511239 0.9068813920 + 0.9230982065 0.9280911088 0.9073014259 + 0.9234530926 0.9284300804 0.9077206850 + 0.9238079786 0.9287689924 0.9081398845 + 0.9241629243 0.9291079044 0.9085592031 + 0.9245178103 0.9294468760 0.9089784026 + 0.9248725772 0.9297857881 0.9093977213 + 0.9252275229 0.9301248193 0.9098169804 + 0.9255810976 0.9304615259 0.9102349281 + 0.9259340167 0.9307969809 0.9106521010 + 0.9262868762 0.9311324954 0.9110692739 + 0.9266399145 0.9314680099 0.9114865065 + 0.9269927740 0.9318035841 0.9119036794 + 0.9273456931 0.9321390986 0.9123209119 + 0.9276980758 0.9324735999 0.9127377272 + 0.9280486703 0.9328051209 0.9131532907 + 0.9283993840 0.9331365824 0.9135689139 + 0.9287499785 0.9334679842 0.9139844775 + 0.9291006923 0.9337995052 0.9144001007 + 0.9294514060 0.9341309071 0.9148157835 + 0.9298020005 0.9344624281 0.9152314067 + 0.9301499724 0.9347928762 0.9156460762 + 0.9304972291 0.9351232052 0.9160605073 + 0.9308444262 0.9354534745 0.9164749980 + 0.9311916232 0.9357836843 0.9168894291 + 0.9315388203 0.9361140132 0.9173039198 + 0.9318860173 0.9364442825 0.9177182913 + 0.9322326779 0.9367740154 0.9181321263 + 0.9325779080 0.9371023774 0.9185441136 + 0.9329230189 0.9374307990 0.9189561009 + 0.9332681894 0.9377592206 0.9193680882 + 0.9336133003 0.9380875826 0.9197800756 + 0.9339584708 0.9384160042 0.9201921821 + 0.9343037009 0.9387444258 0.9206042290 + 0.9346480966 0.9390699267 0.9210147858 + 0.9349920750 0.9393941760 0.9214248061 + 0.9353361726 0.9397184253 0.9218348265 + 0.9356803298 0.9400426745 0.9222449064 + 0.9360243082 0.9403669238 0.9226549268 + 0.9363684058 0.9406911135 0.9230648875 + 0.9367122054 0.9410151839 0.9234749079 + 0.9370527267 0.9413359165 0.9238840938 + 0.9373931885 0.9416565895 0.9242933989 + 0.9377337098 0.9419773817 0.9247027040 + 0.9380741715 0.9422981143 0.9251120090 + 0.9384146929 0.9426189065 0.9255211949 + 0.9387552142 0.9429395795 0.9259305000 + 0.9390947223 0.9432600141 0.9263395071 + 0.9394326210 0.9435796142 0.9267479181 + 0.9397705197 0.9438992739 0.9271563888 + 0.9401084185 0.9442188740 0.9275647998 + 0.9404463172 0.9445385933 0.9279732704 + 0.9407842755 0.9448581934 0.9283816814 + 0.9411221743 0.9451779127 0.9287902117 + 0.9414592981 0.9454959035 0.9291977882 + 0.9417958856 0.9458130002 0.9296048880 + 0.9421325922 0.9461300969 0.9300119877 + 0.9424692988 0.9464471936 0.9304192066 + 0.9428058863 0.9467642903 0.9308263063 + 0.9431425929 0.9470815063 0.9312335253 + 0.9434792995 0.9473986030 0.9316406250 + 0.9438139200 0.9477123022 0.9320465922 + 0.9441481829 0.9480254054 0.9324523807 + 0.9444825053 0.9483386278 0.9328582287 + 0.9448167086 0.9486516714 0.9332640171 + 0.9451509714 0.9489647746 0.9336698055 + 0.9454852939 0.9492779970 0.9340755939 + 0.9458196163 0.9495911002 0.9344813228 + 0.9461503029 0.9499025941 0.9348856807 + 0.9464811087 0.9502142072 0.9352900982 + 0.9468119144 0.9505257010 0.9356945157 + 0.9471427202 0.9508371949 0.9360988140 + 0.9474734068 0.9511486888 0.9365031719 + 0.9478042126 0.9514601827 0.9369075894 + 0.9481347203 0.9517716765 0.9373118281 + 0.9484633207 0.9520822167 0.9377142191 + 0.9487919211 0.9523928165 0.9381167293 + 0.9491205215 0.9527034163 0.9385191798 + 0.9494491220 0.9530138969 0.9389216900 + 0.9497776031 0.9533244967 0.9393242002 + 0.9501062036 0.9536349773 0.9397267103 + 0.9504346251 0.9539452195 0.9401286840 + 0.9507619739 0.9542526007 0.9405273795 + 0.9510893226 0.9545599818 0.9409261942 + 0.9514166713 0.9548674226 0.9413250089 + 0.9517440200 0.9551748037 0.9417237043 + 0.9520713091 0.9554821253 0.9421225190 + 0.9523987174 0.9557895064 0.9425212145 + 0.9527255893 0.9560965896 0.9429191947 + 0.9530493021 0.9564006925 0.9433112144 + 0.9533730745 0.9567047954 0.9437032938 + 0.9536967874 0.9570088983 0.9440953135 + 0.9540205002 0.9573130012 0.9444872737 + 0.9543442726 0.9576171041 0.9448792934 + 0.9546679854 0.9579212070 0.9452713132 + 0.9549915195 0.9582251906 0.9456630945 + 0.9553105235 0.9585260153 0.9460486770 + 0.9556294084 0.9588267803 0.9464343190 + 0.9559482932 0.9591276050 0.9468199015 + 0.9562671781 0.9594284296 0.9472054839 + 0.9565861225 0.9597290754 0.9475911260 + 0.9569051266 0.9600299001 0.9479767084 + 0.9572240114 0.9603307247 0.9483622909 + 0.9575372934 0.9606264234 0.9487441778 + 0.9578500986 0.9609215260 0.9491255879 + 0.9581627846 0.9612166286 0.9495071173 + 0.9584754705 0.9615116715 0.9498885870 + 0.9587882161 0.9618067741 0.9502701163 + 0.9591010213 0.9621018767 0.9506515265 + 0.9594137073 0.9623970985 0.9510329962 + 0.9597231150 0.9626886845 0.9514123797 + 0.9600310922 0.9629788995 0.9517909288 + 0.9603391290 0.9632689953 0.9521692991 + 0.9606471062 0.9635592103 0.9525477886 + 0.9609550834 0.9638493061 0.9529262781 + 0.9612631202 0.9641395211 0.9533047080 + 0.9615712166 0.9644296765 0.9536831975 + 0.9618782997 0.9647189975 0.9540600777 + 0.9621844292 0.9650071859 0.9544352293 + 0.9624904990 0.9652954936 0.9548102021 + 0.9627966285 0.9655836821 0.9551852942 + 0.9631026983 0.9658719897 0.9555603266 + 0.9634088278 0.9661601782 0.9559352994 + 0.9637148976 0.9664484859 0.9563103914 + 0.9640207887 0.9667364955 0.9566850066 + 0.9643250704 0.9670230150 0.9570569992 + 0.9646294117 0.9673094153 0.9574289918 + 0.9649336934 0.9675958753 0.9578009844 + 0.9652379751 0.9678822756 0.9581729770 + 0.9655423164 0.9681687951 0.9585450292 + 0.9658465981 0.9684551954 0.9589170218 + 0.9661508799 0.9687417150 0.9592890143 + 0.9664528966 0.9690259099 0.9596589804 + 0.9667541981 0.9693092108 0.9600282907 + 0.9670553803 0.9695925713 0.9603976011 + 0.9673566818 0.9698758721 0.9607669115 + 0.9676579237 0.9701592922 0.9611362219 + 0.9679592252 0.9704425931 0.9615054727 + 0.9682604074 0.9707260132 0.9618747830 + 0.9685606956 0.9710081220 0.9622433186 + 0.9688587785 0.9712873101 0.9626101255 + 0.9691568017 0.9715664983 0.9629768133 + 0.9694548845 0.9718456864 0.9633435011 + 0.9697530270 0.9721248746 0.9637103081 + 0.9700509906 0.9724041224 0.9640769958 + 0.9703490734 0.9726833105 0.9644438028 + 0.9706472158 0.9729624987 0.9648104906 + 0.9709429741 0.9732391238 0.9651746154 + 0.9712383747 0.9735150933 0.9655379057 + 0.9715337157 0.9737911224 0.9659013152 + 0.9718289971 0.9740669727 0.9662647247 + 0.9721243978 0.9743430018 0.9666280746 + 0.9724196792 0.9746189713 0.9669914842 + 0.9727150202 0.9748950005 0.9673548937 + 0.9730095863 0.9751701951 0.9677174091 + 0.9733015895 0.9754428864 0.9680770040 + 0.9735935926 0.9757155776 0.9684365988 + 0.9738855958 0.9759883285 0.9687961936 + 0.9741775990 0.9762610197 0.9691557884 + 0.9744696021 0.9765337110 0.9695153832 + 0.9747616053 0.9768065214 0.9698749185 + 0.9750537276 0.9770792127 0.9702345133 + 0.9753432274 0.9773492813 0.9705916047 + 0.9756311178 0.9776179194 0.9709470868 + 0.9759190083 0.9778863788 0.9713026285 + 0.9762068987 0.9781550169 0.9716581106 + 0.9764947891 0.9784234762 0.9720135927 + 0.9767827988 0.9786919951 0.9723690748 + 0.9770706892 0.9789605737 0.9727246165 + 0.9773585796 0.9792290926 0.9730800986 + 0.9776431918 0.9794937968 0.9734309912 + 0.9779276252 0.9797580838 0.9737815261 + 0.9782118797 0.9800224900 0.9741320014 + 0.9784963131 0.9802867770 0.9744824767 + 0.9787806273 0.9805511236 0.9748330116 + 0.9790650010 0.9808154106 0.9751834869 + 0.9793493152 0.9810798168 0.9755340219 + 0.9796329737 0.9813433886 0.9758836031 + 0.9799132943 0.9816035032 0.9762284756 + 0.9801936150 0.9818636179 0.9765734076 + 0.9804738760 0.9821236730 0.9769182801 + 0.9807541966 0.9823837876 0.9772632122 + 0.9810345769 0.9826439023 0.9776080251 + 0.9813148975 0.9829040170 0.9779528975 + 0.9815952182 0.9831640720 0.9782978296 + 0.9818738103 0.9834225178 0.9786403775 + 0.9821494222 0.9836776853 0.9789785743 + 0.9824249148 0.9839329123 0.9793167710 + 0.9827005267 0.9841880798 0.9796550274 + 0.9829760790 0.9844433069 0.9799932837 + 0.9832515717 0.9846984744 0.9803314805 + 0.9835271835 0.9849537015 0.9806696773 + 0.9838027954 0.9852089286 0.9810078740 + 0.9840760231 0.9854617715 0.9813424945 + 0.9843466878 0.9857121110 0.9816730022 + 0.9846174121 0.9859622717 0.9820033908 + 0.9848880768 0.9862126112 0.9823338985 + 0.9851588011 0.9864627719 0.9826642871 + 0.9854295254 0.9867131114 0.9829946756 + 0.9857001901 0.9869632721 0.9833251834 + 0.9859709144 0.9872136116 0.9836555719 + 0.9862385988 0.9874609709 0.9839816093 + 0.9865036011 0.9877058268 0.9843034744 + 0.9867686033 0.9879505038 0.9846252799 + 0.9870337248 0.9881951809 0.9849470854 + 0.9872987270 0.9884399772 0.9852690101 + 0.9875637293 0.9886847138 0.9855908155 + 0.9878286719 0.9889293909 0.9859126210 + 0.9880936742 0.9891741872 0.9862344265 + 0.9883552790 0.9894152284 0.9865508080 + 0.9886137247 0.9896525741 0.9868618250 + 0.9888721108 0.9898899198 0.9871727824 + 0.9891304970 0.9901272058 0.9874837995 + 0.9893888831 0.9903646111 0.9877948165 + 0.9896472096 0.9906018972 0.9881057143 + 0.9899055958 0.9908393025 0.9884166718 + 0.9901639819 0.9910765886 0.9887276888 + 0.9904199243 0.9913105965 0.9890335202 + 0.9906725883 0.9915400147 0.9893323183 + 0.9909251928 0.9917694926 0.9896311164 + 0.9911777973 0.9919989109 0.9899299145 + 0.9914304018 0.9922283292 0.9902285933 + 0.9916830063 0.9924576879 0.9905273914 + 0.9919356108 0.9926871061 0.9908261895 + 0.9921882153 0.9929165244 0.9911249876 + 0.9924386740 0.9931442142 0.9914202094 + 0.9926838279 0.9933673143 0.9917060137 + 0.9929288030 0.9935904145 0.9919918180 + 0.9931738973 0.9938135147 0.9922776222 + 0.9934189916 0.9940366149 0.9925634265 + 0.9936640263 0.9942597151 0.9928491712 + 0.9939091206 0.9944828153 0.9931349754 + 0.9941540956 0.9947059751 0.9934207201 + 0.9943984747 0.9949285984 0.9937055707 + 0.9946327806 0.9951431751 0.9939746857 + 0.9948670864 0.9953578115 0.9942438006 + 0.9951013923 0.9955723882 0.9945129156 + 0.9953356981 0.9957870841 0.9947819710 + 0.9955700040 0.9960017204 0.9950512052 + 0.9958043098 0.9962162971 0.9953203201 + 0.9960386157 0.9964308739 0.9955893755 + 0.9962729216 0.9966455102 0.9958584905 + 0.9964994192 0.9968507290 0.9961140156 + 0.9967237115 0.9970530868 0.9963654280 + 0.9969478846 0.9972555041 0.9966169000 + 0.9971721768 0.9974579215 0.9968683720 + 0.9973964095 0.9976602793 0.9971199036 + 0.9976207018 0.9978626966 0.9973713756 + 0.9978448749 0.9980651140 0.9976227880 + 0.9980692267 0.9982674718 0.9978743196 + 0.9982891083 0.9984654784 0.9981188774 + 0.9985029101 0.9986572862 0.9983540177 + 0.9987167716 0.9988490939 0.9985892177 + 0.9989306927 0.9990409017 0.9988242984 + 0.9991444945 0.9992327094 0.9990593791 + 0.9993584156 0.9994245768 0.9992945790 + 0.9995722771 0.9996163845 0.9995297194 + 0.9997860789 0.9998081923 0.9997649193 + 1.0000000000 1.0000000000 1.0000000000 +} diff --git a/rpplugins/color_correction/resources/film_luts_raw/agfa_agfacolor_futura_ii_100.spi1d b/rpplugins/color_correction/resources/film_luts_raw/agfa_agfacolor_futura_ii_100.spi1d new file mode 100644 index 0000000..9545367 --- /dev/null +++ b/rpplugins/color_correction/resources/film_luts_raw/agfa_agfacolor_futura_ii_100.spi1d @@ -0,0 +1,1030 @@ +Version 1 +From 0.0 1.0 +Length 1024 +Components 3 +{ + 0.0000000000 0.0000000000 0.0000000000 + 0.0089918738 0.0088112270 0.0067409412 + 0.0171655007 0.0167162009 0.0131348101 + 0.0242981501 0.0235243607 0.0187877901 + 0.0308058802 0.0297358502 0.0239518695 + 0.0368227884 0.0355986990 0.0288143605 + 0.0424588397 0.0412245393 0.0334390104 + 0.0477601402 0.0466648601 0.0378785282 + 0.0527938083 0.0519550890 0.0421676189 + 0.0575832911 0.0571624711 0.0463436693 + 0.0622247718 0.0623087510 0.0504317991 + 0.0668161213 0.0673468485 0.0544279404 + 0.0713887885 0.0722417235 0.0583436601 + 0.0759282932 0.0769878626 0.0621980987 + 0.0804320127 0.0816073194 0.0659957901 + 0.0848805234 0.0860867798 0.0697494522 + 0.0892914683 0.0904396772 0.0734607279 + 0.0936586633 0.0946798995 0.0771252811 + 0.0979755297 0.0988209695 0.0807478875 + 0.1022336036 0.1028660983 0.0843302682 + 0.1064319983 0.1068392023 0.0878701210 + 0.1105559021 0.1107354984 0.0913715884 + 0.1146129966 0.1145422980 0.0948381424 + 0.1185963973 0.1182733998 0.0982583165 + 0.1225240976 0.1219324991 0.1016350016 + 0.1263933927 0.1255291998 0.1049719974 + 0.1301935017 0.1290597022 0.1082687974 + 0.1339209974 0.1325256974 0.1115282029 + 0.1375810951 0.1359412074 0.1147558987 + 0.1411647946 0.1393028945 0.1179407015 + 0.1446768939 0.1426129043 0.1210891977 + 0.1481269002 0.1458766013 0.1242009997 + 0.1515025944 0.1490920037 0.1272723973 + 0.1548155993 0.1522623003 0.1303056926 + 0.1580781043 0.1553830951 0.1333058029 + 0.1612831950 0.1584683955 0.1362698972 + 0.1644275039 0.1615206003 0.1391921043 + 0.1675149053 0.1645296961 0.1420771927 + 0.1705511063 0.1675007045 0.1449283957 + 0.1735346019 0.1704356074 0.1477468014 + 0.1764681935 0.1733424962 0.1505275071 + 0.1793411970 0.1762108952 0.1532687992 + 0.1821642965 0.1790487021 0.1559778005 + 0.1849396974 0.1818661988 0.1586564928 + 0.1876723021 0.1846542954 0.1613045037 + 0.1903574020 0.1874137968 0.1639243066 + 0.1929987073 0.1901445985 0.1665160060 + 0.1956039965 0.1928485036 0.1690804064 + 0.1981741041 0.1955288947 0.1716223955 + 0.2007140964 0.1981831044 0.1741400957 + 0.2032240033 0.2008188963 0.1766290963 + 0.2057044953 0.2034270018 0.1790864021 + 0.2081623971 0.2060122043 0.1815200001 + 0.2106028944 0.2085773945 0.1839299053 + 0.2130292058 0.2111182064 0.1863144040 + 0.2154411972 0.2136391997 0.1886768937 + 0.2178471982 0.2161431015 0.1910151988 + 0.2202418000 0.2186270058 0.1933256984 + 0.2226282060 0.2210904956 0.1956081986 + 0.2250116020 0.2235327959 0.1978694052 + 0.2273910940 0.2259615064 0.2001121938 + 0.2297631949 0.2283712029 0.2023327053 + 0.2321317047 0.2307610959 0.2045315057 + 0.2344924062 0.2331354022 0.2067105025 + 0.2368433028 0.2354861945 0.2088731974 + 0.2391863018 0.2378192991 0.2110181004 + 0.2415205985 0.2401355058 0.2131436020 + 0.2438464016 0.2424366027 0.2152539939 + 0.2461618036 0.2447226048 0.2173456997 + 0.2484730929 0.2469923943 0.2194202989 + 0.2507739067 0.2492519021 0.2214788944 + 0.2530598044 0.2514967918 0.2235199958 + 0.2553376853 0.2537238002 0.2255467027 + 0.2576029897 0.2559401989 0.2275560051 + 0.2598524094 0.2581427991 0.2295472026 + 0.2620919049 0.2603318095 0.2315239012 + 0.2643215060 0.2625105977 0.2334856987 + 0.2665401995 0.2646790147 0.2354328036 + 0.2687489986 0.2668366134 0.2373681068 + 0.2709451020 0.2689833045 0.2392894030 + 0.2731316984 0.2711197138 0.2411931008 + 0.2753098011 0.2732459903 0.2430835962 + 0.2774744034 0.2753610909 0.2449620068 + 0.2796306908 0.2774659097 0.2468270957 + 0.2817795873 0.2795613110 0.2486820072 + 0.2839165926 0.2816452086 0.2505275905 + 0.2860453129 0.2837195992 0.2523604929 + 0.2881659865 0.2857829928 0.2541792989 + 0.2902776897 0.2878372073 0.2559899092 + 0.2923803031 0.2898777127 0.2577917874 + 0.2944732904 0.2919048965 0.2595866024 + 0.2965568006 0.2939237952 0.2613756955 + 0.2986293137 0.2959322035 0.2631560862 + 0.3006938994 0.2979266047 0.2649283111 + 0.3027508855 0.2999104857 0.2666937113 + 0.3047966063 0.3018867075 0.2684526145 + 0.3068324924 0.3038511872 0.2702021897 + 0.3088631034 0.3058032095 0.2719438076 + 0.3108848929 0.3077456951 0.2736783028 + 0.3128944933 0.3096817136 0.2754063010 + 0.3148933947 0.3116078973 0.2771281898 + 0.3168857992 0.3135224879 0.2788479924 + 0.3188689053 0.3154281080 0.2805649042 + 0.3208411932 0.3173280954 0.2822758853 + 0.3228051066 0.3192209005 0.2839803994 + 0.3247616887 0.3211036026 0.2856811881 + 0.3267089128 0.3229758143 0.2873789072 + 0.3286511004 0.3248389959 0.2890717983 + 0.3305900991 0.3266923130 0.2907603085 + 0.3325229883 0.3285365999 0.2924445868 + 0.3344469070 0.3303725123 0.2941254079 + 0.3363626897 0.3322010040 0.2958011925 + 0.3382742107 0.3340212107 0.2974714935 + 0.3401803970 0.3358336091 0.2991386950 + 0.3420785964 0.3376361132 0.3008036017 + 0.3439661860 0.3394295871 0.3024663031 + 0.3458459079 0.3412173986 0.3041245043 + 0.3477211893 0.3429979980 0.3057765961 + 0.3495895863 0.3447695971 0.3074248135 + 0.3514491022 0.3465310931 0.3090695143 + 0.3533000052 0.3482857049 0.3107109964 + 0.3551431000 0.3500339985 0.3123489022 + 0.3569791913 0.3517752886 0.3139818907 + 0.3588086069 0.3535098135 0.3156122863 + 0.3606314957 0.3552359939 0.3172419071 + 0.3624485135 0.3569523096 0.3188686073 + 0.3642578125 0.3586593866 0.3204928041 + 0.3660599887 0.3603613079 0.3221142888 + 0.3678553998 0.3620558083 0.3237330914 + 0.3696443141 0.3637424111 0.3253495991 + 0.3714273870 0.3654215038 0.3269616067 + 0.3732031882 0.3670935929 0.3285692930 + 0.3749721944 0.3687596917 0.3301742971 + 0.3767344952 0.3704194129 0.3317768872 + 0.3784905076 0.3720717132 0.3333773017 + 0.3802404106 0.3737153113 0.3349755108 + 0.3819842935 0.3753502071 0.3365707099 + 0.3837207854 0.3769770861 0.3381618857 + 0.3854480982 0.3785960078 0.3397505879 + 0.3871636093 0.3802081048 0.3413363993 + 0.3888713121 0.3818149865 0.3429175913 + 0.3905732930 0.3834156990 0.3444958925 + 0.3922694027 0.3850092888 0.3460716903 + 0.3939583898 0.3865957856 0.3476448953 + 0.3956395090 0.3881759942 0.3492155969 + 0.3973124027 0.3897528052 0.3507837951 + 0.3989773989 0.3913241029 0.3523463905 + 0.4006344974 0.3928903043 0.3539063931 + 0.4022842050 0.3944503963 0.3554647863 + 0.4039269090 0.3960036933 0.3570212126 + 0.4055627882 0.3975501060 0.3585749865 + 0.4071914852 0.3990882933 0.3601273000 + 0.4088127911 0.4006206095 0.3616780043 + 0.4104264975 0.4021480083 0.3632257879 + 0.4120318890 0.4036706090 0.3647710979 + 0.4136281908 0.4051879048 0.3663145900 + 0.4152132869 0.4066968858 0.3678534031 + 0.4167909920 0.4081991017 0.3693884909 + 0.4183610082 0.4096961021 0.3709208965 + 0.4199230969 0.4111889005 0.3724510074 + 0.4214732051 0.4126752913 0.3739764094 + 0.4230127037 0.4141556919 0.3754990995 + 0.4245432913 0.4156309962 0.3770196140 + 0.4260652065 0.4171015918 0.3785375953 + 0.4275765121 0.4185652137 0.3800503016 + 0.4290784895 0.4200240970 0.3815599978 + 0.4305722117 0.4214783013 0.3830671012 + 0.4320571125 0.4229275882 0.3845714033 + 0.4335275888 0.4243701994 0.3860712945 + 0.4349885881 0.4258084893 0.3875694871 + 0.4364405870 0.4272427857 0.3890654147 + 0.4378808141 0.4286721051 0.3905574977 + 0.4393113852 0.4300973117 0.3920451999 + 0.4407345057 0.4315193892 0.3935315013 + 0.4421485960 0.4329378009 0.3950169981 + 0.4435501993 0.4343496859 0.3964990079 + 0.4449434876 0.4357573986 0.3979789019 + 0.4463286996 0.4371610880 0.3994567990 + 0.4477010071 0.4385577142 0.4009310007 + 0.4490672052 0.4399507046 0.4024015069 + 0.4504272938 0.4413402975 0.4038689137 + 0.4517762065 0.4427213967 0.4053323865 + 0.4531182945 0.4440990090 0.4067929983 + 0.4544540942 0.4454734921 0.4082511961 + 0.4557775855 0.4468427896 0.4097048938 + 0.4570952952 0.4482089877 0.4111567140 + 0.4584074914 0.4495720863 0.4126070142 + 0.4597108960 0.4509283006 0.4140538871 + 0.4610100091 0.4522809982 0.4154989123 + 0.4623034894 0.4536291957 0.4169419110 + 0.4635887146 0.4549719095 0.4183813035 + 0.4648694992 0.4563120902 0.4198183119 + 0.4661431015 0.4576481879 0.4212512076 + 0.4674094021 0.4589804113 0.4226809144 + 0.4686715007 0.4603103101 0.4241088927 + 0.4699237943 0.4616335034 0.4255332053 + 0.4711718857 0.4629541039 0.4269537926 + 0.4724155962 0.4642721117 0.4283713996 + 0.4736534059 0.4655844867 0.4297845066 + 0.4748887122 0.4668945074 0.4311957955 + 0.4761190116 0.4681994021 0.4326032996 + 0.4773451984 0.4694997966 0.4340074062 + 0.4785684049 0.4707967937 0.4354093969 + 0.4797854125 0.4720880985 0.4368061125 + 0.4810002148 0.4733774066 0.4382002950 + 0.4822092950 0.4746614993 0.4395891130 + 0.4834147990 0.4759416878 0.4409742951 + 0.4846169055 0.4772185087 0.4423570931 + 0.4858146906 0.4784907103 0.4437364042 + 0.4870111048 0.4797612131 0.4451141953 + 0.4882034063 0.4810256064 0.4464867115 + 0.4893937111 0.4822880924 0.4478574991 + 0.4905807078 0.4835473895 0.4492256939 + 0.4917649031 0.4848031998 0.4505923092 + 0.4929473102 0.4860568047 0.4519579113 + 0.4941253960 0.4873049855 0.4533194900 + 0.4953022897 0.4885519147 0.4546799958 + 0.4964750111 0.4897922873 0.4560363889 + 0.4976463020 0.4910312891 0.4573906064 + 0.4988138080 0.4922665060 0.4587404132 + 0.4999791980 0.4934988022 0.4600867033 + 0.5011422038 0.4947274923 0.4614296854 + 0.5023019910 0.4959532917 0.4627693892 + 0.5034598708 0.4971773922 0.4641076028 + 0.5046142936 0.4983972907 0.4654398859 + 0.5057677031 0.4996159971 0.4667710960 + 0.5069164038 0.5008293986 0.4680955112 + 0.5080643892 0.5020418763 0.4694189131 + 0.5092083812 0.5032485127 0.4707360864 + 0.5103514194 0.5044537783 0.4720517099 + 0.5114902854 0.5056533813 0.4733619988 + 0.5126280189 0.5068514943 0.4746705890 + 0.5137624741 0.5080453753 0.4759756923 + 0.5148952007 0.5092371702 0.4772787094 + 0.5160247087 0.5104253888 0.4785786867 + 0.5171523094 0.5116108060 0.4798755050 + 0.5182775259 0.5127922893 0.4811685979 + 0.5194002986 0.5139706731 0.4824582040 + 0.5205205083 0.5151454806 0.4837445021 + 0.5216385126 0.5163174272 0.4850262105 + 0.5227543712 0.5174863935 0.4863041043 + 0.5238677263 0.5186526775 0.4875771999 + 0.5249785781 0.5198165774 0.4888466895 + 0.5260874033 0.5209770203 0.4901134968 + 0.5271940231 0.5221341848 0.4913783967 + 0.5282983184 0.5232884884 0.4926396906 + 0.5294001102 0.5244398713 0.4938982129 + 0.5304998755 0.5255879164 0.4951525033 + 0.5315973759 0.5267319083 0.4964028895 + 0.5326929092 0.5278732777 0.4976496994 + 0.5337855816 0.5290107727 0.4988923073 + 0.5348768830 0.5301455259 0.5001319051 + 0.5359653831 0.5312750936 0.5013670921 + 0.5370525718 0.5324026942 0.5025998950 + 0.5381363034 0.5335251093 0.5038275123 + 0.5392193198 0.5346459746 0.5050536990 + 0.5402988195 0.5357596874 0.5062742829 + 0.5413780808 0.5368732214 0.5074942708 + 0.5424528718 0.5379806757 0.5087080002 + 0.5435277224 0.5390880704 0.5099217296 + 0.5445986986 0.5401890874 0.5111290216 + 0.5456693172 0.5412895083 0.5123360753 + 0.5467364192 0.5423848033 0.5135380030 + 0.5478023291 0.5434783101 0.5147387981 + 0.5488657951 0.5445675254 0.5159347057 + 0.5499275923 0.5456534028 0.5171278119 + 0.5509874821 0.5467371941 0.5183176994 + 0.5520446897 0.5478175282 0.5195037723 + 0.5531010032 0.5488967896 0.5206878185 + 0.5541540980 0.5499712825 0.5218651891 + 0.5552070737 0.5510457754 0.5230425000 + 0.5562556982 0.5521146059 0.5242115855 + 0.5573040843 0.5531831980 0.5253806710 + 0.5583497286 0.5542473793 0.5265437961 + 0.5593940020 0.5553098917 0.5277050734 + 0.5604363084 0.5563696027 0.5288618803 + 0.5614761114 0.5574259162 0.5300140977 + 0.5625151992 0.5584810972 0.5311648846 + 0.5635510087 0.5595309734 0.5323101282 + 0.5645866990 0.5605809093 0.5334553123 + 0.5656185150 0.5616251826 0.5345945954 + 0.5666496754 0.5626686215 0.5357334018 + 0.5676786900 0.5637084246 0.5368676782 + 0.5687059760 0.5647451878 0.5379989743 + 0.5697323084 0.5657805800 0.5391280055 + 0.5707550049 0.5668106079 0.5402505994 + 0.5717777014 0.5678406954 0.5413731933 + 0.5727970004 0.5688648820 0.5424870849 + 0.5738158226 0.5698879957 0.5435999036 + 0.5748323798 0.5709078908 0.5447078943 + 0.5758466721 0.5719239712 0.5458114147 + 0.5768607259 0.5729396939 0.5469142199 + 0.5778710842 0.5739501119 0.5480110049 + 0.5788813829 0.5749605894 0.5491077900 + 0.5798888803 0.5759674907 0.5501992106 + 0.5808948278 0.5769727230 0.5512881875 + 0.5818998814 0.5779765844 0.5523753166 + 0.5829018950 0.5789757967 0.5534570813 + 0.5839039087 0.5799751282 0.5545389056 + 0.5849025846 0.5809702873 0.5556156039 + 0.5859003067 0.5819640756 0.5566909909 + 0.5868967772 0.5829563141 0.5577639937 + 0.5878906250 0.5839440823 0.5588322282 + 0.5888844132 0.5849320292 0.5599002838 + 0.5898746848 0.5859153867 0.5609617233 + 0.5908641219 0.5868976116 0.5620216727 + 0.5918524861 0.5878787041 0.5630789995 + 0.5928381085 0.5888563991 0.5641300082 + 0.5938236713 0.5898339748 0.5651810169 + 0.5948061943 0.5908092260 0.5662257075 + 0.5957874060 0.5917832851 0.5672683120 + 0.5967680812 0.5927566886 0.5683094859 + 0.5977455974 0.5937262774 0.5693448782 + 0.5987229943 0.5946959257 0.5703802705 + 0.5996980071 0.5956636071 0.5714107752 + 0.6006711721 0.5966296196 0.5724381804 + 0.6016442776 0.5975956917 0.5734654069 + 0.6026139259 0.5985574722 0.5744841099 + 0.6035832763 0.5995190740 0.5755028725 + 0.6045511961 0.6004796028 0.5765179992 + 0.6055163741 0.6014376879 0.5775272250 + 0.6064814925 0.6023957729 0.5785365105 + 0.6074441075 0.6033508778 0.5795394778 + 0.6084054708 0.6043046117 0.5805402994 + 0.6093667746 0.6052582264 0.5815405846 + 0.6103240252 0.6062085032 0.5825338960 + 0.6112812161 0.6071587205 0.5835272074 + 0.6122370958 0.6081075072 0.5845175982 + 0.6131905913 0.6090533137 0.5855029821 + 0.6141440868 0.6099991798 0.5864884853 + 0.6150950193 0.6109429002 0.5874683857 + 0.6160442829 0.6118853092 0.5884453058 + 0.6169936061 0.6128277183 0.5894222260 + 0.6179397106 0.6137663126 0.5903909206 + 0.6188852787 0.6147043109 0.5913589001 + 0.6198304892 0.6156420112 0.5923253894 + 0.6207720041 0.6165766120 0.5932837725 + 0.6217133999 0.6175112128 0.5942422152 + 0.6226537228 0.6184443831 0.5951976180 + 0.6235914826 0.6193746924 0.5961477160 + 0.6245294213 0.6203050017 0.5970978737 + 0.6254649758 0.6212335825 0.5980439782 + 0.6263986826 0.6221604943 0.5989869237 + 0.6273323894 0.6230874062 0.5999299288 + 0.6282635927 0.6240113974 0.6008661985 + 0.6291937232 0.6249340177 0.6018002033 + 0.6301239133 0.6258566976 0.6027342081 + 0.6310505271 0.6267765164 0.6036599874 + 0.6319764853 0.6276957989 0.6045848131 + 0.6329025030 0.6286150813 0.6055094004 + 0.6338251233 0.6295301914 0.6064245105 + 0.6347475052 0.6304453015 0.6073396206 + 0.6356697083 0.6313601136 0.6082538962 + 0.6365880966 0.6322718263 0.6091607809 + 0.6375064254 0.6331834793 0.6100676060 + 0.6384242773 0.6340945959 0.6109727025 + 0.6393392086 0.6350020766 0.6118695140 + 0.6402540207 0.6359096169 0.6127663255 + 0.6411681175 0.6368162036 0.6136608124 + 0.6420788765 0.6377186179 0.6145474911 + 0.6429896951 0.6386210918 0.6154342294 + 0.6438996792 0.6395224929 0.6163187027 + 0.6448069811 0.6404194832 0.6171966195 + 0.6457142830 0.6413165927 0.6180744767 + 0.6466206908 0.6422126889 0.6189501882 + 0.6475239992 0.6431049109 0.6198194027 + 0.6484273076 0.6439971924 0.6206886172 + 0.6493299007 0.6448885202 0.6215558052 + 0.6502298117 0.6457754970 0.6224160790 + 0.6511296034 0.6466624737 0.6232764721 + 0.6520287991 0.6475486159 0.6241351962 + 0.6529247165 0.6484292150 0.6249868274 + 0.6538205147 0.6493096948 0.6258383989 + 0.6547160745 0.6501898170 0.6266890764 + 0.6556084752 0.6510639787 0.6275333762 + 0.6565008759 0.6519382000 0.6283777952 + 0.6573932767 0.6528124213 0.6292219758 + 0.6582819223 0.6536806226 0.6300593019 + 0.6591703296 0.6545485854 0.6308966279 + 0.6600587964 0.6554166079 0.6317338943 + 0.6609442830 0.6562796235 0.6325649023 + 0.6618294120 0.6571416855 0.6333950758 + 0.6627144217 0.6580038071 0.6342253089 + 0.6635968089 0.6588618159 0.6350504160 + 0.6644778848 0.6597180963 0.6358736753 + 0.6653590202 0.6605743766 0.6366969943 + 0.6662384272 0.6614277959 0.6375163794 + 0.6671161056 0.6622784734 0.6383327842 + 0.6679939032 0.6631292105 0.6391491294 + 0.6688703895 0.6639782190 0.6399635077 + 0.6697443128 0.6648234725 0.6407744288 + 0.6706181765 0.6656687856 0.6415852904 + 0.6714916825 0.6665136218 0.6423954964 + 0.6723623276 0.6673536897 0.6432008743 + 0.6732327938 0.6681938171 0.6440063715 + 0.6741033196 0.6690338850 0.6448118091 + 0.6749706268 0.6698697209 0.6456125975 + 0.6758372784 0.6707047820 0.6464126706 + 0.6767038703 0.6715397835 0.6472128034 + 0.6775687933 0.6723722219 0.6480097771 + 0.6784321070 0.6732022762 0.6488046050 + 0.6792954803 0.6740325093 0.6495993733 + 0.6801578999 0.6748616099 0.6503927112 + 0.6810173988 0.6756870151 0.6511822939 + 0.6818770170 0.6765124798 0.6519718170 + 0.6827365160 0.6773380041 0.6527613997 + 0.6835916042 0.6781579256 0.6535460949 + 0.6844462752 0.6789773107 0.6543303728 + 0.6853010058 0.6797965765 0.6551148295 + 0.6861529946 0.6806129813 0.6558970809 + 0.6870027184 0.6814268231 0.6566780210 + 0.6878523827 0.6822406054 0.6574587822 + 0.6887013912 0.6830536127 0.6582391262 + 0.6895464063 0.6838616729 0.6590166092 + 0.6903914213 0.6846699119 0.6597940922 + 0.6912363768 0.6854779720 0.6605716944 + 0.6920778751 0.6862823963 0.6613466740 + 0.6929180026 0.6870855093 0.6621211171 + 0.6937581897 0.6878886223 0.6628953815 + 0.6945971251 0.6886901855 0.6636688113 + 0.6954327226 0.6894879937 0.6644400954 + 0.6962683201 0.6902858019 0.6652113795 + 0.6971039176 0.6910836101 0.6659826040 + 0.6979358196 0.6918777227 0.6667515039 + 0.6987668276 0.6926708817 0.6675199270 + 0.6995977163 0.6934641004 0.6682882905 + 0.7004268765 0.6942554712 0.6690558195 + 0.7012518048 0.6950421929 0.6698213816 + 0.7020766735 0.6958289742 0.6705870032 + 0.7029017210 0.6966156960 0.6713526845 + 0.7037221789 0.6973984838 0.6721162796 + 0.7045413256 0.6981800199 0.6728792787 + 0.7053604126 0.6989613771 0.6736422777 + 0.7061784267 0.6997417808 0.6744047999 + 0.7069919109 0.7005174756 0.6751654148 + 0.7078052759 0.7012931108 0.6759259105 + 0.7086187005 0.7020686865 0.6766865253 + 0.7094289064 0.7028416991 0.6774455905 + 0.7102369070 0.7036126852 0.6782038808 + 0.7110447884 0.7043836713 0.6789621115 + 0.7118527889 0.7051547170 0.6797204018 + 0.7126556039 0.7059206963 0.6804764867 + 0.7134582996 0.7066864967 0.6812325716 + 0.7142608762 0.7074524164 0.6819887161 + 0.7150620222 0.7082164884 0.6827440858 + 0.7158594728 0.7089766860 0.6834982038 + 0.7166571021 0.7097368836 0.6842523217 + 0.7174546123 0.7104970813 0.6850063801 + 0.7182490826 0.7112538218 0.6857591867 + 0.7190417051 0.7120084167 0.6865115166 + 0.7198343277 0.7127628922 0.6872637272 + 0.7206268907 0.7135174870 0.6880158782 + 0.7214152217 0.7142676115 0.6887664795 + 0.7222030163 0.7150173187 0.6895170808 + 0.7229908109 0.7157669067 0.6902676225 + 0.7237780094 0.7165157795 0.6910178065 + 0.7245612144 0.7172604799 0.6917667985 + 0.7253444791 0.7180052996 0.6925156713 + 0.7261276841 0.7187500000 0.6932647228 + 0.7269088030 0.7194930911 0.6940131187 + 0.7276861072 0.7202336192 0.6947606206 + 0.7284634709 0.7209740877 0.6955081820 + 0.7292407751 0.7217146754 0.6962556839 + 0.7300150990 0.7224528193 0.6970024705 + 0.7307869792 0.7231891155 0.6977487803 + 0.7315589190 0.7239254117 0.6984950900 + 0.7323307991 0.7246617079 0.6992413998 + 0.7330988050 0.7253944278 0.6999868155 + 0.7338652015 0.7261255980 0.7007319927 + 0.7346317172 0.7268568277 0.7014772296 + 0.7353981137 0.7275879979 0.7022224069 + 0.7361603975 0.7283154130 0.7029678822 + 0.7369217873 0.7290419936 0.7037134767 + 0.7376831770 0.7297685742 0.7044590712 + 0.7384446859 0.7304952145 0.7052047849 + 0.7392014265 0.7312179208 0.7059507966 + 0.7399578094 0.7319403291 0.7066968083 + 0.7407141924 0.7326626778 0.7074428201 + 0.7414705753 0.7333850861 0.7081888914 + 0.7422224879 0.7341023088 0.7089354992 + 0.7429742813 0.7348194718 0.7096819878 + 0.7437260747 0.7355365753 0.7104285955 + 0.7444778085 0.7362536788 0.7111750841 + 0.7452235222 0.7369664907 0.7119207978 + 0.7459692955 0.7376793027 0.7126665115 + 0.7467150092 0.7383921146 0.7134122252 + 0.7474606037 0.7391046882 0.7141578197 + 0.7482010126 0.7398132086 0.7149025798 + 0.7489414215 0.7405217290 0.7156472802 + 0.7496817708 0.7412303090 0.7163920999 + 0.7504222989 0.7419388294 0.7171369195 + 0.7511572838 0.7426438928 0.7178807259 + 0.7518922091 0.7433488965 0.7186245918 + 0.7526270747 0.7440540195 0.7193683982 + 0.7533621192 0.7447590828 0.7201123238 + 0.7540926933 0.7454611063 0.7208564281 + 0.7548229098 0.7461627722 0.7216005921 + 0.7555531859 0.7468644977 0.7223448157 + 0.7562834024 0.7475662231 0.7230889201 + 0.7570096850 0.7482659221 0.7238321900 + 0.7577350736 0.7489652038 0.7245752811 + 0.7584605217 0.7496644258 0.7253183722 + 0.7591857910 0.7503635883 0.7260615230 + 0.7599074841 0.7510594130 0.7268037796 + 0.7606273293 0.7517535090 0.7275456786 + 0.7613471150 0.7524476051 0.7282875776 + 0.7620670199 0.7531417012 0.7290294766 + 0.7627841234 0.7538337111 0.7297707796 + 0.7634984851 0.7545235753 0.7305114269 + 0.7642129064 0.7552134991 0.7312520742 + 0.7649273872 0.7559034228 0.7319927216 + 0.7656403184 0.7565919757 0.7327328920 + 0.7663499117 0.7572777867 0.7334721088 + 0.7670595050 0.7579635978 0.7342113853 + 0.7677689791 0.7586494088 0.7349506021 + 0.7684782743 0.7593349814 0.7356896996 + 0.7691832185 0.7600160837 0.7364274859 + 0.7698879838 0.7606971860 0.7371652126 + 0.7705928087 0.7613782883 0.7379028797 + 0.7712976933 0.7620593905 0.7386407256 + 0.7719981074 0.7627363801 0.7393770814 + 0.7726973295 0.7634121776 0.7401133180 + 0.7733964920 0.7640879750 0.7408493757 + 0.7740957141 0.7647637129 0.7415854931 + 0.7747924924 0.7654371262 0.7423207760 + 0.7754864097 0.7661076188 0.7430552840 + 0.7761803865 0.7667781115 0.7437896729 + 0.7768744230 0.7674486041 0.7445241213 + 0.7775678039 0.7681186199 0.7452582717 + 0.7782570124 0.7687847018 0.7459908724 + 0.7789462805 0.7694507241 0.7467234731 + 0.7796354890 0.7701168060 0.7474560738 + 0.7803246975 0.7707828879 0.7481886744 + 0.7810096741 0.7714446783 0.7489197850 + 0.7816932201 0.7721049190 0.7496504784 + 0.7823767066 0.7727652192 0.7503811717 + 0.7830601931 0.7734254003 0.7511119246 + 0.7837420702 0.7740842104 0.7518419027 + 0.7844206095 0.7747399211 0.7525705099 + 0.7850990891 0.7753955722 0.7532991171 + 0.7857775092 0.7760512829 0.7540277839 + 0.7864559889 0.7767069936 0.7547563910 + 0.7871304154 0.7773585916 0.7554832101 + 0.7878041267 0.7780095935 0.7562096715 + 0.7884777784 0.7786604762 0.7569361925 + 0.7891514897 0.7793114185 0.7576625943 + 0.7898237109 0.7799605727 0.7583882809 + 0.7904931903 0.7806066871 0.7591124773 + 0.7911627889 0.7812528014 0.7598366737 + 0.7918323874 0.7818987966 0.7605609298 + 0.7925019264 0.7825449109 0.7612851858 + 0.7931671143 0.7831870914 0.7620074153 + 0.7938314080 0.7838284969 0.7627292275 + 0.7944955826 0.7844697833 0.7634510994 + 0.7951598167 0.7851111889 0.7641729116 + 0.7958226800 0.7857515812 0.7648941278 + 0.7964813113 0.7863892913 0.7656133771 + 0.7971398830 0.7870268822 0.7663328052 + 0.7977985740 0.7876644731 0.7670521140 + 0.7984572053 0.7883021832 0.7677714825 + 0.7991123796 0.7889375091 0.7684891224 + 0.7997658253 0.7895715833 0.7692058086 + 0.8004190922 0.7902057171 0.7699226141 + 0.8010724783 0.7908397913 0.7706393003 + 0.8017258048 0.7914739251 0.7713559866 + 0.8023747206 0.7921038866 0.7720699906 + 0.8030235171 0.7927339077 0.7727841139 + 0.8036723733 0.7933639288 0.7734981179 + 0.8043212295 0.7939940095 0.7742121220 + 0.8049684167 0.7946221232 0.7749251127 + 0.8056119084 0.7952463031 0.7756363153 + 0.8062555194 0.7958704829 0.7763475180 + 0.8068990111 0.7964947224 0.7770587206 + 0.8075426221 0.7971189022 0.7777698040 + 0.8081833124 0.7977399826 0.7784792185 + 0.8088219762 0.7983589172 0.7791873813 + 0.8094608188 0.7989779115 0.7798956037 + 0.8100996017 0.7995969057 0.7806038260 + 0.8107383251 0.8002158999 0.7813121080 + 0.8113725185 0.8008310199 0.7820175886 + 0.8120058179 0.8014454246 0.7827227712 + 0.8126389980 0.8020598292 0.7834278941 + 0.8132722974 0.8026741743 0.7841330767 + 0.8139054179 0.8032884002 0.7848380208 + 0.8145325184 0.8038988113 0.7855399847 + 0.8151596189 0.8045092821 0.7862420082 + 0.8157867193 0.8051196933 0.7869439125 + 0.8164138198 0.8057301044 0.7876458764 + 0.8170399070 0.8063399196 0.7883471251 + 0.8176615238 0.8069468737 0.7890458107 + 0.8182830811 0.8075540066 0.7897444963 + 0.8189046979 0.8081610203 0.7904431224 + 0.8195263743 0.8087679744 0.7911418080 + 0.8201465011 0.8093742728 0.7918393016 + 0.8207632899 0.8099786043 0.7925345898 + 0.8213800788 0.8105828762 0.7932298779 + 0.8219968081 0.8111872077 0.7939251065 + 0.8226135969 0.8117914796 0.7946203947 + 0.8232282996 0.8123940229 0.7953141928 + 0.8238397241 0.8129937053 0.7960060239 + 0.8244510293 0.8135933876 0.7966976762 + 0.8250623941 0.8141930103 0.7973895073 + 0.8256736994 0.8147926927 0.7980812788 + 0.8262823820 0.8153901100 0.7987713814 + 0.8268874884 0.8159844279 0.7994595766 + 0.8274924755 0.8165788054 0.8001477122 + 0.8280975223 0.8171731234 0.8008359075 + 0.8287026286 0.8177673817 0.8015239835 + 0.8293048739 0.8183599710 0.8022106290 + 0.8299033046 0.8189499974 0.8028950095 + 0.8305016160 0.8195400238 0.8035795093 + 0.8310999870 0.8201299906 0.8042638898 + 0.8316984177 0.8207200170 0.8049483895 + 0.8322945237 0.8213084936 0.8056312799 + 0.8328866959 0.8218945265 0.8063120246 + 0.8334789276 0.8224804997 0.8069925904 + 0.8340710998 0.8230664730 0.8076732755 + 0.8346632719 0.8236525059 0.8083540201 + 0.8352540135 0.8242375851 0.8090333939 + 0.8358410001 0.8248205781 0.8097102046 + 0.8364279270 0.8254035711 0.8103870153 + 0.8370147943 0.8259866238 0.8110637069 + 0.8376017213 0.8265694976 0.8117405176 + 0.8381876945 0.8271517754 0.8124166131 + 0.8387684822 0.8277295828 0.8130893707 + 0.8393492103 0.8283075094 0.8137621880 + 0.8399299979 0.8288853765 0.8144350052 + 0.8405107260 0.8294633031 0.8151078224 + 0.8410913944 0.8300412297 0.8157805800 + 0.8416661024 0.8306139112 0.8164492846 + 0.8422405720 0.8311864138 0.8171179891 + 0.8428151011 0.8317589760 0.8177868128 + 0.8433896899 0.8323314786 0.8184555173 + 0.8439642191 0.8329041004 0.8191242218 + 0.8445343971 0.8334730864 0.8197888136 + 0.8451033235 0.8340409994 0.8204522729 + 0.8456721902 0.8346089125 0.8211157918 + 0.8462411165 0.8351768255 0.8217793107 + 0.8468099833 0.8357446790 0.8224428296 + 0.8473765850 0.8363106847 0.8231034875 + 0.8479408026 0.8368747234 0.8237618208 + 0.8485050201 0.8374385834 0.8244199753 + 0.8490692973 0.8380026221 0.8250783086 + 0.8496335149 0.8385666013 0.8257365227 + 0.8501964808 0.8391299844 0.8263936043 + 0.8507544994 0.8396906853 0.8270465136 + 0.8513123989 0.8402515054 0.8276994228 + 0.8518704176 0.8408122063 0.8283522725 + 0.8524283171 0.8413730264 0.8290051818 + 0.8529862761 0.8419337273 0.8296582103 + 0.8535385728 0.8424912095 0.8303064108 + 0.8540899158 0.8430479765 0.8309540153 + 0.8546411991 0.8436049223 0.8316016197 + 0.8551924825 0.8441618085 0.8322492242 + 0.8557438254 0.8447186947 0.8328968287 + 0.8562924862 0.8452731967 0.8335418105 + 0.8568379879 0.8458250165 0.8341839910 + 0.8573834896 0.8463767767 0.8348261714 + 0.8579289913 0.8469285965 0.8354684114 + 0.8584744930 0.8474804163 0.8361105919 + 0.8590198755 0.8480321169 0.8367525935 + 0.8595604897 0.8485792279 0.8373904824 + 0.8601011038 0.8491263986 0.8380283117 + 0.8606415987 0.8496735096 0.8386662006 + 0.8611822128 0.8502206206 0.8393040895 + 0.8617228270 0.8507677913 0.8399419785 + 0.8622605205 0.8513128757 0.8405768275 + 0.8627955914 0.8518565297 0.8412091136 + 0.8633307815 0.8524000049 0.8418415189 + 0.8638659120 0.8529435992 0.8424739242 + 0.8644011021 0.8534870744 0.8431062102 + 0.8649361134 0.8540306091 0.8437383771 + 0.8654658198 0.8545699716 0.8443654180 + 0.8659955263 0.8551093936 0.8449923992 + 0.8665251732 0.8556488156 0.8456193805 + 0.8670548797 0.8561881781 0.8462464213 + 0.8675845861 0.8567274809 0.8468734026 + 0.8681117296 0.8572648168 0.8474978805 + 0.8686357141 0.8577994704 0.8481194973 + 0.8691598177 0.8583341241 0.8487411141 + 0.8696838021 0.8588687778 0.8493627906 + 0.8702077866 0.8594034910 0.8499844074 + 0.8707317710 0.8599380851 0.8506060243 + 0.8712515831 0.8604686856 0.8512223959 + 0.8717706203 0.8609983921 0.8518378139 + 0.8722895980 0.8615282178 0.8524531126 + 0.8728085756 0.8620579243 0.8530684710 + 0.8733276129 0.8625876904 0.8536838889 + 0.8738456964 0.8631166816 0.8542981148 + 0.8743596077 0.8636423945 0.8549072742 + 0.8748735189 0.8641679883 0.8555164933 + 0.8753873110 0.8646935821 0.8561257124 + 0.8759012222 0.8652192950 0.8567348719 + 0.8764150739 0.8657448888 0.8573440909 + 0.8769264817 0.8662691116 0.8579511046 + 0.8774347901 0.8667913079 0.8585553765 + 0.8779432178 0.8673136234 0.8591597080 + 0.8784515858 0.8678358793 0.8597639799 + 0.8789598942 0.8683581948 0.8603683710 + 0.8794683218 0.8688805103 0.8609727025 + 0.8799737096 0.8694002032 0.8615736961 + 0.8804777265 0.8699188232 0.8621733785 + 0.8809818029 0.8704373240 0.8627730012 + 0.8814858198 0.8709558845 0.8633726835 + 0.8819897771 0.8714743853 0.8639724255 + 0.8824939132 0.8719930053 0.8645719886 + 0.8829929233 0.8725072145 0.8651664853 + 0.8834912181 0.8730208278 0.8657605052 + 0.8839895725 0.8735345006 0.8663544059 + 0.8844879270 0.8740481138 0.8669483066 + 0.8849862218 0.8745617270 0.8675422072 + 0.8854843974 0.8750752807 0.8681359291 + 0.8859770298 0.8755844831 0.8687235117 + 0.8864694834 0.8760938048 0.8693109751 + 0.8869621158 0.8766030073 0.8698986173 + 0.8874546289 0.8771122098 0.8704861999 + 0.8879472017 0.8776214719 0.8710737228 + 0.8884391189 0.8781303167 0.8716604114 + 0.8889269233 0.8786363006 0.8722419143 + 0.8894146085 0.8791422844 0.8728232980 + 0.8899024129 0.8796483278 0.8734048009 + 0.8903900981 0.8801543117 0.8739861846 + 0.8908779025 0.8806601763 0.8745676875 + 0.8913648129 0.8811656237 0.8751479983 + 0.8918477297 0.8816679120 0.8757237196 + 0.8923305869 0.8821702003 0.8762993217 + 0.8928135037 0.8826724291 0.8768749833 + 0.8932964206 0.8831747174 0.8774505854 + 0.8937792778 0.8836770058 0.8780263066 + 0.8942611814 0.8841785789 0.8786008954 + 0.8947380781 0.8846768141 0.8791710138 + 0.8952149153 0.8851749897 0.8797410727 + 0.8956918120 0.8856732249 0.8803111911 + 0.8961687088 0.8861714005 0.8808813095 + 0.8966454864 0.8866695762 0.8814514279 + 0.8971219063 0.8871673942 0.8820207119 + 0.8975936174 0.8876612782 0.8825843930 + 0.8980653286 0.8881552815 0.8831480145 + 0.8985369802 0.8886492252 0.8837116957 + 0.8990086913 0.8891432285 0.8842753768 + 0.8994804025 0.8896371126 0.8848391175 + 0.8999521136 0.8901311159 0.8854026198 + 0.9004188776 0.8906217217 0.8859593272 + 0.9008855820 0.8911123276 0.8865159750 + 0.9013522863 0.8916028738 0.8870726228 + 0.9018189907 0.8920934796 0.8876292706 + 0.9022856951 0.8925840855 0.8881859779 + 0.9027525187 0.8930746913 0.8887426853 + 0.9032139182 0.8935613036 0.8892936707 + 0.9036744833 0.8940473199 0.8898438811 + 0.9041351080 0.8945332170 0.8903939724 + 0.9045956731 0.8950191736 0.8909441829 + 0.9050561786 0.8955051899 0.8914942741 + 0.9055168033 0.8959910870 0.8920444846 + 0.9059740901 0.8964738250 0.8925905228 + 0.9064297080 0.8969547153 0.8931344151 + 0.9068853259 0.8974357247 0.8936784267 + 0.9073408842 0.8979166150 0.8942223191 + 0.9077963829 0.8983975053 0.8947662711 + 0.9082520008 0.8988783956 0.8953102231 + 0.9087055922 0.8993577957 0.8958514929 + 0.9091560841 0.8998348713 0.8963887095 + 0.9096066952 0.9003120065 0.8969259858 + 0.9100571871 0.9007890224 0.8974633217 + 0.9105077982 0.9012660980 0.8980004787 + 0.9109582901 0.9017431736 0.8985378146 + 0.9114084840 0.9022198915 0.8990743160 + 0.9118540883 0.9026929140 0.8996040821 + 0.9122998118 0.9031658173 0.9001339078 + 0.9127454162 0.9036387801 0.9006636739 + 0.9131910801 0.9041116834 0.9011934996 + 0.9136366844 0.9045847058 0.9017233253 + 0.9140822887 0.9050576091 0.9022530913 + 0.9145244956 0.9055281878 0.9027777910 + 0.9149652719 0.9059978724 0.9033007026 + 0.9154061079 0.9064676166 0.9038236141 + 0.9158468843 0.9069373012 0.9043465257 + 0.9162877798 0.9074069262 0.9048693776 + 0.9167286158 0.9078766108 0.9053922892 + 0.9171674848 0.9083452225 0.9059128165 + 0.9176024795 0.9088112712 0.9064283967 + 0.9180374146 0.9092773795 0.9069439173 + 0.9184722900 0.9097434878 0.9074594975 + 0.9189072847 0.9102094769 0.9079750180 + 0.9193422198 0.9106755853 0.9084905982 + 0.9197770953 0.9111416936 0.9090061188 + 0.9202072024 0.9116048217 0.9095147848 + 0.9206364155 0.9120672941 0.9100224972 + 0.9210656285 0.9125298262 0.9105300903 + 0.9214947224 0.9129922986 0.9110376835 + 0.9219238758 0.9134547114 0.9115452766 + 0.9223530889 0.9139171839 0.9120529294 + 0.9227808118 0.9143785834 0.9125580192 + 0.9232053757 0.9148374200 0.9130582809 + 0.9236298800 0.9152963161 0.9135584831 + 0.9240545034 0.9157550931 0.9140588045 + 0.9244791269 0.9162139893 0.9145590067 + 0.9249035716 0.9166728854 0.9150593281 + 0.9253281951 0.9171317220 0.9155594707 + 0.9257494211 0.9175868034 0.9160538912 + 0.9261695147 0.9180405736 0.9165465832 + 0.9265896082 0.9184945226 0.9170392156 + 0.9270097017 0.9189482927 0.9175319076 + 0.9274297953 0.9194021821 0.9180244803 + 0.9278498888 0.9198560119 0.9185171127 + 0.9282693267 0.9203091860 0.9190087914 + 0.9286841154 0.9207581282 0.9194943905 + 0.9290989041 0.9212068915 0.9199801087 + 0.9295135736 0.9216557145 0.9204657078 + 0.9299284220 0.9221044779 0.9209513068 + 0.9303432107 0.9225534201 0.9214370251 + 0.9307579994 0.9230021834 0.9219226241 + 0.9311705828 0.9234492183 0.9224053025 + 0.9315806031 0.9238939285 0.9228845239 + 0.9319906235 0.9243385792 0.9233636856 + 0.9324005842 0.9247832894 0.9238429070 + 0.9328106046 0.9252279997 0.9243221283 + 0.9332206249 0.9256727099 0.9248012900 + 0.9336305857 0.9261174202 0.9252805114 + 0.9340372086 0.9265592098 0.9257540703 + 0.9344422817 0.9269996285 0.9262254834 + 0.9348474145 0.9274401069 0.9266968966 + 0.9352524877 0.9278805256 0.9271683097 + 0.9356576204 0.9283210039 0.9276397228 + 0.9360626936 0.9287614226 0.9281110764 + 0.9364678264 0.9292019010 0.9285824895 + 0.9368677139 0.9296385050 0.9290475249 + 0.9372671247 0.9300746918 0.9295117855 + 0.9376664162 0.9305108786 0.9299762249 + 0.9380658269 0.9309471250 0.9304406047 + 0.9384651780 0.9313833117 0.9309049845 + 0.9388645291 0.9318194985 0.9313693047 + 0.9392635822 0.9322556257 0.9318333268 + 0.9396575093 0.9326885939 0.9322912097 + 0.9400513768 0.9331216216 0.9327492118 + 0.9404454231 0.9335545897 0.9332070947 + 0.9408392906 0.9339876175 0.9336650968 + 0.9412332177 0.9344205856 0.9341230989 + 0.9416270852 0.9348536134 0.9345809817 + 0.9420204759 0.9352859855 0.9350377917 + 0.9424101710 0.9357147813 0.9354882240 + 0.9427999854 0.9361435771 0.9359384775 + 0.9431897998 0.9365724921 0.9363889098 + 0.9435796142 0.9370012879 0.9368392229 + 0.9439694285 0.9374300838 0.9372895956 + 0.9443591833 0.9378589988 0.9377400279 + 0.9447481036 0.9382869005 0.9381886721 + 0.9451332092 0.9387105107 0.9386302829 + 0.9455183744 0.9391341209 0.9390718937 + 0.9459034801 0.9395576715 0.9395135045 + 0.9462885857 0.9399812222 0.9399551153 + 0.9466736913 0.9404047728 0.9403967261 + 0.9470589161 0.9408283830 0.9408382773 + 0.9474430084 0.9412512183 0.9412782192 + 0.9478216767 0.9416697025 0.9417101145 + 0.9482004046 0.9420881867 0.9421418905 + 0.9485790730 0.9425066710 0.9425737858 + 0.9489578009 0.9429252148 0.9430056810 + 0.9493365288 0.9433436990 0.9434375167 + 0.9497151971 0.9437621832 0.9438694119 + 0.9500933290 0.9441801906 0.9443004727 + 0.9504646063 0.9445917010 0.9447228909 + 0.9508358240 0.9450030923 0.9451454282 + 0.9512069821 0.9454146028 0.9455677867 + 0.9515783191 0.9458261132 0.9459903240 + 0.9519494772 0.9462375045 0.9464128017 + 0.9523206949 0.9466490149 0.9468352199 + 0.9526919723 0.9470605254 0.9472576976 + 0.9530565739 0.9474642873 0.9476736784 + 0.9534208179 0.9478675127 0.9480893016 + 0.9537848830 0.9482707977 0.9485049844 + 0.9541491270 0.9486740828 0.9489206076 + 0.9545133114 0.9490773082 0.9493361712 + 0.9548773766 0.9494805932 0.9497517943 + 0.9552416205 0.9498838782 0.9501674175 + 0.9556018114 0.9502828717 0.9505789876 + 0.9559605122 0.9506804943 0.9509891272 + 0.9563192129 0.9510779977 0.9513992071 + 0.9566779137 0.9514756203 0.9518092871 + 0.9570366740 0.9518731236 0.9522194266 + 0.9573953748 0.9522706866 0.9526295066 + 0.9577540755 0.9526681900 0.9530395865 + 0.9581105709 0.9530637264 0.9534469247 + 0.9584643841 0.9534568191 0.9538511038 + 0.9588183165 0.9538499117 0.9542552829 + 0.9591721296 0.9542430043 0.9546595812 + 0.9595260024 0.9546362162 0.9550638199 + 0.9598798752 0.9550293088 0.9554679990 + 0.9602336884 0.9554224014 0.9558722973 + 0.9605869055 0.9558148980 0.9562754035 + 0.9609360099 0.9562035203 0.9566727877 + 0.9612851143 0.9565922022 0.9570701122 + 0.9616342187 0.9569808245 0.9574674964 + 0.9619833827 0.9573695064 0.9578648806 + 0.9623324871 0.9577581882 0.9582623243 + 0.9626815915 0.9581468105 0.9586595893 + 0.9630306959 0.9585354924 0.9590569735 + 0.9633762240 0.9589205980 0.9594489932 + 0.9637206793 0.9593046904 0.9598394036 + 0.9640650749 0.9596887827 0.9602298141 + 0.9644095898 0.9600728750 0.9606202841 + 0.9647539854 0.9604570270 0.9610106945 + 0.9650985003 0.9608411193 0.9614012241 + 0.9654428959 0.9612252116 0.9617915750 + 0.9657856226 0.9616078138 0.9621797204 + 0.9661247730 0.9619873166 0.9625632167 + 0.9664641023 0.9623668194 0.9629465938 + 0.9668033123 0.9627463222 0.9633300900 + 0.9671425223 0.9631258249 0.9637135267 + 0.9674816728 0.9635053277 0.9640970230 + 0.9678210020 0.9638847113 0.9644804001 + 0.9681602120 0.9642642140 0.9648638964 + 0.9684944749 0.9646391869 0.9652413726 + 0.9688279033 0.9650132060 0.9656177759 + 0.9691612124 0.9653872252 0.9659941792 + 0.9694945216 0.9657611847 0.9663705826 + 0.9698278904 0.9661352038 0.9667469859 + 0.9701611996 0.9665092230 0.9671233892 + 0.9704945087 0.9668831825 0.9674997926 + 0.9708263874 0.9672555923 0.9678742290 + 0.9711539745 0.9676234126 0.9682434201 + 0.9714816213 0.9679911137 0.9686124921 + 0.9718093276 0.9683588743 0.9689816833 + 0.9721369147 0.9687265754 0.9693508148 + 0.9724645019 0.9690943956 0.9697200060 + 0.9727920890 0.9694622159 0.9700891972 + 0.9731197953 0.9698299170 0.9704583287 + 0.9734438062 0.9701938033 0.9708225727 + 0.9737656713 0.9705553055 0.9711840749 + 0.9740875959 0.9709169269 0.9715456963 + 0.9744095802 0.9712784290 0.9719071984 + 0.9747315049 0.9716399908 0.9722688198 + 0.9750534296 0.9720014930 0.9726303220 + 0.9753754139 0.9723631144 0.9729918838 + 0.9756972790 0.9727246165 0.9733533859 + 0.9760133028 0.9730800986 0.9737070799 + 0.9763289094 0.9734352231 0.9740604162 + 0.9766445756 0.9737904072 0.9744136930 + 0.9769601822 0.9741454720 0.9747670293 + 0.9772757888 0.9745005965 0.9751201868 + 0.9775915146 0.9748557210 0.9754735231 + 0.9779071212 0.9752107859 0.9758267999 + 0.9782214761 0.9755647182 0.9761784077 + 0.9785307050 0.9759128094 0.9765232205 + 0.9788398147 0.9762609005 0.9768680930 + 0.9791489244 0.9766091108 0.9772129059 + 0.9794579744 0.9769572020 0.9775577188 + 0.9797672033 0.9773054123 0.9779024720 + 0.9800763130 0.9776535034 0.9782472849 + 0.9803854227 0.9780015945 0.9785920978 + 0.9806922078 0.9783468843 0.9789335728 + 0.9809947014 0.9786871076 0.9792693257 + 0.9812973142 0.9790272117 0.9796050191 + 0.9815999269 0.9793673754 0.9799407721 + 0.9819024801 0.9797075987 0.9802765250 + 0.9822049737 0.9800478220 0.9806122184 + 0.9825075865 0.9803879857 0.9809479117 + 0.9828101993 0.9807282090 0.9812836051 + 0.9831092954 0.9810643196 0.9816148877 + 0.9834046960 0.9813960195 0.9819414020 + 0.9837002158 0.9817277789 0.9822679162 + 0.9839956164 0.9820595980 0.9825943708 + 0.9842910171 0.9823912978 0.9829208851 + 0.9845864177 0.9827231169 0.9832475185 + 0.9848818183 0.9830548167 0.9835739732 + 0.9851772189 0.9833865762 0.9839004874 + 0.9854683280 0.9837135077 0.9842218161 + 0.9857556820 0.9840362072 0.9845384955 + 0.9860429764 0.9843589067 0.9848552942 + 0.9863303900 0.9846814871 0.9851719737 + 0.9866176844 0.9850041866 0.9854887724 + 0.9869050980 0.9853268862 0.9858055115 + 0.9871923923 0.9856495261 0.9861223102 + 0.9874798059 0.9859722257 0.9864389896 + 0.9877628088 0.9862895012 0.9867501855 + 0.9880418181 0.9866018295 0.9870560765 + 0.9883208275 0.9869140983 0.9873620272 + 0.9885997772 0.9872264266 0.9876679182 + 0.9888787866 0.9875386953 0.9879738092 + 0.9891577959 0.9878510237 0.9882797003 + 0.9894368052 0.9881632924 0.9885855913 + 0.9897158146 0.9884756207 0.9888914824 + 0.9899904728 0.9887828231 0.9891915917 + 0.9902597070 0.9890834093 0.9894841909 + 0.9905288815 0.9893839955 0.9897767901 + 0.9907981157 0.9896845818 0.9900693893 + 0.9910672903 0.9899852276 0.9903619885 + 0.9913365245 0.9902858138 0.9906545877 + 0.9916056991 0.9905864000 0.9909471869 + 0.9918748736 0.9908869863 0.9912399054 + 0.9921408892 0.9911842942 0.9915285110 + 0.9923989177 0.9914734960 0.9918072224 + 0.9926568866 0.9917625785 0.9920858741 + 0.9929149151 0.9920517802 0.9923645854 + 0.9931728840 0.9923409820 0.9926434159 + 0.9934309125 0.9926301241 0.9929221272 + 0.9936888814 0.9929193258 0.9932007790 + 0.9939469099 0.9932084084 0.9934794903 + 0.9942042232 0.9934967756 0.9937573075 + 0.9944509864 0.9937735200 0.9940230846 + 0.9946978092 0.9940503240 0.9942888021 + 0.9949445724 0.9943270087 0.9945545793 + 0.9951913953 0.9946038127 0.9948202968 + 0.9954382181 0.9948804975 0.9950860739 + 0.9956849813 0.9951573014 0.9953517914 + 0.9959318042 0.9954339862 0.9956176281 + 0.9961786866 0.9957107902 0.9958834052 + 0.9964144826 0.9959757924 0.9961376190 + 0.9966472983 0.9962375760 0.9963884950 + 0.9968799949 0.9964993000 0.9966394901 + 0.9971128106 0.9967610240 0.9968904257 + 0.9973455071 0.9970228076 0.9971414208 + 0.9975783229 0.9972844720 0.9973922968 + 0.9978110194 0.9975461960 0.9976432920 + 0.9980437756 0.9978079200 0.9978942275 + 0.9982696176 0.9980614185 0.9981374741 + 0.9984859228 0.9983037710 0.9983702898 + 0.9987022281 0.9985461235 0.9986031055 + 0.9989184737 0.9987884164 0.9988359213 + 0.9991347790 0.9990307093 0.9990686774 + 0.9993510842 0.9992730021 0.9993016124 + 0.9995673895 0.9995154142 0.9995344281 + 0.9997836947 0.9997577071 0.9997671843 + 1.0000000000 1.0000000000 1.0000000000 +} diff --git a/rpplugins/color_correction/resources/film_luts_raw/agfa_agfacolor_futura_ii_200.spi1d b/rpplugins/color_correction/resources/film_luts_raw/agfa_agfacolor_futura_ii_200.spi1d new file mode 100644 index 0000000..66c0988 --- /dev/null +++ b/rpplugins/color_correction/resources/film_luts_raw/agfa_agfacolor_futura_ii_200.spi1d @@ -0,0 +1,1030 @@ +Version 1 +From 0.0 1.0 +Length 1024 +Components 3 +{ + 0.0000000000 0.0000000000 0.0000000000 + 0.0175220203 0.0159201808 0.0112829898 + 0.0302315596 0.0280031394 0.0208480097 + 0.0407330506 0.0385310091 0.0291486792 + 0.0501033999 0.0480892099 0.0366973914 + 0.0587283783 0.0569948703 0.0437196717 + 0.0668726563 0.0654532537 0.0503452383 + 0.0746254995 0.0734657720 0.0566753708 + 0.0821137205 0.0811266303 0.0627593473 + 0.0893652514 0.0885340869 0.0686344281 + 0.0964666009 0.0956818983 0.0743253529 + 0.1034414992 0.1026156992 0.0798535123 + 0.1102956012 0.1093306020 0.0852200314 + 0.1170141026 0.1157635972 0.0904216021 + 0.1235916987 0.1219805032 0.0954708308 + 0.1299463063 0.1280032992 0.1003969014 + 0.1360912025 0.1338655055 0.1052050963 + 0.1420111060 0.1395675987 0.1098947003 + 0.1477487981 0.1450989991 0.1144763976 + 0.1533298045 0.1504811943 0.1189825982 + 0.1587764025 0.1557295024 0.1233960986 + 0.1640834063 0.1608278006 0.1277330071 + 0.1692633927 0.1657993942 0.1319945008 + 0.1743295044 0.1706517041 0.1361728013 + 0.1792751998 0.1754034013 0.1402668059 + 0.1841226965 0.1800453961 0.1442912966 + 0.1888726950 0.1845912039 0.1482613981 + 0.1935237944 0.1890432984 0.1521809995 + 0.1980873048 0.1934227943 0.1560502052 + 0.2025565058 0.1977252066 0.1598621011 + 0.2069393992 0.2019387037 0.1636209041 + 0.2112462074 0.2060763985 0.1673309952 + 0.2154687047 0.2101363987 0.1709980965 + 0.2196132988 0.2141312063 0.1746173948 + 0.2236949950 0.2180649042 0.1781916022 + 0.2277055979 0.2219256014 0.1817201972 + 0.2316590995 0.2257197052 0.1852061003 + 0.2355517000 0.2294515073 0.1886554062 + 0.2393918931 0.2331303954 0.1920740008 + 0.2431806028 0.2367579043 0.1954559982 + 0.2469168007 0.2403406054 0.1987928003 + 0.2505995929 0.2438685000 0.2020907998 + 0.2542274892 0.2473488003 0.2053564936 + 0.2578184903 0.2507809997 0.2085936964 + 0.2613571882 0.2541683912 0.2117979974 + 0.2648550868 0.2575106919 0.2149727941 + 0.2683109939 0.2608149052 0.2181185931 + 0.2717253864 0.2640857995 0.2212391943 + 0.2750979960 0.2673158050 0.2243300974 + 0.2784220874 0.2705042958 0.2273901999 + 0.2817071974 0.2736572921 0.2304214984 + 0.2849532962 0.2767716050 0.2334305048 + 0.2881663144 0.2798540890 0.2364110053 + 0.2913444042 0.2829042077 0.2393691987 + 0.2944832146 0.2859222889 0.2423065007 + 0.2975896001 0.2889142036 0.2452152967 + 0.3006660938 0.2918727994 0.2480936944 + 0.3037149906 0.2947992980 0.2509461045 + 0.3067280948 0.2976973951 0.2537800968 + 0.3097102046 0.3005683124 0.2565920949 + 0.3126625121 0.3034102917 0.2593840063 + 0.3155854940 0.3062278926 0.2621518970 + 0.3184789121 0.3090203106 0.2648904026 + 0.3213432133 0.3117856979 0.2676062882 + 0.3241868913 0.3145250082 0.2703030109 + 0.3270075023 0.3172332048 0.2729845047 + 0.3298006058 0.3199186921 0.2756457031 + 0.3325676918 0.3225826025 0.2782875001 + 0.3353078067 0.3252244890 0.2809073031 + 0.3380177915 0.3278487027 0.2835057080 + 0.3406989872 0.3304544091 0.2860867977 + 0.3433553874 0.3330389857 0.2886512876 + 0.3459919989 0.3356043994 0.2911956012 + 0.3486098945 0.3381497860 0.2937203944 + 0.3512117863 0.3406724036 0.2962253094 + 0.3537960052 0.3431720138 0.2987118959 + 0.3563596904 0.3456499875 0.3011856973 + 0.3589065075 0.3481073976 0.3036412895 + 0.3614340127 0.3505432010 0.3060742915 + 0.3639450073 0.3529601097 0.3084880114 + 0.3664397895 0.3553602993 0.3108876050 + 0.3689151108 0.3577440977 0.3132722974 + 0.3713718057 0.3601129949 0.3156406879 + 0.3738071918 0.3624683917 0.3179928064 + 0.3762201071 0.3648113012 0.3203321099 + 0.3786138892 0.3671433032 0.3226552010 + 0.3809883893 0.3694634140 0.3249565065 + 0.3833450079 0.3717713058 0.3272385001 + 0.3856788874 0.3740625978 0.3295018971 + 0.3879950047 0.3763391078 0.3317486942 + 0.3902960122 0.3786000907 0.3339833021 + 0.3925783932 0.3808402121 0.3362008929 + 0.3948448002 0.3830653131 0.3384015858 + 0.3970947862 0.3852767050 0.3405882120 + 0.3993253112 0.3874705136 0.3427591920 + 0.4015383124 0.3896510005 0.3449178934 + 0.4037337899 0.3918201923 0.3470610082 + 0.4059110880 0.3939774036 0.3491885066 + 0.4080676138 0.3961207867 0.3513003886 + 0.4102075100 0.3982515931 0.3533968031 + 0.4123331010 0.4003694952 0.3554781973 + 0.4144445062 0.4024741054 0.3575446904 + 0.4165400863 0.4045642912 0.3595972955 + 0.4186260104 0.4066396058 0.3616338074 + 0.4207012057 0.4087007046 0.3636533022 + 0.4227670133 0.4107474089 0.3656555116 + 0.4248233140 0.4127795100 0.3676426113 + 0.4268693924 0.4147967100 0.3696162105 + 0.4289070964 0.4167988002 0.3715760112 + 0.4309335947 0.4187847972 0.3735184968 + 0.4329519868 0.4207592905 0.3754445016 + 0.4349603057 0.4227212965 0.3773564994 + 0.4369597137 0.4246717989 0.3792560101 + 0.4389463067 0.4266099930 0.3811441064 + 0.4409210086 0.4285362065 0.3830193877 + 0.4428839087 0.4304524064 0.3848828077 + 0.4448337853 0.4323602021 0.3867362142 + 0.4467687905 0.4342601001 0.3885799944 + 0.4486894906 0.4361515045 0.3904125988 + 0.4505963922 0.4380353987 0.3922336102 + 0.4524900913 0.4399108887 0.3940415084 + 0.4543710947 0.4417791069 0.3958359063 + 0.4562399089 0.4436390996 0.3976179957 + 0.4580954909 0.4454919100 0.3993878961 + 0.4599367976 0.4473369122 0.4011451006 + 0.4617645144 0.4491747022 0.4028908908 + 0.4635792077 0.4510050118 0.4046252966 + 0.4653801918 0.4528281987 0.4063490927 + 0.4671661854 0.4546442926 0.4080632031 + 0.4689376950 0.4564531147 0.4097684920 + 0.4706963003 0.4582554102 0.4114660919 + 0.4724414945 0.4600501955 0.4131549895 + 0.4741756022 0.4618388116 0.4148359001 + 0.4758949876 0.4636174142 0.4165103137 + 0.4776011109 0.4653869867 0.4181793034 + 0.4792934954 0.4671463966 0.4198431969 + 0.4809749126 0.4688977003 0.4215008914 + 0.4826433957 0.4706400037 0.4231525958 + 0.4842990041 0.4723741114 0.4247975051 + 0.4859426916 0.4740991890 0.4264369905 + 0.4875749052 0.4758136868 0.4280720055 + 0.4891946912 0.4775179923 0.4297009110 + 0.4908007979 0.4792113900 0.4313251078 + 0.4923956096 0.4808942974 0.4329412878 + 0.4939799905 0.4825680852 0.4345523119 + 0.4955542982 0.4842331111 0.4361563027 + 0.4971171916 0.4858896136 0.4377534986 + 0.4986675084 0.4875380993 0.4393444955 + 0.5002059937 0.4891777039 0.4409264028 + 0.5017321706 0.4908088148 0.4425007105 + 0.5032498837 0.4924311936 0.4440687895 + 0.5047596097 0.4940446913 0.4456312060 + 0.5062615871 0.4956491888 0.4471881092 + 0.5077568889 0.4972448051 0.4487377107 + 0.5092430115 0.4988301992 0.4502801001 + 0.5107212067 0.5004084110 0.4518156946 + 0.5121917129 0.5019794703 0.4533447921 + 0.5136547089 0.5035430789 0.4548679888 + 0.5151066184 0.5050961971 0.4563845992 + 0.5165513754 0.5066397786 0.4578959048 + 0.5179892778 0.5081757903 0.4594022036 + 0.5194200277 0.5097053051 0.4609036148 + 0.5208390951 0.5112237930 0.4623981118 + 0.5222476125 0.5127363205 0.4638865888 + 0.5236480236 0.5142416954 0.4653699994 + 0.5250409842 0.5157390833 0.4668483138 + 0.5264229774 0.5172262788 0.4683186114 + 0.5277984142 0.5187063217 0.4697833955 + 0.5291666985 0.5201799870 0.4712427855 + 0.5305246711 0.5216469765 0.4726960957 + 0.5318741798 0.5231056809 0.4741415083 + 0.5332177877 0.5245596170 0.4755817056 + 0.5345557928 0.5260090232 0.4770165980 + 0.5358840227 0.5274482965 0.4784426987 + 0.5372061729 0.5288820863 0.4798631072 + 0.5385223031 0.5303105712 0.4812782109 + 0.5398281813 0.5317319036 0.4826853871 + 0.5411273837 0.5331465006 0.4840855002 + 0.5424209237 0.5345557928 0.4854811132 + 0.5437052250 0.5359572768 0.4868715107 + 0.5449833870 0.5373530984 0.4882541895 + 0.5462568998 0.5387449265 0.4896318913 + 0.5475227237 0.5401304960 0.4910022914 + 0.5487810969 0.5415118933 0.4923650026 + 0.5500348210 0.5428903103 0.4937227964 + 0.5512812138 0.5442638993 0.4950731993 + 0.5525211096 0.5456309915 0.4964149892 + 0.5537570119 0.5469937921 0.4977517128 + 0.5549864769 0.5483481884 0.4990803897 + 0.5562115908 0.5496984124 0.5004032850 + 0.5574334264 0.5510452986 0.5017220974 + 0.5586463809 0.5523828268 0.5030320883 + 0.5598551035 0.5537164807 0.5043380260 + 0.5610579252 0.5550454259 0.5056391954 + 0.5622550249 0.5563679934 0.5069329143 + 0.5634492040 0.5576872230 0.5082232952 + 0.5646370053 0.5589987040 0.5095074773 + 0.5658180714 0.5603044033 0.5107867122 + 0.5669947863 0.5616064072 0.5120629072 + 0.5681625009 0.5628957748 0.5133314133 + 0.5693277121 0.5641813874 0.5145972967 + 0.5704880953 0.5654600263 0.5158582926 + 0.5716452003 0.5667315722 0.5171144009 + 0.5728005171 0.5679996014 0.5183681846 + 0.5739479065 0.5692597032 0.5196151137 + 0.5750917792 0.5705173016 0.5208598971 + 0.5762277842 0.5717689991 0.5221000910 + 0.5773584247 0.5730172992 0.5233365297 + 0.5784850717 0.5742632151 0.5245702863 + 0.5796056986 0.5755022764 0.5257986784 + 0.5807244778 0.5767388940 0.5270252228 + 0.5818371773 0.5779654980 0.5282452703 + 0.5829467773 0.5791882277 0.5294620991 + 0.5840514898 0.5804045796 0.5306738019 + 0.5851526856 0.5816155076 0.5318812132 + 0.5862517953 0.5828229189 0.5330861211 + 0.5873453021 0.5840238929 0.5342842937 + 0.5884373188 0.5852233768 0.5354809761 + 0.5895215273 0.5864148736 0.5366703868 + 0.5906035900 0.5876041055 0.5378572941 + 0.5916786194 0.5887857080 0.5390371084 + 0.5927507281 0.5899624825 0.5402138233 + 0.5938187242 0.5911325812 0.5413867235 + 0.5948839784 0.5922974944 0.5425544977 + 0.5959472060 0.5934585929 0.5437186956 + 0.5970050097 0.5946133137 0.5448786020 + 0.5980607271 0.5957654715 0.5460368991 + 0.5991076231 0.5969123244 0.5471885204 + 0.6001530290 0.5980582237 0.5483391285 + 0.6011908054 0.5991981030 0.5494847894 + 0.6022279263 0.6003370881 0.5506296754 + 0.6032595038 0.6014683843 0.5517669916 + 0.6042903066 0.6025981903 0.5529031754 + 0.6053165793 0.6037194133 0.5540338755 + 0.6063408852 0.6048387885 0.5551629066 + 0.6073579788 0.6059514880 0.5562863946 + 0.6083726883 0.6070622802 0.5574082732 + 0.6093810201 0.6081678867 0.5585262775 + 0.6103867292 0.6092718244 0.5596421957 + 0.6113867760 0.6103717089 0.5607541203 + 0.6123839021 0.6114696264 0.5618643761 + 0.6133750081 0.6125634909 0.5629718900 + 0.6143637896 0.6136540174 0.5640769005 + 0.6153482199 0.6147373915 0.5651777983 + 0.6163303256 0.6158183813 0.5662764907 + 0.6173073053 0.6168941259 0.5673714280 + 0.6182823181 0.6179677844 0.5684645772 + 0.6192523837 0.6190360785 0.5695542097 + 0.6202210188 0.6201022863 0.5706425905 + 0.6211845875 0.6211615205 0.5717275143 + 0.6221469045 0.6222187877 0.5728116035 + 0.6231033206 0.6232674718 0.5738925934 + 0.6240592003 0.6243153811 0.5749726295 + 0.6250107288 0.6253551245 0.5760461092 + 0.6259621978 0.6263948083 0.5771194100 + 0.6269065142 0.6274272203 0.5781859756 + 0.6278507113 0.6284595728 0.5792527199 + 0.6287866235 0.6294867992 0.5803136826 + 0.6297214031 0.6305134296 0.5813742280 + 0.6306506991 0.6315355897 0.5824303031 + 0.6315780878 0.6325563788 0.5834851861 + 0.6325017214 0.6335713863 0.5845344067 + 0.6334224939 0.6345824003 0.5855802298 + 0.6343404055 0.6355903149 0.5866221189 + 0.6352542043 0.6365941763 0.5876594186 + 0.6361662745 0.6375966072 0.5886945724 + 0.6370725036 0.6385940909 0.5897240043 + 0.6379784942 0.6395912170 0.5907528996 + 0.6388779283 0.6405804753 0.5917738080 + 0.6397773027 0.6415697932 0.5927945971 + 0.6406729221 0.6425516009 0.5938079953 + 0.6415677071 0.6435316801 0.5948200226 + 0.6424599886 0.6445075870 0.5958276987 + 0.6433506012 0.6454802752 0.5968323946 + 0.6442388892 0.6464512944 0.5978347063 + 0.6451222897 0.6474183798 0.5988320112 + 0.6460055113 0.6483852863 0.5998288989 + 0.6468821764 0.6493440866 0.6008189917 + 0.6477587819 0.6503030062 0.6018090248 + 0.6486309767 0.6512538791 0.6027926207 + 0.6495016217 0.6522020102 0.6037741899 + 0.6503694057 0.6531463265 0.6047533154 + 0.6512334943 0.6540852189 0.6057292223 + 0.6520972252 0.6550235748 0.6067042947 + 0.6529569030 0.6559551954 0.6076720953 + 0.6538167000 0.6568868160 0.6086397767 + 0.6546720862 0.6578143239 0.6096029878 + 0.6555258036 0.6587402821 0.6105644703 + 0.6563767791 0.6596642733 0.6115236282 + 0.6572223902 0.6605846882 0.6124786735 + 0.6580681205 0.6615051031 0.6134337783 + 0.6589081883 0.6624196172 0.6143844128 + 0.6597480774 0.6633337140 0.6153349876 + 0.6605852842 0.6642439961 0.6162821054 + 0.6614202261 0.6651508808 0.6172264814 + 0.6622543931 0.6660568714 0.6181699038 + 0.6630814075 0.6669554114 0.6191053987 + 0.6639084816 0.6678538918 0.6200408936 + 0.6647310257 0.6687464714 0.6209712029 + 0.6655508876 0.6696357131 0.6218988895 + 0.6663697958 0.6705237031 0.6228252053 + 0.6671835184 0.6714056134 0.6237459183 + 0.6679971218 0.6722874045 0.6246666908 + 0.6688064933 0.6731655002 0.6255832911 + 0.6696135998 0.6740418077 0.6264979839 + 0.6704198122 0.6749172211 0.6274114847 + 0.6712203026 0.6757869720 0.6283187866 + 0.6720207930 0.6766569018 0.6292260289 + 0.6728178263 0.6775221825 0.6301295757 + 0.6736124158 0.6783844233 0.6310310960 + 0.6744068861 0.6792463064 0.6319320798 + 0.6751977801 0.6801002026 0.6328263879 + 0.6759887934 0.6809539795 0.6337206960 + 0.6767783165 0.6818047762 0.6346113086 + 0.6775661707 0.6826521158 0.6354981065 + 0.6783542037 0.6834993958 0.6363847852 + 0.6791371703 0.6843413115 0.6372650266 + 0.6799193025 0.6851823926 0.6381441951 + 0.6807003021 0.6860218048 0.6390221119 + 0.6814774275 0.6868560910 0.6398959160 + 0.6822544932 0.6876903176 0.6407696009 + 0.6830291152 0.6885216832 0.6416400075 + 0.6838018894 0.6893510818 0.6425083876 + 0.6845747232 0.6901804805 0.6433767080 + 0.6853433847 0.6910036206 0.6442382932 + 0.6861116886 0.6918261051 0.6450995803 + 0.6868789792 0.6926466823 0.6459587216 + 0.6876426935 0.6934604049 0.6468116045 + 0.6884064078 0.6942741871 0.6476644874 + 0.6891673207 0.6950843930 0.6485136151 + 0.6899256110 0.6958913207 0.6493594050 + 0.6906839013 0.6966981888 0.6502050757 + 0.6914379001 0.6975011826 0.6510459781 + 0.6921907067 0.6983032227 0.6518856883 + 0.6929433942 0.6991050243 0.6527251005 + 0.6936904788 0.6999025941 0.6535598040 + 0.6944376230 0.7007001042 0.6543945074 + 0.6951832175 0.7014958858 0.6552277207 + 0.6959239244 0.7022861242 0.6560571194 + 0.6966645718 0.7030763030 0.6568865180 + 0.6974024773 0.7038636804 0.6577119827 + 0.6981366873 0.7046473026 0.6585326791 + 0.6988708973 0.7054308057 0.6593534946 + 0.6996024251 0.7062115073 0.6601701975 + 0.7003322840 0.7069903016 0.6609845161 + 0.7010622025 0.7077690959 0.6617987752 + 0.7017893791 0.7085446119 0.6626083255 + 0.7025159001 0.7093191147 0.6634163260 + 0.7032423019 0.7100936174 0.6642243266 + 0.7039636970 0.7108619809 0.6650285125 + 0.7046843171 0.7116296291 0.6658324003 + 0.7054049969 0.7123970985 0.6666362286 + 0.7061207294 0.7131581903 0.6674346924 + 0.7068364024 0.7139192224 0.6682332158 + 0.7075518966 0.7146798968 0.6690312028 + 0.7082635164 0.7154349089 0.6698222160 + 0.7089750171 0.7161899209 0.6706132889 + 0.7096859217 0.7169442177 0.6714035273 + 0.7103911042 0.7176927924 0.6721884012 + 0.7110964060 0.7184414864 0.6729732752 + 0.7118008137 0.7191895247 0.6737573743 + 0.7125003934 0.7199338078 0.6745371819 + 0.7131999731 0.7206779718 0.6753169894 + 0.7138990164 0.7214214206 0.6760962009 + 0.7145938277 0.7221598029 0.6768721938 + 0.7152886987 0.7228981256 0.6776481867 + 0.7159827948 0.7236354947 0.6784234047 + 0.7166706920 0.7243661880 0.6791931987 + 0.7173587084 0.7250968814 0.6799631119 + 0.7180461884 0.7258272171 0.6807324290 + 0.7187278867 0.7265521288 0.6814960837 + 0.7194095850 0.7272771001 0.6822597980 + 0.7200912833 0.7280020118 0.6830233932 + 0.7207676768 0.7287219763 0.6837813854 + 0.7214440703 0.7294420004 0.6845393777 + 0.7221205235 0.7301620245 0.6852974296 + 0.7227922082 0.7308751941 0.6860501766 + 0.7234632969 0.7315877080 0.6868025064 + 0.7241343856 0.7323002219 0.6875547767 + 0.7248032093 0.7330073118 0.6883025169 + 0.7254711986 0.7337129116 0.6890491247 + 0.7261391878 0.7344185114 0.6897956729 + 0.7268046141 0.7351201773 0.6905381083 + 0.7274683118 0.7358196974 0.6912782192 + 0.7281321287 0.7365190983 0.6920182705 + 0.7287933230 0.7372158170 0.6927558780 + 0.7294514775 0.7379088998 0.6934906840 + 0.7301098108 0.7386021018 0.6942256093 + 0.7307670712 0.7392935753 0.6949588060 + 0.7314220071 0.7399803996 0.6956874728 + 0.7320768237 0.7406671047 0.6964163184 + 0.7327315807 0.7413536906 0.6971448064 + 0.7333819270 0.7420334816 0.6978684068 + 0.7340322137 0.7427132130 0.6985918880 + 0.7346825004 0.7433928847 0.6993154287 + 0.7353283763 0.7440670729 0.7000336051 + 0.7359728813 0.7447395921 0.7007502913 + 0.7366175056 0.7454121113 0.7014670968 + 0.7372602820 0.7460821271 0.7021806240 + 0.7379010916 0.7467494011 0.7028908730 + 0.7385420203 0.7474167943 0.7036011219 + 0.7391821146 0.7480832934 0.7043104172 + 0.7398182154 0.7487462759 0.7050154209 + 0.7404543757 0.7494093180 0.7057204247 + 0.7410904765 0.7500723004 0.7064254284 + 0.7417215705 0.7507299781 0.7071260214 + 0.7423517108 0.7513865829 0.7078258991 + 0.7429817915 0.7520431280 0.7085257769 + 0.7436100841 0.7526969910 0.7092229724 + 0.7442362905 0.7533478141 0.7099171877 + 0.7448624969 0.7539986968 0.7106114030 + 0.7454884052 0.7546491027 0.7113050222 + 0.7461096048 0.7552949786 0.7119926810 + 0.7467309237 0.7559409142 0.7126803994 + 0.7473521233 0.7565869093 0.7133681774 + 0.7479693294 0.7572283149 0.7140517831 + 0.7485842705 0.7578672767 0.7147333026 + 0.7491992712 0.7585062981 0.7154148817 + 0.7498134971 0.7591440082 0.7160953879 + 0.7504243255 0.7597767115 0.7167720199 + 0.7510352135 0.7604094148 0.7174485922 + 0.7516459823 0.7610421181 0.7181252241 + 0.7522531152 0.7616708875 0.7187982202 + 0.7528588176 0.7622982264 0.7194700241 + 0.7534645200 0.7629255056 0.7201418281 + 0.7540687919 0.7635515928 0.7208123207 + 0.7546679974 0.7641733885 0.7214787006 + 0.7552672029 0.7647953033 0.7221450806 + 0.7558664083 0.7654170990 0.7228114009 + 0.7564626932 0.7660366893 0.7234749794 + 0.7570574880 0.7666552067 0.7241373062 + 0.7576522827 0.7672737241 0.7247995734 + 0.7582467794 0.7678917050 0.7254614234 + 0.7588381767 0.7685058117 0.7261199951 + 0.7594295740 0.7691199183 0.7267785072 + 0.7600209713 0.7697339058 0.7274370193 + 0.7606108189 0.7703450918 0.7280923128 + 0.7611988783 0.7709534764 0.7287446260 + 0.7617871165 0.7715619802 0.7293969989 + 0.7623751760 0.7721704245 0.7300493121 + 0.7629606128 0.7727757096 0.7306963205 + 0.7635456920 0.7733805180 0.7313426733 + 0.7641307116 0.7739853263 0.7319890857 + 0.7647150159 0.7745891213 0.7326344252 + 0.7652966976 0.7751892805 0.7332763076 + 0.7658783793 0.7757894993 0.7339181900 + 0.7664601207 0.7763897181 0.7345600724 + 0.7670400143 0.7769867778 0.7352002859 + 0.7676184773 0.7775810957 0.7358390093 + 0.7681970000 0.7781754732 0.7364776731 + 0.7687754035 0.7787699103 0.7371163964 + 0.7693514228 0.7793611288 0.7377526164 + 0.7699269056 0.7799516916 0.7383884192 + 0.7705023289 0.7805421948 0.7390242219 + 0.7710775137 0.7811324000 0.7396594882 + 0.7716495991 0.7817180753 0.7402899265 + 0.7722216845 0.7823038101 0.7409204245 + 0.7727938294 0.7828894854 0.7415509224 + 0.7733650208 0.7834734917 0.7421798110 + 0.7739340067 0.7840530872 0.7428051829 + 0.7745028734 0.7846328020 0.7434306741 + 0.7750719190 0.7852125168 0.7440561056 + 0.7756394148 0.7857902050 0.7446792126 + 0.7762054205 0.7863658071 0.7452998757 + 0.7767714262 0.7869415283 0.7459207177 + 0.7773373127 0.7875170708 0.7465413809 + 0.7779011726 0.7880907059 0.7471587062 + 0.7784639001 0.7886632085 0.7477741838 + 0.7790266275 0.7892357111 0.7483897805 + 0.7795892954 0.7898082137 0.7490053177 + 0.7801496983 0.7903760076 0.7496179938 + 0.7807093263 0.7909423709 0.7502297759 + 0.7812688947 0.7915087938 0.7508416176 + 0.7818285227 0.7920752168 0.7514533997 + 0.7823855877 0.7926365137 0.7520614862 + 0.7829421759 0.7931969762 0.7526692152 + 0.7834988832 0.7937574983 0.7532768846 + 0.7840554714 0.7943180203 0.7538844943 + 0.7846093178 0.7948756218 0.7544875145 + 0.7851626873 0.7954329848 0.7550902963 + 0.7857161760 0.7959904075 0.7556930184 + 0.7862696052 0.7965477705 0.7562956810 + 0.7868201733 0.7971013784 0.7568932176 + 0.7873706222 0.7976546884 0.7574905753 + 0.7879210114 0.7982081175 0.7580878735 + 0.7884714007 0.7987614870 0.7586852908 + 0.7890191078 0.7993094921 0.7592788935 + 0.7895665765 0.7998571992 0.7598723769 + 0.7901141047 0.8004049063 0.7604658008 + 0.7906615734 0.8009526134 0.7610592842 + 0.7912061810 0.8014960885 0.7616505027 + 0.7917506099 0.8020390272 0.7622414231 + 0.7922949195 0.8025820255 0.7628324032 + 0.7928392887 0.8031250238 0.7634233832 + 0.7933812141 0.8036649227 0.7640110850 + 0.7939224839 0.8042042255 0.7645980716 + 0.7944638729 0.8047435880 0.7651851177 + 0.7950052023 0.8052828908 0.7657721043 + 0.7955445051 0.8058183789 0.7663552165 + 0.7960829735 0.8063523769 0.7669368982 + 0.7966215014 0.8068864942 0.7675185800 + 0.7971600294 0.8074206114 0.7681002021 + 0.7976967096 0.8079521060 0.7686796188 + 0.7982320786 0.8084818125 0.7692573071 + 0.7987675071 0.8090115786 0.7698349953 + 0.7993028760 0.8095412850 0.7704126835 + 0.7998371124 0.8100696802 0.7709888816 + 0.8003696203 0.8105961084 0.7715629935 + 0.8009020090 0.8111224771 0.7721372247 + 0.8014343977 0.8116489053 0.7727112770 + 0.8019663095 0.8121743798 0.7732846141 + 0.8024960160 0.8126959801 0.7738549113 + 0.8030256033 0.8132175803 0.7744253278 + 0.8035553098 0.8137391806 0.7749956250 + 0.8040848970 0.8142607212 0.7755659819 + 0.8046116829 0.8147786260 0.7761322856 + 0.8051382899 0.8152961731 0.7766984105 + 0.8056647778 0.8158138990 0.7772645950 + 0.8061913848 0.8163315058 0.7778307796 + 0.8067160845 0.8168472052 0.7783944011 + 0.8072397709 0.8173617721 0.7789568901 + 0.8077635169 0.8178765178 0.7795193195 + 0.8082872033 0.8183912039 0.7800818086 + 0.8088098764 0.8189039230 0.7806432843 + 0.8093308210 0.8194131255 0.7812033892 + 0.8098517060 0.8199223280 0.7817634940 + 0.8103727102 0.8204315901 0.7823235989 + 0.8108935952 0.8209407926 0.7828835845 + 0.8114115000 0.8214446902 0.7834416032 + 0.8119295239 0.8219487071 0.7839996219 + 0.8124474287 0.8224527240 0.7845575809 + 0.8129652739 0.8229566813 0.7851157188 + 0.8134815097 0.8234592080 0.7856711745 + 0.8139966130 0.8239607215 0.7862251997 + 0.8145117164 0.8244621158 0.7867792845 + 0.8150267005 0.8249636292 0.7873333097 + 0.8155413270 0.8254641294 0.7878866196 + 0.8160536885 0.8259606957 0.7884370089 + 0.8165659904 0.8264572024 0.7889872789 + 0.8170784116 0.8269537091 0.7895377278 + 0.8175907731 0.8274502158 0.7900881171 + 0.8181009889 0.8279432058 0.7906360030 + 0.8186104298 0.8284350038 0.7911829948 + 0.8191198111 0.8289268017 0.7917301059 + 0.8196291924 0.8294185996 0.7922770977 + 0.8201377988 0.8299099207 0.7928233147 + 0.8206434250 0.8303995728 0.7933669090 + 0.8211489916 0.8308892846 0.7939103842 + 0.8216546178 0.8313789964 0.7944539785 + 0.8221603036 0.8318687081 0.7949975133 + 0.8226630092 0.8323553205 0.7955383062 + 0.8231644034 0.8328405023 0.7960780263 + 0.8236657977 0.8333258033 0.7966176867 + 0.8241671920 0.8338109851 0.7971572876 + 0.8246682286 0.8342955709 0.7976964116 + 0.8251668215 0.8347756267 0.7982317209 + 0.8256654739 0.8352555037 0.7987669706 + 0.8261641264 0.8357354999 0.7993022203 + 0.8266627192 0.8362154961 0.7998375297 + 0.8271595240 0.8366938233 0.8003703952 + 0.8276544809 0.8371704817 0.8009009957 + 0.8281494975 0.8376471996 0.8014315963 + 0.8286445141 0.8381239176 0.8019623160 + 0.8291395903 0.8386006951 0.8024929166 + 0.8296310902 0.8390740752 0.8030207157 + 0.8301221132 0.8395469785 0.8035480976 + 0.8306130767 0.8400198221 0.8040754199 + 0.8311039805 0.8404927254 0.8046028018 + 0.8315945864 0.8409647942 0.8051295280 + 0.8320829272 0.8414331079 0.8056535125 + 0.8325713277 0.8419014215 0.8061774969 + 0.8330597281 0.8423696160 0.8067014217 + 0.8335480094 0.8428379297 0.8072254062 + 0.8340349197 0.8433049917 0.8077479005 + 0.8345198035 0.8437706828 0.8082687855 + 0.8350048065 0.8442363143 0.8087896109 + 0.8354896903 0.8447020054 0.8093103766 + 0.8359745741 0.8451675773 0.8098313212 + 0.8364562988 0.8456311226 0.8103501797 + 0.8369364142 0.8460934758 0.8108682036 + 0.8374165297 0.8465558887 0.8113862276 + 0.8378965259 0.8470183015 0.8119041920 + 0.8383765817 0.8474807143 0.8124222159 + 0.8388531804 0.8479387760 0.8129376173 + 0.8393293023 0.8483963013 0.8134527206 + 0.8398053050 0.8488537073 0.8139677048 + 0.8402814269 0.8493111730 0.8144826889 + 0.8407574296 0.8497685194 0.8149976730 + 0.8412302732 0.8502224088 0.8155111074 + 0.8417032957 0.8506761789 0.8160244226 + 0.8421761990 0.8511301279 0.8165377975 + 0.8426492214 0.8515838981 0.8170511127 + 0.8431215286 0.8520373702 0.8175640702 + 0.8435900211 0.8524886966 0.8180745840 + 0.8440583944 0.8529400229 0.8185852170 + 0.8445268869 0.8533912897 0.8190956712 + 0.8449953198 0.8538426161 0.8196063042 + 0.8454630971 0.8542929888 0.8201159835 + 0.8459277749 0.8547400832 0.8206226230 + 0.8463925719 0.8551871181 0.8211292028 + 0.8468574286 0.8556342125 0.8216357827 + 0.8473222256 0.8560811877 0.8221424818 + 0.8477864265 0.8565273881 0.8226484060 + 0.8482484221 0.8569706082 0.8231524229 + 0.8487104177 0.8574137092 0.8236563802 + 0.8491724133 0.8578569293 0.8241603971 + 0.8496344090 0.8583000898 0.8246644139 + 0.8500953913 0.8587425947 0.8251677155 + 0.8505532742 0.8591822982 0.8256688714 + 0.8510112166 0.8596221209 0.8261700869 + 0.8514690995 0.8600618243 0.8266713023 + 0.8519269824 0.8605015874 0.8271725178 + 0.8523843288 0.8609408140 0.8276733160 + 0.8528388143 0.8613771200 0.8281720281 + 0.8532934189 0.8618134856 0.8286706805 + 0.8537480235 0.8622499108 0.8291695118 + 0.8542025089 0.8626862764 0.8296682239 + 0.8546568751 0.8631222844 0.8301666975 + 0.8551089764 0.8635547757 0.8306632042 + 0.8555610180 0.8639872074 0.8311597109 + 0.8560131192 0.8644195795 0.8316562176 + 0.8564652205 0.8648520708 0.8321527243 + 0.8569173217 0.8652845025 0.8326491714 + 0.8573657870 0.8657131195 0.8331434131 + 0.8578140736 0.8661414981 0.8336374760 + 0.8582624197 0.8665698767 0.8341315985 + 0.8587107062 0.8669981956 0.8346257806 + 0.8591589928 0.8674265742 0.8351199031 + 0.8596050143 0.8678531051 0.8356130719 + 0.8600503206 0.8682789803 0.8361061215 + 0.8604956269 0.8687049150 0.8365991116 + 0.8609408736 0.8691307902 0.8370921016 + 0.8613861799 0.8695567846 0.8375850916 + 0.8618302941 0.8699809909 0.8380767703 + 0.8622733951 0.8704040051 0.8385676146 + 0.8627164960 0.8708269000 0.8390582800 + 0.8631595969 0.8712497950 0.8395491242 + 0.8636026978 0.8716726899 0.8400399089 + 0.8640447855 0.8720946908 0.8405296803 + 0.8644844890 0.8725144863 0.8410171270 + 0.8649240732 0.8729342222 0.8415045738 + 0.8653637171 0.8733540177 0.8419920206 + 0.8658034205 0.8737736940 0.8424795270 + 0.8662430048 0.8741934896 0.8429669142 + 0.8666800261 0.8746116757 0.8434523940 + 0.8671169877 0.8750299215 0.8439378142 + 0.8675538898 0.8754481077 0.8444231749 + 0.8679907918 0.8758662939 0.8449085951 + 0.8684278131 0.8762844801 0.8453940153 + 0.8688635230 0.8767014146 0.8458780050 + 0.8692985177 0.8771173954 0.8463612199 + 0.8697335124 0.8775334954 0.8468443155 + 0.8701685071 0.8779495955 0.8473274708 + 0.8706035018 0.8783656955 0.8478106856 + 0.8710376024 0.8787810802 0.8482931852 + 0.8714686036 0.8791939020 0.8487735987 + 0.8718994856 0.8796067834 0.8492540121 + 0.8723304272 0.8800197244 0.8497344255 + 0.8727613091 0.8804326057 0.8502147794 + 0.8731923103 0.8808454275 0.8506951928 + 0.8736202717 0.8812555075 0.8511731029 + 0.8740472794 0.8816646934 0.8516504765 + 0.8744744062 0.8820738792 0.8521277905 + 0.8749014735 0.8824831247 0.8526051044 + 0.8753286004 0.8828923106 0.8530824184 + 0.8757551908 0.8833009005 0.8535591960 + 0.8761808276 0.8837080002 0.8540347815 + 0.8766062856 0.8841150999 0.8545104265 + 0.8770318031 0.8845221996 0.8549860120 + 0.8774573207 0.8849292994 0.8554615974 + 0.8778828979 0.8853362799 0.8559371829 + 0.8783056736 0.8857411146 0.8564112782 + 0.8787276149 0.8861449957 0.8568848968 + 0.8791493773 0.8865488768 0.8573585153 + 0.8795713186 0.8869528770 0.8578320742 + 0.8799932003 0.8873568177 0.8583056927 + 0.8804144263 0.8877601027 0.8587788939 + 0.8808318973 0.8881598115 0.8592500091 + 0.8812494874 0.8885595798 0.8597210050 + 0.8816670775 0.8889592886 0.8601921201 + 0.8820847273 0.8893591166 0.8606631160 + 0.8825021982 0.8897588849 0.8611341715 + 0.8829184175 0.8901572227 0.8616037965 + 0.8833333850 0.8905543089 0.8620721102 + 0.8837484121 0.8909513950 0.8625404835 + 0.8841633797 0.8913484216 0.8630087972 + 0.8845784068 0.8917455077 0.8634771705 + 0.8849933743 0.8921425939 0.8639456034 + 0.8854057193 0.8925368786 0.8644126058 + 0.8858175278 0.8929308057 0.8648794293 + 0.8862293959 0.8933246732 0.8653463125 + 0.8866413236 0.8937187195 0.8658130765 + 0.8870530725 0.8941125870 0.8662800193 + 0.8874645233 0.8945059180 0.8667466044 + 0.8878725767 0.8948956132 0.8672116995 + 0.8882806897 0.8952853084 0.8676767945 + 0.8886888027 0.8956750035 0.8681420088 + 0.8890969157 0.8960648179 0.8686071038 + 0.8895050287 0.8964545131 0.8690721989 + 0.8899124265 0.8968430161 0.8695368171 + 0.8903183937 0.8972294927 0.8700006008 + 0.8907244802 0.8976160884 0.8704643250 + 0.8911305070 0.8980026245 0.8709279895 + 0.8915365934 0.8983891010 0.8713917136 + 0.8919426203 0.8987755775 0.8718554974 + 0.8923472166 0.8991609216 0.8723185062 + 0.8927506208 0.8995451927 0.8727809787 + 0.8931540847 0.8999295235 0.8732435703 + 0.8935574889 0.9003137946 0.8737061024 + 0.8939608932 0.9006981850 0.8741686940 + 0.8943642974 0.9010825157 0.8746312261 + 0.8947654963 0.9014645815 0.8750917912 + 0.8951656818 0.9018456936 0.8755515218 + 0.8955659270 0.9022269249 0.8760113120 + 0.8959661126 0.9026079774 0.8764711022 + 0.8963662982 0.9029892087 0.8769308925 + 0.8967664838 0.9033703208 0.8773906231 + 0.8971654773 0.9037498236 0.8778483868 + 0.8975641727 0.9041286707 0.8783056736 + 0.8979628086 0.9045075774 0.8787629008 + 0.8983613849 0.9048866034 0.8792201877 + 0.8987600803 0.9052655101 0.8796774745 + 0.8991587162 0.9056444168 0.8801347017 + 0.8995556235 0.9060223103 0.8805907965 + 0.8999521136 0.9064000249 0.8810467124 + 0.9003486037 0.9067776799 0.8815026283 + 0.9007450938 0.9071552753 0.8819584250 + 0.9011415839 0.9075329900 0.8824142814 + 0.9015380740 0.9079107046 0.8828700781 + 0.9019324183 0.9082859159 0.8833250999 + 0.9023262262 0.9086604714 0.8837798834 + 0.9027199149 0.9090350866 0.8842347264 + 0.9031137228 0.9094097018 0.8846895099 + 0.9035074711 0.9097843170 0.8851444125 + 0.9039012790 0.9101588726 0.8855991960 + 0.9042941928 0.9105305076 0.8860530257 + 0.9046869278 0.9109010100 0.8865063787 + 0.9050796032 0.9112715721 0.8869599104 + 0.9054722786 0.9116421938 0.8874133229 + 0.9058650136 0.9120126963 0.8878667951 + 0.9062576890 0.9123833179 0.8883202076 + 0.9066494107 0.9127531052 0.8887727261 + 0.9070404172 0.9131224751 0.8892245293 + 0.9074314237 0.9134919047 0.8896763921 + 0.9078223705 0.9138612747 0.8901283145 + 0.9082133770 0.9142307043 0.8905801773 + 0.9086043835 0.9146000147 0.8910320997 + 0.9089940190 0.9149683714 0.8914834261 + 0.9093819857 0.9153357148 0.8919339776 + 0.9097698927 0.9157028794 0.8923847079 + 0.9101579189 0.9160702229 0.8928353190 + 0.9105458856 0.9164373875 0.8932858706 + 0.9109339118 0.9168046713 0.8937366009 + 0.9113214016 0.9171708822 0.8941872120 + 0.9117074013 0.9175342917 0.8946375847 + 0.9120935202 0.9178975821 0.8950880170 + 0.9124795794 0.9182608724 0.8955383897 + 0.9128655791 0.9186242819 0.8959888220 + 0.9132516980 0.9189875722 0.8964391947 + 0.9136376977 0.9193509221 0.8968896866 + 0.9140226841 0.9197127223 0.8973388076 + 0.9144076109 0.9200745225 0.8977879286 + 0.9147924781 0.9204362035 0.8982371092 + 0.9151775241 0.9207980037 0.8986861706 + 0.9155623913 0.9211596847 0.8991352916 + 0.9159473181 0.9215214849 0.8995844126 + 0.9163296819 0.9218823910 0.9000319839 + 0.9167106748 0.9222429991 0.9004787207 + 0.9170917869 0.9226036072 0.9009253979 + 0.9174728990 0.9229642153 0.9013720751 + 0.9178540111 0.9233248234 0.9018188119 + 0.9182350039 0.9236853719 0.9022654891 + 0.9186152220 0.9240450263 0.9027118087 + 0.9189931750 0.9244018793 0.9031571150 + 0.9193711877 0.9247587919 0.9036024809 + 0.9197492003 0.9251158237 0.9040477872 + 0.9201272130 0.9254726768 0.9044930935 + 0.9205052257 0.9258295894 0.9049385190 + 0.9208831787 0.9261866212 0.9053838253 + 0.9212595224 0.9265406728 0.9058277011 + 0.9216355085 0.9268943071 0.9062713981 + 0.9220116138 0.9272480011 0.9067149758 + 0.9223875999 0.9276016951 0.9071586728 + 0.9227635860 0.9279553890 0.9076024294 + 0.9231395721 0.9283090830 0.9080460072 + 0.9235144258 0.9286624193 0.9084891081 + 0.9238871932 0.9290151000 0.9089311957 + 0.9242599010 0.9293677807 0.9093734026 + 0.9246327281 0.9297205210 0.9098154902 + 0.9250054955 0.9300732017 0.9102576971 + 0.9253782034 0.9304258823 0.9106997848 + 0.9257509708 0.9307786226 0.9111419916 + 0.9261215925 0.9311289787 0.9115830064 + 0.9264919162 0.9314789772 0.9120237827 + 0.9268621802 0.9318289757 0.9124646187 + 0.9272325039 0.9321790934 0.9129055142 + 0.9276028275 0.9325290918 0.9133462906 + 0.9279729724 0.9328790903 0.9137871265 + 0.9283429980 0.9332283139 0.9142274857 + 0.9287117720 0.9335752726 0.9146667123 + 0.9290807247 0.9339222908 0.9151058793 + 0.9294496179 0.9342694283 0.9155451059 + 0.9298185110 0.9346163869 0.9159842730 + 0.9301874042 0.9349634051 0.9164234996 + 0.9305561781 0.9353104234 0.9168627262 + 0.9309234023 0.9356566072 0.9173014760 + 0.9312896132 0.9360023737 0.9177401066 + 0.9316558242 0.9363480806 0.9181786180 + 0.9320219755 0.9366937876 0.9186171889 + 0.9323881865 0.9370396137 0.9190558195 + 0.9327543974 0.9373853207 0.9194943905 + 0.9331206083 0.9377310872 0.9199329019 + 0.9334837794 0.9380753040 0.9203705788 + 0.9338467121 0.9384195209 0.9208081961 + 0.9342097044 0.9387636185 0.9212458730 + 0.9345725775 0.9391077757 0.9216834903 + 0.9349356294 0.9394518733 0.9221211076 + 0.9352985024 0.9397959709 0.9225587249 + 0.9356611967 0.9401394725 0.9229962230 + 0.9360224009 0.9404795766 0.9234330058 + 0.9363836050 0.9408196807 0.9238699079 + 0.9367448092 0.9411597848 0.9243066907 + 0.9371060133 0.9414998889 0.9247435927 + 0.9374672771 0.9418399930 0.9251803756 + 0.9378284812 0.9421800971 0.9256172776 + 0.9381889105 0.9425194263 0.9260538816 + 0.9385479093 0.9428572059 0.9264901876 + 0.9389069080 0.9431951046 0.9269264936 + 0.9392657876 0.9435328841 0.9273626804 + 0.9396247864 0.9438707232 0.9277989864 + 0.9399837852 0.9442085028 0.9282351732 + 0.9403427839 0.9445464015 0.9286714792 + 0.9407004118 0.9448838830 0.9291065931 + 0.9410564899 0.9452211857 0.9295405746 + 0.9414126873 0.9455584288 0.9299746752 + 0.9417688847 0.9458956718 0.9304087162 + 0.9421250820 0.9462329149 0.9308426976 + 0.9424812794 0.9465702176 0.9312766790 + 0.9428374767 0.9469074011 0.9317107797 + 0.9431930184 0.9472429156 0.9321432114 + 0.9435479045 0.9475771785 0.9325743914 + 0.9439027905 0.9479115009 0.9330056906 + 0.9442576766 0.9482458234 0.9334369898 + 0.9446126223 0.9485800862 0.9338682294 + 0.9449675083 0.9489144087 0.9342995286 + 0.9453223944 0.9492486715 0.9347308278 + 0.9456762075 0.9495813847 0.9351599216 + 0.9460293055 0.9499132037 0.9355877042 + 0.9463824034 0.9502449036 0.9360154867 + 0.9467355013 0.9505766034 0.9364433289 + 0.9470885992 0.9509083033 0.9368711114 + 0.9474416971 0.9512400031 0.9372988939 + 0.9477947950 0.9515718222 0.9377266169 + 0.9481452107 0.9519032240 0.9381518960 + 0.9484937191 0.9522345066 0.9385753274 + 0.9488422275 0.9525657892 0.9389986992 + 0.9491906166 0.9528970718 0.9394220710 + 0.9495391250 0.9532284141 0.9398453832 + 0.9498875141 0.9535596967 0.9402688146 + 0.9502360225 0.9538909793 0.9406921864 + 0.9505816102 0.9542205930 0.9411129951 + 0.9509239197 0.9545481801 0.9415308833 + 0.9512662292 0.9548758268 0.9419488907 + 0.9516084790 0.9552034140 0.9423667789 + 0.9519507885 0.9555310011 0.9427847266 + 0.9522932172 0.9558585882 0.9432026148 + 0.9526355267 0.9561861753 0.9436205029 + 0.9529765248 0.9565111995 0.9440370202 + 0.9533149004 0.9568306208 0.9444504976 + 0.9536532164 0.9571499825 0.9448639154 + 0.9539914727 0.9574694037 0.9452773929 + 0.9543299079 0.9577888250 0.9456908107 + 0.9546682239 0.9581081867 0.9461042881 + 0.9550064802 0.9584276080 0.9465177059 + 0.9553446174 0.9587466121 0.9469308853 + 0.9556806087 0.9590610266 0.9473422170 + 0.9560164809 0.9593753815 0.9477534294 + 0.9563524723 0.9596897960 0.9481647015 + 0.9566884041 0.9600043297 0.9485759735 + 0.9570243955 0.9603186846 0.9489871860 + 0.9573603272 0.9606330991 0.9493985176 + 0.9576963186 0.9609475136 0.9498096704 + 0.9580307007 0.9612603188 0.9502192140 + 0.9583647251 0.9615727067 0.9506282806 + 0.9586988091 0.9618852139 0.9510374069 + 0.9590328932 0.9621976018 0.9514464736 + 0.9593669176 0.9625099897 0.9518555999 + 0.9597010016 0.9628223777 0.9522647262 + 0.9600350857 0.9631348252 0.9526737928 + 0.9603679180 0.9634457231 0.9530814290 + 0.9606994987 0.9637547135 0.9534872770 + 0.9610310793 0.9640638232 0.9538931847 + 0.9613626003 0.9643728733 0.9542990923 + 0.9616941810 0.9646819830 0.9547049999 + 0.9620258212 0.9649910927 0.9551109076 + 0.9623572826 0.9653000832 0.9555168152 + 0.9626886845 0.9656090140 0.9559224248 + 0.9630175829 0.9659156799 0.9563245773 + 0.9633464813 0.9662224054 0.9567267895 + 0.9636753798 0.9665290713 0.9571290016 + 0.9640042782 0.9668357968 0.9575312138 + 0.9643331766 0.9671425223 0.9579333067 + 0.9646620750 0.9674491882 0.9583355188 + 0.9649909735 0.9677559137 0.9587376714 + 0.9653183818 0.9680610895 0.9591376185 + 0.9656450152 0.9683653712 0.9595360160 + 0.9659715295 0.9686697125 0.9599344730 + 0.9662981033 0.9689739943 0.9603329897 + 0.9666246176 0.9692782760 0.9607315063 + 0.9669511914 0.9695824981 0.9611299038 + 0.9672777057 0.9698867798 0.9615284204 + 0.9676039219 0.9701907039 0.9619265199 + 0.9679273963 0.9704914093 0.9623209834 + 0.9682508111 0.9707919955 0.9627156258 + 0.9685742855 0.9710927010 0.9631102085 + 0.9688977003 0.9713934064 0.9635047913 + 0.9692211747 0.9716939926 0.9638993740 + 0.9695447087 0.9719946980 0.9642940164 + 0.9698681235 0.9722954035 0.9646884799 + 0.9701895118 0.9725940824 0.9650804996 + 0.9705088735 0.9728909731 0.9654701948 + 0.9708284140 0.9731879234 0.9658597708 + 0.9711478949 0.9734848142 0.9662495255 + 0.9714673162 0.9737817049 0.9666391015 + 0.9717867970 0.9740785956 0.9670287967 + 0.9721062183 0.9743754864 0.9674183726 + 0.9724256992 0.9746723771 0.9678081274 + 0.9727420211 0.9749661088 0.9681929946 + 0.9730579257 0.9752594233 0.9685772061 + 0.9733737707 0.9755526781 0.9689614773 + 0.9736896157 0.9758459926 0.9693456888 + 0.9740055203 0.9761393070 0.9697300196 + 0.9743214250 0.9764326215 0.9701141715 + 0.9746373296 0.9767258763 0.9704985023 + 0.9749523997 0.9770184755 0.9708817005 + 0.9752640724 0.9773074985 0.9712603092 + 0.9755758047 0.9775965214 0.9716387987 + 0.9758874774 0.9778854847 0.9720172882 + 0.9761992097 0.9781745076 0.9723957777 + 0.9765108824 0.9784634709 0.9727743268 + 0.9768224955 0.9787524939 0.9731528163 + 0.9771342278 0.9790415168 0.9735313058 + 0.9774439931 0.9793285728 0.9739072919 + 0.9777507782 0.9796128273 0.9742792845 + 0.9780576229 0.9798970222 0.9746512175 + 0.9783642888 0.9801810980 0.9750232100 + 0.9786710739 0.9804652929 0.9753952026 + 0.9789779186 0.9807494879 0.9757671952 + 0.9792847037 0.9810336828 0.9761391282 + 0.9795914888 0.9813178778 0.9765111208 + 0.9798954725 0.9815995097 0.9768790007 + 0.9801974297 0.9818789959 0.9772434831 + 0.9804993272 0.9821584225 0.9776080847 + 0.9808012247 0.9824379086 0.9779726267 + 0.9811030030 0.9827173948 0.9783372283 + 0.9814049006 0.9829968810 0.9787017703 + 0.9817067981 0.9832764268 0.9790663123 + 0.9820086956 0.9835559130 0.9794309139 + 0.9823070168 0.9838317037 0.9797903895 + 0.9826034904 0.9841055870 0.9801471829 + 0.9828999043 0.9843794703 0.9805040956 + 0.9831963778 0.9846534133 0.9808608890 + 0.9834929109 0.9849272966 0.9812176824 + 0.9837893248 0.9852011800 0.9815745950 + 0.9840857983 0.9854751229 0.9819313884 + 0.9843822718 0.9857488871 0.9822881818 + 0.9846748710 0.9860187769 0.9826393127 + 0.9849656820 0.9862868190 0.9829875827 + 0.9852566123 0.9865549207 0.9833359718 + 0.9855474234 0.9868229032 0.9836843014 + 0.9858381748 0.9870908856 0.9840325713 + 0.9861291051 0.9873589277 0.9843810201 + 0.9864199162 0.9876269102 0.9847292900 + 0.9867107272 0.9878948927 0.9850776196 + 0.9869980216 0.9881591797 0.9854195118 + 0.9872834086 0.9884213805 0.9857577085 + 0.9875686765 0.9886837006 0.9860960245 + 0.9878541231 0.9889459014 0.9864342213 + 0.9881393909 0.9892082214 0.9867724180 + 0.9884247780 0.9894704223 0.9871106744 + 0.9887101054 0.9897326827 0.9874488711 + 0.9889954925 0.9899948835 0.9877871871 + 0.9892771244 0.9902533889 0.9881182909 + 0.9895554185 0.9905087948 0.9884434938 + 0.9898337722 0.9907642007 0.9887685776 + 0.9901121855 0.9910196066 0.9890937209 + 0.9903905988 0.9912750125 0.9894189239 + 0.9906688929 0.9915304184 0.9897440076 + 0.9909473062 0.9917857051 0.9900690913 + 0.9912257195 0.9920411110 0.9903942943 + 0.9915013909 0.9922938943 0.9907138944 + 0.9917727113 0.9925420880 0.9910243154 + 0.9920439720 0.9927902818 0.9913346767 + 0.9923152924 0.9930384159 0.9916450977 + 0.9925866127 0.9932866096 0.9919555187 + 0.9928578734 0.9935348034 0.9922658801 + 0.9931291938 0.9937829971 0.9925763011 + 0.9934003949 0.9940311909 0.9928867221 + 0.9936708212 0.9942783713 0.9931951165 + 0.9939351082 0.9945191741 0.9934899211 + 0.9941995144 0.9947599173 0.9937847257 + 0.9944638014 0.9950006008 0.9940794110 + 0.9947280884 0.9952414036 0.9943742156 + 0.9949923754 0.9954820871 0.9946690202 + 0.9952567220 0.9957227707 0.9949638247 + 0.9955210090 0.9959635139 0.9952586293 + 0.9957852960 0.9962043166 0.9955533743 + 0.9960408211 0.9964358807 0.9958317876 + 0.9962943792 0.9966655970 0.9961066842 + 0.9965478778 0.9968951941 0.9963817000 + 0.9968014956 0.9971249104 0.9966565967 + 0.9970551133 0.9973546267 0.9969314933 + 0.9973086119 0.9975842237 0.9972063899 + 0.9975622296 0.9978138804 0.9974814057 + 0.9978157878 0.9980435967 0.9977563024 + 0.9980642200 0.9982674122 0.9980189800 + 0.9983060956 0.9984840155 0.9982665777 + 0.9985480905 0.9987004995 0.9985142946 + 0.9987900853 0.9989171028 0.9987618923 + 0.9990320802 0.9991337061 0.9990094900 + 0.9992740750 0.9993503094 0.9992570877 + 0.9995160103 0.9995667934 0.9995048046 + 0.9997580051 0.9997833967 0.9997524023 + 1.0000000000 1.0000000000 1.0000000000 +} diff --git a/rpplugins/color_correction/resources/film_luts_raw/agfa_agfacolor_futura_ii_400.spi1d b/rpplugins/color_correction/resources/film_luts_raw/agfa_agfacolor_futura_ii_400.spi1d new file mode 100644 index 0000000..f198692 --- /dev/null +++ b/rpplugins/color_correction/resources/film_luts_raw/agfa_agfacolor_futura_ii_400.spi1d @@ -0,0 +1,1030 @@ +Version 1 +From 0.0 1.0 +Length 1024 +Components 3 +{ + 0.0000000000 0.0000000000 0.0000000000 + 0.0171004608 0.0156014897 0.0110214697 + 0.0296423100 0.0275058597 0.0204370096 + 0.0400087796 0.0378916785 0.0286195297 + 0.0492478795 0.0473487712 0.0360689983 + 0.0577691793 0.0561984889 0.0429962091 + 0.0658048466 0.0644933432 0.0495528691 + 0.0734695420 0.0724152401 0.0558067188 + 0.0808440894 0.0800366476 0.0618191212 + 0.0879925117 0.0873461664 0.0676262975 + 0.0949557200 0.0944325328 0.0732697919 + 0.1018247008 0.1012879983 0.0787453130 + 0.1086272970 0.1079066992 0.0840507299 + 0.1152980998 0.1143304035 0.0892019123 + 0.1217757985 0.1205366999 0.0942221731 + 0.1280754060 0.1265349984 0.0991079137 + 0.1341703981 0.1323578954 0.1038789004 + 0.1400842071 0.1380200982 0.1085413024 + 0.1458258033 0.1435257047 0.1130928993 + 0.1513952017 0.1488672942 0.1175398976 + 0.1568222046 0.1540704072 0.1219094992 + 0.1621166021 0.1591500938 0.1262044013 + 0.1672838926 0.1641122997 0.1304340065 + 0.1723344028 0.1689572036 0.1346047074 + 0.1772560030 0.1737031043 0.1387116015 + 0.1820691973 0.1783441007 0.1427484006 + 0.1867853999 0.1828867942 0.1467114985 + 0.1914003938 0.1873379946 0.1506099999 + 0.1959276944 0.1916999966 0.1544381976 + 0.2003667951 0.1959740072 0.1582106054 + 0.2047297060 0.2001685053 0.1619343013 + 0.2090197951 0.2042849064 0.1656126976 + 0.2132406980 0.2083213031 0.1692394018 + 0.2173902988 0.2122910023 0.1728218049 + 0.2214687020 0.2161971927 0.1763650030 + 0.2254846990 0.2200367004 0.1798641980 + 0.2294346988 0.2238188982 0.1833273023 + 0.2333287001 0.2275474966 0.1867597997 + 0.2371630073 0.2312255949 0.1901571006 + 0.2409424931 0.2348573953 0.1935154945 + 0.2446697950 0.2384261042 0.1968335062 + 0.2483461946 0.2419455051 0.2001166940 + 0.2519711852 0.2454174012 0.2033713013 + 0.2555448115 0.2488500029 0.2066029012 + 0.2590776980 0.2522298098 0.2098037004 + 0.2625567913 0.2555679977 0.2129680067 + 0.2659949958 0.2588672936 0.2161033005 + 0.2693926096 0.2621265948 0.2192150950 + 0.2727515101 0.2653498054 0.2222974002 + 0.2760717869 0.2685379982 0.2253466994 + 0.2793444991 0.2716934979 0.2283667028 + 0.2825835049 0.2748126090 0.2313646972 + 0.2857859135 0.2778981924 0.2343385071 + 0.2889564931 0.2809517980 0.2372840047 + 0.2920953929 0.2839730978 0.2402049005 + 0.2951973081 0.2869609892 0.2431025058 + 0.2982689142 0.2899155021 0.2459677011 + 0.3013125062 0.2928346097 0.2488068938 + 0.3043302894 0.2957249880 0.2516252100 + 0.3073143959 0.2985872030 0.2544235885 + 0.3102650940 0.3014270067 0.2572003901 + 0.3131817877 0.3042409122 0.2599579096 + 0.3160701096 0.3070298135 0.2626875937 + 0.3189300001 0.3097898066 0.2653909028 + 0.3217678964 0.3125233054 0.2680732906 + 0.3245871961 0.3152284920 0.2707414031 + 0.3273836076 0.3179099858 0.2733910084 + 0.3301528096 0.3205696046 0.2760204077 + 0.3328959048 0.3232055902 0.2786307931 + 0.3356123865 0.3258267045 0.2812187076 + 0.3382978141 0.3284305036 0.2837873995 + 0.3409596980 0.3310135007 0.2863405049 + 0.3436000943 0.3335742950 0.2888756096 + 0.3462189138 0.3361156881 0.2913906872 + 0.3488169909 0.3386341035 0.2938865125 + 0.3513996005 0.3411293030 0.2963629961 + 0.3539629877 0.3436000943 0.2988243103 + 0.3565055132 0.3460493982 0.3012714982 + 0.3590308130 0.3484821916 0.3036991060 + 0.3615351915 0.3508949876 0.3061034977 + 0.3640230000 0.3532888889 0.3084929883 + 0.3664914966 0.3556644917 0.3108676076 + 0.3689433038 0.3580288887 0.3132284880 + 0.3713740110 0.3603788912 0.3155708909 + 0.3737848103 0.3627198935 0.3179005086 + 0.3761711121 0.3650496900 0.3202157021 + 0.3785369992 0.3673666120 0.3225137889 + 0.3808847964 0.3696695864 0.3247897923 + 0.3832105994 0.3719570935 0.3270477951 + 0.3855203986 0.3742293119 0.3292933106 + 0.3878141046 0.3764826059 0.3315246105 + 0.3900910914 0.3787195086 0.3337422907 + 0.3923526108 0.3809430897 0.3359439075 + 0.3945967853 0.3831507862 0.3381271064 + 0.3968229890 0.3853423893 0.3402962089 + 0.3990325034 0.3875181973 0.3424524069 + 0.4012250900 0.3896811008 0.3445951045 + 0.4033975899 0.3918299079 0.3467190862 + 0.4055522084 0.3939658999 0.3488298059 + 0.4076915085 0.3960888982 0.3509294987 + 0.4098165929 0.3981984854 0.3530152142 + 0.4119274020 0.4002932906 0.3550836146 + 0.4140225053 0.4023733139 0.3571367860 + 0.4161036909 0.4044389129 0.3591760099 + 0.4181733131 0.4064899981 0.3611989915 + 0.4202328026 0.4085263014 0.3632034063 + 0.4222835898 0.4105474949 0.3651930988 + 0.4243231118 0.4125525951 0.3671697974 + 0.4263541996 0.4145421982 0.3691323996 + 0.4283750057 0.4165202975 0.3710797131 + 0.4303872883 0.4184862077 0.3730098903 + 0.4323903918 0.4204401076 0.3749246895 + 0.4343844950 0.4223816991 0.3768284917 + 0.4363701046 0.4243108928 0.3787207901 + 0.4383463860 0.4262312949 0.3806005120 + 0.4403150082 0.4281423986 0.3824656010 + 0.4422720969 0.4300462902 0.3843190074 + 0.4442181885 0.4319409132 0.3861612082 + 0.4461520910 0.4338287115 0.3879927993 + 0.4480755031 0.4357072115 0.3898114860 + 0.4499849975 0.4375792146 0.3916176856 + 0.4518805146 0.4394420087 0.3934090137 + 0.4537624121 0.4412986040 0.3951860964 + 0.4556312859 0.4431461096 0.3969503045 + 0.4574877024 0.4449875951 0.3987065852 + 0.4593302011 0.4468202889 0.4004544914 + 0.4611577094 0.4486469924 0.4021933973 + 0.4629718959 0.4504652917 0.4039224088 + 0.4647724032 0.4522775114 0.4056409895 + 0.4665606022 0.4540818930 0.4073483944 + 0.4683364928 0.4558798969 0.4090481102 + 0.4700995982 0.4576708078 0.4107409120 + 0.4718486965 0.4594548941 0.4124262929 + 0.4735842943 0.4612326920 0.4141052067 + 0.4753074944 0.4630033076 0.4157783985 + 0.4770157039 0.4647684097 0.4174447060 + 0.4787110090 0.4665257037 0.4191048145 + 0.4803912044 0.4682776928 0.4207561910 + 0.4820596874 0.4700196981 0.4224033952 + 0.4837144017 0.4717536867 0.4240436852 + 0.4853559136 0.4734789133 0.4256787002 + 0.4869849980 0.4751960039 0.4273071885 + 0.4886021018 0.4769046903 0.4289287925 + 0.4902065098 0.4786028862 0.4305444062 + 0.4917967021 0.4802902043 0.4321511984 + 0.4933750033 0.4819664061 0.4337506890 + 0.4949423969 0.4836333096 0.4353412986 + 0.4964992106 0.4852910936 0.4369243979 + 0.4980452061 0.4869402051 0.4385007024 + 0.4995796978 0.4885810018 0.4400705099 + 0.5011045933 0.4902119935 0.4416334033 + 0.5026171207 0.4918344915 0.4431881905 + 0.5041204095 0.4934495986 0.4447365105 + 0.5056149960 0.4950574934 0.4462780058 + 0.5071011186 0.4966585934 0.4478121996 + 0.5085787773 0.4982511103 0.4493379891 + 0.5100476146 0.4998351932 0.4508579075 + 0.5115081072 0.5014110208 0.4523723125 + 0.5129603744 0.5029789209 0.4538812935 + 0.5144031048 0.5045387745 0.4553841949 + 0.5158382058 0.5060889721 0.4568797052 + 0.5172675848 0.5076315999 0.4583696127 + 0.5186911821 0.5091663003 0.4598538876 + 0.5201076865 0.5106902122 0.4613319039 + 0.5215175152 0.5122056007 0.4628019035 + 0.5229220986 0.5137131810 0.4642662108 + 0.5243213177 0.5152136087 0.4657247961 + 0.5257117152 0.5167068243 0.4671759903 + 0.5270925760 0.5181897879 0.4686197937 + 0.5284671783 0.5196657181 0.4700576961 + 0.5298361778 0.5211349726 0.4714899957 + 0.5311961174 0.5225929022 0.4729127884 + 0.5325514078 0.5240452290 0.4743295908 + 0.5339015126 0.5254917741 0.4757412076 + 0.5352419019 0.5269278884 0.4771471024 + 0.5365741253 0.5283558965 0.4785467982 + 0.5379003286 0.5297778845 0.4799422026 + 0.5392192006 0.5311921835 0.4813325107 + 0.5405315757 0.5325987935 0.4827156961 + 0.5418395996 0.5340006948 0.4840947092 + 0.5431419015 0.5353968143 0.4854688942 + 0.5444355011 0.5367845893 0.4868355095 + 0.5457248092 0.5381672978 0.4881992936 + 0.5470086932 0.5395433903 0.4895603955 + 0.5482844114 0.5409129858 0.4909155071 + 0.5495557189 0.5422785878 0.4922682941 + 0.5508213043 0.5436385870 0.4936183095 + 0.5520780087 0.5449923873 0.4949626923 + 0.5533294082 0.5463421941 0.4963046014 + 0.5545719862 0.5476844907 0.4976435006 + 0.5558081865 0.5490229726 0.4989764988 + 0.5570405126 0.5503587723 0.5003060102 + 0.5582659245 0.5516861081 0.5016294718 + 0.5594872832 0.5530081987 0.5029485226 + 0.5607051253 0.5543255210 0.5042636991 + 0.5619114041 0.5556346178 0.5055726767 + 0.5631139278 0.5569404960 0.5068780780 + 0.5643098950 0.5582408905 0.5081769228 + 0.5655001998 0.5595366955 0.5094692111 + 0.5666872859 0.5608298779 0.5107579827 + 0.5678644180 0.5621141195 0.5120382905 + 0.5690370202 0.5633950233 0.5133149028 + 0.5702024102 0.5646705031 0.5145862103 + 0.5713610053 0.5659371018 0.5158511996 + 0.5725166798 0.5671998858 0.5171135068 + 0.5736652017 0.5684533119 0.5183678865 + 0.5748100877 0.5697032809 0.5196194053 + 0.5759480000 0.5709466934 0.5208657980 + 0.5770794153 0.5721855164 0.5221070051 + 0.5782068968 0.5734214783 0.5233457088 + 0.5793256760 0.5746489167 0.5245773196 + 0.5804418921 0.5758739710 0.5258070230 + 0.5815505981 0.5770922899 0.5270308852 + 0.5826562047 0.5783078074 0.5282518268 + 0.5837575793 0.5795192122 0.5294687152 + 0.5848544240 0.5807257891 0.5306801200 + 0.5859488249 0.5819299221 0.5318887830 + 0.5870361924 0.5831274986 0.5330893993 + 0.5881218910 0.5843237042 0.5342882276 + 0.5891991258 0.5855125785 0.5354802012 + 0.5902739763 0.5866997838 0.5366697907 + 0.5913425088 0.5878822207 0.5378534198 + 0.5924072266 0.5890613794 0.5390337706 + 0.5934671760 0.5902367234 0.5402104855 + 0.5945214033 0.5914065838 0.5413823128 + 0.5955718160 0.5925731063 0.5425512791 + 0.5966168046 0.5937318206 0.5437142253 + 0.5976600051 0.5948877931 0.5448753834 + 0.5986986160 0.5960369110 0.5460278988 + 0.5997365713 0.5971850753 0.5471792221 + 0.6007699966 0.5983254910 0.5483239293 + 0.6018025875 0.5994653106 0.5494676232 + 0.6028274298 0.6005986929 0.5506033897 + 0.6038507819 0.6017305255 0.5517382026 + 0.6048673987 0.6028541923 0.5528683066 + 0.6058822274 0.6039755940 0.5539959073 + 0.6068912745 0.6050894260 0.5551165938 + 0.6078979969 0.6062008739 0.5562350750 + 0.6088986993 0.6073063016 0.5573483109 + 0.6098974943 0.6084094048 0.5584586859 + 0.6108921766 0.6095077991 0.5595636964 + 0.6118845940 0.6106038094 0.5606665015 + 0.6128724813 0.6116948724 0.5617650151 + 0.6138582826 0.6127820015 0.5628610849 + 0.6148399115 0.6138613224 0.5639526248 + 0.6158196926 0.6149377227 0.5650421977 + 0.6167954803 0.6160081029 0.5661283135 + 0.6177694201 0.6170759201 0.5672121048 + 0.6187387109 0.6181375980 0.5682907104 + 0.6197069287 0.6191977859 0.5693675280 + 0.6206719279 0.6202535033 0.5704392195 + 0.6216356754 0.6213079095 0.5715097785 + 0.6225941181 0.6223561764 0.5725752711 + 0.6235517263 0.6234036088 0.5736399889 + 0.6245011091 0.6244416237 0.5746986270 + 0.6254506111 0.6254796982 0.5757570267 + 0.6263933778 0.6265093088 0.5768082142 + 0.6273362041 0.6275388002 0.5778594017 + 0.6282750964 0.6285620928 0.5789057016 + 0.6292135119 0.6295846105 0.5799514055 + 0.6301469803 0.6306030154 0.5809925795 + 0.6310787201 0.6316199899 0.5820323825 + 0.6320052743 0.6326320171 0.5830696821 + 0.6329280138 0.6336405277 0.5841053724 + 0.6338480115 0.6346455216 0.5851392150 + 0.6347640753 0.6356455088 0.5861703753 + 0.6356791258 0.6366437078 0.5871999264 + 0.6365907192 0.6376357079 0.5882244110 + 0.6375023127 0.6386275291 0.5892485976 + 0.6384099126 0.6396116018 0.5902659297 + 0.6393175721 0.6405956149 0.5912833214 + 0.6402198076 0.6415734887 0.5922964215 + 0.6411203146 0.6425495744 0.5933085084 + 0.6420174241 0.6435208917 0.5943167210 + 0.6429113746 0.6444880962 0.5953217745 + 0.6438037157 0.6454532146 0.5963243246 + 0.6446918845 0.6464130878 0.5973206162 + 0.6455799937 0.6473729014 0.5983167887 + 0.6464617848 0.6483271718 0.5993061066 + 0.6473435760 0.6492815018 0.6002953053 + 0.6482205987 0.6502330899 0.6012793183 + 0.6490954757 0.6511834860 0.6022611856 + 0.6499673724 0.6521314979 0.6032401919 + 0.6508346200 0.6530753970 0.6042150855 + 0.6517016292 0.6540189981 0.6051893830 + 0.6525605917 0.6549540162 0.6061556935 + 0.6534196734 0.6558889747 0.6071221232 + 0.6542748213 0.6568189859 0.6080846786 + 0.6551280022 0.6577466130 0.6090456247 + 0.6559792757 0.6586722136 0.6100040078 + 0.6568263173 0.6595928073 0.6109567881 + 0.6576732993 0.6605134010 0.6119096279 + 0.6585139036 0.6614270210 0.6128568053 + 0.6593537927 0.6623396873 0.6138035059 + 0.6601899862 0.6632481217 0.6147469282 + 0.6610223055 0.6641519070 0.6156873107 + 0.6618543863 0.6650553942 0.6166272759 + 0.6626814008 0.6659533978 0.6175631881 + 0.6635084748 0.6668512821 0.6184991002 + 0.6643338203 0.6677461267 0.6194313169 + 0.6651577950 0.6686387062 0.6203612089 + 0.6659812927 0.6695305705 0.6212899089 + 0.6668003798 0.6704167128 0.6222109795 + 0.6676195860 0.6713029146 0.6231321096 + 0.6684346199 0.6721845269 0.6240482926 + 0.6692469716 0.6730633974 0.6249616146 + 0.6700590253 0.6739416718 0.6258742213 + 0.6708669066 0.6748149991 0.6267806888 + 0.6716747284 0.6756882071 0.6276870966 + 0.6724805236 0.6765586734 0.6285902858 + 0.6732844710 0.6774268746 0.6294907928 + 0.6740885973 0.6782950759 0.6303914189 + 0.6748862267 0.6791549921 0.6312856078 + 0.6756836176 0.6800147891 0.6321799159 + 0.6764786839 0.6808714271 0.6330708861 + 0.6772701740 0.6817231774 0.6339576244 + 0.6780617833 0.6825749874 0.6348443031 + 0.6788492799 0.6834219098 0.6357238293 + 0.6796358228 0.6842675805 0.6366016269 + 0.6804214120 0.6851121783 0.6374781132 + 0.6812025905 0.6859521270 0.6383491158 + 0.6819838285 0.6867920160 0.6392201185 + 0.6827620864 0.6876285076 0.6400873065 + 0.6835377216 0.6884618998 0.6409513950 + 0.6843134165 0.6892954111 0.6418154836 + 0.6850838065 0.6901227832 0.6426753998 + 0.6858534217 0.6909493208 0.6435347199 + 0.6866219044 0.6917747259 0.6443930268 + 0.6873850822 0.6925947070 0.6452473998 + 0.6881483197 0.6934146285 0.6461017132 + 0.6889085770 0.6942318082 0.6469531059 + 0.6896653175 0.6950455904 0.6478009820 + 0.6904219985 0.6958593726 0.6486489773 + 0.6911736131 0.6966683865 0.6494913101 + 0.6919230819 0.6974754930 0.6503316164 + 0.6926727295 0.6982825994 0.6511718035 + 0.6934152246 0.6990849972 0.6520056725 + 0.6941574216 0.6998872161 0.6528394222 + 0.6948987842 0.7006883025 0.6536720991 + 0.6956359148 0.7014837265 0.6545003057 + 0.6963729858 0.7022790909 0.6553285122 + 0.6971086264 0.7030712962 0.6561551094 + 0.6978415251 0.7038580179 0.6569787860 + 0.6985744238 0.7046447992 0.6578025818 + 0.6993039250 0.7054278255 0.6586238742 + 0.7000302076 0.7062076926 0.6594430208 + 0.7007566094 0.7069876194 0.6602622271 + 0.7014790177 0.7077631950 0.6610757113 + 0.7021995783 0.7085369229 0.6618868113 + 0.7029200792 0.7093105912 0.6626979113 + 0.7036368847 0.7100790143 0.6635041833 + 0.7043526769 0.7108461261 0.6643093824 + 0.7050685287 0.7116131783 0.6651147008 + 0.7057778239 0.7123737931 0.6659145951 + 0.7064864039 0.7131338120 0.6667140722 + 0.7071951032 0.7138937116 0.6675134897 + 0.7078974843 0.7146461010 0.6683061123 + 0.7085998058 0.7153983116 0.6690986156 + 0.7093018889 0.7161502838 0.6698907018 + 0.7100000978 0.7168943882 0.6706752181 + 0.7106983066 0.7176384926 0.6714596748 + 0.7113963962 0.7183822989 0.6722435951 + 0.7120925784 0.7191202044 0.6730211973 + 0.7127888799 0.7198581100 0.6737989187 + 0.7134850025 0.7205957174 0.6745759845 + 0.7141777277 0.7213283181 0.6753479838 + 0.7148702741 0.7220609188 0.6761199236 + 0.7155628204 0.7227932215 0.6768916249 + 0.7162505984 0.7235177755 0.6776590943 + 0.7169383764 0.7242423296 0.6784266233 + 0.7176260948 0.7249668837 0.6791939735 + 0.7183110714 0.7256841063 0.6799570918 + 0.7189961076 0.7264013886 0.6807202101 + 0.7196810246 0.7271186113 0.6814832091 + 0.7203640938 0.7278298140 0.6822391748 + 0.7210471034 0.7285404801 0.6829947233 + 0.7217299938 0.7292512059 0.6837502122 + 0.7224094272 0.7299574018 0.6845011711 + 0.7230880857 0.7306627035 0.6852512956 + 0.7237666845 0.7313678861 0.6860014200 + 0.7244430184 0.7320697904 0.6867479086 + 0.7251182199 0.7327703238 0.6874929070 + 0.7257934213 0.7334707975 0.6882380247 + 0.7264670730 0.7341670990 0.6889796257 + 0.7271397114 0.7348600030 0.6897184253 + 0.7278121710 0.7355527878 0.6904572845 + 0.7284829021 0.7362431884 0.6911934018 + 0.7291505933 0.7369294763 0.6919252872 + 0.7298182249 0.7376158237 0.6926571131 + 0.7304852009 0.7383013964 0.6933879256 + 0.7311487794 0.7389839888 0.6941142082 + 0.7318122983 0.7396667004 0.6948403716 + 0.7324758768 0.7403492928 0.6955665946 + 0.7331362963 0.7410271168 0.6962887049 + 0.7337965965 0.7417047024 0.6970105767 + 0.7344568968 0.7423822284 0.6977325082 + 0.7351133823 0.7430555820 0.6984499097 + 0.7357681990 0.7437270880 0.6991655231 + 0.7364230156 0.7443987131 0.6998810172 + 0.7370759249 0.7450683713 0.7005940080 + 0.7377259731 0.7457355261 0.7013034821 + 0.7383760810 0.7464025021 0.7020128965 + 0.7390258908 0.7470691204 0.7027217150 + 0.7396721244 0.7477303743 0.7034254074 + 0.7403182983 0.7483916879 0.7041289806 + 0.7409644723 0.7490528822 0.7048326731 + 0.7416077852 0.7497091293 0.7055320740 + 0.7422502041 0.7503637075 0.7062302828 + 0.7428925037 0.7510182858 0.7069284916 + 0.7435333729 0.7516707778 0.7076249719 + 0.7441717982 0.7523202896 0.7083188891 + 0.7448102236 0.7529696822 0.7090129256 + 0.7454485893 0.7536191940 0.7097067833 + 0.7460827231 0.7542620897 0.7103967071 + 0.7467167974 0.7549051046 0.7110865116 + 0.7473508716 0.7555481195 0.7117763758 + 0.7479826212 0.7561879754 0.7124634981 + 0.7486125231 0.7568256259 0.7131487131 + 0.7492423058 0.7574632764 0.7138339281 + 0.7498719096 0.7581006289 0.7145183086 + 0.7504996061 0.7587358952 0.7151979804 + 0.7511271834 0.7593712211 0.7158777118 + 0.7517548203 0.7600064874 0.7165573835 + 0.7523803115 0.7606381178 0.7172330022 + 0.7530044913 0.7612677217 0.7179064155 + 0.7536287904 0.7618973851 0.7185798883 + 0.7542523742 0.7625262141 0.7192522883 + 0.7548720837 0.7631500959 0.7199187875 + 0.7554919124 0.7637740970 0.7205854058 + 0.7561116219 0.7643979788 0.7212520242 + 0.7567297816 0.7650203109 0.7219150066 + 0.7573469877 0.7656415105 0.7225760221 + 0.7579641938 0.7662625909 0.7232369781 + 0.7585812807 0.7668836117 0.7238978148 + 0.7591949105 0.7674986720 0.7245547175 + 0.7598084807 0.7681139112 0.7252116203 + 0.7604219913 0.7687290907 0.7258685231 + 0.7610334754 0.7693409920 0.7265231013 + 0.7616422772 0.7699488997 0.7271751165 + 0.7622511983 0.7705568075 0.7278271914 + 0.7628600001 0.7711647153 0.7284792066 + 0.7634664774 0.7717682719 0.7291265130 + 0.7640724778 0.7723709941 0.7297729254 + 0.7646784782 0.7729737163 0.7304192781 + 0.7652838826 0.7735757232 0.7310644984 + 0.7658861279 0.7741742730 0.7317045927 + 0.7664881945 0.7747728825 0.7323446870 + 0.7670903802 0.7753714919 0.7329847813 + 0.7676901221 0.7759671211 0.7336224914 + 0.7682873011 0.7765594721 0.7342575788 + 0.7688844204 0.7771518230 0.7348927855 + 0.7694815993 0.7777441740 0.7355279922 + 0.7700763941 0.7783325911 0.7361595035 + 0.7706704736 0.7789196968 0.7367901206 + 0.7712646127 0.7795069218 0.7374206781 + 0.7718585730 0.7800940275 0.7380509973 + 0.7724485993 0.7806769013 0.7386764884 + 0.7730386257 0.7812598944 0.7393019795 + 0.7736285925 0.7818428874 0.7399274707 + 0.7742174268 0.7824249268 0.7405520082 + 0.7748020887 0.7830036879 0.7411739230 + 0.7753869295 0.7835826278 0.7417957187 + 0.7759717107 0.7841613889 0.7424175143 + 0.7765550017 0.7847386003 0.7430375218 + 0.7771365047 0.7853134871 0.7436553240 + 0.7777178884 0.7858883739 0.7442730069 + 0.7782993913 0.7864633203 0.7448908091 + 0.7788782716 0.7870357037 0.7455062270 + 0.7794554830 0.7876065969 0.7461202145 + 0.7800326943 0.7881773710 0.7467340827 + 0.7806097865 0.7887482047 0.7473481297 + 0.7811824083 0.7893161178 0.7479594946 + 0.7817530036 0.7898828983 0.7485699058 + 0.7823237181 0.7904496789 0.7491803765 + 0.7828943729 0.7910165191 0.7497909069 + 0.7834607959 0.7915802002 0.7503979802 + 0.7840262055 0.7921432257 0.7510045171 + 0.7845916152 0.7927060723 0.7516109943 + 0.7851570249 0.7932690978 0.7522174716 + 0.7857185006 0.7938284874 0.7528216839 + 0.7862794995 0.7943874002 0.7534257174 + 0.7868404984 0.7949463129 0.7540296912 + 0.7874014974 0.7955052853 0.7546337247 + 0.7879565954 0.7960606217 0.7552338839 + 0.7885110974 0.7966156006 0.7558339238 + 0.7890654802 0.7971706986 0.7564339042 + 0.7896199822 0.7977256775 0.7570338249 + 0.7901695967 0.7982773185 0.7576287985 + 0.7907186747 0.7988284826 0.7582232952 + 0.7912678123 0.7993797064 0.7588177919 + 0.7918167710 0.7999309897 0.7594122887 + 0.7923620939 0.8004786968 0.7600033283 + 0.7929067016 0.8010259271 0.7605937719 + 0.7934514284 0.8015732169 0.7611842752 + 0.7939960957 0.8021203876 0.7617747188 + 0.7945355177 0.8026636839 0.7623630762 + 0.7950735092 0.8032060862 0.7629508972 + 0.7956116199 0.8037484288 0.7635387778 + 0.7961496711 0.8042907715 0.7641267180 + 0.7966831923 0.8048292994 0.7647116780 + 0.7972148061 0.8053662181 0.7652955055 + 0.7977464199 0.8059030771 0.7658793926 + 0.7982779741 0.8064399958 0.7664632797 + 0.7988070846 0.8069747090 0.7670440078 + 0.7993342876 0.8075076938 0.7676222920 + 0.7998613715 0.8080406785 0.7682006955 + 0.8003885746 0.8085737228 0.7687789798 + 0.8009144068 0.8091049194 0.7693557739 + 0.8014380932 0.8096331954 0.7699301243 + 0.8019618988 0.8101614714 0.7705044150 + 0.8024855852 0.8106899261 0.7710787058 + 0.8030084968 0.8112171888 0.7716525197 + 0.8035271764 0.8117402792 0.7722241282 + 0.8040459752 0.8122633100 0.7727957964 + 0.8045647144 0.8127862811 0.7733674049 + 0.8050835133 0.8133093119 0.7739390135 + 0.8055983782 0.8138288856 0.7745084763 + 0.8061131239 0.8143482208 0.7750778198 + 0.8066278100 0.8148674965 0.7756472230 + 0.8071424961 0.8153867722 0.7762165070 + 0.8076552153 0.8159031868 0.7767828703 + 0.8081669211 0.8164179921 0.7773479819 + 0.8086786270 0.8169327974 0.7779129744 + 0.8091902137 0.8174476027 0.7784780264 + 0.8097003102 0.8179603219 0.7790415287 + 0.8102073073 0.8184689879 0.7796025872 + 0.8107144237 0.8189777136 0.7801635861 + 0.8112214804 0.8194864988 0.7807245851 + 0.8117284775 0.8199952245 0.7812855840 + 0.8122318983 0.8205006123 0.7818430066 + 0.8127353191 0.8210061193 0.7824004889 + 0.8132386804 0.8215116262 0.7829579711 + 0.8137421012 0.8220170140 0.7835153937 + 0.8142439127 0.8225206733 0.7840704918 + 0.8147445917 0.8230230808 0.7846242189 + 0.8152452707 0.8235256076 0.7851778269 + 0.8157460093 0.8240280747 0.7857314944 + 0.8162457943 0.8245295286 0.7862842083 + 0.8167423010 0.8250265121 0.7868337035 + 0.8172388077 0.8255233765 0.7873830795 + 0.8177353144 0.8260204196 0.7879325747 + 0.8182318211 0.8265172839 0.7884820104 + 0.8187258244 0.8270121813 0.7890285850 + 0.8192189932 0.8275064230 0.7895743251 + 0.8197121024 0.8280006051 0.7901200056 + 0.8202052712 0.8284947872 0.7906656265 + 0.8206979036 0.8289883137 0.7912104726 + 0.8211886883 0.8294799924 0.7917528152 + 0.8216794729 0.8299716711 0.7922950983 + 0.8221703172 0.8304634094 0.7928373814 + 0.8226609826 0.8309550285 0.7933797240 + 0.8231490850 0.8314424157 0.7939193249 + 0.8236359954 0.8319281936 0.7944579124 + 0.8241229057 0.8324139118 0.7949965000 + 0.8246098161 0.8328995705 0.7955352068 + 0.8250963092 0.8333846927 0.7960731983 + 0.8255802989 0.8338664770 0.7966079116 + 0.8260642290 0.8343483210 0.7971426845 + 0.8265480995 0.8348299861 0.7976773977 + 0.8270320892 0.8353117704 0.7982121110 + 0.8275148869 0.8357924819 0.7987449169 + 0.8279966712 0.8362724185 0.7992761135 + 0.8284785748 0.8367521763 0.7998073101 + 0.8289604187 0.8372321129 0.8003385067 + 0.8294422030 0.8377118707 0.8008695841 + 0.8299208879 0.8381869793 0.8013979197 + 0.8303992152 0.8386614919 0.8019258976 + 0.8308774829 0.8391360044 0.8024538755 + 0.8313558102 0.8396105170 0.8029819131 + 0.8318336010 0.8400840759 0.8035091162 + 0.8323091865 0.8405542970 0.8040336967 + 0.8327847719 0.8410243988 0.8045582771 + 0.8332604170 0.8414946198 0.8050829172 + 0.8337361217 0.8419647813 0.8056074977 + 0.8342108130 0.8424335122 0.8061311245 + 0.8346846104 0.8429005742 0.8066536188 + 0.8351584077 0.8433678150 0.8071761131 + 0.8356322050 0.8438348770 0.8076986074 + 0.8361061215 0.8443019986 0.8082212210 + 0.8365774751 0.8447657824 0.8087412715 + 0.8370481133 0.8452283740 0.8092607260 + 0.8375186920 0.8456910253 0.8097800016 + 0.8379892111 0.8461534977 0.8102992773 + 0.8384597898 0.8466160893 0.8108186722 + 0.8389282227 0.8470754027 0.8113338947 + 0.8393964171 0.8475344181 0.8118488789 + 0.8398646116 0.8479933739 0.8123638034 + 0.8403326869 0.8484523892 0.8128787875 + 0.8408008218 0.8489112258 0.8133934736 + 0.8412675261 0.8493679166 0.8139054179 + 0.8417341113 0.8498246074 0.8144173026 + 0.8422008157 0.8502812982 0.8149293065 + 0.8426674008 0.8507381082 0.8154411912 + 0.8431332707 0.8511940241 0.8159524202 + 0.8435961008 0.8516469002 0.8164612055 + 0.8440588713 0.8520997763 0.8169698715 + 0.8445217013 0.8525527120 0.8174785972 + 0.8449844718 0.8530055881 0.8179873228 + 0.8454462886 0.8534573913 0.8184950948 + 0.8459054232 0.8539065123 0.8190008998 + 0.8463646173 0.8543556929 0.8195067048 + 0.8468238115 0.8548048735 0.8200125098 + 0.8472828865 0.8552539945 0.8205183148 + 0.8477417231 0.8557022214 0.8210232854 + 0.8481997848 0.8561481833 0.8215265274 + 0.8486577868 0.8565942049 0.8220297098 + 0.8491159081 0.8570402265 0.8225328922 + 0.8495739102 0.8574863076 0.8230360746 + 0.8500308990 0.8579313755 0.8235384226 + 0.8504856229 0.8583744168 0.8240389228 + 0.8509402275 0.8588173985 0.8245393038 + 0.8513947725 0.8592604995 0.8250396848 + 0.8518494964 0.8597034812 0.8255401850 + 0.8523032069 0.8601452708 0.8260402083 + 0.8527547121 0.8605837226 0.8265390992 + 0.8532062173 0.8610221148 0.8270381093 + 0.8536576033 0.8614605069 0.8275370002 + 0.8541091084 0.8618988991 0.8280360103 + 0.8545603752 0.8623365164 0.8285344243 + 0.8550112247 0.8627706766 0.8290308118 + 0.8554618955 0.8632047772 0.8295271993 + 0.8559126854 0.8636388779 0.8300235271 + 0.8563634157 0.8640729785 0.8305199146 + 0.8568140268 0.8645070195 0.8310160041 + 0.8572617769 0.8649371862 0.8315085769 + 0.8577095270 0.8653674722 0.8320013285 + 0.8581572771 0.8657976985 0.8324939013 + 0.8586050272 0.8662279844 0.8329865932 + 0.8590527773 0.8666582108 0.8334792256 + 0.8594974279 0.8670850992 0.8339697123 + 0.8599414825 0.8675115705 0.8344600201 + 0.8603855968 0.8679379821 0.8349502087 + 0.8608297110 0.8683645129 0.8354403973 + 0.8612738848 0.8687909245 0.8359307051 + 0.8617168069 0.8692150712 0.8364191055 + 0.8621590734 0.8696380854 0.8369066715 + 0.8626012802 0.8700612187 0.8373944163 + 0.8630436063 0.8704841733 0.8378819823 + 0.8634858727 0.8709071875 0.8383696079 + 0.8639271855 0.8713290095 0.8388562799 + 0.8643670082 0.8717489839 0.8393415809 + 0.8648067713 0.8721688986 0.8398268819 + 0.8652465940 0.8725888729 0.8403123021 + 0.8656864166 0.8730089068 0.8407976031 + 0.8661258817 0.8734285831 0.8412827253 + 0.8665626049 0.8738455176 0.8417659998 + 0.8669993281 0.8742625117 0.8422493935 + 0.8674361110 0.8746795058 0.8427327275 + 0.8678727746 0.8750964999 0.8432160020 + 0.8683094978 0.8755133748 0.8436992764 + 0.8687452078 0.8759278059 0.8441810012 + 0.8691806197 0.8763412237 0.8446620703 + 0.8696159720 0.8767547011 0.8451433182 + 0.8700513840 0.8771681786 0.8456243873 + 0.8704867959 0.8775817156 0.8461055160 + 0.8709213734 0.8779937029 0.8465862870 + 0.8713548183 0.8784034848 0.8470665216 + 0.8717882037 0.8788132071 0.8475466967 + 0.8722217083 0.8792229295 0.8480268717 + 0.8726550937 0.8796325922 0.8485071063 + 0.8730884790 0.8800423741 0.8489872217 + 0.8735179901 0.8804501295 0.8494654894 + 0.8739473224 0.8808577061 0.8499435782 + 0.8743764758 0.8812652826 0.8504217267 + 0.8748058081 0.8816729188 0.8508998752 + 0.8752350211 0.8820804954 0.8513780236 + 0.8756635189 0.8824869990 0.8518546820 + 0.8760908842 0.8828920126 0.8523296714 + 0.8765184283 0.8832970262 0.8528047204 + 0.8769457936 0.8837019801 0.8532798290 + 0.8773732781 0.8841069937 0.8537548184 + 0.8778008223 0.8845118880 0.8542299271 + 0.8782266974 0.8849135041 0.8547031283 + 0.8786525726 0.8853148222 0.8551763296 + 0.8790785074 0.8857160211 0.8556494713 + 0.8795043230 0.8861172795 0.8561226130 + 0.8799301982 0.8865185976 0.8565958142 + 0.8803547025 0.8869189024 0.8570681810 + 0.8807768822 0.8873174787 0.8575392962 + 0.8811990023 0.8877161145 0.8580104113 + 0.8816211820 0.8881146908 0.8584814072 + 0.8820433021 0.8885133266 0.8589525223 + 0.8824654818 0.8889119029 0.8594235778 + 0.8828865886 0.8893092871 0.8598933816 + 0.8833072782 0.8897061944 0.8603627086 + 0.8837280869 0.8901032209 0.8608320951 + 0.8841487765 0.8905001879 0.8613014221 + 0.8845695257 0.8908970952 0.8617706895 + 0.8849902153 0.8912938237 0.8622398973 + 0.8854097128 0.8916872740 0.8627077937 + 0.8858292103 0.8920807242 0.8631755710 + 0.8862488270 0.8924741149 0.8636435270 + 0.8866683245 0.8928675056 0.8641113043 + 0.8870878220 0.8932608962 0.8645792007 + 0.8875058293 0.8936526775 0.8650463820 + 0.8879212141 0.8940414786 0.8655126095 + 0.8883365989 0.8944302797 0.8659787178 + 0.8887521029 0.8948190808 0.8664448857 + 0.8891674876 0.8952078223 0.8669111133 + 0.8895828724 0.8955966234 0.8673772812 + 0.8899958134 0.8959844708 0.8678423166 + 0.8904073238 0.8963717818 0.8683065176 + 0.8908187151 0.8967590928 0.8687707782 + 0.8912302256 0.8971464038 0.8692349792 + 0.8916416168 0.8975337148 0.8696991801 + 0.8920531273 0.8979210258 0.8701635003 + 0.8924632072 0.8983063102 0.8706263900 + 0.8928729892 0.8986909986 0.8710889816 + 0.8932827115 0.8990756869 0.8715515733 + 0.8936924934 0.8994604945 0.8720142245 + 0.8941022754 0.8998451829 0.8724768758 + 0.8945121169 0.9002298713 0.8729395270 + 0.8949183226 0.9006112218 0.8734009266 + 0.8953242898 0.9009922743 0.8738622069 + 0.8957303762 0.9013733268 0.8743236065 + 0.8961364031 0.9017543793 0.8747850060 + 0.8965424895 0.9021354914 0.8752462864 + 0.8969483972 0.9025166035 0.8757076263 + 0.8973509073 0.9028971195 0.8761674166 + 0.8977534175 0.9032775760 0.8766270876 + 0.8981559277 0.9036580920 0.8770868778 + 0.8985583186 0.9040386081 0.8775466084 + 0.8989608288 0.9044191837 0.8780063987 + 0.8993632197 0.9047995210 0.8784658909 + 0.8997644186 0.9051784277 0.8789238930 + 0.9001656175 0.9055572748 0.8793817759 + 0.9005668163 0.9059361219 0.8798397183 + 0.9009678960 0.9063150287 0.8802977204 + 0.9013690948 0.9066938758 0.8807556033 + 0.9017699957 0.9070724249 0.8812134266 + 0.9021677971 0.9074478149 0.8816698194 + 0.9025657177 0.9078232050 0.8821262717 + 0.9029635191 0.9081985950 0.8825827241 + 0.9033613801 0.9085739851 0.8830391765 + 0.9037591815 0.9089493155 0.8834956288 + 0.9041569233 0.9093245864 0.8839520812 + 0.9045507908 0.9096974730 0.8844081163 + 0.9049447179 0.9100704193 0.8848640919 + 0.9053385854 0.9104431868 0.8853201270 + 0.9057325125 0.9108160734 0.8857762218 + 0.9061263800 0.9111890197 0.8862321973 + 0.9065201879 0.9115619063 0.8866881728 + 0.9069120288 0.9119333029 0.8871427774 + 0.9073035121 0.9123045802 0.8875973225 + 0.9076951146 0.9126759768 0.8880518079 + 0.9080867171 0.9130473137 0.8885064125 + 0.9084782004 0.9134187102 0.8889608979 + 0.9088698030 0.9137899876 0.8894153833 + 0.9092592001 0.9141587019 0.8898677826 + 0.9096478820 0.9145267010 0.8903195858 + 0.9100366235 0.9148947001 0.8907713890 + 0.9104254246 0.9152626991 0.8912233114 + 0.9108141065 0.9156306982 0.8916751146 + 0.9112027884 0.9159986973 0.8921269178 + 0.9115895033 0.9163650274 0.8925778270 + 0.9119747877 0.9167301059 0.8930280209 + 0.9123600721 0.9170951843 0.8934782743 + 0.9127454162 0.9174603224 0.8939285278 + 0.9131307006 0.9178254008 0.8943787217 + 0.9135159850 0.9181904793 0.8948289752 + 0.9139006734 0.9185553789 0.8952789903 + 0.9142842293 0.9189199805 0.8957288265 + 0.9146677256 0.9192845225 0.8961784840 + 0.9150511026 0.9196491241 0.8966283202 + 0.9154345989 0.9200137258 0.8970779777 + 0.9158180952 0.9203782082 0.8975276947 + 0.9162014723 0.9207428098 0.8979774117 + 0.9165825844 0.9211050272 0.8984262943 + 0.9169636965 0.9214671850 0.8988751769 + 0.9173448086 0.9218295217 0.8993239999 + 0.9177259207 0.9221916795 0.8997728825 + 0.9181070924 0.9225540161 0.9002218246 + 0.9184882045 0.9229161739 0.9006705880 + 0.9188672900 0.9232757092 0.9011185765 + 0.9192454815 0.9236338735 0.9015660286 + 0.9196236134 0.9239919782 0.9020134807 + 0.9200018048 0.9243502021 0.9024609923 + 0.9203799963 0.9247083068 0.9029083848 + 0.9207581282 0.9250664711 0.9033558965 + 0.9211360216 0.9254242182 0.9038028717 + 0.9215127826 0.9257805943 0.9042485952 + 0.9218896031 0.9261369705 0.9046943188 + 0.9222664237 0.9264934063 0.9051399827 + 0.9226431847 0.9268497825 0.9055857062 + 0.9230201244 0.9272062182 0.9060314298 + 0.9233968854 0.9275625944 0.9064772129 + 0.9237722158 0.9279180169 0.9069222808 + 0.9241471291 0.9282730818 0.9073672891 + 0.9245219827 0.9286280870 0.9078122973 + 0.9248968959 0.9289832115 0.9082573056 + 0.9252718091 0.9293382764 0.9087021947 + 0.9256467223 0.9296934009 0.9091472030 + 0.9260206819 0.9300473928 0.9095919132 + 0.9263923764 0.9303987026 0.9100357890 + 0.9267640710 0.9307498932 0.9104797244 + 0.9271358252 0.9311012030 0.9109236002 + 0.9275075197 0.9314523935 0.9113674760 + 0.9278790951 0.9318037033 0.9118114114 + 0.9282507896 0.9321550131 0.9122552872 + 0.9286209941 0.9325038195 0.9126986265 + 0.9289904833 0.9328516126 0.9131416082 + 0.9293599725 0.9331995249 0.9135845900 + 0.9297295213 0.9335473180 0.9140275717 + 0.9300991297 0.9338951111 0.9144706726 + 0.9304686189 0.9342429042 0.9149137139 + 0.9308379889 0.9345906973 0.9153565764 + 0.9312061071 0.9349374175 0.9157990217 + 0.9315742254 0.9352840781 0.9162414074 + 0.9319424033 0.9356307983 0.9166836739 + 0.9323105216 0.9359775186 0.9171261191 + 0.9326786995 0.9363241792 0.9175685048 + 0.9330468178 0.9366708994 0.9180107713 + 0.9334139228 0.9370164871 0.9184523225 + 0.9337794185 0.9373604059 0.9188922048 + 0.9341449142 0.9377043247 0.9193322062 + 0.9345104098 0.9380481243 0.9197722077 + 0.9348759055 0.9383919835 0.9202122092 + 0.9352414012 0.9387359023 0.9206520915 + 0.9356068969 0.9390798211 0.9210920930 + 0.9359713793 0.9394215941 0.9215306044 + 0.9363352060 0.9397622943 0.9219684005 + 0.9366990924 0.9401029944 0.9224061966 + 0.9370629787 0.9404436946 0.9228439927 + 0.9374268055 0.9407843947 0.9232817888 + 0.9377906919 0.9411249757 0.9237195849 + 0.9381545782 0.9414656758 0.9241573811 + 0.9385176897 0.9418051839 0.9245941043 + 0.9388806820 0.9421443939 0.9250305891 + 0.9392436743 0.9424837232 0.9254671931 + 0.9396067262 0.9428228736 0.9259036779 + 0.9399697781 0.9431622028 0.9263402224 + 0.9403327703 0.9435014129 0.9267767072 + 0.9406958222 0.9438406825 0.9272131920 + 0.9410552979 0.9441781044 0.9276493788 + 0.9414148927 0.9445155859 0.9280856252 + 0.9417744875 0.9448531270 0.9285218120 + 0.9421340823 0.9451906085 0.9289579988 + 0.9424936175 0.9455280900 0.9293941259 + 0.9428532124 0.9458655715 0.9298303127 + 0.9432125092 0.9462026954 0.9302664995 + 0.9435694218 0.9465367198 0.9307025075 + 0.9439262748 0.9468708038 0.9311385751 + 0.9442831874 0.9472048283 0.9315745831 + 0.9446401000 0.9475389123 0.9320107102 + 0.9449970126 0.9478729963 0.9324467182 + 0.9453539848 0.9482070208 0.9328827858 + 0.9457105994 0.9485409260 0.9333183765 + 0.9460659027 0.9488738179 0.9337515235 + 0.9464210868 0.9492065907 0.9341846108 + 0.9467762709 0.9495394826 0.9346178174 + 0.9471315145 0.9498723149 0.9350509048 + 0.9474868178 0.9502052069 0.9354839921 + 0.9478420019 0.9505379796 0.9359171987 + 0.9481968880 0.9508708119 0.9363495708 + 0.9485492110 0.9512028098 0.9367771745 + 0.9489015937 0.9515348077 0.9372048974 + 0.9492539167 0.9518669248 0.9376325011 + 0.9496062994 0.9521989226 0.9380601048 + 0.9499586225 0.9525309205 0.9384877086 + 0.9503110051 0.9528629184 0.9389153719 + 0.9506632090 0.9531947970 0.9393426776 + 0.9510114789 0.9535222054 0.9397646785 + 0.9513596892 0.9538496733 0.9401866794 + 0.9517080188 0.9541772008 0.9406086802 + 0.9520562291 0.9545047283 0.9410306811 + 0.9524044991 0.9548320770 0.9414526224 + 0.9527528286 0.9551596045 0.9418746233 + 0.9531009793 0.9554870725 0.9422966242 + 0.9534440041 0.9558085203 0.9427149892 + 0.9537863135 0.9561291933 0.9431329966 + 0.9541286230 0.9564499259 0.9435510039 + 0.9544708729 0.9567705989 0.9439690113 + 0.9548131824 0.9570913911 0.9443870187 + 0.9551554918 0.9574121237 0.9448050261 + 0.9554979205 0.9577327967 0.9452229738 + 0.9558368921 0.9580510259 0.9456391931 + 0.9561746120 0.9583681226 0.9460545182 + 0.9565122724 0.9586851001 0.9464697838 + 0.9568499923 0.9590021968 0.9468852282 + 0.9571877122 0.9593192935 0.9473004937 + 0.9575253725 0.9596363902 0.9477158785 + 0.9578630924 0.9599534869 0.9481312037 + 0.9581995010 0.9602695107 0.9485455155 + 0.9585341215 0.9605841041 0.9489583969 + 0.9588688016 0.9608986974 0.9493712783 + 0.9592034817 0.9612134099 0.9497842193 + 0.9595381021 0.9615280032 0.9501971006 + 0.9598727822 0.9618425965 0.9506099224 + 0.9602074027 0.9621571898 0.9510228038 + 0.9605417848 0.9624714851 0.9514353871 + 0.9608737826 0.9627835751 0.9518461227 + 0.9612057805 0.9630956054 0.9522566795 + 0.9615378976 0.9634075761 0.9526674151 + 0.9618698955 0.9637196064 0.9530779719 + 0.9622018933 0.9640315771 0.9534885883 + 0.9625340104 0.9643437266 0.9538993239 + 0.9628660083 0.9646556973 0.9543098807 + 0.9631955028 0.9649661779 0.9547188878 + 0.9635242820 0.9652761221 0.9551271796 + 0.9638530016 0.9655861259 0.9555355906 + 0.9641817212 0.9658960104 0.9559440017 + 0.9645103812 0.9662060142 0.9563524127 + 0.9648391008 0.9665158987 0.9567608237 + 0.9651678205 0.9668259025 0.9571691751 + 0.9654955268 0.9671350121 0.9575765729 + 0.9658207297 0.9674422145 0.9579817057 + 0.9661458731 0.9677494168 0.9583867788 + 0.9664710760 0.9680566788 0.9587919116 + 0.9667962790 0.9683638811 0.9591971040 + 0.9671214819 0.9686710835 0.9596021771 + 0.9674468040 0.9689784050 0.9600073099 + 0.9677720070 0.9692856073 0.9604123831 + 0.9680947065 0.9695898294 0.9608144760 + 0.9684168100 0.9698932767 0.9612157941 + 0.9687389135 0.9701967239 0.9616171718 + 0.9690610170 0.9705001712 0.9620184898 + 0.9693831205 0.9708036780 0.9624199271 + 0.9697052836 0.9711071253 0.9628211856 + 0.9700273871 0.9714105725 0.9632225037 + 0.9703485966 0.9717134237 0.9636229277 + 0.9706671238 0.9720138907 0.9640201926 + 0.9709854722 0.9723144770 0.9644175172 + 0.9713038802 0.9726150036 0.9648149014 + 0.9716224074 0.9729155898 0.9652122259 + 0.9719408154 0.9732161760 0.9656094909 + 0.9722592831 0.9735167027 0.9660068154 + 0.9725776911 0.9738172889 0.9664040804 + 0.9728938937 0.9741159081 0.9667984843 + 0.9732084870 0.9744132757 0.9671909213 + 0.9735231996 0.9747105837 0.9675834179 + 0.9738377929 0.9750080109 0.9679757953 + 0.9741525054 0.9753053784 0.9683682919 + 0.9744670987 0.9756028056 0.9687607884 + 0.9747818112 0.9759001136 0.9691532254 + 0.9750964046 0.9761974812 0.9695457220 + 0.9754077196 0.9764910936 0.9699333906 + 0.9757186174 0.9767844081 0.9703207016 + 0.9760295749 0.9770777225 0.9707080126 + 0.9763404727 0.9773709774 0.9710952044 + 0.9766514897 0.9776641726 0.9714825153 + 0.9769623876 0.9779574871 0.9718698263 + 0.9772734046 0.9782508016 0.9722570777 + 0.9775835872 0.9785434008 0.9726434946 + 0.9778903127 0.9788324833 0.9730253816 + 0.9781969786 0.9791216254 0.9734073877 + 0.9785035849 0.9794107080 0.9737892747 + 0.9788103104 0.9796997905 0.9741712213 + 0.9791169763 0.9799888730 0.9745532274 + 0.9794237018 0.9802780151 0.9749351144 + 0.9797304273 0.9805672169 0.9753171206 + 0.9800354242 0.9808546901 0.9756969213 + 0.9803376198 0.9811394811 0.9760727882 + 0.9806396961 0.9814242125 0.9764487147 + 0.9809417725 0.9817090034 0.9768247008 + 0.9812439084 0.9819936752 0.9772006273 + 0.9815461040 0.9822785258 0.9775764942 + 0.9818481803 0.9825631976 0.9779524803 + 0.9821503162 0.9828479886 0.9783284068 + 0.9824500084 0.9831303954 0.9787008166 + 0.9827467799 0.9834101796 0.9790692925 + 0.9830436707 0.9836900234 0.9794378281 + 0.9833405018 0.9839698076 0.9798063040 + 0.9836373925 0.9842494726 0.9801747799 + 0.9839342237 0.9845293164 0.9805433154 + 0.9842311144 0.9848091006 0.9809117913 + 0.9845278859 0.9850888848 0.9812803268 + 0.9848216176 0.9853662848 0.9816443920 + 0.9851121902 0.9856415987 0.9820045233 + 0.9854028225 0.9859169126 0.9823644757 + 0.9856935143 0.9861922264 0.9827246070 + 0.9859840870 0.9864674807 0.9830846786 + 0.9862747192 0.9867427945 0.9834446907 + 0.9865652919 0.9870181084 0.9838048220 + 0.9868559837 0.9872933030 0.9841647744 + 0.9871436954 0.9875661731 0.9845203161 + 0.9874286056 0.9878365993 0.9848713875 + 0.9877135158 0.9881070256 0.9852225184 + 0.9879983068 0.9883773923 0.9855734706 + 0.9882832170 0.9886478186 0.9859246016 + 0.9885681272 0.9889181852 0.9862756729 + 0.9888529778 0.9891886115 0.9866266847 + 0.9891378880 0.9894589782 0.9869778156 + 0.9894198179 0.9897269011 0.9873241782 + 0.9896976948 0.9899914265 0.9876642823 + 0.9899755120 0.9902557731 0.9880045056 + 0.9902533889 0.9905201793 0.9883446097 + 0.9905313253 0.9907847047 0.9886847138 + 0.9908092022 0.9910491109 0.9890248179 + 0.9910870194 0.9913135767 0.9893649817 + 0.9913648963 0.9915779829 0.9897050858 + 0.9916403294 0.9918411970 0.9900411963 + 0.9919093251 0.9921011925 0.9903668165 + 0.9921782017 0.9923611879 0.9906923175 + 0.9924470782 0.9926211834 0.9910178781 + 0.9927160144 0.9928811789 0.9913433790 + 0.9929850101 0.9931411743 0.9916689992 + 0.9932538867 0.9934012294 0.9919946194 + 0.9935228229 0.9936612248 0.9923201203 + 0.9937912822 0.9939208031 0.9926447868 + 0.9940528274 0.9941738844 0.9929555058 + 0.9943143129 0.9944270253 0.9932662249 + 0.9945756793 0.9946801066 0.9935768843 + 0.9948372245 0.9949333072 0.9938876033 + 0.9950987101 0.9951863885 0.9941983223 + 0.9953601956 0.9954395294 0.9945089817 + 0.9956216216 0.9956926107 0.9948197007 + 0.9958831072 0.9959456921 0.9951304793 + 0.9961357713 0.9961907864 0.9954292774 + 0.9963858724 0.9964336157 0.9957246780 + 0.9966359735 0.9966763258 0.9960200787 + 0.9968860745 0.9969190955 0.9963154793 + 0.9971361756 0.9971618056 0.9966108799 + 0.9973862767 0.9974045753 0.9969062805 + 0.9976363778 0.9976472855 0.9972016811 + 0.9978864789 0.9978901148 0.9974970818 + 0.9981297851 0.9981291294 0.9977846742 + 0.9983634949 0.9983630180 0.9980615973 + 0.9985973239 0.9985967875 0.9983385205 + 0.9988310933 0.9988306761 0.9986153841 + 0.9990649223 0.9990645051 0.9988924265 + 0.9992986917 0.9992983937 0.9991692901 + 0.9995324016 0.9995322824 0.9994462132 + 0.9997661710 0.9997661114 0.9997230768 + 1.0000000000 1.0000000000 1.0000000000 +} diff --git a/rpplugins/color_correction/resources/film_luts_raw/agfa_agfacolor_hdc_100_plus.spi1d b/rpplugins/color_correction/resources/film_luts_raw/agfa_agfacolor_hdc_100_plus.spi1d new file mode 100644 index 0000000..41dbb8c --- /dev/null +++ b/rpplugins/color_correction/resources/film_luts_raw/agfa_agfacolor_hdc_100_plus.spi1d @@ -0,0 +1,1030 @@ +Version 1 +From 0.0 1.0 +Length 1024 +Components 3 +{ + 0.0000000000 0.0000000000 0.0000000000 + 0.0071816309 0.0082409112 0.0071816309 + 0.0151500301 0.0168459192 0.0151500301 + 0.0224017091 0.0247517005 0.0224017091 + 0.0290685501 0.0319880284 0.0290685501 + 0.0352958813 0.0386751406 0.0352958813 + 0.0411669388 0.0448977016 0.0411669388 + 0.0467281416 0.0507521592 0.0467281416 + 0.0520455502 0.0562780313 0.0520455502 + 0.0571411215 0.0615147501 0.0571411215 + 0.0620320588 0.0665091425 0.0620320588 + 0.0667356402 0.0713089630 0.0667356402 + 0.0712965578 0.0759803429 0.0712965578 + 0.0757385418 0.0805422887 0.0757385418 + 0.0800764337 0.0850213692 0.0800764337 + 0.0843147188 0.0894245878 0.0843147188 + 0.0884548426 0.0937559828 0.0884548426 + 0.0925132483 0.0980221704 0.0925132483 + 0.0964898691 0.1022289991 0.0964898691 + 0.1003945023 0.1063620001 0.1003945023 + 0.1042160019 0.1104390025 0.1042160019 + 0.1079747006 0.1144633964 0.1079747006 + 0.1116577014 0.1184230000 0.1116577014 + 0.1152791977 0.1223274022 0.1152791977 + 0.1188424006 0.1261754930 0.1188424006 + 0.1223476008 0.1299650073 0.1223476008 + 0.1257933974 0.1337056011 0.1257933974 + 0.1291857064 0.1373963058 0.1291857064 + 0.1325111985 0.1410335004 0.1325111985 + 0.1357868016 0.1446186006 0.1357868016 + 0.1390141994 0.1481585056 0.1390141994 + 0.1421941966 0.1516450942 0.1421941966 + 0.1453281939 0.1550758928 0.1453281939 + 0.1484290957 0.1584609002 0.1484290957 + 0.1514863074 0.1617927998 0.1514863074 + 0.1545145065 0.1650730968 0.1545145065 + 0.1575087011 0.1683045030 0.1575087011 + 0.1604654938 0.1714911014 0.1604654938 + 0.1633878052 0.1746436059 0.1633878052 + 0.1662711948 0.1777534932 0.1662711948 + 0.1691236049 0.1808203012 0.1691236049 + 0.1719461977 0.1838431954 0.1719461977 + 0.1747328043 0.1868294030 0.1747328043 + 0.1774906069 0.1897847056 0.1774906069 + 0.1802141964 0.1927071065 0.1802141964 + 0.1829040051 0.1955924034 0.1829040051 + 0.1855681986 0.1984508038 0.1855681986 + 0.1881995946 0.2012735009 0.1881995946 + 0.1908040047 0.2040608972 0.1908040047 + 0.1933835000 0.2068151981 0.1933835000 + 0.1959407926 0.2095429003 0.1959407926 + 0.1984723061 0.2122360021 0.1984723061 + 0.2009814978 0.2149036974 0.2009814978 + 0.2034648061 0.2175482064 0.2034648061 + 0.2059251070 0.2201592028 0.2059251070 + 0.2083660066 0.2227438986 0.2083660066 + 0.2107862979 0.2253006995 0.2107862979 + 0.2131928056 0.2278293073 0.2131928056 + 0.2155797929 0.2303356975 0.2155797929 + 0.2179521024 0.2328161001 0.2179521024 + 0.2203088999 0.2352697998 0.2203088999 + 0.2226427943 0.2377053052 0.2226427943 + 0.2249636948 0.2401220948 0.2249636948 + 0.2272658050 0.2425125986 0.2272658050 + 0.2295507044 0.2448851019 0.2295507044 + 0.2318232954 0.2472407967 0.2318232954 + 0.2340773046 0.2495730072 0.2340773046 + 0.2363186032 0.2518830895 0.2363186032 + 0.2385478020 0.2541756034 0.2385478020 + 0.2407571971 0.2564486861 0.2407571971 + 0.2429528981 0.2587057948 0.2429528981 + 0.2451367974 0.2609438896 0.2451367974 + 0.2473030984 0.2631632090 0.2473030984 + 0.2494540960 0.2653681040 0.2494540960 + 0.2515927851 0.2675603926 0.2515927851 + 0.2537161112 0.2697342932 0.2537161112 + 0.2558267117 0.2718896866 0.2558267117 + 0.2579267025 0.2740308046 0.2579267025 + 0.2600139081 0.2761551142 0.2600139081 + 0.2620905042 0.2782635987 0.2620905042 + 0.2641522884 0.2803570926 0.2641522884 + 0.2661997080 0.2824395895 0.2661997080 + 0.2682358921 0.2845089138 0.2682358921 + 0.2702636123 0.2865653038 0.2702636123 + 0.2722778916 0.2886031866 0.2722778916 + 0.2742806971 0.2906292975 0.2742806971 + 0.2762736082 0.2926450074 0.2762736082 + 0.2782565951 0.2946475148 0.2782565951 + 0.2802278996 0.2966375053 0.2802278996 + 0.2821829021 0.2986125946 0.2821829021 + 0.2841286063 0.3005768061 0.2841286063 + 0.2860676050 0.3025309145 0.2860676050 + 0.2879948914 0.3044739962 0.2879948914 + 0.2899109125 0.3064059913 0.2899109125 + 0.2918199003 0.3083246052 0.2918199003 + 0.2937203050 0.3102298975 0.2937203050 + 0.2956117988 0.3121252954 0.2956117988 + 0.2974927127 0.3140129149 0.2974927127 + 0.2993623018 0.3158906996 0.2993623018 + 0.3012244105 0.3177559078 0.3012244105 + 0.3030805886 0.3196083009 0.3030805886 + 0.3049291968 0.3214524984 0.3049291968 + 0.3067674041 0.3232868016 0.3067674041 + 0.3085950911 0.3251119852 0.3085950911 + 0.3104135990 0.3269273937 0.3104135990 + 0.3122237027 0.3287312090 0.3122237027 + 0.3140270114 0.3305267096 0.3140270114 + 0.3158223927 0.3323149085 0.3158223927 + 0.3176110089 0.3340944946 0.3176110089 + 0.3193928003 0.3358643055 0.3193928003 + 0.3211658001 0.3376250863 0.3211658001 + 0.3229303062 0.3393788934 0.3229303062 + 0.3246853054 0.3411253095 0.3246853054 + 0.3264288902 0.3428628147 0.3264288902 + 0.3281643093 0.3445931077 0.3281643093 + 0.3298931122 0.3463181853 0.3298931122 + 0.3316138089 0.3480368853 0.3316138089 + 0.3333249986 0.3497483134 0.3333249986 + 0.3350282013 0.3514511883 0.3350282013 + 0.3367244899 0.3531453907 0.3367244899 + 0.3384152055 0.3548327088 0.3384152055 + 0.3401009142 0.3565143049 0.3401009142 + 0.3417800069 0.3581889868 0.3417800069 + 0.3434512019 0.3598566949 0.3434512019 + 0.3451134861 0.3615188897 0.3451134861 + 0.3467679918 0.3631770015 0.3467679918 + 0.3484159112 0.3648299873 0.3484159112 + 0.3500581980 0.3664768934 0.3500581980 + 0.3516958952 0.3681172132 0.3516958952 + 0.3533272147 0.3697521985 0.3533272147 + 0.3549514115 0.3713811040 0.3549514115 + 0.3565692902 0.3730033040 0.3565692902 + 0.3581799865 0.3746202886 0.3581799865 + 0.3597826958 0.3762314916 0.3597826958 + 0.3613792062 0.3778361976 0.3613792062 + 0.3629701138 0.3794350028 0.3629701138 + 0.3645544946 0.3810291886 0.3645544946 + 0.3661319017 0.3826195002 0.3661319017 + 0.3677032888 0.3842051923 0.3677032888 + 0.3692691922 0.3857854009 0.3692691922 + 0.3708305955 0.3873588145 0.3708305955 + 0.3723872006 0.3889274001 0.3723872006 + 0.3739395142 0.3904910982 0.3739395142 + 0.3754872978 0.3920491040 0.3754872978 + 0.3770299852 0.3936016858 0.3770299852 + 0.3785668015 0.3951497972 0.3785668015 + 0.3800952137 0.3966915905 0.3800952137 + 0.3816176057 0.3982270956 0.3816176057 + 0.3831363916 0.3997577131 0.3831363916 + 0.3846518993 0.4012834132 0.3846518993 + 0.3861635923 0.4028038085 0.3861635923 + 0.3876700103 0.4043180048 0.3876700103 + 0.3891699910 0.4058266878 0.3891699910 + 0.3906654119 0.4073303044 0.3906654119 + 0.3921560049 0.4088295996 0.3921560049 + 0.3936414123 0.4103249907 0.3936414123 + 0.3951213062 0.4118149877 0.3951213062 + 0.3965955079 0.4132992923 0.3965955079 + 0.3980641961 0.4147784114 0.3980641961 + 0.3995279074 0.4162524939 0.3995279074 + 0.4009875953 0.4177218080 0.4009875953 + 0.4024423063 0.4191871881 0.4024423063 + 0.4038924873 0.4206492007 0.4038924873 + 0.4053378999 0.4221076965 0.4053378999 + 0.4067766070 0.4235613942 0.4067766070 + 0.4082114995 0.4250093997 0.4082114995 + 0.4096431136 0.4264526963 0.4096431136 + 0.4110710919 0.4278913140 0.4110710919 + 0.4124928117 0.4293223023 0.4124928117 + 0.4139108062 0.4307503104 0.4139108062 + 0.4153253138 0.4321753085 0.4153253138 + 0.4167349935 0.4335967898 0.4167349935 + 0.4181382954 0.4350129068 0.4181382954 + 0.4195368886 0.4364252090 0.4195368886 + 0.4209308028 0.4378337860 0.4209308028 + 0.4223197103 0.4392373860 0.4223197103 + 0.4237053990 0.4406375885 0.4237053990 + 0.4250878096 0.4420346022 0.4250878096 + 0.4264639914 0.4434260130 0.4264639914 + 0.4278368056 0.4448128045 0.4278368056 + 0.4292069972 0.4461959004 0.4292069972 + 0.4305736125 0.4475724995 0.4305736125 + 0.4319368899 0.4489449859 0.4319368899 + 0.4332974851 0.4503144026 0.4332974851 + 0.4346528947 0.4516780972 0.4346528947 + 0.4360040128 0.4530383050 0.4360040128 + 0.4373517036 0.4543960094 0.4373517036 + 0.4386920035 0.4557482898 0.4386920035 + 0.4400289059 0.4570981860 0.4400289059 + 0.4413625896 0.4584460855 0.4413625896 + 0.4426892102 0.4597887993 0.4426892102 + 0.4440130889 0.4611299038 0.4440130889 + 0.4453332126 0.4624690115 0.4453332126 + 0.4466494024 0.4638045132 0.4466494024 + 0.4479633868 0.4651381075 0.4479633868 + 0.4492729008 0.4664680064 0.4492729008 + 0.4505785108 0.4677945077 0.4505785108 + 0.4518812895 0.4691188931 0.4518812895 + 0.4531790912 0.4704371989 0.4531790912 + 0.4544754028 0.4717530906 0.4544754028 + 0.4557689130 0.4730646908 0.4557689130 + 0.4570592046 0.4743711948 0.4570592046 + 0.4583478868 0.4756751955 0.4583478868 + 0.4596310854 0.4769738019 0.4596310854 + 0.4609121978 0.4782701135 0.4609121978 + 0.4621888995 0.4795624018 0.4621888995 + 0.4634611011 0.4808515906 0.4634611011 + 0.4647307098 0.4821392894 0.4647307098 + 0.4659950137 0.4834218919 0.4659950137 + 0.4672574103 0.4847030044 0.4672574103 + 0.4685145915 0.4859794974 0.4685145915 + 0.4697686136 0.4872528017 0.4697686136 + 0.4710184932 0.4885227978 0.4710184932 + 0.4722628891 0.4897891879 0.4722628891 + 0.4735049009 0.4910542071 0.4735049009 + 0.4747408926 0.4923141003 0.4747408926 + 0.4759756923 0.4935730100 0.4759756923 + 0.4772061110 0.4948287904 0.4772061110 + 0.4784345031 0.4960829020 0.4784345031 + 0.4796591997 0.4973343015 0.4796591997 + 0.4808802903 0.4985828102 0.4808802903 + 0.4820986092 0.4998292029 0.4820986092 + 0.4833118021 0.5010713935 0.4833118021 + 0.4845229983 0.5023121834 0.4845229983 + 0.4857310057 0.5035473704 0.4857310057 + 0.4869383872 0.5047817826 0.4869383872 + 0.4881415069 0.5060117245 0.4881415069 + 0.4893437922 0.5072407722 0.4893437922 + 0.4905417860 0.5084657073 0.4905417860 + 0.4917384088 0.5096889138 0.4917384088 + 0.4929305911 0.5109081864 0.4929305911 + 0.4941214025 0.5121250749 0.4941214025 + 0.4953092933 0.5133383274 0.4953092933 + 0.4964950979 0.5145484209 0.4964950979 + 0.4976781011 0.5157549977 0.4976781011 + 0.4988583922 0.5169578195 0.4988583922 + 0.5000360012 0.5181573033 0.5000360012 + 0.5012102127 0.5193536878 0.5012102127 + 0.5023818016 0.5205478072 0.5023818016 + 0.5035495758 0.5217382908 0.5035495758 + 0.5047146082 0.5229266286 0.5047146082 + 0.5058754086 0.5241109133 0.5058754086 + 0.5070334077 0.5252929926 0.5070334077 + 0.5081868768 0.5264708996 0.5081868768 + 0.5093373060 0.5276464224 0.5093373060 + 0.5104840994 0.5288175941 0.5104840994 + 0.5116283298 0.5299862027 0.5116283298 + 0.5127689242 0.5311505795 0.5127689242 + 0.5139064193 0.5323119164 0.5139064193 + 0.5150403976 0.5334690809 0.5150403976 + 0.5161709189 0.5346227884 0.5161709189 + 0.5172979832 0.5357729197 0.5172979832 + 0.5184208751 0.5369185805 0.5184208751 + 0.5195422769 0.5380612016 0.5195422769 + 0.5206609964 0.5391985774 0.5206609964 + 0.5217785239 0.5403342843 0.5217785239 + 0.5228924751 0.5414649844 0.5228924751 + 0.5240058899 0.5425949097 0.5240058899 + 0.5251148939 0.5437206030 0.5251148939 + 0.5262238979 0.5448461771 0.5262238979 + 0.5273274183 0.5459663868 0.5273274183 + 0.5284308791 0.5470865965 0.5284308791 + 0.5295295119 0.5482017994 0.5295295119 + 0.5306270719 0.5493162274 0.5306270719 + 0.5317205191 0.5504277945 0.5317205191 + 0.5328117013 0.5515381098 0.5328117013 + 0.5339006782 0.5526462197 0.5339006782 + 0.5349869728 0.5537520051 0.5349869728 + 0.5360723734 0.5548564792 0.5360723734 + 0.5371550918 0.5559577942 0.5371550918 + 0.5382375717 0.5570588112 0.5382375717 + 0.5393161774 0.5581569076 0.5393161774 + 0.5403949022 0.5592550039 0.5403949022 + 0.5414698720 0.5603502989 0.5414698720 + 0.5425440073 0.5614449978 0.5425440073 + 0.5436155200 0.5625376105 0.5436155200 + 0.5446845889 0.5636284947 0.5446845889 + 0.5457528830 0.5647183061 0.5457528830 + 0.5468186140 0.5658050179 0.5468186140 + 0.5478842854 0.5668917894 0.5478842854 + 0.5489463806 0.5679742098 0.5489463806 + 0.5500082970 0.5690563917 0.5500082970 + 0.5510675907 0.5701354742 0.5510675907 + 0.5521252751 0.5712130070 0.5521252751 + 0.5531818271 0.5722888112 0.5531818271 + 0.5542349815 0.5733609796 0.5542349815 + 0.5552883148 0.5744333267 0.5552883148 + 0.5563371181 0.5755001903 0.5563371181 + 0.5573856235 0.5765669942 0.5573856235 + 0.5584312081 0.5776314139 0.5584312081 + 0.5594745278 0.5786941051 0.5594745278 + 0.5605170131 0.5797560811 0.5605170131 + 0.5615549088 0.5808146000 0.5615549088 + 0.5625928044 0.5818731189 0.5625928044 + 0.5636265278 0.5829282999 0.5636265278 + 0.5646585822 0.5839822888 0.5646585822 + 0.5656889081 0.5850347877 0.5656889081 + 0.5667148829 0.5860841274 0.5667148829 + 0.5677409768 0.5871334076 0.5677409768 + 0.5687615871 0.5881785154 0.5687615871 + 0.5697811842 0.5892227888 0.5697811842 + 0.5707985163 0.5902652144 0.5707985163 + 0.5718113780 0.5913044214 0.5718113780 + 0.5728244185 0.5923436284 0.5728244185 + 0.5738328099 0.5933796167 0.5738328099 + 0.5748404264 0.5944151878 0.5748404264 + 0.5758461952 0.5954493880 0.5758461952 + 0.5768483877 0.5964813232 0.5768483877 + 0.5778505206 0.5975130796 0.5778505206 + 0.5788481236 0.5985416770 0.5788481236 + 0.5798444748 0.5995696187 0.5798444748 + 0.5808395147 0.6005964875 0.5808395147 + 0.5818299055 0.6016203165 0.5818299055 + 0.5828202963 0.6026440859 0.5828202963 + 0.5838078260 0.6036651134 0.5838078260 + 0.5847936869 0.6046845913 0.5847936869 + 0.5857794881 0.6057038903 0.5857794881 + 0.5867608190 0.6067190170 0.5867608190 + 0.5877420902 0.6077340841 0.5877420902 + 0.5887213945 0.6087473035 0.5887213945 + 0.5896978974 0.6097577810 0.5896978974 + 0.5906744003 0.6107683182 0.5906744003 + 0.5916472077 0.6117751002 0.5916472077 + 0.5926188231 0.6127809286 0.5926188231 + 0.5935899019 0.6137859821 0.5935899019 + 0.5945563912 0.6147853136 0.5945563912 + 0.5955228806 0.6157847047 0.5955228806 + 0.5964874029 0.6167812943 0.5964874029 + 0.5974487066 0.6177741289 0.5974487066 + 0.5984100103 0.6187667847 0.5984100103 + 0.5993676782 0.6197549105 0.5993676782 + 0.6003236771 0.6207411289 0.6003236771 + 0.6012796760 0.6217272878 0.6012796760 + 0.6022304893 0.6227068901 0.6022304893 + 0.6031810045 0.6236863136 0.6031810045 + 0.6041305065 0.6246638894 0.6041305065 + 0.6050754786 0.6256346703 0.6050754786 + 0.6060203910 0.6266055107 0.6060203910 + 0.6069629788 0.6275725961 0.6069629788 + 0.6079022884 0.6285349131 0.6079022884 + 0.6088414788 0.6294971108 0.6088414788 + 0.6097772717 0.6304540038 0.6097772717 + 0.6107106805 0.6314077973 0.6107106805 + 0.6116440892 0.6323614717 0.6116440892 + 0.6125729084 0.6333085895 0.6125729084 + 0.6135004163 0.6342539191 0.6135004163 + 0.6144278049 0.6351991892 0.6144278049 + 0.6153497100 0.6361367702 0.6153497100 + 0.6162710786 0.6370738149 0.6162710786 + 0.6171923280 0.6380103230 0.6171923280 + 0.6181074977 0.6389390826 0.6181074977 + 0.6190227270 0.6398677826 0.6190227270 + 0.6199370027 0.6407952905 0.6199370027 + 0.6208459139 0.6417160034 0.6208459139 + 0.6217548251 0.6426365972 0.6217548251 + 0.6226627231 0.6435554028 0.6226627231 + 0.6235666871 0.6444680095 0.6235666871 + 0.6244707108 0.6453806162 0.6244707108 + 0.6253734231 0.6462908983 0.6253734231 + 0.6262723804 0.6471955180 0.6262723804 + 0.6271713972 0.6481000781 0.6271713972 + 0.6280689836 0.6490027905 0.6280689836 + 0.6289629936 0.6499009728 0.6289629936 + 0.6298570037 0.6507992148 0.6298570037 + 0.6307495236 0.6516954899 0.6307495236 + 0.6316384077 0.6525874138 0.6316384077 + 0.6325272918 0.6534792781 0.6325272918 + 0.6334148049 0.6543694139 0.6334148049 + 0.6342985034 0.6552550793 0.6342985034 + 0.6351823211 0.6561406851 0.6351823211 + 0.6360648274 0.6570249200 0.6360648274 + 0.6369432807 0.6579043865 0.6369432807 + 0.6378217936 0.6587839127 0.6378217936 + 0.6386997104 0.6596624255 0.6386997104 + 0.6395745873 0.6605358124 0.6395745873 + 0.6404494047 0.6614091992 0.6404494047 + 0.6413241029 0.6622822285 0.6413241029 + 0.6421937943 0.6631495953 0.6421937943 + 0.6430636048 0.6640170217 0.6430636048 + 0.6439334154 0.6648843884 0.6439334154 + 0.6447985768 0.6657463908 0.6447985768 + 0.6456633806 0.6666080952 0.6456633806 + 0.6465281844 0.6674697995 0.6465281844 + 0.6473892927 0.6683270931 0.6473892927 + 0.6482492089 0.6691833138 0.6482492089 + 0.6491091251 0.6700394750 0.6491091251 + 0.6499661207 0.6708925962 0.6499661207 + 0.6508212090 0.6717435718 0.6508212090 + 0.6516762972 0.6725946069 0.6516762972 + 0.6525288820 0.6734434962 0.6525288820 + 0.6533777118 0.6742895246 0.6533777118 + 0.6542264819 0.6751354933 0.6542264819 + 0.6550742984 0.6759806871 0.6550742984 + 0.6559169888 0.6768220067 0.6559169888 + 0.6567596793 0.6776633263 0.6567596793 + 0.6576023102 0.6785045862 0.6576023102 + 0.6584395766 0.6793416739 0.6584395766 + 0.6592763066 0.6801785231 0.6592763066 + 0.6601129770 0.6810153127 0.6601129770 + 0.6609460711 0.6818485260 0.6609460711 + 0.6617770791 0.6826794744 0.6617770791 + 0.6626080275 0.6835106015 0.6626080275 + 0.6634371877 0.6843398213 0.6634371877 + 0.6642624736 0.6851654053 0.6642624736 + 0.6650878787 0.6859909892 0.6650878787 + 0.6659132242 0.6868165731 0.6659132242 + 0.6667333245 0.6876372099 0.6667333245 + 0.6675531864 0.6884577274 0.6675531864 + 0.6683731079 0.6892783046 0.6683731079 + 0.6691898704 0.6900957823 0.6691898704 + 0.6700046062 0.6909114718 0.6700046062 + 0.6708192825 0.6917272210 0.6708192825 + 0.6716328859 0.6925418973 0.6716328859 + 0.6724424958 0.6933531761 0.6724424958 + 0.6732522249 0.6941645145 0.6732522249 + 0.6740617752 0.6949757934 0.6740617752 + 0.6748675704 0.6957837939 0.6748675704 + 0.6756724119 0.6965909004 0.6756724119 + 0.6764771938 0.6973981261 0.6764771938 + 0.6772803068 0.6982039213 0.6772803068 + 0.6780803800 0.6990072131 0.6780803800 + 0.6788805127 0.6998106241 0.6788805127 + 0.6796805263 0.7006139159 0.6796805263 + 0.6804767251 0.7014129758 0.6804767251 + 0.6812722087 0.7022113800 0.6812722087 + 0.6820678115 0.7030097842 0.6820678115 + 0.6828618050 0.7038065195 0.6828618050 + 0.6836528778 0.7046002746 0.6836528778 + 0.6844441295 0.7053942084 0.6844441295 + 0.6852353215 0.7061880827 0.6852353215 + 0.6860229969 0.7069783807 0.6860229969 + 0.6868100166 0.7077680826 0.6868100166 + 0.6875969768 0.7085577846 0.6875969768 + 0.6883826256 0.7093464136 0.6883826256 + 0.6891641021 0.7101323009 0.6891641021 + 0.6899456978 0.7109181881 0.6899456978 + 0.6907271743 0.7117040753 0.6907271743 + 0.6915053725 0.7124866843 0.6915053725 + 0.6922817230 0.7132676244 0.6922817230 + 0.6930580139 0.7140485048 0.6930580139 + 0.6938341856 0.7148293257 0.6938341856 + 0.6946055293 0.7156057954 0.6946055293 + 0.6953768134 0.7163822055 0.6953768134 + 0.6961480975 0.7171586752 0.6961480975 + 0.6969177127 0.7179335952 0.6969177127 + 0.6976842284 0.7187060714 0.6976842284 + 0.6984508038 0.7194784880 0.6984508038 + 0.6992173195 0.7202510238 0.6992173195 + 0.6999806762 0.7210199833 0.6999806762 + 0.7007427216 0.7217875719 0.7007427216 + 0.7015047073 0.7225551009 0.7015047073 + 0.7022666931 0.7233226895 0.7022666931 + 0.7030245066 0.7240859270 0.7030245066 + 0.7037820816 0.7248489857 0.7037820816 + 0.7045397162 0.7256121039 0.7045397162 + 0.7052962184 0.7263739109 0.7052962184 + 0.7060483098 0.7271317244 0.7060483098 + 0.7068005204 0.7278894186 0.7068005204 + 0.7075526118 0.7286471128 0.7075526118 + 0.7083024979 0.7294024825 0.7083024979 + 0.7090494037 0.7301552892 0.7090494037 + 0.7097964287 0.7309080958 0.7097964287 + 0.7105432749 0.7316607833 0.7105432749 + 0.7112872005 0.7324107289 0.7112872005 + 0.7120292187 0.7331590056 0.7120292187 + 0.7127712965 0.7339072227 0.7127712965 + 0.7135133147 0.7346554995 0.7135133147 + 0.7142516971 0.7354004979 0.7142516971 + 0.7149891853 0.7361447215 0.7149891853 + 0.7157266140 0.7368888855 0.7157266140 + 0.7164639831 0.7376331091 0.7164639831 + 0.7171975970 0.7383713126 0.7171975970 + 0.7179307938 0.7391089201 0.7179307938 + 0.7186638713 0.7398465872 0.7186638713 + 0.7193971276 0.7405840755 0.7193971276 + 0.7201262116 0.7413142920 0.7201262116 + 0.7208554149 0.7420445085 0.7208554149 + 0.7215844989 0.7427747846 0.7215844989 + 0.7223134041 0.7435045242 0.7223134041 + 0.7230387926 0.7442278266 0.7230387926 + 0.7237643003 0.7449511290 0.7237643003 + 0.7244896889 0.7456744909 0.7244896889 + 0.7252147198 0.7463970780 0.7252147198 + 0.7259353995 0.7471140027 0.7259353995 + 0.7266560793 0.7478309870 0.7266560793 + 0.7273768187 0.7485479116 0.7273768187 + 0.7280970812 0.7492641807 0.7280970812 + 0.7288134098 0.7499753237 0.7288134098 + 0.7295296788 0.7506862879 0.7295296788 + 0.7302460074 0.7513973117 0.7302460074 + 0.7309620976 0.7521079779 0.7309620976 + 0.7316743135 0.7528135777 0.7316743135 + 0.7323865294 0.7535192966 0.7323865294 + 0.7330986857 0.7542248964 0.7330986857 + 0.7338109016 0.7549306154 0.7338109016 + 0.7345194817 0.7556313276 0.7345194817 + 0.7352281213 0.7563319802 0.7352281213 + 0.7359365821 0.7570326924 0.7359365821 + 0.7366451025 0.7577335238 0.7366451025 + 0.7373495102 0.7584289908 0.7373495102 + 0.7380533218 0.7591239214 0.7380533218 + 0.7387570739 0.7598189116 0.7387570739 + 0.7394608855 0.7605137825 0.7394608855 + 0.7401614785 0.7612038255 0.7401614785 + 0.7408609986 0.7618921995 0.7408609986 + 0.7415605187 0.7625805736 0.7415605187 + 0.7422599792 0.7632690072 0.7422599792 + 0.7429572940 0.7639539838 0.7429572940 + 0.7436528802 0.7646365166 0.7436528802 + 0.7443485260 0.7653189898 0.7443485260 + 0.7450441122 0.7660015225 0.7450441122 + 0.7457385063 0.7666820288 0.7457385063 + 0.7464305758 0.7673591971 0.7464305758 + 0.7471227050 0.7680364251 0.7471227050 + 0.7478148937 0.7687135935 0.7478148937 + 0.7485067248 0.7693902850 0.7485067248 + 0.7491956949 0.7700628042 0.7491956949 + 0.7498847842 0.7707353830 0.7498847842 + 0.7505738735 0.7714080215 0.7505738735 + 0.7512630224 0.7720804811 0.7512630224 + 0.7519487739 0.7727484703 0.7519487739 + 0.7526339889 0.7734156251 0.7526339889 + 0.7533192039 0.7740827203 0.7533192039 + 0.7540044188 0.7747498751 0.7540044188 + 0.7546877861 0.7754138112 0.7546877861 + 0.7553694844 0.7760748863 0.7553694844 + 0.7560511827 0.7767360806 0.7560511827 + 0.7567330003 0.7773972154 0.7567330003 + 0.7574139237 0.7780573964 0.7574139237 + 0.7580912709 0.7787132263 0.7580912709 + 0.7587686777 0.7793691158 0.7587686777 + 0.7594460845 0.7800250053 0.7594460845 + 0.7601234913 0.7806808949 0.7601234913 + 0.7607979178 0.7813320756 0.7607979178 + 0.7614712715 0.7819821835 0.7614712715 + 0.7621448040 0.7826321721 0.7621448040 + 0.7628182769 0.7832822800 0.7628182769 + 0.7634900212 0.7839304209 0.7634900212 + 0.7641587257 0.7845754027 0.7641587257 + 0.7648273110 0.7852203250 0.7648273110 + 0.7654958963 0.7858651876 0.7654958963 + 0.7661646008 0.7865102291 0.7661646008 + 0.7668293118 0.7871509790 0.7668293118 + 0.7674936056 0.7877914906 0.7674936056 + 0.7681578994 0.7884320021 0.7681578994 + 0.7688220739 0.7890725136 0.7688220739 + 0.7694842815 0.7897108197 0.7694842815 + 0.7701433897 0.7903463244 0.7701433897 + 0.7708023787 0.7909818292 0.7708023787 + 0.7714614868 0.7916172743 0.7714614868 + 0.7721205950 0.7922527194 0.7721205950 + 0.7727754116 0.7928832173 0.7727754116 + 0.7734296918 0.7935130000 0.7734296918 + 0.7740839720 0.7941429019 0.7740839720 + 0.7747381926 0.7947726846 0.7747381926 + 0.7753911018 0.7954009771 0.7753911018 + 0.7760409713 0.7960259914 0.7760409713 + 0.7766909003 0.7966510057 0.7766909003 + 0.7773407102 0.7972760201 0.7773407102 + 0.7779905796 0.7979009748 0.7779905796 + 0.7786368132 0.7985221744 0.7786368132 + 0.7792813778 0.7991417050 0.7792813778 + 0.7799261212 0.7997612953 0.7799261212 + 0.7805706859 0.8003808856 0.7805706859 + 0.7812150717 0.8010001779 0.7812150717 + 0.7818549275 0.8016149998 0.7818549275 + 0.7824947834 0.8022298813 0.7824947834 + 0.7831345797 0.8028448224 0.7831345797 + 0.7837744951 0.8034597039 0.7837744951 + 0.7844126821 0.8040724993 0.7844126821 + 0.7850481868 0.8046821952 0.7850481868 + 0.7856836915 0.8052918911 0.7856836915 + 0.7863191962 0.8059015274 0.7863191962 + 0.7869547009 0.8065112233 0.7869547009 + 0.7875875831 0.8071171045 0.7875875831 + 0.7882192135 0.8077210188 0.7882192135 + 0.7888507247 0.8083249927 0.7888507247 + 0.7894822955 0.8089289069 0.7894822955 + 0.7901139259 0.8095328808 0.7901139259 + 0.7907413244 0.8101323843 0.7907413244 + 0.7913681269 0.8107314110 0.7913681269 + 0.7919949889 0.8113303781 0.7919949889 + 0.7926219106 0.8119294047 0.7926219106 + 0.7932484150 0.8125280738 0.7932484150 + 0.7938709855 0.8131231070 0.7938709855 + 0.7944936752 0.8137180209 0.7944936752 + 0.7951163054 0.8143129945 0.7951163054 + 0.7957389951 0.8149080276 0.7957389951 + 0.7963607907 0.8155021071 0.7963607907 + 0.7969797254 0.8160938025 0.7969797254 + 0.7975987196 0.8166856170 0.7975987196 + 0.7982177138 0.8172773123 0.7982177138 + 0.7988365889 0.8178690076 0.7988365889 + 0.7994540930 0.8184589148 0.7994540930 + 0.8000686765 0.8190457821 0.8000686765 + 0.8006833196 0.8196325898 0.8006833196 + 0.8012979031 0.8202195168 0.8012979031 + 0.8019124866 0.8208063245 0.8019124866 + 0.8025255203 0.8213908076 0.8025255203 + 0.8031362891 0.8219724298 0.8031362891 + 0.8037471175 0.8225538731 0.8037471175 + 0.8043578863 0.8231354952 0.8043578863 + 0.8049687147 0.8237169981 0.8049687147 + 0.8055779934 0.8242964149 0.8055779934 + 0.8061854839 0.8248735070 0.8061854839 + 0.8067929745 0.8254505992 0.8067929745 + 0.8074005842 0.8260276914 0.8074005842 + 0.8080080748 0.8266047835 0.8080080748 + 0.8086137772 0.8271802068 0.8086137772 + 0.8092173934 0.8277537823 0.8092173934 + 0.8098208904 0.8283274174 0.8098208904 + 0.8104245067 0.8289008737 0.8104245067 + 0.8110281229 0.8294745088 0.8110281229 + 0.8116297722 0.8300458193 0.8116297722 + 0.8122286797 0.8306140900 0.8122286797 + 0.8128275871 0.8311824203 0.8128275871 + 0.8134266138 0.8317506909 0.8134266138 + 0.8140255213 0.8323189020 0.8140255213 + 0.8146228194 0.8328853846 0.8146228194 + 0.8152164817 0.8334481120 0.8152164817 + 0.8158102036 0.8340108991 0.8158102036 + 0.8164039254 0.8345736265 0.8164039254 + 0.8169975877 0.8351362944 0.8169975877 + 0.8175904751 0.8356981277 0.8175904751 + 0.8181796074 0.8362563252 0.8181796074 + 0.8187686801 0.8368144035 0.8187686801 + 0.8193578124 0.8373724818 0.8193578124 + 0.8199468851 0.8379306793 0.8199468851 + 0.8205358982 0.8384886980 0.8205358982 + 0.8211209774 0.8390418887 0.8211209774 + 0.8217059970 0.8395950794 0.8217059970 + 0.8222910762 0.8401483893 0.8222910762 + 0.8228762150 0.8407015800 0.8228762150 + 0.8234611750 0.8412547708 0.8234611750 + 0.8240435719 0.8418037891 0.8240435719 + 0.8246251941 0.8423519135 0.8246251941 + 0.8252068162 0.8428999782 0.8252068162 + 0.8257884979 0.8434481025 0.8257884979 + 0.8263701200 0.8439962268 0.8263701200 + 0.8269495964 0.8445411921 0.8269495964 + 0.8275271058 0.8450837731 0.8275271058 + 0.8281046152 0.8456264138 0.8281046152 + 0.8286821842 0.8461689949 0.8286821842 + 0.8292596936 0.8467115760 0.8292596936 + 0.8298364282 0.8472530246 0.8298364282 + 0.8304104209 0.8477910757 0.8304104209 + 0.8309844136 0.8483291268 0.8309844136 + 0.8315584064 0.8488671780 0.8315584064 + 0.8321323991 0.8494052291 0.8321323991 + 0.8327063918 0.8499432802 0.8327063918 + 0.8332766891 0.8504770994 0.8332766891 + 0.8338465095 0.8510105014 0.8338465095 + 0.8344163895 0.8515439034 0.8344163895 + 0.8349862099 0.8520773053 0.8349862099 + 0.8355559707 0.8526107073 0.8355559707 + 0.8361235261 0.8531416059 0.8361235261 + 0.8366885781 0.8536701202 0.8366885781 + 0.8372538090 0.8541985750 0.8372538090 + 0.8378189206 0.8547270894 0.8378189206 + 0.8383839726 0.8552556038 0.8383839726 + 0.8389489055 0.8557837009 0.8389489055 + 0.8395100236 0.8563070893 0.8395100236 + 0.8400710821 0.8568304777 0.8400710821 + 0.8406322002 0.8573539257 0.8406322002 + 0.8411933184 0.8578773141 0.8411933184 + 0.8417543173 0.8584007025 0.8417543173 + 0.8423134089 0.8589209914 0.8423134089 + 0.8428711295 0.8594391942 0.8428711295 + 0.8434287906 0.8599573970 0.8434287906 + 0.8439865112 0.8604755998 0.8439865112 + 0.8445441127 0.8609936833 0.8445441127 + 0.8451015949 0.8615115881 0.8451015949 + 0.8456565142 0.8620254993 0.8456565142 + 0.8462113738 0.8625394106 0.8462113738 + 0.8467662930 0.8630533218 0.8467662930 + 0.8473210931 0.8635671735 0.8473210931 + 0.8478760123 0.8640810847 0.8478760123 + 0.8484287262 0.8645929098 0.8484287262 + 0.8489791751 0.8651022911 0.8489791751 + 0.8495296240 0.8656117916 0.8495296240 + 0.8500800133 0.8661211729 0.8500800133 + 0.8506304026 0.8666306734 0.8506304026 + 0.8511807919 0.8671401739 0.8511807919 + 0.8517271280 0.8676456213 0.8517271280 + 0.8522726297 0.8681504130 0.8522726297 + 0.8528181911 0.8686553240 0.8528181911 + 0.8533636928 0.8691601157 0.8533636928 + 0.8539093137 0.8696649075 0.8539093137 + 0.8544539809 0.8701689839 0.8544539809 + 0.8549953103 0.8706703186 0.8549953103 + 0.8555366993 0.8711714745 0.8555366993 + 0.8560780883 0.8716726899 0.8560780883 + 0.8566194177 0.8721739054 0.8566194177 + 0.8571608067 0.8726751804 0.8571608067 + 0.8577004075 0.8731746078 0.8577004075 + 0.8582382798 0.8736721873 0.8582382798 + 0.8587760925 0.8741698861 0.8587760925 + 0.8593140244 0.8746675253 0.8593140244 + 0.8598517776 0.8751651049 0.8598517776 + 0.8603895903 0.8756626844 0.8603895903 + 0.8609246016 0.8761566877 0.8609246016 + 0.8614584208 0.8766493797 0.8614584208 + 0.8619921803 0.8771420121 0.8619921803 + 0.8625261188 0.8776347041 0.8625261188 + 0.8630598783 0.8781273961 0.8630598783 + 0.8635936975 0.8786200285 0.8635936975 + 0.8641244173 0.8791080713 0.8641244173 + 0.8646547794 0.8795956969 0.8646547794 + 0.8651853204 0.8800833821 0.8651853204 + 0.8657156825 0.8805711269 0.8657156825 + 0.8662461042 0.8810586929 0.8662461042 + 0.8667764068 0.8815460801 0.8667764068 + 0.8673040271 0.8820288181 0.8673040271 + 0.8678315878 0.8825113773 0.8678315878 + 0.8683593273 0.8829941154 0.8683593273 + 0.8688868880 0.8834767938 0.8688868880 + 0.8694145083 0.8839594722 0.8694145083 + 0.8699415922 0.8844413757 0.8699415922 + 0.8704659939 0.8849189878 0.8704659939 + 0.8709903955 0.8853965998 0.8709903955 + 0.8715146780 0.8858740926 0.8715146780 + 0.8720390797 0.8863517046 0.8720390797 + 0.8725634813 0.8868293166 0.8725634813 + 0.8730871081 0.8873060942 0.8730871081 + 0.8736078143 0.8877797127 0.8736078143 + 0.8741285205 0.8882532716 0.8741285205 + 0.8746492267 0.8887268901 0.8746492267 + 0.8751698136 0.8892006278 0.8751698136 + 0.8756905198 0.8896741867 0.8756905198 + 0.8762103915 0.8901467919 0.8762103915 + 0.8767271042 0.8906152844 0.8767271042 + 0.8772436976 0.8910837770 0.8772436976 + 0.8777604103 0.8915523887 0.8777604103 + 0.8782770038 0.8920208812 0.8782770038 + 0.8787937164 0.8924893737 0.8787937164 + 0.8793097734 0.8929569721 0.8793097734 + 0.8798230886 0.8934193254 0.8798230886 + 0.8803362846 0.8938816190 0.8803362846 + 0.8808495998 0.8943439126 0.8808495998 + 0.8813629150 0.8948062062 0.8813629150 + 0.8818761110 0.8952684999 0.8818761110 + 0.8823893070 0.8957306147 0.8823893070 + 0.8828998208 0.8961877823 0.8828998208 + 0.8834103942 0.8966450095 0.8834103942 + 0.8839209080 0.8971021771 0.8839209080 + 0.8844314218 0.8975594044 0.8844314218 + 0.8849418759 0.8980165720 0.8849418759 + 0.8854525089 0.8984737992 0.8854525089 + 0.8859602213 0.8989266157 0.8859602213 + 0.8864675760 0.8993787766 0.8864675760 + 0.8869749904 0.8998309970 0.8869749904 + 0.8874824047 0.9002832174 0.8874824047 + 0.8879898190 0.9007353783 0.8879898190 + 0.8884971142 0.9011875987 0.8884971142 + 0.8890014291 0.9016364217 0.8890014291 + 0.8895040751 0.9020836949 0.8895040751 + 0.8900067806 0.9025309086 0.8900067806 + 0.8905096054 0.9029781222 0.8905096054 + 0.8910123110 0.9034253955 0.8910123110 + 0.8915150166 0.9038726091 0.8915150166 + 0.8920161128 0.9043182135 0.8920161128 + 0.8925150037 0.9047616124 0.8925150037 + 0.8930137753 0.9052050114 0.8930137753 + 0.8935126066 0.9056484103 0.8935126066 + 0.8940114975 0.9060918093 0.8940114975 + 0.8945103288 0.9065353274 0.8945103288 + 0.8950086832 0.9069780707 0.8950086832 + 0.8955042958 0.9074168801 0.8955042958 + 0.8959999084 0.9078556895 0.8959999084 + 0.8964955211 0.9082944989 0.8964955211 + 0.8969910741 0.9087331891 0.8969910741 + 0.8974866271 0.9091719985 0.8974866271 + 0.8979821801 0.9096108079 0.8979821801 + 0.8984758854 0.9100461006 0.8984758854 + 0.8989689946 0.9104802012 0.8989689946 + 0.8994619846 0.9109144211 0.8994619846 + 0.8999550939 0.9113485217 0.8999550939 + 0.9004480839 0.9117826819 0.9004480839 + 0.9009411931 0.9122167826 0.9009411931 + 0.9014332891 0.9126496911 0.9014332891 + 0.9019234180 0.9130802751 0.9019234180 + 0.9024136066 0.9135109186 0.9024136066 + 0.9029036760 0.9139415026 0.9029036760 + 0.9033939242 0.9143720865 0.9033939242 + 0.9038839936 0.9148026705 0.9038839936 + 0.9043741822 0.9152333140 0.9043741822 + 0.9048606157 0.9156600237 0.9048606157 + 0.9053465128 0.9160860777 0.9053465128 + 0.9058324099 0.9165123105 0.9058324099 + 0.9063184261 0.9169384241 0.9063184261 + 0.9068043232 0.9173644781 0.9068043232 + 0.9072902203 0.9177907109 0.9072902203 + 0.9077749252 0.9182155728 0.9077749252 + 0.9082573056 0.9186385274 0.9082573056 + 0.9087396860 0.9190613031 0.9087396860 + 0.9092221856 0.9194840789 0.9092221856 + 0.9097046256 0.9199069142 0.9097046256 + 0.9101871252 0.9203298092 0.9101871252 + 0.9106695056 0.9207525849 0.9106695056 + 0.9111497998 0.9211729765 0.9111497998 + 0.9116293788 0.9215927124 0.9116293788 + 0.9121090770 0.9220123887 0.9121090770 + 0.9125887156 0.9224321246 0.9125887156 + 0.9130684137 0.9228518009 0.9130684137 + 0.9135479927 0.9232714772 0.9135479927 + 0.9140272141 0.9236903787 0.9140272141 + 0.9145038724 0.9241051078 0.9145038724 + 0.9149804711 0.9245197177 0.9149804711 + 0.9154571891 0.9249343276 0.9154571891 + 0.9159337878 0.9253488779 0.9159337878 + 0.9164105058 0.9257636070 0.9164105058 + 0.9168871045 0.9261782169 0.9168871045 + 0.9173616767 0.9265909791 0.9173616767 + 0.9178339839 0.9270015955 0.9178339839 + 0.9183062911 0.9274122715 0.9183062911 + 0.9187785983 0.9278230071 0.9187785983 + 0.9192509055 0.9282336831 0.9192509055 + 0.9197230935 0.9286444187 0.9197230935 + 0.9201954007 0.9290549755 0.9201954007 + 0.9206650853 0.9294636846 0.9206650853 + 0.9211338162 0.9298716784 0.9211338162 + 0.9216024876 0.9302796125 0.9216024876 + 0.9220712185 0.9306876063 0.9220712185 + 0.9225397706 0.9310954809 0.9225397706 + 0.9230085015 0.9315034151 0.9230085015 + 0.9234771729 0.9319114089 0.9234771729 + 0.9239432812 0.9323160052 0.9239432812 + 0.9244090915 0.9327204227 0.9244090915 + 0.9248750210 0.9331247211 0.9248750210 + 0.9253407717 0.9335290790 0.9253407717 + 0.9258067012 0.9339333773 0.9258067012 + 0.9262725115 0.9343377948 0.9262725115 + 0.9267380834 0.9347419143 0.9267380834 + 0.9272007942 0.9351428747 0.9272007942 + 0.9276636243 0.9355438948 0.9276636243 + 0.9281262755 0.9359449744 0.9281262755 + 0.9285889864 0.9363459945 0.9285889864 + 0.9290516973 0.9367470145 0.9290516973 + 0.9295145273 0.9371480942 0.9295145273 + 0.9299765825 0.9375485778 0.9299765825 + 0.9304360151 0.9379463792 0.9304360151 + 0.9308953881 0.9383442998 0.9308953881 + 0.9313548207 0.9387422204 0.9313548207 + 0.9318141937 0.9391400814 0.9318141937 + 0.9322736263 0.9395378828 0.9322736263 + 0.9327328801 0.9399358034 0.9327328801 + 0.9331911206 0.9403327703 0.9331911206 + 0.9336444736 0.9407266974 0.9336444736 + 0.9340978861 0.9411206245 0.9340978861 + 0.9345511794 0.9415144920 0.9345511794 + 0.9350045919 0.9419082999 0.9350045919 + 0.9354580045 0.9423022270 0.9354580045 + 0.9359112978 0.9426960945 0.9359112978 + 0.9363633990 0.9430891275 0.9363633990 + 0.9368094206 0.9434779882 0.9368094206 + 0.9372553825 0.9438670278 0.9372553825 + 0.9377014041 0.9442558885 0.9377014041 + 0.9381474853 0.9446449280 0.9381474853 + 0.9385935068 0.9450337887 0.9385935068 + 0.9390395284 0.9454228282 0.9390395284 + 0.9394848943 0.9458109736 0.9394848943 + 0.9399245977 0.9461929798 0.9399245977 + 0.9403643012 0.9465749264 0.9403643012 + 0.9408038855 0.9469568729 0.9408038855 + 0.9412435889 0.9473388195 0.9412435889 + 0.9416832924 0.9477208257 0.9416832924 + 0.9421229959 0.9481027126 0.9421229959 + 0.9425626993 0.9484847188 0.9425626993 + 0.9429975748 0.9488611221 0.9429975748 + 0.9434322119 0.9492372274 0.9434322119 + 0.9438669086 0.9496132731 0.9438669086 + 0.9443014860 0.9499893785 0.9443014860 + 0.9447361827 0.9503654838 0.9447361827 + 0.9451708198 0.9507415891 0.9451708198 + 0.9456055164 0.9511176944 0.9456055164 + 0.9460369945 0.9514914751 0.9460369945 + 0.9464673996 0.9518644810 0.9464673996 + 0.9468979239 0.9522374272 0.9468979239 + 0.9473283887 0.9526103735 0.9473283887 + 0.9477587938 0.9529833794 0.9477587938 + 0.9481893182 0.9533563852 0.9481893182 + 0.9486197233 0.9537293911 0.9486197233 + 0.9490481019 0.9541009068 0.9490481019 + 0.9494742751 0.9544708729 0.9494742751 + 0.9499005079 0.9548410177 0.9499005079 + 0.9503266811 0.9552109838 0.9503266811 + 0.9507529140 0.9555810094 0.9507529140 + 0.9511790872 0.9559510946 0.9511790872 + 0.9516053200 0.9563211203 0.9516053200 + 0.9520307779 0.9566904902 0.9520307779 + 0.9524527192 0.9570568800 0.9524527192 + 0.9528746009 0.9574233890 0.9528746009 + 0.9532964826 0.9577897787 0.9532964826 + 0.9537184238 0.9581562877 0.9537184238 + 0.9541404247 0.9585226774 0.9541404247 + 0.9545623064 0.9588891268 0.9545623064 + 0.9549841881 0.9592555761 0.9549841881 + 0.9554026127 0.9596186876 0.9554026127 + 0.9558200836 0.9599809051 0.9558200836 + 0.9562376142 0.9603431821 0.9562376142 + 0.9566550255 0.9607055187 0.9566550255 + 0.9570724964 0.9610676765 0.9570724964 + 0.9574900270 0.9614300132 0.9574900270 + 0.9579074979 0.9617921710 0.9579074979 + 0.9583234191 0.9621530771 0.9583234191 + 0.9587361217 0.9625114202 0.9587361217 + 0.9591488838 0.9628697038 0.9591488838 + 0.9595617056 0.9632279873 0.9595617056 + 0.9599744081 0.9635863900 0.9599744081 + 0.9603871703 0.9639446735 0.9603871703 + 0.9607999921 0.9643030167 0.9607999921 + 0.9612128139 0.9646613002 0.9612128139 + 0.9616206884 0.9650158882 0.9616206884 + 0.9620277286 0.9653698802 0.9620277286 + 0.9624347091 0.9657238126 0.9624347091 + 0.9628416896 0.9660778046 0.9628416896 + 0.9632487297 0.9664316773 0.9632487297 + 0.9636557102 0.9667857289 0.9636557102 + 0.9640626907 0.9671396017 0.9640626907 + 0.9644678831 0.9674922824 0.9644678831 + 0.9648684859 0.9678416252 0.9648684859 + 0.9652690291 0.9681910276 0.9652690291 + 0.9656695127 0.9685403109 0.9656695127 + 0.9660701156 0.9688897133 0.9660701156 + 0.9664705992 0.9692389965 0.9664705992 + 0.9668712020 0.9695882797 0.9668712020 + 0.9672716856 0.9699376822 0.9672716856 + 0.9676678777 0.9702842832 0.9676678777 + 0.9680616856 0.9706295133 0.9680616856 + 0.9684556127 0.9709746242 0.9684556127 + 0.9688494205 0.9713197947 0.9688494205 + 0.9692432284 0.9716649055 0.9692432284 + 0.9696370959 0.9720100760 0.9696370959 + 0.9700309038 0.9723551869 0.9700309038 + 0.9704247713 0.9727004170 0.9704247713 + 0.9708117247 0.9730417132 0.9708117247 + 0.9711983204 0.9733828902 0.9711983204 + 0.9715849161 0.9737240076 0.9715849161 + 0.9719715118 0.9740651846 0.9719715118 + 0.9723581076 0.9744063020 0.9723581076 + 0.9727448225 0.9747474790 0.9727448225 + 0.9731314182 0.9750885963 0.9731314182 + 0.9735164046 0.9754288793 0.9735164046 + 0.9738947749 0.9757658243 0.9738947749 + 0.9742732048 0.9761027098 0.9742732048 + 0.9746515751 0.9764394760 0.9746515751 + 0.9750298858 0.9767764211 0.9750298858 + 0.9754083157 0.9771133065 0.9754083157 + 0.9757866859 0.9774501920 0.9757866859 + 0.9761651158 0.9777870178 0.9761651158 + 0.9765400887 0.9781219959 0.9765400887 + 0.9769093990 0.9784539938 0.9769093990 + 0.9772787094 0.9787858725 0.9772787094 + 0.9776480198 0.9791178107 0.9776480198 + 0.9780173898 0.9794496894 0.9780173898 + 0.9783867002 0.9797816873 0.9783867002 + 0.9787560105 0.9801136255 0.9787560105 + 0.9791253209 0.9804455042 0.9791253209 + 0.9794902205 0.9807748199 0.9794902205 + 0.9798504114 0.9811015129 0.9798504114 + 0.9802107215 0.9814282060 0.9802107215 + 0.9805709124 0.9817547798 0.9805709124 + 0.9809311032 0.9820814729 0.9809311032 + 0.9812914133 0.9824081063 0.9812914133 + 0.9816516042 0.9827347994 0.9816516042 + 0.9820119143 0.9830613732 0.9820119143 + 0.9823670983 0.9833847284 0.9823670983 + 0.9827178717 0.9837049842 0.9827178717 + 0.9830688238 0.9840254188 0.9830688238 + 0.9834197164 0.9843456745 0.9834197164 + 0.9837704897 0.9846661091 0.9837704897 + 0.9841213822 0.9849864244 0.9841213822 + 0.9844722748 0.9853066802 0.9844722748 + 0.9848231077 0.9856271148 0.9848231077 + 0.9851688147 0.9859436154 0.9851688147 + 0.9855098128 0.9862567186 0.9855098128 + 0.9858506918 0.9865697026 0.9858506918 + 0.9861915708 0.9868828058 0.9861915708 + 0.9865326285 0.9871957898 0.9865326285 + 0.9868735075 0.9875088930 0.9868735075 + 0.9872145057 0.9878218770 0.9872145057 + 0.9875553846 0.9881349802 0.9875553846 + 0.9878913760 0.9884446859 0.9878913760 + 0.9882211089 0.9887502193 0.9882211089 + 0.9885507226 0.9890555739 0.9885507226 + 0.9888803959 0.9893611073 0.9888803959 + 0.9892101288 0.9896665215 0.9892101288 + 0.9895396829 0.9899719954 0.9895396829 + 0.9898694158 0.9902774096 0.9898694158 + 0.9901990294 0.9905828834 0.9901990294 + 0.9905248284 0.9908854961 0.9905248284 + 0.9908407927 0.9911810160 0.9908407927 + 0.9911568165 0.9914764166 0.9911568165 + 0.9914727807 0.9917718768 0.9914727807 + 0.9917888045 0.9920672774 0.9917888045 + 0.9921048284 0.9923627973 0.9921048284 + 0.9924207926 0.9926583171 0.9924207926 + 0.9927368164 0.9929537177 0.9927368164 + 0.9930515885 0.9932484031 0.9930515885 + 0.9933490753 0.9935321808 0.9933490753 + 0.9936466813 0.9938160181 0.9936466813 + 0.9939442873 0.9940996766 0.9939442873 + 0.9942418933 0.9943835139 0.9942418933 + 0.9945394993 0.9946672916 0.9945394993 + 0.9948371053 0.9949511290 0.9948371053 + 0.9951347113 0.9952347875 0.9951347113 + 0.9954321980 0.9955186248 0.9954321980 + 0.9957144260 0.9957929850 0.9957144260 + 0.9959921837 0.9960647821 0.9959921837 + 0.9962701201 0.9963365793 0.9962701201 + 0.9965478778 0.9966083765 0.9965478778 + 0.9968256950 0.9968801737 0.9968256950 + 0.9971035719 0.9971519709 0.9971035719 + 0.9973813891 0.9974238276 0.9973813891 + 0.9976593256 0.9976956248 0.9976593256 + 0.9979289770 0.9979603291 0.9979289770 + 0.9981878996 0.9982151985 0.9981878996 + 0.9984468222 0.9984701872 0.9984468222 + 0.9987056255 0.9987251759 0.9987056255 + 0.9989644885 0.9989801049 0.9989644885 + 0.9992234111 0.9992350936 0.9992234111 + 0.9994822741 0.9994900823 0.9994822741 + 0.9997410774 0.9997450113 0.9997410774 + 1.0000000000 1.0000000000 1.0000000000 +} diff --git a/rpplugins/color_correction/resources/film_luts_raw/agfa_agfacolor_hdc_200_plus.spi1d b/rpplugins/color_correction/resources/film_luts_raw/agfa_agfacolor_hdc_200_plus.spi1d new file mode 100644 index 0000000..66e4d7e --- /dev/null +++ b/rpplugins/color_correction/resources/film_luts_raw/agfa_agfacolor_hdc_200_plus.spi1d @@ -0,0 +1,1030 @@ +Version 1 +From 0.0 1.0 +Length 1024 +Components 3 +{ + 0.0000000000 0.0000000000 0.0000000000 + 0.0127044199 0.0141023202 0.0096477531 + 0.0238081105 0.0259745792 0.0176070407 + 0.0334607586 0.0364749506 0.0246724300 + 0.0421523489 0.0458938591 0.0311751105 + 0.0501546115 0.0544666387 0.0372429788 + 0.0576152317 0.0623432994 0.0429810397 + 0.0646389574 0.0696527734 0.0484409109 + 0.0713031068 0.0764547214 0.0536791012 + 0.0776453391 0.0828472674 0.0587162301 + 0.0837018490 0.0889110714 0.0635792091 + 0.0895045772 0.0946782306 0.0683003217 + 0.0950731933 0.1001901999 0.0728791431 + 0.1004388034 0.1054987013 0.0773395300 + 0.1056184024 0.1106514037 0.0816663206 + 0.1106417999 0.1156636998 0.0858941898 + 0.1155219972 0.1205495000 0.0900247619 + 0.1202521995 0.1252955049 0.0940808207 + 0.1248437986 0.1299131066 0.0980586410 + 0.1292977929 0.1344144046 0.1019453034 + 0.1336303949 0.1388116032 0.1057268977 + 0.1378560066 0.1431176960 0.1094207019 + 0.1419790983 0.1473421007 0.1130444035 + 0.1460126042 0.1514800042 0.1166006997 + 0.1499602944 0.1555261016 0.1200909987 + 0.1538154036 0.1594948024 0.1235229000 + 0.1575873941 0.1633805931 0.1269004941 + 0.1612810045 0.1671908945 0.1302188039 + 0.1648989022 0.1709319055 0.1334829926 + 0.1684425026 0.1746093035 0.1366928071 + 0.1719215959 0.1782346964 0.1398548931 + 0.1753377020 0.1818004996 0.1429744959 + 0.1787009984 0.1853079051 0.1460445970 + 0.1820088029 0.1887629032 0.1490730941 + 0.1852703989 0.1921591014 0.1520525962 + 0.1884782016 0.1955104023 0.1549959034 + 0.1916348040 0.1988154948 0.1578975022 + 0.1947418004 0.2020708025 0.1607636064 + 0.1978072971 0.2052816004 0.1635923982 + 0.2008365989 0.2084514052 0.1663880944 + 0.2038186044 0.2115817070 0.1691492051 + 0.2067597061 0.2146739066 0.1718768030 + 0.2096651047 0.2177291960 0.1745762974 + 0.2125398964 0.2207520008 0.1772498935 + 0.2153764963 0.2237412930 0.1798918992 + 0.2181748003 0.2266951948 0.1825038940 + 0.2209406942 0.2296195030 0.1850908995 + 0.2236783057 0.2325070053 0.1876516938 + 0.2263896018 0.2353623956 0.1901890934 + 0.2290693074 0.2381868958 0.1927060932 + 0.2317135036 0.2409814000 0.1951995045 + 0.2343312949 0.2437489927 0.1976688951 + 0.2369202971 0.2464884967 0.2001180947 + 0.2394883931 0.2492032051 0.2025482059 + 0.2420337945 0.2518971860 0.2049552947 + 0.2445555031 0.2545694113 0.2073439062 + 0.2470511049 0.2572140098 0.2097100019 + 0.2495238036 0.2598383129 0.2120579928 + 0.2519746125 0.2624385953 0.2143891007 + 0.2544065118 0.2650176883 0.2167063057 + 0.2568238080 0.2675766945 0.2190068066 + 0.2592222989 0.2701159120 0.2212958038 + 0.2615979910 0.2726357877 0.2235656977 + 0.2639487982 0.2751353979 0.2258211970 + 0.2662819922 0.2776151896 0.2280610055 + 0.2685964108 0.2800753117 0.2302847058 + 0.2708936930 0.2825163007 0.2324967980 + 0.2731778920 0.2849400938 0.2346933931 + 0.2754473984 0.2873477042 0.2368790060 + 0.2776994109 0.2897374034 0.2390515059 + 0.2799314857 0.2921099067 0.2412095070 + 0.2821440101 0.2944638133 0.2433556020 + 0.2843374014 0.2968018055 0.2454877943 + 0.2865155935 0.2991257012 0.2476056069 + 0.2886820138 0.3014312983 0.2497113049 + 0.2908358872 0.3037211895 0.2518028915 + 0.2929798961 0.3059999049 0.2538796961 + 0.2951102853 0.3082641065 0.2559436858 + 0.2972272933 0.3105159104 0.2579965889 + 0.2993307114 0.3127523959 0.2600373030 + 0.3014214933 0.3149785101 0.2620668113 + 0.3034971058 0.3171896935 0.2640840113 + 0.3055574000 0.3193879128 0.2660909891 + 0.3076024950 0.3215714097 0.2680850029 + 0.3096376061 0.3237439990 0.2700704932 + 0.3116613030 0.3259027898 0.2720479965 + 0.3136739135 0.3280479014 0.2740156054 + 0.3156760931 0.3301830888 0.2759723961 + 0.3176679015 0.3323085010 0.2779215872 + 0.3196499944 0.3344236016 0.2798638940 + 0.3216224015 0.3365249038 0.2817943096 + 0.3235847950 0.3386119902 0.2837162018 + 0.3255361021 0.3406879008 0.2856321931 + 0.3274742067 0.3427498937 0.2875392139 + 0.3294023871 0.3448010087 0.2894361913 + 0.3313204050 0.3468416929 0.2913256884 + 0.3332281113 0.3488731086 0.2932091951 + 0.3351263106 0.3508965969 0.2950840890 + 0.3370158076 0.3529112935 0.2969497144 + 0.3388954103 0.3549158871 0.2988080978 + 0.3407635093 0.3569113910 0.3006610870 + 0.3426195979 0.3588970900 0.3025059998 + 0.3444670141 0.3608722985 0.3043417931 + 0.3463074863 0.3628363907 0.3061706126 + 0.3481400907 0.3647880852 0.3079940081 + 0.3499644995 0.3667264879 0.3098114133 + 0.3517807126 0.3686558902 0.3116197884 + 0.3535911143 0.3705761135 0.3134202063 + 0.3553932011 0.3724865019 0.3152152002 + 0.3571878970 0.3743883967 0.3170050979 + 0.3589738011 0.3762854040 0.3187876940 + 0.3607504964 0.3781766891 0.3205623031 + 0.3625178039 0.3800612986 0.3223307133 + 0.3642742932 0.3819381893 0.3240945041 + 0.3660207987 0.3838064969 0.3258526027 + 0.3677580953 0.3856652975 0.3276030123 + 0.3694871962 0.3875137866 0.3293435872 + 0.3712058961 0.3893510997 0.3310768008 + 0.3729172051 0.3911783993 0.3328061104 + 0.3746241927 0.3929969072 0.3345299065 + 0.3763248026 0.3948045075 0.3362461030 + 0.3780199885 0.3966018856 0.3379529119 + 0.3797098100 0.3983893096 0.3396534920 + 0.3813967109 0.4001693130 0.3413507938 + 0.3830771148 0.4019418955 0.3430429995 + 0.3847537041 0.4037080109 0.3447282910 + 0.3864229918 0.4054659009 0.3464050889 + 0.3880873919 0.4072161019 0.3480730057 + 0.3897438943 0.4089570045 0.3497362137 + 0.3913944960 0.4106892049 0.3513950109 + 0.3930368125 0.4124135971 0.3530482054 + 0.3946720064 0.4141317010 0.3546941876 + 0.3962987065 0.4158441126 0.3563325107 + 0.3979170918 0.4175505042 0.3579638004 + 0.3995271027 0.4192501009 0.3595893085 + 0.4011279941 0.4209432900 0.3612098098 + 0.4027225077 0.4226306081 0.3628252149 + 0.4043093026 0.4243136942 0.3644339144 + 0.4058884978 0.4259892106 0.3660350144 + 0.4074592888 0.4276596904 0.3676308095 + 0.4090228081 0.4293231964 0.3692201078 + 0.4105781019 0.4309802949 0.3708019853 + 0.4121260941 0.4326306880 0.3723767102 + 0.4136680067 0.4342732131 0.3739450872 + 0.4152038097 0.4359092116 0.3755083978 + 0.4167321920 0.4375346899 0.3770667017 + 0.4182567894 0.4391531050 0.3786197007 + 0.4197764993 0.4407626987 0.3801665008 + 0.4212917984 0.4423646033 0.3817074895 + 0.4228025973 0.4439603090 0.3832431138 + 0.4243074954 0.4455477893 0.3847720027 + 0.4258069098 0.4471279085 0.3862960041 + 0.4273006022 0.4487006068 0.3878161013 + 0.4287903011 0.4502668977 0.3893316984 + 0.4302769899 0.4518280029 0.3908422887 + 0.4317578077 0.4533826113 0.3923459053 + 0.4332346916 0.4549309909 0.3938423991 + 0.4347065091 0.4564737976 0.3953357935 + 0.4361734092 0.4580112100 0.3968257904 + 0.4376364946 0.4595425129 0.3983112872 + 0.4390909076 0.4610661864 0.3997904956 + 0.4405421913 0.4625841975 0.4012655020 + 0.4419898093 0.4640966058 0.4027357101 + 0.4434331954 0.4656026065 0.4042006135 + 0.4448713958 0.4671005905 0.4056580067 + 0.4463051856 0.4685927927 0.4071114957 + 0.4477353096 0.4700792134 0.4085614085 + 0.4491625130 0.4715583026 0.4100078046 + 0.4505859017 0.4730297029 0.4114479125 + 0.4520066977 0.4744954109 0.4128834903 + 0.4534246922 0.4759553075 0.4143148959 + 0.4548385143 0.4774056971 0.4157409966 + 0.4562489986 0.4788500965 0.4171645045 + 0.4576565921 0.4802890122 0.4185852110 + 0.4590603113 0.4817211926 0.4200018048 + 0.4604597092 0.4831478894 0.4214130044 + 0.4618560970 0.4845702946 0.4228211045 + 0.4632489979 0.4859867096 0.4242258966 + 0.4646365941 0.4873968959 0.4256238043 + 0.4660210013 0.4888026118 0.4270183146 + 0.4674021006 0.4902028143 0.4284090996 + 0.4687772095 0.4915963113 0.4297944009 + 0.4701490998 0.4929861128 0.4311766922 + 0.4715175033 0.4943715930 0.4325557947 + 0.4728797078 0.4957531989 0.4339298010 + 0.4742386043 0.4971317947 0.4353007078 + 0.4755935073 0.4985060096 0.4366675913 + 0.4769422114 0.4998764992 0.4380275011 + 0.4782876074 0.5012443066 0.4393840134 + 0.4796282947 0.5026069880 0.4407353997 + 0.4809632003 0.5039666891 0.4420841932 + 0.4822948873 0.5053241849 0.4434312880 + 0.4836206138 0.5066757202 0.4447737932 + 0.4849415123 0.5080248713 0.4461131096 + 0.4862594008 0.5093721151 0.4474501014 + 0.4875693917 0.5107128024 0.4487794936 + 0.4888761938 0.5120517015 0.4501057863 + 0.4901781976 0.5133879185 0.4514274895 + 0.4914737940 0.5147191286 0.4527435899 + 0.4927662909 0.5160481930 0.4540570974 + 0.4940516949 0.5173733234 0.4553644061 + 0.4953328967 0.5186954737 0.4566692114 + 0.4966096878 0.5200139880 0.4579710960 + 0.4978792965 0.5213292241 0.4592679143 + 0.4991464019 0.5226427913 0.4605629146 + 0.5004069805 0.5239503980 0.4618535936 + 0.5016648769 0.5252562761 0.4631414115 + 0.5029193163 0.5265597105 0.4644250870 + 0.5041680932 0.5278586149 0.4657050073 + 0.5054149032 0.5291553736 0.4669832885 + 0.5066552162 0.5304455757 0.4682553113 + 0.5078933835 0.5317338109 0.4695254862 + 0.5091258883 0.5330157876 0.4707902074 + 0.5103549957 0.5342947245 0.4720515907 + 0.5115808845 0.5355700254 0.4733094871 + 0.5128020048 0.5368400216 0.4745627046 + 0.5140215755 0.5381075740 0.4758141935 + 0.5152375102 0.5393667817 0.4770599008 + 0.5164520741 0.5406240225 0.4783042073 + 0.5176615715 0.5418733954 0.4795426130 + 0.5188698173 0.5431200266 0.4807788134 + 0.5200755000 0.5443605781 0.4820106924 + 0.5212779045 0.5455970168 0.4832395017 + 0.5224775076 0.5468291044 0.4844653010 + 0.5236744285 0.5480558872 0.4856874049 + 0.5248702168 0.5492796898 0.4869076908 + 0.5260608196 0.5504972935 0.4881236851 + 0.5272505283 0.5517131090 0.4893389046 + 0.5284340978 0.5529218912 0.4905493855 + 0.5296168923 0.5541298985 0.4917592108 + 0.5307930112 0.5553305745 0.4929626882 + 0.5319678783 0.5565304160 0.4941650927 + 0.5331379771 0.5577239990 0.4953621030 + 0.5343062282 0.5589160919 0.4965574145 + 0.5354691148 0.5601027012 0.4977473915 + 0.5366293192 0.5612874031 0.4989356101 + 0.5377836823 0.5624672771 0.5001201034 + 0.5389350057 0.5636451840 0.5013015866 + 0.5400810838 0.5648186207 0.5024777055 + 0.5412240028 0.5659899116 0.5036516190 + 0.5423620939 0.5671570897 0.5048221946 + 0.5434969068 0.5683212280 0.5059906840 + 0.5446271896 0.5694798827 0.5071563125 + 0.5457543135 0.5706359148 0.5083196163 + 0.5468770862 0.5717874765 0.5094795227 + 0.5479968786 0.5729361773 0.5106369257 + 0.5491123796 0.5740798712 0.5117905140 + 0.5502251983 0.5752214193 0.5129418969 + 0.5513336062 0.5763586164 0.5140898228 + 0.5524396896 0.5774930120 0.5152366757 + 0.5535413027 0.5786203146 0.5163816810 + 0.5546411872 0.5797460079 0.5175253153 + 0.5557361841 0.5808660984 0.5186645985 + 0.5568301082 0.5819849968 0.5198031068 + 0.5579187274 0.5830960274 0.5209382176 + 0.5590069294 0.5842068791 0.5220727921 + 0.5600894094 0.5853117108 0.5232008100 + 0.5611718893 0.5864164233 0.5243288279 + 0.5622487068 0.5875138044 0.5254526734 + 0.5633254051 0.5886104107 0.5265762806 + 0.5643972754 0.5897029042 0.5276951194 + 0.5654681921 0.5907940269 0.5288128257 + 0.5665354133 0.5918807983 0.5299268961 + 0.5676007867 0.5929647088 0.5310389996 + 0.5686635971 0.5940455198 0.5321475863 + 0.5697237849 0.5951223969 0.5332525969 + 0.5707824230 0.5961973071 0.5343558788 + 0.5718374848 0.5972664952 0.5354554057 + 0.5728921294 0.5983355045 0.5365543962 + 0.5739423037 0.5993986130 0.5376480818 + 0.5749924779 0.6004617214 0.5387417078 + 0.5760387182 0.6015192866 0.5398297906 + 0.5770841837 0.6025757790 0.5409170985 + 0.5781269073 0.6036278009 0.5420001149 + 0.5791680217 0.6046767235 0.5430803895 + 0.5802066922 0.6057233810 0.5441582203 + 0.5812410712 0.6067652106 0.5452312827 + 0.5822750926 0.6078069210 0.5463038087 + 0.5833042264 0.6088423729 0.5473703146 + 0.5843334198 0.6098778844 0.5484367013 + 0.5853577852 0.6109092832 0.5494986176 + 0.5863807797 0.6119390130 0.5505589843 + 0.5874018073 0.6129667163 0.5516161919 + 0.5884202123 0.6139913201 0.5526692271 + 0.5894376040 0.6150155067 0.5537214875 + 0.5904482007 0.6160331964 0.5547677279 + 0.5914587975 0.6170510054 0.5558139086 + 0.5924654007 0.6180649996 0.5568549037 + 0.5934706926 0.6190776229 0.5578941703 + 0.5944733024 0.6200882196 0.5589315295 + 0.5954716206 0.6210951805 0.5599654913 + 0.5964698195 0.6221022010 0.5609995127 + 0.5974636078 0.6231055260 0.5620262027 + 0.5984573960 0.6241086125 0.5630527139 + 0.5994476080 0.6251075268 0.5640758872 + 0.6004350781 0.6261023879 0.5650966167 + 0.6014220715 0.6270968914 0.5661162734 + 0.6024059057 0.6280854940 0.5671287775 + 0.6033896208 0.6290740967 0.5681412816 + 0.6043697000 0.6300585866 0.5691496134 + 0.6053478718 0.6310405731 0.5701557994 + 0.6063256264 0.6320214868 0.5711603165 + 0.6073008776 0.6329963207 0.5721578002 + 0.6082761288 0.6339710951 0.5731552839 + 0.6092479825 0.6349408031 0.5741487741 + 0.6102185249 0.6359075904 0.5751404166 + 0.6111885905 0.6368734837 0.5761309266 + 0.6121569276 0.6378319860 0.5771154761 + 0.6131250858 0.6387906075 0.5781000853 + 0.6140908003 0.6397454143 0.5790807009 + 0.6150550246 0.6406973004 0.5800589919 + 0.6160188913 0.6416491270 0.5810368061 + 0.6169794202 0.6425917149 0.5820075274 + 0.6179398894 0.6435343027 0.5829781890 + 0.6188982129 0.6444740891 0.5839462876 + 0.6198542714 0.6454101801 0.5849115252 + 0.6208103895 0.6463462710 0.5858767033 + 0.6217638850 0.6472759247 0.5868369937 + 0.6227170825 0.6482042074 0.5877965093 + 0.6236690283 0.6491310000 0.5887547135 + 0.6246173978 0.6500520706 0.5897085071 + 0.6255657077 0.6509732008 0.5906623006 + 0.6265100241 0.6518902183 0.5916125774 + 0.6274515986 0.6528037786 0.5925605297 + 0.6283932924 0.6537175179 0.5935084224 + 0.6293299794 0.6546260715 0.5944507122 + 0.6302664876 0.6555340886 0.5953925848 + 0.6312015057 0.6564409733 0.5963330865 + 0.6321321726 0.6573432088 0.5972688794 + 0.6330627799 0.6582453847 0.5982046127 + 0.6339905262 0.6591445804 0.5991371274 + 0.6349157095 0.6600404978 0.6000667214 + 0.6358407736 0.6609362960 0.6009961963 + 0.6367601752 0.6618282199 0.6019207239 + 0.6376782060 0.6627187133 0.6028438210 + 0.6385959983 0.6636092067 0.6037667990 + 0.6395090818 0.6644952893 0.6046833992 + 0.6404222250 0.6653813124 0.6056001186 + 0.6413338184 0.6662659049 0.6065152884 + 0.6422404051 0.6671448946 0.6074264050 + 0.6431471109 0.6680238843 0.6083375216 + 0.6440510750 0.6689003706 0.6092464924 + 0.6449515224 0.6697732806 0.6101529002 + 0.6458520293 0.6706461906 0.6110591888 + 0.6467483044 0.6715160012 0.6119620800 + 0.6476420164 0.6723836064 0.6128628254 + 0.6485357285 0.6732510924 0.6137633920 + 0.6494253278 0.6741154790 0.6146603823 + 0.6503136158 0.6749786735 0.6155561805 + 0.6512019038 0.6758419275 0.6164519787 + 0.6520848870 0.6766991019 0.6173437238 + 0.6529672742 0.6775552034 0.6182348728 + 0.6538497210 0.6784113050 0.6191260815 + 0.6547253728 0.6792595983 0.6200146079 + 0.6556010842 0.6801074147 0.6209030151 + 0.6564763784 0.6809551120 0.6217911243 + 0.6573458910 0.6817964911 0.6226750016 + 0.6582155228 0.6826378107 0.6235588193 + 0.6590843201 0.6834787726 0.6244422793 + 0.6599482298 0.6843137145 0.6253234148 + 0.6608120799 0.6851487160 0.6262044907 + 0.6616752744 0.6859831810 0.6270849705 + 0.6625339985 0.6868135929 0.6279615164 + 0.6633927822 0.6876440048 0.6288381219 + 0.6642509103 0.6884738207 0.6297143102 + 0.6651049852 0.6892974973 0.6305881143 + 0.6659591794 0.6901211739 0.6314619184 + 0.6668125987 0.6909444928 0.6323351860 + 0.6676605940 0.6917623281 0.6332045794 + 0.6685085893 0.6925802231 0.6340739131 + 0.6693562865 0.6933978796 0.6349430084 + 0.6701996922 0.6942088008 0.6358096004 + 0.6710430980 0.6950196028 0.6366763115 + 0.6718865037 0.6958305240 0.6375429034 + 0.6727249026 0.6966357827 0.6384050846 + 0.6735633016 0.6974408031 0.6392672062 + 0.6744015813 0.6982458830 0.6401293874 + 0.6752368808 0.6990466118 0.6409891844 + 0.6760717034 0.6998466849 0.6418486238 + 0.6769065857 0.7006468177 0.6427081227 + 0.6777368188 0.7014424205 0.6435642242 + 0.6785656810 0.7022364736 0.6444191933 + 0.6793946028 0.7030305266 0.6452742815 + 0.6802213192 0.7038202882 0.6461277008 + 0.6810467839 0.7046071291 0.6469801068 + 0.6818721890 0.7053937912 0.6478325129 + 0.6826949716 0.7061775923 0.6486828923 + 0.6835147142 0.7069572210 0.6495308876 + 0.6843342781 0.7077367902 0.6503788829 + 0.6851524115 0.7085152864 0.6512262821 + 0.6859658957 0.7092896104 0.6520717144 + 0.6867793798 0.7100639939 0.6529170275 + 0.6875926852 0.7108383775 0.6537624002 + 0.6884006262 0.7116078138 0.6546034217 + 0.6892085075 0.7123771906 0.6554443836 + 0.6900163293 0.7131465077 0.6562854052 + 0.6908203959 0.7139121294 0.6571244001 + 0.6916232705 0.7146762013 0.6579627991 + 0.6924263239 0.7154402733 0.6588011980 + 0.6932265162 0.7162014246 0.6596375704 + 0.6940239072 0.7169584036 0.6604716778 + 0.6948214173 0.7177153230 0.6613057256 + 0.6956177950 0.7184715867 0.6621391177 + 0.6964092851 0.7192226052 0.6629688144 + 0.6972007751 0.7199735045 0.6637985706 + 0.6979923844 0.7207245231 0.6646283269 + 0.6987801790 0.7214716077 0.6654537916 + 0.6995673180 0.7222176194 0.6662783027 + 0.7003543973 0.7229636908 0.6671028733 + 0.7011383772 0.7237073183 0.6679254770 + 0.7019187808 0.7244477272 0.6687458754 + 0.7026991248 0.7251880765 0.6695662141 + 0.7034789920 0.7259283066 0.6703861952 + 0.7042531967 0.7266616821 0.6712015867 + 0.7050274014 0.7273951173 0.6720169187 + 0.7058014870 0.7281284928 0.6728321910 + 0.7065715194 0.7288578749 0.6736438274 + 0.7073392868 0.7295845747 0.6744530797 + 0.7081069946 0.7303113937 0.6752625108 + 0.7088738084 0.7310374975 0.6760708094 + 0.7096366882 0.7317596078 0.6768743992 + 0.7103996277 0.7324817777 0.6776779890 + 0.7111625075 0.7332040071 0.6784815192 + 0.7119218111 0.7339224219 0.6792811155 + 0.7126796246 0.7346392274 0.6800791025 + 0.7134374976 0.7353559136 0.6808769703 + 0.7141941786 0.7360715866 0.6816738248 + 0.7149465084 0.7367821932 0.6824663281 + 0.7156988978 0.7374927998 0.6832587719 + 0.7164512873 0.7382034063 0.6840512753 + 0.7172005773 0.7389100790 0.6848403215 + 0.7179483175 0.7396144867 0.6856274009 + 0.7186959982 0.7403188944 0.6864145994 + 0.7194433212 0.7410228848 0.6872013211 + 0.7201871276 0.7417224050 0.6879833937 + 0.7209308743 0.7424219251 0.6887655258 + 0.7216746807 0.7431213856 0.6895475984 + 0.7224153876 0.7438185811 0.6903271079 + 0.7231531739 0.7445130944 0.6911041737 + 0.7238910198 0.7452077270 0.6918814182 + 0.7246286869 0.7459022999 0.6926584840 + 0.7253618240 0.7465913296 0.6934313774 + 0.7260943055 0.7472792864 0.6942036748 + 0.7268267870 0.7479674220 0.6949760914 + 0.7275583148 0.7486543059 0.6957473755 + 0.7282862067 0.7493367791 0.6965150833 + 0.7290140986 0.7500193715 0.6972827911 + 0.7297419906 0.7507019043 0.6980504990 + 0.7304679155 0.7513812184 0.6988149285 + 0.7311919928 0.7520576119 0.6995764971 + 0.7319161296 0.7527340055 0.7003381252 + 0.7326402068 0.7534102798 0.7010996938 + 0.7333592772 0.7540827990 0.7018569708 + 0.7340772748 0.7547543049 0.7026134133 + 0.7347953916 0.7554258108 0.7033697963 + 0.7355127931 0.7560970187 0.7041258216 + 0.7362236977 0.7567629218 0.7048764825 + 0.7369347215 0.7574288845 0.7056272030 + 0.7376456261 0.7580947876 0.7063779235 + 0.7383548021 0.7587593198 0.7071272135 + 0.7390602827 0.7594197989 0.7078732252 + 0.7397658229 0.7600803971 0.7086191177 + 0.7404711843 0.7607408762 0.7093651295 + 0.7411739230 0.7613990903 0.7101075053 + 0.7418738008 0.7620543838 0.7108464241 + 0.7425737977 0.7627096772 0.7115852237 + 0.7432736754 0.7633650899 0.7123240829 + 0.7439711094 0.7640163898 0.7130596042 + 0.7446671128 0.7646651864 0.7137932181 + 0.7453631163 0.7653139830 0.7145268917 + 0.7460591197 0.7659627795 0.7152605057 + 0.7467520237 0.7666075230 0.7159891725 + 0.7474439740 0.7672507167 0.7167164087 + 0.7481361032 0.7678940296 0.7174435258 + 0.7488281131 0.7685372233 0.7181707025 + 0.7495164871 0.7691755295 0.7188938856 + 0.7502045035 0.7698127031 0.7196164727 + 0.7508924007 0.7704498768 0.7203391194 + 0.7515802979 0.7710872293 0.7210617065 + 0.7522624731 0.7717201710 0.7217788100 + 0.7529442906 0.7723528147 0.7224954963 + 0.7536261082 0.7729853988 0.7232123017 + 0.7543079853 0.7736179829 0.7239289880 + 0.7549846768 0.7742474079 0.7246403098 + 0.7556613088 0.7748765945 0.7253513932 + 0.7563378811 0.7755057812 0.7260624766 + 0.7570145726 0.7761349082 0.7267736197 + 0.7576869130 0.7767605186 0.7274788022 + 0.7583590746 0.7773857713 0.7281838059 + 0.7590312958 0.7780112028 0.7288888097 + 0.7597035170 0.7786365151 0.7295936942 + 0.7603724003 0.7792575955 0.7302941084 + 0.7610409856 0.7798781991 0.7309941053 + 0.7617095709 0.7804989219 0.7316941023 + 0.7623782754 0.7811195254 0.7323940992 + 0.7630437016 0.7817357779 0.7330893874 + 0.7637084723 0.7823513150 0.7337840199 + 0.7643734217 0.7829667926 0.7344784737 + 0.7650381923 0.7835822105 0.7351731062 + 0.7656989098 0.7841936946 0.7358644009 + 0.7663580775 0.7848036885 0.7365546227 + 0.7670173049 0.7854136229 0.7372447848 + 0.7676765919 0.7860234976 0.7379350066 + 0.7683327794 0.7866303921 0.7386223078 + 0.7689871788 0.7872350216 0.7393077016 + 0.7696415782 0.7878395915 0.7399932146 + 0.7702959776 0.7884442210 0.7406786084 + 0.7709481716 0.7890473008 0.7413616776 + 0.7715978026 0.7896479964 0.7420418262 + 0.7722473741 0.7902486920 0.7427219152 + 0.7728970051 0.7908495069 0.7434018850 + 0.7735458016 0.7914491296 0.7440809011 + 0.7741922736 0.7920445800 0.7447561026 + 0.7748388052 0.7926400900 0.7454311848 + 0.7754852772 0.7932356000 0.7461063862 + 0.7761318088 0.7938311100 0.7467815876 + 0.7767726183 0.7944201231 0.7474523187 + 0.7774134874 0.7950087786 0.7481228709 + 0.7780542970 0.7955976129 0.7487936020 + 0.7786952257 0.7961863875 0.7494642138 + 0.7793319225 0.7967715263 0.7501307726 + 0.7799670100 0.7973549962 0.7507957220 + 0.7806020975 0.7979385257 0.7514606714 + 0.7812373042 0.7985219955 0.7521256804 + 0.7818704247 0.7991034985 0.7527887821 + 0.7825008035 0.7996814251 0.7534492016 + 0.7831311226 0.8002592921 0.7541096807 + 0.7837613821 0.8008372784 0.7547701001 + 0.7843915224 0.8014150858 0.7554302812 + 0.7850180268 0.8019878864 0.7560858727 + 0.7856444120 0.8025606275 0.7567415237 + 0.7862709165 0.8031334281 0.7573971152 + 0.7868974209 0.8037062287 0.7580528259 + 0.7875211835 0.8042758703 0.7587059736 + 0.7881436944 0.8048439026 0.7593579888 + 0.7887662053 0.8054118752 0.7600100040 + 0.7893887758 0.8059799075 0.7606620193 + 0.7900099158 0.8065465093 0.7613126040 + 0.7906270027 0.8071078062 0.7619590163 + 0.7912439704 0.8076692224 0.7626054883 + 0.7918611169 0.8082305789 0.7632519007 + 0.7924780846 0.8087918758 0.7638983130 + 0.7930914164 0.8093485236 0.7645419240 + 0.7937036753 0.8099036813 0.7651848197 + 0.7943159938 0.8104587793 0.7658277154 + 0.7949283123 0.8110138774 0.7664706111 + 0.7955389023 0.8115677238 0.7671121955 + 0.7961457968 0.8121181130 0.7677505016 + 0.7967525721 0.8126683831 0.7683889270 + 0.7973595262 0.8132187128 0.7690272927 + 0.7979663014 0.8137689829 0.7696655989 + 0.7985696793 0.8143169284 0.7703021169 + 0.7991721034 0.8148639798 0.7709379196 + 0.7997745275 0.8154109716 0.7715737820 + 0.8003767729 0.8159580827 0.7722095847 + 0.8009781241 0.8165045977 0.7728447914 + 0.8015751839 0.8170487285 0.7734771967 + 0.8021721840 0.8175927997 0.7741094828 + 0.8027691841 0.8181368709 0.7747418880 + 0.8033663034 0.8186810017 0.7753742933 + 0.8039602041 0.8192222714 0.7760047913 + 0.8045521975 0.8197615743 0.7766340971 + 0.8051440716 0.8203008175 0.7772634029 + 0.8057360053 0.8208400011 0.7778927088 + 0.8063278794 0.8213791847 0.7785220146 + 0.8069158792 0.8219143748 0.7791473866 + 0.8075037003 0.8224493265 0.7797725201 + 0.8080914021 0.8229840994 0.7803977132 + 0.8086792231 0.8235189915 0.7810227871 + 0.8092660904 0.8240531087 0.7816470265 + 0.8098508120 0.8245849013 0.7822685838 + 0.8104354739 0.8251166940 0.7828900814 + 0.8110200763 0.8256484866 0.7835115790 + 0.8116047978 0.8261802793 0.7841330767 + 0.8121870160 0.8267101049 0.7847530246 + 0.8127670884 0.8272377849 0.7853714228 + 0.8133472204 0.8277655244 0.7859897017 + 0.8139272928 0.8282932043 0.7866080999 + 0.8145074248 0.8288208842 0.7872264981 + 0.8150827289 0.8293445706 0.7878416181 + 0.8156566024 0.8298670053 0.7884557247 + 0.8162304759 0.8303893805 0.7890698910 + 0.8168044090 0.8309118748 0.7896839976 + 0.8173784018 0.8314343095 0.7902982235 + 0.8179473281 0.8319529295 0.7909085751 + 0.8185161948 0.8324713707 0.7915189266 + 0.8190850019 0.8329898119 0.7921292186 + 0.8196539283 0.8335083127 0.7927395105 + 0.8202221990 0.8340262771 0.7933492064 + 0.8207868934 0.8345406055 0.7939547896 + 0.8213515878 0.8350549936 0.7945603132 + 0.8219162822 0.8355693817 0.7951657772 + 0.8224810958 0.8360837102 0.7957714200 + 0.8230450153 0.8365973234 0.7963758111 + 0.8236066103 0.8371080756 0.7969769835 + 0.8241683245 0.8376188278 0.7975782156 + 0.8247299194 0.8381295800 0.7981793284 + 0.8252915144 0.8386403918 0.7987805009 + 0.8258516192 0.8391501904 0.7993801832 + 0.8264086246 0.8396579027 0.7999768257 + 0.8269655704 0.8401656747 0.8005735278 + 0.8275225759 0.8406733871 0.8011701107 + 0.8280795813 0.8411810994 0.8017666936 + 0.8286346793 0.8416873217 0.8023620844 + 0.8291863799 0.8421903253 0.8029553890 + 0.8297381997 0.8426933289 0.8035488129 + 0.8302899003 0.8431962729 0.8041421175 + 0.8308416009 0.8436993957 0.8047354221 + 0.8313921094 0.8442009091 0.8053274155 + 0.8319404125 0.8446996808 0.8059173226 + 0.8324885964 0.8451983929 0.8065071106 + 0.8330368996 0.8456972241 0.8070968986 + 0.8335850835 0.8461958766 0.8076868057 + 0.8341315985 0.8466938734 0.8082754016 + 0.8346744180 0.8471899033 0.8088614941 + 0.8352171183 0.8476858735 0.8094475269 + 0.8357598186 0.8481817842 0.8100336194 + 0.8363025784 0.8486778140 0.8106197119 + 0.8368440270 0.8491731286 0.8112050295 + 0.8373814225 0.8496652842 0.8117879033 + 0.8379188180 0.8501574993 0.8123707771 + 0.8384562135 0.8506497741 0.8129537106 + 0.8389936090 0.8511419892 0.8135365844 + 0.8395305276 0.8516339064 0.8141192198 + 0.8400635719 0.8521212935 0.8146995902 + 0.8405966759 0.8526086807 0.8152799010 + 0.8411297798 0.8530961275 0.8158602118 + 0.8416628242 0.8535835147 0.8164405227 + 0.8421959281 0.8540710211 0.8170207739 + 0.8427261114 0.8545554280 0.8175972104 + 0.8432559967 0.8550394773 0.8181732893 + 0.8437858820 0.8555235863 0.8187493086 + 0.8443158269 0.8560076952 0.8193253875 + 0.8448457122 0.8564918041 0.8199014068 + 0.8453723192 0.8569735885 0.8204749227 + 0.8458976150 0.8574544191 0.8210471869 + 0.8464229107 0.8579350710 0.8216195703 + 0.8469482064 0.8584159017 0.8221920133 + 0.8474735022 0.8588966727 0.8227642775 + 0.8479961157 0.8593757749 0.8233352900 + 0.8485156298 0.8598529100 0.8239045143 + 0.8490350842 0.8603299856 0.8244736791 + 0.8495544791 0.8608071208 0.8250429034 + 0.8500739932 0.8612841964 0.8256121874 + 0.8505926728 0.8617607951 0.8261809945 + 0.8511074781 0.8622341752 0.8267477155 + 0.8516222239 0.8627076149 0.8273143172 + 0.8521370292 0.8631808758 0.8278809786 + 0.8526517749 0.8636543155 0.8284475803 + 0.8531665206 0.8641276956 0.8290143013 + 0.8536782861 0.8645980954 0.8295775056 + 0.8541892767 0.8650677204 0.8301398158 + 0.8547003865 0.8655372858 0.8307021856 + 0.8552113771 0.8660069108 0.8312644958 + 0.8557224274 0.8664764762 0.8318268061 + 0.8562318087 0.8669446111 0.8323876858 + 0.8567386866 0.8674101233 0.8329463005 + 0.8572456837 0.8678756952 0.8335049152 + 0.8577526808 0.8683413267 0.8340634704 + 0.8582596779 0.8688067794 0.8346220851 + 0.8587666154 0.8692724109 0.8351806998 + 0.8592697978 0.8697341084 0.8357362151 + 0.8597729206 0.8701955080 0.8362916708 + 0.8602761030 0.8706570268 0.8368471265 + 0.8607792258 0.8711184859 0.8374025822 + 0.8612822890 0.8715798855 0.8379580975 + 0.8617836833 0.8720393777 0.8385115266 + 0.8622832894 0.8724967837 0.8390629888 + 0.8627830148 0.8729540706 0.8396145105 + 0.8632826209 0.8734114170 0.8401659131 + 0.8637822270 0.8738687038 0.8407173753 + 0.8642818928 0.8743259907 0.8412687778 + 0.8647763133 0.8747799993 0.8418176770 + 0.8652706742 0.8752337098 0.8423663974 + 0.8657649755 0.8756874800 0.8429151177 + 0.8662593961 0.8761413097 0.8434638977 + 0.8667536974 0.8765950203 0.8440126181 + 0.8672459722 0.8770480156 0.8445599079 + 0.8677352071 0.8774996996 0.8451051116 + 0.8682243824 0.8779513836 0.8456501961 + 0.8687136173 0.8784031272 0.8461953998 + 0.8692027926 0.8788548112 0.8467404842 + 0.8696920276 0.8793064952 0.8472856283 + 0.8701782227 0.8797559738 0.8478285074 + 0.8706634045 0.8802047968 0.8483706117 + 0.8711487055 0.8806536198 0.8489127755 + 0.8716340065 0.8811023831 0.8494548798 + 0.8721193075 0.8815513253 0.8499971032 + 0.8726040721 0.8819996119 0.8505387902 + 0.8730852008 0.8824434280 0.8510770202 + 0.8735662103 0.8828871846 0.8516153097 + 0.8740472794 0.8833310008 0.8521534801 + 0.8745284081 0.8837748170 0.8526918292 + 0.8750094771 0.8842185140 0.8532299995 + 0.8754889965 0.8846611977 0.8537666798 + 0.8759661913 0.8851019740 0.8543009758 + 0.8764433861 0.8855428100 0.8548352718 + 0.8769205809 0.8859835863 0.8553696275 + 0.8773978949 0.8864244223 0.8559039235 + 0.8778750896 0.8868651986 0.8564382195 + 0.8783500195 0.8873041272 0.8569704294 + 0.8788238168 0.8877419829 0.8575013280 + 0.8792976141 0.8881797791 0.8580322862 + 0.8797712922 0.8886176944 0.8585631847 + 0.8802450895 0.8890554905 0.8590942025 + 0.8807188272 0.8894934058 0.8596251011 + 0.8811894059 0.8899270296 0.8601537943 + 0.8816593885 0.8903598189 0.8606820703 + 0.8821293116 0.8907926083 0.8612102866 + 0.8825992942 0.8912252784 0.8617386222 + 0.8830692768 0.8916581273 0.8622667789 + 0.8835391998 0.8920909166 0.8627951145 + 0.8840066195 0.8925206065 0.8633205295 + 0.8844739199 0.8929502964 0.8638458848 + 0.8849412799 0.8933799863 0.8643712997 + 0.8854085803 0.8938096762 0.8648967147 + 0.8858758807 0.8942393064 0.8654221296 + 0.8863430023 0.8946688175 0.8659473062 + 0.8868073225 0.8950955272 0.8664698005 + 0.8872717023 0.8955221772 0.8669921756 + 0.8877360225 0.8959488869 0.8675147295 + 0.8882004023 0.8963754773 0.8680372238 + 0.8886647224 0.8968021870 0.8685597181 + 0.8891286850 0.8972283006 0.8690819740 + 0.8895897269 0.8976498842 0.8696026802 + 0.8900507092 0.8980714083 0.8701235056 + 0.8905116916 0.8984929919 0.8706442714 + 0.8909726739 0.8989145160 0.8711650968 + 0.8914337158 0.8993360996 0.8716859221 + 0.8918942809 0.8997570872 0.8722062111 + 0.8923516273 0.9001740813 0.8727232218 + 0.8928089738 0.9005910754 0.8732401133 + 0.8932663798 0.9010080099 0.8737571239 + 0.8937237859 0.9014250040 0.8742740154 + 0.8941810727 0.9018419981 0.8747909069 + 0.8946381807 0.9022588134 0.8753076196 + 0.8950915933 0.9026719928 0.8758205771 + 0.8955450058 0.9030851722 0.8763335943 + 0.8959984183 0.9034984112 0.8768466711 + 0.8964517713 0.9039115906 0.8773596883 + 0.8969051838 0.9043248296 0.8778727055 + 0.8973585963 0.9047380090 0.8783857226 + 0.8978086114 0.9051464796 0.8788955212 + 0.8982583880 0.9055547118 0.8794052005 + 0.8987082839 0.9059628844 0.8799148798 + 0.8991581202 0.9063711166 0.8804246187 + 0.8996080160 0.9067792892 0.8809341788 + 0.9000577927 0.9071875215 0.8814439178 + 0.9005057216 0.9075921774 0.8819513917 + 0.9009531140 0.9079959989 0.8824583888 + 0.9014005065 0.9083997011 0.8829653859 + 0.9018480182 0.9088035226 0.8834723830 + 0.9022954106 0.9092072845 0.8839793801 + 0.9027428031 0.9096111059 0.8844863176 + 0.9031882286 0.9100126028 0.8849915862 + 0.9036322832 0.9104127884 0.8854957223 + 0.9040763974 0.9108129144 0.8859999180 + 0.9045205116 0.9112131000 0.8865039945 + 0.9049645066 0.9116132259 0.8870080709 + 0.9054086208 0.9120134115 0.8875123262 + 0.9058511853 0.9124118090 0.8880149126 + 0.9062910080 0.9128071070 0.8885148168 + 0.9067307115 0.9132024050 0.8890147209 + 0.9071704745 0.9135975838 0.8895145059 + 0.9076102972 0.9139928818 0.8900144100 + 0.9080501199 0.9143881202 0.8905143142 + 0.9084897041 0.9147831798 0.8910140991 + 0.9089263082 0.9151741862 0.8915116191 + 0.9093629122 0.9155650735 0.8920090795 + 0.9097993970 0.9159560800 0.8925067186 + 0.9102360010 0.9163470268 0.8930041790 + 0.9106726050 0.9167379737 0.8935016990 + 0.9111092091 0.9171289206 0.8939992189 + 0.9115434289 0.9175180197 0.8944947124 + 0.9119766951 0.9179061055 0.8949893117 + 0.9124100208 0.9182943106 0.8954837918 + 0.9128432870 0.9186825156 0.8959783912 + 0.9132764935 0.9190706015 0.8964728713 + 0.9137098193 0.9194588065 0.8969674706 + 0.9141420126 0.9198462963 0.8974612951 + 0.9145715833 0.9202318192 0.8979535103 + 0.9150012136 0.9206172824 0.8984456062 + 0.9154307842 0.9210028052 0.8989377022 + 0.9158604145 0.9213883281 0.8994297981 + 0.9162899256 0.9217737913 0.8999218941 + 0.9167194963 0.9221593142 0.9004141092 + 0.9171459079 0.9225426912 0.9009035826 + 0.9175716043 0.9229255915 0.9013926983 + 0.9179974198 0.9233083725 0.9018816948 + 0.9184231162 0.9236912131 0.9023706913 + 0.9188488126 0.9240741134 0.9028596878 + 0.9192745090 0.9244568944 0.9033486843 + 0.9196990132 0.9248390794 0.9038369060 + 0.9201207757 0.9252194166 0.9043233991 + 0.9205424786 0.9255996943 0.9048098922 + 0.9209643006 0.9259800911 0.9052963853 + 0.9213860035 0.9263604283 0.9057828784 + 0.9218078256 0.9267407060 0.9062693715 + 0.9222295880 0.9271209836 0.9067559242 + 0.9226487279 0.9274995923 0.9072409868 + 0.9230669141 0.9278776050 0.9077255726 + 0.9234851003 0.9282554984 0.9082100987 + 0.9239032865 0.9286333919 0.9086946845 + 0.9243214726 0.9290112853 0.9091792703 + 0.9247395992 0.9293891788 0.9096639156 + 0.9251574874 0.9297668934 0.9101482034 + 0.9255725741 0.9301424026 0.9106302261 + 0.9259877801 0.9305179119 0.9111121297 + 0.9264029264 0.9308934212 0.9115940928 + 0.9268180132 0.9312688708 0.9120761156 + 0.9272332191 0.9316444993 0.9125580192 + 0.9276483059 0.9320200086 0.9130399823 + 0.9280616045 0.9323946238 0.9135211110 + 0.9284722805 0.9327678084 0.9140009880 + 0.9288828969 0.9331409931 0.9144809246 + 0.9292935729 0.9335141778 0.9149606824 + 0.9297043085 0.9338874817 0.9154406190 + 0.9301149845 0.9342607260 0.9159204960 + 0.9305256009 0.9346339107 0.9164003730 + 0.9309334755 0.9350057244 0.9168785214 + 0.9313400984 0.9353767037 0.9173557162 + 0.9317467213 0.9357478023 0.9178329110 + 0.9321532845 0.9361187816 0.9183101058 + 0.9325597882 0.9364898205 0.9187873006 + 0.9329664111 0.9368609190 0.9192644954 + 0.9333729744 0.9372318983 0.9197416902 + 0.9337769747 0.9376000166 0.9202169776 + 0.9341807961 0.9379675984 0.9206920266 + 0.9345844984 0.9383351803 0.9211670756 + 0.9349882007 0.9387028217 0.9216421247 + 0.9353919029 0.9390705228 0.9221171737 + 0.9357956052 0.9394381046 0.9225922227 + 0.9361993074 0.9398056865 0.9230672121 + 0.9366000891 0.9401705861 0.9235394001 + 0.9370008707 0.9405354857 0.9240115881 + 0.9374017119 0.9409003854 0.9244837761 + 0.9378024936 0.9412652850 0.9249560237 + 0.9382032752 0.9416301847 0.9254282117 + 0.9386041760 0.9419950843 0.9259003997 + 0.9390046000 0.9423598051 0.9263724089 + 0.9394022822 0.9427227974 0.9268422723 + 0.9397999048 0.9430859089 0.9273123145 + 0.9401975870 0.9434489012 0.9277822971 + 0.9405953288 0.9438120127 0.9282522202 + 0.9409930110 0.9441750050 0.9287222028 + 0.9413906932 0.9445381165 0.9291921854 + 0.9417877793 0.9449006915 0.9296612740 + 0.9421823025 0.9452607036 0.9301261902 + 0.9425768852 0.9456205964 0.9305911064 + 0.9429714084 0.9459806085 0.9310560226 + 0.9433658719 0.9463406205 0.9315208793 + 0.9437603951 0.9467005730 0.9319856763 + 0.9441549182 0.9470605254 0.9324505925 + 0.9445487261 0.9474198818 0.9329144955 + 0.9449381828 0.9477747083 0.9333720803 + 0.9453276992 0.9481294751 0.9338297248 + 0.9457172155 0.9484843016 0.9342873096 + 0.9461067915 0.9488391280 0.9347448945 + 0.9464963078 0.9491938949 0.9352024794 + 0.9468858242 0.9495487809 0.9356601238 + 0.9472748041 0.9499033093 0.9361174107 + 0.9476565719 0.9502521157 0.9365684986 + 0.9480383992 0.9506009221 0.9370197058 + 0.9484201074 0.9509496093 0.9374709129 + 0.9488018751 0.9512984157 0.9379221201 + 0.9491835833 0.9516472220 0.9383733273 + 0.9495654106 0.9519960284 0.9388244152 + 0.9499471784 0.9523447156 0.9392756224 + 0.9503229260 0.9526900053 0.9397230148 + 0.9506981969 0.9530349970 0.9401701093 + 0.9510734081 0.9533799291 0.9406172037 + 0.9514486194 0.9537248015 0.9410642982 + 0.9518237710 0.9540696740 0.9415112734 + 0.9521991014 0.9544147253 0.9419584274 + 0.9525743127 0.9547595978 0.9424055219 + 0.9529467225 0.9551023841 0.9428507090 + 0.9533181190 0.9554443955 0.9432951808 + 0.9536895156 0.9557864070 0.9437395930 + 0.9540607929 0.9561284184 0.9441841245 + 0.9544321895 0.9564703703 0.9446285963 + 0.9548035860 0.9568123817 0.9450731277 + 0.9551749229 0.9571543932 0.9455174804 + 0.9555448294 0.9574952722 0.9459602833 + 0.9559131265 0.9578347802 0.9464008808 + 0.9562813044 0.9581742883 0.9468415976 + 0.9566496015 0.9585137963 0.9472823143 + 0.9570177794 0.9588533044 0.9477229118 + 0.9573860765 0.9591928124 0.9481636286 + 0.9577543139 0.9595323205 0.9486042857 + 0.9581220150 0.9598714113 0.9490444064 + 0.9584864974 0.9602082968 0.9494813085 + 0.9588509798 0.9605451226 0.9499182105 + 0.9592155218 0.9608818889 0.9503551126 + 0.9595801234 0.9612187743 0.9507918954 + 0.9599446058 0.9615556002 0.9512287974 + 0.9603090882 0.9618924856 0.9516656995 + 0.9606735706 0.9622293115 0.9521026015 + 0.9610344768 0.9625636935 0.9525365829 + 0.9613944292 0.9628973007 0.9529696107 + 0.9617542028 0.9632309079 0.9534025788 + 0.9621140957 0.9635645151 0.9538357258 + 0.9624739289 0.9638981223 0.9542686939 + 0.9628337026 0.9642317295 0.9547017813 + 0.9631935954 0.9645652771 0.9551348090 + 0.9635519981 0.9648981094 0.9555665851 + 0.9639074206 0.9652289152 0.9559956789 + 0.9642627835 0.9655597210 0.9564247727 + 0.9646183252 0.9658905268 0.9568538070 + 0.9649736881 0.9662212729 0.9572829008 + 0.9653291106 0.9665520787 0.9577119946 + 0.9656844735 0.9668828845 0.9581410885 + 0.9660398960 0.9672136903 0.9585701227 + 0.9663916826 0.9675421119 0.9589954019 + 0.9667426944 0.9678698778 0.9594197869 + 0.9670937061 0.9681977034 0.9598442912 + 0.9674447179 0.9685255289 0.9602686763 + 0.9677956104 0.9688534141 0.9606931210 + 0.9681466222 0.9691811800 0.9611175060 + 0.9684975743 0.9695090055 0.9615418911 + 0.9688472748 0.9698359966 0.9619650841 + 0.9691932797 0.9701604247 0.9623844028 + 0.9695392847 0.9704847932 0.9628037214 + 0.9698852897 0.9708092213 0.9632229805 + 0.9702312946 0.9711335897 0.9636424184 + 0.9705772996 0.9714580178 0.9640616775 + 0.9709233046 0.9717823863 0.9644809961 + 0.9712691903 0.9721068144 0.9649003148 + 0.9716116190 0.9724292159 0.9653162956 + 0.9719517827 0.9727504253 0.9657304287 + 0.9722920060 0.9730715156 0.9661443830 + 0.9726322293 0.9733927250 0.9665583968 + 0.9729723930 0.9737138152 0.9669724107 + 0.9733124971 0.9740350246 0.9673864245 + 0.9736527205 0.9743561745 0.9678003788 + 0.9739928842 0.9746773243 0.9682143927 + 0.9743273854 0.9749950767 0.9686228037 + 0.9746615291 0.9753125906 0.9690306783 + 0.9749956727 0.9756301045 0.9694386721 + 0.9753298163 0.9759476185 0.9698466063 + 0.9756639004 0.9762650728 0.9702546000 + 0.9759979844 0.9765825868 0.9706624746 + 0.9763321280 0.9769001007 0.9710705280 + 0.9766650200 0.9772170186 0.9714773297 + 0.9769923091 0.9775304198 0.9718787074 + 0.9773195982 0.9778438807 0.9722800851 + 0.9776468873 0.9781572819 0.9726815820 + 0.9779741764 0.9784708023 0.9730830193 + 0.9783015847 0.9787843227 0.9734843969 + 0.9786288738 0.9790977240 0.9738858938 + 0.9789562225 0.9794111848 0.9742872715 + 0.9792808890 0.9797229767 0.9746860862 + 0.9796009064 0.9800319076 0.9750801921 + 0.9799209237 0.9803407788 0.9754742980 + 0.9802408814 0.9806495905 0.9758684039 + 0.9805610180 0.9809585214 0.9762625098 + 0.9808809757 0.9812673926 0.9766566157 + 0.9812009931 0.9815762043 0.9770507216 + 0.9815210104 0.9818850756 0.9774448276 + 0.9818372726 0.9821913242 0.9778347015 + 0.9821496010 0.9824944139 0.9782199264 + 0.9824618101 0.9827976227 0.9786050916 + 0.9827740788 0.9831007123 0.9789903164 + 0.9830862880 0.9834039211 0.9793756008 + 0.9833986163 0.9837070107 0.9797608256 + 0.9837108254 0.9840102196 0.9801459908 + 0.9840230942 0.9843133092 0.9805312157 + 0.9843308926 0.9846134782 0.9809110165 + 0.9846346974 0.9849109054 0.9812859297 + 0.9849383831 0.9852082729 0.9816609025 + 0.9852421880 0.9855058193 0.9820358157 + 0.9855459929 0.9858031869 0.9824107289 + 0.9858497977 0.9861006141 0.9827855825 + 0.9861536026 0.9863979816 0.9831604958 + 0.9864572883 0.9866954088 0.9835355282 + 0.9867570996 0.9869899154 0.9839053154 + 0.9870529771 0.9872815013 0.9842700958 + 0.9873489141 0.9875730872 0.9846349955 + 0.9876447916 0.9878646731 0.9849997759 + 0.9879406095 0.9881563783 0.9853646755 + 0.9882364869 0.9884480238 0.9857295156 + 0.9885324240 0.9887396097 0.9860944152 + 0.9888283014 0.9890311956 0.9864593148 + 0.9891207814 0.9893190861 0.9868193865 + 0.9894089103 0.9896019101 0.9871731997 + 0.9896969199 0.9898846745 0.9875268936 + 0.9899849892 0.9901676178 0.9878807068 + 0.9902729988 0.9904503822 0.9882345200 + 0.9905611277 0.9907332063 0.9885882735 + 0.9908490777 0.9910160899 0.9889420271 + 0.9911370873 0.9912989140 0.9892957807 + 0.9914227128 0.9915794730 0.9896461964 + 0.9917017817 0.9918540716 0.9899876714 + 0.9919809103 0.9921286702 0.9903292060 + 0.9922599792 0.9924033284 0.9906706810 + 0.9925391078 0.9926779866 0.9910122156 + 0.9928181767 0.9929525852 0.9913538098 + 0.9930973053 0.9932271838 0.9916952848 + 0.9933763742 0.9935019016 0.9920368195 + 0.9936547875 0.9937759042 0.9923774004 + 0.9939225912 0.9940415025 0.9927039146 + 0.9941903949 0.9943069816 0.9930304289 + 0.9944581985 0.9945725799 0.9933570027 + 0.9947260022 0.9948381186 0.9936835170 + 0.9949938059 0.9951037169 0.9940099716 + 0.9952616096 0.9953691959 0.9943366051 + 0.9955294132 0.9956346750 0.9946631193 + 0.9957972765 0.9959002733 0.9949895740 + 0.9960541129 0.9961531162 0.9953014851 + 0.9963079095 0.9964022040 0.9956092238 + 0.9965615869 0.9966512918 0.9959169030 + 0.9968153834 0.9969003797 0.9962245226 + 0.9970691204 0.9971495271 0.9965322018 + 0.9973229170 0.9973986149 0.9968398809 + 0.9975765944 0.9976477027 0.9971476197 + 0.9978303909 0.9978967905 0.9974551797 + 0.9980784059 0.9981389046 0.9977517128 + 0.9983186126 0.9983714819 0.9980326891 + 0.9985588193 0.9986041784 0.9983137250 + 0.9987990260 0.9988368154 0.9985948205 + 0.9990391731 0.9990693927 0.9988757968 + 0.9992793798 0.9993020892 0.9991568923 + 0.9995195866 0.9995347261 0.9994379282 + 0.9997597933 0.9997674227 0.9997190237 + 1.0000000000 1.0000000000 1.0000000000 +} diff --git a/rpplugins/color_correction/resources/film_luts_raw/agfa_agfacolor_hdc_400_plus.spi1d b/rpplugins/color_correction/resources/film_luts_raw/agfa_agfacolor_hdc_400_plus.spi1d new file mode 100644 index 0000000..544bf93 --- /dev/null +++ b/rpplugins/color_correction/resources/film_luts_raw/agfa_agfacolor_hdc_400_plus.spi1d @@ -0,0 +1,1030 @@ +Version 1 +From 0.0 1.0 +Length 1024 +Components 3 +{ + 0.0000000000 0.0000000000 0.0000000000 + 0.0188545007 0.0200409293 0.0140067302 + 0.0332524888 0.0348740518 0.0258749295 + 0.0452598706 0.0475615300 0.0362151787 + 0.0559787415 0.0589470603 0.0456109904 + 0.0658830702 0.0694492683 0.0543236583 + 0.0752111897 0.0792194605 0.0625015125 + 0.0841012076 0.0884407684 0.0702229664 + 0.0926621929 0.0972259119 0.0775719434 + 0.1009650975 0.1056030989 0.0846038684 + 0.1090589985 0.1136253998 0.0913083479 + 0.1170130968 0.1213366017 0.0977427885 + 0.1247942969 0.1287464052 0.1039230004 + 0.1323173046 0.1358782053 0.1098598987 + 0.1394851059 0.1427361071 0.1155802011 + 0.1463093013 0.1493203044 0.1211000010 + 0.1528204978 0.1556663066 0.1264265031 + 0.1590683013 0.1617784947 0.1315815002 + 0.1650577933 0.1676822007 0.1365823001 + 0.1708182991 0.1734001040 0.1414559036 + 0.1763903052 0.1789600998 0.1462168992 + 0.1817798018 0.1843533963 0.1508775055 + 0.1870086044 0.1895903945 0.1554276943 + 0.1920844018 0.1946922988 0.1598816961 + 0.1970220059 0.1996600926 0.1642390937 + 0.2018329054 0.2045013011 0.1684959978 + 0.2065093070 0.2092238963 0.1726709008 + 0.2110690027 0.2138542980 0.1767773032 + 0.2155348957 0.2183912992 0.1808128059 + 0.2198981047 0.2228228003 0.1847777069 + 0.2241635025 0.2271593064 0.1886793971 + 0.2283228040 0.2314175963 0.1925252974 + 0.2323801965 0.2355985940 0.1963074058 + 0.2363557965 0.2396991998 0.2000353038 + 0.2402614951 0.2437127978 0.2036948055 + 0.2441187054 0.2476392984 0.2072975934 + 0.2479200959 0.2514924109 0.2108584046 + 0.2516668141 0.2552962005 0.2143702954 + 0.2553597987 0.2590639889 0.2178401053 + 0.2590073943 0.2627837062 0.2212640047 + 0.2626096010 0.2664473057 0.2246434987 + 0.2661620975 0.2700594962 0.2279828042 + 0.2696613073 0.2736192942 0.2312768996 + 0.2731044888 0.2771342099 0.2345380038 + 0.2764894962 0.2806042135 0.2377575040 + 0.2798126042 0.2840265930 0.2409393936 + 0.2830832899 0.2873997092 0.2440892011 + 0.2863064110 0.2907201052 0.2471970022 + 0.2894839048 0.2939862907 0.2502729893 + 0.2926194966 0.2971968949 0.2533178031 + 0.2957077026 0.3003590107 0.2563329041 + 0.2987434864 0.3034782112 0.2593177855 + 0.3017309904 0.3065663874 0.2622711957 + 0.3046731055 0.3096238971 0.2652002871 + 0.3075759113 0.3126527965 0.2681050003 + 0.3104431033 0.3156541884 0.2709783912 + 0.3132778108 0.3186286986 0.2738296092 + 0.3160825074 0.3215768933 0.2766565979 + 0.3188611865 0.3244988918 0.2794562876 + 0.3216165900 0.3273960948 0.2822301984 + 0.3243513107 0.3302688003 0.2849779129 + 0.3270677924 0.3331151903 0.2877022028 + 0.3297683895 0.3359293044 0.2903991938 + 0.3324556947 0.3387104869 0.2930696011 + 0.3351315856 0.3414531052 0.2957195044 + 0.3377983868 0.3441590071 0.2983430922 + 0.3404580057 0.3468317986 0.3009459972 + 0.3431122899 0.3494741917 0.3035286963 + 0.3457567990 0.3520886004 0.3060950041 + 0.3483870029 0.3546772897 0.3086442053 + 0.3509952128 0.3572408855 0.3111701012 + 0.3535763919 0.3597824872 0.3136737049 + 0.3561269045 0.3623043895 0.3161568940 + 0.3586477935 0.3648073971 0.3186241984 + 0.3611387014 0.3672929108 0.3210709095 + 0.3636046052 0.3697636127 0.3234997094 + 0.3660457134 0.3722181916 0.3259125948 + 0.3684634864 0.3746534884 0.3283078969 + 0.3708611131 0.3770717978 0.3306862116 + 0.3732374012 0.3794744015 0.3330459893 + 0.3755970895 0.3818623126 0.3353869021 + 0.3779377937 0.3842301071 0.3377087116 + 0.3802644014 0.3865832984 0.3400174975 + 0.3825747967 0.3889225125 0.3423081040 + 0.3848729134 0.3912503123 0.3445838094 + 0.3871577978 0.3935666978 0.3468438089 + 0.3894316852 0.3958694041 0.3490906954 + 0.3916954100 0.3981603980 0.3513231874 + 0.3939490914 0.4004369080 0.3535391092 + 0.3961951137 0.4026972055 0.3557423055 + 0.3984332085 0.4049367011 0.3579295874 + 0.4006646872 0.4071569145 0.3600991964 + 0.4028908908 0.4093607068 0.3622539937 + 0.4051119983 0.4115476012 0.3643927872 + 0.4073289931 0.4137150049 0.3665145040 + 0.4095427990 0.4158644974 0.3686214983 + 0.4117541909 0.4179973006 0.3707144856 + 0.4139570892 0.4201147854 0.3727920055 + 0.4161537886 0.4222174883 0.3748528957 + 0.4183439910 0.4243085980 0.3768979013 + 0.4205237925 0.4263896048 0.3789266050 + 0.4226934910 0.4284594953 0.3809396923 + 0.4248510003 0.4305211902 0.3829380870 + 0.4269989133 0.4325712025 0.3849214911 + 0.4291365147 0.4346114993 0.3868896961 + 0.4312635958 0.4366433918 0.3888421953 + 0.4333817959 0.4386653006 0.3907817900 + 0.4354879856 0.4406721890 0.3927083015 + 0.4375857115 0.4426656961 0.3946214020 + 0.4396727085 0.4446468949 0.3965215981 + 0.4417509139 0.4466181099 0.3984085917 + 0.4438194931 0.4485799074 0.4002822936 + 0.4458774030 0.4505313933 0.4021424949 + 0.4479227960 0.4524719119 0.4039889872 + 0.4499554038 0.4544002116 0.4058243036 + 0.4519762993 0.4563159049 0.4076485038 + 0.4539847076 0.4582194090 0.4094625115 + 0.4559822977 0.4601128101 0.4112651944 + 0.4579656124 0.4619938135 0.4130575061 + 0.4599342942 0.4638626873 0.4148383141 + 0.4618889093 0.4657208920 0.4166125953 + 0.4638301134 0.4675695002 0.4183782041 + 0.4657584131 0.4694097936 0.4201379120 + 0.4676744044 0.4712429941 0.4218888879 + 0.4695785046 0.4730699956 0.4236342013 + 0.4714691937 0.4748862982 0.4253711104 + 0.4733453989 0.4766918123 0.4271022975 + 0.4752089083 0.4784876108 0.4288255870 + 0.4770591855 0.4802748859 0.4305430055 + 0.4788978100 0.4820528924 0.4322530031 + 0.4807246923 0.4838208854 0.4339570105 + 0.4825393856 0.4855782092 0.4356541038 + 0.4843406081 0.4873236120 0.4373449087 + 0.4861288071 0.4890565872 0.4390296042 + 0.4879052043 0.4907774925 0.4407073855 + 0.4896669984 0.4924885035 0.4423801005 + 0.4914163053 0.4941891134 0.4440453053 + 0.4931511879 0.4958809912 0.4457054138 + 0.4948748052 0.4975647032 0.4473578930 + 0.4965868890 0.4992407858 0.4490056038 + 0.4982892871 0.5009080172 0.4506456852 + 0.4999811053 0.5025680065 0.4522778988 + 0.5016608238 0.5042217970 0.4539025128 + 0.5033277869 0.5058667064 0.4555189908 + 0.5049809813 0.5075010061 0.4571281075 + 0.5066220760 0.5091261864 0.4587261975 + 0.5082523823 0.5107440948 0.4603149891 + 0.5098735094 0.5123543739 0.4618948102 + 0.5114861131 0.5139557719 0.4634658098 + 0.5130900741 0.5155460238 0.4650284052 + 0.5146843791 0.5171270967 0.4665809870 + 0.5162659287 0.5186967850 0.4681251943 + 0.5178381205 0.5202578902 0.4696618021 + 0.5194014907 0.5218108296 0.4711911976 + 0.5209562182 0.5233557224 0.4727137089 + 0.5225027204 0.5248928070 0.4742273986 + 0.5240399241 0.5264220834 0.4757342041 + 0.5255666971 0.5279446244 0.4772349000 + 0.5270826221 0.5294610262 0.4787296057 + 0.5285871029 0.5309712887 0.4802174866 + 0.5300801992 0.5324715972 0.4816986024 + 0.5315656066 0.5339645743 0.4831734896 + 0.5330439210 0.5354511142 0.4846417010 + 0.5345147848 0.5369303823 0.4861015081 + 0.5359786153 0.5384036899 0.4875538051 + 0.5374345779 0.5398699045 0.4889999032 + 0.5388823748 0.5413284898 0.4904398918 + 0.5403190255 0.5427761078 0.4918713868 + 0.5417451859 0.5442144275 0.4932934940 + 0.5431644917 0.5456464291 0.4947094917 + 0.5445777774 0.5470724106 0.4961200953 + 0.5459790826 0.5484896898 0.4975199103 + 0.5473731756 0.5499022007 0.4989153147 + 0.5487601161 0.5513098240 0.5003060102 + 0.5501369238 0.5527070761 0.5016881227 + 0.5515047908 0.5540965199 0.5030658245 + 0.5528663993 0.5554798841 0.5044389963 + 0.5542203188 0.5568554997 0.5058041215 + 0.5555655956 0.5582247972 0.5071626902 + 0.5569046140 0.5595903993 0.5085164905 + 0.5582354069 0.5609512925 0.5098640919 + 0.5595571995 0.5623037219 0.5112056732 + 0.5608744025 0.5636506081 0.5125434995 + 0.5621863008 0.5649901032 0.5138760209 + 0.5634893179 0.5663208961 0.5152037144 + 0.5647879243 0.5676466823 0.5165277719 + 0.5660805702 0.5689647198 0.5178461075 + 0.5673637986 0.5702759027 0.5191584826 + 0.5686416030 0.5715829730 0.5204676986 + 0.5699104071 0.5728827119 0.5217714906 + 0.5711724758 0.5741752982 0.5230712891 + 0.5724303126 0.5754632950 0.5243685842 + 0.5736793280 0.5767428279 0.5256611705 + 0.5749223232 0.5780189037 0.5269505978 + 0.5761598945 0.5792912841 0.5282369256 + 0.5773891807 0.5805559158 0.5295171142 + 0.5786157250 0.5818173885 0.5307943821 + 0.5798376203 0.5830736160 0.5320662856 + 0.5810524225 0.5843229294 0.5333334804 + 0.5822634101 0.5855684876 0.5345982909 + 0.5834617019 0.5868036151 0.5358551741 + 0.5846555233 0.5880358219 0.5371090174 + 0.5858426094 0.5892624855 0.5383573771 + 0.5870230794 0.5904846787 0.5395992994 + 0.5882006884 0.5917047858 0.5408381224 + 0.5893698931 0.5929183960 0.5420668125 + 0.5905355811 0.5941283703 0.5432921052 + 0.5916948915 0.5953302979 0.5445101261 + 0.5928494930 0.5965275168 0.5457227826 + 0.5940014720 0.5977213979 0.5469322205 + 0.5951455235 0.5989087224 0.5481334925 + 0.5962870121 0.6000937819 0.5493327975 + 0.5974202752 0.6012709141 0.5505263209 + 0.5985488296 0.6024438739 0.5517168045 + 0.5996711254 0.6036102176 0.5529028773 + 0.6007874012 0.6047713161 0.5540845990 + 0.6019008160 0.6059291959 0.5552638173 + 0.6030085087 0.6070817113 0.5564357042 + 0.6041145921 0.6082327962 0.5576059818 + 0.6052119732 0.6093747020 0.5587717295 + 0.6063060164 0.6105144024 0.5599352717 + 0.6073911786 0.6116470098 0.5610927939 + 0.6084719896 0.6127761006 0.5622478127 + 0.6095473170 0.6139001250 0.5633994937 + 0.6106179953 0.6150193214 0.5645474792 + 0.6116858125 0.6161350012 0.5656930804 + 0.6127483249 0.6172463298 0.5668336153 + 0.6138089895 0.6183556914 0.5679724216 + 0.6148627996 0.6194601059 0.5691046715 + 0.6159157157 0.6205636263 0.5702360272 + 0.6169633269 0.6216604114 0.5713596940 + 0.6180101037 0.6227564216 0.5724828839 + 0.6190497279 0.6238446832 0.5736011267 + 0.6200875044 0.6249315739 0.5747177005 + 0.6211166978 0.6260104179 0.5758256912 + 0.6221439838 0.6270869970 0.5769320130 + 0.6231651902 0.6281551719 0.5780321956 + 0.6241847873 0.6292213202 0.5791301131 + 0.6252005100 0.6302810907 0.5802220702 + 0.6262137294 0.6313390732 0.5813122988 + 0.6272215247 0.6323928237 0.5823984742 + 0.6282256246 0.6334443092 0.5834822059 + 0.6292229891 0.6344907284 0.5845605731 + 0.6302174926 0.6355344057 0.5856364965 + 0.6312069297 0.6365721822 0.5867068172 + 0.6321943998 0.6376072168 0.5877746940 + 0.6331781745 0.6386352777 0.5888370872 + 0.6341605186 0.6396614909 0.5898970962 + 0.6351392865 0.6406822205 0.5909510255 + 0.6361160278 0.6417014003 0.5920032263 + 0.6370865107 0.6427150965 0.5930498242 + 0.6380555034 0.6437277794 0.5940951109 + 0.6390181184 0.6447337866 0.5951337814 + 0.6399800181 0.6457393169 0.5961719155 + 0.6409355998 0.6467369199 0.5972027779 + 0.6418911219 0.6477345228 0.5982336998 + 0.6428390741 0.6487230062 0.5992593169 + 0.6437870860 0.6497110128 0.6002848744 + 0.6447305083 0.6506903768 0.6013044715 + 0.6456733942 0.6516680717 0.6023231745 + 0.6466109157 0.6526402235 0.6033357978 + 0.6475467086 0.6536098123 0.6043460965 + 0.6484770179 0.6545764208 0.6053528786 + 0.6494035721 0.6555402875 0.6063570976 + 0.6503273249 0.6565018892 0.6073589921 + 0.6512470245 0.6574596167 0.6083570719 + 0.6521654129 0.6584159136 0.6093541980 + 0.6530792713 0.6593660116 0.6103470922 + 0.6539931297 0.6603162289 0.6113399863 + 0.6548979282 0.6612582803 0.6123251915 + 0.6558027267 0.6622002125 0.6133103967 + 0.6567010283 0.6631376147 0.6142895222 + 0.6575976014 0.6640735269 0.6152667999 + 0.6584901810 0.6650068164 0.6162406206 + 0.6593794823 0.6659374237 0.6172112823 + 0.6602666974 0.6668658853 0.6181805134 + 0.6611484885 0.6677879095 0.6191458106 + 0.6620302200 0.6687098742 0.6201111078 + 0.6629042029 0.6696240902 0.6210708022 + 0.6637783051 0.6705380082 0.6220304966 + 0.6646463871 0.6714469790 0.6229835153 + 0.6655120850 0.6723536253 0.6239334941 + 0.6663749814 0.6732575297 0.6248810291 + 0.6672335863 0.6741561890 0.6258239746 + 0.6680920124 0.6750550270 0.6267668009 + 0.6689471006 0.6759482026 0.6277027726 + 0.6698023081 0.6768413782 0.6286388040 + 0.6706528068 0.6777299047 0.6295701861 + 0.6715013981 0.6786159277 0.6304991841 + 0.6723480821 0.6794993281 0.6314260960 + 0.6731910110 0.6803758740 0.6323478818 + 0.6740338206 0.6812524199 0.6332696080 + 0.6748722792 0.6821228266 0.6341838837 + 0.6757103205 0.6829922795 0.6350972056 + 0.6765457988 0.6838589907 0.6360073090 + 0.6773787141 0.6847224236 0.6369137168 + 0.6782112718 0.6855856776 0.6378198266 + 0.6790390015 0.6864398122 0.6387205124 + 0.6798666716 0.6872938871 0.6396213174 + 0.6806908250 0.6881433129 0.6405187845 + 0.6815124750 0.6889889836 0.6414139867 + 0.6823334098 0.6898341179 0.6423081756 + 0.6831489205 0.6906722784 0.6431941986 + 0.6839643717 0.6915106177 0.6440802217 + 0.6847774982 0.6923443079 0.6449621916 + 0.6855893135 0.6931747794 0.6458414197 + 0.6864004731 0.6940047741 0.6467201710 + 0.6872066855 0.6948273182 0.6475932002 + 0.6880130172 0.6956499219 0.6484662294 + 0.6888151765 0.6964679956 0.6493358016 + 0.6896142960 0.6972820163 0.6502025723 + 0.6904134154 0.6980959177 0.6510692835 + 0.6912078261 0.6989029050 0.6519299746 + 0.6920022964 0.6997095942 0.6527906060 + 0.6927950978 0.7005147934 0.6536483169 + 0.6935858130 0.7013174891 0.6545016766 + 0.6943765283 0.7021203041 0.6553550959 + 0.6951621175 0.7029188275 0.6562039852 + 0.6959465146 0.7037159801 0.6570516229 + 0.6967297792 0.7045122981 0.6578981876 + 0.6975088120 0.7053027749 0.6587392092 + 0.6982877254 0.7060933113 0.6595801711 + 0.6990643144 0.7068814039 0.6604182720 + 0.6998388171 0.7076671124 0.6612536907 + 0.7006133199 0.7084527016 0.6620889902 + 0.7013818026 0.7092331052 0.6629180908 + 0.7021492720 0.7100123167 0.6637459993 + 0.7029157877 0.7107905746 0.6645727754 + 0.7036771774 0.7115622759 0.6653935909 + 0.7044386268 0.7123339772 0.6662142873 + 0.7051976919 0.7131032944 0.6670325994 + 0.7059540153 0.7138692141 0.6678475738 + 0.7067102790 0.7146351933 0.6686627269 + 0.7074630260 0.7153962851 0.6694738865 + 0.7082142234 0.7161549926 0.6702834964 + 0.7089654803 0.7169137001 0.6710931063 + 0.7097116709 0.7176669836 0.6718968153 + 0.7104576826 0.7184197903 0.6727002263 + 0.7112026811 0.7191722989 0.6735023856 + 0.7119430900 0.7199227214 0.6742987037 + 0.7126836181 0.7206730843 0.6750949025 + 0.7134215236 0.7214214206 0.6758887768 + 0.7141550779 0.7221655250 0.6766782999 + 0.7148886919 0.7229096293 0.6774678230 + 0.7156193852 0.7236497998 0.6782538295 + 0.7163475752 0.7243860960 0.6790366769 + 0.7170758247 0.7251223922 0.6798195839 + 0.7178009748 0.7258551717 0.6805974841 + 0.7185249925 0.7265861034 0.6813730001 + 0.7192488909 0.7273170948 0.6821485162 + 0.7199671268 0.7280430198 0.6829196215 + 0.7206841111 0.7287673950 0.6836894155 + 0.7214009762 0.7294918895 0.6844593287 + 0.7221128941 0.7302092910 0.6852232814 + 0.7228242755 0.7309256792 0.6859866977 + 0.7235357165 0.7316421866 0.6867499948 + 0.7242426872 0.7323533297 0.6875082850 + 0.7249497175 0.7330641747 0.6882663965 + 0.7256563902 0.7337750793 0.6890243888 + 0.7263563275 0.7344793081 0.6897757053 + 0.7270562053 0.7351834774 0.6905270219 + 0.7277556062 0.7358874083 0.6912779808 + 0.7284498811 0.7365834117 0.6920228004 + 0.7291440964 0.7372794151 0.6927676201 + 0.7298380136 0.7379751801 0.6935120821 + 0.7305275798 0.7386654019 0.6942508817 + 0.7312173247 0.7393556833 0.6949896812 + 0.7319065928 0.7400457859 0.6957281828 + 0.7325891256 0.7407314777 0.6964604259 + 0.7332715988 0.7414172292 0.6971926093 + 0.7339540124 0.7421028018 0.6979246736 + 0.7346293926 0.7427842021 0.6986520290 + 0.7353047729 0.7434653044 0.6993792057 + 0.7359800935 0.7441465259 0.7001065016 + 0.7366490960 0.7448238134 0.7008286715 + 0.7373176217 0.7455006838 0.7015504241 + 0.7379860878 0.7461774945 0.7022721171 + 0.7386487722 0.7468507886 0.7029896975 + 0.7393102050 0.7475231886 0.7037063241 + 0.7399716973 0.7481955886 0.7044230103 + 0.7406283021 0.7488650084 0.7051362991 + 0.7412828207 0.7495329976 0.7058482170 + 0.7419373989 0.7502009869 0.7065600157 + 0.7425882220 0.7508667707 0.7072690129 + 0.7432361841 0.7515305877 0.7079756260 + 0.7438840866 0.7521942854 0.7086821795 + 0.7445294261 0.7528566122 0.7093874216 + 0.7451704741 0.7535158992 0.7100903988 + 0.7458115220 0.7541753054 0.7107933760 + 0.7464513183 0.7548338175 0.7114953995 + 0.7470856905 0.7554876804 0.7121930122 + 0.7477200031 0.7561414838 0.7128906250 + 0.7483543158 0.7567954063 0.7135881782 + 0.7489826083 0.7574434876 0.7142792940 + 0.7496104836 0.7580910921 0.7149698138 + 0.7502384186 0.7587388158 0.7156603932 + 0.7508633137 0.7593836188 0.7163473964 + 0.7514868975 0.7600269914 0.7170326114 + 0.7521104217 0.7606704235 0.7177178264 + 0.7527319193 0.7613118291 0.7184010744 + 0.7533503771 0.7619500160 0.7190815210 + 0.7539688945 0.7625880837 0.7197619081 + 0.7545869946 0.7632259130 0.7204418182 + 0.7552015185 0.7638580203 0.7211170197 + 0.7558159828 0.7644901872 0.7217922807 + 0.7564306259 0.7651224136 0.7224674821 + 0.7570430040 0.7657516003 0.7231383920 + 0.7576547265 0.7663797736 0.7238079906 + 0.7582663894 0.7670078874 0.7244775295 + 0.7588763237 0.7676342130 0.7251446843 + 0.7594832778 0.7682573199 0.7258080840 + 0.7600904107 0.7688804269 0.7264714837 + 0.7606974244 0.7695034742 0.7271348238 + 0.7613009214 0.7701197863 0.7277917266 + 0.7619044185 0.7707359791 0.7284486294 + 0.7625079155 0.7713521719 0.7291054130 + 0.7631099820 0.7719650865 0.7297595143 + 0.7637109756 0.7725753188 0.7304114103 + 0.7643120885 0.7731856108 0.7310634255 + 0.7649124265 0.7737953067 0.7317147851 + 0.7655079961 0.7744010091 0.7323616743 + 0.7661035061 0.7750065923 0.7330086827 + 0.7666990757 0.7756121755 0.7336556911 + 0.7672913074 0.7762138247 0.7342997193 + 0.7678816915 0.7768129110 0.7349420190 + 0.7684720755 0.7774121165 0.7355843782 + 0.7690622211 0.7780106068 0.7362260818 + 0.7696506977 0.7786043286 0.7368643284 + 0.7702391148 0.7791979909 0.7375025153 + 0.7708275914 0.7797915936 0.7381407022 + 0.7714130878 0.7803828716 0.7387762070 + 0.7719966769 0.7809723020 0.7394099236 + 0.7725803256 0.7815617919 0.7400435805 + 0.7731636167 0.7821511030 0.7406771779 + 0.7737426162 0.7827333808 0.7413080931 + 0.7743214965 0.7833157182 0.7419390082 + 0.7749004960 0.7838979959 0.7425699234 + 0.7754787803 0.7844783068 0.7431989908 + 0.7760564089 0.7850558758 0.7438256741 + 0.7766339779 0.7856335044 0.7444524765 + 0.7772114873 0.7862110734 0.7450792193 + 0.7777854800 0.7867867947 0.7457013726 + 0.7783586979 0.7873620987 0.7463225126 + 0.7789319158 0.7879372835 0.7469435930 + 0.7795041800 0.7885116935 0.7475640774 + 0.7800722718 0.7890805006 0.7481812835 + 0.7806403041 0.7896494269 0.7487984896 + 0.7812082767 0.7902181745 0.7494155765 + 0.7817749977 0.7907847166 0.7500311732 + 0.7823402286 0.7913483977 0.7506451011 + 0.7829053998 0.7919120193 0.7512589097 + 0.7834705114 0.7924757004 0.7518727779 + 0.7840328813 0.7930366993 0.7524824739 + 0.7845944762 0.7935966849 0.7530907989 + 0.7851560116 0.7941566706 0.7536991239 + 0.7857174277 0.7947167158 0.7543073297 + 0.7862744927 0.7952712178 0.7549107075 + 0.7868316174 0.7958257794 0.7555140853 + 0.7873886824 0.7963802814 0.7561174035 + 0.7879452109 0.7969337106 0.7567198277 + 0.7885001898 0.7974827886 0.7573189139 + 0.7890551090 0.7980319858 0.7579178810 + 0.7896100283 0.7985811234 0.7585170269 + 0.7901636958 0.7991284132 0.7591142058 + 0.7907155752 0.7996730208 0.7597088218 + 0.7912675738 0.8002175093 0.7603033781 + 0.7918195128 0.8007619977 0.7608978748 + 0.7923693061 0.8013039827 0.7614898086 + 0.7929174900 0.8018441200 0.7620797753 + 0.7934656739 0.8023841977 0.7626696825 + 0.7940139174 0.8029242754 0.7632595897 + 0.7945610285 0.8034613729 0.7638459802 + 0.7951077223 0.8039970994 0.7644308209 + 0.7956544161 0.8045328259 0.7650157213 + 0.7962012291 0.8050686121 0.7656006217 + 0.7967458963 0.8056014776 0.7661811709 + 0.7972903252 0.8061336279 0.7667608261 + 0.7978346944 0.8066657186 0.7673404217 + 0.7983791232 0.8071978092 0.7679200172 + 0.7989180088 0.8077269793 0.7684965134 + 0.7994561791 0.8082556725 0.7690725923 + 0.7999945283 0.8087844253 0.7696486115 + 0.8005326986 0.8093131185 0.7702246904 + 0.8010672927 0.8098369837 0.7707965970 + 0.8016015887 0.8103603125 0.7713679075 + 0.8021358848 0.8108835816 0.7719392776 + 0.8026701808 0.8114069104 0.7725105882 + 0.8032029867 0.8119258285 0.7730767131 + 0.8037356138 0.8124440908 0.7736421227 + 0.8042681813 0.8129622936 0.7742075920 + 0.8048008084 0.8134806156 0.7747730017 + 0.8053286076 0.8139951825 0.7753348947 + 0.8058556914 0.8145089746 0.7758960724 + 0.8063827753 0.8150228262 0.7764574289 + 0.8069099188 0.8155366182 0.7770186067 + 0.8074336052 0.8160470128 0.7775772214 + 0.8079562783 0.8165563941 0.7781350017 + 0.8084790707 0.8170658946 0.7786927819 + 0.8090019226 0.8175752759 0.7792506218 + 0.8095226288 0.8180813193 0.7798048258 + 0.8100423813 0.8185856938 0.7803573012 + 0.8105623126 0.8190901279 0.7809098959 + 0.8110821247 0.8195945024 0.7814623713 + 0.8115993142 0.8200960755 0.7820122838 + 0.8121144772 0.8205952048 0.7825602293 + 0.8126296997 0.8210942745 0.7831079960 + 0.8131449819 0.8215934038 0.7836558223 + 0.8136587739 0.8220912814 0.7842022181 + 0.8141704798 0.8225870728 0.7847461104 + 0.8146821260 0.8230829239 0.7852900028 + 0.8151937723 0.8235787153 0.7858338952 + 0.8157051206 0.8240739107 0.7863767743 + 0.8162146807 0.8245658278 0.7869150043 + 0.8167243004 0.8250576854 0.7874531150 + 0.8172338009 0.8255496025 0.7879912853 + 0.8177434206 0.8260415196 0.7885295153 + 0.8182494044 0.8265284896 0.7890629172 + 0.8187550902 0.8270152211 0.7895959020 + 0.8192608953 0.8275017738 0.7901288867 + 0.8197665811 0.8279885054 0.7906618714 + 0.8202685714 0.8284724951 0.7911921144 + 0.8207687140 0.8289551139 0.7917206883 + 0.8212687969 0.8294377923 0.7922493219 + 0.8217688799 0.8299204111 0.7927778959 + 0.8222674727 0.8304020762 0.7933050990 + 0.8227633834 0.8308820724 0.7938293219 + 0.8232592940 0.8313620090 0.7943534851 + 0.8237550855 0.8318418860 0.7948777080 + 0.8242509961 0.8323218822 0.7954018712 + 0.8247438073 0.8327968717 0.7959234715 + 0.8252366185 0.8332718015 0.7964450121 + 0.8257294297 0.8337466717 0.7969664931 + 0.8262221813 0.8342216015 0.7974880934 + 0.8267118931 0.8346939087 0.7980074286 + 0.8271998763 0.8351643085 0.7985252738 + 0.8276877999 0.8356347084 0.7990432978 + 0.8281757832 0.8361051083 0.7995612025 + 0.8286628127 0.8365753293 0.8000785112 + 0.8291462064 0.8370444179 0.8005927205 + 0.8296297193 0.8375133872 0.8011069894 + 0.8301131129 0.8379824162 0.8016213179 + 0.8305966258 0.8384515047 0.8021355867 + 0.8310769796 0.8389179111 0.8026489019 + 0.8315563798 0.8393831849 0.8031619191 + 0.8320357800 0.8398485780 0.8036748767 + 0.8325151801 0.8403139114 0.8041878939 + 0.8329936266 0.8407778740 0.8047001958 + 0.8334690928 0.8412373066 0.8052101731 + 0.8339444995 0.8416966200 0.8057203293 + 0.8344200253 0.8421559930 0.8062303066 + 0.8348953724 0.8426154256 0.8067402840 + 0.8353682756 0.8430727124 0.8072487116 + 0.8358402252 0.8435291052 0.8077564240 + 0.8363121152 0.8439856172 0.8082640767 + 0.8367841244 0.8444420099 0.8087717295 + 0.8372554779 0.8448981047 0.8092792034 + 0.8377242088 0.8453521729 0.8097851276 + 0.8381929994 0.8458061814 0.8102909923 + 0.8386617899 0.8462603092 0.8107969165 + 0.8391305208 0.8467143774 0.8113027811 + 0.8395975828 0.8471655250 0.8118069172 + 0.8400632739 0.8476139903 0.8123093247 + 0.8405290246 0.8480623960 0.8128117919 + 0.8409947157 0.8485109210 0.8133143187 + 0.8414604068 0.8489593863 0.8138167858 + 0.8419228196 0.8494048715 0.8143168092 + 0.8423848748 0.8498501182 0.8148164153 + 0.8428469896 0.8502953053 0.8153160214 + 0.8433091044 0.8507404923 0.8158156872 + 0.8437703252 0.8511855006 0.8163148761 + 0.8442285061 0.8516296744 0.8168122768 + 0.8446866274 0.8520739079 0.8173096180 + 0.8451448083 0.8525180817 0.8178070188 + 0.8456029892 0.8529623151 0.8183044195 + 0.8460600972 0.8534045219 0.8187999129 + 0.8465161920 0.8538445234 0.8192933798 + 0.8469722867 0.8542845249 0.8197870255 + 0.8474283814 0.8547245860 0.8202804923 + 0.8478844166 0.8551645875 0.8207740188 + 0.8483386040 0.8556007147 0.8212651014 + 0.8487920165 0.8560351133 0.8217552900 + 0.8492454290 0.8564695120 0.8222454786 + 0.8496989012 0.8569039702 0.8227357268 + 0.8501523137 0.8573384285 0.8232259154 + 0.8506020904 0.8577691913 0.8237136006 + 0.8510516286 0.8581997156 0.8242009878 + 0.8515011072 0.8586301804 0.8246884942 + 0.8519507051 0.8590605855 0.8251760006 + 0.8523998260 0.8594908714 0.8256632090 + 0.8528448939 0.8599187136 0.8261479735 + 0.8532899022 0.8603464961 0.8266327977 + 0.8537350297 0.8607742786 0.8271176219 + 0.8541800976 0.8612021208 0.8276023865 + 0.8546246290 0.8616291285 0.8280869722 + 0.8550670743 0.8620529175 0.8285707831 + 0.8555095792 0.8624767065 0.8290544748 + 0.8559520245 0.8629004955 0.8295382261 + 0.8563945293 0.8633242249 0.8300219178 + 0.8568360806 0.8637471199 0.8305050731 + 0.8572757244 0.8641673923 0.8309867978 + 0.8577153087 0.8645877838 0.8314685225 + 0.8581547737 0.8650081158 0.8319501877 + 0.8585944176 0.8654283881 0.8324319124 + 0.8590329289 0.8658478856 0.8329126835 + 0.8594689965 0.8662654161 0.8333914876 + 0.8599051237 0.8666828871 0.8338704109 + 0.8603413105 0.8671004176 0.8343492150 + 0.8607773781 0.8675178885 0.8348280191 + 0.8612130284 0.8679342270 0.8353064060 + 0.8616474867 0.8683475852 0.8357838988 + 0.8620818853 0.8687611222 0.8362613916 + 0.8625164032 0.8691744804 0.8367388844 + 0.8629509211 0.8695878983 0.8372163773 + 0.8633844852 0.8700003028 0.8376932740 + 0.8638160825 0.8704100251 0.8381686211 + 0.8642476797 0.8708196878 0.8386437893 + 0.8646792769 0.8712294102 0.8391190767 + 0.8651108742 0.8716390729 0.8395944238 + 0.8655416965 0.8720481992 0.8400691152 + 0.8659693003 0.8724551201 0.8405413032 + 0.8663967848 0.8728619218 0.8410134912 + 0.8668243885 0.8732687235 0.8414856791 + 0.8672518730 0.8736755252 0.8419578075 + 0.8676794171 0.8740822077 0.8424299955 + 0.8681045771 0.8744865060 0.8429005742 + 0.8685297966 0.8748908043 0.8433712125 + 0.8689550161 0.8752951026 0.8438417912 + 0.8693801761 0.8756992817 0.8443124890 + 0.8698053956 0.8761035800 0.8447831273 + 0.8702281117 0.8765046000 0.8452516198 + 0.8706504107 0.8769050241 0.8457198143 + 0.8710728288 0.8773053885 0.8461880088 + 0.8714951277 0.8777058125 0.8466562033 + 0.8719174862 0.8781061769 0.8471243978 + 0.8723371029 0.8785045147 0.8475905061 + 0.8727555275 0.8789016008 0.8480554223 + 0.8731737733 0.8792986870 0.8485202789 + 0.8735920787 0.8796957731 0.8489853144 + 0.8740105033 0.8800929785 0.8494501710 + 0.8744276166 0.8804891109 0.8499143720 + 0.8748430014 0.8808835745 0.8503776193 + 0.8752583861 0.8812779784 0.8508408070 + 0.8756737709 0.8816725016 0.8513038754 + 0.8760892153 0.8820670247 0.8517671227 + 0.8765044212 0.8824610710 0.8522300124 + 0.8769180179 0.8828517199 0.8526905179 + 0.8773316145 0.8832423091 0.8531510830 + 0.8777452111 0.8836328983 0.8536115885 + 0.8781588078 0.8840234280 0.8540722132 + 0.8785724044 0.8844140172 0.8545327187 + 0.8789830208 0.8848019242 0.8549907207 + 0.8793928027 0.8851888776 0.8554478288 + 0.8798025250 0.8855758905 0.8559048772 + 0.8802123070 0.8859630227 0.8563619852 + 0.8806220293 0.8863499761 0.8568190932 + 0.8810304999 0.8867359757 0.8572754264 + 0.8814368844 0.8871203065 0.8577305079 + 0.8818433285 0.8875045180 0.8581857085 + 0.8822497725 0.8878887892 0.8586407900 + 0.8826562166 0.8882731199 0.8590958714 + 0.8830626011 0.8886573911 0.8595510125 + 0.8834682703 0.8890393972 0.8600043058 + 0.8838739991 0.8894212842 0.8604574800 + 0.8842797279 0.8898031712 0.8609105945 + 0.8846853971 0.8901851177 0.8613638282 + 0.8850911260 0.8905668855 0.8618170023 + 0.8854956031 0.8909478784 0.8622695208 + 0.8858984709 0.8913276792 0.8627213240 + 0.8863015175 0.8917074800 0.8631731272 + 0.8867045045 0.8920872808 0.8636248708 + 0.8871074915 0.8924670815 0.8640766740 + 0.8875104785 0.8928470016 0.8645284772 + 0.8879091144 0.8932240009 0.8649795055 + 0.8883073926 0.8936008811 0.8654304147 + 0.8887057900 0.8939777017 0.8658813238 + 0.8891041279 0.8943545818 0.8663321733 + 0.8895024061 0.8947314024 0.8667832017 + 0.8899000287 0.8951069117 0.8672332168 + 0.8902962208 0.8954799175 0.8676818013 + 0.8906924725 0.8958529830 0.8681303263 + 0.8910887241 0.8962259889 0.8685787916 + 0.8914849162 0.8965989947 0.8690273166 + 0.8918812275 0.8969720006 0.8694759011 + 0.8922762275 0.8973435163 0.8699231148 + 0.8926709294 0.8977146149 0.8703697920 + 0.8930655122 0.8980855942 0.8708165288 + 0.8934602141 0.8984566927 0.8712632060 + 0.8938547969 0.8988276720 0.8717098832 + 0.8942492008 0.8991985917 0.8721565008 + 0.8946403265 0.8995674253 0.8726019263 + 0.8950313926 0.8999361992 0.8730471730 + 0.8954225779 0.9003049731 0.8734925985 + 0.8958137035 0.9006738067 0.8739380240 + 0.8962048292 0.9010425806 0.8743833899 + 0.8965950012 0.9014102817 0.8748276830 + 0.8969836235 0.9017760158 0.8752703071 + 0.8973723054 0.9021416903 0.8757128716 + 0.8977609277 0.9025074244 0.8761554956 + 0.8981494904 0.9028730989 0.8765981197 + 0.8985381126 0.9032387733 0.8770406246 + 0.8989257812 0.9036024809 0.8774818182 + 0.8993129730 0.9039648175 0.8779221773 + 0.8997001052 0.9043270946 0.8783624768 + 0.9000871778 0.9046893716 0.8788027763 + 0.9004744291 0.9050518274 0.8792430758 + 0.9008615017 0.9054141045 0.8796833754 + 0.9012458920 0.9057751894 0.8801223040 + 0.9016296864 0.9061359763 0.8805608749 + 0.9020134211 0.9064968824 0.8809995055 + 0.9023972154 0.9068577290 0.8814380169 + 0.9027810097 0.9072185159 0.8818765879 + 0.9031646848 0.9075793028 0.8823152184 + 0.9035456777 0.9079378843 0.8827506900 + 0.9039264917 0.9082962871 0.8831861019 + 0.9043073058 0.9086548090 0.8836215138 + 0.9046881795 0.9090132117 0.8840568066 + 0.9050689936 0.9093716741 0.8844922185 + 0.9054498076 0.9097300172 0.8849275112 + 0.9058302045 0.9100852013 0.8853601813 + 0.9062106013 0.9104403853 0.8857929111 + 0.9065908790 0.9107956290 0.8862255812 + 0.9069712758 0.9111508727 0.8866581917 + 0.9073516726 0.9115061164 0.8870909214 + 0.9077318907 0.9118611813 0.8875234127 + 0.9081099033 0.9122149944 0.8879539967 + 0.9084879756 0.9125688076 0.8883845210 + 0.9088661075 0.9129226208 0.8888149858 + 0.9092441201 0.9132763743 0.8892456293 + 0.9096221924 0.9136301875 0.8896760941 + 0.9099997878 0.9139838219 0.8901063204 + 0.9103738070 0.9143360257 0.8905333281 + 0.9107477069 0.9146881104 0.8909602761 + 0.9111216068 0.9150401950 0.8913872838 + 0.9114955068 0.9153922796 0.8918141723 + 0.9118694067 0.9157444239 0.8922411799 + 0.9122431874 0.9160963893 0.8926680088 + 0.9126154184 0.9164451957 0.8930919170 + 0.9129875898 0.9167940021 0.8935158253 + 0.9133598208 0.9171428084 0.8939396739 + 0.9137319922 0.9174916148 0.8943635821 + 0.9141042233 0.9178404212 0.8947874904 + 0.9144763947 0.9181892276 0.8952113986 + 0.9148473740 0.9185342193 0.8956335783 + 0.9152182937 0.9188787937 0.8960558176 + 0.9155892134 0.9192234874 0.8964778781 + 0.9159600735 0.9195681214 0.8969001174 + 0.9163309932 0.9199128151 0.8973221779 + 0.9167019725 0.9202573895 0.8977444172 + 0.9170697927 0.9206014276 0.8981651068 + 0.9174367785 0.9209452271 0.8985853791 + 0.9178038836 0.9212889075 0.8990057111 + 0.9181709290 0.9216327071 0.8994259834 + 0.9185379148 0.9219765067 0.8998463750 + 0.9189050198 0.9223201871 0.9002667069 + 0.9192699194 0.9226629734 0.9006865025 + 0.9196335077 0.9230049849 0.9011059999 + 0.9199969769 0.9233471155 0.9015253782 + 0.9203606248 0.9236891270 0.9019448757 + 0.9207240939 0.9240310788 0.9023643732 + 0.9210876226 0.9243732095 0.9027838111 + 0.9214507937 0.9247142076 0.9032027721 + 0.9218133092 0.9250528812 0.9036207795 + 0.9221758246 0.9253916144 0.9040387273 + 0.9225382209 0.9257302880 0.9044566751 + 0.9229006767 0.9260690212 0.9048746824 + 0.9232631922 0.9264076948 0.9052925706 + 0.9236255884 0.9267463088 0.9057105780 + 0.9239851832 0.9270828962 0.9061275721 + 0.9243447781 0.9274194837 0.9065446854 + 0.9247043729 0.9277560115 0.9069616795 + 0.9250640273 0.9280925989 0.9073787928 + 0.9254236221 0.9284291863 0.9077957869 + 0.9257832170 0.9287657142 0.9082127810 + 0.9261407256 0.9291017056 0.9086294770 + 0.9264971018 0.9294372797 0.9090461135 + 0.9268534780 0.9297729135 0.9094625711 + 0.9272099137 0.9301084876 0.9098792076 + 0.9275662899 0.9304441214 0.9102957249 + 0.9279227257 0.9307796955 0.9107123017 + 0.9282786846 0.9311146736 0.9111282825 + 0.9286336899 0.9314478040 0.9115430117 + 0.9289886951 0.9317808747 0.9119576216 + 0.9293437004 0.9321138859 0.9123722911 + 0.9296985865 0.9324470162 0.9127869010 + 0.9300535917 0.9327800870 0.9132015705 + 0.9304085970 0.9331132174 0.9136161804 + 0.9307621717 0.9334436059 0.9140297771 + 0.9311155081 0.9337733984 0.9144430757 + 0.9314687252 0.9341030717 0.9148563743 + 0.9318218827 0.9344329238 0.9152696729 + 0.9321752191 0.9347625971 0.9156829715 + 0.9325283766 0.9350923896 0.9160963297 + 0.9328805208 0.9354220033 0.9165095091 + 0.9332295060 0.9357516170 0.9169226885 + 0.9335784912 0.9360811114 0.9173358083 + 0.9339274764 0.9364106059 0.9177489877 + 0.9342765212 0.9367401004 0.9181622267 + 0.9346253872 0.9370697141 0.9185752869 + 0.9349743724 0.9373992085 0.9189885259 + 0.9353216887 0.9377279878 0.9194009900 + 0.9356681705 0.9380565286 0.9198130965 + 0.9360147715 0.9383850098 0.9202253222 + 0.9363613129 0.9387134910 0.9206374884 + 0.9367079139 0.9390419722 0.9210495949 + 0.9370543957 0.9393705130 0.9214618206 + 0.9374008775 0.9396988153 0.9218738079 + 0.9377468228 0.9400240183 0.9222841263 + 0.9380925894 0.9403492212 0.9226943851 + 0.9384384751 0.9406743050 0.9231047034 + 0.9387843013 0.9409995079 0.9235150218 + 0.9391301870 0.9413247108 0.9239252806 + 0.9394760728 0.9416499138 0.9243355989 + 0.9398207068 0.9419735074 0.9247456193 + 0.9401633739 0.9422945976 0.9251552224 + 0.9405061007 0.9426156878 0.9255648851 + 0.9408488274 0.9429367781 0.9259744883 + 0.9411916137 0.9432579875 0.9263840914 + 0.9415342808 0.9435790777 0.9267938137 + 0.9418770075 0.9439002275 0.9272034168 + 0.9422174096 0.9442206025 0.9276124835 + 0.9425566196 0.9445406795 0.9280213118 + 0.9428958297 0.9448608160 0.9284300804 + 0.9432349801 0.9451808929 0.9288390279 + 0.9435741901 0.9455009103 0.9292477965 + 0.9439134002 0.9458209872 0.9296566248 + 0.9442526102 0.9461411238 0.9300655127 + 0.9445902705 0.9464595914 0.9304733276 + 0.9449278116 0.9467778802 0.9308810234 + 0.9452651739 0.9470962286 0.9312887192 + 0.9456027150 0.9474143982 0.9316964149 + 0.9459400773 0.9477326870 0.9321041107 + 0.9462776184 0.9480509758 0.9325118065 + 0.9466149807 0.9483692050 0.9329195023 + 0.9469503760 0.9486842155 0.9333260059 + 0.9472857118 0.9489991069 0.9337323904 + 0.9476211071 0.9493141174 0.9341388941 + 0.9479565024 0.9496291280 0.9345452785 + 0.9482918978 0.9499440193 0.9349517822 + 0.9486272931 0.9502589703 0.9353582263 + 0.9489622712 0.9505736828 0.9357644916 + 0.9492946267 0.9508864880 0.9361696243 + 0.9496268034 0.9511991739 0.9365745783 + 0.9499590993 0.9515119791 0.9369797111 + 0.9502912760 0.9518247843 0.9373847842 + 0.9506235719 0.9521374702 0.9377897978 + 0.9509558082 0.9524502754 0.9381948709 + 0.9512878060 0.9527629018 0.9385995269 + 0.9516180754 0.9530745149 0.9390019178 + 0.9519485235 0.9533861876 0.9394041896 + 0.9522787929 0.9536978006 0.9398065209 + 0.9526091218 0.9540094733 0.9402087927 + 0.9529393911 0.9543210864 0.9406111836 + 0.9532697797 0.9546328187 0.9410135150 + 0.9535998702 0.9549441934 0.9414151907 + 0.9539285898 0.9552533031 0.9418125749 + 0.9542574286 0.9555622935 0.9422100186 + 0.9545860887 0.9558714032 0.9426074028 + 0.9549148083 0.9561805129 0.9430047870 + 0.9552435875 0.9564896226 0.9434021711 + 0.9555723071 0.9567986727 0.9437994957 + 0.9559007883 0.9571076035 0.9441967010 + 0.9562236071 0.9574112892 0.9445887208 + 0.9565463066 0.9577149749 0.9449806213 + 0.9568691254 0.9580187798 0.9453725219 + 0.9571918845 0.9583225250 0.9457644224 + 0.9575145841 0.9586262107 0.9461563230 + 0.9578374028 0.9589298964 0.9465482235 + 0.9581602216 0.9592335820 0.9469401240 + 0.9584769011 0.9595324993 0.9473283291 + 0.9587929249 0.9598308802 0.9477159977 + 0.9591090083 0.9601292014 0.9481037259 + 0.9594249725 0.9604275823 0.9484915137 + 0.9597409964 0.9607260227 0.9488791823 + 0.9600570798 0.9610242844 0.9492670298 + 0.9603731036 0.9613227248 0.9496546984 + 0.9606860280 0.9616187215 0.9500409961 + 0.9609975219 0.9619138241 0.9504266977 + 0.9613090158 0.9622088075 0.9508125186 + 0.9616205096 0.9625037909 0.9511982203 + 0.9619320035 0.9627988935 0.9515839219 + 0.9622434974 0.9630938768 0.9519696236 + 0.9625549912 0.9633889198 0.9523553848 + 0.9628651738 0.9636827707 0.9527397752 + 0.9631738067 0.9639751911 0.9531226158 + 0.9634823203 0.9642676115 0.9535053968 + 0.9637908936 0.9645599127 0.9538881183 + 0.9640994072 0.9648522735 0.9542708993 + 0.9644079804 0.9651446939 0.9546536803 + 0.9647164941 0.9654371142 0.9550365210 + 0.9650247097 0.9657291174 0.9554188848 + 0.9653298855 0.9660187960 0.9557983279 + 0.9656351805 0.9663084149 0.9561777711 + 0.9659404755 0.9665980935 0.9565572739 + 0.9662457705 0.9668877721 0.9569367170 + 0.9665510058 0.9671773911 0.9573162198 + 0.9668563008 0.9674671292 0.9576957226 + 0.9671615958 0.9677568078 0.9580751061 + 0.9674646854 0.9680448771 0.9584522843 + 0.9677671194 0.9683324099 0.9588286877 + 0.9680693746 0.9686200023 0.9592050910 + 0.9683718085 0.9689074755 0.9595814943 + 0.9686741829 0.9691951275 0.9599578977 + 0.9689764977 0.9694827199 0.9603341818 + 0.9692788720 0.9697701931 0.9607105851 + 0.9695801735 0.9700570107 0.9610859156 + 0.9698789120 0.9703419209 0.9614585042 + 0.9701775908 0.9706267715 0.9618310928 + 0.9704763889 0.9709116817 0.9622036815 + 0.9707751274 0.9711965919 0.9625763297 + 0.9710738063 0.9714813828 0.9629489183 + 0.9713726044 0.9717662930 0.9633215070 + 0.9716712832 0.9720512033 0.9636940956 + 0.9719662070 0.9723331928 0.9640635252 + 0.9722601175 0.9726145267 0.9644321799 + 0.9725540876 0.9728958011 0.9648008943 + 0.9728481174 0.9731770754 0.9651694894 + 0.9731420279 0.9734582901 0.9655382037 + 0.9734359980 0.9737396240 0.9659067988 + 0.9737300277 0.9740208983 0.9662755132 + 0.9740229845 0.9743015170 0.9666432738 + 0.9743129015 0.9745799899 0.9670084119 + 0.9746028185 0.9748585820 0.9673733711 + 0.9748927951 0.9751371145 0.9677385092 + 0.9751827121 0.9754155874 0.9681035280 + 0.9754726887 0.9756941199 0.9684686065 + 0.9757626057 0.9759727120 0.9688336253 + 0.9760525823 0.9762511849 0.9691987038 + 0.9763398170 0.9765279293 0.9695615172 + 0.9766253829 0.9768033028 0.9699230194 + 0.9769108891 0.9770787954 0.9702845216 + 0.9771965146 0.9773542285 0.9706460238 + 0.9774820209 0.9776297212 0.9710075259 + 0.9777675867 0.9779050946 0.9713690281 + 0.9780532122 0.9781805873 0.9717304707 + 0.9783387184 0.9784560204 0.9720919132 + 0.9786192775 0.9787276983 0.9724497199 + 0.9788995981 0.9789990783 0.9728072286 + 0.9791797996 0.9792703986 0.9731646776 + 0.9794600010 0.9795417786 0.9735221267 + 0.9797403216 0.9798130989 0.9738795757 + 0.9800205231 0.9800844789 0.9742370844 + 0.9803007245 0.9803557992 0.9745944738 + 0.9805799723 0.9806264043 0.9749512076 + 0.9808548093 0.9808933139 0.9753037095 + 0.9811295867 0.9811602235 0.9756562710 + 0.9814044237 0.9814270735 0.9760088921 + 0.9816792011 0.9816939831 0.9763615131 + 0.9819539785 0.9819608927 0.9767140150 + 0.9822288752 0.9822278023 0.9770665765 + 0.9825037122 0.9824947119 0.9774191976 + 0.9827765226 0.9827601910 0.9777697921 + 0.9830456972 0.9830228090 0.9781169295 + 0.9833148718 0.9832854867 0.9784640074 + 0.9835842252 0.9835482240 0.9788110256 + 0.9838533998 0.9838109016 0.9791581035 + 0.9841225743 0.9840735197 0.9795051813 + 0.9843918085 0.9843361974 0.9798521996 + 0.9846609831 0.9845988750 0.9801992774 + 0.9849274158 0.9848592281 0.9805430770 + 0.9851905704 0.9851167798 0.9808833003 + 0.9854537249 0.9853743911 0.9812235236 + 0.9857168794 0.9856320024 0.9815636277 + 0.9859799743 0.9858896136 0.9819037914 + 0.9862431884 0.9861472249 0.9822440147 + 0.9865062833 0.9864048958 0.9825841188 + 0.9867694974 0.9866625071 0.9829242826 + 0.9870293140 0.9869173169 0.9832602739 + 0.9872860909 0.9871696234 0.9835925102 + 0.9875429273 0.9874218702 0.9839246869 + 0.9877997041 0.9876741767 0.9842569232 + 0.9880564809 0.9879264832 0.9845890999 + 0.9883133173 0.9881787896 0.9849212766 + 0.9885700941 0.9884310961 0.9852535129 + 0.9888268709 0.9886834025 0.9855856895 + 0.9890797734 0.9889330268 0.9859133959 + 0.9893288016 0.9891800284 0.9862366915 + 0.9895778894 0.9894269109 0.9865599871 + 0.9898269176 0.9896739125 0.9868832827 + 0.9900760055 0.9899207950 0.9872065783 + 0.9903249741 0.9901676774 0.9875298738 + 0.9905740023 0.9904146791 0.9878532290 + 0.9908230901 0.9906616211 0.9881765246 + 0.9910683036 0.9909055829 0.9884948134 + 0.9913083911 0.9911454916 0.9888063073 + 0.9915484786 0.9913855195 0.9891179204 + 0.9917885065 0.9916254282 0.9894294143 + 0.9920285940 0.9918652773 0.9897409081 + 0.9922686219 0.9921053052 0.9900524020 + 0.9925087094 0.9923452139 0.9903638959 + 0.9927487969 0.9925851822 0.9906755090 + 0.9929866791 0.9928228855 0.9909834266 + 0.9932188988 0.9930546284 0.9912818074 + 0.9934511185 0.9932863712 0.9915801883 + 0.9936832786 0.9935181141 0.9918786883 + 0.9939156175 0.9937499166 0.9921771288 + 0.9941477776 0.9939817190 0.9924755096 + 0.9943799973 0.9942134023 0.9927738905 + 0.9946122169 0.9944452047 0.9930723906 + 0.9948437810 0.9946765900 0.9933699965 + 0.9950650930 0.9949020743 0.9936543703 + 0.9952864051 0.9951274991 0.9939388037 + 0.9955077171 0.9953529835 0.9942231178 + 0.9957290292 0.9955784082 0.9945074916 + 0.9959502816 0.9958038926 0.9947919250 + 0.9961715937 0.9960293770 0.9950762987 + 0.9963929057 0.9962548018 0.9953606725 + 0.9966142178 0.9964802861 0.9956451058 + 0.9968237877 0.9966976047 0.9959148765 + 0.9970299006 0.9969125986 0.9961804748 + 0.9972360730 0.9971275926 0.9964460731 + 0.9974421859 0.9973425865 0.9967116117 + 0.9976484179 0.9975575209 0.9969772100 + 0.9978544712 0.9977725148 0.9972428083 + 0.9980607033 0.9979875088 0.9975084066 + 0.9982668161 0.9982025027 0.9977738857 + 0.9984667897 0.9984105825 0.9980313182 + 0.9986584783 0.9986093044 0.9982774258 + 0.9988501072 0.9988079071 0.9985234737 + 0.9990417957 0.9990066290 0.9987695813 + 0.9992334247 0.9992052913 0.9990156293 + 0.9994251132 0.9994040132 0.9992616773 + 0.9996166825 0.9996026158 0.9995077848 + 0.9998083711 0.9998012781 0.9997538924 + 1.0000000000 1.0000000000 1.0000000000 +} diff --git a/rpplugins/color_correction/resources/film_luts_raw/agfa_agfacolor_optima_ii_100.spi1d b/rpplugins/color_correction/resources/film_luts_raw/agfa_agfacolor_optima_ii_100.spi1d new file mode 100644 index 0000000..8a56fcf --- /dev/null +++ b/rpplugins/color_correction/resources/film_luts_raw/agfa_agfacolor_optima_ii_100.spi1d @@ -0,0 +1,1030 @@ +Version 1 +From 0.0 1.0 +Length 1024 +Components 3 +{ + 0.0000000000 0.0000000000 0.0000000000 + 0.0076661762 0.0083268499 0.0068440801 + 0.0158262700 0.0170417801 0.0131509099 + 0.0232411809 0.0250322502 0.0190004501 + 0.0300489496 0.0323281400 0.0244449992 + 0.0363852791 0.0390635394 0.0295583308 + 0.0423460715 0.0453425013 0.0343772098 + 0.0479932986 0.0512349084 0.0389431007 + 0.0533834286 0.0567868613 0.0432897806 + 0.0585362613 0.0620452613 0.0474547893 + 0.0634827465 0.0670664310 0.0514379889 + 0.0682476535 0.0719086230 0.0552622713 + 0.0728643686 0.0766109228 0.0590022616 + 0.0773498490 0.0812185779 0.0626629591 + 0.0817248896 0.0857366771 0.0662265718 + 0.0860022604 0.0901816636 0.0696830973 + 0.0901876912 0.0945459083 0.0730567127 + 0.0942838192 0.0988429263 0.0763788819 + 0.0983011201 0.1030735970 0.0796598792 + 0.1022287980 0.1072389036 0.0828902796 + 0.1060905010 0.1113395020 0.0860634297 + 0.1098807007 0.1153889000 0.0891731530 + 0.1136023998 0.1193716973 0.0922177732 + 0.1172552034 0.1232964024 0.0952064171 + 0.1208416000 0.1271591038 0.0981551483 + 0.1243667975 0.1309625953 0.1010731980 + 0.1278326958 0.1347209960 0.1039592028 + 0.1312370002 0.1384246945 0.1068119034 + 0.1345919073 0.1420657933 0.1096345037 + 0.1378999949 0.1456594020 0.1124313995 + 0.1411581933 0.1492089927 0.1151997000 + 0.1443776041 0.1527009010 0.1179367006 + 0.1475483030 0.1561467052 0.1206402034 + 0.1506752074 0.1595402956 0.1233116984 + 0.1537552029 0.1628801972 0.1259557009 + 0.1567965001 0.1661709994 0.1285720021 + 0.1598031074 0.1694162935 0.1311601996 + 0.1627652049 0.1726270020 0.1337202936 + 0.1656907946 0.1757915020 0.1362521052 + 0.1685829014 0.1789050996 0.1387566030 + 0.1714359969 0.1819735020 0.1412398964 + 0.1742600948 0.1850046962 0.1437025964 + 0.1770537049 0.1879996955 0.1461455971 + 0.1798166037 0.1909551024 0.1485693008 + 0.1825578958 0.1938706934 0.1509743035 + 0.1852674037 0.1967559010 0.1533614993 + 0.1879525036 0.1996030957 0.1557313949 + 0.1906042993 0.2024182975 0.1580837965 + 0.1932311952 0.2052014023 0.1604201049 + 0.1958318949 0.2079581022 0.1627393067 + 0.1984055936 0.2106810957 0.1650432050 + 0.2009532005 0.2133824974 0.1673322022 + 0.2034747005 0.2160581946 0.1696034074 + 0.2059706002 0.2187004983 0.1718567014 + 0.2084430009 0.2213200927 0.1740909964 + 0.2108965069 0.2239086032 0.1763089001 + 0.2133263052 0.2264758050 0.1785116047 + 0.2157393992 0.2290169001 0.1806990951 + 0.2181292027 0.2315327972 0.1828715056 + 0.2205027044 0.2340238988 0.1850311011 + 0.2228585035 0.2364936024 0.1871781945 + 0.2251935005 0.2389385998 0.1893118024 + 0.2275121957 0.2413554937 0.1914346963 + 0.2298126966 0.2437552065 0.1935469061 + 0.2320972979 0.2461318970 0.1956477016 + 0.2343686968 0.2484831065 0.1977396011 + 0.2366248071 0.2508153021 0.1998216063 + 0.2388661057 0.2531288862 0.2018945962 + 0.2410929054 0.2554250956 0.2039602995 + 0.2433024943 0.2577019930 0.2060160935 + 0.2454963028 0.2599579096 0.2080630958 + 0.2476740032 0.2621991932 0.2100999057 + 0.2498372942 0.2644275129 0.2121268064 + 0.2519871891 0.2666364014 0.2141437978 + 0.2541207969 0.2688263953 0.2161484957 + 0.2562352121 0.2710013986 0.2181435972 + 0.2583388984 0.2731583118 0.2201271951 + 0.2604309916 0.2752990127 0.2221024036 + 0.2625060081 0.2774248123 0.2240664065 + 0.2645739019 0.2795382142 0.2260230929 + 0.2666332126 0.2816390097 0.2279690057 + 0.2686808109 0.2837243974 0.2299083024 + 0.2707110047 0.2857916951 0.2318374068 + 0.2727304995 0.2878476977 0.2337605953 + 0.2747409046 0.2898918092 0.2356743068 + 0.2767409086 0.2919228971 0.2375825942 + 0.2787257135 0.2939389050 0.2394821942 + 0.2807008028 0.2959417999 0.2413766980 + 0.2826663852 0.2979333103 0.2432633042 + 0.2846207917 0.2999132872 0.2451453060 + 0.2865644097 0.3018836081 0.2470199019 + 0.2884986103 0.3038400114 0.2488902956 + 0.2904250026 0.3057815135 0.2507540882 + 0.2923448086 0.3077118099 0.2526113987 + 0.2942551076 0.3096336126 0.2544620037 + 0.2961547077 0.3115448952 0.2563053966 + 0.2980456948 0.3134449124 0.2581430972 + 0.2999280095 0.3153319061 0.2599739134 + 0.3018029034 0.3172087073 0.2617988884 + 0.3036679029 0.3190751076 0.2636143863 + 0.3055250049 0.3209312856 0.2654233873 + 0.3073746860 0.3227779865 0.2672255039 + 0.3092148006 0.3246138990 0.2690199912 + 0.3110457957 0.3264397979 0.2708095908 + 0.3128677905 0.3282575011 0.2725906968 + 0.3146800101 0.3300665915 0.2743658125 + 0.3164839149 0.3318657875 0.2761324048 + 0.3182795942 0.3336552978 0.2778904140 + 0.3200652003 0.3354372978 0.2796432972 + 0.3218409121 0.3372116983 0.2813872993 + 0.3236100078 0.3389771879 0.2831256986 + 0.3253748119 0.3407320082 0.2848586142 + 0.3271335959 0.3424785137 0.2865825891 + 0.3288846016 0.3442190886 0.2883006930 + 0.3306263983 0.3459519148 0.2900108993 + 0.3323577940 0.3476763070 0.2917132080 + 0.3340801001 0.3493919075 0.2934105098 + 0.3357945085 0.3511008918 0.2951011062 + 0.3375023901 0.3528040051 0.2967849970 + 0.3392041922 0.3545002043 0.2984645963 + 0.3408981860 0.3561894000 0.3001382947 + 0.3425840139 0.3578724861 0.3018057048 + 0.3442628086 0.3595485985 0.3034670949 + 0.3459351063 0.3612180948 0.3051221967 + 0.3476001024 0.3628816009 0.3067719936 + 0.3492591083 0.3645390868 0.3084169924 + 0.3509126008 0.3661913872 0.3100563884 + 0.3525592089 0.3678377867 0.3116889000 + 0.3541980982 0.3694776893 0.3133162856 + 0.3558301926 0.3711101115 0.3149392903 + 0.3574565947 0.3727348149 0.3165563047 + 0.3590759039 0.3743531108 0.3181675971 + 0.3606899083 0.3759661019 0.3197731972 + 0.3622973859 0.3775736094 0.3213737905 + 0.3638975024 0.3791748881 0.3229694963 + 0.3654907048 0.3807713985 0.3245606124 + 0.3670778871 0.3823625147 0.3261463046 + 0.3686599135 0.3839488924 0.3277261853 + 0.3702372015 0.3855310977 0.3293007910 + 0.3718093038 0.3871083856 0.3308694959 + 0.3733766973 0.3886804879 0.3324309886 + 0.3749383092 0.3902452886 0.3339884877 + 0.3764936924 0.3918035924 0.3355414867 + 0.3780421019 0.3933547139 0.3370898068 + 0.3795835972 0.3948993087 0.3386338055 + 0.3811194897 0.3964386880 0.3401749134 + 0.3826521933 0.3979738951 0.3417122960 + 0.3841798007 0.3995029926 0.3432452977 + 0.3857024908 0.4010264874 0.3447737098 + 0.3872196972 0.4025439918 0.3462958038 + 0.3887315094 0.4040569961 0.3478113115 + 0.3902386129 0.4055672884 0.3493227065 + 0.3917382061 0.4070734084 0.3508295119 + 0.3932329118 0.4085750878 0.3523303866 + 0.3947235942 0.4100722969 0.3538272977 + 0.3962103128 0.4115647078 0.3553214967 + 0.3976925015 0.4130522907 0.3568125963 + 0.3991701007 0.4145320952 0.3582983017 + 0.4006435871 0.4160074890 0.3597793877 + 0.4021126926 0.4174784124 0.3612557054 + 0.4035769105 0.4189445972 0.3627254069 + 0.4050329924 0.4204039872 0.3641889989 + 0.4064843059 0.4218592048 0.3656494021 + 0.4079307020 0.4233103096 0.3671061099 + 0.4093720019 0.4247572124 0.3685575128 + 0.4108068049 0.4261992872 0.3700045943 + 0.4122380912 0.4276376069 0.3714494109 + 0.4136658907 0.4290730059 0.3728919923 + 0.4150888920 0.4305058122 0.3743301034 + 0.4165056050 0.4319339991 0.3757638931 + 0.4179174900 0.4333589077 0.3771938980 + 0.4193247855 0.4347805977 0.3786191940 + 0.4207271934 0.4361965060 0.3800374866 + 0.4221262932 0.4376091063 0.3814533055 + 0.4235219955 0.4390187860 0.3828668892 + 0.4249120951 0.4404245913 0.3842754960 + 0.4262982905 0.4418255091 0.3856791854 + 0.4276815057 0.4432229102 0.3870786130 + 0.4290600121 0.4446159899 0.3884716928 + 0.4304330051 0.4460026920 0.3898597956 + 0.4318026900 0.4473862946 0.3912445009 + 0.4331685901 0.4487664998 0.3926242888 + 0.4345290065 0.4501408041 0.3940002024 + 0.4358857870 0.4515124857 0.3953734040 + 0.4372372925 0.4528811872 0.3967424929 + 0.4385837018 0.4542450011 0.3981088102 + 0.4399270117 0.4556061029 0.3994731903 + 0.4412651956 0.4569629133 0.4008344114 + 0.4425975978 0.4583143890 0.4021924138 + 0.4439268112 0.4596636891 0.4035479128 + 0.4452503920 0.4610106945 0.4048978090 + 0.4465709925 0.4623551965 0.4062455893 + 0.4478893876 0.4636982977 0.4075908959 + 0.4492019117 0.4650372863 0.4089311063 + 0.4505116045 0.4663740098 0.4102692008 + 0.4518170953 0.4677081108 0.4116033912 + 0.4531182945 0.4690375030 0.4129329026 + 0.4544177055 0.4703648090 0.4142597914 + 0.4557136893 0.4716871977 0.4155794978 + 0.4570071995 0.4730058014 0.4168972969 + 0.4582982063 0.4743215144 0.4182122946 + 0.4595845044 0.4756304026 0.4195236862 + 0.4608688056 0.4769366980 0.4208334088 + 0.4621477127 0.4782372117 0.4221383929 + 0.4634240866 0.4795337915 0.4234414995 + 0.4646978974 0.4808278084 0.4247420132 + 0.4659669995 0.4821158051 0.4260379970 + 0.4672344029 0.4834016860 0.4273321033 + 0.4684959054 0.4846813977 0.4286206067 + 0.4697546959 0.4859575927 0.4299075007 + 0.4710089862 0.4872294962 0.4311901927 + 0.4722594917 0.4884983897 0.4324694872 + 0.4735080004 0.4897660017 0.4337458909 + 0.4747509062 0.4910294116 0.4350179136 + 0.4759922028 0.4922915101 0.4362885952 + 0.4772273898 0.4935492873 0.4375523031 + 0.4784607887 0.4948048890 0.4388141930 + 0.4796907008 0.4960573018 0.4400705993 + 0.4809170961 0.4973073006 0.4413250089 + 0.4821406901 0.4985556006 0.4425770938 + 0.4833607972 0.4998002946 0.4438262880 + 0.4845795929 0.5010439754 0.4450738132 + 0.4857935905 0.5022826791 0.4463163912 + 0.4870069027 0.5035204291 0.4475578070 + 0.4882164896 0.5047531128 0.4487918913 + 0.4894252121 0.5059841275 0.4500248134 + 0.4906300902 0.5072104931 0.4512509108 + 0.4918332100 0.5084347725 0.4524757862 + 0.4930329919 0.5096561909 0.4536970854 + 0.4942300022 0.5108749270 0.4549165070 + 0.4954235852 0.5120911002 0.4561327994 + 0.4966148138 0.5133035183 0.4573467076 + 0.4978038967 0.5145136714 0.4585579038 + 0.4989897013 0.5157194734 0.4597668052 + 0.5001736879 0.5169236064 0.4609735906 + 0.5013538003 0.5181236863 0.4621770084 + 0.5025321245 0.5193228126 0.4633781016 + 0.5037057996 0.5205178857 0.4645760059 + 0.5048779845 0.5217121840 0.4657720923 + 0.5060449243 0.5229014754 0.4669648111 + 0.5072103143 0.5240899920 0.4681558907 + 0.5083714128 0.5252736807 0.4693433940 + 0.5095313787 0.5264567137 0.4705292881 + 0.5106868744 0.5276340246 0.4717121124 + 0.5118411779 0.5288106203 0.4728935957 + 0.5129907131 0.5299817920 0.4740710855 + 0.5141386986 0.5311521292 0.4752467871 + 0.5152817965 0.5323163867 0.4764178097 + 0.5164232850 0.5334795713 0.4775865078 + 0.5175597072 0.5346372724 0.4787499011 + 0.5186939240 0.5357934833 0.4799101949 + 0.5198233724 0.5369442105 0.4810669124 + 0.5209500790 0.5380924940 0.4822207987 + 0.5220733881 0.5392372012 0.4833728075 + 0.5231938958 0.5403798223 0.4845224917 + 0.5243116021 0.5415189862 0.4856700897 + 0.5254257917 0.5426552296 0.4868142903 + 0.5265377760 0.5437887907 0.4879572093 + 0.5276451111 0.5449187160 0.4890958965 + 0.5287510753 0.5460466743 0.4902341068 + 0.5298516154 0.5471696258 0.4913682044 + 0.5309517980 0.5482918024 0.4925023019 + 0.5320447087 0.5494078994 0.4936308861 + 0.5331376195 0.5505239964 0.4947592020 + 0.5342239141 0.5516330004 0.4958822131 + 0.5353093743 0.5527415872 0.4970037043 + 0.5363904834 0.5538460016 0.4981215894 + 0.5374696255 0.5549491048 0.4992372096 + 0.5385463834 0.5560489893 0.5003510118 + 0.5396206975 0.5571463108 0.5014619827 + 0.5406937003 0.5582417250 0.5025722980 + 0.5417628884 0.5593330860 0.5036795735 + 0.5428320169 0.5604240894 0.5047869086 + 0.5438956022 0.5615094900 0.5058897138 + 0.5449593067 0.5625947714 0.5069922209 + 0.5460199714 0.5636752248 0.5080906749 + 0.5470796227 0.5647544265 0.5091872215 + 0.5481380224 0.5658313036 0.5102818012 + 0.5491948128 0.5669060946 0.5113732815 + 0.5502511859 0.5679798722 0.5124642849 + 0.5513052940 0.5690498948 0.5135501027 + 0.5523592830 0.5701199174 0.5146359205 + 0.5534104109 0.5711855888 0.5157186985 + 0.5544610023 0.5722507834 0.5168005228 + 0.5555099249 0.5733129978 0.5178806782 + 0.5565569997 0.5743728876 0.5189586282 + 0.5576034784 0.5754317045 0.5200362802 + 0.5586465001 0.5764862895 0.5211094022 + 0.5596894026 0.5775408745 0.5221825242 + 0.5607293248 0.5785906911 0.5232514739 + 0.5617681146 0.5796394944 0.5243185163 + 0.5628052950 0.5806865096 0.5253840089 + 0.5638393164 0.5817313194 0.5264452100 + 0.5648733974 0.5827760100 0.5275064707 + 0.5659030080 0.5838158727 0.5285636187 + 0.5669323206 0.5848557949 0.5296201110 + 0.5679587722 0.5858927965 0.5306740999 + 0.5689827204 0.5869277716 0.5317248702 + 0.5700063109 0.5879620910 0.5327755809 + 0.5710247755 0.5889919996 0.5338218212 + 0.5720431805 0.5900217891 0.5348678231 + 0.5730581880 0.5910484195 0.5359107256 + 0.5740705729 0.5920730829 0.5369504094 + 0.5750827193 0.5930969715 0.5379900932 + 0.5760906935 0.5941162705 0.5390231013 + 0.5770987868 0.5951356888 0.5400561094 + 0.5781041980 0.5961515903 0.5410866141 + 0.5791074038 0.5971654058 0.5421143770 + 0.5801107287 0.5981786847 0.5431421995 + 0.5811091065 0.5991874933 0.5441660285 + 0.5821076035 0.6001963019 0.5451896191 + 0.5831037164 0.6012020707 0.5462111831 + 0.5840969086 0.6022052765 0.5472295880 + 0.5850901008 0.6032084823 0.5482478738 + 0.5860803127 0.6042070985 0.5492616296 + 0.5870699286 0.6052052975 0.5502738953 + 0.5880584717 0.6062015891 0.5512850285 + 0.5890443921 0.6071943045 0.5522903204 + 0.5900301933 0.6081869006 0.5532956719 + 0.5910136104 0.6091759801 0.5542973876 + 0.5919954777 0.6101636887 0.5552961826 + 0.5929774046 0.6111510992 0.5562950969 + 0.5939552784 0.6121332049 0.5572906733 + 0.5949330926 0.6131153107 0.5582858920 + 0.5959095955 0.6140955091 0.5592799187 + 0.5968831778 0.6150727272 0.5602700710 + 0.5978568196 0.6160498857 0.5612602830 + 0.5988277197 0.6170232296 0.5622476935 + 0.5997968912 0.6179949045 0.5632326007 + 0.6007661223 0.6189665794 0.5642176270 + 0.6017311215 0.6199334264 0.5651969910 + 0.6026958227 0.6209002137 0.5661752820 + 0.6036596894 0.6218655705 0.5671530962 + 0.6046196222 0.6228268743 0.5681259036 + 0.6055796146 0.6237881780 0.5690985918 + 0.6065375805 0.6247472167 0.5700702071 + 0.6074926853 0.6257035732 0.5710396171 + 0.6084479094 0.6266599894 0.5720090270 + 0.6093999147 0.6276127100 0.5729761720 + 0.6103500724 0.6285637021 0.5739415884 + 0.6113001704 0.6295146942 0.5749070048 + 0.6122449040 0.6304615140 0.5758687854 + 0.6131883860 0.6314076781 0.5768293738 + 0.6141319871 0.6323534846 0.5777900219 + 0.6150689125 0.6332944036 0.5787457228 + 0.6160058975 0.6342352033 0.5797008276 + 0.6169418097 0.6351751089 0.5806555748 + 0.6178718805 0.6361111999 0.5816044807 + 0.6188020110 0.6370472908 0.5825533867 + 0.6197304130 0.6379815936 0.5835011005 + 0.6206536889 0.6389123797 0.5844430923 + 0.6215770841 0.6398432255 0.5853852034 + 0.6224973202 0.6407719851 0.5863258839 + 0.6234118938 0.6416980028 0.5872634053 + 0.6243265271 0.6426240802 0.5882009268 + 0.6252374053 0.6435475945 0.5891368985 + 0.6261436939 0.6444684267 0.5900704265 + 0.6270499825 0.6453893185 0.5910037756 + 0.6279519796 0.6463075876 0.5919355154 + 0.6288496852 0.6472237706 0.5928648710 + 0.6297472715 0.6481400132 0.5937942266 + 0.6306408048 0.6490532160 0.5947210789 + 0.6315302253 0.6499642134 0.5956451297 + 0.6324197054 0.6508752108 0.5965691209 + 0.6333047748 0.6517835855 0.5974907279 + 0.6341857910 0.6526899934 0.5984091759 + 0.6350668073 0.6535964012 0.5993278027 + 0.6359438896 0.6545000076 0.6002436280 + 0.6368169188 0.6554012895 0.6011555791 + 0.6376898289 0.6563025713 0.6020675898 + 0.6385591030 0.6572015882 0.6029770970 + 0.6394237876 0.6580982804 0.6038823724 + 0.6402884722 0.6589950919 0.6047877073 + 0.6411507130 0.6598895788 0.6056910157 + 0.6420087814 0.6607813239 0.6065897942 + 0.6428670287 0.6616728902 0.6074885130 + 0.6437233090 0.6625624895 0.6083862782 + 0.6445748210 0.6634479761 0.6092801094 + 0.6454262733 0.6643334031 0.6101740003 + 0.6462768912 0.6652175188 0.6110675931 + 0.6471220255 0.6660966277 0.6119573116 + 0.6479671001 0.6669756770 0.6128469110 + 0.6488121748 0.6678544283 0.6137366295 + 0.6496508718 0.6687275171 0.6146218181 + 0.6504895091 0.6696006060 0.6155067086 + 0.6513282061 0.6704736948 0.6163915992 + 0.6521630287 0.6713413000 0.6172724962 + 0.6529970765 0.6722081900 0.6181520224 + 0.6538311243 0.6730750799 0.6190316081 + 0.6546623707 0.6739377975 0.6199085712 + 0.6554920077 0.6747987270 0.6207835078 + 0.6563215852 0.6756594777 0.6216583848 + 0.6571496129 0.6765179038 0.6225318909 + 0.6579748988 0.6773731709 0.6234022975 + 0.6588003039 0.6782284975 0.6242725849 + 0.6596251130 0.6790826917 0.6251426935 + 0.6604462862 0.6799324751 0.6260074973 + 0.6612675786 0.6807821989 0.6268723011 + 0.6620888114 0.6816319823 0.6277372241 + 0.6629067063 0.6824771762 0.6286000013 + 0.6637240052 0.6833220124 0.6294621825 + 0.6645414233 0.6841667295 0.6303244233 + 0.6653565764 0.6850084066 0.6311848760 + 0.6661701798 0.6858481765 0.6320434213 + 0.6669837236 0.6866878867 0.6329019070 + 0.6677964926 0.6875264049 0.6337599754 + 0.6686064005 0.6883615851 0.6346150041 + 0.6694163084 0.6891968250 0.6354699135 + 0.6702262163 0.6900320053 0.6363248825 + 0.6710332036 0.6908645034 0.6371762753 + 0.6718395948 0.6916965842 0.6380265951 + 0.6726461053 0.6925287247 0.6388769746 + 0.6734504104 0.6933588982 0.6397256255 + 0.6742519736 0.6941872239 0.6405714750 + 0.6750535965 0.6950153708 0.6414173245 + 0.6758551002 0.6958433986 0.6422631145 + 0.6766521931 0.6966664791 0.6431037188 + 0.6774494052 0.6974896193 0.6439439058 + 0.6782464981 0.6983126998 0.6447842121 + 0.6790412068 0.6991328001 0.6456223726 + 0.6798340082 0.6999511123 0.6464583874 + 0.6806266904 0.7007693052 0.6472944021 + 0.6814191937 0.7015869021 0.6481302977 + 0.6822078824 0.7024006248 0.6489617229 + 0.6829966903 0.7032142878 0.6497930884 + 0.6837854981 0.7040280104 0.6506243944 + 0.6845712066 0.7048389912 0.6514533162 + 0.6853544712 0.7056484222 0.6522796154 + 0.6861379147 0.7064577937 0.6531059742 + 0.6869211197 0.7072668076 0.6539323926 + 0.6876996756 0.7080708742 0.6547545791 + 0.6884782910 0.7088748813 0.6555765867 + 0.6892567873 0.7096790075 0.6563987136 + 0.6900330782 0.7104793787 0.6572191119 + 0.6908069253 0.7112764716 0.6580371261 + 0.6915807128 0.7120736241 0.6588550806 + 0.6923545003 0.7128707170 0.6596730947 + 0.6931245923 0.7136620879 0.6604871154 + 0.6938942075 0.7144529819 0.6613001823 + 0.6946637034 0.7152439952 0.6621131897 + 0.6954323053 0.7160329819 0.6629254222 + 0.6961976886 0.7168176174 0.6637337804 + 0.6969630122 0.7176023126 0.6645420790 + 0.6977283955 0.7183870077 0.6653504968 + 0.6984916925 0.7191671133 0.6661558747 + 0.6992534995 0.7199447751 0.6669585705 + 0.7000153065 0.7207224965 0.6677613854 + 0.7007771134 0.7215002179 0.6685642004 + 0.7015355825 0.7222713232 0.6693624258 + 0.7022938132 0.7230420709 0.6701598167 + 0.7030519843 0.7238129973 0.6709572077 + 0.7038096786 0.7245823145 0.6717540026 + 0.7045649290 0.7253469229 0.6725463867 + 0.7053201199 0.7261115909 0.6733387113 + 0.7060751915 0.7268761992 0.6741309762 + 0.7068290710 0.7276378274 0.6749218106 + 0.7075812817 0.7283964157 0.6757097840 + 0.7083334923 0.7291548848 0.6764978766 + 0.7090857029 0.7299134731 0.6772860289 + 0.7098354101 0.7306681275 0.6780707836 + 0.7105838060 0.7314211130 0.6788532734 + 0.7113320827 0.7321742177 0.6796358824 + 0.7120804787 0.7329273224 0.6804183722 + 0.7128257751 0.7336754799 0.6811972857 + 0.7135705948 0.7344232798 0.6819751263 + 0.7143152952 0.7351710200 0.6827530265 + 0.7150601149 0.7359182835 0.6835308075 + 0.7158017159 0.7366598248 0.6843031049 + 0.7165433168 0.7374011874 0.6850749850 + 0.7172849178 0.7381426096 0.6858468056 + 0.7180262208 0.7388827205 0.6866185069 + 0.7187647820 0.7396168113 0.6873862147 + 0.7195035219 0.7403510213 0.6881539822 + 0.7202422023 0.7410851717 0.6889218092 + 0.7209799886 0.7418174744 0.6896888018 + 0.7217146754 0.7425451279 0.6904516816 + 0.7224494219 0.7432727218 0.6912146211 + 0.7231841087 0.7440003157 0.6919776201 + 0.7239174843 0.7447258234 0.6927394867 + 0.7246472836 0.7454472184 0.6934980154 + 0.7253772020 0.7461684942 0.6942564845 + 0.7261071205 0.7468898892 0.6950148940 + 0.7268354893 0.7476091981 0.6957721114 + 0.7275608182 0.7483249903 0.6965253949 + 0.7282860279 0.7490409017 0.6972786784 + 0.7290111780 0.7497566938 0.6980319023 + 0.7297351956 0.7504705787 0.6987839937 + 0.7304564118 0.7511811852 0.6995325089 + 0.7311775088 0.7518917918 0.7002809048 + 0.7318987250 0.7526022792 0.7010293007 + 0.7326188087 0.7533113956 0.7017766237 + 0.7333359718 0.7540174723 0.7025194764 + 0.7340533137 0.7547234893 0.7032623887 + 0.7347705960 0.7554296255 0.7040053010 + 0.7354866862 0.7561342120 0.7047476172 + 0.7361978889 0.7568343878 0.7054864168 + 0.7369092107 0.7575346828 0.7062252164 + 0.7376204133 0.7582349181 0.7069640160 + 0.7383310795 0.7589343190 0.7077025771 + 0.7390366197 0.7596284151 0.7084372044 + 0.7397419810 0.7603225112 0.7091717720 + 0.7404474020 0.7610166073 0.7099062800 + 0.7411528230 0.7617105842 0.7106409073 + 0.7418531179 0.7623990178 0.7113716006 + 0.7425531745 0.7630872726 0.7121018767 + 0.7432532907 0.7637757063 0.7128322124 + 0.7439532876 0.7644640207 0.7135624886 + 0.7446492910 0.7651482821 0.7142896056 + 0.7453442216 0.7658317089 0.7150154114 + 0.7460390925 0.7665150762 0.7157412767 + 0.7467340231 0.7671986222 0.7164672017 + 0.7474262714 0.7678791881 0.7171908021 + 0.7481164932 0.7685580850 0.7179121971 + 0.7488067150 0.7692371011 0.7186335921 + 0.7494968772 0.7699159980 0.7193549871 + 0.7501856089 0.7705929279 0.7200750709 + 0.7508713007 0.7712666988 0.7207918763 + 0.7515569925 0.7719404101 0.7215088010 + 0.7522428036 0.7726141810 0.7222256064 + 0.7529281974 0.7732872963 0.7229424119 + 0.7536085248 0.7739552259 0.7236546278 + 0.7542889118 0.7746230960 0.7243667245 + 0.7549691796 0.7752910256 0.7250788808 + 0.7556495070 0.7759588957 0.7257910967 + 0.7563261986 0.7766230106 0.7264999747 + 0.7570015788 0.7772859931 0.7272074223 + 0.7576768994 0.7779489756 0.7279146910 + 0.7583522797 0.7786120772 0.7286220789 + 0.7590258718 0.7792726755 0.7293279171 + 0.7596967220 0.7799301147 0.7300304770 + 0.7603675127 0.7805876136 0.7307329774 + 0.7610384226 0.7812449932 0.7314354777 + 0.7617092133 0.7819021940 0.7321380973 + 0.7623745203 0.7825548053 0.7328367829 + 0.7630398870 0.7832074165 0.7335352898 + 0.7637053132 0.7838600278 0.7342339158 + 0.7643706203 0.7845125198 0.7349324226 + 0.7650331855 0.7851625085 0.7356290221 + 0.7656937242 0.7858108282 0.7363240123 + 0.7663542032 0.7864592075 0.7370188832 + 0.7670148015 0.7871075869 0.7377138734 + 0.7676746845 0.7877553105 0.7384086251 + 0.7683306932 0.7884001732 0.7390993834 + 0.7689867020 0.7890449762 0.7397902012 + 0.7696425915 0.7896898985 0.7404810786 + 0.7702986002 0.7903347015 0.7411718965 + 0.7709521055 0.7909758091 0.7418606281 + 0.7716041803 0.7916151285 0.7425476909 + 0.7722561955 0.7922543287 0.7432348728 + 0.7729082108 0.7928935289 0.7439219952 + 0.7735598087 0.7935318947 0.7446089983 + 0.7742068172 0.7941648960 0.7452918887 + 0.7748538256 0.7947977781 0.7459747791 + 0.7755008936 0.7954307795 0.7466577291 + 0.7761479020 0.7960637808 0.7473406196 + 0.7767928243 0.7966936827 0.7480217814 + 0.7774356008 0.7973213196 0.7487009168 + 0.7780783772 0.7979490161 0.7493799925 + 0.7787212729 0.7985765934 0.7500591278 + 0.7793641090 0.7992041707 0.7507382035 + 0.7800034285 0.7998272181 0.7514144778 + 0.7806422710 0.8004500270 0.7520902753 + 0.7812811732 0.8010727763 0.7527660728 + 0.7819200754 0.8016955256 0.7534418702 + 0.7825579047 0.8023167253 0.7541171908 + 0.7831923962 0.8029342890 0.7547907233 + 0.7838268876 0.8035517931 0.7554641962 + 0.7844614983 0.8041694164 0.7561377287 + 0.7850959897 0.8047869205 0.7568112016 + 0.7857282162 0.8054007888 0.7574830055 + 0.7863587141 0.8060125113 0.7581532001 + 0.7869892716 0.8066241741 0.7588235140 + 0.7876198292 0.8072358966 0.7594937086 + 0.7882503867 0.8078476191 0.7601639032 + 0.7888780832 0.8084548712 0.7608323097 + 0.7895054221 0.8090618253 0.7615002990 + 0.7901325822 0.8096686006 0.7621682286 + 0.7907598019 0.8102754951 0.7628362179 + 0.7913867235 0.8108816743 0.7635040283 + 0.7920100093 0.8114830852 0.7641686797 + 0.7926331758 0.8120846152 0.7648333907 + 0.7932564020 0.8126860857 0.7654981017 + 0.7938796282 0.8132876158 0.7661628127 + 0.7945017815 0.8138875961 0.7668269873 + 0.7951213717 0.8144844770 0.7674893737 + 0.7957410812 0.8150814176 0.7681518197 + 0.7963607907 0.8156782985 0.7688142061 + 0.7969803810 0.8162751794 0.7694767118 + 0.7975987792 0.8168696761 0.7701377869 + 0.7982153893 0.8174614906 0.7707970738 + 0.7988319993 0.8180533051 0.7714563012 + 0.7994486094 0.8186451197 0.7721155286 + 0.8000652790 0.8192368746 0.7727746964 + 0.8006798029 0.8198254108 0.7734327912 + 0.8012925982 0.8204118013 0.7740896940 + 0.8019053936 0.8209980726 0.7747467160 + 0.8025181890 0.8215845227 0.7754036784 + 0.8031309843 0.8221707940 0.7760605812 + 0.8037403226 0.8227540851 0.7767156959 + 0.8043475151 0.8233358264 0.7773694992 + 0.8049547076 0.8239176273 0.7780233026 + 0.8055619001 0.8244994283 0.7786769867 + 0.8061690927 0.8250811100 0.7793307900 + 0.8067730069 0.8256602883 0.7799832225 + 0.8073750138 0.8262382746 0.7806347013 + 0.8079770803 0.8268163800 0.7812862992 + 0.8085792065 0.8273944855 0.7819377780 + 0.8091812730 0.8279724717 0.7825893164 + 0.8097804189 0.8285468221 0.7832390070 + 0.8103780150 0.8291193843 0.7838873267 + 0.8109756112 0.8296921253 0.7845357060 + 0.8115732074 0.8302646875 0.7851840854 + 0.8121708035 0.8308374286 0.7858325243 + 0.8127658963 0.8314061761 0.7864795923 + 0.8133594990 0.8319730759 0.7871257067 + 0.8139529824 0.8325399160 0.7877718806 + 0.8145465851 0.8331068158 0.7884181142 + 0.8151401281 0.8336737156 0.7890642285 + 0.8157312274 0.8342378736 0.7897089124 + 0.8163201213 0.8348001242 0.7903519273 + 0.8169090152 0.8353623152 0.7909948826 + 0.8174979091 0.8359245062 0.7916380167 + 0.8180868030 0.8364866972 0.7922809720 + 0.8186740875 0.8370468020 0.7929232717 + 0.8192589283 0.8376039267 0.7935640812 + 0.8198438287 0.8381611109 0.7942048907 + 0.8204286098 0.8387181759 0.7948457003 + 0.8210135102 0.8392754197 0.7954866290 + 0.8215975761 0.8398311734 0.7961269021 + 0.8221790195 0.8403828740 0.7967646122 + 0.8227605224 0.8409346938 0.7974023223 + 0.8233419061 0.8414865136 0.7980399728 + 0.8239232898 0.8420382142 0.7986776829 + 0.8245046735 0.8425897956 0.7993155122 + 0.8250821829 0.8431358933 0.7999498844 + 0.8256595731 0.8436819911 0.8005841970 + 0.8262370229 0.8442280889 0.8012183905 + 0.8268144131 0.8447741866 0.8018527031 + 0.8273919225 0.8453204036 0.8024870157 + 0.8279669285 0.8458629251 0.8031185865 + 0.8285411000 0.8464043140 0.8037490249 + 0.8291152716 0.8469458222 0.8043794036 + 0.8296893835 0.8474872112 0.8050099015 + 0.8302636147 0.8480286002 0.8056402802 + 0.8308361769 0.8485683799 0.8062694073 + 0.8314064741 0.8491060734 0.8068965077 + 0.8319767714 0.8496438265 0.8075236082 + 0.8325471282 0.8501815200 0.8081507087 + 0.8331174850 0.8507192135 0.8087778091 + 0.8336874843 0.8512564898 0.8094046712 + 0.8342546225 0.8517901897 0.8100280762 + 0.8348217010 0.8523237705 0.8106514215 + 0.8353887796 0.8528574705 0.8112748265 + 0.8359557986 0.8533911109 0.8118981123 + 0.8365228772 0.8539248109 0.8125215173 + 0.8370872736 0.8544545770 0.8131418824 + 0.8376504779 0.8549830914 0.8137606978 + 0.8382136822 0.8555114865 0.8143793941 + 0.8387768269 0.8560398817 0.8149982095 + 0.8393399715 0.8565682769 0.8156170249 + 0.8399021029 0.8570951819 0.8162348866 + 0.8404610157 0.8576182127 0.8168491721 + 0.8410199285 0.8581411242 0.8174635172 + 0.8415787816 0.8586640954 0.8180779219 + 0.8421378136 0.8591871262 0.8186922073 + 0.8426967263 0.8597099781 0.8193064928 + 0.8432520032 0.8602293730 0.8199177980 + 0.8438060880 0.8607478738 0.8205277920 + 0.8443602920 0.8612663150 0.8211377859 + 0.8449144959 0.8617848158 0.8217477798 + 0.8454685807 0.8623031974 0.8223577738 + 0.8460217714 0.8628203869 0.8229669929 + 0.8465716839 0.8633341193 0.8235728145 + 0.8471217155 0.8638477921 0.8241786957 + 0.8476716280 0.8643614054 0.8247845173 + 0.8482214808 0.8648750782 0.8253902793 + 0.8487715125 0.8653888106 0.8259961009 + 0.8493191004 0.8658990860 0.8265994787 + 0.8498654962 0.8664078712 0.8272011876 + 0.8504120111 0.8669167757 0.8278030157 + 0.8509584069 0.8674256206 0.8284047246 + 0.8515049219 0.8679344058 0.8290064931 + 0.8520511985 0.8684428930 0.8296083212 + 0.8525946736 0.8689479232 0.8302060962 + 0.8531380892 0.8694528937 0.8308039904 + 0.8536815047 0.8699579239 0.8314018250 + 0.8542249799 0.8704627752 0.8319995999 + 0.8547683954 0.8709678054 0.8325974941 + 0.8553109765 0.8714712262 0.8331940770 + 0.8558521867 0.8719722033 0.8337880969 + 0.8563933969 0.8724731803 0.8343821168 + 0.8569346070 0.8729742765 0.8349761963 + 0.8574758172 0.8734753132 0.8355702162 + 0.8580170274 0.8739762902 0.8361642957 + 0.8585556149 0.8744739294 0.8367559910 + 0.8590927720 0.8749697804 0.8373463750 + 0.8596299887 0.8754656911 0.8379368186 + 0.8601672053 0.8759617209 0.8385272026 + 0.8607044220 0.8764575720 0.8391175270 + 0.8612416983 0.8769536018 0.8397079110 + 0.8617749810 0.8774446845 0.8402953148 + 0.8623077869 0.8779354095 0.8408821225 + 0.8628407121 0.8784260750 0.8414688706 + 0.8633735776 0.8789168000 0.8420556784 + 0.8639063835 0.8794075251 0.8426426053 + 0.8644390106 0.8798975945 0.8432291746 + 0.8649681211 0.8803830147 0.8438127041 + 0.8654972911 0.8808683753 0.8443961143 + 0.8660264015 0.8813537955 0.8449795246 + 0.8665555716 0.8818392158 0.8455628753 + 0.8670848012 0.8823245764 0.8461462855 + 0.8676131964 0.8828086853 0.8467290998 + 0.8681393862 0.8832886815 0.8473091722 + 0.8686655164 0.8837687969 0.8478893042 + 0.8691915870 0.8842489123 0.8484694958 + 0.8697177172 0.8847289085 0.8490496278 + 0.8702437878 0.8852090240 0.8496297002 + 0.8707692027 0.8856875896 0.8502088785 + 0.8712928891 0.8861634731 0.8507859111 + 0.8718166947 0.8866394162 0.8513628244 + 0.8723403811 0.8871151805 0.8519396782 + 0.8728641272 0.8875911236 0.8525167108 + 0.8733878732 0.8880670071 0.8530936241 + 0.8739106059 0.8885408044 0.8536695838 + 0.8744313717 0.8890113831 0.8542435169 + 0.8749523163 0.8894819021 0.8548172712 + 0.8754730821 0.8899524808 0.8553912044 + 0.8759940267 0.8904231191 0.8559650779 + 0.8765147924 0.8908935785 0.8565390110 + 0.8770341873 0.8913617134 0.8571118712 + 0.8775507808 0.8918259144 0.8576828837 + 0.8780673742 0.8922899961 0.8582537770 + 0.8785840869 0.8927540779 0.8588247895 + 0.8791006804 0.8932182193 0.8593956828 + 0.8796172738 0.8936823010 0.8599665761 + 0.8801329136 0.8941447139 0.8605368137 + 0.8806458712 0.8946034908 0.8611049056 + 0.8811588883 0.8950623274 0.8616731167 + 0.8816719055 0.8955211043 0.8622412086 + 0.8821849227 0.8959800005 0.8628093004 + 0.8826978803 0.8964387774 0.8633773923 + 0.8832104206 0.8968967199 0.8639450073 + 0.8837205172 0.8973513246 0.8645104170 + 0.8842306733 0.8978059292 0.8650758266 + 0.8847408891 0.8982604742 0.8656411767 + 0.8852511048 0.8987150788 0.8662065864 + 0.8857613206 0.8991696835 0.8667719960 + 0.8862714171 0.8996242285 0.8673374057 + 0.8867782950 0.9000756741 0.8679000735 + 0.8872851729 0.9005271792 0.8684629202 + 0.8877921104 0.9009786844 0.8690257072 + 0.8882989883 0.9014301896 0.8695884943 + 0.8888059855 0.9018816948 0.8701512218 + 0.8893129230 0.9023333192 0.8707140088 + 0.8898167014 0.9027820826 0.8712748289 + 0.8903198838 0.9032304287 0.8718351126 + 0.8908231258 0.9036787152 0.8723952770 + 0.8913263083 0.9041271210 0.8729556203 + 0.8918294907 0.9045754075 0.8735159039 + 0.8923326731 0.9050236940 0.8740761280 + 0.8928335905 0.9054703116 0.8746351004 + 0.8933327794 0.9059156179 0.8751929998 + 0.8938320279 0.9063609838 0.8757507801 + 0.8943310976 0.9068062901 0.8763086796 + 0.8948302865 0.9072515965 0.8768665791 + 0.8953294754 0.9076969028 0.8774244785 + 0.8958278894 0.9081414938 0.8779817820 + 0.8963238001 0.9085838795 0.8785374165 + 0.8968197107 0.9090263247 0.8790928721 + 0.8973156810 0.9094687104 0.8796485066 + 0.8978115916 0.9099110961 0.8802040815 + 0.8983076215 0.9103534818 0.8807597160 + 0.8988034725 0.9107959270 0.8813151717 + 0.8992962837 0.9112346172 0.8818688989 + 0.8997886181 0.9116730094 0.8824223280 + 0.9002810121 0.9121112823 0.8829756975 + 0.9007734060 0.9125496745 0.8835291266 + 0.9012656808 0.9129880071 0.8840824962 + 0.9017580748 0.9134262800 0.8846358061 + 0.9022489786 0.9138627052 0.8851882815 + 0.9027383924 0.9142972231 0.8857396245 + 0.9032276869 0.9147316813 0.8862909079 + 0.9037171006 0.9151660800 0.8868421912 + 0.9042065144 0.9156005979 0.8873934746 + 0.9046958089 0.9160349965 0.8879448175 + 0.9051852226 0.9164693952 0.8884961009 + 0.9056711793 0.9169011116 0.8890454173 + 0.9061573148 0.9173327088 0.8895946741 + 0.9066432714 0.9177644253 0.8901439905 + 0.9071292877 0.9181960821 0.8906934261 + 0.9076154232 0.9186277986 0.8912426829 + 0.9081013799 0.9190593958 0.8917919993 + 0.9085853100 0.9194893241 0.8923398852 + 0.9090666771 0.9199172854 0.8928862214 + 0.9095481038 0.9203454256 0.8934323788 + 0.9100295901 0.9207733870 0.8939787149 + 0.9105110168 0.9212014079 0.8945249915 + 0.9109923840 0.9216294885 0.8950712085 + 0.9114738703 0.9220575094 0.8956174850 + 0.9119517803 0.9224802852 0.8961616158 + 0.9124293923 0.9229027033 0.8967053890 + 0.9129070044 0.9233251214 0.8972491026 + 0.9133846164 0.9237474799 0.8977928758 + 0.9138621092 0.9241697788 0.8983367085 + 0.9143397212 0.9245921969 0.8988804817 + 0.9148163795 0.9250133038 0.8994235992 + 0.9152907729 0.9254313111 0.8999646902 + 0.9157652259 0.9258493185 0.9005057216 + 0.9162396193 0.9262673259 0.9010468125 + 0.9167140126 0.9266853929 0.9015879035 + 0.9171885252 0.9271034002 0.9021288753 + 0.9176629186 0.9275214076 0.9026700258 + 0.9181352854 0.9279373884 0.9032099247 + 0.9186062217 0.9283521175 0.9037488103 + 0.9190772176 0.9287667274 0.9042876959 + 0.9195482135 0.9291813970 0.9048265815 + 0.9200190902 0.9295961261 0.9053655267 + 0.9204900861 0.9300107956 0.9059044123 + 0.9209610820 0.9304254055 0.9064432979 + 0.9214289188 0.9308364987 0.9069793224 + 0.9218962193 0.9312469959 0.9075146914 + 0.9223635197 0.9316574931 0.9080500007 + 0.9228308201 0.9320679903 0.9085853100 + 0.9232981205 0.9324784875 0.9091206789 + 0.9237653017 0.9328889847 0.9096559882 + 0.9242324829 0.9332993031 0.9101912975 + 0.9246969223 0.9337061048 0.9107241035 + 0.9251613021 0.9341129065 0.9112569094 + 0.9256256819 0.9345198274 0.9117897153 + 0.9260901213 0.9349266291 0.9123224020 + 0.9265545011 0.9353333712 0.9128552079 + 0.9270188808 0.9357401729 0.9133880138 + 0.9274827838 0.9361463189 0.9139202237 + 0.9279441237 0.9365494251 0.9144498706 + 0.9284055233 0.9369524121 0.9149795175 + 0.9288668036 0.9373555183 0.9155091047 + 0.9293280840 0.9377586246 0.9160386920 + 0.9297894835 0.9381616116 0.9165682793 + 0.9302508235 0.9385647178 0.9170979261 + 0.9307109714 0.9389663935 0.9176266789 + 0.9311680794 0.9393649101 0.9181531072 + 0.9316251278 0.9397633076 0.9186794758 + 0.9320821762 0.9401618242 0.9192059040 + 0.9325392842 0.9405602813 0.9197322726 + 0.9329962730 0.9409586787 0.9202587008 + 0.9334533811 0.9413571954 0.9207851291 + 0.9339085817 0.9417545795 0.9213101268 + 0.9343593717 0.9421498775 0.9218313098 + 0.9348102212 0.9425451756 0.9223526120 + 0.9352610111 0.9429404736 0.9228739142 + 0.9357118011 0.9433357716 0.9233952165 + 0.9361625910 0.9437311292 0.9239163995 + 0.9366133809 0.9441264272 0.9244377017 + 0.9370620251 0.9445207715 0.9249573946 + 0.9375048280 0.9449130297 0.9254726171 + 0.9379475713 0.9453052282 0.9259877801 + 0.9383903742 0.9456974268 0.9265030026 + 0.9388331771 0.9460896254 0.9270182252 + 0.9392759800 0.9464818239 0.9275333881 + 0.9397187829 0.9468740225 0.9280486107 + 0.9401605129 0.9472647905 0.9285627007 + 0.9405969977 0.9476501942 0.9290714860 + 0.9410336018 0.9480355978 0.9295802116 + 0.9414702058 0.9484211206 0.9300889969 + 0.9419068098 0.9488065243 0.9305977225 + 0.9423432946 0.9491919279 0.9311063886 + 0.9427798986 0.9495772719 0.9316151738 + 0.9432163239 0.9499623179 0.9321237803 + 0.9436482191 0.9503390789 0.9326291084 + 0.9440801740 0.9507158995 0.9331343770 + 0.9445121288 0.9510927200 0.9336397052 + 0.9449440837 0.9514694810 0.9341449142 + 0.9453759789 0.9518463016 0.9346501827 + 0.9458078742 0.9522231221 0.9351555109 + 0.9462398887 0.9526000023 0.9356607795 + 0.9466683865 0.9529722929 0.9361640811 + 0.9470962882 0.9533438087 0.9366669059 + 0.9475240707 0.9537153840 0.9371697903 + 0.9479519725 0.9540868998 0.9376726151 + 0.9483798146 0.9544584155 0.9381753802 + 0.9488077164 0.9548299909 0.9386783242 + 0.9492354989 0.9552015066 0.9391810894 + 0.9496610165 0.9555711746 0.9396826029 + 0.9500846863 0.9559394717 0.9401828051 + 0.9505084157 0.9563078284 0.9406831264 + 0.9509320855 0.9566761255 0.9411833882 + 0.9513558149 0.9570444226 0.9416837096 + 0.9517794847 0.9574127197 0.9421839714 + 0.9522032142 0.9577810168 0.9426841736 + 0.9526256919 0.9581483006 0.9431836009 + 0.9530442953 0.9585124254 0.9436798096 + 0.9534628987 0.9588766098 0.9441760778 + 0.9538815022 0.9592407942 0.9446722865 + 0.9543001056 0.9596049190 0.9451684952 + 0.9547187090 0.9599691033 0.9456648231 + 0.9551373124 0.9603332281 0.9461609721 + 0.9555559158 0.9606974125 0.9466571808 + 0.9559701085 0.9610580802 0.9471496940 + 0.9563835859 0.9614182115 0.9476413727 + 0.9567971230 0.9617784023 0.9481331706 + 0.9572104812 0.9621384740 0.9486249089 + 0.9576240182 0.9624987245 0.9491167068 + 0.9580374956 0.9628589153 0.9496085048 + 0.9584509730 0.9632189870 0.9501001835 + 0.9588623047 0.9635775089 0.9505898952 + 0.9592704177 0.9639338851 0.9510766864 + 0.9596785903 0.9642902017 0.9515634179 + 0.9600868225 0.9646465182 0.9520500898 + 0.9604949951 0.9650027752 0.9525368214 + 0.9609032273 0.9653592110 0.9530236125 + 0.9613113999 0.9657155275 0.9535102844 + 0.9617195725 0.9660717845 0.9539970160 + 0.9621226192 0.9664239883 0.9544786215 + 0.9625251889 0.9667757750 0.9549596906 + 0.9629278183 0.9671275020 0.9554407001 + 0.9633303285 0.9674792886 0.9559217095 + 0.9637328982 0.9678310752 0.9564027190 + 0.9641355276 0.9681829214 0.9568837285 + 0.9645379782 0.9685347080 0.9573647976 + 0.9649384022 0.9688847065 0.9578434825 + 0.9653344154 0.9692314267 0.9583176970 + 0.9657304883 0.9695780873 0.9587917924 + 0.9661265016 0.9699246883 0.9592658877 + 0.9665225148 0.9702714086 0.9597399831 + 0.9669185281 0.9706181288 0.9602141976 + 0.9673146009 0.9709647894 0.9606882930 + 0.9677106142 0.9713115096 0.9611623883 + 0.9681016803 0.9716545939 0.9616312981 + 0.9684907198 0.9719963074 0.9620978236 + 0.9688798189 0.9723380208 0.9625642896 + 0.9692687988 0.9726796746 0.9630308151 + 0.9696578979 0.9730213881 0.9634972811 + 0.9700468779 0.9733629823 0.9639638066 + 0.9704359174 0.9737046957 0.9644302726 + 0.9708248973 0.9740462899 0.9648967981 + 0.9712070227 0.9743828177 0.9653550982 + 0.9715890288 0.9747192860 0.9658132792 + 0.9719710946 0.9750556946 0.9662715793 + 0.9723531008 0.9753922224 0.9667298794 + 0.9727351069 0.9757285714 0.9671881199 + 0.9731171727 0.9760650992 0.9676464200 + 0.9734991789 0.9764015079 0.9681046009 + 0.9738795161 0.9767364264 0.9685608149 + 0.9742544293 0.9770668149 0.9690101147 + 0.9746292830 0.9773972034 0.9694594145 + 0.9750041962 0.9777275920 0.9699087143 + 0.9753791094 0.9780579805 0.9703580141 + 0.9757540226 0.9783884883 0.9708073139 + 0.9761288762 0.9787188768 0.9712566137 + 0.9765037894 0.9790493250 0.9717059135 + 0.9768754840 0.9793767929 0.9721511006 + 0.9772428274 0.9797003865 0.9725903869 + 0.9776101112 0.9800240993 0.9730296731 + 0.9779773951 0.9803476930 0.9734690785 + 0.9783446789 0.9806714058 0.9739084244 + 0.9787119031 0.9809949994 0.9743477702 + 0.9790791869 0.9813187122 0.9747871161 + 0.9794464707 0.9816424251 0.9752265215 + 0.9798092246 0.9819620252 0.9756602049 + 0.9801679254 0.9822781086 0.9760888815 + 0.9805266261 0.9825941920 0.9765176177 + 0.9808852077 0.9829102755 0.9769461751 + 0.9812439084 0.9832264185 0.9773749113 + 0.9816026092 0.9835425019 0.9778035879 + 0.9819613099 0.9838585854 0.9782322049 + 0.9823198915 0.9841747284 0.9786608815 + 0.9826725125 0.9844858050 0.9790827036 + 0.9830206037 0.9847931862 0.9794991016 + 0.9833686948 0.9851006866 0.9799156189 + 0.9837167263 0.9854081273 0.9803320765 + 0.9840648174 0.9857155085 0.9807485938 + 0.9844129086 0.9860228896 0.9811649919 + 0.9847608805 0.9863303900 0.9815815091 + 0.9851089716 0.9866377711 0.9819980264 + 0.9854506254 0.9869400859 0.9824073911 + 0.9857869148 0.9872382283 0.9828109741 + 0.9861232042 0.9875363708 0.9832146168 + 0.9864594936 0.9878345132 0.9836181998 + 0.9867957830 0.9881327152 0.9840217233 + 0.9871320724 0.9884307981 0.9844253063 + 0.9874684215 0.9887290001 0.9848288894 + 0.9878047109 0.9890270829 0.9852324724 + 0.9881356955 0.9893202186 0.9856290817 + 0.9884604216 0.9896075130 0.9860175252 + 0.9887850881 0.9898949265 0.9864059091 + 0.9891096950 0.9901822209 0.9867942929 + 0.9894344211 0.9904695153 0.9871826768 + 0.9897590876 0.9907568097 0.9875711203 + 0.9900838137 0.9910441041 0.9879595041 + 0.9904084802 0.9913313985 0.9883478880 + 0.9907290936 0.9916148782 0.9887315035 + 0.9910402894 0.9918898940 0.9891040921 + 0.9913514853 0.9921647906 0.9894766212 + 0.9916628003 0.9924398065 0.9898492098 + 0.9919739962 0.9927147031 0.9902216792 + 0.9922851920 0.9929897189 0.9905943274 + 0.9925965071 0.9932646751 0.9909667969 + 0.9929077029 0.9935395718 0.9913393855 + 0.9932175875 0.9938135147 0.9917104244 + 0.9935122728 0.9940760732 0.9920637012 + 0.9938070774 0.9943386912 0.9924169779 + 0.9941018224 0.9946013093 0.9927703142 + 0.9943966269 0.9948639274 0.9931235909 + 0.9946913123 0.9951264858 0.9934769273 + 0.9949861169 0.9953891039 0.9938303232 + 0.9952808022 0.9956517220 0.9941835999 + 0.9955756068 0.9959142804 0.9945368767 + 0.9958524704 0.9961653948 0.9948744774 + 0.9961246848 0.9964134097 0.9952080250 + 0.9963967800 0.9966614842 0.9955413938 + 0.9966689944 0.9969094992 0.9958748817 + 0.9969412088 0.9971575141 0.9962083101 + 0.9972134233 0.9974055886 0.9965417981 + 0.9974855781 0.9976536036 0.9968752265 + 0.9977576733 0.9979016185 0.9972087145 + 0.9980192780 0.9981427789 0.9975314736 + 0.9982668757 0.9983748794 0.9978399873 + 0.9985144734 0.9986070991 0.9981486201 + 0.9987620711 0.9988391995 0.9984571934 + 0.9990097284 0.9990714192 0.9987657070 + 0.9992572069 0.9993035197 0.9990742803 + 0.9995048046 0.9995356798 0.9993829131 + 0.9997524023 0.9997677803 0.9996914268 + 1.0000000000 1.0000000000 1.0000000000 +} diff --git a/rpplugins/color_correction/resources/film_luts_raw/agfa_agfacolor_optima_ii_200.spi1d b/rpplugins/color_correction/resources/film_luts_raw/agfa_agfacolor_optima_ii_200.spi1d new file mode 100644 index 0000000..11a3328 --- /dev/null +++ b/rpplugins/color_correction/resources/film_luts_raw/agfa_agfacolor_optima_ii_200.spi1d @@ -0,0 +1,1030 @@ +Version 1 +From 0.0 1.0 +Length 1024 +Components 3 +{ + 0.0000000000 0.0000000000 0.0000000000 + 0.0111121098 0.0121509498 0.0121509498 + 0.0217311792 0.0234846398 0.0234846398 + 0.0310309306 0.0335913785 0.0335913785 + 0.0394427888 0.0427072011 0.0427072011 + 0.0472172312 0.0510250889 0.0510250889 + 0.0544895791 0.0587030984 0.0587030984 + 0.0613539182 0.0658273399 0.0658273399 + 0.0678610802 0.0724957809 0.0724957809 + 0.0740588829 0.0787753463 0.0787753463 + 0.0799922720 0.0847034305 0.0847034305 + 0.0856926665 0.0903405622 0.0903405622 + 0.0911944881 0.0957725719 0.0957725719 + 0.0965085030 0.1010297015 0.1010297015 + 0.1016504988 0.1061294973 0.1061294973 + 0.1066408977 0.1110759974 0.1110759974 + 0.1114827022 0.1158965006 0.1158965006 + 0.1161810011 0.1205943003 0.1205943003 + 0.1207583994 0.1251748055 0.1251748055 + 0.1252014935 0.1296516955 0.1296516955 + 0.1295239031 0.1340274960 0.1340274960 + 0.1337441057 0.1383039951 0.1383039951 + 0.1378667057 0.1424947977 0.1424947977 + 0.1418835968 0.1466037929 0.1466037929 + 0.1458135992 0.1506410986 0.1506410986 + 0.1496558040 0.1545946002 0.1545946002 + 0.1534211040 0.1584779024 0.1584779024 + 0.1571090072 0.1622924954 0.1622924954 + 0.1607228965 0.1660465002 0.1660465002 + 0.1642647982 0.1697326005 0.1697326005 + 0.1677455008 0.1733641028 0.1733641028 + 0.1711609066 0.1769354939 0.1769354939 + 0.1745131016 0.1804486960 0.1804486960 + 0.1778111011 0.1839037985 0.1839037985 + 0.1810566932 0.1873078942 0.1873078942 + 0.1842480004 0.1906577051 0.1906577051 + 0.1873922944 0.1939612031 0.1939612031 + 0.1904910952 0.1972206980 0.1972206980 + 0.1935475022 0.2004390955 0.2004390955 + 0.1965657026 0.2036167979 0.2036167979 + 0.1995460987 0.2067523003 0.2067523003 + 0.2024825066 0.2098508030 0.2098508030 + 0.2053820044 0.2129165977 0.2129165977 + 0.2082439959 0.2159480006 0.2159480006 + 0.2110687941 0.2189517021 0.2189517021 + 0.2138601989 0.2219190001 0.2219190001 + 0.2166164964 0.2248522043 0.2248522043 + 0.2193437964 0.2277560979 0.2277560979 + 0.2220394015 0.2306237966 0.2306237966 + 0.2247070074 0.2334605008 0.2334605008 + 0.2273449004 0.2362726033 0.2362726033 + 0.2299581021 0.2390560061 0.2390560061 + 0.2325424999 0.2418099940 0.2418099940 + 0.2350990027 0.2445425987 0.2445425987 + 0.2376336008 0.2472528070 0.2472528070 + 0.2401454002 0.2499340028 0.2499340028 + 0.2426387966 0.2525874972 0.2525874972 + 0.2451128960 0.2552196980 0.2552196980 + 0.2475619018 0.2578315139 0.2578315139 + 0.2499863058 0.2604233027 0.2604233027 + 0.2523908913 0.2629944980 0.2629944980 + 0.2547743022 0.2655487061 0.2655487061 + 0.2571432889 0.2680800855 0.2680800855 + 0.2594946027 0.2705903947 0.2705903947 + 0.2618246973 0.2730821967 0.2730821967 + 0.2641352117 0.2755582929 0.2755582929 + 0.2664259076 0.2780191004 0.2780191004 + 0.2686997056 0.2804580927 0.2804580927 + 0.2709574103 0.2828805149 0.2828805149 + 0.2731972933 0.2852869034 0.2852869034 + 0.2754215896 0.2876777947 0.2876777947 + 0.2776325047 0.2900503874 0.2900503874 + 0.2798275948 0.2924054861 0.2924054861 + 0.2820053995 0.2947433889 0.2947433889 + 0.2841629088 0.2970634997 0.2970634997 + 0.2863053083 0.2993713021 0.2993713021 + 0.2884348929 0.3016661108 0.3016661108 + 0.2905501127 0.3039461970 0.3039461970 + 0.2926583886 0.3062120080 0.3062120080 + 0.2947568893 0.3084635139 0.3084635139 + 0.2968437076 0.3106997013 0.3106997013 + 0.2989166081 0.3129228055 0.3129228055 + 0.3009737134 0.3151350021 0.3151350021 + 0.3030146956 0.3173327148 0.3173327148 + 0.3050420880 0.3195173144 0.3195173144 + 0.3070568144 0.3216913044 0.3216913044 + 0.3090623915 0.3238545060 0.3238545060 + 0.3110578060 0.3260023892 0.3260023892 + 0.3130468130 0.3281404078 0.3281404078 + 0.3150278926 0.3302693069 0.3302693069 + 0.3169982135 0.3323845863 0.3323845863 + 0.3189576864 0.3344885111 0.3344885111 + 0.3209047019 0.3365832865 0.3365832865 + 0.3228406012 0.3386682868 0.3386682868 + 0.3247657120 0.3407419920 0.3407419920 + 0.3266789913 0.3428055942 0.3428055942 + 0.3285810053 0.3448581100 0.3448581100 + 0.3304736018 0.3468984962 0.3468984962 + 0.3323583901 0.3489289880 0.3489289880 + 0.3342367113 0.3509478867 0.3509478867 + 0.3361082971 0.3529567122 0.3529567122 + 0.3379718065 0.3549566865 0.3549566865 + 0.3398267031 0.3569482863 0.3569482863 + 0.3416717947 0.3589293957 0.3589293957 + 0.3435060084 0.3609009981 0.3609009981 + 0.3453314900 0.3628633916 0.3628633916 + 0.3471463919 0.3648136854 0.3648136854 + 0.3489513993 0.3667523861 0.3667523861 + 0.3507472873 0.3686820865 0.3686820865 + 0.3525382876 0.3706041873 0.3706041873 + 0.3543233871 0.3725175858 0.3725175858 + 0.3561016917 0.3744210899 0.3744210899 + 0.3578726053 0.3763135970 0.3763135970 + 0.3596351147 0.3781942129 0.3781942129 + 0.3613910973 0.3800665140 0.3800665140 + 0.3631403148 0.3819315135 0.3819315135 + 0.3648819029 0.3837873042 0.3837873042 + 0.3666147888 0.3856337070 0.3856337070 + 0.3683386147 0.3874723017 0.3874723017 + 0.3700559139 0.3893026114 0.3893026114 + 0.3717651963 0.3911237121 0.3911237121 + 0.3734667003 0.3929347992 0.3929347992 + 0.3751592040 0.3947354853 0.3947354853 + 0.3768459857 0.3965282142 0.3965282142 + 0.3785249889 0.3983115852 0.3983115852 + 0.3801974952 0.4000878930 0.4000878930 + 0.3818610907 0.4018566012 0.4018566012 + 0.3835192919 0.4036169052 0.4036169052 + 0.3851707876 0.4053680897 0.4053680897 + 0.3868159950 0.4071125984 0.4071125984 + 0.3884536028 0.4088492990 0.4088492990 + 0.3900853097 0.4105800986 0.4105800986 + 0.3917112947 0.4123049974 0.4123049974 + 0.3933308125 0.4140234888 0.4140234888 + 0.3949447870 0.4157348871 0.4157348871 + 0.3965539038 0.4174388051 0.4174388051 + 0.3981573880 0.4191350937 0.4191350937 + 0.3997552991 0.4208256006 0.4208256006 + 0.4013460875 0.4225083888 0.4225083888 + 0.4029329121 0.4241839945 0.4241839945 + 0.4045143127 0.4258517921 0.4258517921 + 0.4060910046 0.4275138080 0.4275138080 + 0.4076623023 0.4291698933 0.4291698933 + 0.4092277884 0.4308196008 0.4308196008 + 0.4107879102 0.4324634969 0.4324634969 + 0.4123404026 0.4340988100 0.4340988100 + 0.4138863087 0.4357272089 0.4357272089 + 0.4154250026 0.4373478889 0.4373478889 + 0.4169568121 0.4389612079 0.4389612079 + 0.4184818864 0.4405669868 0.4405669868 + 0.4199990034 0.4421640933 0.4421640933 + 0.4215070009 0.4437515140 0.4437515140 + 0.4230087101 0.4453321993 0.4453321993 + 0.4245057106 0.4469063878 0.4469063878 + 0.4259983897 0.4484742880 0.4484742880 + 0.4274863899 0.4500342011 0.4500342011 + 0.4289681017 0.4515857995 0.4515857995 + 0.4304446876 0.4531300068 0.4531300068 + 0.4319162071 0.4546670914 0.4546670914 + 0.4333826005 0.4561972916 0.4561972916 + 0.4348441064 0.4577195942 0.4577195942 + 0.4363026917 0.4592362046 0.4592362046 + 0.4377590120 0.4607473016 0.4607473016 + 0.4392131865 0.4622528851 0.4622528851 + 0.4406625032 0.4637500048 0.4637500048 + 0.4421091080 0.4652411938 0.4652411938 + 0.4435526133 0.4667268991 0.4667268991 + 0.4449920058 0.4682061076 0.4682061076 + 0.4464268088 0.4696769118 0.4696769118 + 0.4478574991 0.4711419940 0.4711419940 + 0.4492841959 0.4726015031 0.4726015031 + 0.4507060051 0.4740524888 0.4740524888 + 0.4521220922 0.4754965901 0.4754965901 + 0.4535340965 0.4769350886 0.4769350886 + 0.4549413919 0.4783662856 0.4783662856 + 0.4563410878 0.4797913134 0.4797913134 + 0.4577364922 0.4812119901 0.4812119901 + 0.4591276050 0.4826276898 0.4826276898 + 0.4605121911 0.4840362966 0.4840362966 + 0.4618934989 0.4854404926 0.4854404926 + 0.4632714987 0.4868401885 0.4868401885 + 0.4646422863 0.4882321954 0.4882321954 + 0.4660094976 0.4896200001 0.4896200001 + 0.4673734009 0.4910030961 0.4910030961 + 0.4687319994 0.4923816025 0.4923816025 + 0.4700880945 0.4937570095 0.4937570095 + 0.4714413881 0.4951288104 0.4951288104 + 0.4727892876 0.4964961112 0.4964961112 + 0.4741345942 0.4978606999 0.4978606999 + 0.4754764140 0.4992212057 0.4992212057 + 0.4768131077 0.5005778074 0.5005778074 + 0.4781472087 0.5019320250 0.5019320250 + 0.4794766903 0.5032812953 0.5032812953 + 0.4808017015 0.5046275854 0.5046275854 + 0.4821242094 0.5059717894 0.5059717894 + 0.4834404886 0.5073099732 0.5073099732 + 0.4847536087 0.5086460710 0.5086460710 + 0.4860630035 0.5099794865 0.5099794865 + 0.4873664975 0.5113078952 0.5113078952 + 0.4886673987 0.5126342773 0.5126342773 + 0.4899624884 0.5139567852 0.5139567852 + 0.4912536144 0.5152760744 0.5152760744 + 0.4925413132 0.5165923238 0.5165923238 + 0.4938223064 0.5179045796 0.5179045796 + 0.4951008856 0.5192151070 0.5192151070 + 0.4963732958 0.5205205083 0.5205205083 + 0.4976417124 0.5218238235 0.5218238235 + 0.4989061058 0.5231245160 0.5231245160 + 0.5001640916 0.5244206190 0.5244206190 + 0.5014199018 0.5257151127 0.5257151127 + 0.5026680231 0.5270051956 0.5270051956 + 0.5039132833 0.5282933712 0.5282933712 + 0.5051530004 0.5295773745 0.5295773745 + 0.5063877106 0.5308588743 0.5308588743 + 0.5076187253 0.5321382880 0.5321382880 + 0.5088446736 0.5334129930 0.5334129930 + 0.5100693107 0.5346865058 0.5346865058 + 0.5112869740 0.5359553099 0.5359553099 + 0.5125030875 0.5372229815 0.5372229815 + 0.5137143135 0.5384858847 0.5384858847 + 0.5149223804 0.5397471189 0.5397471189 + 0.5161263943 0.5410054922 0.5410054922 + 0.5173262954 0.5422605872 0.5422605872 + 0.5185235143 0.5435131192 0.5435131192 + 0.5197150707 0.5447623730 0.5447623730 + 0.5209047794 0.5460104942 0.5460104942 + 0.5220907927 0.5472519994 0.5472519994 + 0.5232760906 0.5484923720 0.5484923720 + 0.5244560838 0.5497261286 0.5497261286 + 0.5256354809 0.5509589911 0.5509589911 + 0.5268111825 0.5521854162 0.5521854162 + 0.5279856920 0.5534102917 0.5534102917 + 0.5291559100 0.5546302199 0.5546302199 + 0.5303248167 0.5558478832 0.5558478832 + 0.5314909220 0.5570605993 0.5570605993 + 0.5326548815 0.5582709908 0.5582709908 + 0.5338155031 0.5594773889 0.5594773889 + 0.5349742770 0.5606803298 0.5606803298 + 0.5361307859 0.5618779063 0.5618779063 + 0.5372846723 0.5630717278 0.5630717278 + 0.5384358168 0.5642607808 0.5642607808 + 0.5395848155 0.5654460788 0.5654460788 + 0.5407317877 0.5666270256 0.5666270256 + 0.5418760777 0.5678040981 0.5678040981 + 0.5430176854 0.5689768791 0.5689768791 + 0.5441573858 0.5701463819 0.5701463819 + 0.5452948809 0.5713114142 0.5713114142 + 0.5464299917 0.5724735260 0.5724735260 + 0.5475621819 0.5736311078 0.5736311078 + 0.5486928225 0.5747861266 0.5747861266 + 0.5498210192 0.5759364963 0.5759364963 + 0.5509474277 0.5770848989 0.5770848989 + 0.5520703197 0.5782284141 0.5782284141 + 0.5531921983 0.5793704987 0.5793704987 + 0.5543109775 0.5805072188 0.5805072188 + 0.5554292202 0.5816432238 0.5816432238 + 0.5565428138 0.5827717781 0.5827717781 + 0.5576562881 0.5839003921 0.5839003921 + 0.5587658882 0.5850207806 0.5850207806 + 0.5598756075 0.5861409903 0.5861409903 + 0.5609806180 0.5872548819 0.5872548819 + 0.5620849729 0.5883675814 0.5883675814 + 0.5631865859 0.5894749165 0.5894749165 + 0.5642871261 0.5905798078 0.5905798078 + 0.5653848052 0.5916802287 0.5916802287 + 0.5664801002 0.5927764773 0.5927764773 + 0.5675740242 0.5938696861 0.5938696861 + 0.5686653852 0.5949565172 0.5949565172 + 0.5697557926 0.5960423946 0.5960423946 + 0.5708405972 0.5971215963 0.5971215963 + 0.5719254017 0.5982007980 0.5982007980 + 0.5730047226 0.5992723107 0.5992723107 + 0.5740836263 0.6003429890 0.6003429890 + 0.5751580000 0.6014091969 0.6014091969 + 0.5762305260 0.6024730802 0.6024730802 + 0.5773004889 0.6035333276 0.6035333276 + 0.5783671737 0.6045879722 0.6045879722 + 0.5794330835 0.6056417823 0.6056417823 + 0.5804936290 0.6066883802 0.6066883802 + 0.5815541148 0.6077349782 0.6077349782 + 0.5826098919 0.6087749004 0.6087749004 + 0.5836648941 0.6098132730 0.6098132730 + 0.5847159028 0.6108481884 0.6108481884 + 0.5857632160 0.6118795872 0.6118795872 + 0.5868092775 0.6129097939 0.6129097939 + 0.5878490806 0.6139339209 0.6139339209 + 0.5888888836 0.6149579883 0.6149579883 + 0.5899229050 0.6159774065 0.6159774065 + 0.5909554958 0.6169953942 0.6169953942 + 0.5919851065 0.6180102229 0.6180102229 + 0.5930107236 0.6190204024 0.6190204024 + 0.5940359831 0.6200305223 0.6200305223 + 0.5950549245 0.6210334897 0.6210334897 + 0.5960736871 0.6220365167 0.6220365167 + 0.5970885158 0.6230354905 0.6230354905 + 0.5981007814 0.6240319014 0.6240319014 + 0.5991119742 0.6250271201 0.6250271201 + 0.6001179814 0.6260160208 0.6260160208 + 0.6011241078 0.6270048022 0.6270048022 + 0.6021257043 0.6279885173 0.6279885173 + 0.6031255722 0.6289699078 0.6289699078 + 0.6041241288 0.6299499273 0.6299499273 + 0.6051182151 0.6309251785 0.6309251785 + 0.6061123013 0.6319004297 0.6319004297 + 0.6071022153 0.6328712106 0.6328712106 + 0.6080906987 0.6338403821 0.6338403821 + 0.6090779901 0.6348081827 0.6348081827 + 0.6100609899 0.6357709169 0.6357709169 + 0.6110439897 0.6367335916 0.6367335916 + 0.6120234728 0.6376916766 0.6376916766 + 0.6130014062 0.6386474967 0.6386474967 + 0.6139786243 0.6396028996 0.6396028996 + 0.6149513721 0.6405537724 0.6405537724 + 0.6159241796 0.6415047050 0.6415047050 + 0.6168935895 0.6424521804 0.6424521804 + 0.6178600788 0.6433963180 0.6433963180 + 0.6188266873 0.6443403959 0.6443403959 + 0.6197869778 0.6452776790 0.6452776790 + 0.6207470298 0.6462143064 0.6462143064 + 0.6217051744 0.6471490860 0.6471490860 + 0.6226593852 0.6480789185 0.6480789185 + 0.6236134768 0.6490086913 0.6490086913 + 0.6245638132 0.6499348283 0.6499348283 + 0.6255118847 0.6508585811 0.6508585811 + 0.6264600754 0.6517825127 0.6517825127 + 0.6274017096 0.6527013183 0.6527013183 + 0.6283431053 0.6536198854 0.6536198854 + 0.6292824149 0.6545372009 0.6545372009 + 0.6302164793 0.6554512978 0.6554512978 + 0.6311504841 0.6563653946 0.6563653946 + 0.6320812106 0.6572765708 0.6572765708 + 0.6330093145 0.6581853032 0.6581853032 + 0.6339374781 0.6590940952 0.6590940952 + 0.6348599792 0.6599957943 0.6599957943 + 0.6357815266 0.6608958244 0.6608958244 + 0.6367025971 0.6617954969 0.6617954969 + 0.6376188993 0.6626883149 0.6626883149 + 0.6385352015 0.6635810733 0.6635810733 + 0.6394497752 0.6644719243 0.6644719243 + 0.6403601766 0.6653575897 0.6653575897 + 0.6412705779 0.6662433147 0.6662433147 + 0.6421788931 0.6671264172 0.6671264172 + 0.6430848837 0.6680064797 0.6680064797 + 0.6439908147 0.6688866019 0.6688866019 + 0.6448925138 0.6697621942 0.6697621942 + 0.6457918882 0.6706354022 0.6706354022 + 0.6466913819 0.6715084910 0.6715084910 + 0.6475862861 0.6723757982 0.6723757982 + 0.6484801769 0.6732414961 0.6732414961 + 0.6493741274 0.6741071939 0.6741071939 + 0.6502627134 0.6749665737 0.6749665737 + 0.6511508822 0.6758252978 0.6758252978 + 0.6520388722 0.6766840219 0.6766840219 + 0.6529223919 0.6775373220 0.6775373220 + 0.6538059115 0.6783906221 0.6783906221 + 0.6546888947 0.6792433858 0.6792433858 + 0.6555675864 0.6800916791 0.6800916791 + 0.6564462185 0.6809399128 0.6809399128 + 0.6573243141 0.6817873716 0.6817873716 + 0.6581990719 0.6826301217 0.6826301217 + 0.6590738893 0.6834728122 0.6834728122 + 0.6599478126 0.6843147278 0.6843147278 + 0.6608172059 0.6851527095 0.6851527095 + 0.6616867185 0.6859906912 0.6859906912 + 0.6625552177 0.6868278980 0.6868278980 + 0.6634197831 0.6876606941 0.6876606941 + 0.6642844081 0.6884933710 0.6884933710 + 0.6651483178 0.6893252730 0.6893252730 + 0.6660085917 0.6901518106 0.6901518106 + 0.6668688059 0.6909784079 0.6909784079 + 0.6677287221 0.6918041706 0.6918041706 + 0.6685851216 0.6926234961 0.6926234961 + 0.6694415808 0.6934428215 0.6934428215 + 0.6702979207 0.6942619085 0.6942619085 + 0.6711509824 0.6950753927 0.6950753927 + 0.6720041037 0.6958888769 0.6958888769 + 0.6728572845 0.6967023015 0.6967023015 + 0.6737046838 0.6975108981 0.6975108981 + 0.6745517850 0.6983190179 0.6983190179 + 0.6753988862 0.6991270781 0.6991270781 + 0.6762413979 0.6999309063 0.6999309063 + 0.6770828962 0.7007337213 0.7007337213 + 0.6779245138 0.7015364766 0.7015364766 + 0.6787626743 0.7023348808 0.7023348808 + 0.6795991063 0.7031309009 0.7031309009 + 0.6804355979 0.7039269209 0.7039269209 + 0.6812698841 0.7047196031 0.7047196031 + 0.6821017861 0.7055087090 0.7055087090 + 0.6829338074 0.7062976956 0.7062976956 + 0.6837641001 0.7070850730 0.7070850730 + 0.6845905781 0.7078680992 0.7078680992 + 0.6854171157 0.7086511850 0.7086511850 + 0.6862432957 0.7094339728 0.7094339728 + 0.6870644093 0.7102119923 0.7102119923 + 0.6878855824 0.7109900117 0.7109900117 + 0.6887066960 0.7117680907 0.7117680907 + 0.6895229220 0.7125418782 0.7125418782 + 0.6903378963 0.7133144736 0.7133144736 + 0.6911528707 0.7140871286 0.7140871286 + 0.6919643283 0.7148566246 0.7148566246 + 0.6927723289 0.7156230807 0.7156230807 + 0.6935803890 0.7163894773 0.7163894773 + 0.6943870187 0.7171549797 0.7171549797 + 0.6951882243 0.7179164886 0.7179164886 + 0.6959893703 0.7186779976 0.7186779976 + 0.6967905760 0.7194393873 0.7194393873 + 0.6975867748 0.7201958895 0.7201958895 + 0.6983821988 0.7209516168 0.7209516168 + 0.6991776228 0.7217072248 0.7217072248 + 0.6999700069 0.7224600911 0.7224600911 + 0.7007597089 0.7232102752 0.7232102752 + 0.7015494108 0.7239603996 0.7239603996 + 0.7023385167 0.7247099280 0.7247099280 + 0.7031233907 0.7254531980 0.7254531980 + 0.7039083838 0.7261965275 0.7261965275 + 0.7046933770 0.7269399166 0.7269399166 + 0.7054750919 0.7276784778 0.7276784778 + 0.7062553763 0.7284148932 0.7284148932 + 0.7070357203 0.7291513085 0.7291513085 + 0.7078148127 0.7298862934 0.7298862934 + 0.7085903287 0.7306169271 0.7306169271 + 0.7093657255 0.7313475013 0.7313475013 + 0.7101411223 0.7320780158 0.7320780158 + 0.7109115124 0.7328050733 0.7328050733 + 0.7116804719 0.7335309982 0.7335309982 + 0.7124493718 0.7342568040 0.7342568040 + 0.7132170200 0.7349814773 0.7349814773 + 0.7139806747 0.7357025146 0.7357025146 + 0.7147443891 0.7364236116 0.7364236116 + 0.7155081034 0.7371445894 0.7371445894 + 0.7162681222 0.7378603816 0.7378603816 + 0.7170267105 0.7385740280 0.7385740280 + 0.7177852988 0.7392876148 0.7392876148 + 0.7185432911 0.7400004268 0.7400004268 + 0.7192980051 0.7407081723 0.7407081723 + 0.7200527191 0.7414160967 0.7414160967 + 0.7208074927 0.7421239018 0.7421239018 + 0.7215601206 0.7428290248 0.7428290248 + 0.7223110795 0.7435317039 0.7435317039 + 0.7230620980 0.7442343831 0.7442343831 + 0.7238131166 0.7449371815 0.7449371815 + 0.7245600820 0.7456340194 0.7456340194 + 0.7253068089 0.7463302016 0.7463302016 + 0.7260534763 0.7470265031 0.7470265031 + 0.7267987728 0.7477208972 0.7477208972 + 0.7275406122 0.7484099865 0.7484099865 + 0.7282822728 0.7490991950 0.7490991950 + 0.7290241122 0.7497884035 0.7497884035 + 0.7297623158 0.7504742146 0.7504742146 + 0.7304981947 0.7511575818 0.7511575818 + 0.7312340140 0.7518410087 0.7518410087 + 0.7319697738 0.7525243759 0.7525243759 + 0.7327011228 0.7532038093 0.7532038093 + 0.7334318161 0.7538825870 0.7538825870 + 0.7341625094 0.7545614839 0.7545614839 + 0.7348924279 0.7552397847 0.7552397847 + 0.7356168032 0.7559139729 0.7559139729 + 0.7363412976 0.7565882802 0.7565882802 + 0.7370656729 0.7572625279 0.7572625279 + 0.7377883792 0.7579351068 0.7579351068 + 0.7385078073 0.7586042881 0.7586042881 + 0.7392271757 0.7592735291 0.7592735291 + 0.7399466038 0.7599428296 0.7599428296 + 0.7406626940 0.7606090903 0.7606090903 + 0.7413759828 0.7612727880 0.7612727880 + 0.7420892715 0.7619364262 0.7619364262 + 0.7428025007 0.7626001239 0.7626001239 + 0.7435113192 0.7632591724 0.7632591724 + 0.7442179918 0.7639161944 0.7639161944 + 0.7449247241 0.7645732164 0.7645732164 + 0.7456315160 0.7652301788 0.7652301788 + 0.7463331223 0.7658814788 0.7658814788 + 0.7470337152 0.7665314078 0.7665314078 + 0.7477343082 0.7671812773 0.7671812773 + 0.7484349012 0.7678310871 0.7678310871 + 0.7491310239 0.7684757710 0.7684757710 + 0.7498267293 0.7691197991 0.7691197991 + 0.7505223751 0.7697638273 0.7697638273 + 0.7512180805 0.7704077959 0.7704077959 + 0.7519093156 0.7710475922 0.7710475922 + 0.7526003718 0.7716872096 0.7716872096 + 0.7532914877 0.7723268270 0.7723268270 + 0.7539826035 0.7729663849 0.7729663849 + 0.7546687722 0.7736009955 0.7736009955 + 0.7553548813 0.7742356062 0.7742356062 + 0.7560411096 0.7748702168 0.7748702168 + 0.7567272782 0.7755048275 0.7755048275 + 0.7574092150 0.7761334777 0.7761334777 + 0.7580910921 0.7767620087 0.7767620087 + 0.7587730885 0.7773905993 0.7773905993 + 0.7594550252 0.7780190706 0.7780190706 + 0.7601323724 0.7786415219 0.7786415219 + 0.7608097196 0.7792634964 0.7792634964 + 0.7614868879 0.7798855901 0.7798855901 + 0.7621641159 0.7805076241 0.7805076241 + 0.7628363967 0.7811251283 0.7811251283 + 0.7635082006 0.7817419171 0.7817419171 + 0.7641798854 0.7823588252 0.7823588252 + 0.7648516297 0.7829756141 0.7829756141 + 0.7655196786 0.7835885286 0.7835885286 + 0.7661867738 0.7842003107 0.7842003107 + 0.7668539286 0.7848120928 0.7848120928 + 0.7675210238 0.7854238749 0.7854238749 + 0.7681856155 0.7860323191 0.7860323191 + 0.7688488960 0.7866386771 0.7866386771 + 0.7695121765 0.7872452140 0.7872452140 + 0.7701753974 0.7878515720 0.7878515720 + 0.7708364725 0.7884562016 0.7884562016 + 0.7714951038 0.7890586853 0.7890586853 + 0.7721537948 0.7896612287 0.7896612287 + 0.7728124261 0.7902637124 0.7902637124 + 0.7734698057 0.7908648252 0.7908648252 + 0.7741237879 0.7914618850 0.7914618850 + 0.7747778296 0.7920590043 0.7920590043 + 0.7754318118 0.7926561832 0.7926561832 + 0.7760856748 0.7932531834 0.7932531834 + 0.7767338753 0.7938435078 0.7938435078 + 0.7773820758 0.7944338918 0.7944338918 + 0.7780303955 0.7950242162 0.7950242162 + 0.7786785960 0.7956146002 0.7956146002 + 0.7793235779 0.7962008715 0.7962008715 + 0.7799674273 0.7967858911 0.7967858911 + 0.7806112766 0.7973707914 0.7973707914 + 0.7812551260 0.7979558110 0.7979558110 + 0.7818971872 0.7985386252 0.7985386252 + 0.7825371027 0.7991185188 0.7991185188 + 0.7831770182 0.7996984124 0.7996984124 + 0.7838168740 0.8002783060 0.8002783060 + 0.7844563127 0.8008577824 0.8008577824 + 0.7850909233 0.8014323711 0.8014323711 + 0.7857254744 0.8020070791 0.8020070791 + 0.7863600850 0.8025817871 0.8025817871 + 0.7869946957 0.8031563759 0.8031563759 + 0.7876250744 0.8037273288 0.8037273288 + 0.7882537842 0.8042966127 0.8042966127 + 0.7888823748 0.8048657775 0.8048657775 + 0.7895110250 0.8054350019 0.8054350019 + 0.7901381850 0.8060027957 0.8060027957 + 0.7907618284 0.8065670133 0.8065670133 + 0.7913854122 0.8071311116 0.8071311116 + 0.7920088768 0.8076952100 0.8076952100 + 0.7926325202 0.8082594275 0.8082594275 + 0.7932527065 0.8088204861 0.8088204861 + 0.7938721776 0.8093808889 0.8093808889 + 0.7944917083 0.8099412918 0.8099412918 + 0.7951111794 0.8105016947 0.8105016947 + 0.7957289815 0.8110610247 0.8110610247 + 0.7963436842 0.8116179109 0.8116179109 + 0.7969583869 0.8121749163 0.8121749163 + 0.7975730896 0.8127318025 0.8127318025 + 0.7981876731 0.8132886887 0.8132886887 + 0.7987986803 0.8138427734 0.8138427734 + 0.7994089127 0.8143960834 0.8143960834 + 0.8000190258 0.8149495125 0.8149495125 + 0.8006290793 0.8155028224 0.8155028224 + 0.8012378812 0.8160552979 0.8160552979 + 0.8018423915 0.8166047931 0.8166047931 + 0.8024469018 0.8171542883 0.8171542883 + 0.8030514717 0.8177037835 0.8177037835 + 0.8036559820 0.8182532787 0.8182532787 + 0.8042569160 0.8187999725 0.8187999725 + 0.8048557043 0.8193448782 0.8193448782 + 0.8054544926 0.8198897839 0.8198897839 + 0.8060532808 0.8204346895 0.8204346895 + 0.8066521287 0.8209795952 0.8209795952 + 0.8072462082 0.8215199113 0.8215199113 + 0.8078402877 0.8220599890 0.8220599890 + 0.8084343076 0.8226001859 0.8226001859 + 0.8090283275 0.8231403232 0.8231403232 + 0.8096209168 0.8236796260 0.8236796260 + 0.8102098703 0.8242164254 0.8242164254 + 0.8107990026 0.8247532248 0.8247532248 + 0.8113880157 0.8252900839 0.8252900839 + 0.8119770885 0.8258268833 0.8258268833 + 0.8125630021 0.8263612986 0.8263612986 + 0.8131465912 0.8268936872 0.8268936872 + 0.8137301803 0.8274261951 0.8274261951 + 0.8143138885 0.8279585838 0.8279585838 + 0.8148974776 0.8284909725 0.8284909725 + 0.8154776096 0.8290188909 0.8290188909 + 0.8160567880 0.8295456767 0.8295456767 + 0.8166360855 0.8300724030 0.8300724030 + 0.8172153234 0.8305991888 0.8305991888 + 0.8177946210 0.8311259151 0.8311259151 + 0.8183705211 0.8316484094 0.8316484094 + 0.8189464211 0.8321709037 0.8321709037 + 0.8195223212 0.8326933980 0.8326933980 + 0.8200982213 0.8332158923 0.8332158923 + 0.8206732869 0.8337377906 0.8337377906 + 0.8212442994 0.8342564106 0.8342564106 + 0.8218153119 0.8347749710 0.8347749710 + 0.8223863244 0.8352935910 0.8352935910 + 0.8229573965 0.8358122706 0.8358122706 + 0.8235266209 0.8363298774 0.8363298774 + 0.8240911961 0.8368446231 0.8368446231 + 0.8246557713 0.8373593092 0.8373593092 + 0.8252205253 0.8378741145 0.8378741145 + 0.8257851005 0.8383888006 0.8383888006 + 0.8263477087 0.8389021754 0.8389021754 + 0.8269069791 0.8394131064 0.8394131064 + 0.8274661899 0.8399239779 0.8399239779 + 0.8280254006 0.8404349089 0.8404349089 + 0.8285846114 0.8409457803 0.8409457803 + 0.8291420937 0.8414549232 0.8414549232 + 0.8296970129 0.8419613242 0.8419613242 + 0.8302518129 0.8424677253 0.8424677253 + 0.8308066726 0.8429740071 0.8429740071 + 0.8313614726 0.8434804082 0.8434804082 + 0.8319147229 0.8439850211 0.8439850211 + 0.8324651122 0.8444867730 0.8444867730 + 0.8330155015 0.8449885845 0.8449885845 + 0.8335660100 0.8454903960 0.8454903960 + 0.8341163993 0.8459923267 0.8459923267 + 0.8346651196 0.8464931250 0.8464931250 + 0.8352108002 0.8469917774 0.8469917774 + 0.8357564807 0.8474906087 0.8474906087 + 0.8363021016 0.8479893804 0.8479893804 + 0.8368477821 0.8484880924 0.8484880924 + 0.8373925090 0.8489859104 0.8489859104 + 0.8379346132 0.8494806290 0.8494806290 + 0.8384767175 0.8499752879 0.8499752879 + 0.8390188217 0.8504700065 0.8504700065 + 0.8395608068 0.8509647250 0.8509647250 + 0.8401023746 0.8514587879 0.8514587879 + 0.8406404257 0.8519484997 0.8519484997 + 0.8411784768 0.8524380922 0.8524380922 + 0.8417165279 0.8529276848 0.8529276848 + 0.8422545791 0.8534172773 0.8534172773 + 0.8427925706 0.8539069295 0.8539069295 + 0.8433259130 0.8543931246 0.8543931246 + 0.8438590169 0.8548790812 0.8548790812 + 0.8443921208 0.8553649783 0.8553649783 + 0.8449252248 0.8558509946 0.8558509946 + 0.8454583287 0.8563370109 0.8563370109 + 0.8459873796 0.8568208218 0.8568208218 + 0.8465151787 0.8573036194 0.8573036194 + 0.8470429182 0.8577864766 0.8577864766 + 0.8475707173 0.8582693934 0.8582693934 + 0.8480983973 0.8587523103 0.8587523103 + 0.8486241102 0.8592330217 0.8592330217 + 0.8491476178 0.8597115278 0.8597115278 + 0.8496711254 0.8601899147 0.8601899147 + 0.8501945734 0.8606684208 0.8606684208 + 0.8507180810 0.8611468077 0.8611468077 + 0.8512408137 0.8616245985 0.8616245985 + 0.8517602086 0.8620989919 0.8620989919 + 0.8522796035 0.8625733852 0.8625733852 + 0.8527989984 0.8630477786 0.8630477786 + 0.8533183932 0.8635221720 0.8635221720 + 0.8538377881 0.8639966249 0.8639966249 + 0.8543522954 0.8644680977 0.8644680977 + 0.8548657894 0.8649389744 0.8649389744 + 0.8553792834 0.8654097915 0.8654097915 + 0.8558928967 0.8658807278 0.8658807278 + 0.8564063907 0.8663516045 0.8663516045 + 0.8569173813 0.8668203950 0.8668203950 + 0.8574250937 0.8672863841 0.8672863841 + 0.8579329252 0.8677524924 0.8677524924 + 0.8584406972 0.8682186007 0.8682186007 + 0.8589485288 0.8686845899 0.8686845899 + 0.8594563007 0.8691506982 0.8691506982 + 0.8599594831 0.8696123958 0.8696123958 + 0.8604626060 0.8700739741 0.8700739741 + 0.8609657884 0.8705356121 0.8705356121 + 0.8614689708 0.8709973097 0.8709973097 + 0.8619722128 0.8714588881 0.8714588881 + 0.8624734879 0.8719184995 0.8719184995 + 0.8629732132 0.8723762035 0.8723762035 + 0.8634728193 0.8728339076 0.8728339076 + 0.8639724255 0.8732916117 0.8732916117 + 0.8644720912 0.8737491965 0.8737491965 + 0.8649716973 0.8742069006 0.8742069006 + 0.8654679060 0.8746609092 0.8746609092 + 0.8659641147 0.8751147985 0.8751147985 + 0.8664603233 0.8755686283 0.8755686283 + 0.8669564128 0.8760225177 0.8760225177 + 0.8674526215 0.8764764071 0.8764764071 + 0.8679472208 0.8769292831 0.8769292831 + 0.8684396744 0.8773809075 0.8773809075 + 0.8689323068 0.8778324723 0.8778324723 + 0.8694248199 0.8782839775 0.8782839775 + 0.8699172735 0.8787356019 0.8787356019 + 0.8704097867 0.8791871071 0.8791871071 + 0.8709002137 0.8796362281 0.8796362281 + 0.8713902235 0.8800846934 0.8800846934 + 0.8718801737 0.8805330992 0.8805330992 + 0.8723701835 0.8809816241 0.8809816241 + 0.8728601933 0.8814300895 0.8814300895 + 0.8733496070 0.8818780184 0.8818780184 + 0.8738359213 0.8823224902 0.8823224902 + 0.8743221760 0.8827670217 0.8827670217 + 0.8748083711 0.8832114935 0.8832114935 + 0.8752946854 0.8836559057 0.8836559057 + 0.8757808805 0.8841003776 0.8841003776 + 0.8762651086 0.8845438957 0.8845438957 + 0.8767464757 0.8849858046 0.8849858046 + 0.8772279024 0.8854277730 0.8854277730 + 0.8777093291 0.8858698010 0.8858698010 + 0.8781906962 0.8863118291 0.8863118291 + 0.8786721230 0.8867536783 0.8867536783 + 0.8791509867 0.8871935010 0.8871935010 + 0.8796287179 0.8876323104 0.8876323104 + 0.8801062703 0.8880710006 0.8880710006 + 0.8805840015 0.8885096908 0.8885096908 + 0.8810616732 0.8889483809 0.8889483809 + 0.8815392852 0.8893870711 0.8893870711 + 0.8820139766 0.8898223042 0.8898223042 + 0.8824881911 0.8902568817 0.8902568817 + 0.8829622865 0.8906915188 0.8906915188 + 0.8834365010 0.8911259770 0.8911259770 + 0.8839107156 0.8915606141 0.8915606141 + 0.8843848109 0.8919951916 0.8919951916 + 0.8848553896 0.8924270868 0.8924270868 + 0.8853260279 0.8928589821 0.8928589821 + 0.8857964873 0.8932908773 0.8932908773 + 0.8862671256 0.8937227726 0.8937227726 + 0.8867377043 0.8941547275 0.8941547275 + 0.8872079253 0.8945863247 0.8945863247 + 0.8876746893 0.8950147033 0.8950147033 + 0.8881413937 0.8954432011 0.8954432011 + 0.8886082172 0.8958716989 0.8958716989 + 0.8890749812 0.8963001966 0.8963001966 + 0.8895418048 0.8967286944 0.8967286944 + 0.8900079131 0.8971564770 0.8971564770 + 0.8904703259 0.8975806832 0.8975806832 + 0.8909326196 0.8980048895 0.8980048895 + 0.8913949728 0.8984290957 0.8984290957 + 0.8918573856 0.8988533020 0.8988533020 + 0.8923196793 0.8992775083 0.8992775083 + 0.8927813768 0.8997012973 0.8997012973 + 0.8932392001 0.9001227021 0.9001227021 + 0.8936970234 0.9005439878 0.9005439878 + 0.8941549063 0.9009653926 0.9009653926 + 0.8946127295 0.9013866782 0.9013866782 + 0.8950704932 0.9018080831 0.9018080831 + 0.8955280185 0.9022290707 0.9022290707 + 0.8959823847 0.9026468992 0.9026468992 + 0.8964369297 0.9030647278 0.9030647278 + 0.8968912959 0.9034824967 0.9034824967 + 0.8973457813 0.9039003253 0.9039003253 + 0.8978002071 0.9043180943 0.9043180943 + 0.8982545733 0.9047358036 0.9047358036 + 0.8987048864 0.9051483870 0.9051483870 + 0.8991550803 0.9055609107 0.9055609107 + 0.8996052742 0.9059733152 0.9059733152 + 0.9000555277 0.9063857794 0.9063857794 + 0.9005057216 0.9067983031 0.9067983031 + 0.9009559155 0.9072108269 0.9072108269 + 0.9014015794 0.9076197743 0.9076197743 + 0.9018465281 0.9080280066 0.9080280066 + 0.9022914171 0.9084362984 0.9084362984 + 0.9027363062 0.9088445902 0.9088445902 + 0.9031810760 0.9092528820 0.9092528820 + 0.9036260247 0.9096611738 0.9096611738 + 0.9040681720 0.9100679755 0.9100679755 + 0.9045090079 0.9104740024 0.9104740024 + 0.9049497247 0.9108799100 0.9108799100 + 0.9053903818 0.9112858772 0.9112858772 + 0.9058312178 0.9116917849 0.9116917849 + 0.9062718749 0.9120978117 0.9120978117 + 0.9067112207 0.9125025868 0.9125025868 + 0.9071481824 0.9129055142 0.9129055142 + 0.9075852036 0.9133083820 0.9133083820 + 0.9080221057 0.9137113094 0.9137113094 + 0.9084591269 0.9141142964 0.9141142964 + 0.9088960886 0.9145172238 0.9145172238 + 0.9093328118 0.9149199128 0.9149199128 + 0.9097660184 0.9153187871 0.9153187871 + 0.9101991057 0.9157177210 0.9157177210 + 0.9106323123 0.9161165953 0.9161165953 + 0.9110653996 0.9165155292 0.9165155292 + 0.9114986062 0.9169144034 0.9169144034 + 0.9119318128 0.9173132777 0.9173132777 + 0.9123622179 0.9177098274 0.9177098274 + 0.9127916098 0.9181053042 0.9181053042 + 0.9132210016 0.9185007811 0.9185007811 + 0.9136503935 0.9188963175 0.9188963175 + 0.9140797853 0.9192917943 0.9192917943 + 0.9145091772 0.9196872711 0.9196872711 + 0.9149373174 0.9200819731 0.9200819731 + 0.9153624177 0.9204747081 0.9204747081 + 0.9157875180 0.9208673835 0.9208673835 + 0.9162126184 0.9212601781 0.9212601781 + 0.9166377187 0.9216529131 0.9216529131 + 0.9170628190 0.9220455885 0.9220455885 + 0.9174879193 0.9224383831 0.9224383831 + 0.9179093242 0.9228280187 0.9228280187 + 0.9183300734 0.9232169986 0.9232169986 + 0.9187508225 0.9236060977 0.9236060977 + 0.9191715717 0.9239950776 0.9239950776 + 0.9195923209 0.9243841171 0.9243841171 + 0.9200131297 0.9247730970 0.9247730970 + 0.9204329252 0.9251611829 0.9251611829 + 0.9208505154 0.9255470037 0.9255470037 + 0.9212682247 0.9259328842 0.9259328842 + 0.9216858745 0.9263188243 0.9263188243 + 0.9221035838 0.9267047048 0.9267047048 + 0.9225212932 0.9270905852 0.9270905852 + 0.9229388833 0.9274765253 0.9274765253 + 0.9233536720 0.9278604984 0.9278604984 + 0.9237673879 0.9282438755 0.9282438755 + 0.9241812229 0.9286273122 0.9286273122 + 0.9245948792 0.9290106893 0.9290106893 + 0.9250087142 0.9293940067 0.9293940067 + 0.9254223704 0.9297773838 0.9297773838 + 0.9258356094 0.9301604033 0.9301604033 + 0.9262446165 0.9305403829 0.9305403829 + 0.9266535044 0.9309204221 0.9309204221 + 0.9270625114 0.9313002825 0.9313002825 + 0.9274715185 0.9316803217 0.9316803217 + 0.9278804064 0.9320603013 0.9320603013 + 0.9282894135 0.9324402213 0.9324402213 + 0.9286968112 0.9328190088 0.9328190088 + 0.9291023016 0.9331961274 0.9331961274 + 0.9295076728 0.9335731864 0.9335731864 + 0.9299131036 0.9339503050 0.9339503050 + 0.9303184748 0.9343274236 0.9343274236 + 0.9307240248 0.9347046018 0.9347046018 + 0.9311293960 0.9350817204 0.9350817204 + 0.9315326810 0.9354572296 0.9354572296 + 0.9319350123 0.9358320832 0.9358320832 + 0.9323372841 0.9362069964 0.9362069964 + 0.9327396154 0.9365817904 0.9365817904 + 0.9331418872 0.9369567037 0.9369567037 + 0.9335442781 0.9373314977 0.9373314977 + 0.9339466095 0.9377064109 0.9377064109 + 0.9343459010 0.9380785227 0.9380785227 + 0.9347448945 0.9384502172 0.9384502172 + 0.9351438880 0.9388219118 0.9388219118 + 0.9355428815 0.9391937256 0.9391937256 + 0.9359418750 0.9395654202 0.9395654202 + 0.9363409281 0.9399371147 0.9399371147 + 0.9367398024 0.9403086901 0.9403086901 + 0.9371359944 0.9406778812 0.9406778812 + 0.9375321865 0.9410470128 0.9410470128 + 0.9379284978 0.9414162040 0.9414162040 + 0.9383246899 0.9417852759 0.9417852759 + 0.9387210011 0.9421545267 0.9421545267 + 0.9391171932 0.9425235987 0.9425235987 + 0.9395130277 0.9428924918 0.9428924918 + 0.9399057031 0.9432595968 0.9432595968 + 0.9402983189 0.9436268210 0.9436268210 + 0.9406909943 0.9439939260 0.9439939260 + 0.9410837293 0.9443609715 0.9443609715 + 0.9414764047 0.9447280765 0.9447280765 + 0.9418690205 0.9450953007 0.9450953007 + 0.9422609806 0.9454616904 0.9454616904 + 0.9426497221 0.9458243847 0.9458243847 + 0.9430382848 0.9461871982 0.9461871982 + 0.9434270263 0.9465500116 0.9465500116 + 0.9438155890 0.9469127059 0.9469127059 + 0.9442042708 0.9472755194 0.9472755194 + 0.9445928931 0.9476382732 0.9476382732 + 0.9449806213 0.9480000734 0.9480000734 + 0.9453629851 0.9483562708 0.9483562708 + 0.9457452893 0.9487125278 0.9487125278 + 0.9461275935 0.9490686059 0.9490686059 + 0.9465098977 0.9494248033 0.9494248033 + 0.9468922019 0.9497810006 0.9497810006 + 0.9472745061 0.9501371980 0.9501371980 + 0.9476562738 0.9504929781 0.9504929781 + 0.9480308890 0.9508436918 0.9508436918 + 0.9484055042 0.9511944056 0.9511944056 + 0.9487801194 0.9515451193 0.9515451193 + 0.9491547942 0.9518957734 0.9518957734 + 0.9495294094 0.9522464871 0.9522464871 + 0.9499040246 0.9525972009 0.9525972009 + 0.9502785802 0.9529479146 0.9529479146 + 0.9506484270 0.9532948732 0.9532948732 + 0.9510179162 0.9536415935 0.9536415935 + 0.9513872862 0.9539883733 0.9539883733 + 0.9517567158 0.9543350935 0.9543350935 + 0.9521262050 0.9546818137 0.9546818137 + 0.9524955750 0.9550285935 0.9550285935 + 0.9528651237 0.9553753138 0.9553753138 + 0.9532322884 0.9557194710 0.9557194710 + 0.9535986781 0.9560627937 0.9560627937 + 0.9539651275 0.9564061165 0.9564061165 + 0.9543313980 0.9567493796 0.9567493796 + 0.9546977878 0.9570927024 0.9570927024 + 0.9550641775 0.9574360251 0.9574360251 + 0.9554306269 0.9577792883 0.9577792883 + 0.9557952285 0.9581211805 0.9581211805 + 0.9561576843 0.9584614038 0.9584614038 + 0.9565201998 0.9588016272 0.9588016272 + 0.9568827152 0.9591417909 0.9591417909 + 0.9572451711 0.9594820142 0.9594820142 + 0.9576076865 0.9598221183 0.9598221183 + 0.9579702020 0.9601622820 0.9601622820 + 0.9583321214 0.9605020285 0.9605020285 + 0.9586902261 0.9608384967 0.9608384967 + 0.9590482712 0.9611749053 0.9611749053 + 0.9594063163 0.9615113735 0.9615113735 + 0.9597644210 0.9618479013 0.9618479013 + 0.9601225257 0.9621844292 0.9621844292 + 0.9604805708 0.9625207782 0.9625207782 + 0.9608386755 0.9628573060 0.9628573060 + 0.9611936212 0.9631906748 0.9631906748 + 0.9615474939 0.9635230899 0.9635230899 + 0.9619014263 0.9638555050 0.9638555050 + 0.9622552991 0.9641879201 0.9641879201 + 0.9626091719 0.9645202756 0.9645202756 + 0.9629632235 0.9648526907 0.9648526907 + 0.9633170962 0.9651851058 0.9651851058 + 0.9636694193 0.9655163288 0.9655163288 + 0.9640185833 0.9658449292 0.9658449292 + 0.9643678069 0.9661735892 0.9661735892 + 0.9647169709 0.9665021896 0.9665021896 + 0.9650661945 0.9668309093 0.9668309093 + 0.9654154181 0.9671595097 0.9671595097 + 0.9657645822 0.9674882293 0.9674882293 + 0.9661138058 0.9678168297 0.9678168297 + 0.9664589763 0.9681419134 0.9681419134 + 0.9668033123 0.9684662819 0.9684662819 + 0.9671475887 0.9687907100 0.9687907100 + 0.9674918056 0.9691150784 0.9691150784 + 0.9678360820 0.9694393873 0.9694393873 + 0.9681804180 0.9697638154 0.9697638154 + 0.9685246944 0.9700881839 0.9700881839 + 0.9688677788 0.9704114199 0.9704114199 + 0.9692075849 0.9707313180 0.9707313180 + 0.9695475101 0.9710512161 0.9710512161 + 0.9698873162 0.9713711143 0.9713711143 + 0.9702271223 0.9716910124 0.9716910124 + 0.9705669284 0.9720107913 0.9720107913 + 0.9709066749 0.9723306894 0.9723306894 + 0.9712464809 0.9726505876 0.9726505876 + 0.9715837240 0.9729676843 0.9729676843 + 0.9719191790 0.9732831717 0.9732831717 + 0.9722548127 0.9735987186 0.9735987186 + 0.9725903869 0.9739142060 0.9739142060 + 0.9729259014 0.9742296934 0.9742296934 + 0.9732614756 0.9745451808 0.9745451808 + 0.9735971093 0.9748606086 0.9748606086 + 0.9739326239 0.9751760960 0.9751760960 + 0.9742640257 0.9754871130 0.9754871130 + 0.9745951295 0.9757977724 0.9757977724 + 0.9749261737 0.9761084914 0.9761084914 + 0.9752572775 0.9764190912 0.9764190912 + 0.9755883813 0.9767298102 0.9767298102 + 0.9759194851 0.9770405293 0.9770405293 + 0.9762505889 0.9773511291 0.9773511291 + 0.9765807986 0.9776608944 0.9776608944 + 0.9769067764 0.9779667258 0.9779667258 + 0.9772328138 0.9782724977 0.9782724977 + 0.9775589108 0.9785783291 0.9785783291 + 0.9778848886 0.9788841009 0.9788841009 + 0.9782109261 0.9791898727 0.9791898727 + 0.9785370231 0.9794957042 0.9794957042 + 0.9788630009 0.9798014164 0.9798014164 + 0.9791870713 0.9801052809 0.9801052809 + 0.9795076847 0.9804059267 0.9804059267 + 0.9798284173 0.9807065129 0.9807065129 + 0.9801490903 0.9810069799 0.9810069799 + 0.9804697037 0.9813076258 0.9813076258 + 0.9807903767 0.9816082120 0.9816082120 + 0.9811111093 0.9819087982 0.9819087982 + 0.9814317226 0.9822093248 0.9822093248 + 0.9817494154 0.9825072885 0.9825072885 + 0.9820637703 0.9828022718 0.9828022718 + 0.9823781848 0.9830973148 0.9830973148 + 0.9826925993 0.9833922982 0.9833922982 + 0.9830070138 0.9836874008 0.9836874008 + 0.9833214283 0.9839823842 0.9839823842 + 0.9836357236 0.9842774272 0.9842774272 + 0.9839500785 0.9845724106 0.9845724106 + 0.9842607975 0.9848645926 0.9848645926 + 0.9845681787 0.9851542115 0.9851542115 + 0.9848756194 0.9854437709 0.9854437709 + 0.9851830006 0.9857333899 0.9857333899 + 0.9854903817 0.9860230088 0.9860230088 + 0.9857978225 0.9863126874 0.9863126874 + 0.9861052036 0.9866023064 0.9866023064 + 0.9864125848 0.9868919253 0.9868919253 + 0.9867162704 0.9871780872 0.9871780872 + 0.9870163798 0.9874610901 0.9874610901 + 0.9873164892 0.9877440929 0.9877440929 + 0.9876165986 0.9880272150 0.9880272150 + 0.9879167080 0.9883102179 0.9883102179 + 0.9882168174 0.9885932207 0.9885932207 + 0.9885169268 0.9888762236 0.9888762236 + 0.9888169765 0.9891592264 0.9891592264 + 0.9891130924 0.9894391894 0.9894391894 + 0.9894037247 0.9897152781 0.9897152781 + 0.9896944165 0.9899914265 0.9899914265 + 0.9899849892 0.9902673960 0.9902673960 + 0.9902756810 0.9905434847 0.9905434847 + 0.9905663133 0.9908195734 0.9908195734 + 0.9908568859 0.9910956025 0.9910956025 + 0.9911475778 0.9913716912 0.9913716912 + 0.9914352894 0.9916458726 0.9916458726 + 0.9917153716 0.9919152260 0.9919152260 + 0.9919955134 0.9921845198 0.9921845198 + 0.9922757149 0.9924538136 0.9924538136 + 0.9925557971 0.9927231073 0.9927231073 + 0.9928358793 0.9929924011 0.9929924011 + 0.9931160808 0.9932618141 0.9932618141 + 0.9933962226 0.9935311079 0.9935311079 + 0.9936755896 0.9937998056 0.9937998056 + 0.9939448833 0.9940592051 0.9940592051 + 0.9942141175 0.9943186045 0.9943186045 + 0.9944832921 0.9945781231 0.9945781231 + 0.9947525263 0.9948375225 0.9948375225 + 0.9950217009 0.9950969815 0.9950969815 + 0.9952909946 0.9953563809 0.9953563809 + 0.9955602288 0.9956158996 0.9956158996 + 0.9958294034 0.9958752990 0.9958752990 + 0.9960865974 0.9961261749 0.9961261749 + 0.9963403940 0.9963746071 0.9963746071 + 0.9965941906 0.9966229796 0.9966229796 + 0.9968479276 0.9968714118 0.9968714118 + 0.9971017241 0.9971197844 0.9971197844 + 0.9973555207 0.9973682165 0.9973682165 + 0.9976093173 0.9976165891 0.9976165891 + 0.9978629947 0.9978650212 0.9978650212 + 0.9981094003 0.9981083274 0.9981083274 + 0.9983456731 0.9983447790 0.9983447790 + 0.9985821247 0.9985812902 0.9985812902 + 0.9988183975 0.9988176823 0.9988176823 + 0.9990546703 0.9990541935 0.9990541935 + 0.9992910028 0.9992905855 0.9992905855 + 0.9995273948 0.9995270967 0.9995270967 + 0.9997637272 0.9997634888 0.9997634888 + 1.0000000000 1.0000000000 1.0000000000 +} diff --git a/rpplugins/color_correction/resources/film_luts_raw/agfa_agfacolor_ultra_050.spi1d b/rpplugins/color_correction/resources/film_luts_raw/agfa_agfacolor_ultra_050.spi1d new file mode 100644 index 0000000..bbfcdf7 --- /dev/null +++ b/rpplugins/color_correction/resources/film_luts_raw/agfa_agfacolor_ultra_050.spi1d @@ -0,0 +1,1030 @@ +Version 1 +From 0.0 1.0 +Length 1024 +Components 3 +{ + 0.0000000000 0.0000000000 0.0000000000 + 0.0261295997 0.0275282897 0.0193712804 + 0.0436814092 0.0463444404 0.0334131084 + 0.0581157207 0.0624009110 0.0459993482 + 0.0707884133 0.0767784268 0.0574880093 + 0.0822683722 0.0900187567 0.0680924430 + 0.0928523093 0.1023626998 0.0779986978 + 0.1027420014 0.1139826998 0.0873259678 + 0.1121006012 0.1249416992 0.0962512568 + 0.1209674031 0.1352714002 0.1049458012 + 0.1293299943 0.1450500935 0.1134937033 + 0.1372125000 0.1543603987 0.1219277978 + 0.1446518004 0.1632550061 0.1302694976 + 0.1517110020 0.1717393994 0.1385125965 + 0.1584471017 0.1798606068 0.1466525048 + 0.1648889929 0.1876538992 0.1546880007 + 0.1710644960 0.1951581985 0.1626233011 + 0.1769893020 0.2023999989 0.1704642028 + 0.1826931983 0.2093926072 0.1781909019 + 0.1881920993 0.2161574960 0.1858115941 + 0.1935151964 0.2226887047 0.1933328062 + 0.1986732930 0.2290194929 0.2007412016 + 0.2036796063 0.2351579070 0.2080101967 + 0.2085503936 0.2411172986 0.2151511014 + 0.2132862955 0.2469058037 0.2221754044 + 0.2178914994 0.2525430918 0.2290547043 + 0.2223861068 0.2580389082 0.2357912064 + 0.2267823070 0.2634046972 0.2423840016 + 0.2310760021 0.2686296105 0.2488331944 + 0.2352629006 0.2737227976 0.2551515996 + 0.2393413931 0.2787044942 0.2613373995 + 0.2433319986 0.2835777998 0.2673675120 + 0.2472561002 0.2883430123 0.2732523978 + 0.2511121929 0.2930105031 0.2790116072 + 0.2549034059 0.2975909114 0.2846449912 + 0.2586241066 0.3020789027 0.2901515961 + 0.2622672915 0.3064748049 0.2955358922 + 0.2658410072 0.3107773066 0.3008053899 + 0.2693549097 0.3150070012 0.3059557974 + 0.2728112042 0.3191769123 0.3109906018 + 0.2762080133 0.3232814074 0.3159134090 + 0.2795439959 0.3273217976 0.3207265139 + 0.2828184962 0.3312951028 0.3254382014 + 0.2860270143 0.3351995945 0.3300522864 + 0.2891789079 0.3390446007 0.3345699012 + 0.2922790051 0.3428247869 0.3389827907 + 0.2953406870 0.3465405107 0.3433066905 + 0.2983652055 0.3501957953 0.3475450873 + 0.3013558090 0.3538022935 0.3517045081 + 0.3043130934 0.3573650122 0.3557837009 + 0.3072336018 0.3608897924 0.3597820997 + 0.3101125956 0.3643819094 0.3637022078 + 0.3129473925 0.3678374887 0.3675518930 + 0.3157351017 0.3712525070 0.3713383079 + 0.3184793890 0.3746286929 0.3750616014 + 0.3211834133 0.3779700100 0.3787159920 + 0.3238503933 0.3812797964 0.3823012114 + 0.3264833987 0.3845624030 0.3858228922 + 0.3290852010 0.3878163993 0.3892802894 + 0.3316572905 0.3910405934 0.3926731944 + 0.3341959119 0.3942339122 0.3960165083 + 0.3367032111 0.3973953128 0.3993082047 + 0.3391802907 0.4005222023 0.4025487006 + 0.3416261971 0.4036155939 0.4057467878 + 0.3440423906 0.4066751897 0.4088996053 + 0.3464320898 0.4097003937 0.4120030999 + 0.3487968147 0.4126878977 0.4150581956 + 0.3511416912 0.4156408012 0.4180706143 + 0.3534660041 0.4185580909 0.4210394919 + 0.3557670116 0.4214420021 0.4239597917 + 0.3580501974 0.4243034124 0.4268440902 + 0.3603110015 0.4271419048 0.4296903014 + 0.3625530899 0.4299592078 0.4325061142 + 0.3647739887 0.4327593148 0.4352906942 + 0.3669759929 0.4355489016 0.4380438924 + 0.3691574037 0.4383288026 0.4407683015 + 0.3713135123 0.4410988092 0.4434654117 + 0.3734453022 0.4438571036 0.4461325109 + 0.3755545914 0.4466049075 0.4487735927 + 0.3776372969 0.4493390918 0.4513854980 + 0.3797005117 0.4520614147 0.4539698958 + 0.3817447126 0.4547702968 0.4565226138 + 0.3837673068 0.4574646056 0.4590449929 + 0.3857727945 0.4601452947 0.4615412056 + 0.3877620995 0.4628106952 0.4640046060 + 0.3897323012 0.4654597938 0.4664371908 + 0.3916867077 0.4680936038 0.4688445032 + 0.3936245143 0.4707117081 0.4712260067 + 0.3955442011 0.4733099043 0.4735803902 + 0.3974477053 0.4758862853 0.4759103060 + 0.3993369937 0.4784410894 0.4782153070 + 0.4012120068 0.4809744954 0.4804973900 + 0.4030661881 0.4834777117 0.4827564061 + 0.4049043059 0.4859539866 0.4849967062 + 0.4067262113 0.4884032905 0.4872167110 + 0.4085322917 0.4908267856 0.4894092977 + 0.4103249907 0.4932255149 0.4915755093 + 0.4121057093 0.4955982864 0.4937163889 + 0.4138723910 0.4979467094 0.4958330989 + 0.4156245887 0.5002682805 0.4979225099 + 0.4173628986 0.5025631189 0.4999859035 + 0.4190871119 0.5048316121 0.5020250082 + 0.4207980931 0.5070779920 0.5040426254 + 0.4224953055 0.5093029141 0.5060408115 + 0.4241782129 0.5115067959 0.5080217719 + 0.4258452058 0.5136871934 0.5099846721 + 0.4274975955 0.5158441067 0.5119276047 + 0.4291372001 0.5179803967 0.5138525963 + 0.4307664931 0.5200970173 0.5157613158 + 0.4323846996 0.5221933722 0.5176572204 + 0.4339928925 0.5242717862 0.5195353031 + 0.4355897009 0.5263323784 0.5213940144 + 0.4371742010 0.5283774137 0.5232350826 + 0.4387458861 0.5304070115 0.5250611901 + 0.4403051138 0.5324196219 0.5268712044 + 0.4418540895 0.5344129205 0.5286645889 + 0.4433917105 0.5363882184 0.5304409266 + 0.4449174106 0.5383464098 0.5322008729 + 0.4464308918 0.5402891040 0.5339469910 + 0.4479325116 0.5422176123 0.5356794000 + 0.4494239092 0.5441330075 0.5373972058 + 0.4509055912 0.5460358262 0.5391005874 + 0.4523760974 0.5479230881 0.5407894254 + 0.4538336098 0.5497955084 0.5424653888 + 0.4552780986 0.5516521931 0.5441265702 + 0.4567125142 0.5534964204 0.5457723737 + 0.4581381083 0.5553289056 0.5474044085 + 0.4595550001 0.5571491718 0.5490232706 + 0.4609611034 0.5589544773 0.5506296158 + 0.4623560905 0.5607442260 0.5522220135 + 0.4637416899 0.5625196099 0.5537992120 + 0.4651190937 0.5642817020 0.5553634167 + 0.4664886892 0.5660303235 0.5569143295 + 0.4678488970 0.5677667856 0.5584530830 + 0.4691990018 0.5694890022 0.5599805117 + 0.4705401957 0.5711963773 0.5614979267 + 0.4718737006 0.5728896260 0.5630066991 + 0.4731974900 0.5745667219 0.5645061731 + 0.4745135009 0.5762310028 0.5659909844 + 0.4758217931 0.5778843760 0.5674638748 + 0.4771224856 0.5795271993 0.5689262748 + 0.4784156084 0.5811589956 0.5703796744 + 0.4796993136 0.5827751756 0.5718243718 + 0.4809752107 0.5843808055 0.5732576847 + 0.4822460115 0.5859761834 0.5746794939 + 0.4835121036 0.5875607729 0.5760902762 + 0.4847720861 0.5891314745 0.5774900913 + 0.4860242903 0.5906872153 0.5788798928 + 0.4872705042 0.5922328234 0.5802617073 + 0.4885112047 0.5937690735 0.5816357136 + 0.4897463918 0.5952950716 0.5830007195 + 0.4909757972 0.5968127251 0.5843585134 + 0.4922001958 0.5983219147 0.5857095718 + 0.4934197068 0.5998219848 0.5870532990 + 0.4946334958 0.6013069153 0.5883836150 + 0.4958420992 0.6027836800 0.5897060037 + 0.4970462918 0.6042528749 0.5910214186 + 0.4982447922 0.6057118773 0.5923281908 + 0.4994386137 0.6071583033 0.5936253071 + 0.5006300211 0.6085960865 0.5949164033 + 0.5018193126 0.6100246906 0.5962014794 + 0.5030052066 0.6114413142 0.5974758863 + 0.5041871071 0.6128522754 0.5987439752 + 0.5053647161 0.6142578721 0.6000061035 + 0.5065345168 0.6156520247 0.6012579203 + 0.5077012181 0.6170390844 0.6025043726 + 0.5088649988 0.6184194088 0.6037459970 + 0.5100249052 0.6197851896 0.6049779058 + 0.5111827254 0.6211447716 0.6062039733 + 0.5123385787 0.6224983931 0.6074249148 + 0.5134863853 0.6238390207 0.6086357832 + 0.5146304965 0.6251735091 0.6098436117 + 0.5157698989 0.6265006065 0.6110476255 + 0.5169038177 0.6278185248 0.6122431159 + 0.5180357099 0.6291317940 0.6134337187 + 0.5191645026 0.6304373145 0.6146162748 + 0.5202901959 0.6317332983 0.6157922149 + 0.5214136243 0.6330240965 0.6169643998 + 0.5225296021 0.6343023181 0.6181287766 + 0.5236412883 0.6355733275 0.6192877889 + 0.5247489214 0.6368368864 0.6204416752 + 0.5258507133 0.6380882263 0.6215860248 + 0.5269507170 0.6393350959 0.6227265000 + 0.5280470252 0.6405732036 0.6238588095 + 0.5291407108 0.6418051720 0.6249852777 + 0.5302323103 0.6430323720 0.6261076927 + 0.5313162208 0.6442492008 0.6272221208 + 0.5323973894 0.6454623938 0.6283330917 + 0.5334717035 0.6466655731 0.6294345856 + 0.5345426798 0.6478630900 0.6305302978 + 0.5356101990 0.6490542889 0.6316205263 + 0.5366739035 0.6502388120 0.6327043772 + 0.5377362967 0.6514207721 0.6337860823 + 0.5387936831 0.6525934935 0.6348581910 + 0.5398488045 0.6537632942 0.6359266043 + 0.5408974290 0.6549249887 0.6369863153 + 0.5419415236 0.6560810804 0.6380411983 + 0.5429813266 0.6572313905 0.6390917897 + 0.5440160036 0.6583732963 0.6401355863 + 0.5450487137 0.6595116258 0.6411771178 + 0.5460764766 0.6606398225 0.6422092915 + 0.5471035242 0.6617661715 0.6432397962 + 0.5481255054 0.6628851295 0.6442614794 + 0.5491452217 0.6640012264 0.6452804804 + 0.5501583219 0.6651095748 0.6462923288 + 0.5511676073 0.6662127972 0.6473004222 + 0.5521715879 0.6673082113 0.6483036280 + 0.5531716943 0.6683982015 0.6493026018 + 0.5541684031 0.6694834828 0.6502984166 + 0.5551614761 0.6705622077 0.6512870789 + 0.5561527014 0.6716372967 0.6522722840 + 0.5571410060 0.6727038026 0.6532505155 + 0.5581284165 0.6737673879 0.6542266011 + 0.5591105223 0.6748213768 0.6551975012 + 0.5600913763 0.6758732796 0.6561676264 + 0.5610644817 0.6769148111 0.6571305990 + 0.5620365143 0.6779549718 0.6580929756 + 0.5630018115 0.6789849997 0.6590462923 + 0.5639665723 0.6800143123 0.6599991918 + 0.5649260283 0.6810361147 0.6609457731 + 0.5658853054 0.6820576191 0.6618922949 + 0.5668407083 0.6830697060 0.6628310084 + 0.5677961111 0.6840814948 0.6637696028 + 0.5687469244 0.6850817800 0.6646987200 + 0.5696974993 0.6860815883 0.6656274796 + 0.5706422925 0.6870731711 0.6665499806 + 0.5715867281 0.6880642176 0.6674721837 + 0.5725247860 0.6890473962 0.6683868766 + 0.5734621882 0.6900296211 0.6693009138 + 0.5743951201 0.6910039783 0.6702064872 + 0.5753269792 0.6919766068 0.6711105704 + 0.5762560964 0.6929423809 0.6720092893 + 0.5771843195 0.6939054728 0.6729062796 + 0.5781095028 0.6948626041 0.6737989187 + 0.5790330768 0.6958160996 0.6746891737 + 0.5799536109 0.6967654824 0.6755756736 + 0.5808709860 0.6977106929 0.6764587164 + 0.5817859769 0.6986532807 0.6773390174 + 0.5826966763 0.6995912194 0.6782149076 + 0.5836061835 0.7005271912 0.6790891886 + 0.5845115781 0.7014548779 0.6799582839 + 0.5854169130 0.7023826241 0.6808270812 + 0.5863186121 0.7033014894 0.6816880107 + 0.5872203112 0.7042204142 0.6825488806 + 0.5881202817 0.7051343918 0.6834049821 + 0.5890197754 0.7060474157 0.6842601895 + 0.5899165869 0.7069560289 0.6851115227 + 0.5908117294 0.7078614831 0.6859601736 + 0.5917043090 0.7087628841 0.6868060231 + 0.5925924778 0.7096565962 0.6876469851 + 0.5934802294 0.7105495930 0.6884872913 + 0.5943630934 0.7114354968 0.6893228889 + 0.5952460170 0.7123214006 0.6901584268 + 0.5961257815 0.7132012248 0.6909888983 + 0.5970050097 0.7140796185 0.6918182969 + 0.5978829861 0.7149519920 0.6926438212 + 0.5987598896 0.7158185244 0.6934657097 + 0.5996358991 0.7166832089 0.6942861080 + 0.6005082130 0.7175390124 0.6951001883 + 0.6013805866 0.7183946967 0.6959143281 + 0.6022471786 0.7192428708 0.6967222095 + 0.6031126976 0.7200896144 0.6975290179 + 0.6039757133 0.7209308743 0.6983324289 + 0.6048358083 0.7217659950 0.6991323233 + 0.6056957245 0.7226004004 0.6999315023 + 0.6065520048 0.7234249711 0.7007243037 + 0.6074082851 0.7242496014 0.7015169859 + 0.6082630754 0.7250695229 0.7023050785 + 0.6091169715 0.7258870006 0.7030910850 + 0.6099703908 0.7267029285 0.7038756013 + 0.6108219028 0.7275134921 0.7046552896 + 0.6116734743 0.7283241749 0.7054349184 + 0.6125208139 0.7291293740 0.7062094212 + 0.6133667827 0.7299330831 0.7069824934 + 0.6142112017 0.7307348251 0.7077537179 + 0.6150516868 0.7315317988 0.7085208297 + 0.6158921719 0.7323288918 0.7092878222 + 0.6167293787 0.7331209779 0.7100501060 + 0.6175658107 0.7339118123 0.7108113170 + 0.6184015274 0.7347002029 0.7115700245 + 0.6192352176 0.7354820967 0.7123227715 + 0.6200687885 0.7362639904 0.7130755782 + 0.6209005713 0.7370405197 0.7138231993 + 0.6217315793 0.7378150225 0.7145689726 + 0.6225616932 0.7385885119 0.7153139710 + 0.6233869195 0.7393574119 0.7160546780 + 0.6242122054 0.7401263118 0.7167953849 + 0.6250342131 0.7408906817 0.7175316215 + 0.6258537173 0.7416514754 0.7182646990 + 0.6266732216 0.7424122095 0.7189977765 + 0.6274886131 0.7431641817 0.7197247744 + 0.6283037066 0.7439156771 0.7204515934 + 0.6291179061 0.7446653247 0.7211769223 + 0.6299300790 0.7454105020 0.7218992710 + 0.6307423115 0.7461556792 0.7226216197 + 0.6315525770 0.7468963265 0.7233393788 + 0.6323618293 0.7476344109 0.7240548134 + 0.6331710219 0.7483724952 0.7247703075 + 0.6339744925 0.7491027117 0.7254779935 + 0.6347777843 0.7498325706 0.7261853814 + 0.6355797052 0.7505611777 0.7268915772 + 0.6363769770 0.7512856722 0.7275938988 + 0.6371744275 0.7520102859 0.7282962799 + 0.6379693747 0.7527318001 0.7289955020 + 0.6387621760 0.7534502149 0.7296919227 + 0.6395549774 0.7541685104 0.7303882241 + 0.6403455138 0.7548798919 0.7310792208 + 0.6411350965 0.7555885911 0.7317686081 + 0.6419246793 0.7562974095 0.7324578762 + 0.6427112222 0.7570006847 0.7331432104 + 0.6434975863 0.7577037215 0.7338283062 + 0.6442831755 0.7584059834 0.7345126271 + 0.6450635195 0.7591038942 0.7351925969 + 0.6458438039 0.7598018050 0.7358726263 + 0.6466221809 0.7604972720 0.7365499139 + 0.6473965049 0.7611867189 0.7372214794 + 0.6481707096 0.7618761063 0.7378931046 + 0.6489428878 0.7625625134 0.7385625839 + 0.6497123837 0.7632448077 0.7392295003 + 0.6504818797 0.7639272213 0.7398964167 + 0.6512495279 0.7646067142 0.7405610085 + 0.6520156264 0.7652835846 0.7412236929 + 0.6527817249 0.7659605145 0.7418864965 + 0.6535456181 0.7666330934 0.7425445914 + 0.6543081999 0.7673028111 0.7432000041 + 0.6550709009 0.7679725885 0.7438554168 + 0.6558291912 0.7686370015 0.7445067167 + 0.6565855742 0.7692987919 0.7451562285 + 0.6573420167 0.7699605227 0.7458056808 + 0.6580939889 0.7706184983 0.7464519739 + 0.6588441133 0.7712748051 0.7470970154 + 0.6595942974 0.7719311118 0.7477421165 + 0.6603410244 0.7725834250 0.7483826876 + 0.6610863209 0.7732340097 0.7490215898 + 0.6618314981 0.7738845944 0.7496606112 + 0.6625742912 0.7745307088 0.7502961755 + 0.6633158922 0.7751746774 0.7509304881 + 0.6640574932 0.7758187056 0.7515646815 + 0.6647968292 0.7764587998 0.7521967888 + 0.6655347943 0.7770963907 0.7528278232 + 0.6662726998 0.7777339816 0.7534586787 + 0.6670070887 0.7783685923 0.7540869117 + 0.6677386165 0.7790005803 0.7547128797 + 0.6684702039 0.7796326280 0.7553389072 + 0.6691988707 0.7802624106 0.7559623122 + 0.6699240804 0.7808893919 0.7565826774 + 0.6706492901 0.7815164924 0.7572029829 + 0.6713730097 0.7821415067 0.7578222752 + 0.6720930934 0.7827615142 0.7584391832 + 0.6728131771 0.7833815813 0.7590560913 + 0.6735327840 0.7840009928 0.7596722841 + 0.6742489934 0.7846158147 0.7602841854 + 0.6749653220 0.7852305174 0.7608960867 + 0.6756814718 0.7858452797 0.7615079880 + 0.6763954163 0.7864570022 0.7621135712 + 0.6771090031 0.7870684266 0.7627189159 + 0.6778227091 0.7876799107 0.7633240819 + 0.6785330772 0.7882875800 0.7639262080 + 0.6792423129 0.7888938189 0.7645270228 + 0.6799514294 0.7894999981 0.7651277781 + 0.6806576848 0.7901020050 0.7657262087 + 0.6813606024 0.7906988859 0.7663218975 + 0.6820635200 0.7912957072 0.7669175863 + 0.6827654839 0.7918915749 0.7675123215 + 0.6834632158 0.7924820781 0.7681027055 + 0.6841610074 0.7930727005 0.7686930895 + 0.6848587990 0.7936632037 0.7692834735 + 0.6855531931 0.7942507863 0.7698693871 + 0.6862471104 0.7948378921 0.7704545856 + 0.6869410276 0.7954249978 0.7710397840 + 0.6876335144 0.7960084081 0.7716224790 + 0.6883248091 0.7965881228 0.7722026706 + 0.6890159845 0.7971677780 0.7727829218 + 0.6897066236 0.7977464795 0.7733623981 + 0.6903933287 0.7983182073 0.7739374042 + 0.6910800934 0.7988898158 0.7745124102 + 0.6917667985 0.7994614840 0.7750874162 + 0.6924489737 0.8000293970 0.7756578922 + 0.6931294799 0.8005958796 0.7762268782 + 0.6938099861 0.8011624217 0.7767959237 + 0.6944890022 0.8017272949 0.7773637772 + 0.6951643825 0.8022881746 0.7779290080 + 0.6958398223 0.8028491139 0.7784942985 + 0.6965152025 0.8034101129 0.7790595293 + 0.6971874237 0.8039643764 0.7796214223 + 0.6978589892 0.8045170903 0.7801826000 + 0.6985304952 0.8050699234 0.7807437778 + 0.6992011070 0.8056213260 0.7813032866 + 0.6998698711 0.8061696291 0.7818598151 + 0.7005386949 0.8067178130 0.7824162841 + 0.7012075186 0.8072661161 0.7829726934 + 0.7018737197 0.8078114986 0.7835255265 + 0.7025392056 0.8083561063 0.7840774059 + 0.7032046914 0.8089007139 0.7846292853 + 0.7038692236 0.8094440103 0.7851802707 + 0.7045302987 0.8099824190 0.7857282162 + 0.7051913738 0.8105208278 0.7862762213 + 0.7058525085 0.8110591769 0.7868241072 + 0.7065104842 0.8115934730 0.7873699069 + 0.7071666718 0.8121252060 0.7879143953 + 0.7078229189 0.8126569986 0.7884590030 + 0.7084791064 0.8131887913 0.7890034914 + 0.7091314793 0.8137164712 0.7895429134 + 0.7097837925 0.8142442107 0.7900823951 + 0.7104362249 0.8147718906 0.7906218171 + 0.7110877037 0.8152979016 0.7911595106 + 0.7117375135 0.8158202767 0.7916939855 + 0.7123872042 0.8163427114 0.7922285199 + 0.7130370140 0.8168652058 0.7927629948 + 0.7136846781 0.8173835278 0.7932949066 + 0.7143312097 0.8178995252 0.7938255072 + 0.7149778008 0.8184155226 0.7943559885 + 0.7156242728 0.8189315200 0.7948865891 + 0.7162669897 0.8194420934 0.7954136133 + 0.7169092894 0.8199520707 0.7959402800 + 0.7175515890 0.8204621077 0.7964671254 + 0.7181931138 0.8209713101 0.7969928980 + 0.7188305855 0.8214758039 0.7975142002 + 0.7194681168 0.8219804168 0.7980353832 + 0.7201055884 0.8224849105 0.7985566258 + 0.7207418084 0.8229876161 0.7990764976 + 0.7213757038 0.8234868050 0.7995939851 + 0.7220094800 0.8239858747 0.8001114726 + 0.7226433158 0.8244851232 0.8006290197 + 0.7232757807 0.8249812126 0.8011451960 + 0.7239069939 0.8254746199 0.8016602993 + 0.7245383263 0.8259679079 0.8021754026 + 0.7251694798 0.8264611959 0.8026905060 + 0.7257997990 0.8269500136 0.8032016754 + 0.7264295220 0.8274360895 0.8037108779 + 0.7270591855 0.8279222846 0.8042200804 + 0.7276890278 0.8284084797 0.8047292829 + 0.7283164263 0.8288906813 0.8052350879 + 0.7289428711 0.8293713927 0.8057398200 + 0.7295694947 0.8298521042 0.8062443733 + 0.7301961184 0.8303328753 0.8067491055 + 0.7308188081 0.8308109045 0.8072515130 + 0.7314406037 0.8312882185 0.8077533245 + 0.7320623994 0.8317655921 0.8082550764 + 0.7326841950 0.8322429061 0.8087568879 + 0.7333028913 0.8327162862 0.8092550039 + 0.7339209914 0.8331888914 0.8097522855 + 0.7345389724 0.8336614966 0.8102496862 + 0.7351570725 0.8341341019 0.8107470274 + 0.7357730865 0.8346002102 0.8112403154 + 0.7363885045 0.8350648880 0.8117327094 + 0.7370039821 0.8355295062 0.8122249842 + 0.7376194000 0.8359941244 0.8127173781 + 0.7382336855 0.8364549279 0.8132079244 + 0.7388474941 0.8369144201 0.8136978149 + 0.7394614220 0.8373739719 0.8141875863 + 0.7400751710 0.8378335238 0.8146774769 + 0.7406880260 0.8382915258 0.8151652813 + 0.7413002849 0.8387488127 0.8156523108 + 0.7419126034 0.8392060995 0.8161392212 + 0.7425248027 0.8396633863 0.8166260719 + 0.7431349754 0.8401176929 0.8171094060 + 0.7437434196 0.8405694962 0.8175901175 + 0.7443519235 0.8410212994 0.8180707097 + 0.7449604273 0.8414732218 0.8185513020 + 0.7455673218 0.8419228196 0.8190304041 + 0.7461718917 0.8423690200 0.8195071220 + 0.7467764020 0.8428152204 0.8199838996 + 0.7473809719 0.8432614207 0.8204606771 + 0.7479851246 0.8437070847 0.8209370971 + 0.7485867739 0.8441503048 0.8214123249 + 0.7491886020 0.8445935845 0.8218876123 + 0.7497903705 0.8450369239 0.8223627806 + 0.7503920794 0.8454802036 0.8228381276 + 0.7509921193 0.8459206223 0.8233087063 + 0.7515920997 0.8463609219 0.8237791061 + 0.7521920204 0.8468011022 0.8242496252 + 0.7527918816 0.8472414017 0.8247200251 + 0.7533906102 0.8476775289 0.8251867890 + 0.7539888024 0.8481116891 0.8256520033 + 0.7545868754 0.8485457897 0.8261172175 + 0.7551851273 0.8489800096 0.8265823722 + 0.7557817101 0.8494123220 0.8270465136 + 0.7563759089 0.8498412967 0.8275086880 + 0.7569699883 0.8502702713 0.8279709816 + 0.7575641274 0.8506993055 0.8284332156 + 0.7581582069 0.8511282802 0.8288952708 + 0.7587482929 0.8515555859 0.8293542862 + 0.7593383789 0.8519830108 0.8298131824 + 0.7599285841 0.8524103165 0.8302720785 + 0.7605187297 0.8528376222 0.8307309747 + 0.7611069083 0.8532627225 0.8311864138 + 0.7616940141 0.8536863923 0.8316398859 + 0.7622811198 0.8541101217 0.8320934176 + 0.7628682852 0.8545337915 0.8325468898 + 0.7634549737 0.8549563885 0.8329998851 + 0.7640401125 0.8553745747 0.8334509134 + 0.7646251917 0.8557928205 0.8339020014 + 0.7652102113 0.8562110066 0.8343530297 + 0.7657952905 0.8566291928 0.8348039985 + 0.7663789988 0.8570433855 0.8352537155 + 0.7669621110 0.8574560881 0.8357028961 + 0.7675452232 0.8578686714 0.8361520767 + 0.7681282163 0.8582813144 0.8366013169 + 0.7687104940 0.8586933017 0.8370494843 + 0.7692893744 0.8591027856 0.8374937177 + 0.7698683143 0.8595123291 0.8379380107 + 0.7704473138 0.8599218130 0.8383821845 + 0.7710261941 0.8603312969 0.8388264775 + 0.7716023922 0.8607382774 0.8392679095 + 0.7721772194 0.8611438274 0.8397077918 + 0.7727519870 0.8615493774 0.8401476741 + 0.7733268142 0.8619549870 0.8405876756 + 0.7739014030 0.8623604178 0.8410274982 + 0.7744730115 0.8627613187 0.8414660096 + 0.7750446200 0.8631622195 0.8419045210 + 0.7756162882 0.8635631800 0.8423430920 + 0.7761878967 0.8639640808 0.8427816033 + 0.7767586112 0.8643633723 0.8432186246 + 0.7773280144 0.8647603989 0.8436536789 + 0.7778974175 0.8651574254 0.8440887928 + 0.7784668207 0.8655543923 0.8445239067 + 0.7790362835 0.8659514189 0.8449590206 + 0.7796040773 0.8663460016 0.8453900218 + 0.7801712751 0.8667395711 0.8458197117 + 0.7807385921 0.8671333194 0.8462492824 + 0.7813057899 0.8675270081 0.8466789722 + 0.7818729877 0.8679206967 0.8471086025 + 0.7824358940 0.8683102727 0.8475356102 + 0.7829989195 0.8686999083 0.8479626775 + 0.7835618258 0.8690894842 0.8483896852 + 0.7841247916 0.8694791198 0.8488166928 + 0.7846866846 0.8698676229 0.8492432833 + 0.7852454185 0.8702524900 0.8496683240 + 0.7858040929 0.8706374168 0.8500934243 + 0.7863628268 0.8710222244 0.8505184054 + 0.7869215012 0.8714070916 0.8509433866 + 0.7874788046 0.8717902899 0.8513662815 + 0.7880342007 0.8721709847 0.8517863750 + 0.7885895967 0.8725517988 0.8522065282 + 0.7891449928 0.8729326129 0.8526266217 + 0.7897003293 0.8733134270 0.8530467153 + 0.7902544141 0.8736922145 0.8534634113 + 0.7908074260 0.8740695715 0.8538776040 + 0.7913604975 0.8744469285 0.8542917967 + 0.7919135094 0.8748242259 0.8547059894 + 0.7924665213 0.8752015829 0.8551203012 + 0.7930179834 0.8755767941 0.8555328250 + 0.7935686111 0.8759508729 0.8559445739 + 0.7941192985 0.8763250709 0.8563563824 + 0.7946699858 0.8766993284 0.8567680717 + 0.7952206731 0.8770734072 0.8571798801 + 0.7957680821 0.8774452806 0.8575891852 + 0.7963144183 0.8778162003 0.8579975963 + 0.7968606949 0.8781871796 0.8584060073 + 0.7974069715 0.8785582185 0.8588144183 + 0.7979531884 0.8789290786 0.8592228293 + 0.7984963059 0.8792970777 0.8596280217 + 0.7990381718 0.8796638846 0.8600320816 + 0.7995802164 0.8800308108 0.8604362011 + 0.8001220822 0.8803976774 0.8608403206 + 0.8006640077 0.8807644844 0.8612444997 + 0.8012034893 0.8811290264 0.8616467714 + 0.8017420173 0.8814923167 0.8620483875 + 0.8022804856 0.8818557262 0.8624501228 + 0.8028190136 0.8822190762 0.8628516793 + 0.8033574820 0.8825824857 0.8632534146 + 0.8038944006 0.8829445243 0.8636533022 + 0.8044304252 0.8833057880 0.8640521765 + 0.8049663901 0.8836669922 0.8644511104 + 0.8055024147 0.8840281963 0.8648499846 + 0.8060383797 0.8843894005 0.8652489185 + 0.8065730929 0.8847498894 0.8656460047 + 0.8071064949 0.8851096034 0.8660413027 + 0.8076400161 0.8854691982 0.8664366007 + 0.8081734180 0.8858289123 0.8668318987 + 0.8087068796 0.8861885071 0.8672271967 + 0.8092389107 0.8865470290 0.8676213026 + 0.8097679019 0.8869025707 0.8680127263 + 0.8102967739 0.8872582912 0.8684040904 + 0.8108258247 0.8876140118 0.8687955141 + 0.8113546968 0.8879696727 0.8691868782 + 0.8118832111 0.8883249760 0.8695781231 + 0.8124076724 0.8886772990 0.8699674010 + 0.8129323125 0.8890296221 0.8703566790 + 0.8134567738 0.8893818855 0.8707460165 + 0.8139812946 0.8897342086 0.8711354136 + 0.8145058155 0.8900865912 0.8715246916 + 0.8150272965 0.8904371858 0.8719115257 + 0.8155483007 0.8907874227 0.8722978830 + 0.8160691857 0.8911375999 0.8726842999 + 0.8165901899 0.8914877772 0.8730705976 + 0.8171110749 0.8918380141 0.8734570146 + 0.8176307082 0.8921874762 0.8738412857 + 0.8181489706 0.8925362229 0.8742238879 + 0.8186672926 0.8928849101 0.8746063709 + 0.8191856146 0.8932335973 0.8749889135 + 0.8197038770 0.8935822845 0.8753713965 + 0.8202217817 0.8939304948 0.8757534027 + 0.8207373023 0.8942753077 0.8761324286 + 0.8212528825 0.8946201801 0.8765113950 + 0.8217685223 0.8949649930 0.8768904209 + 0.8222841024 0.8953098059 0.8772693872 + 0.8227996826 0.8956546187 0.8776484132 + 0.8233128786 0.8959960938 0.8780251145 + 0.8238251805 0.8963361979 0.8784009814 + 0.8243374825 0.8966763020 0.8787769079 + 0.8248497844 0.8970165253 0.8791527152 + 0.8253620863 0.8973566294 0.8795285821 + 0.8258733749 0.8976960182 0.8799036145 + 0.8263819218 0.8980333209 0.8802763820 + 0.8268905282 0.8983706236 0.8806490898 + 0.8273990154 0.8987079263 0.8810219169 + 0.8279076219 0.8990452886 0.8813946843 + 0.8284161091 0.8993825912 0.8817673922 + 0.8289219141 0.8997188807 0.8821375966 + 0.8294265866 0.9000548124 0.8825070262 + 0.8299313784 0.9003908038 0.8828763962 + 0.8304362297 0.9007266760 0.8832458258 + 0.8309410214 0.9010627270 0.8836151958 + 0.8314452171 0.9013980031 0.8839840293 + 0.8319470882 0.9017302990 0.8843502998 + 0.8324490190 0.9020625949 0.8847165704 + 0.8329507709 0.9023948908 0.8850830197 + 0.8334527016 0.9027271867 0.8854492903 + 0.8339545727 0.9030594826 0.8858156800 + 0.8344553113 0.9033885002 0.8861801028 + 0.8349552155 0.9037148952 0.8865432143 + 0.8354550004 0.9040412903 0.8869063258 + 0.8359549046 0.9043676853 0.8872693777 + 0.8364546895 0.9046940804 0.8876324296 + 0.8369545937 0.9050204754 0.8879954815 + 0.8374524713 0.9053437710 0.8883556724 + 0.8379502892 0.9056668282 0.8887156248 + 0.8384481072 0.9059898257 0.8890755177 + 0.8389458060 0.9063128233 0.8894352913 + 0.8394436240 0.9066357017 0.8897951841 + 0.8399409056 0.9069585204 0.8901546001 + 0.8404362202 0.9072805047 0.8905115724 + 0.8409314156 0.9076024294 0.8908686042 + 0.8414266706 0.9079242945 0.8912255764 + 0.8419219255 0.9082462192 0.8915826082 + 0.8424171209 0.9085682034 0.8919395804 + 0.8429111242 0.9088888168 0.8922954798 + 0.8434032798 0.9092074037 0.8926500082 + 0.8438953757 0.9095259905 0.8930044770 + 0.8443875909 0.9098446965 0.8933590055 + 0.8448796868 0.9101632833 0.8937134147 + 0.8453719020 0.9104819894 0.8940678835 + 0.8458622098 0.9107974172 0.8944209218 + 0.8463512063 0.9111105800 0.8947728276 + 0.8468402028 0.9114238024 0.8951247931 + 0.8473293185 0.9117369056 0.8954768181 + 0.8478183150 0.9120501280 0.8958287239 + 0.8483073115 0.9123632908 0.8961806893 + 0.8487946987 0.9126743078 0.8965306878 + 0.8492814898 0.9129843712 0.8968799114 + 0.8497682214 0.9132944942 0.8972290158 + 0.8502548933 0.9136046171 0.8975781798 + 0.8507416844 0.9139146805 0.8979274035 + 0.8512284160 0.9142248034 0.8982766271 + 0.8517140150 0.9145342708 0.8986228108 + 0.8521993160 0.9148436785 0.8989682794 + 0.8526844978 0.9151530266 0.8993136883 + 0.8531697989 0.9154623747 0.8996590972 + 0.8536550999 0.9157717228 0.9000046253 + 0.8541402817 0.9160810113 0.9003499746 + 0.8546243906 0.9163880944 0.9006927013 + 0.8551082015 0.9166945219 0.9010347128 + 0.8555920720 0.9170008898 0.9013767242 + 0.8560758829 0.9173073173 0.9017186761 + 0.8565596938 0.9176136851 0.9020606875 + 0.8570435047 0.9179201126 0.9024026990 + 0.8575248718 0.9182233214 0.9027428031 + 0.8580054045 0.9185255170 0.9030823112 + 0.8584859967 0.9188277125 0.9034218192 + 0.8589665890 0.9191299081 0.9037613273 + 0.8594471216 0.9194321036 0.9041007757 + 0.8599277139 0.9197342992 0.9044402838 + 0.8604061007 0.9200347066 0.9047783017 + 0.8608834743 0.9203342199 0.9051156044 + 0.8613607883 0.9206337929 0.9054529071 + 0.8618381023 0.9209333062 0.9057902098 + 0.8623154163 0.9212328196 0.9061275125 + 0.8627927899 0.9215323925 0.9064648151 + 0.8632687926 0.9218313098 0.9068005085 + 0.8637437224 0.9221296906 0.9071345925 + 0.8642185926 0.9224280119 0.9074686766 + 0.8646935225 0.9227263927 0.9078028202 + 0.8651683927 0.9230247736 0.9081369042 + 0.8656433225 0.9233232141 0.9084709883 + 0.8661177158 0.9236208200 0.9088042974 + 0.8665909171 0.9239168167 0.9091358781 + 0.8670641780 0.9242126942 0.9094673991 + 0.8675373793 0.9245086908 0.9097989202 + 0.8680106997 0.9248046279 0.9101303816 + 0.8684839010 0.9251006246 0.9104620218 + 0.8689571023 0.9253963828 0.9107934237 + 0.8694286942 0.9256886244 0.9111229181 + 0.8699004054 0.9259809256 0.9114524126 + 0.8703719974 0.9262732267 0.9117819071 + 0.8708435893 0.9265655279 0.9121115208 + 0.8713153005 0.9268577099 0.9124410152 + 0.8717868924 0.9271500111 0.9127705097 + 0.8722561002 0.9274398088 0.9130979180 + 0.8727244139 0.9277285933 0.9134243727 + 0.8731926084 0.9280173182 0.9137510061 + 0.8736609221 0.9283061028 0.9140775204 + 0.8741291761 0.9285948873 0.9144040942 + 0.8745974898 0.9288836718 0.9147307277 + 0.8750646114 0.9291719198 0.9150562882 + 0.8755295277 0.9294592738 0.9153801799 + 0.8759943843 0.9297466278 0.9157040715 + 0.8764593005 0.9300339222 0.9160280824 + 0.8769242167 0.9303212166 0.9163519740 + 0.8773891926 0.9306085110 0.9166759253 + 0.8778541088 0.9308958054 0.9169998169 + 0.8783167005 0.9311814904 0.9173220992 + 0.8787789941 0.9314669967 0.9176442027 + 0.8792414069 0.9317525029 0.9179663062 + 0.8797037005 0.9320380092 0.9182885289 + 0.8801661134 0.9323235154 0.9186105728 + 0.8806284070 0.9326090217 0.9189326763 + 0.8810901046 0.9328929186 0.9192541838 + 0.8815506101 0.9331744909 0.9195749164 + 0.8820111752 0.9334561825 0.9198955297 + 0.8824717999 0.9337378144 0.9202160835 + 0.8829324245 0.9340193868 0.9205368161 + 0.8833928704 0.9343010783 0.9208574295 + 0.8838534951 0.9345827103 0.9211781025 + 0.8843126297 0.9348607063 0.9214954972 + 0.8847714067 0.9351381063 0.9218124747 + 0.8852301836 0.9354155064 0.9221295118 + 0.8856890202 0.9356929064 0.9224464297 + 0.8861477971 0.9359703064 0.9227634072 + 0.8866065741 0.9362477064 0.9230803847 + 0.8870645761 0.9365242720 0.9233967066 + 0.8875198960 0.9367982149 0.9237111211 + 0.8879752755 0.9370720983 0.9240254760 + 0.8884305954 0.9373459816 0.9243398905 + 0.8888859153 0.9376199245 0.9246544242 + 0.8893412948 0.9378938079 0.9249687791 + 0.8897966146 0.9381676912 0.9252831936 + 0.8902500272 0.9384400249 0.9255968928 + 0.8907018900 0.9387111068 0.9259101152 + 0.8911538124 0.9389823079 0.9262232780 + 0.8916056752 0.9392533898 0.9265365005 + 0.8920575976 0.9395244718 0.9268497229 + 0.8925095201 0.9397956133 0.9271628857 + 0.8929613829 0.9400668144 0.9274761081 + 0.8934110999 0.9403352737 0.9277874827 + 0.8938602805 0.9406033158 0.9280986190 + 0.8943095207 0.9408712983 0.9284096956 + 0.8947588205 0.9411392808 0.9287207127 + 0.8952080011 0.9414073229 0.9290317893 + 0.8956571817 0.9416753054 0.9293429255 + 0.8961064219 0.9419432282 0.9296538234 + 0.8965536952 0.9422078133 0.9299619198 + 0.8970010281 0.9424722791 0.9302698970 + 0.8974484205 0.9427369237 0.9305778742 + 0.8978956938 0.9430013895 0.9308859110 + 0.8983430266 0.9432659149 0.9311940074 + 0.8987902999 0.9435304999 0.9315019846 + 0.8992372751 0.9437944889 0.9318097234 + 0.8996827006 0.9440562725 0.9321159720 + 0.9001281261 0.9443179965 0.9324222803 + 0.9005734921 0.9445797801 0.9327287078 + 0.9010189772 0.9448416233 0.9330350161 + 0.9014644027 0.9451032877 0.9333413243 + 0.9019098282 0.9453650713 0.9336475730 + 0.9023545980 0.9456260204 0.9339538217 + 0.9027975798 0.9458845258 0.9342594147 + 0.9032405019 0.9461429715 0.9345651269 + 0.9036834836 0.9464014769 0.9348707795 + 0.9041265249 0.9466599822 0.9351763725 + 0.9045695066 0.9469184875 0.9354820848 + 0.9050124884 0.9471769929 0.9357876778 + 0.9054549932 0.9474347234 0.9360926151 + 0.9058961868 0.9476901293 0.9363955855 + 0.9063374996 0.9479454756 0.9366984963 + 0.9067788124 0.9482008815 0.9370014071 + 0.9072200060 0.9484562874 0.9373043180 + 0.9076613188 0.9487115741 0.9376072288 + 0.9081025720 0.9489669800 0.9379101992 + 0.9085432887 0.9492217898 0.9382125139 + 0.9089823961 0.9494745135 0.9385129809 + 0.9094215035 0.9497271776 0.9388133883 + 0.9098604918 0.9499800205 0.9391139150 + 0.9102995992 0.9502326846 0.9394143820 + 0.9107387066 0.9504854083 0.9397147894 + 0.9111778140 0.9507380724 0.9400153160 + 0.9116166234 0.9509906173 0.9403156042 + 0.9120534062 0.9512413144 0.9406144023 + 0.9124903083 0.9514918923 0.9409132004 + 0.9129270911 0.9517425895 0.9412119985 + 0.9133639932 0.9519932866 0.9415107965 + 0.9138007760 0.9522439837 0.9418095946 + 0.9142376781 0.9524946809 0.9421083927 + 0.9146745205 0.9527453780 0.9424071908 + 0.9151092768 0.9529926777 0.9427046776 + 0.9155439138 0.9532396197 0.9430022240 + 0.9159784913 0.9534866214 0.9432995915 + 0.9164131284 0.9537336230 0.9435970187 + 0.9168477058 0.9539806247 0.9438943863 + 0.9172822833 0.9542276263 0.9441918135 + 0.9177169800 0.9544746280 0.9444893003 + 0.9181497097 0.9547194839 0.9447842836 + 0.9185816050 0.9549633861 0.9450783730 + 0.9190135002 0.9552074075 0.9453724027 + 0.9194452763 0.9554513097 0.9456663728 + 0.9198771715 0.9556952715 0.9459604025 + 0.9203091264 0.9559391737 0.9462544918 + 0.9207410216 0.9561831951 0.9465485215 + 0.9211720824 0.9564263821 0.9468415976 + 0.9216020107 0.9566686153 0.9471331835 + 0.9220318198 0.9569107294 0.9474248886 + 0.9224616289 0.9571527839 0.9477164745 + 0.9228914976 0.9573948979 0.9480081797 + 0.9233213067 0.9576370120 0.9482998252 + 0.9237511754 0.9578791857 0.9485914707 + 0.9241809845 0.9581212997 0.9488831162 + 0.9246084094 0.9583622217 0.9491736293 + 0.9250357151 0.9586032033 0.9494642019 + 0.9254630804 0.9588441253 0.9497547150 + 0.9258903861 0.9590849876 0.9500452280 + 0.9263178110 0.9593259096 0.9503356814 + 0.9267451167 0.9595668912 0.9506263137 + 0.9271724820 0.9598078132 0.9509168267 + 0.9275984168 0.9600471854 0.9512062073 + 0.9280232787 0.9602853060 0.9514948130 + 0.9284480810 0.9605233073 0.9517832994 + 0.9288728833 0.9607614279 0.9520719051 + 0.9292978048 0.9609994888 0.9523603916 + 0.9297226071 0.9612376094 0.9526489973 + 0.9301474094 0.9614756703 0.9529374838 + 0.9305720925 0.9617136121 0.9532259107 + 0.9309926033 0.9619483948 0.9535105228 + 0.9314129949 0.9621831179 0.9537950754 + 0.9318335056 0.9624179006 0.9540796876 + 0.9322540164 0.9626526237 0.9543642998 + 0.9326745272 0.9628874063 0.9546489120 + 0.9330949187 0.9631221294 0.9549335837 + 0.9335154295 0.9633569121 0.9552181959 + 0.9339327216 0.9635908008 0.9555017948 + 0.9343463778 0.9638239145 0.9557842016 + 0.9347600937 0.9640570283 0.9560666084 + 0.9351738095 0.9642900229 0.9563490152 + 0.9355874062 0.9645230770 0.9566314220 + 0.9360011220 0.9647560716 0.9569138288 + 0.9364147782 0.9649891853 0.9571961761 + 0.9368284941 0.9652221799 0.9574785829 + 0.9372366071 0.9654536247 0.9577592015 + 0.9376435280 0.9656844735 0.9580392838 + 0.9380503893 0.9659153223 0.9583194256 + 0.9384573102 0.9661461711 0.9585996270 + 0.9388641119 0.9663770795 0.9588797092 + 0.9392709732 0.9666079879 0.9591597915 + 0.9396778941 0.9668388963 0.9594399929 + 0.9400843978 0.9670693874 0.9597195983 + 0.9404869080 0.9672951102 0.9599938989 + 0.9408894777 0.9675207734 0.9602683187 + 0.9412919879 0.9677464962 0.9605426192 + 0.9416946173 0.9679722190 0.9608169794 + 0.9420971870 0.9681978822 0.9610913992 + 0.9424996972 0.9684236050 0.9613656998 + 0.9429023266 0.9686493278 0.9616401196 + 0.9433040023 0.9688737988 0.9619129896 + 0.9437037706 0.9690952897 0.9621827006 + 0.9441037178 0.9693168998 0.9624524713 + 0.9445034862 0.9695385098 0.9627221823 + 0.9449033141 0.9697600007 0.9629918933 + 0.9453032017 0.9699816108 0.9632616043 + 0.9457030296 0.9702031016 0.9635313153 + 0.9461029172 0.9704247117 0.9638010263 + 0.9465014935 0.9706450105 0.9640696049 + 0.9468985796 0.9708636999 0.9643365741 + 0.9472957253 0.9710823298 0.9646036029 + 0.9476928711 0.9713010192 0.9648706913 + 0.9480900168 0.9715197086 0.9651377201 + 0.9484871030 0.9717382789 0.9654048085 + 0.9488843083 0.9719570279 0.9656717777 + 0.9492813945 0.9721757174 0.9659388065 + 0.9496768117 0.9723932743 0.9662050009 + 0.9500706792 0.9726098180 0.9664703012 + 0.9504644871 0.9728264213 0.9667354822 + 0.9508582950 0.9730429053 0.9670007825 + 0.9512521029 0.9732595086 0.9672660828 + 0.9516459107 0.9734759927 0.9675313830 + 0.9520397782 0.9736925960 0.9677966237 + 0.9524335861 0.9739090800 0.9680619240 + 0.9528253078 0.9741246104 0.9683256745 + 0.9532151222 0.9743391275 0.9685881138 + 0.9536048174 0.9745535254 0.9688504934 + 0.9539945126 0.9747679830 0.9691128731 + 0.9543843269 0.9749823809 0.9693753123 + 0.9547740221 0.9751967788 0.9696376920 + 0.9551637173 0.9754112959 0.9699000716 + 0.9555534720 0.9756256938 0.9701625109 + 0.9559414983 0.9758388996 0.9704235196 + 0.9563273191 0.9760503173 0.9706826210 + 0.9567130208 0.9762617946 0.9709417224 + 0.9570987821 0.9764732122 0.9712008238 + 0.9574846029 0.9766845703 0.9714599848 + 0.9578703046 0.9768959880 0.9717190862 + 0.9582561255 0.9771075249 0.9719781876 + 0.9586418867 0.9773188829 0.9722372890 + 0.9590265751 0.9775292873 0.9724956751 + 0.9594085217 0.9777370095 0.9727519751 + 0.9597904086 0.9779447913 0.9730082750 + 0.9601722956 0.9781525135 0.9732645750 + 0.9605541825 0.9783601761 0.9735208750 + 0.9609361291 0.9785678983 0.9737771749 + 0.9613180161 0.9787756801 0.9740334749 + 0.9616999030 0.9789834023 0.9742897749 + 0.9620816708 0.9791910052 0.9745460153 + 0.9624596238 0.9793955088 0.9747992754 + 0.9628375769 0.9796000719 0.9750527143 + 0.9632155895 0.9798046947 0.9753059745 + 0.9635934830 0.9800091982 0.9755592942 + 0.9639714956 0.9802138209 0.9758126140 + 0.9643493891 0.9804183841 0.9760659933 + 0.9647274017 0.9806228876 0.9763193130 + 0.9651054144 0.9808275104 0.9765725732 + 0.9654802084 0.9810302258 0.9768230915 + 0.9658539295 0.9812322855 0.9770727158 + 0.9662274718 0.9814344049 0.9773222208 + 0.9666011930 0.9816365242 0.9775717854 + 0.9669749141 0.9818385839 0.9778214097 + 0.9673485756 0.9820407033 0.9780709147 + 0.9677222967 0.9822428226 0.9783204794 + 0.9680960178 0.9824448824 0.9785699844 + 0.9684677720 0.9826459289 0.9788182974 + 0.9688364863 0.9828448296 0.9790642262 + 0.9692050815 0.9830436707 0.9793102145 + 0.9695736766 0.9832426906 0.9795560837 + 0.9699423909 0.9834415913 0.9798020720 + 0.9703109860 0.9836406112 0.9800480008 + 0.9706795812 0.9838395119 0.9802939892 + 0.9710482955 0.9840384126 0.9805399179 + 0.9714168906 0.9842373729 0.9807859063 + 0.9717804790 0.9844332933 0.9810283780 + 0.9721437097 0.9846289158 0.9812706113 + 0.9725068212 0.9848244786 0.9815129042 + 0.9728699923 0.9850201011 0.9817550778 + 0.9732331038 0.9852156043 0.9819973707 + 0.9735962152 0.9854112267 0.9822396040 + 0.9739593863 0.9856067896 0.9824817777 + 0.9743224978 0.9858024120 0.9827240705 + 0.9746835232 0.9859969020 0.9829645157 + 0.9750407934 0.9861896038 0.9832020998 + 0.9753981233 0.9863823056 0.9834396839 + 0.9757553935 0.9865750074 0.9836772084 + 0.9761127234 0.9867678285 0.9839147925 + 0.9764701128 0.9869604707 0.9841523767 + 0.9768273830 0.9871531725 0.9843899012 + 0.9771847129 0.9873458743 0.9846274853 + 0.9775419831 0.9875385761 0.9848651290 + 0.9778943062 0.9877287149 0.9850988984 + 0.9782450199 0.9879180193 0.9853315949 + 0.9785957932 0.9881073236 0.9855642915 + 0.9789465070 0.9882966280 0.9857969284 + 0.9792972803 0.9884859920 0.9860296249 + 0.9796479940 0.9886752963 0.9862623215 + 0.9799987078 0.9888646007 0.9864950180 + 0.9803494811 0.9890539050 0.9867277145 + 0.9806995988 0.9892429113 0.9869599938 + 0.9810422063 0.9894282222 0.9871879816 + 0.9813848138 0.9896134138 0.9874159098 + 0.9817274213 0.9897987247 0.9876437783 + 0.9820700288 0.9899839163 0.9878718257 + 0.9824125767 0.9901692271 0.9880996943 + 0.9827551246 0.9903544188 0.9883276820 + 0.9830976725 0.9905397296 0.9885556102 + 0.9834402800 0.9907249212 0.9887835979 + 0.9837800264 0.9909089208 0.9890096188 + 0.9841130972 0.9910902977 0.9892314076 + 0.9844462276 0.9912716150 0.9894531965 + 0.9847792983 0.9914529920 0.9896751046 + 0.9851124287 0.9916343093 0.9898968935 + 0.9854454994 0.9918156266 0.9901186824 + 0.9857786298 0.9919970036 0.9903404713 + 0.9861117005 0.9921783209 0.9905623198 + 0.9864447713 0.9923596978 0.9907841086 + 0.9867734909 0.9925395250 0.9910029769 + 0.9870970845 0.9927175045 0.9912183881 + 0.9874207973 0.9928954840 0.9914339185 + 0.9877445102 0.9930735230 0.9916493297 + 0.9880681038 0.9932515025 0.9918648005 + 0.9883918166 0.9934294820 0.9920802116 + 0.9887155294 0.9936075211 0.9922956824 + 0.9890391231 0.9937855005 0.9925110936 + 0.9893627763 0.9939634800 0.9927266240 + 0.9896805286 0.9941388965 0.9929388165 + 0.9899929762 0.9943121076 0.9931482077 + 0.9903056026 0.9944853187 0.9933575988 + 0.9906181097 0.9946585298 0.9935669899 + 0.9909306765 0.9948316813 0.9937765002 + 0.9912433028 0.9950047731 0.9939858913 + 0.9915558100 0.9951779842 0.9941952825 + 0.9918683767 0.9953511953 0.9944046736 + 0.9921808839 0.9955244064 0.9946141243 + 0.9924861789 0.9956938028 0.9948195219 + 0.9927850962 0.9958598018 0.9950211048 + 0.9930838943 0.9960258007 0.9952228069 + 0.9933826923 0.9961917996 0.9954243898 + 0.9936814904 0.9963577986 0.9956260920 + 0.9939802885 0.9965237975 0.9958277941 + 0.9942790866 0.9966899157 0.9960293770 + 0.9945780039 0.9968559146 0.9962310791 + 0.9948768020 0.9970219135 0.9964327216 + 0.9951673746 0.9971848130 0.9966300130 + 0.9954472184 0.9973435998 0.9968215227 + 0.9957271218 0.9975023866 0.9970129728 + 0.9960069060 0.9976611733 0.9972046018 + 0.9962868094 0.9978200197 0.9973961115 + 0.9965665936 0.9979788065 0.9975876212 + 0.9968464971 0.9981375933 0.9977790713 + 0.9971262813 0.9982963800 0.9979707003 + 0.9974061847 0.9984552264 0.9981622100 + 0.9976803064 0.9986127019 0.9983515143 + 0.9979380965 0.9987668991 0.9985346794 + 0.9981958270 0.9989209771 0.9987179041 + 0.9984536171 0.9990751743 0.9989010096 + 0.9987112880 0.9992293119 0.9990841746 + 0.9989690185 0.9993833899 0.9992673993 + 0.9992268085 0.9995375872 0.9994505048 + 0.9994844794 0.9996917248 0.9996337295 + 0.9997423291 0.9998459220 0.9998167753 + 1.0000000000 1.0000000000 1.0000000000 +} diff --git a/rpplugins/color_correction/resources/film_luts_raw/agfa_agfacolor_vista_100.spi1d b/rpplugins/color_correction/resources/film_luts_raw/agfa_agfacolor_vista_100.spi1d new file mode 100644 index 0000000..18c00d1 --- /dev/null +++ b/rpplugins/color_correction/resources/film_luts_raw/agfa_agfacolor_vista_100.spi1d @@ -0,0 +1,1030 @@ +Version 1 +From 0.0 1.0 +Length 1024 +Components 3 +{ + 0.0000000000 0.0000000000 0.0000000000 + 0.0090248538 0.0088125290 0.0067258808 + 0.0172150191 0.0167176109 0.0131098796 + 0.0243747793 0.0235208403 0.0187523402 + 0.0308876392 0.0297362003 0.0239069704 + 0.0369180292 0.0355890803 0.0287567694 + 0.0425458290 0.0411948487 0.0333772190 + 0.0478529185 0.0466255695 0.0378036089 + 0.0528910905 0.0519192591 0.0420932695 + 0.0576865897 0.0571291298 0.0462520085 + 0.0623513199 0.0622628704 0.0503120609 + 0.0669768602 0.0672920421 0.0542953908 + 0.0715567619 0.0721824616 0.0582090616 + 0.0760855973 0.0769187585 0.0620570593 + 0.0805741325 0.0815202296 0.0658472329 + 0.0850307494 0.0859836414 0.0695805177 + 0.0894547775 0.0903253108 0.0732729286 + 0.0938297287 0.0945612267 0.0769176036 + 0.0981539637 0.0986936092 0.0805180594 + 0.1024200022 0.1027287021 0.0840807334 + 0.1066194996 0.1066882983 0.0876046494 + 0.1107435003 0.1105668023 0.0910888687 + 0.1148013026 0.1143577993 0.0945325121 + 0.1187836006 0.1180787012 0.0979359895 + 0.1227072999 0.1217278987 0.1012983993 + 0.1265697032 0.1253149062 0.1046219021 + 0.1303700954 0.1288353056 0.1078997031 + 0.1340970993 0.1322914958 0.1111387014 + 0.1377590001 0.1356990933 0.1143449992 + 0.1413495988 0.1390592009 0.1175180003 + 0.1448680013 0.1423660964 0.1206526011 + 0.1483224928 0.1456252038 0.1237441003 + 0.1516993940 0.1488344073 0.1267928034 + 0.1550139934 0.1519985944 0.1298023015 + 0.1582762003 0.1551181972 0.1327774972 + 0.1614779979 0.1581996977 0.1357243061 + 0.1646181941 0.1612505019 0.1386376023 + 0.1676993966 0.1642563939 0.1415113956 + 0.1707275957 0.1672241986 0.1443507969 + 0.1737034023 0.1701561958 0.1471655965 + 0.1766317040 0.1730598062 0.1499509066 + 0.1795026064 0.1759244055 0.1527041048 + 0.1823239028 0.1787561029 0.1554242969 + 0.1850987971 0.1815645993 0.1581097990 + 0.1878297031 0.1843390018 0.1607618928 + 0.1905121952 0.1870823056 0.1633782983 + 0.1931522936 0.1898010969 0.1659625024 + 0.1957568973 0.1924955994 0.1685173064 + 0.1983253062 0.1951646954 0.1710429937 + 0.2008654028 0.1978061944 0.1735426039 + 0.2033737004 0.2004275024 0.1760165989 + 0.2058539987 0.2030244023 0.1784628034 + 0.2083114982 0.2055975944 0.1808815002 + 0.2107529044 0.2081506997 0.1832714975 + 0.2131794989 0.2106831074 0.1856442988 + 0.2155988961 0.2131962031 0.1879992038 + 0.2180117071 0.2156914026 0.1903316975 + 0.2204127014 0.2181655020 0.1926410943 + 0.2228053063 0.2206185013 0.1949304938 + 0.2251946926 0.2230494022 0.1971997023 + 0.2275789976 0.2254669964 0.1994490027 + 0.2299547046 0.2278635949 0.2016751021 + 0.2323268950 0.2302404940 0.2038796991 + 0.2346891016 0.2326005995 0.2060652971 + 0.2370416969 0.2349402010 0.2082331926 + 0.2393849939 0.2372657061 0.2103780955 + 0.2417193949 0.2395751029 0.2125052065 + 0.2440440953 0.2418743074 0.2146157026 + 0.2463590056 0.2441594005 0.2167119980 + 0.2486687005 0.2464269996 0.2187922001 + 0.2509658039 0.2486840934 0.2208545059 + 0.2532486022 0.2509253025 0.2229007035 + 0.2555230856 0.2531493902 0.2249286026 + 0.2577824891 0.2553615868 0.2269378006 + 0.2600266933 0.2575596869 0.2289337069 + 0.2622607946 0.2597441971 0.2309127003 + 0.2644844949 0.2619175017 0.2328774929 + 0.2667022049 0.2640810013 0.2348311990 + 0.2689101100 0.2662318051 0.2367679030 + 0.2711063027 0.2683725059 0.2386890054 + 0.2732926905 0.2705014944 0.2405951023 + 0.2754707932 0.2726207078 0.2424882054 + 0.2776342928 0.2747271955 0.2443652004 + 0.2797912061 0.2768242061 0.2462334931 + 0.2819392085 0.2789101899 0.2480895966 + 0.2840760946 0.2809852958 0.2499316037 + 0.2862043977 0.2830494046 0.2517591119 + 0.2883251011 0.2851034105 0.2535771132 + 0.2904368043 0.2871474028 0.2553840876 + 0.2925382853 0.2891792059 0.2571800053 + 0.2946313024 0.2912011147 0.2589674890 + 0.2967143953 0.2932142019 0.2607443035 + 0.2987858057 0.2952139080 0.2625100017 + 0.3008505106 0.2972015142 0.2642692924 + 0.3029071987 0.2991822064 0.2660228014 + 0.3049511909 0.3011547029 0.2677705884 + 0.3069872856 0.3031156063 0.2695144117 + 0.3090176880 0.3050638139 0.2712531090 + 0.3110390007 0.3070029020 0.2729856968 + 0.3130499125 0.3089343011 0.2747122049 + 0.3150539994 0.3108555079 0.2764343023 + 0.3170512021 0.3127650023 0.2781510949 + 0.3190402091 0.3146660924 0.2798615098 + 0.3210211992 0.3165611923 0.2815661132 + 0.3229936957 0.3184478879 0.2832651138 + 0.3249579072 0.3203234971 0.2849591076 + 0.3269129992 0.3221895099 0.2866472900 + 0.3288631141 0.3240458071 0.2883332074 + 0.3308089077 0.3258920908 0.2900170982 + 0.3327476978 0.3277291059 0.2916966081 + 0.3346762955 0.3295575976 0.2933689058 + 0.3365967870 0.3313786089 0.2950361967 + 0.3385129869 0.3331907094 0.2967014909 + 0.3404223025 0.3349941075 0.2983629107 + 0.3423224092 0.3367873132 0.3000209033 + 0.3442116082 0.3385719061 0.3016754985 + 0.3460933864 0.3403505981 0.3033275902 + 0.3479698002 0.3421216011 0.3049786985 + 0.3498382866 0.3438830078 0.3066262007 + 0.3516973853 0.3456346095 0.3082687855 + 0.3535484076 0.3473792970 0.3099066913 + 0.3553937972 0.3491171896 0.3115408123 + 0.3572331965 0.3508478105 0.3131729960 + 0.3590649962 0.3525711000 0.3148024082 + 0.3608897924 0.3542861938 0.3164277971 + 0.3627074957 0.3559936881 0.3180496991 + 0.3645170927 0.3576950133 0.3196698129 + 0.3663190007 0.3593909144 0.3212881088 + 0.3681136072 0.3610796034 0.3229044080 + 0.3699010015 0.3627603948 0.3245167136 + 0.3716816008 0.3644332886 0.3261250854 + 0.3734537065 0.3660990894 0.3277314901 + 0.3752183020 0.3677594066 0.3293341994 + 0.3769755960 0.3694128990 0.3309333026 + 0.3787257969 0.3710587025 0.3325302899 + 0.3804695010 0.3726957142 0.3341256976 + 0.3822059929 0.3743239939 0.3357195854 + 0.3839339912 0.3759444058 0.3373118043 + 0.3856526017 0.3775574863 0.3389019072 + 0.3873623013 0.3791646957 0.3404884040 + 0.3890652955 0.3807657957 0.3420729041 + 0.3907626867 0.3823603094 0.3436552882 + 0.3924534023 0.3839474916 0.3452340066 + 0.3941374123 0.3855277002 0.3468089998 + 0.3958151042 0.3871026039 0.3483793139 + 0.3974870145 0.3886739910 0.3499442935 + 0.3991512060 0.3902403116 0.3515053093 + 0.4008058012 0.3918004930 0.3530634046 + 0.4024530053 0.3933542967 0.3546175063 + 0.4040930867 0.3949011862 0.3561685979 + 0.4057264924 0.3964413106 0.3577178121 + 0.4073539078 0.3979749084 0.3592661023 + 0.4089717865 0.3995010853 0.3608109057 + 0.4105815887 0.4010227919 0.3623529971 + 0.4121825993 0.4025394022 0.3638921082 + 0.4137746990 0.4040510952 0.3654282987 + 0.4153572917 0.4055579901 0.3669610918 + 0.4169301987 0.4070582092 0.3684917986 + 0.4184952080 0.4085538983 0.3700191975 + 0.4200516045 0.4100449979 0.3715431988 + 0.4215987027 0.4115310907 0.3730638027 + 0.4231320918 0.4130091071 0.3745814860 + 0.4246563911 0.4144822061 0.3760955930 + 0.4261722863 0.4159503877 0.3776068985 + 0.4276798964 0.4174129963 0.3791159987 + 0.4291754067 0.4188691974 0.3806217909 + 0.4306622148 0.4203203917 0.3821237981 + 0.4321402907 0.4217669070 0.3836225867 + 0.4336062968 0.4232077003 0.3851186037 + 0.4350613952 0.4246425927 0.3866108060 + 0.4365088940 0.4260734916 0.3881003857 + 0.4379490912 0.4275006056 0.3895873129 + 0.4393770993 0.4289224148 0.3910715878 + 0.4407972097 0.4303407967 0.3925527930 + 0.4422096014 0.4317556918 0.3940311074 + 0.4436098039 0.4331642091 0.3955051005 + 0.4449998140 0.4345675111 0.3969767988 + 0.4463821948 0.4359666109 0.3984459937 + 0.4477544129 0.4373601079 0.3999111950 + 0.4491179883 0.4387483895 0.4013735950 + 0.4504755139 0.4401332140 0.4028339982 + 0.4518243968 0.4415132105 0.4042919874 + 0.4531635940 0.4428895116 0.4057449996 + 0.4544965029 0.4442631900 0.4071955085 + 0.4558199048 0.4456324875 0.4086431861 + 0.4571351111 0.4469971061 0.4100872874 + 0.4584454000 0.4483583868 0.4115292132 + 0.4597485065 0.4497137070 0.4129675031 + 0.4610452950 0.4510636032 0.4144037068 + 0.4623377919 0.4524100125 0.4158385098 + 0.4636217058 0.4537501931 0.4172705114 + 0.4649001062 0.4550873041 0.4187003970 + 0.4661735892 0.4564214945 0.4201287925 + 0.4674373865 0.4577501118 0.4215534031 + 0.4686970115 0.4590756893 0.4229756892 + 0.4699491858 0.4603962004 0.4243943989 + 0.4711951911 0.4617125988 0.4258098900 + 0.4724380970 0.4630267918 0.4272238910 + 0.4736748040 0.4643347859 0.4286344051 + 0.4749085009 0.4656395018 0.4300416112 + 0.4761387110 0.4669404924 0.4314455986 + 0.4773631096 0.4682346880 0.4328455925 + 0.4785852134 0.4695264101 0.4342440069 + 0.4798015058 0.4708124995 0.4356383979 + 0.4810144007 0.4720954001 0.4370301068 + 0.4822235107 0.4733743072 0.4384193122 + 0.4834271073 0.4746474028 0.4398039877 + 0.4846287966 0.4759184122 0.4411869943 + 0.4858255088 0.4771836102 0.4425632954 + 0.4870207012 0.4784463942 0.4439373910 + 0.4882127941 0.4797044098 0.4453079998 + 0.4894016981 0.4809592068 0.4466761053 + 0.4905884862 0.4822115898 0.4480428994 + 0.4917714894 0.4834589958 0.4494043887 + 0.4929533005 0.4847050011 0.4507643878 + 0.4941304028 0.4859468937 0.4521192908 + 0.4953059852 0.4871870875 0.4534727931 + 0.4964784980 0.4884232879 0.4548236132 + 0.4976483881 0.4896576107 0.4561721087 + 0.4988156855 0.4908897877 0.4575186968 + 0.4999799132 0.4921190143 0.4588620961 + 0.5011426806 0.4933466911 0.4602043927 + 0.5023010969 0.4945699871 0.4615409970 + 0.5034586191 0.4957925081 0.4628765881 + 0.5046117902 0.4970094860 0.4642063081 + 0.5057641864 0.4982253909 0.4655351043 + 0.5069122910 0.4994361997 0.4668604136 + 0.5080590844 0.5006449223 0.4681833088 + 0.5092027783 0.5018489957 0.4695020914 + 0.5103443861 0.5030499101 0.4708178043 + 0.5114830136 0.5042467117 0.4721299112 + 0.5126193762 0.5054402947 0.4734382927 + 0.5137537122 0.5066308975 0.4747439027 + 0.5148848891 0.5078179240 0.4760439992 + 0.5160142183 0.5090023875 0.4773412049 + 0.5171405077 0.5101822019 0.4786339104 + 0.5182654262 0.5113596916 0.4799247086 + 0.5193868279 0.5125321746 0.4812121093 + 0.5205066800 0.5137025714 0.4824982882 + 0.5216233730 0.5148683786 0.4837796092 + 0.5227389932 0.5160326958 0.4850594997 + 0.5238509178 0.5171926022 0.4863342941 + 0.5249615908 0.5183511972 0.4876079857 + 0.5260689855 0.5195046067 0.4888750911 + 0.5271754265 0.5206564069 0.4901408851 + 0.5282781124 0.5218034983 0.4914003909 + 0.5293796062 0.5229489207 0.4926582873 + 0.5304781199 0.5240889788 0.4939117134 + 0.5315753818 0.5252268910 0.4951637089 + 0.5326694250 0.5263600945 0.4964101911 + 0.5337619185 0.5274910927 0.4976545870 + 0.5348516703 0.5286170840 0.4988938868 + 0.5359399915 0.5297397971 0.5001304746 + 0.5370256901 0.5308594704 0.5013629794 + 0.5381091237 0.5319762826 0.5025923252 + 0.5391908288 0.5330902934 0.5038173795 + 0.5402699709 0.5342003703 0.5050377846 + 0.5413478017 0.5353085995 0.5062550902 + 0.5424222946 0.5364122987 0.5074666739 + 0.5434960723 0.5375146866 0.5086768866 + 0.5445663929 0.5386111736 0.5098820925 + 0.5456367135 0.5397076011 0.5110868812 + 0.5467023253 0.5407969952 0.5122858882 + 0.5477678180 0.5418863893 0.5134847760 + 0.5488299727 0.5429692864 0.5146782994 + 0.5498914719 0.5440509915 0.5158712268 + 0.5509498715 0.5451288819 0.5170599818 + 0.5520067215 0.5462048054 0.5182471871 + 0.5530617237 0.5472781062 0.5194309950 + 0.5541145205 0.5483480096 0.5206112266 + 0.5551661849 0.5494166017 0.5217891932 + 0.5562142730 0.5504804254 0.5229610801 + 0.5572623014 0.5515441895 0.5241327286 + 0.5583065152 0.5526019931 0.5252950191 + 0.5593506098 0.5536596179 0.5264571905 + 0.5603913069 0.5547125936 0.5276136994 + 0.5614306927 0.5557637811 0.5287684202 + 0.5624685287 0.5568122864 0.5299198031 + 0.5635039210 0.5578569174 0.5310674906 + 0.5645387173 0.5589007735 0.5322136879 + 0.5655695796 0.5599387884 0.5333532095 + 0.5666003823 0.5609768033 0.5344926119 + 0.5676280856 0.5620093942 0.5356252789 + 0.5686550140 0.5630406141 0.5367568731 + 0.5696796775 0.5640686154 0.5378847122 + 0.5707020164 0.5650928020 0.5390092134 + 0.5717239976 0.5661163926 0.5401322842 + 0.5727424026 0.5671336055 0.5412485003 + 0.5737608075 0.5681508183 0.5423645973 + 0.5747758746 0.5691627264 0.5434734821 + 0.5757898092 0.5701727271 0.5445804000 + 0.5768023729 0.5711808205 0.5456839204 + 0.5778123736 0.5721849203 0.5467820168 + 0.5788223743 0.5731890202 0.5478801131 + 0.5798283219 0.5741881132 0.5489701033 + 0.5808337927 0.5751867294 0.5500597954 + 0.5818374753 0.5761824846 0.5511454940 + 0.5828391910 0.5771750808 0.5522276759 + 0.5838407278 0.5781676173 0.5533092022 + 0.5848379731 0.5791544914 0.5543829203 + 0.5858352184 0.5801414251 0.5554565787 + 0.5868303776 0.5811259151 0.5565248132 + 0.5878236890 0.5821083188 0.5575889945 + 0.5888170004 0.5830906034 0.5586525202 + 0.5898060203 0.5840693712 0.5597082973 + 0.5907949805 0.5850481987 0.5607640147 + 0.5917819738 0.5860245824 0.5618162751 + 0.5927671790 0.5869988799 0.5628659725 + 0.5937523842 0.5879732966 0.5639154911 + 0.5947332978 0.5889440179 0.5649582148 + 0.5957140923 0.5899146795 0.5660009980 + 0.5966933966 0.5908836126 0.5670400858 + 0.5976703763 0.5918499231 0.5680750012 + 0.5986474752 0.5928161144 0.5691099763 + 0.5996209979 0.5937793851 0.5701385736 + 0.6005936861 0.5947421193 0.5711663961 + 0.6015655994 0.5957037807 0.5721924901 + 0.6025345922 0.5966621041 0.5732141137 + 0.6035035849 0.5976204276 0.5742357969 + 0.6044700146 0.5985764861 0.5752530098 + 0.6054347157 0.5995312929 0.5762677789 + 0.6063994169 0.6004859805 0.5772826076 + 0.6073606014 0.6014366150 0.5782899261 + 0.6083216071 0.6023870111 0.5792971849 + 0.6092813015 0.6033363938 0.5803018212 + 0.6102380753 0.6042832136 0.5813007951 + 0.6111947894 0.6052300930 0.5822998285 + 0.6121494174 0.6061744094 0.5832931995 + 0.6131024957 0.6071168780 0.5842832923 + 0.6140555143 0.6080595255 0.5852733850 + 0.6150048971 0.6089988947 0.5862563252 + 0.6159536839 0.6099380255 0.5872384906 + 0.6169021130 0.6108763814 0.5882192254 + 0.6178473234 0.6118112206 0.5891932249 + 0.6187924743 0.6127460003 0.5901671052 + 0.6197360754 0.6136794090 0.5911372900 + 0.6206771135 0.6146106720 0.5921025276 + 0.6216180921 0.6155419946 0.5930677056 + 0.6225569844 0.6164706945 0.5940269232 + 0.6234943867 0.6173977852 0.5949828029 + 0.6244317889 0.6183248162 0.5959386826 + 0.6253659129 0.6192492247 0.5968865156 + 0.6262990832 0.6201726794 0.5978326797 + 0.6272323728 0.6210963130 0.5987787843 + 0.6281622052 0.6220158935 0.5997148156 + 0.6290917993 0.6229352951 0.6006507277 + 0.6300209761 0.6238542795 0.6015853286 + 0.6309465766 0.6247702837 0.6025123000 + 0.6318721175 0.6256862879 0.6034393907 + 0.6327968240 0.6266012788 0.6043639183 + 0.6337187886 0.6275131106 0.6052818894 + 0.6346408129 0.6284248829 0.6061998010 + 0.6355614066 0.6293355823 0.6071143150 + 0.6364793181 0.6302440166 0.6080229282 + 0.6373972297 0.6311523914 0.6089316010 + 0.6383137107 0.6320592165 0.6098359823 + 0.6392281055 0.6329634190 0.6107351780 + 0.6401425004 0.6338676810 0.6116343737 + 0.6410549879 0.6347705126 0.6125288010 + 0.6419653296 0.6356713772 0.6134184003 + 0.6428756118 0.6365723014 0.6143079996 + 0.6437842846 0.6374711990 0.6151924133 + 0.6446911097 0.6383680105 0.6160721779 + 0.6455978751 0.6392648816 0.6169518828 + 0.6465027928 0.6401593089 0.6178272963 + 0.6474056244 0.6410511136 0.6186987758 + 0.6483083963 0.6419429183 0.6195703149 + 0.6492096186 0.6428322792 0.6204382777 + 0.6501089931 0.6437187791 0.6213029027 + 0.6510083079 0.6446053982 0.6221675277 + 0.6519060135 0.6454898715 0.6230288744 + 0.6528013945 0.6463716030 0.6238865852 + 0.6536967158 0.6472532749 0.6247442961 + 0.6545909047 0.6481332779 0.6255992055 + 0.6554828286 0.6490098834 0.6264498830 + 0.6563746929 0.6498864293 0.6273005009 + 0.6572657228 0.6507614851 0.6281492114 + 0.6581537127 0.6516315937 0.6289927959 + 0.6590415835 0.6525018215 0.6298364997 + 0.6599292159 0.6533712149 0.6306790113 + 0.6608136892 0.6542350054 0.6315155029 + 0.6616982818 0.6550989151 0.6323519945 + 0.6625828743 0.6559628248 0.6331884265 + 0.6634635925 0.6568207741 0.6340178251 + 0.6643443108 0.6576786041 0.6348472238 + 0.6652249098 0.6585363150 0.6356766224 + 0.6661028862 0.6593894958 0.6365011930 + 0.6669800878 0.6602413058 0.6373249888 + 0.6678574085 0.6610931754 0.6381487846 + 0.6687322855 0.6619417071 0.6389691234 + 0.6696056724 0.6627879143 0.6397873759 + 0.6704791188 0.6636340022 0.6406056881 + 0.6713513136 0.6644781828 0.6414217949 + 0.6722213030 0.6653187871 0.6422346234 + 0.6730912924 0.6661595106 0.6430473924 + 0.6739609241 0.6669995189 0.6438593864 + 0.6748270988 0.6678348184 0.6446667910 + 0.6756932139 0.6686701179 0.6454741955 + 0.6765593886 0.6695052981 0.6462816000 + 0.6774228215 0.6703364253 0.6470842957 + 0.6782855988 0.6711664796 0.6478862166 + 0.6791484952 0.6719965935 0.6486880779 + 0.6800094247 0.6728242040 0.6494870782 + 0.6808683872 0.6736493111 0.6502835751 + 0.6817274094 0.6744744182 0.6510801911 + 0.6825857759 0.6752986908 0.6518756151 + 0.6834415793 0.6761190295 0.6526666880 + 0.6842973232 0.6769393086 0.6534578204 + 0.6851530075 0.6777595878 0.6542488933 + 0.6860055923 0.6785761118 0.6550366282 + 0.6868575811 0.6793918014 0.6558237076 + 0.6877095103 0.6802073717 0.6566109061 + 0.6885594130 0.6810206175 0.6573961973 + 0.6894065738 0.6818302274 0.6581792831 + 0.6902536750 0.6826397777 0.6589624286 + 0.6911007762 0.6834495068 0.6597452760 + 0.6919429898 0.6842535734 0.6605246067 + 0.6927852035 0.6850578189 0.6613038182 + 0.6936272979 0.6858618855 0.6620830894 + 0.6944670081 0.6866629720 0.6628600955 + 0.6953045130 0.6874614954 0.6636353731 + 0.6961420178 0.6882600188 0.6644108295 + 0.6969792247 0.6890581846 0.6651858091 + 0.6978119016 0.6898517013 0.6659575105 + 0.6986445785 0.6906450987 0.6667290926 + 0.6994773149 0.6914386153 0.6675007939 + 0.7003065944 0.6922283173 0.6682701707 + 0.7011330724 0.6930149794 0.6690381765 + 0.7019597292 0.6938015819 0.6698061824 + 0.7027862072 0.6945881844 0.6705740094 + 0.7036067843 0.6953691244 0.6713399291 + 0.7044274211 0.6961500049 0.6721059084 + 0.7052479982 0.6969308257 0.6728718281 + 0.7060660124 0.6977090240 0.6736367941 + 0.7068808079 0.6984837055 0.6744008064 + 0.7076956034 0.6992583871 0.6751648188 + 0.7085103989 0.7000331879 0.6759287715 + 0.7093204856 0.7008035183 0.6766912937 + 0.7101296782 0.7015730739 0.6774535775 + 0.7109388709 0.7023426890 0.6782159209 + 0.7117468715 0.7031109929 0.6789777875 + 0.7125505805 0.7038751245 0.6797384024 + 0.7133544087 0.7046391964 0.6804990768 + 0.7141581178 0.7054032087 0.6812598109 + 0.7149589062 0.7061647773 0.6820197105 + 0.7157574296 0.7069243193 0.6827788949 + 0.7165558934 0.7076838017 0.6835381985 + 0.7173544168 0.7084434032 0.6842973828 + 0.7181484103 0.7091985941 0.6850554943 + 0.7189418077 0.7099533081 0.6858134866 + 0.7197352052 0.7107080221 0.6865714788 + 0.7205278277 0.7114617229 0.6873291731 + 0.7213162780 0.7122108936 0.6880860925 + 0.7221047878 0.7129601240 0.6888428926 + 0.7228932977 0.7137092948 0.6895998120 + 0.7236797810 0.7144563198 0.6903561950 + 0.7244635820 0.7152001262 0.6911119819 + 0.7252473235 0.7159438729 0.6918678880 + 0.7260311246 0.7166876197 0.6926236749 + 0.7268118858 0.7174283862 0.6933789849 + 0.7275910974 0.7181674242 0.6941339970 + 0.7283703089 0.7189065218 0.6948890090 + 0.7291494012 0.7196455002 0.6956440210 + 0.7299249768 0.7203806043 0.6963983774 + 0.7306997180 0.7211148739 0.6971526146 + 0.7314745188 0.7218492031 0.6979069114 + 0.7322493196 0.7225834727 0.6986610889 + 0.7330183983 0.7233123183 0.6994134188 + 0.7337874770 0.7240409851 0.7001656890 + 0.7345564961 0.7247697115 0.7009178996 + 0.7353249788 0.7254979014 0.7016698718 + 0.7360888124 0.7262215018 0.7024201751 + 0.7368525863 0.7269449830 0.7031704187 + 0.7376164198 0.7276685834 0.7039207220 + 0.7383791208 0.7283911705 0.7046704888 + 0.7391375899 0.7291100025 0.7054188251 + 0.7398961186 0.7298288941 0.7061672211 + 0.7406545877 0.7305477262 0.7069156170 + 0.7414119244 0.7312654257 0.7076634169 + 0.7421655059 0.7319800258 0.7084097862 + 0.7429192066 0.7326945066 0.7091562748 + 0.7436727881 0.7334091067 0.7099028230 + 0.7444245815 0.7341225147 0.7106482983 + 0.7451719046 0.7348331809 0.7113916874 + 0.7459192276 0.7355439067 0.7121351957 + 0.7466664910 0.7362545729 0.7128785849 + 0.7474122047 0.7369639277 0.7136210203 + 0.7481539249 0.7376697063 0.7143614292 + 0.7488955855 0.7383756042 0.7151017189 + 0.7496371865 0.7390813828 0.7158420086 + 0.7503774762 0.7397862077 0.7165814042 + 0.7511134148 0.7404878736 0.7173187733 + 0.7518494129 0.7411895990 0.7180560827 + 0.7525852919 0.7418913245 0.7187933922 + 0.7533203959 0.7425922751 0.7195299864 + 0.7540513277 0.7432901263 0.7202641964 + 0.7547823191 0.7439879179 0.7209984064 + 0.7555131912 0.7446855903 0.7217326164 + 0.7562438250 0.7453832030 0.7224665284 + 0.7569695711 0.7460777760 0.7231976986 + 0.7576953769 0.7467724085 0.7239289880 + 0.7584211826 0.7474669814 0.7246602178 + 0.7591469884 0.7481616139 0.7253913879 + 0.7598674297 0.7488520145 0.7261208892 + 0.7605875134 0.7495421171 0.7268503904 + 0.7613074780 0.7502321005 0.7275798917 + 0.7620275021 0.7509222031 0.7283093929 + 0.7627431750 0.7516098022 0.7290375829 + 0.7634574771 0.7522965074 0.7297652960 + 0.7641718984 0.7529832125 0.7304931283 + 0.7648862004 0.7536699772 0.7312207818 + 0.7655977011 0.7543541789 0.7319474816 + 0.7663068771 0.7550362945 0.7326734066 + 0.7670161724 0.7557184100 0.7333992720 + 0.7677254081 0.7564005256 0.7341251969 + 0.7684330940 0.7570810914 0.7348505259 + 0.7691373229 0.7577580214 0.7355744839 + 0.7698414922 0.7584350109 0.7362985015 + 0.7705457211 0.7591118813 0.7370225787 + 0.7712497711 0.7597886920 0.7377464771 + 0.7719480991 0.7604609728 0.7384685278 + 0.7726464272 0.7611331940 0.7391905189 + 0.7733446956 0.7618054748 0.7399126291 + 0.7740430236 0.7624776959 0.7406346202 + 0.7747374177 0.7631471157 0.7413551211 + 0.7754303217 0.7638152242 0.7420752048 + 0.7761231065 0.7644832730 0.7427952290 + 0.7768160105 0.7651513815 0.7435151935 + 0.7775070071 0.7658178210 0.7442349195 + 0.7781947851 0.7664811015 0.7449539900 + 0.7788826227 0.7671443820 0.7456731200 + 0.7795704007 0.7678076029 0.7463921905 + 0.7802581787 0.7684708834 0.7471113205 + 0.7809401155 0.7691282034 0.7478293777 + 0.7816219926 0.7697854042 0.7485474944 + 0.7823038101 0.7704424858 0.7492656112 + 0.7829856873 0.7710996866 0.7499837279 + 0.7836645842 0.7717540264 0.7507011294 + 0.7843410969 0.7724062204 0.7514179945 + 0.7850177288 0.7730582952 0.7521349788 + 0.7856941819 0.7737104893 0.7528519034 + 0.7863702774 0.7743622065 0.7535687089 + 0.7870417833 0.7750092745 0.7542843819 + 0.7877132893 0.7756564021 0.7550001144 + 0.7883847952 0.7763035297 0.7557157874 + 0.7890563011 0.7769505978 0.7564315200 + 0.7897251844 0.7775946259 0.7571462989 + 0.7903923988 0.7782363892 0.7578606009 + 0.7910594940 0.7788782716 0.7585750222 + 0.7917265892 0.7795200944 0.7592893243 + 0.7923933864 0.7801616192 0.7600035071 + 0.7930548787 0.7807983756 0.7607163787 + 0.7937164903 0.7814353108 0.7614293098 + 0.7943781018 0.7820721269 0.7621421814 + 0.7950395942 0.7827090025 0.7628551126 + 0.7956982851 0.7833436728 0.7635670900 + 0.7963539958 0.7839763761 0.7642784715 + 0.7970097065 0.7846090794 0.7649897933 + 0.7976654172 0.7852417827 0.7657011151 + 0.7983211279 0.7858744860 0.7664124966 + 0.7989718914 0.7865037918 0.7671223283 + 0.7996219993 0.7871326208 0.7678319812 + 0.8002722263 0.7877613902 0.7685415745 + 0.8009223938 0.7883902192 0.7692512870 + 0.8015714288 0.7890179753 0.7699605227 + 0.8022168875 0.7896423936 0.7706683874 + 0.8028622866 0.7902668118 0.7713763118 + 0.8035078049 0.7908911705 0.7720841765 + 0.8041532040 0.7915155888 0.7727922201 + 0.8047962189 0.7921379209 0.7734990120 + 0.8054372072 0.7927585840 0.7742050290 + 0.8060783148 0.7933791876 0.7749111056 + 0.8067193031 0.7939997911 0.7756171227 + 0.8073604107 0.7946205139 0.7763231993 + 0.8079984188 0.7952384949 0.7770274878 + 0.8086358905 0.7958559990 0.7777315974 + 0.8092733026 0.7964735031 0.7784357071 + 0.8099107146 0.7970910072 0.7791396976 + 0.8105478287 0.7977082133 0.7798436284 + 0.8111795783 0.7983207703 0.7805455923 + 0.8118113279 0.7989333272 0.7812476158 + 0.8124430776 0.7995458841 0.7819495797 + 0.8130748868 0.8001585007 0.7826516032 + 0.8137050271 0.8007699251 0.7833529115 + 0.8143305779 0.8013781905 0.7840527296 + 0.8149561286 0.8019865155 0.7847524881 + 0.8155816197 0.8025947809 0.7854523063 + 0.8162071109 0.8032031059 0.7861521244 + 0.8168302774 0.8038098216 0.7868509293 + 0.8174502254 0.8044143915 0.7875484228 + 0.8180701137 0.8050190210 0.7882459164 + 0.8186900020 0.8056234717 0.7889434099 + 0.8193098903 0.8062281013 0.7896409035 + 0.8199270964 0.8068311214 0.7903370261 + 0.8205420971 0.8074325919 0.7910320759 + 0.8211570978 0.8080341220 0.7917271852 + 0.8217719793 0.8086355925 0.7924222946 + 0.8223869801 0.8092371225 0.7931174040 + 0.8229985237 0.8098356128 0.7938109040 + 0.8236079812 0.8104321957 0.7945033908 + 0.8242173791 0.8110287189 0.7951959968 + 0.8248267770 0.8116251826 0.7958884835 + 0.8254361749 0.8122218251 0.7965810895 + 0.8260415196 0.8128147125 0.7972719073 + 0.8266444802 0.8134055734 0.7979617715 + 0.8272475004 0.8139964938 0.7986516953 + 0.8278505206 0.8145874739 0.7993416190 + 0.8284534812 0.8151783943 0.8000316024 + 0.8290522099 0.8157662749 0.8007196188 + 0.8296483755 0.8163524866 0.8014068007 + 0.8302447200 0.8169388175 0.8020939827 + 0.8308408856 0.8175250292 0.8027811050 + 0.8314371109 0.8181111813 0.8034682870 + 0.8320297003 0.8186948895 0.8041536808 + 0.8326196074 0.8192769289 0.8048380017 + 0.8332095742 0.8198587894 0.8055223227 + 0.8337996006 0.8204407096 0.8062065840 + 0.8343895078 0.8210226893 0.8068909049 + 0.8349767923 0.8216028810 0.8075736761 + 0.8355613947 0.8221815228 0.8082550168 + 0.8361459970 0.8227599859 0.8089362979 + 0.8367305994 0.8233386278 0.8096176982 + 0.8373152018 0.8239170909 0.8102989793 + 0.8378980160 0.8244941235 0.8109787107 + 0.8384776711 0.8250682950 0.8116558790 + 0.8390573859 0.8256425858 0.8123331070 + 0.8396371007 0.8262168169 0.8130102158 + 0.8402168155 0.8267911077 0.8136873841 + 0.8407955170 0.8273645043 0.8143637180 + 0.8413699865 0.8279343843 0.8150367141 + 0.8419443965 0.8285043836 0.8157097101 + 0.8425189257 0.8290743232 0.8163827062 + 0.8430932760 0.8296442032 0.8170557022 + 0.8436678052 0.8302142024 0.8177286983 + 0.8442364931 0.8307793736 0.8183974028 + 0.8448051214 0.8313444853 0.8190662265 + 0.8453736901 0.8319095969 0.8197348714 + 0.8459423184 0.8324747086 0.8204035759 + 0.8465108275 0.8330397010 0.8210722804 + 0.8470758796 0.8336018920 0.8217378855 + 0.8476396799 0.8341627717 0.8224022985 + 0.8482034206 0.8347237706 0.8230667114 + 0.8487671018 0.8352848291 0.8237311244 + 0.8493307829 0.8358457088 0.8243954778 + 0.8498923182 0.8364052773 0.8250575066 + 0.8504505157 0.8369628191 0.8257161975 + 0.8510087132 0.8375203013 0.8263750076 + 0.8515669703 0.8380777836 0.8270336986 + 0.8521252275 0.8386353254 0.8276925087 + 0.8526831269 0.8391926289 0.8283507228 + 0.8532357216 0.8397459984 0.8290038705 + 0.8537883759 0.8402994871 0.8296570778 + 0.8543409705 0.8408529162 0.8303104043 + 0.8548936248 0.8414064050 0.8309636116 + 0.8554462194 0.8419598937 0.8316168189 + 0.8559948802 0.8425098062 0.8322660923 + 0.8565415144 0.8430578709 0.8329136968 + 0.8570882082 0.8436061144 0.8335613012 + 0.8576349020 0.8441541791 0.8342089057 + 0.8581814766 0.8447024226 0.8348565102 + 0.8587269783 0.8452494144 0.8355026841 + 0.8592686057 0.8457927704 0.8361449242 + 0.8598102927 0.8463361263 0.8367869854 + 0.8603519201 0.8468794227 0.8374292254 + 0.8608934879 0.8474227190 0.8380714059 + 0.8614351153 0.8479660153 0.8387135267 + 0.8619735241 0.8485065103 0.8393514156 + 0.8625109196 0.8490459919 0.8399881124 + 0.8630483150 0.8495854735 0.8406246901 + 0.8635855913 0.8501250148 0.8412613869 + 0.8641229868 0.8506644964 0.8418980837 + 0.8646594286 0.8512032032 0.8425334096 + 0.8651921749 0.8517394066 0.8431646824 + 0.8657249808 0.8522754908 0.8437960744 + 0.8662577868 0.8528116941 0.8444274068 + 0.8667905927 0.8533477783 0.8450586796 + 0.8673233986 0.8538839817 0.8456900120 + 0.8678523898 0.8544178009 0.8463178277 + 0.8683791757 0.8549503088 0.8469436765 + 0.8689060211 0.8554828167 0.8475697041 + 0.8694328070 0.8560153246 0.8481956124 + 0.8699597120 0.8565478921 0.8488215804 + 0.8704863787 0.8570802808 0.8494471908 + 0.8710079193 0.8576077819 0.8500669003 + 0.8715295196 0.8581352830 0.8506866097 + 0.8720510006 0.8586627841 0.8513063192 + 0.8725726008 0.8591902852 0.8519260287 + 0.8730940819 0.8597177863 0.8525456786 + 0.8736137748 0.8602437973 0.8531630039 + 0.8741300106 0.8607671261 0.8537763953 + 0.8746461868 0.8612903953 0.8543899059 + 0.8751623034 0.8618137240 0.8550032973 + 0.8756784797 0.8623369932 0.8556168079 + 0.8761947155 0.8628603220 0.8562303185 + 0.8767071962 0.8633813858 0.8568397164 + 0.8772177100 0.8639011979 0.8574470282 + 0.8777281046 0.8644211292 0.8580543995 + 0.8782384992 0.8649408817 0.8586617112 + 0.8787490129 0.8654606938 0.8592690825 + 0.8792594075 0.8659806252 0.8598763943 + 0.8797658086 0.8664970994 0.8604782820 + 0.8802716732 0.8670130968 0.8610795736 + 0.8807774782 0.8675292134 0.8616809249 + 0.8812834024 0.8680452108 0.8622822165 + 0.8817893267 0.8685612082 0.8628833890 + 0.8822947145 0.8690769076 0.8634842038 + 0.8827946782 0.8695878983 0.8640792966 + 0.8832945824 0.8700988889 0.8646745086 + 0.8837944865 0.8706098795 0.8652696013 + 0.8842945099 0.8711209297 0.8658648133 + 0.8847944140 0.8716319203 0.8664600253 + 0.8852931261 0.8721420169 0.8670535088 + 0.8857870102 0.8726484776 0.8676418066 + 0.8862808943 0.8731549978 0.8682301044 + 0.8867747784 0.8736615181 0.8688184023 + 0.8872687221 0.8741679788 0.8694065809 + 0.8877626061 0.8746744990 0.8699948788 + 0.8882550001 0.8751800060 0.8705809712 + 0.8887438774 0.8756831288 0.8711625934 + 0.8892328143 0.8761863112 0.8717442155 + 0.8897215724 0.8766893744 0.8723257780 + 0.8902105093 0.8771924973 0.8729074001 + 0.8906993866 0.8776956201 0.8734890223 + 0.8911864758 0.8781973720 0.8740683198 + 0.8916702867 0.8786967993 0.8746433854 + 0.8921542168 0.8791961074 0.8752185106 + 0.8926380277 0.8796954155 0.8757935762 + 0.8931217790 0.8801947236 0.8763688207 + 0.8936055899 0.8806940913 0.8769438863 + 0.8940873146 0.8811920285 0.8775168061 + 0.8945649266 0.8816872239 0.8780856133 + 0.8950424790 0.8821823001 0.8786544800 + 0.8955200911 0.8826774955 0.8792232871 + 0.8959977031 0.8831726909 0.8797922134 + 0.8964753151 0.8836678863 0.8803610802 + 0.8969513178 0.8841618896 0.8809276819 + 0.8974236250 0.8846526742 0.8814892769 + 0.8978958130 0.8851435781 0.8820508718 + 0.8983680010 0.8856344223 0.8826125264 + 0.8988403082 0.8861253262 0.8831741810 + 0.8993124962 0.8866161108 0.8837357759 + 0.8997837901 0.8871064186 0.8842961192 + 0.9002509117 0.8875938058 0.8848509789 + 0.9007179141 0.8880811930 0.8854060173 + 0.9011849761 0.8885685802 0.8859608769 + 0.9016519785 0.8890560269 0.8865159154 + 0.9021189809 0.8895434141 0.8870707750 + 0.9025859833 0.8900306821 0.8876255155 + 0.9030467272 0.8905134201 0.8881742954 + 0.9035072923 0.8909960985 0.8887230158 + 0.9039679766 0.8914787173 0.8892716765 + 0.9044287205 0.8919613957 0.8898203969 + 0.9048894048 0.8924440742 0.8903691769 + 0.9053500891 0.8929268122 0.8909178972 + 0.9058066010 0.8934053183 0.8914616704 + 0.9062620997 0.8938828707 0.8920044899 + 0.9067175984 0.8943604827 0.8925474286 + 0.9071730971 0.8948379755 0.8930901885 + 0.9076285958 0.8953155875 0.8936330080 + 0.9080840945 0.8957931995 0.8941758871 + 0.9085366726 0.8962686062 0.8947150111 + 0.9089869857 0.8967422247 0.8952515125 + 0.9094372988 0.8972157836 0.8957878947 + 0.9098876119 0.8976894021 0.8963243961 + 0.9103379250 0.8981630206 0.8968607783 + 0.9107881784 0.8986366987 0.8973972201 + 0.9112372994 0.8991093040 0.8979318142 + 0.9116824865 0.8995786905 0.8984611034 + 0.9121276736 0.9000480771 0.8989903927 + 0.9125729203 0.9005175233 0.8995196819 + 0.9130182266 0.9009870291 0.9000489712 + 0.9134634137 0.9014564157 0.9005783200 + 0.9139086008 0.9019258022 0.9011074901 + 0.9143493772 0.9023923278 0.9016308784 + 0.9147896171 0.9028583765 0.9021536112 + 0.9152297974 0.9033244848 0.9026762843 + 0.9156699777 0.9037905931 0.9031988978 + 0.9161102176 0.9042567015 0.9037215710 + 0.9165503979 0.9047226906 0.9042443037 + 0.9169877172 0.9051871896 0.9047639966 + 0.9174218178 0.9056496024 0.9052804708 + 0.9178559780 0.9061120749 0.9057971239 + 0.9182900786 0.9065744877 0.9063135982 + 0.9187241793 0.9070370197 0.9068300724 + 0.9191582799 0.9074993730 0.9073466063 + 0.9195923805 0.9079619050 0.9078630805 + 0.9200205803 0.9084206820 0.9083728194 + 0.9204487801 0.9088795185 0.9088826180 + 0.9208769798 0.9093382955 0.9093922973 + 0.9213051796 0.9097970724 0.9099020958 + 0.9217333794 0.9102559090 0.9104117751 + 0.9221615195 0.9107146263 0.9109215140 + 0.9225875139 0.9111716747 0.9114277959 + 0.9230108261 0.9116266966 0.9119303823 + 0.9234341979 0.9120817780 0.9124330878 + 0.9238576293 0.9125369191 0.9129356742 + 0.9242808819 0.9129918814 0.9134383202 + 0.9247043133 0.9134470224 0.9139409065 + 0.9251276851 0.9139019847 0.9144436121 + 0.9255468845 0.9143533707 0.9149402976 + 0.9259656072 0.9148042798 0.9154363871 + 0.9263843298 0.9152551889 0.9159325957 + 0.9268029928 0.9157060981 0.9164286852 + 0.9272217155 0.9161570072 0.9169248939 + 0.9276403785 0.9166079164 0.9174209833 + 0.9280576706 0.9170578122 0.9179155231 + 0.9284709096 0.9175047278 0.9184057117 + 0.9288840890 0.9179517031 0.9188959002 + 0.9292973280 0.9183986187 0.9193860888 + 0.9297105074 0.9188455939 0.9198762774 + 0.9301236868 0.9192925096 0.9203665257 + 0.9305369258 0.9197394848 0.9208567142 + 0.9309471846 0.9201840758 0.9213432074 + 0.9313554764 0.9206268787 0.9218271971 + 0.9317637086 0.9210698009 0.9223111272 + 0.9321720004 0.9215126038 0.9227951169 + 0.9325801730 0.9219554067 0.9232789874 + 0.9329885244 0.9223983288 0.9237629771 + 0.9333966970 0.9228410721 0.9242469072 + 0.9338006973 0.9232804775 0.9247245193 + 0.9342038035 0.9237191081 0.9252008200 + 0.9346070290 0.9241576791 0.9256771207 + 0.9350100756 0.9245964289 0.9261534810 + 0.9354133010 0.9250349998 0.9266297817 + 0.9358164072 0.9254735708 0.9271062016 + 0.9362192750 0.9259120822 0.9275822043 + 0.9366164804 0.9263464808 0.9280517101 + 0.9370136857 0.9267808795 0.9285210967 + 0.9374108911 0.9272152781 0.9289906025 + 0.9378080964 0.9276496768 0.9294601083 + 0.9382053018 0.9280840755 0.9299296141 + 0.9386025071 0.9285184741 0.9303991199 + 0.9389988780 0.9289522767 0.9308673143 + 0.9393916130 0.9293835163 0.9313306212 + 0.9397842884 0.9298146963 0.9317938089 + 0.9401770830 0.9302458763 0.9322569966 + 0.9405698180 0.9306771159 0.9327201843 + 0.9409624934 0.9311082959 0.9331833720 + 0.9413552284 0.9315395951 0.9336466193 + 0.9417470098 0.9319697022 0.9341077209 + 0.9421362281 0.9323967099 0.9345635176 + 0.9425255060 0.9328237176 0.9350193143 + 0.9429147243 0.9332507849 0.9354749918 + 0.9433040023 0.9336777925 0.9359307885 + 0.9436932206 0.9341048002 0.9363865256 + 0.9440824986 0.9345319271 0.9368423223 + 0.9444702864 0.9349573851 0.9372959733 + 0.9448544979 0.9353792071 0.9377450943 + 0.9452388287 0.9358010292 0.9381942153 + 0.9456230998 0.9362229109 0.9386432171 + 0.9460073113 0.9366446733 0.9390922785 + 0.9463915825 0.9370664954 0.9395413995 + 0.9467759132 0.9374883175 0.9399905205 + 0.9471582770 0.9379090071 0.9404376745 + 0.9475358129 0.9383267164 0.9408801198 + 0.9479132891 0.9387443066 0.9413226247 + 0.9482908249 0.9391620159 0.9417650104 + 0.9486683011 0.9395796061 0.9422073960 + 0.9490457773 0.9399973154 0.9426497817 + 0.9494233131 0.9404149055 0.9430922866 + 0.9497994184 0.9408314824 0.9435328841 + 0.9501690865 0.9412431121 0.9439659715 + 0.9505386949 0.9416546822 0.9443989992 + 0.9509084225 0.9420663118 0.9448320866 + 0.9512780905 0.9424778819 0.9452651739 + 0.9516478181 0.9428895116 0.9456983209 + 0.9520174861 0.9433010817 0.9461312890 + 0.9523869157 0.9437124729 0.9465638995 + 0.9527491927 0.9441193938 0.9469869137 + 0.9531115294 0.9445263147 0.9474099278 + 0.9534738064 0.9449331760 0.9478328824 + 0.9538360834 0.9453400970 0.9482558966 + 0.9541984200 0.9457470179 0.9486789107 + 0.9545606971 0.9461538792 0.9491018057 + 0.9549229741 0.9465608001 0.9495248199 + 0.9552813768 0.9469650984 0.9499412179 + 0.9556391239 0.9473688006 0.9503563046 + 0.9559966922 0.9477726221 0.9507713914 + 0.9563543200 0.9481763244 0.9511865973 + 0.9567118883 0.9485800862 0.9516016841 + 0.9570695162 0.9489837885 0.9520167708 + 0.9574272037 0.9493876100 0.9524319768 + 0.9577826262 0.9497889876 0.9528437853 + 0.9581363201 0.9501885772 0.9532533288 + 0.9584900737 0.9505882263 0.9536628127 + 0.9588438272 0.9509878159 0.9540722966 + 0.9591975808 0.9513874054 0.9544817805 + 0.9595512748 0.9517869949 0.9548913240 + 0.9599050879 0.9521865845 0.9553006887 + 0.9602577090 0.9525852203 0.9557086825 + 0.9606065750 0.9529808164 0.9561120272 + 0.9609556198 0.9533764124 0.9565153718 + 0.9613046050 0.9537721276 0.9569187164 + 0.9616534710 0.9541677237 0.9573221207 + 0.9620025158 0.9545633197 0.9577255249 + 0.9623513818 0.9549589753 0.9581288099 + 0.9627004266 0.9553545713 0.9585322142 + 0.9630452991 0.9557468891 0.9589298964 + 0.9633895755 0.9561386704 0.9593268037 + 0.9637339115 0.9565305114 0.9597237110 + 0.9640781879 0.9569222927 0.9601204991 + 0.9644225240 0.9573140740 0.9605174065 + 0.9647668004 0.9577057958 0.9609143138 + 0.9651110172 0.9580975771 0.9613112211 + 0.9654532075 0.9584879279 0.9617047906 + 0.9657922983 0.9588758945 0.9620940089 + 0.9661315084 0.9592639804 0.9624832273 + 0.9664705992 0.9596521258 0.9628723860 + 0.9668096900 0.9600400925 0.9632616043 + 0.9671489000 0.9604281783 0.9636508822 + 0.9674879909 0.9608163238 0.9640401006 + 0.9678270817 0.9612042904 0.9644293189 + 0.9681611061 0.9615883827 0.9648113251 + 0.9684945941 0.9619721174 0.9651926756 + 0.9688280225 0.9623557925 0.9655740857 + 0.9691613913 0.9627394080 0.9659554958 + 0.9694948792 0.9631230831 0.9663369060 + 0.9698283076 0.9635068178 0.9667183161 + 0.9701616764 0.9638903737 0.9670996070 + 0.9704933763 0.9642724991 0.9674782753 + 0.9708213806 0.9646512270 0.9678518176 + 0.9711495042 0.9650298953 0.9682253003 + 0.9714776278 0.9654086828 0.9685987830 + 0.9718056917 0.9657874107 0.9689723253 + 0.9721336961 0.9661661983 0.9693458080 + 0.9724618196 0.9665449262 0.9697191715 + 0.9727898836 0.9669237137 0.9700927138 + 0.9731143117 0.9672991037 0.9704605937 + 0.9734373093 0.9676731825 0.9708260894 + 0.9737601876 0.9680472016 0.9711915851 + 0.9740831852 0.9684212804 0.9715570807 + 0.9744061232 0.9687952995 0.9719226956 + 0.9747291207 0.9691693783 0.9722881913 + 0.9750519991 0.9695433974 0.9726536870 + 0.9753749967 0.9699174762 0.9730191231 + 0.9756926894 0.9702869058 0.9733765125 + 0.9760103822 0.9706562757 0.9737339020 + 0.9763280749 0.9710255861 0.9740912914 + 0.9766458273 0.9713950157 0.9744486809 + 0.9769635201 0.9717643857 0.9748060703 + 0.9772812128 0.9721338153 0.9751635194 + 0.9775989056 0.9725031853 0.9755209088 + 0.9779152274 0.9728714228 0.9758762121 + 0.9782270789 0.9732357860 0.9762253165 + 0.9785388708 0.9736002088 0.9765743017 + 0.9788507819 0.9739645720 0.9769234061 + 0.9791625738 0.9743289948 0.9772723913 + 0.9794744253 0.9746934772 0.9776214957 + 0.9797862768 0.9750579000 0.9779704809 + 0.9800981283 0.9754223228 0.9783195853 + 0.9804072976 0.9757844210 0.9786648750 + 0.9807128906 0.9761431813 0.9790049791 + 0.9810184240 0.9765020013 0.9793450832 + 0.9813238978 0.9768608212 0.9796851873 + 0.9816294909 0.9772195816 0.9800254107 + 0.9819350243 0.9775784016 0.9803655148 + 0.9822404981 0.9779372215 0.9807056189 + 0.9825460911 0.9782959819 0.9810457230 + 0.9828479290 0.9786517024 0.9813808799 + 0.9831464887 0.9790048003 0.9817116857 + 0.9834451079 0.9793578982 0.9820424914 + 0.9837437272 0.9797109962 0.9823732972 + 0.9840422869 0.9800640941 0.9827041030 + 0.9843410254 0.9804171920 0.9830349088 + 0.9846395850 0.9807702899 0.9833657146 + 0.9849382043 0.9811233878 0.9836965203 + 0.9852322936 0.9814730883 0.9840217233 + 0.9855231047 0.9818202257 0.9843425751 + 0.9858139157 0.9821674228 0.9846634865 + 0.9861047268 0.9825145006 0.9849843979 + 0.9863954782 0.9828615785 0.9853054285 + 0.9866862893 0.9832087755 0.9856262803 + 0.9869771004 0.9835559130 0.9859471917 + 0.9872679114 0.9839029908 0.9862681031 + 0.9875541925 0.9842463732 0.9865829945 + 0.9878368974 0.9845867157 0.9868929982 + 0.9881196022 0.9849269986 0.9872030020 + 0.9884023070 0.9852672815 0.9875130057 + 0.9886850119 0.9856076241 0.9878228903 + 0.9889677167 0.9859479070 0.9881328940 + 0.9892504215 0.9862881899 0.9884428978 + 0.9895331264 0.9866284728 0.9887529016 + 0.9898114204 0.9869654179 0.9890568256 + 0.9900845885 0.9872981906 0.9893537164 + 0.9903576970 0.9876310825 0.9896506071 + 0.9906309247 0.9879639149 0.9899474978 + 0.9909039736 0.9882966876 0.9902443886 + 0.9911772013 0.9886295795 0.9905412793 + 0.9914503098 0.9889624119 0.9908382297 + 0.9917234778 0.9892953038 0.9911351204 + 0.9919933081 0.9896262288 0.9914277196 + 0.9922555089 0.9899526834 0.9917106032 + 0.9925177097 0.9902790785 0.9919934273 + 0.9927799106 0.9906055927 0.9922763109 + 0.9930421114 0.9909321070 0.9925591946 + 0.9933043122 0.9912585020 0.9928420782 + 0.9935665131 0.9915850163 0.9931250215 + 0.9938287139 0.9919114709 0.9934079051 + 0.9940900207 0.9922373891 0.9936895967 + 0.9943411946 0.9925572872 0.9939587712 + 0.9945924878 0.9928773046 0.9942278862 + 0.9948437214 0.9931972027 0.9944971204 + 0.9950950146 0.9935171008 0.9947661757 + 0.9953461885 0.9938369989 0.9950354099 + 0.9955974221 0.9941570163 0.9953045845 + 0.9958487153 0.9944769144 0.9955736995 + 0.9960998893 0.9947968125 0.9958428741 + 0.9963402152 0.9951102734 0.9960997105 + 0.9965775013 0.9954220057 0.9963533282 + 0.9968149066 0.9957337976 0.9966068864 + 0.9970521927 0.9960455894 0.9968605042 + 0.9972895980 0.9963573217 0.9971140027 + 0.9975268841 0.9966691136 0.9973676205 + 0.9977642894 0.9969809055 0.9976211786 + 0.9980015755 0.9972925782 0.9978747964 + 0.9982318878 0.9975994229 0.9981204271 + 0.9984529018 0.9978994727 0.9983553290 + 0.9986739755 0.9981995225 0.9985902905 + 0.9988949895 0.9984995723 0.9988251925 + 0.9991160035 0.9987996817 0.9990602136 + 0.9993370175 0.9990997910 0.9992951155 + 0.9995579720 0.9993997812 0.9995300770 + 0.9997789860 0.9996998906 0.9997649789 + 1.0000000000 1.0000000000 1.0000000000 +} diff --git a/rpplugins/color_correction/resources/film_luts_raw/agfa_agfacolor_vista_200.spi1d b/rpplugins/color_correction/resources/film_luts_raw/agfa_agfacolor_vista_200.spi1d new file mode 100644 index 0000000..4ef1e35 --- /dev/null +++ b/rpplugins/color_correction/resources/film_luts_raw/agfa_agfacolor_vista_200.spi1d @@ -0,0 +1,1030 @@ +Version 1 +From 0.0 1.0 +Length 1024 +Components 3 +{ + 0.0000000000 0.0000000000 0.0000000000 + 0.0182101503 0.0179095902 0.0133477096 + 0.0321649686 0.0326713808 0.0245428905 + 0.0435327813 0.0445400514 0.0339762792 + 0.0535616502 0.0549106896 0.0424365215 + 0.0627619624 0.0643109381 0.0502561592 + 0.0713807195 0.0730527714 0.0576005317 + 0.0795889422 0.0812662989 0.0646079034 + 0.0874749497 0.0890629813 0.0713189989 + 0.0951398313 0.0965353027 0.0778023675 + 0.1026329994 0.1037214994 0.0840878412 + 0.1098783985 0.1106367037 0.0901622772 + 0.1168456972 0.1172993034 0.0960228518 + 0.1235098019 0.1237140000 0.1016969979 + 0.1299058944 0.1299183965 0.1071913987 + 0.1360470951 0.1359218955 0.1125032008 + 0.1419679970 0.1417497993 0.1176472977 + 0.1476961970 0.1474111974 0.1226311028 + 0.1532527953 0.1529219002 0.1274778992 + 0.1586499959 0.1582891047 0.1321873963 + 0.1639094949 0.1635248065 0.1367731988 + 0.1690364927 0.1686291993 0.1412428021 + 0.1740324050 0.1736201942 0.1455994993 + 0.1789164990 0.1784920990 0.1498488039 + 0.1836923957 0.1832599044 0.1539963931 + 0.1883690059 0.1879281998 0.1580594927 + 0.1929446012 0.1924999058 0.1620312035 + 0.1974374950 0.1969808936 0.1659148932 + 0.2018467933 0.2013725042 0.1697210968 + 0.2061869949 0.2056811005 0.1734540015 + 0.2104454935 0.2099131942 0.1771208942 + 0.2146379054 0.2140665054 0.1807264984 + 0.2187689990 0.2181411982 0.1842699945 + 0.2228457928 0.2221457958 0.1877449006 + 0.2268676013 0.2260929942 0.1911672056 + 0.2308367044 0.2299744040 0.1945340037 + 0.2347573936 0.2337978929 0.1978531927 + 0.2386282980 0.2375611067 0.2011176944 + 0.2424549013 0.2412583977 0.2043330073 + 0.2462375015 0.2449042946 0.2075064927 + 0.2499749959 0.2485097051 0.2106339037 + 0.2536737919 0.2520638108 0.2137185931 + 0.2573330998 0.2555652857 0.2167686969 + 0.2609579861 0.2590112984 0.2197788060 + 0.2645516098 0.2624117136 0.2227548957 + 0.2681075931 0.2657625973 0.2257010043 + 0.2716293931 0.2690761089 0.2286102027 + 0.2751240134 0.2723546028 0.2314918935 + 0.2785834074 0.2755965889 0.2343432009 + 0.2820093036 0.2787989080 0.2371643037 + 0.2854062021 0.2819635868 0.2399580032 + 0.2887754142 0.2850886881 0.2427307069 + 0.2921054959 0.2881690860 0.2454746962 + 0.2953915000 0.2912029028 0.2481936961 + 0.2986359894 0.2941966951 0.2508893013 + 0.3018450141 0.2971538901 0.2535605133 + 0.3050135970 0.3000777960 0.2562063038 + 0.3081485033 0.3029662073 0.2588256896 + 0.3112491965 0.3058190048 0.2614240944 + 0.3143157065 0.3086350858 0.2640033066 + 0.3173457086 0.3114137053 0.2665627897 + 0.3203401864 0.3141573966 0.2691006958 + 0.3232952952 0.3168714046 0.2716197073 + 0.3262135088 0.3195553124 0.2741247118 + 0.3290931880 0.3222120106 0.2766116858 + 0.3319376111 0.3248479962 0.2790769935 + 0.3347463012 0.3274633884 0.2815260887 + 0.3375192881 0.3300592899 0.2839562893 + 0.3402611911 0.3326362073 0.2863681912 + 0.3429714143 0.3351945877 0.2887654006 + 0.3456538916 0.3377344012 0.2911457121 + 0.3483096957 0.3402554095 0.2935140133 + 0.3509393930 0.3427593112 0.2958686948 + 0.3535420001 0.3452464938 0.2982082963 + 0.3561150134 0.3477157056 0.3005363941 + 0.3586607873 0.3501690924 0.3028526008 + 0.3611787856 0.3526060879 0.3051568866 + 0.3636738956 0.3550266922 0.3074469864 + 0.3661471903 0.3574325144 0.3097249866 + 0.3686017990 0.3598220050 0.3119905889 + 0.3710421920 0.3621949852 0.3142440021 + 0.3734661043 0.3645452857 0.3164834976 + 0.3758763969 0.3668780029 0.3187099993 + 0.3782708049 0.3691841960 0.3209230006 + 0.3806518912 0.3714686930 0.3231270015 + 0.3830181956 0.3737291098 0.3253178000 + 0.3853709102 0.3759689927 0.3274958134 + 0.3877105117 0.3781890869 0.3296644986 + 0.3900356889 0.3803892136 0.3318220973 + 0.3923485875 0.3825727105 0.3339678943 + 0.3946483135 0.3847385943 0.3360984921 + 0.3969348967 0.3868887126 0.3382169902 + 0.3992097080 0.3890219927 0.3403255939 + 0.4014719129 0.3911359906 0.3424212933 + 0.4037215114 0.3932318985 0.3445019126 + 0.4059596956 0.3953123093 0.3465686142 + 0.4081867933 0.3973782957 0.3486247063 + 0.4103969038 0.3994235098 0.3506675959 + 0.4125916958 0.4014526010 0.3526985049 + 0.4147717953 0.4034663141 0.3547205925 + 0.4169346094 0.4054656029 0.3567343056 + 0.4190779030 0.4074513912 0.3587369919 + 0.4212022126 0.4094235003 0.3607279956 + 0.4233098924 0.4113812149 0.3627093136 + 0.4254015088 0.4133256972 0.3646796942 + 0.4274776876 0.4152582884 0.3666377068 + 0.4295392036 0.4171769023 0.3685849011 + 0.4315859079 0.4190813899 0.3705236912 + 0.4336147010 0.4209738970 0.3724532127 + 0.4356271923 0.4228563905 0.3743726909 + 0.4376241863 0.4247288108 0.3762832880 + 0.4396047890 0.4265901148 0.3781884909 + 0.4415675104 0.4284402132 0.3800868988 + 0.4435133040 0.4302783012 0.3819774091 + 0.4454411864 0.4321058095 0.3838588893 + 0.4473508894 0.4339239895 0.3857302964 + 0.4492434859 0.4357284009 0.3875930905 + 0.4511201978 0.4375185072 0.3894470930 + 0.4529820085 0.4392957091 0.3912915885 + 0.4548301101 0.4410578907 0.3931255937 + 0.4566622972 0.4428066909 0.3949485123 + 0.4584765136 0.4445427954 0.3967649043 + 0.4602738023 0.4462682009 0.3985747099 + 0.4620555043 0.4479798973 0.4003768861 + 0.4638229907 0.4496806860 0.4021708071 + 0.4655745029 0.4513705969 0.4039582014 + 0.4673084915 0.4530492127 0.4057385027 + 0.4690262079 0.4547170997 0.4075132012 + 0.4707291126 0.4563761950 0.4092822969 + 0.4724188149 0.4580253959 0.4110448956 + 0.4740945101 0.4596652091 0.4128004014 + 0.4757550955 0.4612967968 0.4145481884 + 0.4774011075 0.4629195929 0.4162878096 + 0.4790340960 0.4645322859 0.4180184007 + 0.4806557000 0.4661347866 0.4197404087 + 0.4822664857 0.4677279890 0.4214550853 + 0.4838629961 0.4693109989 0.4231620133 + 0.4854427874 0.4708836973 0.4248597026 + 0.4870088995 0.4724482000 0.4265482128 + 0.4885635972 0.4740057886 0.4282296002 + 0.4901061058 0.4755555987 0.4299038947 + 0.4916355014 0.4770967066 0.4315708876 + 0.4931511879 0.4786292911 0.4332301915 + 0.4946528077 0.4801545143 0.4348819852 + 0.4961408973 0.4816705883 0.4365274012 + 0.4976170063 0.4831782877 0.4381654859 + 0.4990840852 0.4846773148 0.4397968054 + 0.5005418062 0.4861674011 0.4414210916 + 0.5019897819 0.4876480103 0.4430381060 + 0.5034281015 0.4891189933 0.4446476102 + 0.5048564076 0.4905793965 0.4462502003 + 0.5062754154 0.4920318127 0.4478481114 + 0.5076872110 0.4934777915 0.4494414032 + 0.5090919137 0.4949184060 0.4510299861 + 0.5104892850 0.4963541031 0.4526137114 + 0.5118765831 0.4977797866 0.4541929066 + 0.5132548809 0.4991959929 0.4557681084 + 0.5146262050 0.5006046891 0.4573394060 + 0.5159909725 0.5020067096 0.4589067101 + 0.5173475742 0.5034021735 0.4604690969 + 0.5186926126 0.5047916770 0.4620254934 + 0.5200299025 0.5061759949 0.4635772109 + 0.5213602781 0.5075541139 0.4651241004 + 0.5226839185 0.5089235902 0.4666649997 + 0.5240020156 0.5102841854 0.4681988955 + 0.5253158808 0.5116395950 0.4697273076 + 0.5266252756 0.5129901171 0.4712502062 + 0.5279287100 0.5143331885 0.4727657139 + 0.5292261243 0.5156680942 0.4742735922 + 0.5305185914 0.5169963837 0.4757766128 + 0.5318061113 0.5183182955 0.4772751927 + 0.5330879092 0.5196315050 0.4787661135 + 0.5343660116 0.5209389925 0.4802523851 + 0.5356402993 0.5222411752 0.4817340076 + 0.5369089246 0.5235363245 0.4832083881 + 0.5381723046 0.5248249173 0.4846785069 + 0.5394316912 0.5261074901 0.4861451089 + 0.5406854153 0.5273811817 0.4876070917 + 0.5419325829 0.5286462903 0.4890637100 + 0.5431752801 0.5299065113 0.4905168116 + 0.5444123149 0.5311611295 0.4919654131 + 0.5456442237 0.5324099064 0.4934079051 + 0.5468729138 0.5336548090 0.4948467910 + 0.5480973125 0.5348948240 0.4962810874 + 0.5493161082 0.5361279249 0.4977090061 + 0.5505313873 0.5373569727 0.4991332889 + 0.5517416000 0.5385804772 0.5005524158 + 0.5529457927 0.5397964120 0.5019652843 + 0.5541468859 0.5410084128 0.5033745766 + 0.5553439856 0.5422148705 0.5047777891 + 0.5565372705 0.5434154272 0.5061753988 + 0.5577278137 0.5446121097 0.5075693727 + 0.5589103103 0.5458009839 0.5089558959 + 0.5600882173 0.5469862819 0.5103380084 + 0.5612615943 0.5481684208 0.5117158890 + 0.5624287128 0.5493460298 0.5130857825 + 0.5635939837 0.5505207777 0.5144522190 + 0.5647562146 0.5516902208 0.5158123970 + 0.5659151077 0.5528519750 0.5171663761 + 0.5670722127 0.5540099740 0.5185170174 + 0.5682216287 0.5551596284 0.5198565125 + 0.5693680048 0.5563063025 0.5211923718 + 0.5705093145 0.5574489832 0.5225226283 + 0.5716463923 0.5585880280 0.5238460898 + 0.5727816820 0.5597252250 0.5251665711 + 0.5739135742 0.5608549118 0.5264781117 + 0.5750433803 0.5619807243 0.5277863741 + 0.5761687756 0.5630995035 0.5290886760 + 0.5772883892 0.5642123818 0.5303848982 + 0.5784044862 0.5653222799 0.5316777825 + 0.5795143247 0.5664256811 0.5329598784 + 0.5806226730 0.5675271749 0.5342394114 + 0.5817270875 0.5686224103 0.5355114937 + 0.5828294754 0.5697141886 0.5367797017 + 0.5839291215 0.5708016157 0.5380430222 + 0.5850237012 0.5718852878 0.5393006206 + 0.5861157179 0.5729672909 0.5405554175 + 0.5872008204 0.5740441084 0.5418028235 + 0.5882844925 0.5751196146 0.5430486798 + 0.5893629789 0.5761870146 0.5442872047 + 0.5904405713 0.5772519112 0.5455237031 + 0.5915157199 0.5783103704 0.5467544794 + 0.5925881267 0.5793656707 0.5479820967 + 0.5936570168 0.5804172754 0.5492056012 + 0.5947207212 0.5814660788 0.5504246950 + 0.5957809091 0.5825130939 0.5516411066 + 0.5968360901 0.5835543871 0.5528522134 + 0.5978894830 0.5845938921 0.5540617108 + 0.5989391208 0.5856245756 0.5552654266 + 0.5999881029 0.5866541862 0.5564681888 + 0.6010323763 0.5876761079 0.5576648116 + 0.6020759940 0.5886973739 0.5588607192 + 0.6031129956 0.5897135735 0.5600510836 + 0.6041488051 0.5907285810 0.5612400770 + 0.6051782966 0.5917387009 0.5624223948 + 0.6062065959 0.5927467942 0.5636029243 + 0.6072307825 0.5937488079 0.5647776127 + 0.6082534790 0.5947481990 0.5659500957 + 0.6092721820 0.5957416296 0.5671173930 + 0.6102892160 0.5967329144 0.5682824850 + 0.6113023162 0.5977199078 0.5694428086 + 0.6123135090 0.5987045169 0.5706002116 + 0.6133208871 0.5996844769 0.5717515945 + 0.6143262982 0.6006621718 0.5729001760 + 0.6153277755 0.6016355753 0.5740433931 + 0.6163274050 0.6026067138 0.5751839876 + 0.6173228025 0.6035735011 0.5763192177 + 0.6183164120 0.6045382023 0.5774521828 + 0.6193056703 0.6054980159 0.5785800815 + 0.6202933788 0.6064559221 0.5797063112 + 0.6212763786 0.6074082851 0.5808271170 + 0.6222583055 0.6083593965 0.5819467902 + 0.6232348084 0.6093046069 0.5830612183 + 0.6242107153 0.6102492809 0.5841749907 + 0.6251806021 0.6111894846 0.5852832198 + 0.6261504889 0.6121296883 0.5863913894 + 0.6271138787 0.6130650043 0.5874921083 + 0.6280770898 0.6140003204 0.5885927081 + 0.6290364861 0.6149287820 0.5896871090 + 0.6299952865 0.6158562899 0.5907804966 + 0.6309506893 0.6167783141 0.5918691754 + 0.6319050193 0.6176983714 0.5929561257 + 0.6328564286 0.6186152101 0.5940394998 + 0.6338058114 0.6195300221 0.5951203108 + 0.6347532272 0.6204434037 0.5961987972 + 0.6356977224 0.6213548779 0.5972741246 + 0.6366410255 0.6222651005 0.5983482003 + 0.6375805140 0.6231712103 0.5994184017 + 0.6385198832 0.6240770817 0.6004886031 + 0.6394541860 0.6249756217 0.6015521884 + 0.6403884888 0.6258741021 0.6026158929 + 0.6413171291 0.6267682910 0.6036748886 + 0.6422441006 0.6276612878 0.6047325730 + 0.6431670189 0.6285513043 0.6057875156 + 0.6440864801 0.6294386983 0.6068398952 + 0.6450045109 0.6303241253 0.6078910232 + 0.6459187269 0.6312044263 0.6089388132 + 0.6468328238 0.6320846081 0.6099866033 + 0.6477437019 0.6329575181 0.6110302806 + 0.6486546993 0.6338304281 0.6120740771 + 0.6495618224 0.6346995831 0.6131126285 + 0.6504672766 0.6355671883 0.6141489744 + 0.6513699889 0.6364325881 0.6151828170 + 0.6522679925 0.6372947097 0.6162124276 + 0.6531658173 0.6381564736 0.6172416806 + 0.6540582776 0.6390134096 0.6182652116 + 0.6549509168 0.6398702264 0.6192886233 + 0.6558411717 0.6407238245 0.6203082800 + 0.6567304134 0.6415758729 0.6213262081 + 0.6576179862 0.6424263716 0.6223418713 + 0.6585016847 0.6432734728 0.6233528256 + 0.6593855023 0.6441205740 0.6243637204 + 0.6602624059 0.6449629068 0.6253690124 + 0.6611385942 0.6458048224 0.6263738275 + 0.6620121002 0.6466442943 0.6273748279 + 0.6628826857 0.6474813819 0.6283720732 + 0.6637530923 0.6483181715 0.6293689013 + 0.6646183133 0.6491507292 0.6303573847 + 0.6654834747 0.6499832869 0.6313458085 + 0.6663444042 0.6508116722 0.6323295832 + 0.6672021747 0.6516373754 0.6333100796 + 0.6680591702 0.6524623036 0.6342896819 + 0.6689094901 0.6532815099 0.6352627873 + 0.6697599292 0.6541007161 0.6362358928 + 0.6706069708 0.6549171805 0.6372048855 + 0.6714519858 0.6557319760 0.6381713152 + 0.6722967029 0.6565461755 0.6391372085 + 0.6731383204 0.6573548913 0.6400974989 + 0.6739798784 0.6581636071 0.6410579085 + 0.6748195887 0.6589679122 0.6420152187 + 0.6756578088 0.6597688198 0.6429703236 + 0.6764960289 0.6605696082 0.6439253092 + 0.6773291230 0.6613646746 0.6448736787 + 0.6781619787 0.6621596813 0.6458221078 + 0.6789928079 0.6629531980 0.6467680931 + 0.6798204780 0.6637446284 0.6477108002 + 0.6806482077 0.6645358801 0.6486533880 + 0.6814717054 0.6653245091 0.6495919824 + 0.6822941899 0.6661124825 0.6505295038 + 0.6831157207 0.6668993831 0.6514660120 + 0.6839330792 0.6676816940 0.6523975730 + 0.6847504973 0.6684640050 0.6533290744 + 0.6855651736 0.6692435145 0.6542578936 + 0.6863775253 0.6700205207 0.6551842093 + 0.6871898174 0.6707975864 0.6561105847 + 0.6879963279 0.6715716720 0.6570330858 + 0.6888018250 0.6723455191 0.6579551101 + 0.6896061897 0.6731184125 0.6588761210 + 0.6904050112 0.6738871932 0.6597927213 + 0.6912037730 0.6746560931 0.6607092023 + 0.6920003891 0.6754217744 0.6616228223 + 0.6927945018 0.6761841178 0.6625328064 + 0.6935886145 0.6769462824 0.6634427905 + 0.6943795085 0.6777051091 0.6643487811 + 0.6951690912 0.6784626842 0.6652531028 + 0.6959587932 0.6792201996 0.6661574841 + 0.6967442036 0.6799734235 0.6670572758 + 0.6975293159 0.6807262897 0.6679568291 + 0.6983137727 0.6814782023 0.6688550711 + 0.6990944743 0.6822254062 0.6697469950 + 0.6998751163 0.6829724908 0.6706389785 + 0.7006543279 0.6837174892 0.6715285182 + 0.7014306784 0.6844587922 0.6724137068 + 0.7022070885 0.6851999760 0.6732988954 + 0.7029811740 0.6859381795 0.6741808057 + 0.7037534118 0.6866738200 0.6750599742 + 0.7045254707 0.6874092817 0.6759392023 + 0.7052934766 0.6881412268 0.6768147945 + 0.7060595751 0.6888713837 0.6776887774 + 0.7068256140 0.6896017194 0.6785628200 + 0.7075870037 0.6903280020 0.6794317961 + 0.7083472013 0.6910533905 0.6802995801 + 0.7091073990 0.6917787790 0.6811674237 + 0.7098640800 0.6924982071 0.6820288897 + 0.7106204033 0.6932169795 0.6828898191 + 0.7113767266 0.6939358115 0.6837506890 + 0.7121276259 0.6946483254 0.6846057177 + 0.7128784060 0.6953607798 0.6854606867 + 0.7136288881 0.6960731149 0.6863154173 + 0.7143725157 0.6967815161 0.6871635914 + 0.7151160836 0.6974899173 0.6880118847 + 0.7158594131 0.6981980801 0.6888597012 + 0.7165976167 0.6989027858 0.6897020936 + 0.7173358798 0.6996076107 0.6905444860 + 0.7180739045 0.7003120780 0.6913864017 + 0.7188072801 0.7010132074 0.6922219992 + 0.7195405960 0.7017142773 0.6930575967 + 0.7202737927 0.7024151087 0.6938928962 + 0.7210023999 0.7031126022 0.6947227716 + 0.7217310071 0.7038099766 0.6955527067 + 0.7224596143 0.7045074105 0.6963825822 + 0.7231836915 0.7052016854 0.6972076297 + 0.7239078283 0.7058959007 0.6980326772 + 0.7246319056 0.7065901160 0.6988577247 + 0.7253506184 0.7072818279 0.6996777058 + 0.7260687947 0.7079733014 0.7004973292 + 0.7267869711 0.7086647749 0.7013168931 + 0.7275004983 0.7093524933 0.7021313906 + 0.7282128930 0.7100393772 0.7029448152 + 0.7289254069 0.7107263207 0.7037581801 + 0.7296341062 0.7114102840 0.7045679092 + 0.7303411961 0.7120929956 0.7053759098 + 0.7310482860 0.7127758265 0.7061840296 + 0.7317516804 0.7134565115 0.7069895864 + 0.7324519753 0.7141355872 0.7077932954 + 0.7331522107 0.7148147225 0.7085970044 + 0.7338507175 0.7154917121 0.7093988061 + 0.7345461249 0.7161653042 0.7101973295 + 0.7352414727 0.7168390155 0.7109956741 + 0.7359364033 0.7175115943 0.7117931843 + 0.7366288900 0.7181801796 0.7125861049 + 0.7373213172 0.7188488245 0.7133789062 + 0.7380138040 0.7195172906 0.7141718268 + 0.7387021184 0.7201828957 0.7149586082 + 0.7393900752 0.7208483815 0.7157452106 + 0.7400780916 0.7215139270 0.7165318131 + 0.7407631874 0.7221763134 0.7173146009 + 0.7414469719 0.7228373885 0.7180958986 + 0.7421306968 0.7234985232 0.7188770771 + 0.7428128123 0.7241570950 0.7196565866 + 0.7434924841 0.7248123884 0.7204334736 + 0.7441722155 0.7254676819 0.7212104201 + 0.7448515892 0.7261224985 0.7219868898 + 0.7455275059 0.7267739773 0.7227588296 + 0.7462034225 0.7274255157 0.7235307097 + 0.7468793988 0.7280768752 0.7243025899 + 0.7475525737 0.7287256122 0.7250691056 + 0.7482250929 0.7293733954 0.7258337736 + 0.7488974929 0.7300211787 0.7265986204 + 0.7495679855 0.7306671739 0.7273609042 + 0.7502354980 0.7313104868 0.7281196117 + 0.7509030104 0.7319536805 0.7288782001 + 0.7515705228 0.7325968742 0.7296367884 + 0.7522333264 0.7332357764 0.7303904295 + 0.7528960109 0.7338746786 0.7311440110 + 0.7535588145 0.7345135808 0.7318975925 + 0.7542191148 0.7351499796 0.7326478958 + 0.7548775077 0.7357847095 0.7333958745 + 0.7555359006 0.7364193797 0.7341439128 + 0.7561935782 0.7370532751 0.7348909974 + 0.7568460703 0.7376828790 0.7356327176 + 0.7574986815 0.7383124828 0.7363743782 + 0.7581512928 0.7389420867 0.7371160984 + 0.7588003278 0.7395684719 0.7378535271 + 0.7594472766 0.7401931286 0.7385885119 + 0.7600942850 0.7408177853 0.7393234968 + 0.7607408166 0.7414417863 0.7400577068 + 0.7613841295 0.7420616746 0.7407870889 + 0.7620275021 0.7426816225 0.7415165901 + 0.7626708746 0.7433015108 0.7422459722 + 0.7633122802 0.7439180017 0.7429726720 + 0.7639523745 0.7445324063 0.7436977029 + 0.7645925283 0.7451466918 0.7444226146 + 0.7652325034 0.7457607985 0.7451472878 + 0.7658681273 0.7463697195 0.7458673120 + 0.7665035725 0.7469785810 0.7465873957 + 0.7671391964 0.7475875020 0.7473074198 + 0.7677729130 0.7481939793 0.7480244040 + 0.7684043050 0.7487975955 0.7487375736 + 0.7690356970 0.7494012117 0.7494506836 + 0.7696670890 0.7500048876 0.7501639128 + 0.7702953815 0.7506046295 0.7508723140 + 0.7709228992 0.7512034774 0.7515797019 + 0.7715504766 0.7518025041 0.7522869706 + 0.7721772194 0.7524008751 0.7529935837 + 0.7727996707 0.7529972196 0.7536963820 + 0.7734221816 0.7535933852 0.7543991804 + 0.7740446925 0.7541896105 0.7551020980 + 0.7746649981 0.7547839284 0.7558023930 + 0.7752826810 0.7553762794 0.7565001845 + 0.7759004831 0.7559686899 0.7571979761 + 0.7765182853 0.7565611005 0.7578958273 + 0.7771326900 0.7571496964 0.7585895061 + 0.7777460814 0.7577372789 0.7592819929 + 0.7783594728 0.7583248019 0.7599744201 + 0.7789728045 0.7589122057 0.7606667280 + 0.7795792222 0.7594966888 0.7613533735 + 0.7801855803 0.7600811720 0.7620400190 + 0.7807919979 0.7606657147 0.7627267241 + 0.7813968062 0.7612491846 0.7634122968 + 0.7819966078 0.7618296742 0.7640944123 + 0.7825964093 0.7624102235 0.7647765279 + 0.7831960917 0.7629907131 0.7654587030 + 0.7837939262 0.7635689974 0.7661380172 + 0.7843887806 0.7641444206 0.7668138146 + 0.7849838138 0.7647197843 0.7674896717 + 0.7855787873 0.7652952075 0.7681655288 + 0.7861704826 0.7658686042 0.7688372731 + 0.7867596745 0.7664408088 0.7695063949 + 0.7873489261 0.7670128942 0.7701755166 + 0.7879381776 0.7675850987 0.7708445787 + 0.7885246873 0.7681542039 0.7715098858 + 0.7891101837 0.7687221169 0.7721735835 + 0.7896956205 0.7692900896 0.7728372812 + 0.7902809978 0.7698580027 0.7735010982 + 0.7908638120 0.7704228759 0.7741602063 + 0.7914459109 0.7709870934 0.7748184204 + 0.7920280099 0.7715513706 0.7754765153 + 0.7926099896 0.7721155882 0.7761346102 + 0.7931870222 0.7726777196 0.7767888904 + 0.7937632799 0.7732396722 0.7774425745 + 0.7943394780 0.7738016248 0.7780963182 + 0.7949157953 0.7743635178 0.7787501216 + 0.7954884768 0.7749227285 0.7793995142 + 0.7960608006 0.7754815817 0.7800486088 + 0.7966331244 0.7760406137 0.7806975842 + 0.7972053885 0.7765995860 0.7813466787 + 0.7977746129 0.7771558762 0.7819913030 + 0.7983434796 0.7777119875 0.7826355100 + 0.7989124060 0.7782680988 0.7832797170 + 0.7994812727 0.7788242102 0.7839238048 + 0.8000450134 0.7793778181 0.7845636010 + 0.8006079793 0.7799311280 0.7852026820 + 0.8011708856 0.7804843187 0.7858418226 + 0.8017339110 0.7810376287 0.7864809036 + 0.8022924066 0.7815880775 0.7871146202 + 0.8028498292 0.7821378708 0.7877470851 + 0.8034073114 0.7826877236 0.7883794904 + 0.8039646745 0.7832375765 0.7890118957 + 0.8045186996 0.7837849855 0.7896395922 + 0.8050711751 0.7843313813 0.7902652025 + 0.8056237102 0.7848778963 0.7908908129 + 0.8061761856 0.7854242921 0.7915164232 + 0.8067255020 0.7859687805 0.7921388745 + 0.8072721958 0.7865118980 0.7927588820 + 0.8078188896 0.7870550156 0.7933788896 + 0.8083655834 0.7875980735 0.7939988971 + 0.8089101911 0.7881401777 0.7946166992 + 0.8094515800 0.7886806130 0.7952311039 + 0.8099929094 0.7892209888 0.7958455086 + 0.8105341792 0.7897614241 0.7964599133 + 0.8110746741 0.7903016806 0.7970730066 + 0.8116112947 0.7908411026 0.7976801991 + 0.8121479154 0.7913805842 0.7982873917 + 0.8126844764 0.7919200063 0.7988945842 + 0.8132210970 0.7924594879 0.7995017767 + 0.8137524128 0.7929970026 0.8001034260 + 0.8142833114 0.7935343981 0.8007047176 + 0.8148142099 0.7940719128 0.8013060093 + 0.8153451085 0.7946093082 0.8019073009 + 0.8158726096 0.7951447964 0.8025054932 + 0.8163983226 0.7956792712 0.8031023145 + 0.8169239759 0.7962138057 0.8036990762 + 0.8174496889 0.7967482209 0.8042958975 + 0.8179737926 0.7972822785 0.8048911095 + 0.8184949160 0.7978156209 0.8054832816 + 0.8190159798 0.7983487844 0.8060755134 + 0.8195371032 0.7988821268 0.8066676855 + 0.8200582862 0.7994152904 0.8072599173 + 0.8205738068 0.7999464273 0.8078473806 + 0.8210893273 0.8004773855 0.8084350228 + 0.8216049075 0.8010084033 0.8090224862 + 0.8221204281 0.8015394211 0.8096100092 + 0.8226320148 0.8020684123 0.8101946115 + 0.8231410980 0.8025962710 0.8107774258 + 0.8236501217 0.8031241298 0.8113601804 + 0.8241592050 0.8036519289 0.8119429946 + 0.8246672153 0.8041794896 0.8125250936 + 0.8251705170 0.8047057986 0.8131045103 + 0.8256738186 0.8052322268 0.8136839271 + 0.8261770010 0.8057584763 0.8142634034 + 0.8266803026 0.8062849045 0.8148428202 + 0.8271808028 0.8068094254 0.8154187202 + 0.8276802897 0.8073332906 0.8159933090 + 0.8281797171 0.8078572154 0.8165680170 + 0.8286792040 0.8083810806 0.8171426058 + 0.8291776180 0.8089041114 0.8177158237 + 0.8296723962 0.8094245791 0.8182842731 + 0.8301671743 0.8099449873 0.8188527822 + 0.8306620121 0.8104655147 0.8194214106 + 0.8311567903 0.8109859824 0.8199899197 + 0.8316488266 0.8115053177 0.8205549717 + 0.8321394920 0.8120239973 0.8211187720 + 0.8326302767 0.8125427961 0.8216825724 + 0.8331211209 0.8130615950 0.8222463727 + 0.8336114883 0.8135799170 0.8228093982 + 0.8341001868 0.8140959740 0.8233684897 + 0.8345888853 0.8146120906 0.8239275217 + 0.8350775242 0.8151282072 0.8244866133 + 0.8355662227 0.8156443238 0.8250455856 + 0.8360525966 0.8161584139 0.8256021738 + 0.8365371227 0.8166708946 0.8261566162 + 0.8370215297 0.8171833158 0.8267109990 + 0.8375059962 0.8176957965 0.8272655010 + 0.8379905224 0.8182082772 0.8278198838 + 0.8384705782 0.8187190294 0.8283702135 + 0.8389502168 0.8192296028 0.8289201260 + 0.8394296765 0.8197401166 0.8294699192 + 0.8399093151 0.8202505708 0.8300197124 + 0.8403881788 0.8207604885 0.8305683136 + 0.8408648968 0.8212682009 0.8311123848 + 0.8413414955 0.8217757940 0.8316563964 + 0.8418180943 0.8222835064 0.8322004080 + 0.8422946930 0.8227912188 0.8327444792 + 0.8427696228 0.8232969046 0.8332856894 + 0.8432425857 0.8238008022 0.8338239789 + 0.8437157273 0.8243045807 0.8343623281 + 0.8441886902 0.8248084784 0.8349006772 + 0.8446617723 0.8253123760 0.8354390264 + 0.8451316953 0.8258146048 0.8359742165 + 0.8456004858 0.8263162971 0.8365082145 + 0.8460692167 0.8268179893 0.8370422125 + 0.8465380073 0.8273196816 0.8375762105 + 0.8470066786 0.8278213739 0.8381102085 + 0.8474733233 0.8283202052 0.8386403918 + 0.8479397297 0.8288187981 0.8391703963 + 0.8484060764 0.8293173909 0.8397002816 + 0.8488724828 0.8298161030 0.8402302861 + 0.8493387103 0.8303142786 0.8407598138 + 0.8498020768 0.8308088779 0.8412843943 + 0.8502655029 0.8313035965 0.8418090940 + 0.8507289290 0.8317981958 0.8423337936 + 0.8511922956 0.8322929144 0.8428584933 + 0.8516547084 0.8327869773 0.8433821201 + 0.8521131873 0.8332791924 0.8439015746 + 0.8525716066 0.8337715268 0.8444212079 + 0.8530300856 0.8342636824 0.8449407220 + 0.8534886241 0.8347560167 0.8454602957 + 0.8539462090 0.8352472782 0.8459783792 + 0.8544015884 0.8357362747 0.8464931250 + 0.8548570871 0.8362252712 0.8470076919 + 0.8553125858 0.8367143273 0.8475223184 + 0.8557680249 0.8372033238 0.8480370045 + 0.8562228084 0.8376908898 0.8485500813 + 0.8566759229 0.8381757140 0.8490599990 + 0.8571289778 0.8386605978 0.8495699167 + 0.8575822115 0.8391454220 0.8500797749 + 0.8580353260 0.8396301866 0.8505896926 + 0.8584871292 0.8401141763 0.8510981798 + 0.8589360118 0.8405964971 0.8516036868 + 0.8593848944 0.8410786986 0.8521090746 + 0.8598337770 0.8415609002 0.8526145816 + 0.8602827191 0.8420432210 0.8531200290 + 0.8607307076 0.8425244093 0.8536239862 + 0.8611760139 0.8430032134 0.8541238904 + 0.8616213202 0.8434820175 0.8546237946 + 0.8620666862 0.8439608812 0.8551236987 + 0.8625119925 0.8444396853 0.8556236029 + 0.8629568219 0.8449175954 0.8561224937 + 0.8633992076 0.8453921080 0.8566170931 + 0.8638417125 0.8458666205 0.8571115732 + 0.8642840981 0.8463410139 0.8576061130 + 0.8647266030 0.8468155265 0.8581007123 + 0.8651688099 0.8472898006 0.8585950136 + 0.8656079173 0.8477615118 0.8590856194 + 0.8660469055 0.8482331038 0.8595762849 + 0.8664858937 0.8487048149 0.8600668907 + 0.8669250011 0.8491765261 0.8605576158 + 0.8673639894 0.8496481180 0.8610482216 + 0.8677995801 0.8501166105 0.8615357280 + 0.8682346940 0.8505846262 0.8620226979 + 0.8686698079 0.8510527015 0.8625097871 + 0.8691048026 0.8515207767 0.8629968762 + 0.8695399165 0.8519887924 0.8634839058 + 0.8699728847 0.8524538279 0.8639678955 + 0.8704047799 0.8529173732 0.8644505143 + 0.8708366156 0.8533809185 0.8649330735 + 0.8712685108 0.8538445234 0.8654156923 + 0.8717002869 0.8543081284 0.8658981919 + 0.8721306920 0.8547704220 0.8663790226 + 0.8725587130 0.8552309275 0.8668572903 + 0.8729867935 0.8556914926 0.8673356175 + 0.8734148741 0.8561519980 0.8678138852 + 0.8738428950 0.8566126227 0.8682922125 + 0.8742704988 0.8570727110 0.8687700033 + 0.8746942878 0.8575295210 0.8692442775 + 0.8751180172 0.8579862714 0.8697186112 + 0.8755416870 0.8584430814 0.8701928854 + 0.8759654760 0.8588998914 0.8706671000 + 0.8763892055 0.8593567014 0.8711413741 + 0.8768100739 0.8598098755 0.8716111183 + 0.8772302270 0.8602619767 0.8720793724 + 0.8776502013 0.8607140779 0.8725476861 + 0.8780702949 0.8611662984 0.8730159998 + 0.8784903288 0.8616183996 0.8734843135 + 0.8789088130 0.8620693088 0.8739504814 + 0.8793246746 0.8625183105 0.8744130135 + 0.8797405958 0.8629671931 0.8748756051 + 0.8801565170 0.8634161949 0.8753381968 + 0.8805723190 0.8638650775 0.8758007884 + 0.8809881806 0.8643140793 0.8762633801 + 0.8814008832 0.8647593260 0.8767219186 + 0.8818134069 0.8652043939 0.8771802187 + 0.8822258711 0.8656494021 0.8776385188 + 0.8826382756 0.8660945296 0.8780966997 + 0.8830507994 0.8665394783 0.8785549998 + 0.8834620118 0.8669828176 0.8790109158 + 0.8838717937 0.8674241900 0.8794640899 + 0.8842815161 0.8678655028 0.8799173236 + 0.8846911788 0.8683068752 0.8803703785 + 0.8851009011 0.8687481880 0.8808236122 + 0.8855106831 0.8691896200 0.8812767863 + 0.8859174252 0.8696290851 0.8817254901 + 0.8863239288 0.8700686097 0.8821738958 + 0.8867303729 0.8705080152 0.8826223016 + 0.8871369958 0.8709474802 0.8830707073 + 0.8875434995 0.8713868856 0.8835191131 + 0.8879491091 0.8718252778 0.8839659095 + 0.8883531094 0.8722618222 0.8844100833 + 0.8887569904 0.8726983070 0.8848543167 + 0.8891609907 0.8731347919 0.8852983713 + 0.8895649910 0.8735713959 0.8857426047 + 0.8899689913 0.8740078807 0.8861867189 + 0.8903707862 0.8744425774 0.8866271973 + 0.8907716870 0.8748766780 0.8870663047 + 0.8911727071 0.8753107786 0.8875054717 + 0.8915737271 0.8757449985 0.8879445791 + 0.8919746876 0.8761790991 0.8883838058 + 0.8923754096 0.8766130209 0.8888226151 + 0.8927729726 0.8770452738 0.8892570734 + 0.8931705952 0.8774775267 0.8896915913 + 0.8935680985 0.8779097199 0.8901261091 + 0.8939657211 0.8783419728 0.8905606270 + 0.8943632245 0.8787742257 0.8909950852 + 0.8947597742 0.8792054057 0.8914281130 + 0.8951544762 0.8796346784 0.8918585181 + 0.8955491781 0.8800640702 0.8922889233 + 0.8959439993 0.8804934025 0.8927193284 + 0.8963387012 0.8809227943 0.8931496739 + 0.8967334032 0.8813521862 0.8935800791 + 0.8971260786 0.8817800879 0.8940076232 + 0.8975175023 0.8822070956 0.8944330812 + 0.8979089856 0.8826341033 0.8948585987 + 0.8983004093 0.8830611110 0.8952841163 + 0.8986917734 0.8834881186 0.8957095742 + 0.8990831971 0.8839151263 0.8961350918 + 0.8994715810 0.8843405843 0.8965569735 + 0.8998593092 0.8847656846 0.8969780207 + 0.9002469778 0.8851909041 0.8973988891 + 0.9006347060 0.8856160045 0.8978198767 + 0.9010223746 0.8860412240 0.8982409239 + 0.9014101028 0.8864663243 0.8986619115 + 0.9017949104 0.8868888021 0.8990790844 + 0.9021794796 0.8873111010 0.8994960785 + 0.9025642276 0.8877333999 0.8999131918 + 0.9029487967 0.8881556988 0.9003301859 + 0.9033334851 0.8885779977 0.9007471800 + 0.9037179947 0.8890001774 0.9011639953 + 0.9041002989 0.8894202113 0.9015762210 + 0.9044826031 0.8898401856 0.9019883871 + 0.9048647881 0.8902602196 0.9024006128 + 0.9052470922 0.8906801939 0.9028128982 + 0.9056293964 0.8911002278 0.9032251239 + 0.9060112834 0.8915200233 0.9036368132 + 0.9063897133 0.8919382095 0.9040434957 + 0.9067682028 0.8923563957 0.9044501781 + 0.9071465731 0.8927745819 0.9048569202 + 0.9075250030 0.8931927085 0.9052636027 + 0.9079034925 0.8936108947 0.9056702852 + 0.9082816243 0.8940287828 0.9060766101 + 0.9086568952 0.8944442272 0.9064794779 + 0.9090322256 0.8948596120 0.9068824053 + 0.9094074965 0.8952749968 0.9072852731 + 0.9097827077 0.8956903815 0.9076882005 + 0.9101579785 0.8961058259 0.9080911279 + 0.9105333090 0.8965210915 0.9084938765 + 0.9109072089 0.8969342113 0.9088944793 + 0.9112812281 0.8973472714 0.9092950225 + 0.9116551280 0.8977603912 0.9096956253 + 0.9120290875 0.8981735110 0.9100962281 + 0.9124029875 0.8985865712 0.9104967713 + 0.9127770066 0.8989996910 0.9108973742 + 0.9131482840 0.8994112015 0.9112942219 + 0.9135193825 0.8998224735 0.9116908908 + 0.9138906002 0.9002338052 0.9120875001 + 0.9142616987 0.9006450772 0.9124842286 + 0.9146327972 0.9010564089 0.9128807783 + 0.9150040150 0.9014678001 0.9132773876 + 0.9153717160 0.9018769264 0.9136704803 + 0.9157385230 0.9022855163 0.9140626192 + 0.9161052704 0.9026941061 0.9144545794 + 0.9164720774 0.9031026959 0.9148467183 + 0.9168388844 0.9035112262 0.9152387977 + 0.9172058105 0.9039198160 0.9156308770 + 0.9175711274 0.9043270946 0.9160212278 + 0.9179353714 0.9047334194 0.9164103270 + 0.9182996750 0.9051396847 0.9167994261 + 0.9186639786 0.9055461287 0.9171885848 + 0.9190282822 0.9059523940 0.9175776839 + 0.9193925858 0.9063587785 0.9179667830 + 0.9197562933 0.9067645073 0.9183548093 + 0.9201188087 0.9071691036 0.9187405109 + 0.9204813242 0.9075737000 0.9191262126 + 0.9208437800 0.9079781771 0.9195119143 + 0.9212062955 0.9083827734 0.9198976159 + 0.9215688109 0.9087874293 0.9202833176 + 0.9219312072 0.9091919065 0.9206687808 + 0.9222893715 0.9095938206 0.9210494161 + 0.9226475954 0.9099956155 0.9214301109 + 0.9230058193 0.9103975296 0.9218106866 + 0.9233639836 0.9107993841 0.9221913218 + 0.9237222075 0.9112012982 0.9225718975 + 0.9240803123 0.9116032124 0.9229525924 + 0.9244369268 0.9120035768 0.9233309031 + 0.9247925282 0.9124032259 0.9237080812 + 0.9251481891 0.9128028750 0.9240853786 + 0.9255039096 0.9132025838 0.9244626164 + 0.9258595705 0.9136022925 0.9248397946 + 0.9262152910 0.9140018821 0.9252169728 + 0.9265707731 0.9144011736 0.9255934954 + 0.9269257188 0.9147990942 0.9259678721 + 0.9272807240 0.9151970148 0.9263421893 + 0.9276356101 0.9155949950 0.9267166257 + 0.9279906154 0.9159929156 0.9270910025 + 0.9283455014 0.9163908958 0.9274653792 + 0.9287005067 0.9167888165 0.9278396964 + 0.9290528893 0.9171856046 0.9282106161 + 0.9294046760 0.9175820947 0.9285805225 + 0.9297564030 0.9179785252 0.9289504290 + 0.9301081896 0.9183750153 0.9293202758 + 0.9304599166 0.9187715054 0.9296901822 + 0.9308117032 0.9191678762 0.9300600886 + 0.9311624765 0.9195644259 0.9304289222 + 0.9315106869 0.9199606180 0.9307948947 + 0.9318587780 0.9203569293 0.9311608076 + 0.9322069883 0.9207531810 0.9315267801 + 0.9325551987 0.9211494923 0.9318928123 + 0.9329034090 0.9215456843 0.9322587848 + 0.9332516193 0.9219419956 0.9326246977 + 0.9335985184 0.9223375916 0.9329884052 + 0.9339448810 0.9227328897 0.9333512187 + 0.9342911839 0.9231281281 0.9337139130 + 0.9346376061 0.9235234261 0.9340766072 + 0.9349840283 0.9239187241 0.9344394207 + 0.9353303909 0.9243140221 0.9348021150 + 0.9356765747 0.9247090816 0.9351645112 + 0.9360207915 0.9251027107 0.9355235100 + 0.9363651276 0.9254962802 0.9358825088 + 0.9367092848 0.9258899093 0.9362415075 + 0.9370536208 0.9262835979 0.9366003871 + 0.9373977780 0.9266772270 0.9369593859 + 0.9377421141 0.9270707965 0.9373183846 + 0.9380850196 0.9274641871 0.9376757145 + 0.9384257793 0.9278573990 0.9380304813 + 0.9387664795 0.9282506704 0.9383851886 + 0.9391072989 0.9286438823 0.9387400150 + 0.9394481182 0.9290370941 0.9390947223 + 0.9397888780 0.9294303060 0.9394494891 + 0.9401296973 0.9298235178 0.9398041964 + 0.9404693842 0.9302158952 0.9401566982 + 0.9408084750 0.9306079149 0.9405080080 + 0.9411476254 0.9309998751 0.9408593178 + 0.9414865971 0.9313920140 0.9412106276 + 0.9418256879 0.9317839742 0.9415618777 + 0.9421647787 0.9321759939 0.9419131875 + 0.9425039291 0.9325680137 0.9422644973 + 0.9428421259 0.9329584837 0.9426131845 + 0.9431802034 0.9333485961 0.9429615140 + 0.9435182810 0.9337388277 0.9433097839 + 0.9438564181 0.9341289997 0.9436581135 + 0.9441944957 0.9345191121 0.9440063834 + 0.9445325732 0.9349092841 0.9443547130 + 0.9448707104 0.9352995157 0.9447029829 + 0.9452053905 0.9356890917 0.9450477958 + 0.9455401897 0.9360786080 0.9453927279 + 0.9458749294 0.9364681840 0.9457374811 + 0.9462096095 0.9368578196 0.9460824132 + 0.9465444088 0.9372473955 0.9464272261 + 0.9468790889 0.9376369119 0.9467720985 + 0.9472135901 0.9380264282 0.9471164942 + 0.9475457072 0.9384145737 0.9474576116 + 0.9478777051 0.9388027787 0.9477987289 + 0.9482098222 0.9391909838 0.9481397867 + 0.9485418797 0.9395791888 0.9484809041 + 0.9488739967 0.9399673939 0.9488220215 + 0.9492059946 0.9403555989 0.9491630793 + 0.9495379925 0.9407432079 0.9495037794 + 0.9498690963 0.9411267042 0.9498416781 + 0.9502003193 0.9415103197 0.9501795769 + 0.9505314231 0.9418938756 0.9505175948 + 0.9508625865 0.9422774911 0.9508554935 + 0.9511936903 0.9426611066 0.9511933923 + 0.9515247941 0.9430447221 0.9515312910 + 0.9518557191 0.9434276223 0.9518690109 + 0.9521846175 0.9438055754 0.9522042871 + 0.9525135756 0.9441835880 0.9525396228 + 0.9528424740 0.9445616007 0.9528750181 + 0.9531713724 0.9449396133 0.9532102942 + 0.9535002708 0.9453176260 0.9535456896 + 0.9538292289 0.9456955194 0.9538810253 + 0.9541580081 0.9460734129 0.9542161226 + 0.9544816017 0.9464468956 0.9545456171 + 0.9548051953 0.9468203783 0.9548751116 + 0.9551287889 0.9471939802 0.9552046061 + 0.9554523826 0.9475675225 0.9555341005 + 0.9557759166 0.9479411244 0.9558635950 + 0.9560995102 0.9483146071 0.9561930895 + 0.9564231038 0.9486880898 0.9565225840 + 0.9567415714 0.9490590096 0.9568458200 + 0.9570595026 0.9494295716 0.9571682215 + 0.9573773146 0.9498001933 0.9574906230 + 0.9576951861 0.9501708150 0.9578130245 + 0.9580131173 0.9505413771 0.9581354260 + 0.9583309889 0.9509119987 0.9584578276 + 0.9586488008 0.9512825012 0.9587802291 + 0.9589642882 0.9516518712 0.9591000080 + 0.9592787027 0.9520208240 0.9594187140 + 0.9595931172 0.9523895979 0.9597374201 + 0.9599075913 0.9527583718 0.9600561261 + 0.9602220058 0.9531273246 0.9603748918 + 0.9605364203 0.9534960985 0.9606935978 + 0.9608507752 0.9538649917 0.9610123038 + 0.9611636996 0.9542328715 0.9613298178 + 0.9614747763 0.9545994997 0.9616457224 + 0.9617857933 0.9549661875 0.9619616866 + 0.9620968103 0.9553328753 0.9622775912 + 0.9624078274 0.9556996226 0.9625936151 + 0.9627187848 0.9560663104 0.9629095197 + 0.9630298018 0.9564329982 0.9632254839 + 0.9633405209 0.9567993283 0.9635409713 + 0.9636486173 0.9571633935 0.9638535976 + 0.9639567733 0.9575273991 0.9641662836 + 0.9642649889 0.9578914046 0.9644789100 + 0.9645730853 0.9582554102 0.9647914767 + 0.9648813009 0.9586194158 0.9651042223 + 0.9651893973 0.9589834809 0.9654167891 + 0.9654976130 0.9593474865 0.9657294154 + 0.9658039808 0.9597097039 0.9660398960 + 0.9661098123 0.9600713849 0.9663494825 + 0.9664155245 0.9604331255 0.9666591883 + 0.9667212963 0.9607948065 0.9669688940 + 0.9670271277 0.9611564875 0.9672784805 + 0.9673328996 0.9615182281 0.9675881863 + 0.9676386118 0.9618799090 0.9678978920 + 0.9679433107 0.9622406960 0.9682065248 + 0.9682455063 0.9625995755 0.9685127139 + 0.9685477018 0.9629585743 0.9688190222 + 0.9688498974 0.9633175135 0.9691252112 + 0.9691520929 0.9636763930 0.9694314003 + 0.9694542885 0.9640353918 0.9697375894 + 0.9697564840 0.9643942714 0.9700438976 + 0.9700586796 0.9647533298 0.9703500867 + 0.9703577757 0.9651095867 0.9706525803 + 0.9706562161 0.9654654264 0.9709542990 + 0.9709545970 0.9658210874 0.9712558985 + 0.9712529182 0.9661768079 0.9715574980 + 0.9715512991 0.9665325880 0.9718590975 + 0.9718496799 0.9668883085 0.9721608162 + 0.9721480012 0.9672440290 0.9724624157 + 0.9724456072 0.9675989747 0.9727630019 + 0.9727405906 0.9679515958 0.9730604291 + 0.9730355740 0.9683042169 0.9733577967 + 0.9733306766 0.9686567783 0.9736552238 + 0.9736257195 0.9690095186 0.9739525914 + 0.9739207029 0.9693620801 0.9742500186 + 0.9742156863 0.9697147012 0.9745473862 + 0.9745107293 0.9700673223 0.9748446941 + 0.9748036265 0.9704176188 0.9751394987 + 0.9750949740 0.9707666039 0.9754326940 + 0.9753863811 0.9711155295 0.9757258296 + 0.9756777883 0.9714645147 0.9760190248 + 0.9759691954 0.9718133807 0.9763122201 + 0.9762606025 0.9721624255 0.9766052961 + 0.9765521288 0.9725112915 0.9768984914 + 0.9768434763 0.9728602171 0.9771916270 + 0.9771314263 0.9732053876 0.9774799943 + 0.9774190784 0.9735503197 0.9777678847 + 0.9777066708 0.9738951921 0.9780558944 + 0.9779943228 0.9742401242 0.9783437848 + 0.9782819748 0.9745849967 0.9786317945 + 0.9785696268 0.9749299288 0.9789196849 + 0.9788572788 0.9752748013 0.9792076945 + 0.9791442752 0.9756188989 0.9794946909 + 0.9794281721 0.9759591818 0.9797772765 + 0.9797121286 0.9762995839 0.9800599217 + 0.9799959064 0.9766399860 0.9803425074 + 0.9802798033 0.9769803882 0.9806250930 + 0.9805637002 0.9773206711 0.9809077978 + 0.9808475971 0.9776610732 0.9811903834 + 0.9811314940 0.9780014753 0.9814730287 + 0.9814137816 0.9783400297 0.9817537069 + 0.9816933274 0.9786750078 0.9820309877 + 0.9819728136 0.9790101051 0.9823082089 + 0.9822522998 0.9793450832 0.9825854897 + 0.9825317860 0.9796801805 0.9828627110 + 0.9828112721 0.9800152183 0.9831399918 + 0.9830908179 0.9803503156 0.9834172726 + 0.9833703041 0.9806852937 0.9836944938 + 0.9836477041 0.9810177088 0.9839690924 + 0.9839227200 0.9813470840 0.9842407703 + 0.9841976762 0.9816765189 0.9845123887 + 0.9844726920 0.9820057750 0.9847840071 + 0.9847477078 0.9823352098 0.9850556254 + 0.9850227237 0.9826645255 0.9853271842 + 0.9852976203 0.9829939008 0.9855988026 + 0.9855725765 0.9833232760 0.9858704209 + 0.9858452082 0.9836488962 0.9861391783 + 0.9861155152 0.9839711785 0.9864053130 + 0.9863858223 0.9842935205 0.9866713285 + 0.9866561890 0.9846158028 0.9869374037 + 0.9869264960 0.9849380851 0.9872034788 + 0.9871968031 0.9852603078 0.9874696136 + 0.9874671102 0.9855825901 0.9877356291 + 0.9877374172 0.9859048724 0.9880017042 + 0.9880046248 0.9862229228 0.9882646799 + 0.9882686138 0.9865366220 0.9885246158 + 0.9885327220 0.9868503809 0.9887844920 + 0.9887967110 0.9871640801 0.9890444875 + 0.9890608191 0.9874778986 0.9893044233 + 0.9893248081 0.9877915978 0.9895642996 + 0.9895889163 0.9881054163 0.9898241758 + 0.9898529053 0.9884191155 0.9900841713 + 0.9901142120 0.9887291193 0.9903411865 + 0.9903718829 0.9890338778 0.9905943871 + 0.9906294942 0.9893386960 0.9908475280 + 0.9908872247 0.9896435142 0.9911007285 + 0.9911447763 0.9899483919 0.9913538098 + 0.9914023876 0.9902532101 0.9916070104 + 0.9916601181 0.9905580282 0.9918600917 + 0.9919177294 0.9908627868 0.9921131730 + 0.9921736121 0.9911643267 0.9923645854 + 0.9924249053 0.9914569855 0.9926109910 + 0.9926763177 0.9917497039 0.9928573966 + 0.9929276109 0.9920424223 0.9931039214 + 0.9931789041 0.9923352003 0.9933503270 + 0.9934303164 0.9926279187 0.9935967922 + 0.9936816096 0.9929205775 0.9938431978 + 0.9939329028 0.9932134151 0.9940897226 + 0.9941837192 0.9935051799 0.9943355918 + 0.9944264293 0.9937829971 0.9945728183 + 0.9946690202 0.9940606952 0.9948101044 + 0.9949116111 0.9943385124 0.9950473905 + 0.9951542020 0.9946163297 0.9952846169 + 0.9953969121 0.9948940873 0.9955219030 + 0.9956395030 0.9951717854 0.9957591891 + 0.9958820939 0.9954496026 0.9959964752 + 0.9961246848 0.9957274199 0.9962337017 + 0.9963588715 0.9959930182 0.9964621067 + 0.9965906739 0.9962550998 0.9966878295 + 0.9968224764 0.9965171814 0.9969136119 + 0.9970542789 0.9967793226 0.9971392751 + 0.9972860217 0.9970414042 0.9973651171 + 0.9975178242 0.9973034859 0.9975907803 + 0.9977496266 0.9975656271 0.9978166223 + 0.9979814291 0.9978277087 0.9980422854 + 0.9982097745 0.9980804920 0.9982643723 + 0.9984334707 0.9983204007 0.9984812737 + 0.9986572862 0.9985604286 0.9986982942 + 0.9988811016 0.9988002777 0.9989151955 + 0.9991049170 0.9990401864 0.9991322160 + 0.9993286729 0.9992802143 0.9993491173 + 0.9995524287 0.9995201230 0.9995660782 + 0.9997761846 0.9997600913 0.9997829795 + 1.0000000000 1.0000000000 1.0000000000 +} diff --git a/rpplugins/color_correction/resources/film_luts_raw/agfa_agfacolor_vista_400.spi1d b/rpplugins/color_correction/resources/film_luts_raw/agfa_agfacolor_vista_400.spi1d new file mode 100644 index 0000000..3346388 --- /dev/null +++ b/rpplugins/color_correction/resources/film_luts_raw/agfa_agfacolor_vista_400.spi1d @@ -0,0 +1,1030 @@ +Version 1 +From 0.0 1.0 +Length 1024 +Components 3 +{ + 0.0000000000 0.0000000000 0.0000000000 + 0.0176717807 0.0159793403 0.0112875197 + 0.0304853506 0.0281650797 0.0208594296 + 0.0410733782 0.0387531407 0.0291500594 + 0.0505116396 0.0483908802 0.0366822407 + 0.0592069514 0.0573300086 0.0436884314 + 0.0673851594 0.0657815933 0.0503007919 + 0.0751756504 0.0738594905 0.0565973185 + 0.0826697499 0.0815291628 0.0626588985 + 0.0899700671 0.0889572278 0.0685112923 + 0.0971127078 0.0961195603 0.0741866305 + 0.1040614992 0.1030588970 0.0796945021 + 0.1108867973 0.1097960994 0.0850348696 + 0.1175592989 0.1162500009 0.0902234167 + 0.1240769997 0.1224389970 0.0952606276 + 0.1304063946 0.1284389049 0.1001622975 + 0.1365357041 0.1342712045 0.1049377993 + 0.1425068974 0.1399544030 0.1096132994 + 0.1483051926 0.1454842985 0.1141887009 + 0.1539328992 0.1508464068 0.1186479032 + 0.1594130993 0.1560681015 0.1230128035 + 0.1647385061 0.1611503065 0.1272864938 + 0.1699229032 0.1660998017 0.1315000951 + 0.1749854982 0.1709350944 0.1356704980 + 0.1799377054 0.1756564975 0.1397946030 + 0.1847759038 0.1802780032 0.1438630074 + 0.1895146966 0.1848101020 0.1478590965 + 0.1941531003 0.1892485023 0.1517767012 + 0.1987002045 0.1936012954 0.1556075960 + 0.2031593025 0.1978708953 0.1593558043 + 0.2075425982 0.2020536959 0.1630499065 + 0.2118435949 0.2061593980 0.1667018980 + 0.2160740942 0.2101961970 0.1703169942 + 0.2202394009 0.2141588926 0.1739034057 + 0.2243397981 0.2180612981 0.1774580032 + 0.2283758074 0.2218959928 0.1809788048 + 0.2323485017 0.2256778032 0.1844571978 + 0.2362571955 0.2294041961 0.1878990978 + 0.2401061058 0.2330839932 0.1913042963 + 0.2438924015 0.2367096990 0.1946662962 + 0.2476287931 0.2402735949 0.1979884058 + 0.2513082922 0.2437945008 0.2012688965 + 0.2549471855 0.2472652048 0.2045135945 + 0.2585380971 0.2506807148 0.2077264041 + 0.2620711029 0.2540544868 0.2109075934 + 0.2655648887 0.2573910058 0.2140623927 + 0.2690165043 0.2606757879 0.2171906978 + 0.2724193931 0.2639169097 0.2202925980 + 0.2757751048 0.2671265006 0.2233645022 + 0.2791010141 0.2702954113 0.2264122963 + 0.2823888063 0.2734270096 0.2294276059 + 0.2856281996 0.2765175104 0.2324116975 + 0.2888259888 0.2795749009 0.2353696972 + 0.2919923067 0.2826111019 0.2383048981 + 0.2951227129 0.2856203914 0.2412146926 + 0.2982215881 0.2885940969 0.2441015989 + 0.3012860119 0.2915267050 0.2469657958 + 0.3043090105 0.2944279015 0.2498013973 + 0.3073101938 0.2973093092 0.2526110113 + 0.3102934957 0.3001666963 0.2553977966 + 0.3132512867 0.3029935062 0.2581652105 + 0.3161765933 0.3057951033 0.2609097958 + 0.3190675080 0.3085728884 0.2636330128 + 0.3219313025 0.3113223910 0.2663359046 + 0.3247652054 0.3140394092 0.2690128982 + 0.3275650144 0.3167183995 0.2716695964 + 0.3303397894 0.3193723857 0.2743076086 + 0.3330946863 0.3220146000 0.2769277096 + 0.3358342946 0.3246417940 0.2795312107 + 0.3385555148 0.3272505105 0.2821188867 + 0.3412531912 0.3298355937 0.2846879959 + 0.3439249098 0.3323946893 0.2872357965 + 0.3465682864 0.3349305987 0.2897650003 + 0.3491815031 0.3374486864 0.2922779918 + 0.3517724872 0.3399476111 0.2947722971 + 0.3543426991 0.3424271047 0.2972482145 + 0.3568890095 0.3448829055 0.2997061908 + 0.3594169915 0.3473187089 0.3021450043 + 0.3619238138 0.3497349918 0.3045690060 + 0.3644065857 0.3521293998 0.3069755137 + 0.3668681085 0.3545056880 0.3093619943 + 0.3693178892 0.3568738103 0.3117316961 + 0.3717587888 0.3592340052 0.3140853941 + 0.3741885126 0.3615838885 0.3164219856 + 0.3766059875 0.3639225960 0.3187406957 + 0.3790099025 0.3662486970 0.3210408986 + 0.3813976049 0.3685598075 0.3233255148 + 0.3837701082 0.3708567023 0.3255949020 + 0.3861232102 0.3731352985 0.3278453052 + 0.3884578049 0.3753966093 0.3300752938 + 0.3907732964 0.3776400983 0.3322862089 + 0.3930662870 0.3798610866 0.3344799876 + 0.3953461945 0.3820647001 0.3366613984 + 0.3976148069 0.3842560053 0.3388288021 + 0.3998697102 0.3864341080 0.3409801126 + 0.4021120965 0.3886001110 0.3431150019 + 0.4043419063 0.3907540143 0.3452382982 + 0.4065585136 0.3928948939 0.3473502100 + 0.4087597132 0.3950211108 0.3494505882 + 0.4109471142 0.3971337974 0.3515371084 + 0.4131202102 0.3992326856 0.3536098003 + 0.4152786136 0.4013175070 0.3556677103 + 0.4174210131 0.4033867121 0.3577109873 + 0.4195466042 0.4054397941 0.3597368896 + 0.4216561913 0.4074774981 0.3617466092 + 0.4237481952 0.4094994962 0.3637399971 + 0.4258198142 0.4115054905 0.3657152951 + 0.4278750122 0.4134953022 0.3676727116 + 0.4299133122 0.4154728055 0.3696179092 + 0.4319362044 0.4174365997 0.3715522885 + 0.4339421093 0.4193887115 0.3734749854 + 0.4359337986 0.4213280082 0.3753845096 + 0.4379098117 0.4232569933 0.3772805035 + 0.4398722053 0.4251773953 0.3791654110 + 0.4418199062 0.4270893037 0.3810392916 + 0.4437533915 0.4289928973 0.3829011917 + 0.4456734061 0.4308882058 0.3847497106 + 0.4475804865 0.4327754080 0.3865840137 + 0.4494752884 0.4346545041 0.3884027004 + 0.4513584077 0.4365256131 0.3902072906 + 0.4532304108 0.4383887947 0.3919999897 + 0.4550901055 0.4402442873 0.3937804997 + 0.4569362104 0.4420920908 0.3955484033 + 0.4587698877 0.4439322948 0.3973042071 + 0.4605911970 0.4457649887 0.3990490139 + 0.4624013007 0.4475904107 0.4007813931 + 0.4641987979 0.4494084120 0.4025042057 + 0.4659827948 0.4512192011 0.4042207897 + 0.4677540958 0.4530228972 0.4059314132 + 0.4695135057 0.4548195899 0.4076353014 + 0.4712609053 0.4566093981 0.4093317986 + 0.4729954898 0.4583922923 0.4110203981 + 0.4747171104 0.4601685107 0.4127005041 + 0.4764277041 0.4619381130 0.4143716097 + 0.4781259000 0.4637005925 0.4160360992 + 0.4798142016 0.4654561877 0.4176951051 + 0.4814904928 0.4672054946 0.4193486869 + 0.4831553996 0.4689483941 0.4209963977 + 0.4848085046 0.4706839025 0.4226379097 + 0.4864495993 0.4724108875 0.4242731035 + 0.4880791903 0.4741292000 0.4259015024 + 0.4896988869 0.4758399129 0.4275228083 + 0.4913074970 0.4775409997 0.4291365147 + 0.4929072857 0.4792341888 0.4307413101 + 0.4944972992 0.4809193015 0.4323380888 + 0.4960778058 0.4825971127 0.4339267015 + 0.4976491034 0.4842678010 0.4355069101 + 0.4992105067 0.4859308898 0.4370785952 + 0.5007578135 0.4875870049 0.4386403859 + 0.5022947788 0.4892325103 0.4401915073 + 0.5038217902 0.4908691049 0.4417355955 + 0.5053405166 0.4924972057 0.4432739019 + 0.5068516731 0.4941171110 0.4448068142 + 0.5083519220 0.4957279861 0.4463337958 + 0.5098429918 0.4973297119 0.4478540123 + 0.5113254189 0.4989241958 0.4493685067 + 0.5127993822 0.5005111098 0.4508773983 + 0.5142660141 0.5020899177 0.4523806870 + 0.5157235265 0.5036565065 0.4538762867 + 0.5171709061 0.5052154064 0.4553655088 + 0.5186092257 0.5067667961 0.4568488002 + 0.5200390816 0.5083103776 0.4583263099 + 0.5214567780 0.5098450780 0.4597958028 + 0.5228651762 0.5113719106 0.4612582922 + 0.5242664218 0.5128924847 0.4627147019 + 0.5256614089 0.5144073963 0.4641650915 + 0.5270467997 0.5159106255 0.4656063020 + 0.5284280181 0.5174064040 0.4670408070 + 0.5298041105 0.5188953876 0.4684692025 + 0.5311722159 0.5203765035 0.4698903859 + 0.5325285792 0.5218489766 0.4713025093 + 0.5338789225 0.5233148932 0.4727083147 + 0.5352239013 0.5247743726 0.4741083086 + 0.5365588069 0.5262218714 0.4755015075 + 0.5378903151 0.5276635885 0.4768893123 + 0.5392178297 0.5290997028 0.4782724977 + 0.5405359268 0.5305265784 0.4796496034 + 0.5418452024 0.5319476128 0.4810225964 + 0.5431485176 0.5333635211 0.4823926091 + 0.5444443226 0.5347704887 0.4837583005 + 0.5457333922 0.5361695886 0.4851197004 + 0.5470187068 0.5375636816 0.4864782095 + 0.5482994914 0.5389505029 0.4878326058 + 0.5495707989 0.5403308272 0.4891827106 + 0.5508363843 0.5417066813 0.4905301034 + 0.5520933270 0.5430750251 0.4918732047 + 0.5533440113 0.5444362164 0.4932124019 + 0.5545908809 0.5457931161 0.4945487976 + 0.5558316112 0.5471432805 0.4958792031 + 0.5570693016 0.5484884977 0.4972046018 + 0.5583047271 0.5498301983 0.4985263944 + 0.5595293045 0.5511658192 0.4998416901 + 0.5607494712 0.5524978042 0.5011532903 + 0.5619639754 0.5538250208 0.5024604797 + 0.5631700754 0.5551431775 0.5037620068 + 0.5643717051 0.5564572215 0.5050604939 + 0.5655639768 0.5577635169 0.5063533187 + 0.5667486787 0.5590627193 0.5076419711 + 0.5679283738 0.5603570938 0.5089282990 + 0.5691004992 0.5616438985 0.5102069974 + 0.5702697039 0.5629271865 0.5114836097 + 0.5714333057 0.5642039180 0.5127562284 + 0.5725921988 0.5654767156 0.5140225887 + 0.5737485886 0.5667474866 0.5152860284 + 0.5748950243 0.5680088997 0.5165405869 + 0.5760377049 0.5692681074 0.5177925825 + 0.5771713853 0.5705221891 0.5190386772 + 0.5783004761 0.5717713237 0.5202798247 + 0.5794264078 0.5730165839 0.5215175748 + 0.5805451870 0.5742524266 0.5227484703 + 0.5816622972 0.5754857063 0.5239772797 + 0.5827761292 0.5767114758 0.5251995921 + 0.5838869214 0.5779340267 0.5264189839 + 0.5849927068 0.5791509748 0.5276340246 + 0.5860930085 0.5803642869 0.5288445950 + 0.5871897936 0.5815749764 0.5300526023 + 0.5882819295 0.5827775002 0.5312535167 + 0.5893725753 0.5839778781 0.5324525833 + 0.5904521942 0.5851687789 0.5336431861 + 0.5915297270 0.5863571763 0.5348318219 + 0.5925999880 0.5875378251 0.5360146761 + 0.5936675072 0.5887145996 0.5371940136 + 0.5947307944 0.5898860097 0.5383685827 + 0.5957894921 0.5910528898 0.5395389199 + 0.5968446136 0.5922164917 0.5407065153 + 0.5978962779 0.5933740139 0.5418683290 + 0.5989465714 0.5945292115 0.5430281758 + 0.5999879837 0.5956771970 0.5441824794 + 0.6010277867 0.5968238711 0.5453361273 + 0.6020594835 0.5979635715 0.5464810133 + 0.6030905247 0.5991023779 0.5476251245 + 0.6041157842 0.6002333760 0.5487617254 + 0.6051399112 0.6013631821 0.5498968959 + 0.6061576009 0.6024864912 0.5510259271 + 0.6071736217 0.6036077142 0.5521529913 + 0.6081838012 0.6047217250 0.5532745719 + 0.6091915965 0.6058334112 0.5543937087 + 0.6101928949 0.6069393754 0.5555071235 + 0.6111915708 0.6080427766 0.5566176176 + 0.6121845841 0.6091406941 0.5577220917 + 0.6131750941 0.6102350950 0.5588241220 + 0.6141607165 0.6113222241 0.5599215031 + 0.6151443720 0.6124070883 0.5610160828 + 0.6161242723 0.6134874821 0.5621057153 + 0.6171023250 0.6145648956 0.5631932020 + 0.6180763841 0.6156355739 0.5642765760 + 0.6190484166 0.6167044044 0.5653579831 + 0.6200155020 0.6177682281 0.5664346814 + 0.6209805012 0.6188302040 0.5675101280 + 0.6219391823 0.6198859811 0.5685818195 + 0.6228963733 0.6209400296 0.5696520209 + 0.6238467097 0.6219862103 0.5707165003 + 0.6247966886 0.6230316758 0.5717800856 + 0.6257433295 0.6240708828 0.5728380084 + 0.6266897917 0.6251100898 0.5738958120 + 0.6276292801 0.6261410713 0.5749465227 + 0.6285687089 0.6271719933 0.5759971142 + 0.6294990182 0.6281968951 0.5770409107 + 0.6304280162 0.6292210221 0.5780838728 + 0.6313526034 0.6302379966 0.5791224837 + 0.6322757006 0.6312527061 0.5801597238 + 0.6331943870 0.6322625875 0.5811929703 + 0.6341099739 0.6332694292 0.5822238922 + 0.6350240111 0.6342734098 0.5832517147 + 0.6359356046 0.6352738142 0.5842757225 + 0.6368461251 0.6362721920 0.5852975249 + 0.6377531290 0.6372647285 0.5863136053 + 0.6386598945 0.6382569075 0.5873292089 + 0.6395592093 0.6392408013 0.5883370042 + 0.6404585242 0.6402246952 0.5893447995 + 0.6413550973 0.6412026286 0.5903472900 + 0.6422510147 0.6421790719 0.5913487077 + 0.6431431770 0.6431517005 0.5923461914 + 0.6440324783 0.6441212296 0.5933409929 + 0.6449189186 0.6450884938 0.5943337083 + 0.6457985044 0.6460511088 0.5953221917 + 0.6466779113 0.6470134854 0.5963103771 + 0.6475521922 0.6479676962 0.5972914100 + 0.6484264135 0.6489219069 0.5982723832 + 0.6492943764 0.6498695016 0.5992498994 + 0.6501600742 0.6508147120 0.6002262235 + 0.6510232091 0.6517578959 0.6011999249 + 0.6518825889 0.6526980996 0.6021702886 + 0.6527417898 0.6536375880 0.6031401157 + 0.6535974145 0.6545693278 0.6041048169 + 0.6544529200 0.6555008888 0.6050693989 + 0.6553012729 0.6564255953 0.6060274839 + 0.6561468244 0.6573476791 0.6069834232 + 0.6569896936 0.6582674980 0.6079360247 + 0.6578274965 0.6591829062 0.6088829041 + 0.6586652994 0.6600983739 0.6098297834 + 0.6594979167 0.6610056758 0.6107699275 + 0.6603302956 0.6619125009 0.6117097735 + 0.6611601710 0.6628168225 0.6126456857 + 0.6619879007 0.6637189984 0.6135783195 + 0.6628152728 0.6646203995 0.6145102978 + 0.6636397243 0.6655144095 0.6154376268 + 0.6644641161 0.6664084196 0.6163650155 + 0.6652842164 0.6672983170 0.6172876954 + 0.6661018729 0.6681858897 0.6182081103 + 0.6669185758 0.6690726876 0.6191273928 + 0.6677302122 0.6699557900 0.6200417876 + 0.6685419083 0.6708388925 0.6209561825 + 0.6693503857 0.6717147827 0.6218646765 + 0.6701574922 0.6725872159 0.6227704883 + 0.6709632874 0.6734582186 0.6236749887 + 0.6717622876 0.6743215919 0.6245731711 + 0.6725612283 0.6751849055 0.6254714131 + 0.6733565927 0.6760439873 0.6263654232 + 0.6741496921 0.6769003272 0.6272568703 + 0.6749426126 0.6777564287 0.6281480193 + 0.6757320762 0.6786072850 0.6290338039 + 0.6765215993 0.6794583201 0.6299195290 + 0.6773090959 0.6803076863 0.6308029294 + 0.6780942082 0.6811552048 0.6316838264 + 0.6788793206 0.6820027232 0.6325647235 + 0.6796609163 0.6828439832 0.6334397793 + 0.6804419756 0.6836842895 0.6343142986 + 0.6812220216 0.6845229864 0.6351867914 + 0.6819983721 0.6853569150 0.6360538006 + 0.6827747822 0.6861907244 0.6369209290 + 0.6835479140 0.6870210767 0.6377838254 + 0.6843187809 0.6878491044 0.6386439800 + 0.6850897074 0.6886770129 0.6395043135 + 0.6858559847 0.6894986033 0.6403582096 + 0.6866217852 0.6903195977 0.6412116885 + 0.6873862743 0.6911389828 0.6420640945 + 0.6881462932 0.6919528246 0.6429128051 + 0.6889063120 0.6927667260 0.6437615156 + 0.6896629930 0.6935775876 0.6446070075 + 0.6904165149 0.6943858266 0.6454496980 + 0.6911699772 0.6951940060 0.6462923288 + 0.6919187903 0.6959962845 0.6471291780 + 0.6926661134 0.6967967749 0.6479645967 + 0.6934133768 0.6975972056 0.6487997770 + 0.6941565275 0.6983886957 0.6496288180 + 0.6948996186 0.6991801262 0.6504579186 + 0.6956412792 0.6999704242 0.6512849927 + 0.6963785291 0.7007569075 0.6521068215 + 0.6971156001 0.7015432715 0.6529284716 + 0.6978498101 0.7023270130 0.6537482738 + 0.6985800862 0.7031068802 0.6545658112 + 0.6993104219 0.7038868070 0.6553832293 + 0.7000390291 0.7046630979 0.6561965942 + 0.7007665038 0.7054370046 0.6570075750 + 0.7014939785 0.7062109113 0.6578186154 + 0.7022175789 0.7069805264 0.6586261988 + 0.7029399872 0.7077487707 0.6594328284 + 0.7036622763 0.7085170746 0.6602393985 + 0.7043780088 0.7092791796 0.6610412002 + 0.7050929070 0.7100403905 0.6618425250 + 0.7058076859 0.7108017206 0.6626436710 + 0.7065191269 0.7115598917 0.6634386182 + 0.7072305083 0.7123181224 0.6642333865 + 0.7079415917 0.7130758762 0.6650279164 + 0.7086470723 0.7138280869 0.6658183932 + 0.7093526721 0.7145804167 0.6666089296 + 0.7100573778 0.7153319120 0.6673982143 + 0.7107548714 0.7160776854 0.6681799293 + 0.7114523053 0.7168235183 0.6689617038 + 0.7121492028 0.7175688744 0.6697422266 + 0.7128425837 0.7183113098 0.6705163717 + 0.7135359049 0.7190536857 0.6712905765 + 0.7142282724 0.7197949886 0.6720638275 + 0.7149152756 0.7205299139 0.6728317142 + 0.7156022191 0.7212648988 0.6735996008 + 0.7162883878 0.7219992280 0.6743667722 + 0.7169690132 0.7227286100 0.6751294732 + 0.7176495790 0.7234581113 0.6758921742 + 0.7183300257 0.7241873145 0.6766545177 + 0.7190073729 0.7249132991 0.6774132252 + 0.7196847796 0.7256392837 0.6781718731 + 0.7203623056 0.7263653278 0.6789305210 + 0.7210342288 0.7270826101 0.6796817780 + 0.7217060924 0.7277998924 0.6804329753 + 0.7223780155 0.7285171747 0.6811842918 + 0.7230476737 0.7292283773 0.6819289923 + 0.7237172127 0.7299389243 0.6826732159 + 0.7243866920 0.7306494117 0.6834173203 + 0.7250542045 0.7313563228 0.6841576099 + 0.7257212996 0.7320619822 0.6848968267 + 0.7263882756 0.7327678204 0.6856359839 + 0.7270516157 0.7334702015 0.6863722205 + 0.7277126908 0.7341706157 0.6871067882 + 0.7283738256 0.7348709702 0.6878414154 + 0.7290335298 0.7355691195 0.6885737777 + 0.7296916246 0.7362642884 0.6893038154 + 0.7303497791 0.7369595170 0.6900337934 + 0.7310072184 0.7376533151 0.6907622814 + 0.7316623926 0.7383428216 0.6914864779 + 0.7323176265 0.7390323281 0.6922107935 + 0.7329726815 0.7397217155 0.6929348111 + 0.7336215973 0.7404049039 0.6936529279 + 0.7342703938 0.7410882115 0.6943709254 + 0.7349191904 0.7417714000 0.6950889826 + 0.7355654240 0.7424499989 0.6958044767 + 0.7362108827 0.7431272268 0.6965193748 + 0.7368562818 0.7438042760 0.6972342730 + 0.7375000715 0.7444782853 0.6979461908 + 0.7381421924 0.7451488972 0.6986551881 + 0.7387843132 0.7458193898 0.6993641257 + 0.7394251823 0.7464888096 0.7000715137 + 0.7400605083 0.7471522093 0.7007719278 + 0.7406957746 0.7478156090 0.7014722228 + 0.7413311005 0.7484790087 0.7021725774 + 0.7419633269 0.7491366267 0.7028682828 + 0.7425947785 0.7497931123 0.7035630941 + 0.7432262897 0.7504494786 0.7042579055 + 0.7438560724 0.7511044741 0.7049499154 + 0.7444838881 0.7517579198 0.7056387067 + 0.7451115847 0.7524113059 0.7063274980 + 0.7457391024 0.7530642748 0.7070159912 + 0.7463619113 0.7537124157 0.7077018023 + 0.7469847202 0.7543604970 0.7083876133 + 0.7476075292 0.7550085783 0.7090734243 + 0.7482284904 0.7556517720 0.7097554207 + 0.7488484979 0.7562924027 0.7104355097 + 0.7494685054 0.7569329739 0.7111154795 + 0.7500876784 0.7575728297 0.7117941976 + 0.7507038116 0.7582098246 0.7124679089 + 0.7513198256 0.7588467002 0.7131415009 + 0.7519357800 0.7594835758 0.7138150930 + 0.7525480986 0.7601163983 0.7144855857 + 0.7531589270 0.7607474923 0.7151550055 + 0.7537698150 0.7613785863 0.7158244252 + 0.7543799877 0.7620080113 0.7164921761 + 0.7549877763 0.7626309991 0.7171549201 + 0.7555956244 0.7632541060 0.7178174853 + 0.7562034130 0.7638770938 0.7184802294 + 0.7568084002 0.7644972801 0.7191396952 + 0.7574118972 0.7651162148 0.7197976708 + 0.7580155134 0.7657349706 0.7204558253 + 0.7586185932 0.7663530707 0.7211132050 + 0.7592173815 0.7669656277 0.7217658758 + 0.7598162889 0.7675780058 0.7224187255 + 0.7604150772 0.7681905031 0.7230715156 + 0.7610118985 0.7688006759 0.7237222195 + 0.7616066933 0.7694088817 0.7243710160 + 0.7622014880 0.7700170875 0.7250198722 + 0.7627962828 0.7706251740 0.7256687284 + 0.7633875012 0.7712314725 0.7263153195 + 0.7639781237 0.7718374133 0.7269614935 + 0.7645688057 0.7724434137 0.7276077867 + 0.7651584148 0.7730479240 0.7282524109 + 0.7657443881 0.7736473083 0.7288914919 + 0.7663304806 0.7742465734 0.7295305729 + 0.7669165730 0.7748460174 0.7301695943 + 0.7675005794 0.7754428983 0.7308055162 + 0.7680826783 0.7760378122 0.7314386964 + 0.7686648965 0.7766327262 0.7320718765 + 0.7692471147 0.7772275209 0.7327051759 + 0.7698258758 0.7778202891 0.7333346009 + 0.7704041004 0.7784126997 0.7339633703 + 0.7709822059 0.7790051103 0.7345920801 + 0.7715600729 0.7795969248 0.7352203727 + 0.7721338272 0.7801824808 0.7358438969 + 0.7727075219 0.7807679772 0.7364673018 + 0.7732812762 0.7813535929 0.7370908260 + 0.7738538980 0.7819374800 0.7377125025 + 0.7744238973 0.7825171947 0.7383304834 + 0.7749938965 0.7830970287 0.7389485836 + 0.7755638957 0.7836768031 0.7395666242 + 0.7761321068 0.7842543721 0.7401825190 + 0.7766981125 0.7848296165 0.7407962084 + 0.7772641778 0.7854048014 0.7414098978 + 0.7778303027 0.7859801054 0.7420237064 + 0.7783936262 0.7865508795 0.7426350117 + 0.7789554000 0.7871193290 0.7432450056 + 0.7795171738 0.7876875997 0.7438551188 + 0.7800790071 0.7882559896 0.7444651127 + 0.7806380987 0.7888197899 0.7450724840 + 0.7811962962 0.7893822789 0.7456791997 + 0.7817544937 0.7899448276 0.7462859154 + 0.7823126912 0.7905073166 0.7468925714 + 0.7828676105 0.7910656929 0.7474957108 + 0.7834218740 0.7916235924 0.7480981946 + 0.7839761972 0.7921813726 0.7487007976 + 0.7845305204 0.7927392125 0.7493032813 + 0.7850810289 0.7932925820 0.7499018908 + 0.7856311202 0.7938457131 0.7505000830 + 0.7861812711 0.7943987250 0.7510983944 + 0.7867314219 0.7949517965 0.7516967058 + 0.7872781754 0.7955003977 0.7522919178 + 0.7878248096 0.7960488200 0.7528868914 + 0.7883713841 0.7965971828 0.7534819841 + 0.7889180183 0.7971456051 0.7540770769 + 0.7894610167 0.7976896763 0.7546678185 + 0.7900037169 0.7982336283 0.7552582026 + 0.7905464172 0.7987774014 0.7558485866 + 0.7910891175 0.7993212938 0.7564390898 + 0.7916281223 0.7998626232 0.7570242286 + 0.7921667099 0.8004035950 0.7576088905 + 0.7927052975 0.8009446263 0.7581936121 + 0.7932438850 0.8014857173 0.7587782741 + 0.7937796116 0.8020228744 0.7593606710 + 0.7943146825 0.8025593758 0.7599425912 + 0.7948498130 0.8030958772 0.7605245113 + 0.7953848839 0.8036323190 0.7611063719 + 0.7959170938 0.8041642904 0.7616853714 + 0.7964482903 0.8046945930 0.7622634172 + 0.7969794869 0.8052248955 0.7628415227 + 0.7975106239 0.8057551980 0.7634195089 + 0.7980393767 0.8062841296 0.7639942765 + 0.7985665202 0.8068119287 0.7645670176 + 0.7990936041 0.8073397875 0.7651396990 + 0.7996206284 0.8078677058 0.7657123804 + 0.8001462817 0.8083937764 0.7662832737 + 0.8006699085 0.8089175224 0.7668517828 + 0.8011934161 0.8094412088 0.7674202919 + 0.8017169833 0.8099648952 0.7679886818 + 0.8022397757 0.8104875088 0.7685561776 + 0.8027595282 0.8110054135 0.7691202760 + 0.8032791018 0.8115233779 0.7696843743 + 0.8037986755 0.8120412827 0.7702484727 + 0.8043184280 0.8125593066 0.7708125114 + 0.8048341870 0.8130753040 0.7713751793 + 0.8053497076 0.8135911822 0.7719377279 + 0.8058652878 0.8141071200 0.7725002766 + 0.8063809276 0.8146229982 0.7730628848 + 0.8068935871 0.8151363730 0.7736229897 + 0.8074046969 0.8156484962 0.7741820216 + 0.8079158068 0.8161606789 0.7747409940 + 0.8084269762 0.8166728020 0.7753000259 + 0.8089368939 0.8171827197 0.7758569121 + 0.8094444871 0.8176885247 0.7764102221 + 0.8099520802 0.8181943893 0.7769634724 + 0.8104596734 0.8187001944 0.7775169015 + 0.8109673858 0.8192059994 0.7780702114 + 0.8114724159 0.8197085261 0.7786207199 + 0.8119773865 0.8202108741 0.7791712880 + 0.8124824762 0.8207132816 0.7797217965 + 0.8129875064 0.8212158084 0.7802724242 + 0.8134900928 0.8217161894 0.7808198929 + 0.8139910102 0.8222153783 0.7813655734 + 0.8144919276 0.8227146268 0.7819113135 + 0.8149927855 0.8232136965 0.7824569941 + 0.8154932261 0.8237118125 0.7830020189 + 0.8159909248 0.8242052197 0.7835443020 + 0.8164886236 0.8246986270 0.7840867043 + 0.8169863820 0.8251919150 0.7846289873 + 0.8174840808 0.8256853223 0.7851713896 + 0.8179801702 0.8261765242 0.7857123017 + 0.8184756041 0.8266668916 0.7862526774 + 0.8189710975 0.8271573782 0.7867931128 + 0.8194664717 0.8276478052 0.7873336077 + 0.8199610710 0.8281375170 0.7878730297 + 0.8204528093 0.8286252022 0.7884094715 + 0.8209444284 0.8291128278 0.7889459729 + 0.8214361072 0.8296005130 0.7894824743 + 0.8219277859 0.8300880790 0.7900189757 + 0.8224173784 0.8305714130 0.7905547023 + 0.8229061961 0.8310527205 0.7910900116 + 0.8233950138 0.8315340281 0.7916253805 + 0.8238837719 0.8320153952 0.7921606898 + 0.8243722916 0.8324962258 0.7926955819 + 0.8248590827 0.8329733014 0.7932277918 + 0.8253458738 0.8334503770 0.7937598825 + 0.8258327246 0.8339275122 0.7942920923 + 0.8263195157 0.8344045877 0.7948243022 + 0.8268045187 0.8348805904 0.7953537107 + 0.8272879124 0.8353555799 0.7958806753 + 0.8277711868 0.8358306289 0.7964078188 + 0.8282545209 0.8363054991 0.7969347835 + 0.8287379146 0.8367804885 0.7974618077 + 0.8292189837 0.8372507095 0.7979866862 + 0.8296996951 0.8377199769 0.7985112071 + 0.8301805258 0.8381894231 0.7990357876 + 0.8306612968 0.8386586905 0.7995604277 + 0.8311417103 0.8391273022 0.8000841737 + 0.8316208124 0.8395920992 0.8006044030 + 0.8320997953 0.8400568962 0.8011245728 + 0.8325788975 0.8405218124 0.8016448021 + 0.8330578804 0.8409866095 0.8021649718 + 0.8335351944 0.8414500952 0.8026837707 + 0.8340101242 0.8419117928 0.8032010794 + 0.8344849944 0.8423734903 0.8037183285 + 0.8349598050 0.8428351879 0.8042355180 + 0.8354346752 0.8432968855 0.8047528267 + 0.8359069824 0.8437553048 0.8052688837 + 0.8363779783 0.8442121744 0.8057845831 + 0.8368489742 0.8446689844 0.8063002229 + 0.8373200297 0.8451257944 0.8068159223 + 0.8377910256 0.8455827236 0.8073315024 + 0.8382608294 0.8460361958 0.8078433275 + 0.8387305140 0.8464891911 0.8083544970 + 0.8392001987 0.8469423056 0.8088657260 + 0.8396698833 0.8473953009 0.8093768954 + 0.8401396275 0.8478482962 0.8098881245 + 0.8406054974 0.8482989073 0.8103969097 + 0.8410714865 0.8487493992 0.8109058142 + 0.8415374756 0.8492000103 0.8114145994 + 0.8420035243 0.8496506214 0.8119235039 + 0.8424689770 0.8501005769 0.8124318719 + 0.8429316282 0.8505470157 0.8129380941 + 0.8433941007 0.8509933949 0.8134443164 + 0.8438566923 0.8514398932 0.8139504194 + 0.8443192244 0.8518862724 0.8144565821 + 0.8447815776 0.8523321152 0.8149620891 + 0.8452432752 0.8527753949 0.8154653907 + 0.8457049727 0.8532186747 0.8159685731 + 0.8461666107 0.8536620140 0.8164718747 + 0.8466283083 0.8541052938 0.8169751167 + 0.8470892906 0.8545482159 0.8174781203 + 0.8475477099 0.8549897075 0.8179804087 + 0.8480061889 0.8554311991 0.8184826970 + 0.8484646082 0.8558726907 0.8189849854 + 0.8489230871 0.8563141823 0.8194872737 + 0.8493804932 0.8567548990 0.8199887276 + 0.8498343825 0.8571929932 0.8204873204 + 0.8502882719 0.8576310277 0.8209857941 + 0.8507422209 0.8580691218 0.8214843869 + 0.8511961102 0.8585072160 0.8219829798 + 0.8516497016 0.8589447141 0.8224810958 + 0.8521021008 0.8593794107 0.8229773045 + 0.8525546193 0.8598141074 0.8234735131 + 0.8530070186 0.8602489233 0.8239697218 + 0.8534594178 0.8606836200 0.8244658709 + 0.8539115787 0.8611180186 0.8249620199 + 0.8543611169 0.8615491986 0.8254572153 + 0.8548105955 0.8619803190 0.8259524107 + 0.8552600741 0.8624114990 0.8264474869 + 0.8557096124 0.8628426194 0.8269426823 + 0.8561590910 0.8632737994 0.8274378777 + 0.8566038013 0.8637009859 0.8279286027 + 0.8570482135 0.8641281128 0.8284192085 + 0.8574925065 0.8645551205 0.8289096951 + 0.8579369187 0.8649821281 0.8294003010 + 0.8583812118 0.8654091954 0.8298907876 + 0.8588234782 0.8658344150 0.8303787708 + 0.8592652082 0.8662589788 0.8308660984 + 0.8597068191 0.8666837215 0.8313534260 + 0.8601484895 0.8671082854 0.8318405747 + 0.8605902195 0.8675329089 0.8323279023 + 0.8610305190 0.8679561019 0.8328140974 + 0.8614696860 0.8683781028 0.8332993984 + 0.8619089127 0.8687999845 0.8337846994 + 0.8623480797 0.8692219853 0.8342700005 + 0.8627873063 0.8696439862 0.8347553015 + 0.8632252216 0.8700649738 0.8352395296 + 0.8636596203 0.8704838157 0.8357210755 + 0.8640940785 0.8709024787 0.8362026215 + 0.8645285964 0.8713212013 0.8366841078 + 0.8649629951 0.8717399836 0.8371655941 + 0.8653975129 0.8721587062 0.8376470804 + 0.8658297062 0.8725745082 0.8381273746 + 0.8662618995 0.8729901910 0.8386076093 + 0.8666940928 0.8734058738 0.8390877843 + 0.8671262264 0.8738214970 0.8395680785 + 0.8675584197 0.8742371798 0.8400483131 + 0.8679893017 0.8746507168 0.8405265808 + 0.8684194088 0.8750627041 0.8410037756 + 0.8688495159 0.8754748106 0.8414809108 + 0.8692796230 0.8758867979 0.8419579864 + 0.8697096705 0.8762987852 0.8424351811 + 0.8701388836 0.8767099977 0.8429118991 + 0.8705646992 0.8771181107 0.8433871865 + 0.8709903955 0.8775262237 0.8438625932 + 0.8714162111 0.8779342771 0.8443378806 + 0.8718420267 0.8783423901 0.8448132277 + 0.8722677827 0.8787505031 0.8452885151 + 0.8726921082 0.8791568875 0.8457635045 + 0.8731160164 0.8795629144 0.8462383151 + 0.8735398054 0.8799688220 0.8467131257 + 0.8739637136 0.8803747892 0.8471878767 + 0.8743875027 0.8807808161 0.8476626873 + 0.8748108745 0.8811860085 0.8481363058 + 0.8752331138 0.8815891743 0.8486071229 + 0.8756552935 0.8819925189 0.8490779996 + 0.8760774732 0.8823956847 0.8495488167 + 0.8764997125 0.8827990294 0.8500195742 + 0.8769218922 0.8832021952 0.8504905105 + 0.8773404956 0.8836026192 0.8509593010 + 0.8777579069 0.8840019703 0.8514273763 + 0.8781753182 0.8844013810 0.8518955112 + 0.8785927296 0.8848007917 0.8523637056 + 0.8790100813 0.8852002025 0.8528317809 + 0.8794270754 0.8855990767 0.8532996774 + 0.8798415065 0.8859958053 0.8537663817 + 0.8802559972 0.8863924146 0.8542332053 + 0.8806704283 0.8867890835 0.8546999097 + 0.8810849190 0.8871858120 0.8551666141 + 0.8814992905 0.8875824213 0.8556333184 + 0.8819131851 0.8879781961 0.8560982943 + 0.8823264837 0.8883730769 0.8565617800 + 0.8827397227 0.8887680769 0.8570253253 + 0.8831530213 0.8891630173 0.8574888110 + 0.8835663199 0.8895580173 0.8579522967 + 0.8839796185 0.8899530172 0.8584157825 + 0.8843892813 0.8903455138 0.8588786721 + 0.8847984076 0.8907375932 0.8593413830 + 0.8852074146 0.8911296725 0.8598040938 + 0.8856164813 0.8915218115 0.8602668047 + 0.8860256076 0.8919138908 0.8607295752 + 0.8864343166 0.8923054934 0.8611919284 + 0.8868409991 0.8926942945 0.8616520762 + 0.8872476220 0.8930829763 0.8621122837 + 0.8876541853 0.8934717774 0.8625724912 + 0.8880609274 0.8938605189 0.8630326986 + 0.8884674907 0.8942492008 0.8634929061 + 0.8888738751 0.8946374059 0.8639521003 + 0.8892799020 0.8950244188 0.8644095063 + 0.8896859288 0.8954114914 0.8648669124 + 0.8900917768 0.8957985044 0.8653243780 + 0.8904978037 0.8961855769 0.8657817841 + 0.8909037709 0.8965725899 0.8662391901 + 0.8913077116 0.8969581127 0.8666961193 + 0.8917099833 0.8973423243 0.8671525121 + 0.8921123147 0.8977264762 0.8676090240 + 0.8925145864 0.8981108069 0.8680654168 + 0.8929169178 0.8984950185 0.8685219288 + 0.8933190703 0.8988791704 0.8689783216 + 0.8937194943 0.8992601037 0.8694334030 + 0.8941190839 0.8996396065 0.8698878884 + 0.8945186138 0.9000191092 0.8703424931 + 0.8949180841 0.9003986120 0.8707969785 + 0.8953176737 0.9007781148 0.8712515235 + 0.8957172036 0.9011576176 0.8717060089 + 0.8961154819 0.9015353918 0.8721609116 + 0.8965135217 0.9019128084 0.8726158142 + 0.8969115019 0.9022902250 0.8730707765 + 0.8973094821 0.9026675820 0.8735256791 + 0.8977075219 0.9030449986 0.8739807010 + 0.8981055021 0.9034224153 0.8744356036 + 0.8985009789 0.9037982821 0.8748894930 + 0.8988959789 0.9041739702 0.8753430843 + 0.8992909193 0.9045495987 0.8757967949 + 0.8996858001 0.9049252868 0.8762505054 + 0.9000808001 0.9053009152 0.8767040968 + 0.9004756808 0.9056766033 0.8771578074 + 0.9008677006 0.9060493112 0.8776090145 + 0.9012590051 0.9064213037 0.8780596852 + 0.9016503096 0.9067932963 0.8785104156 + 0.9020416141 0.9071652889 0.8789610863 + 0.9024329782 0.9075372815 0.8794118166 + 0.9028242826 0.9079092741 0.8798624873 + 0.9032142162 0.9082794189 0.8803126812 + 0.9036036134 0.9086487889 0.8807626963 + 0.9039930105 0.9090182185 0.8812127113 + 0.9043824077 0.9093875885 0.8816627264 + 0.9047718048 0.9097570181 0.8821126819 + 0.9051612020 0.9101263881 0.8825628161 + 0.9055489898 0.9104949236 0.8830112815 + 0.9059358239 0.9108626842 0.8834589720 + 0.9063225985 0.9112305045 0.8839067221 + 0.9067094922 0.9115983844 0.8843544126 + 0.9070963264 0.9119662046 0.8848021030 + 0.9074832201 0.9123340845 0.8852497935 + 0.9078686237 0.9127002954 0.8856955767 + 0.9082522988 0.9130645990 0.8861392736 + 0.9086359739 0.9134290218 0.8865829706 + 0.9090197086 0.9137933254 0.8870267272 + 0.9094033837 0.9141576886 0.8874704242 + 0.9097871184 0.9145219922 0.8879141212 + 0.9101704955 0.9148855805 0.8883572817 + 0.9105526805 0.9152469039 0.8887993097 + 0.9109349847 0.9156082273 0.8892412782 + 0.9113172293 0.9159694910 0.8896833062 + 0.9116994739 0.9163308144 0.8901252747 + 0.9120817184 0.9166920185 0.8905673027 + 0.9124640226 0.9170532823 0.8910092711 + 0.9128441811 0.9174141288 0.8914495111 + 0.9132243991 0.9177749157 0.8918895721 + 0.9136046171 0.9181355834 0.8923298120 + 0.9139847755 0.9184963703 0.8927698731 + 0.9143649936 0.9188570976 0.8932099938 + 0.9147452116 0.9192178845 0.8936501741 + 0.9151231050 0.9195770025 0.8940905929 + 0.9154999256 0.9199352860 0.8945311904 + 0.9158766270 0.9202936888 0.8949717283 + 0.9162533283 0.9206519723 0.8954123259 + 0.9166300893 0.9210103154 0.8958528042 + 0.9170067906 0.9213687181 0.8962934017 + 0.9173828959 0.9217258096 0.8967335224 + 0.9177572727 0.9220798016 0.8971729279 + 0.9181317091 0.9224339128 0.8976122141 + 0.9185060859 0.9227880239 0.8980515003 + 0.9188805223 0.9231420159 0.8984909058 + 0.9192548990 0.9234961271 0.8989301920 + 0.9196293950 0.9238501787 0.8993694782 + 0.9200025201 0.9242026806 0.8998063803 + 0.9203755260 0.9245550036 0.9002429247 + 0.9207484126 0.9249072075 0.9006794095 + 0.9211214185 0.9252594709 0.9011157751 + 0.9214943051 0.9256117940 0.9015523195 + 0.9218673110 0.9259641171 0.9019888043 + 0.9222391248 0.9263157845 0.9024249911 + 0.9226092100 0.9266666770 0.9028608799 + 0.9229792953 0.9270175099 0.9032967091 + 0.9233493209 0.9273684025 0.9037325978 + 0.9237194061 0.9277192950 0.9041684866 + 0.9240894914 0.9280701280 0.9046043158 + 0.9244595766 0.9284210205 0.9050402045 + 0.9248281121 0.9287691116 0.9054753184 + 0.9251965284 0.9291167259 0.9059103727 + 0.9255648255 0.9294642806 0.9063454866 + 0.9259331226 0.9298120141 0.9067806005 + 0.9263014793 0.9301596284 0.9072157145 + 0.9266697764 0.9305071831 0.9076508284 + 0.9270378947 0.9308542013 0.9080855250 + 0.9274052978 0.9311996102 0.9085192084 + 0.9277727008 0.9315450191 0.9089530110 + 0.9281402230 0.9318904281 0.9093868136 + 0.9285076261 0.9322357178 0.9098204970 + 0.9288750291 0.9325811267 0.9102542996 + 0.9292423725 0.9329264760 0.9106879830 + 0.9296076298 0.9332711101 0.9111205935 + 0.9299712777 0.9336152077 0.9115526080 + 0.9303351045 0.9339594245 0.9119845033 + 0.9306988120 0.9343035221 0.9124163985 + 0.9310625792 0.9346476197 0.9128482938 + 0.9314264059 0.9349917769 0.9132803082 + 0.9317901134 0.9353358746 0.9137122035 + 0.9321511984 0.9356771708 0.9141423106 + 0.9325122237 0.9360182285 0.9145721793 + 0.9328730702 0.9363592863 0.9150022268 + 0.9332339764 0.9367004037 0.9154322147 + 0.9335948825 0.9370414019 0.9158620834 + 0.9339559078 0.9373825192 0.9162920713 + 0.9343165159 0.9377229810 0.9167218208 + 0.9346756935 0.9380605817 0.9171506166 + 0.9350348711 0.9383983016 0.9175792933 + 0.9353941083 0.9387360215 0.9180080891 + 0.9357532859 0.9390736222 0.9184368849 + 0.9361125231 0.9394112825 0.9188656211 + 0.9364717007 0.9397490025 0.9192944169 + 0.9368298054 0.9400861263 0.9197227955 + 0.9371858835 0.9404221773 0.9201506972 + 0.9375420213 0.9407582879 0.9205787182 + 0.9378980994 0.9410943985 0.9210066199 + 0.9382542968 0.9414305091 0.9214345813 + 0.9386103749 0.9417666197 0.9218624830 + 0.9389665127 0.9421027899 0.9222903848 + 0.9393215179 0.9424378872 0.9227181077 + 0.9396752715 0.9427719712 0.9231454134 + 0.9400290847 0.9431061745 0.9235727191 + 0.9403830171 0.9434403181 0.9240000844 + 0.9407367706 0.9437745214 0.9244273901 + 0.9410905838 0.9441086054 0.9248546958 + 0.9414445162 0.9444426894 0.9252821207 + 0.9417976141 0.9447755218 0.9257091880 + 0.9421502948 0.9451072812 0.9261360765 + 0.9425029159 0.9454391003 0.9265630841 + 0.9428554773 0.9457709193 0.9269899726 + 0.9432082176 0.9461026788 0.9274169803 + 0.9435607791 0.9464343786 0.9278439283 + 0.9439134002 0.9467661977 0.9282708764 + 0.9442645907 0.9470977187 0.9286978245 + 0.9446147084 0.9474288821 0.9291247725 + 0.9449648261 0.9477601051 0.9295517802 + 0.9453148842 0.9480913281 0.9299787283 + 0.9456650019 0.9484224916 0.9304056764 + 0.9460151196 0.9487537146 0.9308326840 + 0.9463651776 0.9490848780 0.9312595725 + 0.9467138052 0.9494156241 0.9316855073 + 0.9470613003 0.9497458935 0.9321106076 + 0.9474087954 0.9500762224 0.9325357080 + 0.9477561712 0.9504064918 0.9329606891 + 0.9481037259 0.9507368207 0.9333857894 + 0.9484512210 0.9510670900 0.9338108897 + 0.9487985969 0.9513974190 0.9342358708 + 0.9491446018 0.9517257214 0.9346597791 + 0.9494888783 0.9520516992 0.9350821972 + 0.9498332143 0.9523777962 0.9355046749 + 0.9501774907 0.9527037740 0.9359272122 + 0.9505218267 0.9530298114 0.9363496900 + 0.9508661032 0.9533559084 0.9367721081 + 0.9512103200 0.9536818862 0.9371945858 + 0.9515535235 0.9540063143 0.9376161098 + 0.9518942237 0.9543272853 0.9380356073 + 0.9522349238 0.9546483159 0.9384549856 + 0.9525756836 0.9549692869 0.9388744831 + 0.9529163837 0.9552901983 0.9392939806 + 0.9532570839 0.9556112289 0.9397134185 + 0.9535977840 0.9559322000 0.9401329160 + 0.9539381862 0.9562529922 0.9405519962 + 0.9542763233 0.9565721750 0.9409685731 + 0.9546142817 0.9568914175 0.9413852096 + 0.9549522996 0.9572107196 0.9418017864 + 0.9552903771 0.9575299025 0.9422184229 + 0.9556283951 0.9578490853 0.9426349998 + 0.9559664726 0.9581683874 0.9430515766 + 0.9563044906 0.9584875703 0.9434682131 + 0.9566408992 0.9588049054 0.9438832998 + 0.9569768906 0.9591218233 0.9442980289 + 0.9573128819 0.9594386816 0.9447128177 + 0.9576488733 0.9597554803 0.9451274872 + 0.9579848051 0.9600723982 0.9455422759 + 0.9583207965 0.9603893161 0.9459570050 + 0.9586567879 0.9607061744 0.9463717937 + 0.9589915872 0.9610219002 0.9467856288 + 0.9593248963 0.9613364935 0.9471985102 + 0.9596583247 0.9616510868 0.9476113915 + 0.9599916935 0.9619656205 0.9480242729 + 0.9603250027 0.9622802138 0.9484372139 + 0.9606583714 0.9625946879 0.9488500953 + 0.9609917998 0.9629092813 0.9492629170 + 0.9613248706 0.9632236958 0.9496756792 + 0.9616556168 0.9635366201 0.9500876069 + 0.9619864225 0.9638494849 0.9504995942 + 0.9623171091 0.9641624093 0.9509115219 + 0.9626479149 0.9644752741 0.9513233900 + 0.9629786015 0.9647881985 0.9517353177 + 0.9633094072 0.9651011825 0.9521471858 + 0.9636400938 0.9654141068 0.9525591135 + 0.9639695287 0.9657256007 0.9529703259 + 0.9642981291 0.9660363197 0.9533810019 + 0.9646267891 0.9663469791 0.9537916780 + 0.9649553895 0.9666576982 0.9542024136 + 0.9652839899 0.9669682980 0.9546130896 + 0.9656125903 0.9672790170 0.9550238252 + 0.9659413099 0.9675896764 0.9554345012 + 0.9662696123 0.9679000974 0.9558449984 + 0.9665955901 0.9682075977 0.9562532902 + 0.9669216275 0.9685152173 0.9566615820 + 0.9672476053 0.9688227177 0.9570698738 + 0.9675735831 0.9691302180 0.9574782252 + 0.9678996801 0.9694377780 0.9578865170 + 0.9682257175 0.9697452784 0.9582948089 + 0.9685516953 0.9700528979 0.9587031007 + 0.9688763022 0.9703593254 0.9591103792 + 0.9691995978 0.9706646800 0.9595170021 + 0.9695230126 0.9709700942 0.9599235058 + 0.9698463082 0.9712755084 0.9603301287 + 0.9701697230 0.9715809226 0.9607365727 + 0.9704930186 0.9718862772 0.9611431956 + 0.9708163738 0.9721916914 0.9615496993 + 0.9711397290 0.9724971056 0.9619563222 + 0.9714608192 0.9728004932 0.9623609781 + 0.9717814922 0.9731037021 0.9627655149 + 0.9721022844 0.9734067917 0.9631699920 + 0.9724230170 0.9737098813 0.9635745883 + 0.9727438092 0.9740129709 0.9639791250 + 0.9730644822 0.9743161798 0.9643836021 + 0.9733852744 0.9746193290 0.9647880793 + 0.9737054706 0.9749218822 0.9651920795 + 0.9740229845 0.9752221107 0.9655939937 + 0.9743404984 0.9755222797 0.9659960270 + 0.9746580720 0.9758223891 0.9663978815 + 0.9749755859 0.9761226177 0.9667997956 + 0.9752930999 0.9764227271 0.9672017097 + 0.9756106138 0.9767228961 0.9676036239 + 0.9759281278 0.9770230055 0.9680054784 + 0.9762442708 0.9773221016 0.9684066772 + 0.9765583873 0.9776195288 0.9688066840 + 0.9768725038 0.9779168963 0.9692066908 + 0.9771866798 0.9782143235 0.9696066976 + 0.9775007963 0.9785116911 0.9700067043 + 0.9778149128 0.9788091779 0.9704067111 + 0.9781290293 0.9791066051 0.9708067775 + 0.9784432054 0.9794039726 0.9712067842 + 0.9787554741 0.9796999097 0.9716057777 + 0.9790663123 0.9799945951 0.9720041752 + 0.9793770909 0.9802892804 0.9724025130 + 0.9796879888 0.9805839062 0.9728007913 + 0.9799988270 0.9808785915 0.9731991291 + 0.9803097248 0.9811732769 0.9735975266 + 0.9806205034 0.9814680219 0.9739958048 + 0.9809312820 0.9817627072 0.9743940830 + 0.9812394977 0.9820554852 0.9747912884 + 0.9815462828 0.9823471904 0.9751877785 + 0.9818530083 0.9826390147 0.9755843282 + 0.9821597934 0.9829307199 0.9759808183 + 0.9824665785 0.9832224846 0.9763773084 + 0.9827733040 0.9835141897 0.9767737985 + 0.9830800891 0.9838058949 0.9771704078 + 0.9833868742 0.9840977192 0.9775668979 + 0.9836912751 0.9843873978 0.9779617190 + 0.9839947224 0.9846761227 0.9783557057 + 0.9842982292 0.9849647880 0.9787496924 + 0.9846016169 0.9852535129 0.9791436791 + 0.9849050045 0.9855421782 0.9795376062 + 0.9852083921 0.9858309031 0.9799315929 + 0.9855117798 0.9861196280 0.9803255796 + 0.9858152270 0.9864082932 0.9807196259 + 0.9861156940 0.9866940975 0.9811127782 + 0.9864144921 0.9869784117 0.9815055132 + 0.9867134094 0.9872627258 0.9818981886 + 0.9870122075 0.9875469804 0.9822909236 + 0.9873110056 0.9878312945 0.9826835990 + 0.9876099229 0.9881156087 0.9830763936 + 0.9879087210 0.9883999228 0.9834691286 + 0.9882075787 0.9886841774 0.9838618040 + 0.9885028005 0.9889653921 0.9842537045 + 0.9887949228 0.9892442226 0.9846450090 + 0.9890869856 0.9895228744 0.9850361943 + 0.9893791080 0.9898015857 0.9854274988 + 0.9896711111 0.9900802970 0.9858188033 + 0.9899631739 0.9903590083 0.9862099886 + 0.9902552962 0.9906377196 0.9866012931 + 0.9905474186 0.9909163713 0.9869924784 + 0.9908375740 0.9911934733 0.9873834252 + 0.9911243916 0.9914677739 0.9877734184 + 0.9914113283 0.9917420745 0.9881634712 + 0.9916980863 0.9920163751 0.9885535240 + 0.9919849038 0.9922906756 0.9889435768 + 0.9922717810 0.9925649762 0.9893336296 + 0.9925585985 0.9928393960 0.9897236824 + 0.9928454161 0.9931136966 0.9901136756 + 0.9931316972 0.9933875203 0.9905033112 + 0.9934136868 0.9936578870 0.9908893108 + 0.9936957955 0.9939283133 0.9912753105 + 0.9939777851 0.9941986799 0.9916613102 + 0.9942598939 0.9944691062 0.9920473099 + 0.9945418835 0.9947394729 0.9924331903 + 0.9948239923 0.9950098991 0.9928191900 + 0.9951061010 0.9952803850 0.9932051897 + 0.9953880906 0.9955508113 0.9935911894 + 0.9956638217 0.9958161116 0.9939712286 + 0.9959380031 0.9960802794 0.9943498969 + 0.9962123036 0.9963445067 0.9947286248 + 0.9964866042 0.9966086745 0.9951072931 + 0.9967609048 0.9968729019 0.9954860210 + 0.9970350862 0.9971370101 0.9958646894 + 0.9973093867 0.9974011779 0.9962432981 + 0.9975836873 0.9976654053 0.9966220260 + 0.9978551865 0.9979274273 0.9969990849 + 0.9981232882 0.9981864095 0.9973741770 + 0.9983913898 0.9984455109 0.9977493286 + 0.9986594915 0.9987046123 0.9981244206 + 0.9989275932 0.9989637136 0.9984995723 + 0.9991956949 0.9992228150 0.9988747239 + 0.9994637966 0.9994817972 0.9992498159 + 0.9997318983 0.9997408986 0.9996249080 + 1.0000000000 1.0000000000 1.0000000000 +} diff --git a/rpplugins/color_correction/resources/film_luts_raw/agfa_agfacolor_vista_800.spi1d b/rpplugins/color_correction/resources/film_luts_raw/agfa_agfacolor_vista_800.spi1d new file mode 100644 index 0000000..2289f6b --- /dev/null +++ b/rpplugins/color_correction/resources/film_luts_raw/agfa_agfacolor_vista_800.spi1d @@ -0,0 +1,1030 @@ +Version 1 +From 0.0 1.0 +Length 1024 +Components 3 +{ + 0.0000000000 0.0000000000 0.0000000000 + 0.0185100008 0.0164319202 0.0126006696 + 0.0311950799 0.0276685897 0.0221115705 + 0.0417797714 0.0372233018 0.0303079691 + 0.0512531996 0.0458445400 0.0377487317 + 0.0600418709 0.0538478307 0.0446756296 + 0.0683360174 0.0614236407 0.0512225516 + 0.0762501881 0.0686839372 0.0574930906 + 0.0838661790 0.0756844804 0.0635228232 + 0.0913166925 0.0824975967 0.0693578273 + 0.0986084193 0.0892031565 0.0750138834 + 0.1057450026 0.0958264992 0.0805220678 + 0.1127896011 0.1024202034 0.0859134421 + 0.1197260022 0.1089596003 0.0911877826 + 0.1265023947 0.1154130027 0.0963427573 + 0.1330948025 0.1217321977 0.1013797969 + 0.1394809932 0.1279036999 0.1063025966 + 0.1456708014 0.1339247972 0.1111140996 + 0.1516747028 0.1397916973 0.1158170998 + 0.1575195938 0.1455152035 0.1204319000 + 0.1632243991 0.1510861963 0.1249561980 + 0.1688113064 0.1565372944 0.1294070035 + 0.1742866039 0.1618628055 0.1337791979 + 0.1796312928 0.1670635045 0.1380856037 + 0.1848537028 0.1721491963 0.1423334032 + 0.1899529994 0.1771177948 0.1465034038 + 0.1949339062 0.1819808930 0.1506060064 + 0.1998192966 0.1867358983 0.1546511948 + 0.2046055943 0.1913896054 0.1586488932 + 0.2093106955 0.1959585994 0.1626013964 + 0.2139423043 0.2004473954 0.1665008068 + 0.2184966058 0.2048527002 0.1703405976 + 0.2229668945 0.2091723979 0.1741351932 + 0.2273671031 0.2134197950 0.1778849959 + 0.2316877991 0.2175989002 0.1815871000 + 0.2359403968 0.2217054963 0.1852401942 + 0.2401207983 0.2257481962 0.1888412982 + 0.2442404926 0.2297320962 0.1923972070 + 0.2482959926 0.2336588949 0.1959189028 + 0.2522906065 0.2375231981 0.1994097978 + 0.2562406063 0.2413284928 0.2028710991 + 0.2601419091 0.2450881004 0.2062990963 + 0.2639907897 0.2487992048 0.2096917033 + 0.2677909136 0.2524616122 0.2130511999 + 0.2715432942 0.2560823858 0.2163791060 + 0.2752490938 0.2596504092 0.2196782976 + 0.2789067924 0.2631703019 0.2229489982 + 0.2825185061 0.2666490972 0.2261860967 + 0.2860870957 0.2700851858 0.2293913960 + 0.2896127105 0.2734856904 0.2325628996 + 0.2930983901 0.2768476009 0.2357040942 + 0.2965483069 0.2801684141 0.2388191074 + 0.2999581099 0.2834582031 0.2419067025 + 0.3033216894 0.2867042124 0.2449615002 + 0.3066503108 0.2899151146 0.2479871958 + 0.3099426925 0.2930943966 0.2509889007 + 0.3132070005 0.2962363064 0.2539705932 + 0.3164420128 0.2993449867 0.2569276094 + 0.3196372092 0.3024170995 0.2598538995 + 0.3228017092 0.3054631948 0.2627541125 + 0.3259347975 0.3084770143 0.2656317949 + 0.3290332854 0.3114668131 0.2684907913 + 0.3321030140 0.3144359887 0.2713276148 + 0.3351433873 0.3173773885 0.2741436064 + 0.3381536007 0.3202837110 0.2769415081 + 0.3411369026 0.3231653869 0.2797215879 + 0.3440904915 0.3260202110 0.2824831903 + 0.3470189869 0.3288542926 0.2852219939 + 0.3499220014 0.3316698968 0.2879402041 + 0.3528007865 0.3344615102 0.2906357050 + 0.3556517959 0.3372254968 0.2933070958 + 0.3584778011 0.3399674892 0.2959615886 + 0.3612776995 0.3426899016 0.2985951900 + 0.3640502095 0.3453918099 0.3012051880 + 0.3667984903 0.3480693996 0.3037928045 + 0.3695279062 0.3507238925 0.3063583076 + 0.3722384870 0.3533582091 0.3089059889 + 0.3749296069 0.3559763134 0.3114354908 + 0.3776003122 0.3585732877 0.3139464855 + 0.3802514076 0.3611460924 0.3164429963 + 0.3828811944 0.3637025952 0.3189218938 + 0.3854868114 0.3662396967 0.3213779926 + 0.3880729079 0.3687601089 0.3238114119 + 0.3906360865 0.3712593019 0.3262237906 + 0.3931770027 0.3737432957 0.3286206126 + 0.3956986070 0.3762117028 0.3310020864 + 0.3982034028 0.3786646128 0.3333649933 + 0.4006921947 0.3811041117 0.3357118070 + 0.4031597972 0.3835237026 0.3380421996 + 0.4056158066 0.3859252036 0.3403576910 + 0.4080604017 0.3883082867 0.3426569998 + 0.4104911089 0.3906767964 0.3449401855 + 0.4129078090 0.3930304050 0.3472093046 + 0.4153085053 0.3953728974 0.3494597971 + 0.4176962078 0.3977056146 0.3516952097 + 0.4200707078 0.4000267088 0.3539173901 + 0.4224311113 0.4023346007 0.3561232984 + 0.4247764051 0.4046272933 0.3583106995 + 0.4271036088 0.4069069028 0.3604839146 + 0.4294143915 0.4091728926 0.3626427054 + 0.4317080081 0.4114241898 0.3647843897 + 0.4339860082 0.4136590064 0.3669061959 + 0.4362483025 0.4158793986 0.3690074980 + 0.4384947121 0.4180856943 0.3710916936 + 0.4407278895 0.4202806056 0.3731572032 + 0.4429492950 0.4224627912 0.3752071857 + 0.4451586008 0.4246312082 0.3772436082 + 0.4473553896 0.4267886877 0.3792651892 + 0.4495382905 0.4289326072 0.3812715113 + 0.4517078996 0.4310675859 0.3832643926 + 0.4538640976 0.4331924021 0.3852454126 + 0.4560067058 0.4353078902 0.3872154057 + 0.4581354856 0.4374152124 0.3891724944 + 0.4602501988 0.4395132959 0.3911151886 + 0.4623506069 0.4416010976 0.3930422068 + 0.4644348025 0.4436782002 0.3949519098 + 0.4665004909 0.4457429945 0.3968465030 + 0.4685483873 0.4477992058 0.3987269998 + 0.4705809951 0.4498446882 0.4005940855 + 0.4725970030 0.4518814087 0.4024456143 + 0.4745942950 0.4539059103 0.4042817056 + 0.4765745997 0.4559206069 0.4061039090 + 0.4785369933 0.4579218924 0.4079152048 + 0.4804831147 0.4599123001 0.4097140133 + 0.4824160933 0.4618884921 0.4115009010 + 0.4843369126 0.4638526142 0.4132741988 + 0.4862442017 0.4658051133 0.4150344133 + 0.4881368876 0.4677473903 0.4167799056 + 0.4900161922 0.4696780145 0.4185154140 + 0.4918822050 0.4715974033 0.4202412963 + 0.4937359989 0.4735072851 0.4219577014 + 0.4955778122 0.4754084051 0.4236656129 + 0.4974071980 0.4772998095 0.4253664017 + 0.4992232919 0.4791795909 0.4270611107 + 0.5010253191 0.4810472131 0.4287497997 + 0.5028162003 0.4829035103 0.4304314852 + 0.5045911074 0.4847469032 0.4321100116 + 0.5063520074 0.4865756035 0.4337812066 + 0.5080993772 0.4883880019 0.4354482889 + 0.5098353028 0.4901869893 0.4371086061 + 0.5115584135 0.4919714034 0.4387632906 + 0.5132681727 0.4937416911 0.4404115975 + 0.5149654746 0.4954991937 0.4420526028 + 0.5166510940 0.4972419143 0.4436877966 + 0.5183221102 0.4989711940 0.4453130066 + 0.5199794769 0.5006883740 0.4469313920 + 0.5216261744 0.5023959875 0.4485433996 + 0.5232623219 0.5040932894 0.4501496851 + 0.5248879194 0.5057805181 0.4517503083 + 0.5265035033 0.5074588060 0.4533442855 + 0.5281016231 0.5091217756 0.4549309015 + 0.5296890140 0.5107734203 0.4565131068 + 0.5312656760 0.5124161243 0.4580908120 + 0.5328325033 0.5140507221 0.4596638978 + 0.5343909860 0.5156767964 0.4612325132 + 0.5359356999 0.5172935128 0.4627946019 + 0.5374701023 0.5189024210 0.4643518031 + 0.5389943719 0.5205038190 0.4659039974 + 0.5405091047 0.5220975280 0.4674513042 + 0.5420141220 0.5236791968 0.4689922929 + 0.5435104966 0.5252534747 0.4705272019 + 0.5449982285 0.5268201232 0.4720568061 + 0.5464764833 0.5283790827 0.4735811949 + 0.5479413867 0.5299316049 0.4750989974 + 0.5493953824 0.5314735174 0.4766100943 + 0.5508413911 0.5330083966 0.4781157076 + 0.5522797704 0.5345366001 0.4796159863 + 0.5537052155 0.5360544920 0.4811086059 + 0.5551214218 0.5375661254 0.4825947881 + 0.5565286875 0.5390713811 0.4840748906 + 0.5579245090 0.5405685902 0.4855479002 + 0.5593087077 0.5420556068 0.4870094061 + 0.5606855154 0.5435367227 0.4884645045 + 0.5620552897 0.5450118780 0.4899129868 + 0.5634167790 0.5464770794 0.4913502932 + 0.5647714138 0.5479345918 0.4927789867 + 0.5661193728 0.5493863225 0.4941999018 + 0.5674555898 0.5508307815 0.4956082106 + 0.5687829256 0.5522680879 0.4970068932 + 0.5701043010 0.5537011027 0.4983989000 + 0.5714179873 0.5551288724 0.4997817874 + 0.5727239251 0.5565506816 0.5011560917 + 0.5740242004 0.5579689145 0.5025244951 + 0.5753160715 0.5593820214 0.5038843155 + 0.5766007900 0.5607866049 0.5052357912 + 0.5778805017 0.5621855855 0.5065827966 + 0.5791519880 0.5635759830 0.5079236031 + 0.5804169178 0.5649588108 0.5092585087 + 0.5816770792 0.5663369298 0.5105897188 + 0.5829272270 0.5677073002 0.5119146109 + 0.5841702223 0.5690726042 0.5132346749 + 0.5854083896 0.5704342723 0.5145516992 + 0.5866373777 0.5717855096 0.5158618093 + 0.5878623724 0.5731319785 0.5171685815 + 0.5890823007 0.5744730830 0.5184715986 + 0.5902937055 0.5758020282 0.5197688937 + 0.5915008187 0.5771260858 0.5210636258 + 0.5926988721 0.5784417987 0.5223534703 + 0.5938925147 0.5797501802 0.5236395001 + 0.5950831771 0.5810542107 0.5249232054 + 0.5962653160 0.5823497176 0.5262010098 + 0.5974434018 0.5836412907 0.5274763107 + 0.5986136198 0.5849254727 0.5287467241 + 0.5997778177 0.5862020850 0.5300114751 + 0.6009387970 0.5874748230 0.5312736034 + 0.6020932198 0.5887362957 0.5325291157 + 0.6032456160 0.5899950862 0.5337823033 + 0.6043936014 0.5912477970 0.5350301862 + 0.6055356264 0.5924956203 0.5362746119 + 0.6066730022 0.5937396884 0.5375164747 + 0.6078019142 0.5949761868 0.5387526155 + 0.6089282036 0.5962103009 0.5399869084 + 0.6100460291 0.5974360704 0.5412151814 + 0.6111602783 0.5986577868 0.5424402952 + 0.6122679114 0.5998724103 0.5436596870 + 0.6133708954 0.6010810733 0.5448756218 + 0.6144707203 0.6022859216 0.5460891724 + 0.6155622005 0.6034839749 0.5472962856 + 0.6166514754 0.6046805978 0.5485017896 + 0.6177281141 0.6058706045 0.5497025847 + 0.6188026071 0.6070585251 0.5509018898 + 0.6198686957 0.6082382798 0.5520957708 + 0.6209319830 0.6094141006 0.5532882214 + 0.6219903827 0.6105834842 0.5544781089 + 0.6230461001 0.6117473245 0.5556638837 + 0.6240993738 0.6129062772 0.5568463802 + 0.6251472831 0.6140604019 0.5580248833 + 0.6261926293 0.6152123213 0.5592017174 + 0.6272296906 0.6163583994 0.5603731871 + 0.6282647848 0.6175032258 0.5615437031 + 0.6292926073 0.6186398864 0.5627098083 + 0.6303197145 0.6197757125 0.5638754964 + 0.6313399076 0.6209014058 0.5650361180 + 0.6323593259 0.6220262051 0.5661963820 + 0.6333720088 0.6231431961 0.5673534870 + 0.6343832016 0.6242589951 0.5685095787 + 0.6353875995 0.6253690720 0.5696610212 + 0.6363899708 0.6264768839 0.5708104968 + 0.6373851895 0.6275768280 0.5719538927 + 0.6383780837 0.6286739707 0.5730956197 + 0.6393638253 0.6297637224 0.5742328763 + 0.6403476000 0.6308506727 0.5753682256 + 0.6413263083 0.6319305897 0.5764986873 + 0.6423032880 0.6330078840 0.5776277781 + 0.6432760954 0.6340783238 0.5787534118 + 0.6442463994 0.6351463199 0.5798763037 + 0.6452097297 0.6362072825 0.5809919834 + 0.6461709738 0.6372658014 0.5821056962 + 0.6471257210 0.6383160949 0.5832133293 + 0.6480792165 0.6393647790 0.5843191743 + 0.6490263939 0.6404061913 0.5854179859 + 0.6499727964 0.6414468288 0.5865159035 + 0.6509122849 0.6424813271 0.5876076818 + 0.6518514752 0.6435155869 0.5886991024 + 0.6527829170 0.6445450187 0.5897815824 + 0.6537142992 0.6455743909 0.5908641219 + 0.6546376944 0.6465963721 0.5919384956 + 0.6555603743 0.6476178765 0.5930123925 + 0.6564759016 0.6486306787 0.5940799117 + 0.6573897004 0.6496415138 0.5951458812 + 0.6582992077 0.6506463289 0.5962070227 + 0.6592066884 0.6516482234 0.5972657800 + 0.6601099968 0.6526457071 0.5983211994 + 0.6610093117 0.6536391973 0.5993734002 + 0.6619052887 0.6546294093 0.6004229784 + 0.6627947092 0.6556134224 0.6014679074 + 0.6636828780 0.6565961838 0.6025115252 + 0.6645650268 0.6575726271 0.6035487056 + 0.6654471159 0.6585490704 0.6045858264 + 0.6663234830 0.6595203876 0.6056172848 + 0.6671994925 0.6604915261 0.6066485047 + 0.6680691242 0.6614578962 0.6076750755 + 0.6689361930 0.6624224782 0.6086999774 + 0.6697993875 0.6633834243 0.6097220182 + 0.6706585288 0.6643403172 0.6107410192 + 0.6715161204 0.6652954221 0.6117582917 + 0.6723682880 0.6662437916 0.6127699018 + 0.6732205749 0.6671922207 0.6137815118 + 0.6740664840 0.6681342721 0.6147891283 + 0.6749119163 0.6690760255 0.6157965064 + 0.6757528782 0.6700139046 0.6167991757 + 0.6765912771 0.6709495783 0.6177995205 + 0.6774272919 0.6718820930 0.6187973022 + 0.6782582998 0.6728078723 0.6197900176 + 0.6790893078 0.6737337112 0.6207826734 + 0.6799132228 0.6746503115 0.6217687130 + 0.6807367802 0.6755667925 0.6227545738 + 0.6815574765 0.6764777899 0.6237366796 + 0.6823765039 0.6773855090 0.6247165203 + 0.6831939816 0.6782909036 0.6256946921 + 0.6840069294 0.6791892052 0.6266679764 + 0.6848198175 0.6800873876 0.6276412010 + 0.6856262088 0.6809793711 0.6286085844 + 0.6864315271 0.6818702221 0.6295750141 + 0.6872345805 0.6827588081 0.6305391788 + 0.6880347729 0.6836444139 0.6315007806 + 0.6888350248 0.6845300198 0.6324623823 + 0.6896290183 0.6854097843 0.6334151030 + 0.6904228926 0.6862894893 0.6343677044 + 0.6912125945 0.6871656179 0.6353166103 + 0.6919984818 0.6880385280 0.6362622976 + 0.6927841902 0.6889110208 0.6372076273 + 0.6935647726 0.6897763014 0.6381461024 + 0.6943454146 0.6906415820 0.6390845776 + 0.6951224208 0.6915038824 0.6400200725 + 0.6958963871 0.6923636794 0.6409534216 + 0.6966701746 0.6932234168 0.6418864131 + 0.6974359155 0.6940783858 0.6428129077 + 0.6982017159 0.6949334145 0.6437392831 + 0.6989647150 0.6957843900 0.6446622014 + 0.6997249126 0.6966313720 0.6455814838 + 0.7004849911 0.6974784732 0.6465008855 + 0.7012411952 0.6983184814 0.6474134922 + 0.7019971013 0.6991580725 0.6483256817 + 0.7027515173 0.6999952793 0.6492353082 + 0.7035031915 0.7008281946 0.6501401067 + 0.7042549253 0.7016611099 0.6510447860 + 0.7050036788 0.7024886012 0.6519446969 + 0.7057514191 0.7033143044 0.6528429985 + 0.7064986229 0.7041394114 0.6537404060 + 0.7072420716 0.7049599886 0.6546317935 + 0.7079855204 0.7057806253 0.6555231810 + 0.7087271214 0.7065981030 0.6564105749 + 0.7094665170 0.7074120045 0.6572937965 + 0.7102057934 0.7082259059 0.6581770182 + 0.7109420896 0.7090328932 0.6590545774 + 0.7116774917 0.7098382115 0.6599308252 + 0.7124124765 0.7106426954 0.6608062983 + 0.7131438255 0.7114415169 0.6616767049 + 0.7138749957 0.7122402787 0.6625469923 + 0.7146041989 0.7130368948 0.6634144187 + 0.7153301239 0.7138301134 0.6642774940 + 0.7160559893 0.7146233916 0.6651405096 + 0.7167779207 0.7154110074 0.6660001278 + 0.7174975872 0.7161955833 0.6668580174 + 0.7182173133 0.7169802785 0.6677159071 + 0.7189335227 0.7177579999 0.6685678959 + 0.7196493149 0.7185348868 0.6694192886 + 0.7203645110 0.7193109989 0.6702697873 + 0.7210751772 0.7200810909 0.6711146235 + 0.7217859030 0.7208511829 0.6719594002 + 0.7224943042 0.7216190100 0.6728019714 + 0.7231976986 0.7223820090 0.6736403108 + 0.7239010930 0.7231450081 0.6744784713 + 0.7246015072 0.7239043713 0.6753134131 + 0.7252988219 0.7246599793 0.6761450768 + 0.7259960771 0.7254155874 0.6769768000 + 0.7266904712 0.7261663079 0.6778048873 + 0.7273831964 0.7269141078 0.6786310077 + 0.7280758023 0.7276619077 0.6794571280 + 0.7287634015 0.7284036279 0.6802788973 + 0.7294492126 0.7291433215 0.6810994148 + 0.7301350832 0.7298830152 0.6819198132 + 0.7308161855 0.7306177020 0.6827344894 + 0.7314965725 0.7313514948 0.6835482121 + 0.7321768999 0.7320852876 0.6843619943 + 0.7328532934 0.7328147292 0.6851683259 + 0.7335293889 0.7335436940 0.6859741211 + 0.7342054844 0.7342727184 0.6867799163 + 0.7348755002 0.7349944711 0.6875799894 + 0.7355453968 0.7357162237 0.6883801222 + 0.7362151742 0.7364377975 0.6891800761 + 0.7368800044 0.7371528745 0.6899746060 + 0.7375447750 0.7378680706 0.6907690763 + 0.7382096052 0.7385832071 0.6915634871 + 0.7388706207 0.7392929196 0.6923534274 + 0.7395316958 0.7400025725 0.6931431890 + 0.7401927114 0.7407122850 0.6939331293 + 0.7408468127 0.7414141893 0.6947162747 + 0.7415009141 0.7421159744 0.6954995990 + 0.7421548963 0.7428178191 0.6962828040 + 0.7428026199 0.7435129285 0.6970598102 + 0.7434499264 0.7442076206 0.6978365183 + 0.7440971732 0.7449023128 0.6986131072 + 0.7447416782 0.7455918193 0.6993851066 + 0.7453858256 0.7462803721 0.7001565099 + 0.7460299134 0.7469691038 0.7009277940 + 0.7466691136 0.7476530075 0.7016950250 + 0.7473068833 0.7483354807 0.7024608850 + 0.7479445934 0.7490180135 0.7032269239 + 0.7485784292 0.7496981025 0.7039886713 + 0.7492100000 0.7503767014 0.7047483921 + 0.7498415709 0.7510554194 0.7055081129 + 0.7504718900 0.7517315149 0.7062641978 + 0.7511010170 0.7524052262 0.7070168853 + 0.7517300248 0.7530788183 0.7077695727 + 0.7523571253 0.7537503839 0.7085205913 + 0.7529804111 0.7544177175 0.7092683911 + 0.7536036968 0.7550848722 0.7100160718 + 0.7542262077 0.7557517290 0.7107632756 + 0.7548426986 0.7564147711 0.7115064859 + 0.7554591894 0.7570779920 0.7122498155 + 0.7560756803 0.7577410936 0.7129930258 + 0.7566884756 0.7583994865 0.7137312293 + 0.7573007941 0.7590574026 0.7144687772 + 0.7579131722 0.7597153187 0.7152063251 + 0.7585223913 0.7603682280 0.7159397006 + 0.7591298223 0.7610182762 0.7166706920 + 0.7597371936 0.7616683841 0.7174018025 + 0.7603425980 0.7623162270 0.7181308866 + 0.7609441280 0.7629598975 0.7188568115 + 0.7615455985 0.7636035085 0.7195826769 + 0.7621468902 0.7642468810 0.7203084230 + 0.7627450824 0.7648851871 0.7210304737 + 0.7633432150 0.7655234933 0.7217525244 + 0.7639414072 0.7661617994 0.7224745750 + 0.7645366192 0.7667945027 0.7231923938 + 0.7651305795 0.7674250007 0.7239086032 + 0.7657245994 0.7680554986 0.7246248126 + 0.7663164139 0.7686836720 0.7253388762 + 0.7669041157 0.7693076730 0.7260494232 + 0.7674916983 0.7699316144 0.7267599106 + 0.7680794001 0.7705556154 0.7274703979 + 0.7686625719 0.7711765170 0.7281758785 + 0.7692456245 0.7717971802 0.7288811207 + 0.7698286176 0.7724180222 0.7295863032 + 0.7704098821 0.7730364203 0.7302888036 + 0.7709895968 0.7736529112 0.7309889793 + 0.7715693116 0.7742694020 0.7316892147 + 0.7721486092 0.7748854160 0.7323889732 + 0.7727230191 0.7754955888 0.7330843210 + 0.7732973099 0.7761058211 0.7337794900 + 0.7738716006 0.7767159939 0.7344747782 + 0.7744429708 0.7773231864 0.7351666093 + 0.7750123739 0.7779282928 0.7358562946 + 0.7755817175 0.7785333991 0.7365459800 + 0.7761507034 0.7791380882 0.7372353077 + 0.7767155766 0.7797393203 0.7379208803 + 0.7772805095 0.7803406119 0.7386065722 + 0.7778455019 0.7809417844 0.7392922044 + 0.7784079909 0.7815397978 0.7399750948 + 0.7789685726 0.7821353078 0.7406558990 + 0.7795292139 0.7827306986 0.7413367033 + 0.7800899148 0.7833262086 0.7420175076 + 0.7806466818 0.7839170098 0.7426925898 + 0.7812033892 0.7845076919 0.7433677912 + 0.7817602158 0.7850984931 0.7440428734 + 0.7823156118 0.7856879234 0.7447155118 + 0.7828689814 0.7862753272 0.7453842759 + 0.7834224105 0.7868626118 0.7460532188 + 0.7839757204 0.7874500155 0.7467219830 + 0.7845265865 0.7880331874 0.7473868728 + 0.7850766778 0.7886152267 0.7480508089 + 0.7856268287 0.7891972065 0.7487146258 + 0.7861765027 0.7897787094 0.7493779063 + 0.7867226005 0.7903565168 0.7500371933 + 0.7872688174 0.7909343243 0.7506964803 + 0.7878149152 0.7915120721 0.7513558269 + 0.7883592248 0.7920885086 0.7520118952 + 0.7889010906 0.7926632762 0.7526640296 + 0.7894430161 0.7932379842 0.7533161044 + 0.7899848223 0.7938128114 0.7539681792 + 0.7905251980 0.7943832278 0.7546153069 + 0.7910649180 0.7949519753 0.7552605867 + 0.7916046977 0.7955207229 0.7559058070 + 0.7921444178 0.7960894704 0.7565510869 + 0.7926815152 0.7966526747 0.7571910024 + 0.7932183743 0.7972157001 0.7578307986 + 0.7937554121 0.7977787256 0.7584705949 + 0.7942914963 0.7983412147 0.7591093183 + 0.7948241234 0.7989016175 0.7597439289 + 0.7953568101 0.7994620800 0.7603784800 + 0.7958894968 0.8000226021 0.7610130906 + 0.7964202166 0.8005809188 0.7616454959 + 0.7969478965 0.8011360168 0.7622743845 + 0.7974755764 0.8016909957 0.7629033923 + 0.7980033159 0.8022460938 0.7635322809 + 0.7985295057 0.8027976751 0.7641590238 + 0.7990543842 0.8033463955 0.7647839189 + 0.7995793819 0.8038951755 0.7654088140 + 0.8001043200 0.8044440150 0.7660337090 + 0.8006263971 0.8049899936 0.7666553855 + 0.8011472225 0.8055347204 0.7672758102 + 0.8016679287 0.8060795069 0.7678961754 + 0.8021886945 0.8066241741 0.7685164809 + 0.8027051091 0.8071653843 0.7691326737 + 0.8032202721 0.8077054024 0.7697477937 + 0.8037353754 0.8082454801 0.7703629136 + 0.8042505980 0.8087856174 0.7709779143 + 0.8047627807 0.8093202114 0.7715882063 + 0.8052744269 0.8098536730 0.7721974850 + 0.8057860136 0.8103871942 0.7728068233 + 0.8062974811 0.8109207153 0.7734162211 + 0.8068054914 0.8114497066 0.7740216851 + 0.8073129058 0.8119781017 0.7746266723 + 0.8078203201 0.8125064969 0.7752317190 + 0.8083277941 0.8130347729 0.7758368254 + 0.8088303804 0.8135598898 0.7764384151 + 0.8093321919 0.8140844107 0.7770395875 + 0.8098341227 0.8146088719 0.7776407003 + 0.8103358746 0.8151333928 0.7782418728 + 0.8108342886 0.8156532049 0.7788380980 + 0.8113318086 0.8161720037 0.7794333100 + 0.8118293881 0.8166908026 0.7800284028 + 0.8123269081 0.8172097206 0.7806236148 + 0.8128222823 0.8177251816 0.7812144756 + 0.8133168817 0.8182396889 0.7818040252 + 0.8138114810 0.8187540770 0.7823935151 + 0.8143060803 0.8192685843 0.7829831243 + 0.8147979975 0.8197811246 0.7835692167 + 0.8152884245 0.8202924728 0.7841535807 + 0.8157786727 0.8208039999 0.7847380042 + 0.8162690997 0.8213154078 0.7853223085 + 0.8167579174 0.8218243122 0.7859038711 + 0.8172453046 0.8223307729 0.7864828110 + 0.8177325726 0.8228374124 0.7870616913 + 0.8182200193 0.8233438730 0.7876405716 + 0.8187068105 0.8238489032 0.7882180810 + 0.8191924095 0.8243508935 0.7887930274 + 0.8196780086 0.8248528838 0.7893679738 + 0.8201637268 0.8253548741 0.7899429202 + 0.8206487894 0.8258563876 0.7905169725 + 0.8211302757 0.8263542056 0.7910869122 + 0.8216118813 0.8268520832 0.7916566730 + 0.8220934272 0.8273500204 0.7922264934 + 0.8225749731 0.8278478980 0.7927963734 + 0.8230516911 0.8283423185 0.7933602929 + 0.8235278726 0.8288363218 0.7939236760 + 0.8240039945 0.8293302059 0.7944871187 + 0.8244801164 0.8298242092 0.7950503826 + 0.8249552846 0.8303152919 0.7956107259 + 0.8254299164 0.8308048248 0.7961691022 + 0.8259044886 0.8312941790 0.7967274785 + 0.8263791203 0.8317837119 0.7972859144 + 0.8268527985 0.8322715759 0.7978432178 + 0.8273245096 0.8327561021 0.7983981967 + 0.8277962208 0.8332406282 0.7989532948 + 0.8282678723 0.8337250948 0.7995082736 + 0.8287395835 0.8342096210 0.8000633717 + 0.8292062879 0.8346912861 0.8006147146 + 0.8296728134 0.8351728916 0.8011659980 + 0.8301392794 0.8356546164 0.8017172813 + 0.8306058049 0.8361362219 0.8022685051 + 0.8310710788 0.8366158009 0.8028172851 + 0.8315353990 0.8370940089 0.8033642769 + 0.8319997787 0.8375722170 0.8039113879 + 0.8324642181 0.8380503058 0.8044583797 + 0.8329282999 0.8385276794 0.8050045967 + 0.8333910704 0.8390009999 0.8055471182 + 0.8338539004 0.8394743204 0.8060895801 + 0.8343166113 0.8399475813 0.8066321015 + 0.8347793818 0.8404209018 0.8071746230 + 0.8352388144 0.8408915997 0.8077148795 + 0.8356966972 0.8413612843 0.8082543015 + 0.8361546993 0.8418310285 0.8087937832 + 0.8366125822 0.8423007131 0.8093332052 + 0.8370695710 0.8427699208 0.8098720908 + 0.8375232220 0.8432372808 0.8104090095 + 0.8379768133 0.8437047005 0.8109459281 + 0.8384304047 0.8441720009 0.8114827871 + 0.8388838768 0.8446394205 0.8120197058 + 0.8393365741 0.8451036811 0.8125535250 + 0.8397887945 0.8455665112 0.8130859137 + 0.8402410746 0.8460292220 0.8136183023 + 0.8406932950 0.8464919925 0.8141508102 + 0.8411452174 0.8469541073 0.8146827221 + 0.8415938020 0.8474109769 0.8152111769 + 0.8420425057 0.8478677869 0.8157396913 + 0.8424912095 0.8483247161 0.8162680864 + 0.8429399133 0.8487815261 0.8167966008 + 0.8433864713 0.8492373228 0.8173233867 + 0.8438311815 0.8496921062 0.8178485036 + 0.8442757726 0.8501468897 0.8183735013 + 0.8447204828 0.8506016731 0.8188986182 + 0.8451651931 0.8510563970 0.8194236755 + 0.8456082940 0.8515083194 0.8199456930 + 0.8460512161 0.8519595861 0.8204671741 + 0.8464940786 0.8524109125 0.8209887743 + 0.8469370008 0.8528622985 0.8215103149 + 0.8473795056 0.8533126116 0.8220310807 + 0.8478202820 0.8537582755 0.8225489855 + 0.8482609987 0.8542038798 0.8230667710 + 0.8487017155 0.8546496034 0.8235846162 + 0.8491423726 0.8550952077 0.8241025209 + 0.8495807052 0.8555396795 0.8246183991 + 0.8500161767 0.8559827209 0.8251321912 + 0.8504515886 0.8564257026 0.8256459236 + 0.8508870006 0.8568686247 0.8261595964 + 0.8513224125 0.8573116064 0.8266733885 + 0.8517556787 0.8577530980 0.8271840811 + 0.8521881104 0.8581939936 0.8276935816 + 0.8526204824 0.8586348295 0.8282030821 + 0.8530527949 0.8590756059 0.8287125826 + 0.8534852266 0.8595165014 0.8292220831 + 0.8539168239 0.8599526286 0.8297290802 + 0.8543483019 0.8603882194 0.8302358985 + 0.8547797799 0.8608238101 0.8307427168 + 0.8552113175 0.8612592816 0.8312494755 + 0.8556426764 0.8616946936 0.8317559958 + 0.8560702801 0.8621253967 0.8322589993 + 0.8564978242 0.8625560999 0.8327620029 + 0.8569254279 0.8629868031 0.8332650065 + 0.8573529720 0.8634175062 0.8337680101 + 0.8577799201 0.8638479114 0.8342701197 + 0.8582031131 0.8642767072 0.8347682953 + 0.8586263061 0.8647056222 0.8352664709 + 0.8590494990 0.8651344180 0.8357647061 + 0.8594726920 0.8655632138 0.8362628818 + 0.8598954082 0.8659911156 0.8367602229 + 0.8603163958 0.8664159179 0.8372551203 + 0.8607373834 0.8668407202 0.8377498984 + 0.8611584902 0.8672655225 0.8382447958 + 0.8615794778 0.8676903248 0.8387396932 + 0.8619998097 0.8681135774 0.8392338157 + 0.8624181747 0.8685330153 0.8397259712 + 0.8628365993 0.8689525127 0.8402181864 + 0.8632550836 0.8693720102 0.8407104015 + 0.8636735082 0.8697913885 0.8412026763 + 0.8640908003 0.8702098131 0.8416935802 + 0.8645054102 0.8706253171 0.8421815038 + 0.8649199009 0.8710408807 0.8426694274 + 0.8653343916 0.8714563847 0.8431572914 + 0.8657490015 0.8718720078 0.8436452150 + 0.8661630154 0.8722869754 0.8441321850 + 0.8665751219 0.8726999760 0.8446164131 + 0.8669872284 0.8731129766 0.8451005220 + 0.8673992753 0.8735259771 0.8455846906 + 0.8678115010 0.8739389777 0.8460687995 + 0.8682234287 0.8743513823 0.8465524912 + 0.8686344028 0.8747605085 0.8470336199 + 0.8690453172 0.8751696944 0.8475146890 + 0.8694562912 0.8755788207 0.8479956985 + 0.8698672056 0.8759880066 0.8484768271 + 0.8702781200 0.8763970137 0.8489577174 + 0.8706849217 0.8768029213 0.8494340777 + 0.8710917830 0.8772087097 0.8499104977 + 0.8714985847 0.8776144981 0.8503869176 + 0.8719053864 0.8780202866 0.8508632183 + 0.8723123074 0.8784261942 0.8513395786 + 0.8727166057 0.8788295984 0.8518124223 + 0.8731204867 0.8792327046 0.8522846103 + 0.8735244274 0.8796356916 0.8527569175 + 0.8739284277 0.8800387979 0.8532291055 + 0.8743323088 0.8804419041 0.8537012935 + 0.8747352958 0.8808423877 0.8541712761 + 0.8751378059 0.8812415004 0.8546400070 + 0.8755401969 0.8816406131 0.8551086783 + 0.8759427071 0.8820397258 0.8555774093 + 0.8763452172 0.8824387789 0.8560460806 + 0.8767465949 0.8828365803 0.8565135002 + 0.8771464229 0.8832321167 0.8569787145 + 0.8775460720 0.8836277127 0.8574439287 + 0.8779459000 0.8840233088 0.8579090834 + 0.8783457279 0.8844187856 0.8583742976 + 0.8787450790 0.8848142028 0.8588392138 + 0.8791409135 0.8852068782 0.8593007922 + 0.8795366287 0.8855996132 0.8597623706 + 0.8799324036 0.8859922886 0.8602240086 + 0.8803281784 0.8863850236 0.8606855869 + 0.8807238936 0.8867778182 0.8611472249 + 0.8811178207 0.8871687055 0.8616060019 + 0.8815109730 0.8875589967 0.8620637059 + 0.8819041848 0.8879492879 0.8625215292 + 0.8822973967 0.8883395791 0.8629792929 + 0.8826907277 0.8887298703 0.8634371161 + 0.8830834031 0.8891189098 0.8638935089 + 0.8834751844 0.8895053864 0.8643475175 + 0.8838670850 0.8898919821 0.8648015261 + 0.8842589855 0.8902785778 0.8652554154 + 0.8846508265 0.8906651735 0.8657094240 + 0.8850427270 0.8910517097 0.8661633730 + 0.8854306936 0.8914347291 0.8666151762 + 0.8858184218 0.8918172717 0.8670668006 + 0.8862060905 0.8921998739 0.8675184846 + 0.8865936995 0.8925824761 0.8679701090 + 0.8869814277 0.8929650784 0.8684217930 + 0.8873677850 0.8933458924 0.8688719869 + 0.8877524734 0.8937243819 0.8693205714 + 0.8881371021 0.8941028714 0.8697690964 + 0.8885217905 0.8944814205 0.8702176213 + 0.8889064789 0.8948599100 0.8706660867 + 0.8892911077 0.8952383995 0.8711146712 + 0.8896743059 0.8956134915 0.8715596199 + 0.8900573850 0.8959884048 0.8720040917 + 0.8904405236 0.8963631988 0.8724486828 + 0.8908236027 0.8967379928 0.8728932142 + 0.8912066221 0.8971129060 0.8733376861 + 0.8915888071 0.8974866271 0.8737813830 + 0.8919690251 0.8978582025 0.8742234111 + 0.8923493028 0.8982297778 0.8746654987 + 0.8927295208 0.8986012936 0.8751075268 + 0.8931097984 0.8989729285 0.8755494952 + 0.8934900165 0.8993445039 0.8759915829 + 0.8938673735 0.8997135758 0.8764312267 + 0.8942434788 0.9000818133 0.8768699765 + 0.8946197033 0.9004498720 0.8773087263 + 0.8949959278 0.9008181095 0.8777474761 + 0.8953720927 0.9011862874 0.8781862855 + 0.8957480788 0.9015542269 0.8786247969 + 0.8961216211 0.9019187093 0.8790593743 + 0.8964951038 0.9022831917 0.8794940114 + 0.8968685865 0.9026476741 0.8799285889 + 0.8972421288 0.9030122161 0.8803632259 + 0.8976156116 0.9033766985 0.8807978034 + 0.8979886174 0.9037405849 0.8812314868 + 0.8983604908 0.9041035175 0.8816633821 + 0.8987324834 0.9044662714 0.8820952773 + 0.8991044760 0.9048290849 0.8825271726 + 0.8994765282 0.9051918983 0.8829591274 + 0.8998485208 0.9055547714 0.8833910823 + 0.9002189040 0.9059160948 0.8838210106 + 0.9005880952 0.9062762856 0.8842495084 + 0.9009574056 0.9066364765 0.8846780062 + 0.9013267159 0.9069967270 0.8851063848 + 0.9016959071 0.9073569179 0.8855348825 + 0.9020652175 0.9077171087 0.8859633803 + 0.9024326801 0.9080746174 0.8863885999 + 0.9027997851 0.9084312916 0.8868126869 + 0.9031668901 0.9087879062 0.8872368932 + 0.9035339952 0.9091445804 0.8876610994 + 0.9039011002 0.9095013142 0.8880853057 + 0.9042682052 0.9098579884 0.8885095119 + 0.9046338201 0.9102131128 0.8889309764 + 0.9049991965 0.9105681777 0.8893523812 + 0.9053646922 0.9109231830 0.8897737265 + 0.9057301283 0.9112783074 0.8901950717 + 0.9060956240 0.9116333723 0.8906164169 + 0.9064608812 0.9119883776 0.8910375834 + 0.9068235755 0.9123414755 0.8914554119 + 0.9071862102 0.9126946926 0.8918731809 + 0.9075487852 0.9130477905 0.8922908902 + 0.9079114795 0.9134010077 0.8927087188 + 0.9082741141 0.9137542248 0.8931264281 + 0.9086365104 0.9141070843 0.8935438991 + 0.9089967012 0.9144567251 0.8939571977 + 0.9093567729 0.9148061872 0.8943704963 + 0.9097169042 0.9151558280 0.8947837949 + 0.9100769758 0.9155054092 0.8951970935 + 0.9104372263 0.9158549905 0.8956103921 + 0.9107971787 0.9162042737 0.8960235119 + 0.9111555219 0.9165493846 0.8964337707 + 0.9115139246 0.9168946147 0.8968440890 + 0.9118723273 0.9172397256 0.8972544074 + 0.9122306108 0.9175848961 0.8976647258 + 0.9125890136 0.9179300070 0.8980749846 + 0.9129472971 0.9182751179 0.8984851837 + 0.9133043289 0.9186192155 0.8988931775 + 0.9136611819 0.9189633131 0.8993011713 + 0.9140180945 0.9193074107 0.8997092247 + 0.9143750072 0.9196515083 0.9001170993 + 0.9147319198 0.9199956059 0.9005250931 + 0.9150887728 0.9203397036 0.9009330869 + 0.9154434204 0.9206820130 0.9013389945 + 0.9157977104 0.9210242033 0.9017447233 + 0.9161520004 0.9213662744 0.9021503925 + 0.9165062904 0.9217085242 0.9025561810 + 0.9168605804 0.9220507145 0.9029619098 + 0.9172148705 0.9223927855 0.9033675790 + 0.9175676107 0.9227315784 0.9037716985 + 0.9179198146 0.9230694175 0.9041752815 + 0.9182720184 0.9234071970 0.9045788050 + 0.9186242223 0.9237450957 0.9049823880 + 0.9189764857 0.9240828753 0.9053859711 + 0.9193286896 0.9244207144 0.9057894945 + 0.9196799994 0.9247564077 0.9061918259 + 0.9200307131 0.9250903726 0.9065930843 + 0.9203813076 0.9254245162 0.9069944024 + 0.9207320213 0.9257584810 0.9073956013 + 0.9210826159 0.9260926247 0.9077969193 + 0.9214332104 0.9264267087 0.9081981778 + 0.9217830896 0.9267603755 0.9085987806 + 0.9221310019 0.9270933867 0.9089978933 + 0.9224789143 0.9274263978 0.9093968868 + 0.9228268862 0.9277595282 0.9097959995 + 0.9231747985 0.9280924797 0.9101951122 + 0.9235227704 0.9284254909 0.9105942249 + 0.9238706827 0.9287585020 0.9109932184 + 0.9242162108 0.9290888906 0.9113901854 + 0.9245617986 0.9294192791 0.9117870927 + 0.9249073267 0.9297497272 0.9121840000 + 0.9252527952 0.9300799966 0.9125810266 + 0.9255983829 0.9304103851 0.9129778743 + 0.9259439111 0.9307407737 0.9133749008 + 0.9262884259 0.9310684204 0.9137703776 + 0.9266322255 0.9313945174 0.9141650796 + 0.9269760847 0.9317206740 0.9145597816 + 0.9273198843 0.9320467710 0.9149544835 + 0.9276638031 0.9323729277 0.9153491855 + 0.9280076027 0.9326990247 0.9157438874 + 0.9283512235 0.9330248237 0.9161379933 + 0.9286935925 0.9333493114 0.9165306091 + 0.9290360808 0.9336737990 0.9169231057 + 0.9293785095 0.9339984059 0.9173156023 + 0.9297209978 0.9343228936 0.9177080989 + 0.9300634265 0.9346475005 0.9181007147 + 0.9304059148 0.9349719882 0.9184932113 + 0.9307463765 0.9352958202 0.9188840985 + 0.9310864210 0.9356192946 0.9192745090 + 0.9314262867 0.9359428883 0.9196649790 + 0.9317662716 0.9362664223 0.9200553894 + 0.9321063161 0.9365898967 0.9204457998 + 0.9324461818 0.9369134903 0.9208363295 + 0.9327856898 0.9372361898 0.9212262034 + 0.9331235886 0.9375563860 0.9216144085 + 0.9334616065 0.9378765821 0.9220026135 + 0.9337995052 0.9381968975 0.9223908186 + 0.9341375232 0.9385170937 0.9227790236 + 0.9344754219 0.9388374090 0.9231672883 + 0.9348133802 0.9391576052 0.9235554934 + 0.9351503253 0.9394760132 0.9239422083 + 0.9354866743 0.9397935271 0.9243283272 + 0.9358232021 0.9401109815 0.9247143865 + 0.9361596107 0.9404284954 0.9251005054 + 0.9364960790 0.9407460093 0.9254866242 + 0.9368324876 0.9410635233 0.9258726835 + 0.9371687770 0.9413809776 0.9262586236 + 0.9375026822 0.9416983128 0.9266427159 + 0.9378365278 0.9420157075 0.9270266891 + 0.9381703734 0.9423331022 0.9274107218 + 0.9385042191 0.9426503778 0.9277948141 + 0.9388381243 0.9429677725 0.9281787872 + 0.9391719103 0.9432851076 0.9285628200 + 0.9395049214 0.9436019063 0.9289460182 + 0.9398363829 0.9439175129 0.9293279052 + 0.9401680231 0.9442331791 0.9297096729 + 0.9404994845 0.9445489049 0.9300916195 + 0.9408311248 0.9448645115 0.9304735065 + 0.9411625862 0.9451801777 0.9308552742 + 0.9414941072 0.9454957843 0.9312372208 + 0.9418246746 0.9458090067 0.9316176772 + 0.9421545863 0.9461206794 0.9319974184 + 0.9424844980 0.9464324117 0.9323772192 + 0.9428144097 0.9467440844 0.9327569008 + 0.9431443810 0.9470558167 0.9331367016 + 0.9434742928 0.9473674893 0.9335163832 + 0.9438042045 0.9476792812 0.9338961840 + 0.9441329837 0.9479892850 0.9342741966 + 0.9444615841 0.9482989907 0.9346519709 + 0.9447901845 0.9486086965 0.9350296855 + 0.9451187849 0.9489185214 0.9354074001 + 0.9454473853 0.9492282271 0.9357851744 + 0.9457759261 0.9495378733 0.9361628890 + 0.9461045265 0.9498476982 0.9365406036 + 0.9464306831 0.9501572847 0.9369168878 + 0.9467568994 0.9504669905 0.9372932911 + 0.9470831156 0.9507766962 0.9376695752 + 0.9474092722 0.9510864019 0.9380459189 + 0.9477354884 0.9513961077 0.9384223223 + 0.9480617046 0.9517058134 0.9387986064 + 0.9483876824 0.9520152807 0.9391748905 + 0.9487118721 0.9523227215 0.9395511150 + 0.9490361810 0.9526301026 0.9399273992 + 0.9493604898 0.9529374838 0.9403036237 + 0.9496846795 0.9532449245 0.9406797886 + 0.9500089884 0.9535524249 0.9410560131 + 0.9503332973 0.9538598061 0.9414321780 + 0.9506573081 0.9541665912 0.9418082833 + 0.9509801865 0.9544696212 0.9421828985 + 0.9513030052 0.9547725916 0.9425575733 + 0.9516258240 0.9550755024 0.9429323077 + 0.9519485831 0.9553784728 0.9433069229 + 0.9522714019 0.9556815028 0.9436815977 + 0.9525942206 0.9559844136 0.9440562725 + 0.9529168010 0.9562870860 0.9444304109 + 0.9532371163 0.9565876126 0.9448000789 + 0.9535574913 0.9568880200 0.9451699257 + 0.9538778067 0.9571884871 0.9455395937 + 0.9541981220 0.9574888945 0.9459093809 + 0.9545183778 0.9577893019 0.9462791085 + 0.9548388124 0.9580898285 0.9466487765 + 0.9551590085 0.9583901763 0.9470183849 + 0.9554758072 0.9586884975 0.9473823905 + 0.9557926059 0.9589868784 0.9477463961 + 0.9561094046 0.9592853189 0.9481102824 + 0.9564262033 0.9595835805 0.9484742880 + 0.9567428827 0.9598820210 0.9488382936 + 0.9570596814 0.9601804018 0.9492021799 + 0.9573764801 0.9604787827 0.9495661855 + 0.9576882720 0.9607712030 0.9499266744 + 0.9579992890 0.9610629082 0.9502866864 + 0.9583104253 0.9613546133 0.9506466985 + 0.9586215019 0.9616461992 0.9510068297 + 0.9589325786 0.9619379044 0.9513667822 + 0.9592437148 0.9622296095 0.9517267942 + 0.9595547915 0.9625213146 0.9520869255 + 0.9598625898 0.9628093243 0.9524452090 + 0.9601690769 0.9630957246 0.9528027773 + 0.9604755044 0.9633821249 0.9531604052 + 0.9607818723 0.9636685252 0.9535179734 + 0.9610882998 0.9639549255 0.9538757205 + 0.9613947272 0.9642413259 0.9542332888 + 0.9617010951 0.9645277262 0.9545909166 + 0.9620065093 0.9648134112 0.9549475908 + 0.9623104930 0.9650980830 0.9553031921 + 0.9626144767 0.9653828144 0.9556587934 + 0.9629185200 0.9656674862 0.9560143948 + 0.9632223845 0.9659522176 0.9563699961 + 0.9635264277 0.9662368894 0.9567255974 + 0.9638304114 0.9665215015 0.9570811987 + 0.9641342163 0.9668059945 0.9574365020 + 0.9644362926 0.9670882821 0.9577893019 + 0.9647383094 0.9673706293 0.9581422210 + 0.9650403857 0.9676529169 0.9584950805 + 0.9653425217 0.9679353237 0.9588479996 + 0.9656445980 0.9682176113 0.9592007995 + 0.9659466743 0.9684998989 0.9595537186 + 0.9662488103 0.9687821865 0.9599065781 + 0.9665489793 0.9690619707 0.9602572918 + 0.9668484926 0.9693408012 0.9606072903 + 0.9671481252 0.9696195722 0.9609572887 + 0.9674475789 0.9698984027 0.9613072872 + 0.9677472115 0.9701771140 0.9616572261 + 0.9680467248 0.9704558849 0.9620072246 + 0.9683462977 0.9707347155 0.9623572230 + 0.9686446786 0.9710127711 0.9627063870 + 0.9689406157 0.9712892175 0.9630538225 + 0.9692364931 0.9715657234 0.9634011984 + 0.9695323706 0.9718421102 0.9637485743 + 0.9698283076 0.9721184969 0.9640960097 + 0.9701241851 0.9723948836 0.9644433856 + 0.9704201818 0.9726712704 0.9647908211 + 0.9707161188 0.9729477167 0.9651381969 + 0.9710099101 0.9732221961 0.9654831290 + 0.9713031054 0.9734960794 0.9658272862 + 0.9715964198 0.9737700224 0.9661715031 + 0.9718896151 0.9740439057 0.9665157199 + 0.9721829295 0.9743177891 0.9668598771 + 0.9724761248 0.9745916724 0.9672040939 + 0.9727693796 0.9748656750 0.9675483108 + 0.9730619788 0.9751387239 0.9678918123 + 0.9733523726 0.9754089713 0.9682325721 + 0.9736428857 0.9756792784 0.9685735106 + 0.9739332795 0.9759495854 0.9689142704 + 0.9742236733 0.9762198925 0.9692552090 + 0.9745141864 0.9764901996 0.9695960879 + 0.9748045802 0.9767605066 0.9699369073 + 0.9750950933 0.9770308137 0.9702777863 + 0.9753832817 0.9772984982 0.9706165791 + 0.9756699204 0.9775645137 0.9709541798 + 0.9759566188 0.9778305292 0.9712917209 + 0.9762431979 0.9780964851 0.9716293216 + 0.9765298963 0.9783625007 0.9719668031 + 0.9768165946 0.9786285162 0.9723044038 + 0.9771031737 0.9788944721 0.9726418853 + 0.9773898721 0.9791604877 0.9729794860 + 0.9776729941 0.9794232845 0.9733135104 + 0.9779558182 0.9796857238 0.9736471772 + 0.9782385826 0.9799482226 0.9739809036 + 0.9785215259 0.9802107215 0.9743145704 + 0.9788042903 0.9804731011 0.9746482968 + 0.9790871143 0.9807356000 0.9749820232 + 0.9793698788 0.9809979796 0.9753156900 + 0.9796521068 0.9812598825 0.9756488204 + 0.9799309969 0.9815183878 0.9759784937 + 0.9802098870 0.9817768931 0.9763082266 + 0.9804887772 0.9820353985 0.9766378999 + 0.9807677269 0.9822939038 0.9769675732 + 0.9810466766 0.9825525284 0.9772973061 + 0.9813256264 0.9828109741 0.9776269794 + 0.9816045165 0.9830694795 0.9779567122 + 0.9818817973 0.9833264947 0.9782847762 + 0.9821562171 0.9835805297 0.9786099792 + 0.9824305177 0.9838346243 0.9789351821 + 0.9827048182 0.9840885997 0.9792603850 + 0.9829791784 0.9843426943 0.9795857072 + 0.9832534790 0.9845967293 0.9799109101 + 0.9835278988 0.9848508239 0.9802361131 + 0.9838021994 0.9851047993 0.9805613160 + 0.9840744138 0.9853568077 0.9808841944 + 0.9843440056 0.9856063724 0.9812043905 + 0.9846137166 0.9858559966 0.9815247059 + 0.9848834276 0.9861056209 0.9818449020 + 0.9851530790 0.9863551855 0.9821652174 + 0.9854227901 0.9866049290 0.9824854136 + 0.9856923819 0.9868544936 0.9828057289 + 0.9859620929 0.9871041179 0.9831259251 + 0.9862291813 0.9873511195 0.9834434986 + 0.9864938259 0.9875954986 0.9837586880 + 0.9867584109 0.9878399968 0.9840738177 + 0.9870229959 0.9880844951 0.9843888879 + 0.9872875810 0.9883289933 0.9847040176 + 0.9875522256 0.9885734916 0.9850190878 + 0.9878168106 0.9888179898 0.9853342175 + 0.9880813956 0.9890624881 0.9856492877 + 0.9883427024 0.9893040061 0.9859611988 + 0.9886007905 0.9895424843 0.9862697124 + 0.9888588786 0.9897810817 0.9865782261 + 0.9891169071 0.9900196195 0.9868866801 + 0.9893749952 0.9902582169 0.9871953130 + 0.9896330833 0.9904968143 0.9875038266 + 0.9898911119 0.9907352924 0.9878122807 + 0.9901492000 0.9909738898 0.9881207943 + 0.9904044867 0.9912102818 0.9884263873 + 0.9906560183 0.9914438128 0.9887279868 + 0.9909074903 0.9916772246 0.9890295267 + 0.9911590219 0.9919106960 0.9893310070 + 0.9914104939 0.9921442270 0.9896326065 + 0.9916620851 0.9923775792 0.9899340868 + 0.9919136167 0.9926111102 0.9902356267 + 0.9921650887 0.9928445816 0.9905372262 + 0.9924147129 0.9930760264 0.9908366799 + 0.9926593900 0.9933021069 0.9911310077 + 0.9929041266 0.9935281873 0.9914252162 + 0.9931489229 0.9937543273 0.9917194843 + 0.9933936000 0.9939802885 0.9920136929 + 0.9936382771 0.9942064285 0.9923080206 + 0.9938830137 0.9944325089 0.9926022291 + 0.9941276908 0.9946585894 0.9928964972 + 0.9943717718 0.9948840141 0.9931902289 + 0.9946069717 0.9950991869 0.9934738874 + 0.9948421717 0.9953144193 0.9937577248 + 0.9950773716 0.9955294728 0.9940413833 + 0.9953125715 0.9957447052 0.9943252206 + 0.9955477715 0.9959598184 0.9946088791 + 0.9957829714 0.9961749911 0.9948927164 + 0.9960181713 0.9963901043 0.9951763749 + 0.9962533712 0.9966052771 0.9954602122 + 0.9964799881 0.9968116283 0.9957352877 + 0.9967042208 0.9970152974 0.9960079789 + 0.9969282746 0.9972190857 0.9962807298 + 0.9971525073 0.9974228144 0.9965534210 + 0.9973766208 0.9976264834 0.9968259931 + 0.9976006746 0.9978302121 0.9970986843 + 0.9978249073 0.9980338812 0.9973713756 + 0.9980490208 0.9982377291 0.9976441264 + 0.9982699156 0.9984378219 0.9979118109 + 0.9984861016 0.9986330867 0.9981728196 + 0.9987024069 0.9988284111 0.9984338880 + 0.9989187121 0.9990236163 0.9986948967 + 0.9991348982 0.9992188811 0.9989559054 + 0.9993512034 0.9994142056 0.9992169142 + 0.9995675087 0.9996094704 0.9994779825 + 0.9997836947 0.9998046756 0.9997389913 + 1.0000000000 1.0000000000 1.0000000000 +} diff --git a/rpplugins/color_correction/resources/film_luts_raw/canon_optura_981111.slrr.spi1d b/rpplugins/color_correction/resources/film_luts_raw/canon_optura_981111.slrr.spi1d new file mode 100644 index 0000000..2081fd8 --- /dev/null +++ b/rpplugins/color_correction/resources/film_luts_raw/canon_optura_981111.slrr.spi1d @@ -0,0 +1,1030 @@ +Version 1 +From 0.0 1.0 +Length 1024 +Components 1 +{ + 0.0000000000 + 0.0014726890 + 0.0029453780 + 0.0044180658 + 0.0058907550 + 0.0073634442 + 0.0088361334 + 0.0103471801 + 0.0120028201 + 0.0136584500 + 0.0153140901 + 0.0169697199 + 0.0186253507 + 0.0203142408 + 0.0221658293 + 0.0240174104 + 0.0258690007 + 0.0277205799 + 0.0295721702 + 0.0315769389 + 0.0336277485 + 0.0356785506 + 0.0377293602 + 0.0397801585 + 0.0420004018 + 0.0442409813 + 0.0464815497 + 0.0487221293 + 0.0510343090 + 0.0534415208 + 0.0558487400 + 0.0582559519 + 0.0606994517 + 0.0632383898 + 0.0657773167 + 0.0683162585 + 0.0708854869 + 0.0735143498 + 0.0761432126 + 0.0787720680 + 0.0814261734 + 0.0841023996 + 0.0867786184 + 0.0894548520 + 0.0921387821 + 0.0948246717 + 0.0975105688 + 0.1001949981 + 0.1028613001 + 0.1055274978 + 0.1081937999 + 0.1108473018 + 0.1134739965 + 0.1161006987 + 0.1187274009 + 0.1213281006 + 0.1239041984 + 0.1264802963 + 0.1290563941 + 0.1315979064 + 0.1341194063 + 0.1366408020 + 0.1391623020 + 0.1416479945 + 0.1441158056 + 0.1465836018 + 0.1490515023 + 0.1514890045 + 0.1539075971 + 0.1563262939 + 0.1587449014 + 0.1611427963 + 0.1635183990 + 0.1658940017 + 0.1682696044 + 0.1706354022 + 0.1729750037 + 0.1753146052 + 0.1776542068 + 0.1799937934 + 0.1823045015 + 0.1846151054 + 0.1869256943 + 0.1892361939 + 0.1915317029 + 0.1938195974 + 0.1961075068 + 0.1983955055 + 0.2006783038 + 0.2029488981 + 0.2052195966 + 0.2074902058 + 0.2097609043 + 0.2120196968 + 0.2142771035 + 0.2165344954 + 0.2187919021 + 0.2210443020 + 0.2232909948 + 0.2255375981 + 0.2277843058 + 0.2300308049 + 0.2322676033 + 0.2345044017 + 0.2367410958 + 0.2389778942 + 0.2412088960 + 0.2434349060 + 0.2456609011 + 0.2478868961 + 0.2501122952 + 0.2523249984 + 0.2545377910 + 0.2567506135 + 0.2589632869 + 0.2611669004 + 0.2633624077 + 0.2655578852 + 0.2677533925 + 0.2699488997 + 0.2721224129 + 0.2742953897 + 0.2764684856 + 0.2786414921 + 0.2808037996 + 0.2829482853 + 0.2850928009 + 0.2872372866 + 0.2893818021 + 0.2915014923 + 0.2936109900 + 0.2957204878 + 0.2978301048 + 0.2999396026 + 0.3020089865 + 0.3040772080 + 0.3061453998 + 0.3082135916 + 0.3102754056 + 0.3122963905 + 0.3143174946 + 0.3163385093 + 0.3183594942 + 0.3203707039 + 0.3223395944 + 0.3243085146 + 0.3262774050 + 0.3282462955 + 0.3302091062 + 0.3321220875 + 0.3340350986 + 0.3359481096 + 0.3378610909 + 0.3397741020 + 0.3416356146 + 0.3434903026 + 0.3453449905 + 0.3471997082 + 0.3490543962 + 0.3508799970 + 0.3526752889 + 0.3544706106 + 0.3562659025 + 0.3580613136 + 0.3598566055 + 0.3615975976 + 0.3633337915 + 0.3650701046 + 0.3668062985 + 0.3685424924 + 0.3702695072 + 0.3719482124 + 0.3736267984 + 0.3753054142 + 0.3769840896 + 0.3786627054 + 0.3803300858 + 0.3819536865 + 0.3835771978 + 0.3852007091 + 0.3868241906 + 0.3884477019 + 0.3900690079 + 0.3916406929 + 0.3932124078 + 0.3947840929 + 0.3963558972 + 0.3979276121 + 0.3994992971 + 0.4010384083 + 0.4025622904 + 0.4040861130 + 0.4056099951 + 0.4071337879 + 0.4086576998 + 0.4101763964 + 0.4116567969 + 0.4131371975 + 0.4146175981 + 0.4160979986 + 0.4175783992 + 0.4190588892 + 0.4205251932 + 0.4219667912 + 0.4234085083 + 0.4248501956 + 0.4262919128 + 0.4277335107 + 0.4291751981 + 0.4306024015 + 0.4320102930 + 0.4334180951 + 0.4348258972 + 0.4362337887 + 0.4376415908 + 0.4390495121 + 0.4404478967 + 0.4418269098 + 0.4432058930 + 0.4445849061 + 0.4459638894 + 0.4473429024 + 0.4487217963 + 0.4500991106 + 0.4514541924 + 0.4528093040 + 0.4541643858 + 0.4555194974 + 0.4568746090 + 0.4582296908 + 0.4595848024 + 0.4609268010 + 0.4622628987 + 0.4635990858 + 0.4649352133 + 0.4662713110 + 0.4676074982 + 0.4689435959 + 0.4702768028 + 0.4715988040 + 0.4729208052 + 0.4742426872 + 0.4755646884 + 0.4768866897 + 0.4782086909 + 0.4795306027 + 0.4808464944 + 0.4821588993 + 0.4834713042 + 0.4847837985 + 0.4860962033 + 0.4874086976 + 0.4887211025 + 0.4900333881 + 0.4913406968 + 0.4926480055 + 0.4939553142 + 0.4952625930 + 0.4965699017 + 0.4978772104 + 0.4991844893 + 0.5004913807 + 0.5017976761 + 0.5031039119 + 0.5044102073 + 0.5057165027 + 0.5070226789 + 0.5083289742 + 0.5096353292 + 0.5109434724 + 0.5122525096 + 0.5135614872 + 0.5148705244 + 0.5161795020 + 0.5174884796 + 0.5187975168 + 0.5201069117 + 0.5214219093 + 0.5227369070 + 0.5240519047 + 0.5253669024 + 0.5266819000 + 0.5279968977 + 0.5293118954 + 0.5306311250 + 0.5319548249 + 0.5332785249 + 0.5346022248 + 0.5359259844 + 0.5372496843 + 0.5385733843 + 0.5398970842 + 0.5412306786 + 0.5425651073 + 0.5438994765 + 0.5452339053 + 0.5465683937 + 0.5479028225 + 0.5492371917 + 0.5505766869 + 0.5519229174 + 0.5532690883 + 0.5546153188 + 0.5559614897 + 0.5573077202 + 0.5586538911 + 0.5600001812 + 0.5613582134 + 0.5627163053 + 0.5640742779 + 0.5654324293 + 0.5667904019 + 0.5681484938 + 0.5695065260 + 0.5708712935 + 0.5722399950 + 0.5736086965 + 0.5749773979 + 0.5763460994 + 0.5777148008 + 0.5790835023 + 0.5804548860 + 0.5818316936 + 0.5832085013 + 0.5845853090 + 0.5859621763 + 0.5873389840 + 0.5887157917 + 0.5900928974 + 0.5914738178 + 0.5928547978 + 0.5942357779 + 0.5956166983 + 0.5969976783 + 0.5983787179 + 0.5997595787 + 0.6011396050 + 0.6025193930 + 0.6038991809 + 0.6052790284 + 0.6066588163 + 0.6080386043 + 0.6094183922 + 0.6107937098 + 0.6121658087 + 0.6135379076 + 0.6149100065 + 0.6162821054 + 0.6176542044 + 0.6190263033 + 0.6203941107 + 0.6217511296 + 0.6231080890 + 0.6244651079 + 0.6258221269 + 0.6271792054 + 0.6285362244 + 0.6298931837 + 0.6312292218 + 0.6325632930 + 0.6338974833 + 0.6352316141 + 0.6365658045 + 0.6378998756 + 0.6392341256 + 0.6405552030 + 0.6418588161 + 0.6431624293 + 0.6444659829 + 0.6457697153 + 0.6470733285 + 0.6483768821 + 0.6496804953 + 0.6509557962 + 0.6522219181 + 0.6534879804 + 0.6547541022 + 0.6560202241 + 0.6572862864 + 0.6585524082 + 0.6598184109 + 0.6610473990 + 0.6622701883 + 0.6634929776 + 0.6647157073 + 0.6659384966 + 0.6671612859 + 0.6683840156 + 0.6696068048 + 0.6707972884 + 0.6719723940 + 0.6731474996 + 0.6743227243 + 0.6754977703 + 0.6766729951 + 0.6778481007 + 0.6790233254 + 0.6801899076 + 0.6813148260 + 0.6824398041 + 0.6835647225 + 0.6846895814 + 0.6858144999 + 0.6869394779 + 0.6880643964 + 0.6891893148 + 0.6902999878 + 0.6913738251 + 0.6924476027 + 0.6935213804 + 0.6945952773 + 0.6956691146 + 0.6967428923 + 0.6978167295 + 0.6988906264 + 0.6999644041 + 0.7009894848 + 0.7020128965 + 0.7030364275 + 0.7040597796 + 0.7050833106 + 0.7061067224 + 0.7071300745 + 0.7081536055 + 0.7091770172 + 0.7101910114 + 0.7111660838 + 0.7121412754 + 0.7131164074 + 0.7140914798 + 0.7150666714 + 0.7160418034 + 0.7170169950 + 0.7179921269 + 0.7189671993 + 0.7199423909 + 0.7208750844 + 0.7218052149 + 0.7227352262 + 0.7236652970 + 0.7245953083 + 0.7255253792 + 0.7264555097 + 0.7273855209 + 0.7283155918 + 0.7292456031 + 0.7301679254 + 0.7310569882 + 0.7319461107 + 0.7328351140 + 0.7337241769 + 0.7346132994 + 0.7355023026 + 0.7363914251 + 0.7372804880 + 0.7381694913 + 0.7390586138 + 0.7399476767 + 0.7408025861 + 0.7416555285 + 0.7425082922 + 0.7433611155 + 0.7442138791 + 0.7450668216 + 0.7459195852 + 0.7467724085 + 0.7476251721 + 0.7484781146 + 0.7493308783 + 0.7501770258 + 0.7509987950 + 0.7518206835 + 0.7526425123 + 0.7534642816 + 0.7542861104 + 0.7551078796 + 0.7559298277 + 0.7567515969 + 0.7575734258 + 0.7583951950 + 0.7592170238 + 0.7600377202 + 0.7608340979 + 0.7616304755 + 0.7624269128 + 0.7632232904 + 0.7640197873 + 0.7648162246 + 0.7656126022 + 0.7664089799 + 0.7672054768 + 0.7680019140 + 0.7687982917 + 0.7695947289 + 0.7703816295 + 0.7711585760 + 0.7719355226 + 0.7727125287 + 0.7734894156 + 0.7742664218 + 0.7750433087 + 0.7758203149 + 0.7765973210 + 0.7773742080 + 0.7781512141 + 0.7789281011 + 0.7797051072 + 0.7804738283 + 0.7812374830 + 0.7820013165 + 0.7827649713 + 0.7835286856 + 0.7842923999 + 0.7850561142 + 0.7858198881 + 0.7865836024 + 0.7873473167 + 0.7881109715 + 0.7888746858 + 0.7896384001 + 0.7903987169 + 0.7911556959 + 0.7919127941 + 0.7926697731 + 0.7934268713 + 0.7941839099 + 0.7949410081 + 0.7956979871 + 0.7964550853 + 0.7972121239 + 0.7979692221 + 0.7987263203 + 0.7994832993 + 0.8002405167 + 0.8009977937 + 0.8017551899 + 0.8025125861 + 0.8032699227 + 0.8040273190 + 0.8047845960 + 0.8055419922 + 0.8062993884 + 0.8070567250 + 0.8078141212 + 0.8085715175 + 0.8093287945 + 0.8100870848 + 0.8108522296 + 0.8116173148 + 0.8123824000 + 0.8131474853 + 0.8139125705 + 0.8146777749 + 0.8154429197 + 0.8162080050 + 0.8169730902 + 0.8177381754 + 0.8185033202 + 0.8192685246 + 0.8200343251 + 0.8208150864 + 0.8215959072 + 0.8223767281 + 0.8231574893 + 0.8239383101 + 0.8247190714 + 0.8255000114 + 0.8262807727 + 0.8270615935 + 0.8278424144 + 0.8286231756 + 0.8294039965 + 0.8301904798 + 0.8309953809 + 0.8318002820 + 0.8326051831 + 0.8334100246 + 0.8342149258 + 0.8350198269 + 0.8358247280 + 0.8366295099 + 0.8374344110 + 0.8382393122 + 0.8390442133 + 0.8398489952 + 0.8406803012 + 0.8415176272 + 0.8423550129 + 0.8431922793 + 0.8440296054 + 0.8448669910 + 0.8457043171 + 0.8465415835 + 0.8473790288 + 0.8482162952 + 0.8490536213 + 0.8498910069 + 0.8507630229 + 0.8516402841 + 0.8525176048 + 0.8533949256 + 0.8542721868 + 0.8551493883 + 0.8560267091 + 0.8569039702 + 0.8577812910 + 0.8586584926 + 0.8595358133 + 0.8604339957 + 0.8613557816 + 0.8622775078 + 0.8631992936 + 0.8641210198 + 0.8650426865 + 0.8659644723 + 0.8668861985 + 0.8678079844 + 0.8687297106 + 0.8696514964 + 0.8705996275 + 0.8715636730 + 0.8725277781 + 0.8734918833 + 0.8744559884 + 0.8754202127 + 0.8763843179 + 0.8773484230 + 0.8783125281 + 0.8792766929 + 0.8802478909 + 0.8812404275 + 0.8822329044 + 0.8832253814 + 0.8842179179 + 0.8852105141 + 0.8862029910 + 0.8871955276 + 0.8881880045 + 0.8891804814 + 0.8901726007 + 0.8911628127 + 0.8921530247 + 0.8931431174 + 0.8941333294 + 0.8951234818 + 0.8961136937 + 0.8971037865 + 0.8980939984 + 0.8990842104 + 0.9000707269 + 0.9010120034 + 0.9019532800 + 0.9028946161 + 0.9038360119 + 0.9047772884 + 0.9057186246 + 0.9066599011 + 0.9076012969 + 0.9085425735 + 0.9094839096 + 0.9103804827 + 0.9112226963 + 0.9120650291 + 0.9129071832 + 0.9137495160 + 0.9145917892 + 0.9154340029 + 0.9162762761 + 0.9171184897 + 0.9179608226 + 0.9188029766 + 0.9196453094 + 0.9204097986 + 0.9211177230 + 0.9218255877 + 0.9225335121 + 0.9232413769 + 0.9239493012 + 0.9246572256 + 0.9253650904 + 0.9260730147 + 0.9267808795 + 0.9274888039 + 0.9281967282 + 0.9289045930 + 0.9296125174 + 0.9302552938 + 0.9308195710 + 0.9313837886 + 0.9319481254 + 0.9325122833 + 0.9330765009 + 0.9336407781 + 0.9342049956 + 0.9347692132 + 0.9353334904 + 0.9358977079 + 0.9364619255 + 0.9370262027 + 0.9375904202 + 0.9381545782 + 0.9387189150 + 0.9392830729 + 0.9398472905 + 0.9403160810 + 0.9407495856 + 0.9411829710 + 0.9416164160 + 0.9420498013 + 0.9424831867 + 0.9429165721 + 0.9433500171 + 0.9437834024 + 0.9442167878 + 0.9446501732 + 0.9450836182 + 0.9455170035 + 0.9459503889 + 0.9463838935 + 0.9468172789 + 0.9472507238 + 0.9476841092 + 0.9481174946 + 0.9485508800 + 0.9489843249 + 0.9494177103 + 0.9498510957 + 0.9502140880 + 0.9505401850 + 0.9508662820 + 0.9511923790 + 0.9515184760 + 0.9518445730 + 0.9521707296 + 0.9524968266 + 0.9528229237 + 0.9531490207 + 0.9534751177 + 0.9538012147 + 0.9541273117 + 0.9544534087 + 0.9547795057 + 0.9551056027 + 0.9554316998 + 0.9557577968 + 0.9560838938 + 0.9564099908 + 0.9567360878 + 0.9570621848 + 0.9573882818 + 0.9577143788 + 0.9580404758 + 0.9583665729 + 0.9586927295 + 0.9590188265 + 0.9593449235 + 0.9596710205 + 0.9599971175 + 0.9602413177 + 0.9604846835 + 0.9607281089 + 0.9609714746 + 0.9612150192 + 0.9614583850 + 0.9617018104 + 0.9619451761 + 0.9621887207 + 0.9624320865 + 0.9626755118 + 0.9629188776 + 0.9631623030 + 0.9634057879 + 0.9636492133 + 0.9638925791 + 0.9641360044 + 0.9643794894 + 0.9646229148 + 0.9648662806 + 0.9651097059 + 0.9653531909 + 0.9655966163 + 0.9658399820 + 0.9660834074 + 0.9663268924 + 0.9665703177 + 0.9668136835 + 0.9670571089 + 0.9673005939 + 0.9675440192 + 0.9677873850 + 0.9680308104 + 0.9682741761 + 0.9685177207 + 0.9687610865 + 0.9690045118 + 0.9692478776 + 0.9694914222 + 0.9697347879 + 0.9699782133 + 0.9701654911 + 0.9703474045 + 0.9705291986 + 0.9707109928 + 0.9708927870 + 0.9710745811 + 0.9712563753 + 0.9714382291 + 0.9716200233 + 0.9718018770 + 0.9719836712 + 0.9721655250 + 0.9723473191 + 0.9725291133 + 0.9727109075 + 0.9728927016 + 0.9730746150 + 0.9732564092 + 0.9734382033 + 0.9736199975 + 0.9738017917 + 0.9739835858 + 0.9741653800 + 0.9743471742 + 0.9745290875 + 0.9747108817 + 0.9748926759 + 0.9750745296 + 0.9752563238 + 0.9754381180 + 0.9756199121 + 0.9758018255 + 0.9759836197 + 0.9761654139 + 0.9763472080 + 0.9765290022 + 0.9767107964 + 0.9768925905 + 0.9770743847 + 0.9772562981 + 0.9774380922 + 0.9776198864 + 0.9778016806 + 0.9779834747 + 0.9781653285 + 0.9783471227 + 0.9785289168 + 0.9787107706 + 0.9788926244 + 0.9790744185 + 0.9792562127 + 0.9794380069 + 0.9796198010 + 0.9798015952 + 0.9799835086 + 0.9801241159 + 0.9802607298 + 0.9803972840 + 0.9805337787 + 0.9806703925 + 0.9808070064 + 0.9809435010 + 0.9810801148 + 0.9812166095 + 0.9813532233 + 0.9814897776 + 0.9816262722 + 0.9817628860 + 0.9818994999 + 0.9820359945 + 0.9821726084 + 0.9823091030 + 0.9824457169 + 0.9825822711 + 0.9827188253 + 0.9828553796 + 0.9829919934 + 0.9831284881 + 0.9832651019 + 0.9834015965 + 0.9835382104 + 0.9836748242 + 0.9838113189 + 0.9839478731 + 0.9840844870 + 0.9842209816 + 0.9843575954 + 0.9844942093 + 0.9846307039 + 0.9847673178 + 0.9849038124 + 0.9850404263 + 0.9851769805 + 0.9853134751 + 0.9854500890 + 0.9855867028 + 0.9857231975 + 0.9858598113 + 0.9859963059 + 0.9861329198 + 0.9862694740 + 0.9864060283 + 0.9865425825 + 0.9866791964 + 0.9868156910 + 0.9869523048 + 0.9870887995 + 0.9872254133 + 0.9873620272 + 0.9874985218 + 0.9876350760 + 0.9877716899 + 0.9879081845 + 0.9880447984 + 0.9881814122 + 0.9883179069 + 0.9884545207 + 0.9885910153 + 0.9887276292 + 0.9888641834 + 0.9890006781 + 0.9891372919 + 0.9892739058 + 0.9894104004 + 0.9895470142 + 0.9896835089 + 0.9898201227 + 0.9899566770 + 0.9900705814 + 0.9901739955 + 0.9902775288 + 0.9903808832 + 0.9904842973 + 0.9905877709 + 0.9906911850 + 0.9907945991 + 0.9908980727 + 0.9910014868 + 0.9911049008 + 0.9912083745 + 0.9913117886 + 0.9914152026 + 0.9915186167 + 0.9916220903 + 0.9917255044 + 0.9918289185 + 0.9919323921 + 0.9920358062 + 0.9921392202 + 0.9922426939 + 0.9923461080 + 0.9924495220 + 0.9925529957 + 0.9926564097 + 0.9927598238 + 0.9928632975 + 0.9929667115 + 0.9930701256 + 0.9931734800 + 0.9932770133 + 0.9933804274 + 0.9934837818 + 0.9935873151 + 0.9936907291 + 0.9937940836 + 0.9938976169 + 0.9940009713 + 0.9941043854 + 0.9942079186 + 0.9943112731 + 0.9944146872 + 0.9945182204 + 0.9946215749 + 0.9947249889 + 0.9948284030 + 0.9949318767 + 0.9950352907 + 0.9951387048 + 0.9952421784 + 0.9953455925 + 0.9954490066 + 0.9955524802 + 0.9956558943 + 0.9957593083 + 0.9958627820 + 0.9959661961 + 0.9960696101 + 0.9961730242 + 0.9962764978 + 0.9963799119 + 0.9964833260 + 0.9965867996 + 0.9966902137 + 0.9967936277 + 0.9968971014 + 0.9970005155 + 0.9971039295 + 0.9972074032 + 0.9973108172 + 0.9974141717 + 0.9975177050 + 0.9976211190 + 0.9977244735 + 0.9978278875 + 0.9979314208 + 0.9980347753 + 0.9981381893 + 0.9982417226 + 0.9983450770 + 0.9984484911 + 0.9985520244 + 0.9986553788 + 0.9987587929 + 0.9988623261 + 0.9989656806 + 0.9990690947 + 0.9991726279 + 0.9992759824 + 0.9993793964 + 0.9994828105 + 0.9995862842 + 0.9996896982 + 0.9997931123 + 0.9998965859 + 1.0000000000 +} diff --git a/rpplugins/color_correction/resources/film_luts_raw/canon_optura_981111.spi1d b/rpplugins/color_correction/resources/film_luts_raw/canon_optura_981111.spi1d new file mode 100644 index 0000000..23ca3fa --- /dev/null +++ b/rpplugins/color_correction/resources/film_luts_raw/canon_optura_981111.spi1d @@ -0,0 +1,1030 @@ +Version 1 +From 0.0 1.0 +Length 1024 +Components 1 +{ + 0.0000000000 + 0.0025450480 + 0.0050900960 + 0.0076351431 + 0.0101884697 + 0.0128504699 + 0.0155124702 + 0.0181744602 + 0.0208844505 + 0.0236991905 + 0.0265139192 + 0.0293286499 + 0.0322732218 + 0.0352584682 + 0.0382437110 + 0.0412991717 + 0.0444549806 + 0.0476107895 + 0.0508038513 + 0.0541130006 + 0.0574221388 + 0.0607581101 + 0.0641886517 + 0.0676191822 + 0.0710741282 + 0.0745844394 + 0.0780947506 + 0.0816211328 + 0.0851665810 + 0.0887120292 + 0.0922535583 + 0.0957928598 + 0.0993321612 + 0.1028394997 + 0.1063392982 + 0.1098392010 + 0.1132792011 + 0.1167163998 + 0.1201502010 + 0.1235113963 + 0.1268725991 + 0.1302281022 + 0.1335085034 + 0.1367888004 + 0.1400675029 + 0.1432684064 + 0.1464692056 + 0.1496700943 + 0.1528047025 + 0.1559316963 + 0.1590587050 + 0.1621396989 + 0.1652007997 + 0.1682619005 + 0.1712982953 + 0.1743023992 + 0.1773066074 + 0.1803057045 + 0.1832617074 + 0.1862176061 + 0.1891735941 + 0.1921004951 + 0.1950162053 + 0.1979319006 + 0.2008378059 + 0.2037197053 + 0.2066015005 + 0.2094834000 + 0.2123412043 + 0.2151937932 + 0.2180463970 + 0.2208905071 + 0.2237161994 + 0.2265419066 + 0.2293675989 + 0.2321725041 + 0.2349714041 + 0.2377703935 + 0.2405633926 + 0.2433333993 + 0.2461033016 + 0.2488732934 + 0.2516236007 + 0.2543602884 + 0.2570970953 + 0.2598339021 + 0.2625338137 + 0.2652313113 + 0.2679288983 + 0.2706156075 + 0.2732666135 + 0.2759177089 + 0.2785687149 + 0.2811945975 + 0.2837912142 + 0.2863877118 + 0.2889842987 + 0.2915427089 + 0.2940768003 + 0.2966108024 + 0.2991448939 + 0.3016327024 + 0.3040969968 + 0.3065612912 + 0.3090254962 + 0.3114438951 + 0.3138321042 + 0.3162203133 + 0.3186084926 + 0.3209632039 + 0.3232708871 + 0.3255786002 + 0.3278863132 + 0.3301869929 + 0.3324112892 + 0.3346355855 + 0.3368599117 + 0.3390842080 + 0.3412589133 + 0.3433989882 + 0.3455390036 + 0.3476791084 + 0.3498190939 + 0.3518827856 + 0.3539395034 + 0.3559961915 + 0.3580527902 + 0.3601051867 + 0.3620809913 + 0.3640567958 + 0.3660326004 + 0.3680082858 + 0.3699840903 + 0.3718833923 + 0.3737820983 + 0.3756807148 + 0.3775793910 + 0.3794780076 + 0.3813242912 + 0.3831506073 + 0.3849770129 + 0.3868033886 + 0.3886297941 + 0.3904395103 + 0.3921990991 + 0.3939588070 + 0.3957183957 + 0.3974781036 + 0.3992376924 + 0.4009630084 + 0.4026620984 + 0.4043611884 + 0.4060603082 + 0.4077593982 + 0.4094584882 + 0.4111205935 + 0.4127655029 + 0.4144104123 + 0.4160552919 + 0.4177002013 + 0.4193451107 + 0.4209614098 + 0.4225586951 + 0.4241560102 + 0.4257532954 + 0.4273506105 + 0.4289478958 + 0.4305312037 + 0.4320875108 + 0.4336437881 + 0.4352000058 + 0.4367563128 + 0.4383125007 + 0.4398688078 + 0.4413934946 + 0.4429152012 + 0.4444369972 + 0.4459587932 + 0.4474805892 + 0.4490022957 + 0.4505144060 + 0.4520080984 + 0.4535017014 + 0.4549953938 + 0.4564889967 + 0.4579826891 + 0.4594762921 + 0.4609557092 + 0.4624272883 + 0.4638989866 + 0.4653705955 + 0.4668422043 + 0.4683139026 + 0.4697855115 + 0.4712435007 + 0.4726991057 + 0.4741545916 + 0.4756101966 + 0.4770658016 + 0.4785214067 + 0.4799770117 + 0.4814223051 + 0.4828675091 + 0.4843125939 + 0.4857577980 + 0.4872029126 + 0.4886480868 + 0.4900929034 + 0.4915328026 + 0.4929727912 + 0.4944128096 + 0.4958527088 + 0.4972926974 + 0.4987326860 + 0.5001726151 + 0.5016121864 + 0.5030518770 + 0.5044915080 + 0.5059311986 + 0.5073708296 + 0.5088104010 + 0.5102508068 + 0.5116943717 + 0.5131379962 + 0.5145816207 + 0.5160253048 + 0.5174689293 + 0.5189124942 + 0.5203580260 + 0.5218092799 + 0.5232605934 + 0.5247119069 + 0.5261632800 + 0.5276145935 + 0.5290659070 + 0.5305209160 + 0.5319827199 + 0.5334445238 + 0.5349063277 + 0.5363680720 + 0.5378299952 + 0.5392917991 + 0.5407599807 + 0.5422341824 + 0.5437083840 + 0.5451825857 + 0.5466567874 + 0.5481309891 + 0.5496053100 + 0.5510889888 + 0.5525763035 + 0.5540636182 + 0.5555508137 + 0.5570381284 + 0.5585253239 + 0.5600126982 + 0.5615121722 + 0.5630118251 + 0.5645112991 + 0.5660107732 + 0.5675103068 + 0.5690099001 + 0.5705127120 + 0.5720220804 + 0.5735315084 + 0.5750408769 + 0.5765503049 + 0.5780596733 + 0.5795689821 + 0.5810825229 + 0.5825976133 + 0.5841127038 + 0.5856277943 + 0.5871428251 + 0.5886579156 + 0.5901730061 + 0.5916877985 + 0.5932027102 + 0.5947175026 + 0.5962324142 + 0.5977472067 + 0.5992619991 + 0.6007729173 + 0.6022800207 + 0.6037871242 + 0.6052942872 + 0.6068013906 + 0.6083084941 + 0.6098155975 + 0.6113082170 + 0.6127988100 + 0.6142895222 + 0.6157801151 + 0.6172707081 + 0.6187613010 + 0.6202476025 + 0.6217123270 + 0.6231769919 + 0.6246417165 + 0.6261065006 + 0.6275712252 + 0.6290358901 + 0.6304885149 + 0.6319180131 + 0.6333473921 + 0.6347767711 + 0.6362062097 + 0.6376355886 + 0.6390650272 + 0.6404792070 + 0.6418644786 + 0.6432499290 + 0.6446353197 + 0.6460205913 + 0.6474059820 + 0.6487913728 + 0.6501702070 + 0.6515042186 + 0.6528382897 + 0.6541723013 + 0.6555063725 + 0.6568403840 + 0.6581745148 + 0.6595085263 + 0.6608067155 + 0.6620839238 + 0.6633611917 + 0.6646384001 + 0.6659157276 + 0.6671929955 + 0.6684702039 + 0.6697474718 + 0.6709765196 + 0.6721935868 + 0.6734107137 + 0.6746279001 + 0.6758450270 + 0.6770620942 + 0.6782792807 + 0.6794964075 + 0.6806775928 + 0.6818333864 + 0.6829891801 + 0.6841449738 + 0.6853008270 + 0.6864566207 + 0.6876124144 + 0.6887682080 + 0.6899240017 + 0.6910231709 + 0.6921185255 + 0.6932137012 + 0.6943089962 + 0.6954041719 + 0.6964995265 + 0.6975947022 + 0.6986898780 + 0.6997851729 + 0.7008336782 + 0.7018709183 + 0.7029079795 + 0.7039451003 + 0.7049822807 + 0.7060194016 + 0.7070565820 + 0.7080937028 + 0.7091308236 + 0.7101591825 + 0.7111420035 + 0.7121248245 + 0.7131077051 + 0.7140905261 + 0.7150732875 + 0.7160561085 + 0.7170389891 + 0.7180218101 + 0.7190045714 + 0.7199873924 + 0.7209213972 + 0.7218546867 + 0.7227879763 + 0.7237213254 + 0.7246546149 + 0.7255879045 + 0.7265211940 + 0.7274544835 + 0.7283877730 + 0.7293211222 + 0.7302423716 + 0.7311316729 + 0.7320209742 + 0.7329102755 + 0.7337995768 + 0.7346888781 + 0.7355781198 + 0.7364674211 + 0.7373567224 + 0.7382460237 + 0.7391353250 + 0.7400234938 + 0.7408747077 + 0.7417259812 + 0.7425771952 + 0.7434284091 + 0.7442796826 + 0.7451308966 + 0.7459822297 + 0.7468333840 + 0.7476845980 + 0.7485358715 + 0.7493870854 + 0.7502294183 + 0.7510489225 + 0.7518684268 + 0.7526878715 + 0.7535073757 + 0.7543268800 + 0.7551463842 + 0.7559658885 + 0.7567853928 + 0.7576048970 + 0.7584244013 + 0.7592439055 + 0.7600615025 + 0.7608557940 + 0.7616500854 + 0.7624443769 + 0.7632387877 + 0.7640330791 + 0.7648273706 + 0.7656217217 + 0.7664160132 + 0.7672104239 + 0.7680047154 + 0.7687990069 + 0.7695932984 + 0.7703787088 + 0.7711545825 + 0.7719305158 + 0.7727065086 + 0.7734823823 + 0.7742583156 + 0.7750343084 + 0.7758101821 + 0.7765861154 + 0.7773621082 + 0.7781379819 + 0.7789139152 + 0.7796899080 + 0.7804589868 + 0.7812235951 + 0.7819883227 + 0.7827528715 + 0.7835174799 + 0.7842820883 + 0.7850466967 + 0.7858114243 + 0.7865759730 + 0.7873405814 + 0.7881051898 + 0.7888697982 + 0.7896345258 + 0.7903971076 + 0.7911577821 + 0.7919185162 + 0.7926793098 + 0.7934399843 + 0.7942007184 + 0.7949615121 + 0.7957221866 + 0.7964829803 + 0.7972437143 + 0.7980043888 + 0.7987651825 + 0.7995259166 + 0.8002882004 + 0.8010529876 + 0.8018177152 + 0.8025825024 + 0.8033472896 + 0.8041120768 + 0.8048768044 + 0.8056415915 + 0.8064063787 + 0.8071712255 + 0.8079360127 + 0.8087006807 + 0.8094655275 + 0.8102341294 + 0.8110113740 + 0.8117886782 + 0.8125661016 + 0.8133434057 + 0.8141207099 + 0.8148980737 + 0.8156753778 + 0.8164526820 + 0.8172299862 + 0.8180074096 + 0.8187847137 + 0.8195620179 + 0.8203489184 + 0.8211479187 + 0.8219469786 + 0.8227460980 + 0.8235452175 + 0.8243442774 + 0.8251432776 + 0.8259423971 + 0.8267415166 + 0.8275405765 + 0.8283395767 + 0.8291386962 + 0.8299378157 + 0.8307659030 + 0.8315964937 + 0.8324270844 + 0.8332576752 + 0.8340882063 + 0.8349187970 + 0.8357493877 + 0.8365799785 + 0.8374106288 + 0.8382411003 + 0.8390716910 + 0.8399022818 + 0.8407692909 + 0.8416411877 + 0.8425130248 + 0.8433849216 + 0.8442568183 + 0.8451285958 + 0.8460004926 + 0.8468723893 + 0.8477442265 + 0.8486161232 + 0.8494880199 + 0.8503803015 + 0.8513019085 + 0.8522233963 + 0.8531450033 + 0.8540664911 + 0.8549880981 + 0.8559095860 + 0.8568311930 + 0.8577526808 + 0.8586742282 + 0.8595957756 + 0.8605474234 + 0.8615226150 + 0.8624976873 + 0.8634728789 + 0.8644480705 + 0.8654232025 + 0.8663983941 + 0.8673735261 + 0.8683487177 + 0.8693237901 + 0.8703135848 + 0.8713365197 + 0.8723592758 + 0.8733820915 + 0.8744049072 + 0.8754277825 + 0.8764505982 + 0.8774734139 + 0.8784962893 + 0.8795191050 + 0.8805549145 + 0.8816024065 + 0.8826497793 + 0.8836972117 + 0.8847445846 + 0.8857920170 + 0.8868393898 + 0.8878868222 + 0.8889341950 + 0.8899816275 + 0.8910092115 + 0.8920364976 + 0.8930637240 + 0.8940910101 + 0.8951181769 + 0.8961455226 + 0.8971728086 + 0.8981999755 + 0.8992273211 + 0.9002348185 + 0.9011824131 + 0.9021301270 + 0.9030777216 + 0.9040253758 + 0.9049729705 + 0.9059206247 + 0.9068682790 + 0.9078158736 + 0.9087635279 + 0.9097111821 + 0.9105666876 + 0.9113819003 + 0.9121969938 + 0.9130122066 + 0.9138273001 + 0.9146425128 + 0.9154576063 + 0.9162728190 + 0.9170879126 + 0.9179031253 + 0.9187182188 + 0.9195333719 + 0.9202811718 + 0.9209386706 + 0.9215962887 + 0.9222537875 + 0.9229114056 + 0.9235690236 + 0.9242265224 + 0.9248840809 + 0.9255415797 + 0.9261991978 + 0.9268566966 + 0.9275143147 + 0.9281718135 + 0.9288293719 + 0.9294869900 + 0.9301112294 + 0.9306169152 + 0.9311227202 + 0.9316285253 + 0.9321342111 + 0.9326400161 + 0.9331458211 + 0.9336515069 + 0.9341573119 + 0.9346631169 + 0.9351688027 + 0.9356746078 + 0.9361804128 + 0.9366860986 + 0.9371919036 + 0.9376977086 + 0.9382033944 + 0.9387091994 + 0.9392150044 + 0.9397206903 + 0.9401693940 + 0.9405475855 + 0.9409257770 + 0.9413040876 + 0.9416822791 + 0.9420604706 + 0.9424387813 + 0.9428169727 + 0.9431952238 + 0.9435734153 + 0.9439517260 + 0.9443299174 + 0.9447081089 + 0.9450864196 + 0.9454646111 + 0.9458428025 + 0.9462211132 + 0.9465993047 + 0.9469774961 + 0.9473558068 + 0.9477339983 + 0.9481121898 + 0.9484903812 + 0.9488686919 + 0.9492468834 + 0.9496250749 + 0.9500024915 + 0.9502819777 + 0.9505615234 + 0.9508408904 + 0.9511203766 + 0.9513999224 + 0.9516794086 + 0.9519588947 + 0.9522383809 + 0.9525179267 + 0.9527974129 + 0.9530767798 + 0.9533563256 + 0.9536358118 + 0.9539152980 + 0.9541947842 + 0.9544742703 + 0.9547538161 + 0.9550331831 + 0.9553127289 + 0.9555922151 + 0.9558717012 + 0.9561511874 + 0.9564306736 + 0.9567102194 + 0.9569895864 + 0.9572690725 + 0.9575486183 + 0.9578281045 + 0.9581075907 + 0.9583870769 + 0.9586666226 + 0.9589459896 + 0.9592254758 + 0.9595050216 + 0.9597845078 + 0.9600471854 + 0.9602534771 + 0.9604598880 + 0.9606661797 + 0.9608724713 + 0.9610788226 + 0.9612851143 + 0.9614914060 + 0.9616976976 + 0.9619039893 + 0.9621102810 + 0.9623166919 + 0.9625229836 + 0.9627292752 + 0.9629356265 + 0.9631419182 + 0.9633482099 + 0.9635545015 + 0.9637607932 + 0.9639670849 + 0.9641734958 + 0.9643797874 + 0.9645860791 + 0.9647923708 + 0.9649987221 + 0.9652050138 + 0.9654113054 + 0.9656175971 + 0.9658238888 + 0.9660302997 + 0.9662365913 + 0.9664428830 + 0.9666491747 + 0.9668555260 + 0.9670618176 + 0.9672681093 + 0.9674744010 + 0.9676806927 + 0.9678869843 + 0.9680933952 + 0.9682996869 + 0.9685059786 + 0.9687122703 + 0.9689186215 + 0.9691249132 + 0.9693312049 + 0.9695374966 + 0.9697437882 + 0.9699501991 + 0.9701160789 + 0.9702693224 + 0.9704223871 + 0.9705755115 + 0.9707286954 + 0.9708818197 + 0.9710348845 + 0.9711880088 + 0.9713411927 + 0.9714943171 + 0.9716473818 + 0.9718006253 + 0.9719536901 + 0.9721068144 + 0.9722599983 + 0.9724131227 + 0.9725661874 + 0.9727193713 + 0.9728724957 + 0.9730256200 + 0.9731786847 + 0.9733319283 + 0.9734849930 + 0.9736381173 + 0.9737913013 + 0.9739444256 + 0.9740974903 + 0.9742506742 + 0.9744037986 + 0.9745569229 + 0.9747101068 + 0.9748631716 + 0.9750162959 + 0.9751694202 + 0.9753226042 + 0.9754757285 + 0.9756287932 + 0.9757819772 + 0.9759351015 + 0.9760882258 + 0.9762414098 + 0.9763944745 + 0.9765475988 + 0.9767007232 + 0.9768539071 + 0.9770069718 + 0.9771600962 + 0.9773132801 + 0.9774664044 + 0.9776195288 + 0.9777727127 + 0.9779257774 + 0.9780789018 + 0.9782320857 + 0.9783852100 + 0.9785382748 + 0.9786913991 + 0.9788445830 + 0.9789977074 + 0.9791507721 + 0.9793040156 + 0.9794570804 + 0.9796102047 + 0.9797633886 + 0.9799165130 + 0.9800521135 + 0.9801667929 + 0.9802814722 + 0.9803960919 + 0.9805107713 + 0.9806255102 + 0.9807401896 + 0.9808548093 + 0.9809694886 + 0.9810842276 + 0.9811989069 + 0.9813135266 + 0.9814282060 + 0.9815428853 + 0.9816575050 + 0.9817721844 + 0.9818869233 + 0.9820016026 + 0.9821162224 + 0.9822309017 + 0.9823455811 + 0.9824602008 + 0.9825748801 + 0.9826896191 + 0.9828042984 + 0.9829189181 + 0.9830335975 + 0.9831482768 + 0.9832628965 + 0.9833775759 + 0.9834923148 + 0.9836069942 + 0.9837216139 + 0.9838362932 + 0.9839509726 + 0.9840655923 + 0.9841802716 + 0.9842950106 + 0.9844096899 + 0.9845243096 + 0.9846389890 + 0.9847537279 + 0.9848682880 + 0.9849830270 + 0.9850977063 + 0.9852123857 + 0.9853270054 + 0.9854416847 + 0.9855564237 + 0.9856711030 + 0.9857857227 + 0.9859004021 + 0.9860150814 + 0.9861297011 + 0.9862443805 + 0.9863591194 + 0.9864737988 + 0.9865884185 + 0.9867030978 + 0.9868177772 + 0.9869323969 + 0.9870470762 + 0.9871618152 + 0.9872764945 + 0.9873911142 + 0.9875057936 + 0.9876204729 + 0.9877350926 + 0.9878497720 + 0.9879645109 + 0.9880791903 + 0.9881938100 + 0.9883084893 + 0.9884232283 + 0.9885377884 + 0.9886525273 + 0.9887672067 + 0.9888818860 + 0.9889965057 + 0.9891111851 + 0.9892259240 + 0.9893404841 + 0.9894552231 + 0.9895699024 + 0.9896845818 + 0.9897992015 + 0.9899138808 + 0.9900215864 + 0.9901083708 + 0.9901952147 + 0.9902818799 + 0.9903687239 + 0.9904555082 + 0.9905421734 + 0.9906290174 + 0.9907158017 + 0.9908025265 + 0.9908893108 + 0.9909760952 + 0.9910628200 + 0.9911496043 + 0.9912363887 + 0.9913231730 + 0.9914098978 + 0.9914966822 + 0.9915835261 + 0.9916701913 + 0.9917569757 + 0.9918438196 + 0.9919304848 + 0.9920173287 + 0.9921041131 + 0.9921907783 + 0.9922776222 + 0.9923644066 + 0.9924510717 + 0.9925379157 + 0.9926247001 + 0.9927114248 + 0.9927982092 + 0.9928849936 + 0.9929717779 + 0.9930585027 + 0.9931452870 + 0.9932320714 + 0.9933187962 + 0.9934055805 + 0.9934924245 + 0.9935790896 + 0.9936658740 + 0.9937527180 + 0.9938393831 + 0.9939262271 + 0.9940130115 + 0.9940996766 + 0.9941865206 + 0.9942733049 + 0.9943600297 + 0.9944468141 + 0.9945335984 + 0.9946203828 + 0.9947071075 + 0.9947938919 + 0.9948806763 + 0.9949674010 + 0.9950541854 + 0.9951410294 + 0.9952276945 + 0.9953144789 + 0.9954013228 + 0.9954879880 + 0.9955747724 + 0.9956616163 + 0.9957482815 + 0.9958351254 + 0.9959219098 + 0.9960085750 + 0.9960954189 + 0.9961822033 + 0.9962689877 + 0.9963557124 + 0.9964424968 + 0.9965292811 + 0.9966160059 + 0.9967027903 + 0.9967895746 + 0.9968762994 + 0.9969630837 + 0.9970499277 + 0.9971365929 + 0.9972233772 + 0.9973102212 + 0.9973968863 + 0.9974836707 + 0.9975705147 + 0.9976572990 + 0.9977440238 + 0.9978308082 + 0.9979175925 + 0.9980043173 + 0.9980911016 + 0.9981778860 + 0.9982646108 + 0.9983513951 + 0.9984381795 + 0.9985249043 + 0.9986116886 + 0.9986984730 + 0.9987851977 + 0.9988719821 + 0.9989588261 + 0.9990454912 + 0.9991322756 + 0.9992191195 + 0.9993059039 + 0.9993926287 + 0.9994794130 + 0.9995661974 + 0.9996529222 + 0.9997397065 + 0.9998264909 + 0.9999132156 + 1.0000000000 +} diff --git a/rpplugins/color_correction/resources/film_luts_raw/canon_optura_981113.spi1d b/rpplugins/color_correction/resources/film_luts_raw/canon_optura_981113.spi1d new file mode 100644 index 0000000..b3ee4a4 --- /dev/null +++ b/rpplugins/color_correction/resources/film_luts_raw/canon_optura_981113.spi1d @@ -0,0 +1,1030 @@ +Version 1 +From 0.0 1.0 +Length 1024 +Components 1 +{ + 0.0000000000 + 0.0135446005 + 0.0202735607 + 0.0249911100 + 0.0297086593 + 0.0336879417 + 0.0376186185 + 0.0414095595 + 0.0449856818 + 0.0485617891 + 0.0520423800 + 0.0554586984 + 0.0588750206 + 0.0622536913 + 0.0656138808 + 0.0689740628 + 0.0723363981 + 0.0756996870 + 0.0790629685 + 0.0824523792 + 0.0858518705 + 0.0892513692 + 0.0926911235 + 0.0961422473 + 0.0995933712 + 0.1030920967 + 0.1065972000 + 0.1101036966 + 0.1136552989 + 0.1172067970 + 0.1207652017 + 0.1243487000 + 0.1279322952 + 0.1315212995 + 0.1351177990 + 0.1387142986 + 0.1423058063 + 0.1458943933 + 0.1494830996 + 0.1530472934 + 0.1566074044 + 0.1601652950 + 0.1636777967 + 0.1671904027 + 0.1706901938 + 0.1741389930 + 0.1775878072 + 0.1810134947 + 0.1843854934 + 0.1877575070 + 0.1911004037 + 0.1943856031 + 0.1976709068 + 0.2009288967 + 0.2041203976 + 0.2073118985 + 0.2104879022 + 0.2135811001 + 0.2166742980 + 0.2197676003 + 0.2227675021 + 0.2257598937 + 0.2287521958 + 0.2316852063 + 0.2345757037 + 0.2374662012 + 0.2403441072 + 0.2431329042 + 0.2459215969 + 0.2487103939 + 0.2514449954 + 0.2541329861 + 0.2568210065 + 0.2595090866 + 0.2621161044 + 0.2647050917 + 0.2672941089 + 0.2698830068 + 0.2723794878 + 0.2748715878 + 0.2773636878 + 0.2798557878 + 0.2822589874 + 0.2846567929 + 0.2870545983 + 0.2894524038 + 0.2917796075 + 0.2940860093 + 0.2963924110 + 0.2986988127 + 0.3009667993 + 0.3031851053 + 0.3054032922 + 0.3076215982 + 0.3098397851 + 0.3119795024 + 0.3141129911 + 0.3162465096 + 0.3183799982 + 0.3204940856 + 0.3225466013 + 0.3245992064 + 0.3266518116 + 0.3287042975 + 0.3307285011 + 0.3327040076 + 0.3346796036 + 0.3366551101 + 0.3386305869 + 0.3405838013 + 0.3424864113 + 0.3443889916 + 0.3462916017 + 0.3481942117 + 0.3500933051 + 0.3519271910 + 0.3537611067 + 0.3555949926 + 0.3574289083 + 0.3592627943 + 0.3610582054 + 0.3628278077 + 0.3645974100 + 0.3663670123 + 0.3681367040 + 0.3699063063 + 0.3716191053 + 0.3733288050 + 0.3750385046 + 0.3767482042 + 0.3784579039 + 0.3801622093 + 0.3818163872 + 0.3834707141 + 0.3851250112 + 0.3867791891 + 0.3884334862 + 0.3900850117 + 0.3916882873 + 0.3932915032 + 0.3948946893 + 0.3964979947 + 0.3981012106 + 0.3997044861 + 0.4012697041 + 0.4028263986 + 0.4043830931 + 0.4059396982 + 0.4074963927 + 0.4090530872 + 0.4105932117 + 0.4121075869 + 0.4136219919 + 0.4151363969 + 0.4166508019 + 0.4181652069 + 0.4196796119 + 0.4211640060 + 0.4226402938 + 0.4241167009 + 0.4255929887 + 0.4270693958 + 0.4285457134 + 0.4300214946 + 0.4314638972 + 0.4329062998 + 0.4343487024 + 0.4357911050 + 0.4372335076 + 0.4386759102 + 0.4401158094 + 0.4415282011 + 0.4429405034 + 0.4443528950 + 0.4457651973 + 0.4471774995 + 0.4485898912 + 0.4500021935 + 0.4513882101 + 0.4527741969 + 0.4541603029 + 0.4555462897 + 0.4569323957 + 0.4583184123 + 0.4597044885 + 0.4610725939 + 0.4624359906 + 0.4637992978 + 0.4651626050 + 0.4665259123 + 0.4678891897 + 0.4692525864 + 0.4706071019 + 0.4719510078 + 0.4732949138 + 0.4746387899 + 0.4759826958 + 0.4773266017 + 0.4786705077 + 0.4800142050 + 0.4813418090 + 0.4826692939 + 0.4839968979 + 0.4853244126 + 0.4866518974 + 0.4879795015 + 0.4893069863 + 0.4906280935 + 0.4919421077 + 0.4932560027 + 0.4945699871 + 0.4958840013 + 0.4971979856 + 0.4985119104 + 0.4998258948 + 0.5011302829 + 0.5024331212 + 0.5037360191 + 0.5050389171 + 0.5063418150 + 0.5076445937 + 0.5089474916 + 0.5102487206 + 0.5115424991 + 0.5128363967 + 0.5141302943 + 0.5154240727 + 0.5167179704 + 0.5180119276 + 0.5193057060 + 0.5205962062 + 0.5218827128 + 0.5231692791 + 0.5244557858 + 0.5257424116 + 0.5270289779 + 0.5283154845 + 0.5296021104 + 0.5308843851 + 0.5321649909 + 0.5334454775 + 0.5347260237 + 0.5360065103 + 0.5372869968 + 0.5385676026 + 0.5398480892 + 0.5411239266 + 0.5423991084 + 0.5436742902 + 0.5449494720 + 0.5462247133 + 0.5474998951 + 0.5487750769 + 0.5500500798 + 0.5513203144 + 0.5525904298 + 0.5538604856 + 0.5551306009 + 0.5564007759 + 0.5576708913 + 0.5589410067 + 0.5602102280 + 0.5614749193 + 0.5627396107 + 0.5640043020 + 0.5652689934 + 0.5665336847 + 0.5677983761 + 0.5690631270 + 0.5703262091 + 0.5715845227 + 0.5728427768 + 0.5741010904 + 0.5753594041 + 0.5766177177 + 0.5778759718 + 0.5791342854 + 0.5803902149 + 0.5816406012 + 0.5828909874 + 0.5841413736 + 0.5853918195 + 0.5866422057 + 0.5878925920 + 0.5891429782 + 0.5903903246 + 0.5916306973 + 0.5928711295 + 0.5941116214 + 0.5953519940 + 0.5965924263 + 0.5978329182 + 0.5990732908 + 0.6003105044 + 0.6015384197 + 0.6027662754 + 0.6039940715 + 0.6052219868 + 0.6064499021 + 0.6076776981 + 0.6089056134 + 0.6101318002 + 0.6113442183 + 0.6125565171 + 0.6137688756 + 0.6149812937 + 0.6161937118 + 0.6174060702 + 0.6186184883 + 0.6198309064 + 0.6210271716 + 0.6222209930 + 0.6234146953 + 0.6246085167 + 0.6258022189 + 0.6269959807 + 0.6281896830 + 0.6293835044 + 0.6305665970 + 0.6317384839 + 0.6329103708 + 0.6340823174 + 0.6352540851 + 0.6364259720 + 0.6375979185 + 0.6387698054 + 0.6399416924 + 0.6410897970 + 0.6422367096 + 0.6433836222 + 0.6445304751 + 0.6456773281 + 0.6468241811 + 0.6479710937 + 0.6491180062 + 0.6502584815 + 0.6513776183 + 0.6524966955 + 0.6536157131 + 0.6547347903 + 0.6558539271 + 0.6569730043 + 0.6580920815 + 0.6592112184 + 0.6603214145 + 0.6614102721 + 0.6624991894 + 0.6635881066 + 0.6646770239 + 0.6657658815 + 0.6668547988 + 0.6679437160 + 0.6690325737 + 0.6701179743 + 0.6711750031 + 0.6722319126 + 0.6732888818 + 0.6743459105 + 0.6754028797 + 0.6764597893 + 0.6775168180 + 0.6785737872 + 0.6796308160 + 0.6806663275 + 0.6816902161 + 0.6827141047 + 0.6837379932 + 0.6847618818 + 0.6857857704 + 0.6868097186 + 0.6878336072 + 0.6888574958 + 0.6898815036 + 0.6908758283 + 0.6918662190 + 0.6928567290 + 0.6938471198 + 0.6948375106 + 0.6958280206 + 0.6968184114 + 0.6978089213 + 0.6987993121 + 0.6997897029 + 0.7007541060 + 0.7017112970 + 0.7026686072 + 0.7036259174 + 0.7045832276 + 0.7055404782 + 0.7064977884 + 0.7074550986 + 0.7084122896 + 0.7093695998 + 0.7103158832 + 0.7112410069 + 0.7121660709 + 0.7130911946 + 0.7140163183 + 0.7149413824 + 0.7158665061 + 0.7167915106 + 0.7177165747 + 0.7186416984 + 0.7195668221 + 0.7204756141 + 0.7213701010 + 0.7222645879 + 0.7231590748 + 0.7240536213 + 0.7249481082 + 0.7258424759 + 0.7267370224 + 0.7276315093 + 0.7285259962 + 0.7294204831 + 0.7303048968 + 0.7311708927 + 0.7320368886 + 0.7329028845 + 0.7337688208 + 0.7346348166 + 0.7355008125 + 0.7363668084 + 0.7372328043 + 0.7380986810 + 0.7389646769 + 0.7398306727 + 0.7406758070 + 0.7415158749 + 0.7423558831 + 0.7431960106 + 0.7440360188 + 0.7448760867 + 0.7457160950 + 0.7465562224 + 0.7473961711 + 0.7482362986 + 0.7490763068 + 0.7499163747 + 0.7507357001 + 0.7515528202 + 0.7523698211 + 0.7531868219 + 0.7540038824 + 0.7548208833 + 0.7556380033 + 0.7564550042 + 0.7572721243 + 0.7580891252 + 0.7589061260 + 0.7597231865 + 0.7605271935 + 0.7613244057 + 0.7621216774 + 0.7629190087 + 0.7637162805 + 0.7645134926 + 0.7653108239 + 0.7661080956 + 0.7669054270 + 0.7677025795 + 0.7684999108 + 0.7692971826 + 0.7700924873 + 0.7708734870 + 0.7716544271 + 0.7724353075 + 0.7732163072 + 0.7739971876 + 0.7747781873 + 0.7755591273 + 0.7763401270 + 0.7771210074 + 0.7779018879 + 0.7786828876 + 0.7794638276 + 0.7802407742 + 0.7810090184 + 0.7817772031 + 0.7825455070 + 0.7833136916 + 0.7840818763 + 0.7848501801 + 0.7856184244 + 0.7863866091 + 0.7871549129 + 0.7879230976 + 0.7886912823 + 0.7894595265 + 0.7902250886 + 0.7909842730 + 0.7917435169 + 0.7925027013 + 0.7932620049 + 0.7940211892 + 0.7947803736 + 0.7955396175 + 0.7962988019 + 0.7970579863 + 0.7978171706 + 0.7985764742 + 0.7993357182 + 0.8000941873 + 0.8008481264 + 0.8016020060 + 0.8023558855 + 0.8031098247 + 0.8038637042 + 0.8046175838 + 0.8053714037 + 0.8061252832 + 0.8068792224 + 0.8076331019 + 0.8083869815 + 0.8091409206 + 0.8098948002 + 0.8106470704 + 0.8113992214 + 0.8121513724 + 0.8129035234 + 0.8136556149 + 0.8144077063 + 0.8151597977 + 0.8159118891 + 0.8166639805 + 0.8174160719 + 0.8181682825 + 0.8189203739 + 0.8196725249 + 0.8204253912 + 0.8211789131 + 0.8219323754 + 0.8226860166 + 0.8234394789 + 0.8241930008 + 0.8249465227 + 0.8257001042 + 0.8264536262 + 0.8272070885 + 0.8279606104 + 0.8287141919 + 0.8294677138 + 0.8302224278 + 0.8309798241 + 0.8317372799 + 0.8324947953 + 0.8332523108 + 0.8340097070 + 0.8347672224 + 0.8355246782 + 0.8362820745 + 0.8370395899 + 0.8377971053 + 0.8385546207 + 0.8393120170 + 0.8400700092 + 0.8408328295 + 0.8415954709 + 0.8423582911 + 0.8431211114 + 0.8438838720 + 0.8446465731 + 0.8454093933 + 0.8461722136 + 0.8469349146 + 0.8476976752 + 0.8484604955 + 0.8492233157 + 0.8499860168 + 0.8507534862 + 0.8515210152 + 0.8522886038 + 0.8530561924 + 0.8538237214 + 0.8545913100 + 0.8553587794 + 0.8561264277 + 0.8568938971 + 0.8576614857 + 0.8584290147 + 0.8591966033 + 0.8599640727 + 0.8607330918 + 0.8615021706 + 0.8622711897 + 0.8630402088 + 0.8638092875 + 0.8645783067 + 0.8653473854 + 0.8661164045 + 0.8668854833 + 0.8676545024 + 0.8684235215 + 0.8691926003 + 0.8699616194 + 0.8707253933 + 0.8714889288 + 0.8722524047 + 0.8730158806 + 0.8737794161 + 0.8745428920 + 0.8753064871 + 0.8760700226 + 0.8768334985 + 0.8775969744 + 0.8783605099 + 0.8791239858 + 0.8798875213 + 0.8806365728 + 0.8813831210 + 0.8821297288 + 0.8828762770 + 0.8836228848 + 0.8843694925 + 0.8851159811 + 0.8858625889 + 0.8866091967 + 0.8873558044 + 0.8881024122 + 0.8888489008 + 0.8895955086 + 0.8903272748 + 0.8910415769 + 0.8917558193 + 0.8924701214 + 0.8931844234 + 0.8938987255 + 0.8946129084 + 0.8953272104 + 0.8960415125 + 0.8967556953 + 0.8974699974 + 0.8981842995 + 0.8988986015 + 0.8996127844 + 0.9003043175 + 0.9009687901 + 0.9016332030 + 0.9022976756 + 0.9029622078 + 0.9036266804 + 0.9042910933 + 0.9049556255 + 0.9056200981 + 0.9062845707 + 0.9069489837 + 0.9076135159 + 0.9082779884 + 0.9089424014 + 0.9096068740 + 0.9102444053 + 0.9108428955 + 0.9114415050 + 0.9120399952 + 0.9126384854 + 0.9132369757 + 0.9138355255 + 0.9144340158 + 0.9150325060 + 0.9156309962 + 0.9162294865 + 0.9168279767 + 0.9174265265 + 0.9180250168 + 0.9186235070 + 0.9192219973 + 0.9198204875 + 0.9203649759 + 0.9208863974 + 0.9214078188 + 0.9219291210 + 0.9224504828 + 0.9229717851 + 0.9234932065 + 0.9240146279 + 0.9245358706 + 0.9250572920 + 0.9255785942 + 0.9261000156 + 0.9266213775 + 0.9271426797 + 0.9276641011 + 0.9281855226 + 0.9287068248 + 0.9292281866 + 0.9297494888 + 0.9302288294 + 0.9306690097 + 0.9311093092 + 0.9315496087 + 0.9319899082 + 0.9324302077 + 0.9328703880 + 0.9333106875 + 0.9337509871 + 0.9341912866 + 0.9346315861 + 0.9350718260 + 0.9355121255 + 0.9359524250 + 0.9363927245 + 0.9368330240 + 0.9372732043 + 0.9377135038 + 0.9381538033 + 0.9385941029 + 0.9390344024 + 0.9394745827 + 0.9399148822 + 0.9402922988 + 0.9406545758 + 0.9410169125 + 0.9413791895 + 0.9417415261 + 0.9421038032 + 0.9424660802 + 0.9428284168 + 0.9431906939 + 0.9435529709 + 0.9439153075 + 0.9442775846 + 0.9446399212 + 0.9450021982 + 0.9453645945 + 0.9457268715 + 0.9460892081 + 0.9464514852 + 0.9468138218 + 0.9471760988 + 0.9475383759 + 0.9479007125 + 0.9482629895 + 0.9486253262 + 0.9489876032 + 0.9493498802 + 0.9497122169 + 0.9500601292 + 0.9503526092 + 0.9506450295 + 0.9509373903 + 0.9512298107 + 0.9515222907 + 0.9518147111 + 0.9521070719 + 0.9523994923 + 0.9526919723 + 0.9529843926 + 0.9532768130 + 0.9535691738 + 0.9538617134 + 0.9541540742 + 0.9544464946 + 0.9547389150 + 0.9550313950 + 0.9553238153 + 0.9556161761 + 0.9559085965 + 0.9562010765 + 0.9564934969 + 0.9567859173 + 0.9570782781 + 0.9573706985 + 0.9576631784 + 0.9579555988 + 0.9582480192 + 0.9585403800 + 0.9588329196 + 0.9591252804 + 0.9594177008 + 0.9597101212 + 0.9600020051 + 0.9602351189 + 0.9604681134 + 0.9607011080 + 0.9609341025 + 0.9611670971 + 0.9614000916 + 0.9616330862 + 0.9618662000 + 0.9620991945 + 0.9623321891 + 0.9625651836 + 0.9627981782 + 0.9630311728 + 0.9632642269 + 0.9634972811 + 0.9637302756 + 0.9639633298 + 0.9641963243 + 0.9644293189 + 0.9646623135 + 0.9648953080 + 0.9651284218 + 0.9653614163 + 0.9655944109 + 0.9658274055 + 0.9660604000 + 0.9662933946 + 0.9665263891 + 0.9667595029 + 0.9669924974 + 0.9672254920 + 0.9674584866 + 0.9676914811 + 0.9679244757 + 0.9681574702 + 0.9683905840 + 0.9686235785 + 0.9688565731 + 0.9690896273 + 0.9693226218 + 0.9695556164 + 0.9697886109 + 0.9700170755 + 0.9702014923 + 0.9703857899 + 0.9705702066 + 0.9707545042 + 0.9709389210 + 0.9711232185 + 0.9713075757 + 0.9714918733 + 0.9716762900 + 0.9718605876 + 0.9720450044 + 0.9722293019 + 0.9724137187 + 0.9725980163 + 0.9727823734 + 0.9729666710 + 0.9731510878 + 0.9733353853 + 0.9735198021 + 0.9737040997 + 0.9738885164 + 0.9740728140 + 0.9742571712 + 0.9744415283 + 0.9746258855 + 0.9748101830 + 0.9749945998 + 0.9751788974 + 0.9753633142 + 0.9755476117 + 0.9757320285 + 0.9759163260 + 0.9761006236 + 0.9762849808 + 0.9764692783 + 0.9766536951 + 0.9768379927 + 0.9770224094 + 0.9772067070 + 0.9773911238 + 0.9775754213 + 0.9777597785 + 0.9779440761 + 0.9781284928 + 0.9783127904 + 0.9784972072 + 0.9786815047 + 0.9788659215 + 0.9790502191 + 0.9792345762 + 0.9794188738 + 0.9796032906 + 0.9797875881 + 0.9799720049 + 0.9801232815 + 0.9802687764 + 0.9804142118 + 0.9805597067 + 0.9807050824 + 0.9808505774 + 0.9809960127 + 0.9811415076 + 0.9812868834 + 0.9814323783 + 0.9815778136 + 0.9817233086 + 0.9818686843 + 0.9820141792 + 0.9821596146 + 0.9823051095 + 0.9824504852 + 0.9825959802 + 0.9827414155 + 0.9828869104 + 0.9830322862 + 0.9831777811 + 0.9833232164 + 0.9834687114 + 0.9836140871 + 0.9837595820 + 0.9839050174 + 0.9840505123 + 0.9841958880 + 0.9843413830 + 0.9844868183 + 0.9846323133 + 0.9847776890 + 0.9849231839 + 0.9850686193 + 0.9852141142 + 0.9853594899 + 0.9855049849 + 0.9856504202 + 0.9857959151 + 0.9859412909 + 0.9860867858 + 0.9862322211 + 0.9863777161 + 0.9865230918 + 0.9866685867 + 0.9868140221 + 0.9869595170 + 0.9871048927 + 0.9872503877 + 0.9873958230 + 0.9875413179 + 0.9876866937 + 0.9878321886 + 0.9879776239 + 0.9881231189 + 0.9882684946 + 0.9884139895 + 0.9885594249 + 0.9887049198 + 0.9888502955 + 0.9889957905 + 0.9891412258 + 0.9892867208 + 0.9894320965 + 0.9895775914 + 0.9897230864 + 0.9898685217 + 0.9900109768 + 0.9901257753 + 0.9902405739 + 0.9903554916 + 0.9904702902 + 0.9905850887 + 0.9906998873 + 0.9908146858 + 0.9909294844 + 0.9910444021 + 0.9911592007 + 0.9912739992 + 0.9913887978 + 0.9915035963 + 0.9916183949 + 0.9917333126 + 0.9918481112 + 0.9919629097 + 0.9920777082 + 0.9921925068 + 0.9923073053 + 0.9924221039 + 0.9925370216 + 0.9926518202 + 0.9927666187 + 0.9928814173 + 0.9929962158 + 0.9931110144 + 0.9932258725 + 0.9933406711 + 0.9934555292 + 0.9935703278 + 0.9936851263 + 0.9937999249 + 0.9939147830 + 0.9940295815 + 0.9941443801 + 0.9942591786 + 0.9943739772 + 0.9944887757 + 0.9946036935 + 0.9947184920 + 0.9948332906 + 0.9949480891 + 0.9950628877 + 0.9951776862 + 0.9952924848 + 0.9954074025 + 0.9955222011 + 0.9956369996 + 0.9957517982 + 0.9958665967 + 0.9959813952 + 0.9960963130 + 0.9962111115 + 0.9963259101 + 0.9964407086 + 0.9965555072 + 0.9966703057 + 0.9967852235 + 0.9969000220 + 0.9970148206 + 0.9971296191 + 0.9972444177 + 0.9973592162 + 0.9974740148 + 0.9975888729 + 0.9977036715 + 0.9978185296 + 0.9979333282 + 0.9980481267 + 0.9981629252 + 0.9982777834 + 0.9983925819 + 0.9985073805 + 0.9986221790 + 0.9987369776 + 0.9988517761 + 0.9989666939 + 0.9990814924 + 0.9991962910 + 0.9993110895 + 0.9994258881 + 0.9995406866 + 0.9996556044 + 0.9997704029 + 0.9998852015 + 1.0000000000 +} diff --git a/rpplugins/color_correction/resources/film_luts_raw/canon_optura_981114.spi1d b/rpplugins/color_correction/resources/film_luts_raw/canon_optura_981114.spi1d new file mode 100644 index 0000000..477d237 --- /dev/null +++ b/rpplugins/color_correction/resources/film_luts_raw/canon_optura_981114.spi1d @@ -0,0 +1,1030 @@ +Version 1 +From 0.0 1.0 +Length 1024 +Components 1 +{ + 0.0000000000 + 0.0011549980 + 0.0023099950 + 0.0034649931 + 0.0046199900 + 0.0057749879 + 0.0069299862 + 0.0080849826 + 0.0092399810 + 0.0104988897 + 0.0119577302 + 0.0134165697 + 0.0148754101 + 0.0163342599 + 0.0177931003 + 0.0192519408 + 0.0208822303 + 0.0226929598 + 0.0245036893 + 0.0263144094 + 0.0281251408 + 0.0299358703 + 0.0321105719 + 0.0342986286 + 0.0364867002 + 0.0386747718 + 0.0410060883 + 0.0435574502 + 0.0461088084 + 0.0486601703 + 0.0513551086 + 0.0542088412 + 0.0570625700 + 0.0599162988 + 0.0629694685 + 0.0660286620 + 0.0690878481 + 0.0722158924 + 0.0753731802 + 0.0785304680 + 0.0816907808 + 0.0848537087 + 0.0880166367 + 0.0911577269 + 0.0942621008 + 0.0973664671 + 0.1004566029 + 0.1034670025 + 0.1064774022 + 0.1094878018 + 0.1124091968 + 0.1153123975 + 0.1182155982 + 0.1210779995 + 0.1238754019 + 0.1266727000 + 0.1294700056 + 0.1321890950 + 0.1348897964 + 0.1375904977 + 0.1402821988 + 0.1428993046 + 0.1455163062 + 0.1481333971 + 0.1507305056 + 0.1532779038 + 0.1558253020 + 0.1583727002 + 0.1608998030 + 0.1633909047 + 0.1658820063 + 0.1683731973 + 0.1708489954 + 0.1732959002 + 0.1757428944 + 0.1781897992 + 0.1806280017 + 0.1830410063 + 0.1854541004 + 0.1878671944 + 0.1902772933 + 0.1926648021 + 0.1950524002 + 0.1974398941 + 0.1998274028 + 0.2021971047 + 0.2045654058 + 0.2069337070 + 0.2093019933 + 0.2116595954 + 0.2140129060 + 0.2163662016 + 0.2187193930 + 0.2210668027 + 0.2234072983 + 0.2257477045 + 0.2280880958 + 0.2304262072 + 0.2327540070 + 0.2350818068 + 0.2374096066 + 0.2397374958 + 0.2420527041 + 0.2443664074 + 0.2466800958 + 0.2489937991 + 0.2512977123 + 0.2535941005 + 0.2558904886 + 0.2581869066 + 0.2604787052 + 0.2627533972 + 0.2650280893 + 0.2673028111 + 0.2695775032 + 0.2718302011 + 0.2740780115 + 0.2763257027 + 0.2785733938 + 0.2808091044 + 0.2830238938 + 0.2852387130 + 0.2874535024 + 0.2896682024 + 0.2918500006 + 0.2940258980 + 0.2962017953 + 0.2983776927 + 0.3005422950 + 0.3026734889 + 0.3048047125 + 0.3069359958 + 0.3090671897 + 0.3111704886 + 0.3132519126 + 0.3153333068 + 0.3174147904 + 0.3194962144 + 0.3215366006 + 0.3235639036 + 0.3255912066 + 0.3276185095 + 0.3296456933 + 0.3316256106 + 0.3335955143 + 0.3355652988 + 0.3375352025 + 0.3395051062 + 0.3414301872 + 0.3433403969 + 0.3452506065 + 0.3471607864 + 0.3490709960 + 0.3509500921 + 0.3527995944 + 0.3546490967 + 0.3564985991 + 0.3583481908 + 0.3601911962 + 0.3619799018 + 0.3637686074 + 0.3655573130 + 0.3673459888 + 0.3691348135 + 0.3708924949 + 0.3726212978 + 0.3743501008 + 0.3760789037 + 0.3778077066 + 0.3795365095 + 0.3812226951 + 0.3828932047 + 0.3845637143 + 0.3862341940 + 0.3879047036 + 0.3895752132 + 0.3912039101 + 0.3928183019 + 0.3944328129 + 0.3960472047 + 0.3976615965 + 0.3992759883 + 0.4008611143 + 0.4024221897 + 0.4039832950 + 0.4055444002 + 0.4071055949 + 0.4086667001 + 0.4102205038 + 0.4117313921 + 0.4132421911 + 0.4147531092 + 0.4162639976 + 0.4177747965 + 0.4192857146 + 0.4207718074 + 0.4222356975 + 0.4236997068 + 0.4251635969 + 0.4266274869 + 0.4280914068 + 0.4295552969 + 0.4309889078 + 0.4324092865 + 0.4338296950 + 0.4352501035 + 0.4366703928 + 0.4380908012 + 0.4395112097 + 0.4409053028 + 0.4422855079 + 0.4436658025 + 0.4450460970 + 0.4464263916 + 0.4478066862 + 0.4491870105 + 0.4505521953 + 0.4518958032 + 0.4532394111 + 0.4545829892 + 0.4559265971 + 0.4572702050 + 0.4586139023 + 0.4599575102 + 0.4612688124 + 0.4625791907 + 0.4638895094 + 0.4651997983 + 0.4665100873 + 0.4678204060 + 0.4691306949 + 0.4704309106 + 0.4717111886 + 0.4729914069 + 0.4742717147 + 0.4755519032 + 0.4768322110 + 0.4781123996 + 0.4793927073 + 0.4806587100 + 0.4819119871 + 0.4831652939 + 0.4844186008 + 0.4856719077 + 0.4869252145 + 0.4881784916 + 0.4894317091 + 0.4906719029 + 0.4919010997 + 0.4931303859 + 0.4943596125 + 0.4955888987 + 0.4968182147 + 0.4980474114 + 0.4992766976 + 0.5004972219 + 0.5017052293 + 0.5029131770 + 0.5041211247 + 0.5053290725 + 0.5065370798 + 0.5077450871 + 0.5089530945 + 0.5101585984 + 0.5113480091 + 0.5125373006 + 0.5137265921 + 0.5149158835 + 0.5161052942 + 0.5172945857 + 0.5184838772 + 0.5196732879 + 0.5208507776 + 0.5220239162 + 0.5231968760 + 0.5243700147 + 0.5255430937 + 0.5267161727 + 0.5278891921 + 0.5290622711 + 0.5302324891 + 0.5313915014 + 0.5325505733 + 0.5337095857 + 0.5348685980 + 0.5360276103 + 0.5371866226 + 0.5383455753 + 0.5395045877 + 0.5406568050 + 0.5418037772 + 0.5429506898 + 0.5440977216 + 0.5452446938 + 0.5463917255 + 0.5475386977 + 0.5486857295 + 0.5498327017 + 0.5509709120 + 0.5521076918 + 0.5532444715 + 0.5543813109 + 0.5555180907 + 0.5566548705 + 0.5577917099 + 0.5589284897 + 0.5600647926 + 0.5611929893 + 0.5623211861 + 0.5634493828 + 0.5645775795 + 0.5657057762 + 0.5668339729 + 0.5679622293 + 0.5690904260 + 0.5702171922 + 0.5713382959 + 0.5724593997 + 0.5735803843 + 0.5747014880 + 0.5758225918 + 0.5769436955 + 0.5780646801 + 0.5791857839 + 0.5803052783 + 0.5814204812 + 0.5825356245 + 0.5836508274 + 0.5847659707 + 0.5858811736 + 0.5869963765 + 0.5881115794 + 0.5892267823 + 0.5903404951 + 0.5914508104 + 0.5925611258 + 0.5936715007 + 0.5947818160 + 0.5958921909 + 0.5970025063 + 0.5981128812 + 0.5992231965 + 0.6003323793 + 0.6014387012 + 0.6025450826 + 0.6036515236 + 0.6047579050 + 0.6058642268 + 0.6069706082 + 0.6080769897 + 0.6091833115 + 0.6102889180 + 0.6113919020 + 0.6124950051 + 0.6135979891 + 0.6147010922 + 0.6158041954 + 0.6169071794 + 0.6180102825 + 0.6191133857 + 0.6202158928 + 0.6213160753 + 0.6224163771 + 0.6235166788 + 0.6246169209 + 0.6257172227 + 0.6268175244 + 0.6279177070 + 0.6290180087 + 0.6301180124 + 0.6312158108 + 0.6323136091 + 0.6334114075 + 0.6345092058 + 0.6356070042 + 0.6367048025 + 0.6378026009 + 0.6389003992 + 0.6399981976 + 0.6410936117 + 0.6421890855 + 0.6432846189 + 0.6443799734 + 0.6454755068 + 0.6465709805 + 0.6476663947 + 0.6487619281 + 0.6498574018 + 0.6509507895 + 0.6520439982 + 0.6531370878 + 0.6542302966 + 0.6553233862 + 0.6564165950 + 0.6575096846 + 0.6586028934 + 0.6596959829 + 0.6607874036 + 0.6618781090 + 0.6629688740 + 0.6640595794 + 0.6651502848 + 0.6662409902 + 0.6673316956 + 0.6684224010 + 0.6695131063 + 0.6706023216 + 0.6716902852 + 0.6727783084 + 0.6738662720 + 0.6749542952 + 0.6760423779 + 0.6771304011 + 0.6782184243 + 0.6793063879 + 0.6803932190 + 0.6814782023 + 0.6825631261 + 0.6836479902 + 0.6847329140 + 0.6858178973 + 0.6869028211 + 0.6879876852 + 0.6890726089 + 0.6901569963 + 0.6912384033 + 0.6923196912 + 0.6934009790 + 0.6944823861 + 0.6955636740 + 0.6966450214 + 0.6977263093 + 0.6988077164 + 0.6998890042 + 0.7009665966 + 0.7020437121 + 0.7031208873 + 0.7041980028 + 0.7052751780 + 0.7063522935 + 0.7074295282 + 0.7085065842 + 0.7095838189 + 0.7106578946 + 0.7117301822 + 0.7128025293 + 0.7138748169 + 0.7149469852 + 0.7160192728 + 0.7170916200 + 0.7181639075 + 0.7192360759 + 0.7203068137 + 0.7213733792 + 0.7224400043 + 0.7235066295 + 0.7245730758 + 0.7256397009 + 0.7267063260 + 0.7277728915 + 0.7288395166 + 0.7299060822 + 0.7309666276 + 0.7320265770 + 0.7330865860 + 0.7341464758 + 0.7352064848 + 0.7362664938 + 0.7373265028 + 0.7383863926 + 0.7394464016 + 0.7405027151 + 0.7415549159 + 0.7426071763 + 0.7436593771 + 0.7447115779 + 0.7457638979 + 0.7468160987 + 0.7478684187 + 0.7489206195 + 0.7499728203 + 0.7510163188 + 0.7520595193 + 0.7531027794 + 0.7541459799 + 0.7551891804 + 0.7562325001 + 0.7572757006 + 0.7583189011 + 0.7593622208 + 0.7604013085 + 0.7614340186 + 0.7624667287 + 0.7634993792 + 0.7645320892 + 0.7655647993 + 0.7665975094 + 0.7676302195 + 0.7686629295 + 0.7696955800 + 0.7707195878 + 0.7717399001 + 0.7727602124 + 0.7737805247 + 0.7748007774 + 0.7758212090 + 0.7768415213 + 0.7778617740 + 0.7788820863 + 0.7799023986 + 0.7809095979 + 0.7819153070 + 0.7829210758 + 0.7839267850 + 0.7849326134 + 0.7859383225 + 0.7869439721 + 0.7879498005 + 0.7889555097 + 0.7899612784 + 0.7909504771 + 0.7919390202 + 0.7929275036 + 0.7939161062 + 0.7949045897 + 0.7958930731 + 0.7968816757 + 0.7978702188 + 0.7988587022 + 0.7998473048 + 0.8008186221 + 0.8017867804 + 0.8027549982 + 0.8037232161 + 0.8046914935 + 0.8056597114 + 0.8066279292 + 0.8075960875 + 0.8085643053 + 0.8095325232 + 0.8104882836 + 0.8114324808 + 0.8123767972 + 0.8133209944 + 0.8142651916 + 0.8152093887 + 0.8161537051 + 0.8170979023 + 0.8180420995 + 0.8189862967 + 0.8199306130 + 0.8208488226 + 0.8217648864 + 0.8226810098 + 0.8235970736 + 0.8245131969 + 0.8254293203 + 0.8263453841 + 0.8272615075 + 0.8281775713 + 0.8290936947 + 0.8300095201 + 0.8308929205 + 0.8317763209 + 0.8326597214 + 0.8335431218 + 0.8344264030 + 0.8353098035 + 0.8361932039 + 0.8370766044 + 0.8379600048 + 0.8388434052 + 0.8397268057 + 0.8405842185 + 0.8414300084 + 0.8422756791 + 0.8431215286 + 0.8439673185 + 0.8448129892 + 0.8456587791 + 0.8465046287 + 0.8473502994 + 0.8481960893 + 0.8490418792 + 0.8498876095 + 0.8506965041 + 0.8514996767 + 0.8523029089 + 0.8531060815 + 0.8539093137 + 0.8547124267 + 0.8555155993 + 0.8563187718 + 0.8571220040 + 0.8579251766 + 0.8587284088 + 0.8595315814 + 0.8603150249 + 0.8610708714 + 0.8618267775 + 0.8625826240 + 0.8633384705 + 0.8640943170 + 0.8648502231 + 0.8656061292 + 0.8663619161 + 0.8671178222 + 0.8678736091 + 0.8686295152 + 0.8693854213 + 0.8701316118 + 0.8708360195 + 0.8715404272 + 0.8722447157 + 0.8729491234 + 0.8736534715 + 0.8743578196 + 0.8750622272 + 0.8757665753 + 0.8764709830 + 0.8771752715 + 0.8778796792 + 0.8785840869 + 0.8792883754 + 0.8799927831 + 0.8806430101 + 0.8812925816 + 0.8819422126 + 0.8825919032 + 0.8832414746 + 0.8838911057 + 0.8845406771 + 0.8851904273 + 0.8858399987 + 0.8864896297 + 0.8871392012 + 0.8877888918 + 0.8884385228 + 0.8890880942 + 0.8897377253 + 0.8903535008 + 0.8909463286 + 0.8915392160 + 0.8921319842 + 0.8927248120 + 0.8933175802 + 0.8939105272 + 0.8945032954 + 0.8950961232 + 0.8956890106 + 0.8962817788 + 0.8968746066 + 0.8974674940 + 0.8980603218 + 0.8986530900 + 0.8992459178 + 0.8998388052 + 0.9003897905 + 0.9009250998 + 0.9014605284 + 0.9019957781 + 0.9025312066 + 0.9030665755 + 0.9036018848 + 0.9041373134 + 0.9046726227 + 0.9052079916 + 0.9057434201 + 0.9062787294 + 0.9068140984 + 0.9073494077 + 0.9078847766 + 0.9084202051 + 0.9089555144 + 0.9094908834 + 0.9100235105 + 0.9105020761 + 0.9109807014 + 0.9114593863 + 0.9119380116 + 0.9124165773 + 0.9128953218 + 0.9133738875 + 0.9138525128 + 0.9143311977 + 0.9148098230 + 0.9152883887 + 0.9157670736 + 0.9162456989 + 0.9167243242 + 0.9172030091 + 0.9176815748 + 0.9181602001 + 0.9186388850 + 0.9191175103 + 0.9195960760 + 0.9200661778 + 0.9204902053 + 0.9209141135 + 0.9213380814 + 0.9217619896 + 0.9221860170 + 0.9226099253 + 0.9230338931 + 0.9234578013 + 0.9238818288 + 0.9243056774 + 0.9247297049 + 0.9251536131 + 0.9255775213 + 0.9260014892 + 0.9264253974 + 0.9268494248 + 0.9272732735 + 0.9276973009 + 0.9281212091 + 0.9285451770 + 0.9289690852 + 0.9293931127 + 0.9298170209 + 0.9302117229 + 0.9305840731 + 0.9309564829 + 0.9313287735 + 0.9317011833 + 0.9320735931 + 0.9324460030 + 0.9328184128 + 0.9331908226 + 0.9335631728 + 0.9339355826 + 0.9343079925 + 0.9346802831 + 0.9350526929 + 0.9354251027 + 0.9357975125 + 0.9361699224 + 0.9365422726 + 0.9369146824 + 0.9372870922 + 0.9376595020 + 0.9380317926 + 0.9384042025 + 0.9387766123 + 0.9391490221 + 0.9395213723 + 0.9398937821 + 0.9402320981 + 0.9405568838 + 0.9408816099 + 0.9412062764 + 0.9415311217 + 0.9418557882 + 0.9421805739 + 0.9425053000 + 0.9428300858 + 0.9431548119 + 0.9434794784 + 0.9438043237 + 0.9441289902 + 0.9444537759 + 0.9447785020 + 0.9451032877 + 0.9454280138 + 0.9457526803 + 0.9460775256 + 0.9464021921 + 0.9467269778 + 0.9470517039 + 0.9473763704 + 0.9477012157 + 0.9480258822 + 0.9483507276 + 0.9486753941 + 0.9490001798 + 0.9493249059 + 0.9496495724 + 0.9499744177 + 0.9502593279 + 0.9505407810 + 0.9508221745 + 0.9511036873 + 0.9513852000 + 0.9516667128 + 0.9519482255 + 0.9522296190 + 0.9525110722 + 0.9527925849 + 0.9530740976 + 0.9533556104 + 0.9536370039 + 0.9539185166 + 0.9542000294 + 0.9544814825 + 0.9547629952 + 0.9550443888 + 0.9553259015 + 0.9556074142 + 0.9558889270 + 0.9561703801 + 0.9564517736 + 0.9567332864 + 0.9570147991 + 0.9572963119 + 0.9575778246 + 0.9578592181 + 0.9581406713 + 0.9584221840 + 0.9587036967 + 0.9589852095 + 0.9592666030 + 0.9595481157 + 0.9598296285 + 0.9600958228 + 0.9603385925 + 0.9605814219 + 0.9608241916 + 0.9610670209 + 0.9613097906 + 0.9615526199 + 0.9617953897 + 0.9620382190 + 0.9622809887 + 0.9625238180 + 0.9627665877 + 0.9630094171 + 0.9632521868 + 0.9634950161 + 0.9637377858 + 0.9639806151 + 0.9642233849 + 0.9644662142 + 0.9647089839 + 0.9649518132 + 0.9651945829 + 0.9654374123 + 0.9656801820 + 0.9659230113 + 0.9661657810 + 0.9664086103 + 0.9666513801 + 0.9668942094 + 0.9671369791 + 0.9673798084 + 0.9676225781 + 0.9678654075 + 0.9681081772 + 0.9683510065 + 0.9685937762 + 0.9688366055 + 0.9690793753 + 0.9693222046 + 0.9695649743 + 0.9698078036 + 0.9700434208 + 0.9702520967 + 0.9704607725 + 0.9706693888 + 0.9708781242 + 0.9710866809 + 0.9712954164 + 0.9715039730 + 0.9717127085 + 0.9719213247 + 0.9721300006 + 0.9723386168 + 0.9725472927 + 0.9727559090 + 0.9729645848 + 0.9731732011 + 0.9733818769 + 0.9735904932 + 0.9737992287 + 0.9740077853 + 0.9742165208 + 0.9744251966 + 0.9746338129 + 0.9748424888 + 0.9750511050 + 0.9752597809 + 0.9754683971 + 0.9756770730 + 0.9758856893 + 0.9760944247 + 0.9763029814 + 0.9765117168 + 0.9767202735 + 0.9769290090 + 0.9771376252 + 0.9773463011 + 0.9775549173 + 0.9777635932 + 0.9779723287 + 0.9781808853 + 0.9783896208 + 0.9785981774 + 0.9788069129 + 0.9790155292 + 0.9792242050 + 0.9794328213 + 0.9796414971 + 0.9798501134 + 0.9800503850 + 0.9802291989 + 0.9804080129 + 0.9805868864 + 0.9807657003 + 0.9809445143 + 0.9811233282 + 0.9813022017 + 0.9814810157 + 0.9816598296 + 0.9818385839 + 0.9820175171 + 0.9821962714 + 0.9823750854 + 0.9825540185 + 0.9827327728 + 0.9829115868 + 0.9830904007 + 0.9832692742 + 0.9834480882 + 0.9836269021 + 0.9838057160 + 0.9839845896 + 0.9841634035 + 0.9843422174 + 0.9845209718 + 0.9846999049 + 0.9848787189 + 0.9850574732 + 0.9852364063 + 0.9854152203 + 0.9855939746 + 0.9857727885 + 0.9859517217 + 0.9861304760 + 0.9863092899 + 0.9864881039 + 0.9866669774 + 0.9868457913 + 0.9870246053 + 0.9872034192 + 0.9873822927 + 0.9875611067 + 0.9877399206 + 0.9879187942 + 0.9880976081 + 0.9882764220 + 0.9884551764 + 0.9886341095 + 0.9888129234 + 0.9889916778 + 0.9891704917 + 0.9893494248 + 0.9895281792 + 0.9897069931 + 0.9898858070 + 0.9900553226 + 0.9902083278 + 0.9903612733 + 0.9905142784 + 0.9906672835 + 0.9908202887 + 0.9909732938 + 0.9911262989 + 0.9912793040 + 0.9914323092 + 0.9915853143 + 0.9917383194 + 0.9918913245 + 0.9920443296 + 0.9921972752 + 0.9923502803 + 0.9925032854 + 0.9926561713 + 0.9928091764 + 0.9929621816 + 0.9931151867 + 0.9932681918 + 0.9934211969 + 0.9935742021 + 0.9937272072 + 0.9938802123 + 0.9940332174 + 0.9941862226 + 0.9943392277 + 0.9944921732 + 0.9946451783 + 0.9947981834 + 0.9949511886 + 0.9951041937 + 0.9952571988 + 0.9954102039 + 0.9955630898 + 0.9957160950 + 0.9958691001 + 0.9960221052 + 0.9961751103 + 0.9963281155 + 0.9964811206 + 0.9966341257 + 0.9967870712 + 0.9969400764 + 0.9970930815 + 0.9972460866 + 0.9973990917 + 0.9975520968 + 0.9977051020 + 0.9978581071 + 0.9980111122 + 0.9981641173 + 0.9983171225 + 0.9984701276 + 0.9986230135 + 0.9987760186 + 0.9989290237 + 0.9990820289 + 0.9992349744 + 0.9993879795 + 0.9995409846 + 0.9996939898 + 0.9998469949 + 1.0000000000 +} diff --git a/rpplugins/color_correction/resources/film_luts_raw/eastman_double_x_neg_12min.spi1d b/rpplugins/color_correction/resources/film_luts_raw/eastman_double_x_neg_12min.spi1d new file mode 100644 index 0000000..d5e4ea9 --- /dev/null +++ b/rpplugins/color_correction/resources/film_luts_raw/eastman_double_x_neg_12min.spi1d @@ -0,0 +1,1030 @@ +Version 1 +From 0.0 1.0 +Length 1024 +Components 1 +{ + 0.0000000000 + 0.0007793432 + 0.0016043870 + 0.0025048309 + 0.0034564850 + 0.0044531059 + 0.0054927212 + 0.0065743062 + 0.0076966030 + 0.0088652465 + 0.0100406297 + 0.0112482598 + 0.0124893002 + 0.0137513904 + 0.0150318900 + 0.0163053796 + 0.0175968707 + 0.0188959707 + 0.0202209800 + 0.0215417892 + 0.0228415392 + 0.0241345204 + 0.0254166108 + 0.0267051402 + 0.0279715508 + 0.0292299706 + 0.0305107906 + 0.0318148397 + 0.0331244394 + 0.0344182886 + 0.0356710814 + 0.0369000100 + 0.0381264500 + 0.0393604413 + 0.0405932292 + 0.0418275297 + 0.0430539995 + 0.0442756005 + 0.0454925410 + 0.0467148200 + 0.0479568392 + 0.0492201187 + 0.0505055487 + 0.0518039688 + 0.0530999005 + 0.0543935411 + 0.0556728095 + 0.0569286086 + 0.0581700616 + 0.0593975298 + 0.0606211387 + 0.0618490316 + 0.0630754977 + 0.0642991737 + 0.0655274168 + 0.0667622983 + 0.0679954067 + 0.0692288280 + 0.0704668984 + 0.0717051104 + 0.0729388893 + 0.0741742104 + 0.0754114315 + 0.0766490623 + 0.0779046863 + 0.0791758820 + 0.0804568231 + 0.0817457736 + 0.0830455273 + 0.0843512416 + 0.0856669694 + 0.0869878605 + 0.0883099586 + 0.0896294117 + 0.0909416676 + 0.0922398567 + 0.0935223699 + 0.0948002487 + 0.0960806310 + 0.0973561779 + 0.0986227468 + 0.0998791903 + 0.1011310965 + 0.1023767963 + 0.1036218032 + 0.1048732996 + 0.1061237976 + 0.1073772013 + 0.1086406037 + 0.1099131033 + 0.1111890003 + 0.1124633029 + 0.1137432009 + 0.1150280014 + 0.1163161024 + 0.1176021993 + 0.1188817993 + 0.1201585010 + 0.1214374006 + 0.1227219999 + 0.1240141019 + 0.1253069043 + 0.1266023964 + 0.1279031932 + 0.1292033046 + 0.1305052042 + 0.1318120956 + 0.1331252009 + 0.1344417036 + 0.1357488036 + 0.1370531023 + 0.1383568048 + 0.1396605074 + 0.1409630030 + 0.1422598958 + 0.1435438991 + 0.1448162943 + 0.1460811943 + 0.1473405957 + 0.1486002952 + 0.1498605013 + 0.1511213034 + 0.1523707062 + 0.1536183953 + 0.1548663974 + 0.1561181992 + 0.1573731005 + 0.1586305052 + 0.1598910987 + 0.1611555964 + 0.1624190062 + 0.1636800021 + 0.1649398953 + 0.1662012041 + 0.1674640030 + 0.1687299013 + 0.1699973047 + 0.1712664962 + 0.1725308001 + 0.1737935990 + 0.1750548929 + 0.1763173938 + 0.1775805950 + 0.1788450032 + 0.1801103055 + 0.1813762039 + 0.1826315969 + 0.1838831007 + 0.1851277947 + 0.1863732934 + 0.1876191944 + 0.1888664067 + 0.1901142001 + 0.1913629025 + 0.1926099062 + 0.1938558966 + 0.1950968057 + 0.1963375956 + 0.1975809038 + 0.1988252997 + 0.2000714988 + 0.2013193965 + 0.2025685012 + 0.2038163990 + 0.2050641030 + 0.2063076943 + 0.2075518072 + 0.2087996006 + 0.2100487053 + 0.2113008052 + 0.2125546932 + 0.2138112932 + 0.2150679976 + 0.2163249999 + 0.2175804973 + 0.2188349068 + 0.2200877964 + 0.2213395983 + 0.2225918025 + 0.2238440067 + 0.2250992060 + 0.2263558954 + 0.2276154011 + 0.2288765013 + 0.2301405072 + 0.2314060032 + 0.2326692939 + 0.2339307964 + 0.2351918072 + 0.2364521027 + 0.2377136946 + 0.2389771044 + 0.2402402014 + 0.2415028960 + 0.2427645028 + 0.2440197021 + 0.2452747971 + 0.2465146035 + 0.2477540970 + 0.2489840984 + 0.2502116859 + 0.2514351010 + 0.2526553869 + 0.2538737059 + 0.2550880015 + 0.2563014030 + 0.2575060129 + 0.2587105036 + 0.2599005997 + 0.2610872090 + 0.2622725964 + 0.2634567022 + 0.2646411955 + 0.2658275068 + 0.2670137882 + 0.2682031095 + 0.2693929970 + 0.2705830038 + 0.2717730105 + 0.2729629874 + 0.2741507888 + 0.2753385901 + 0.2765288949 + 0.2777211964 + 0.2789132893 + 0.2801041007 + 0.2812949121 + 0.2824903131 + 0.2836886942 + 0.2848882973 + 0.2861017883 + 0.2873153090 + 0.2885307968 + 0.2897481024 + 0.2909654081 + 0.2921859026 + 0.2934064865 + 0.2946256995 + 0.2958427072 + 0.2970597148 + 0.2982782125 + 0.2994971871 + 0.3007166982 + 0.3019422889 + 0.3031679094 + 0.3043949902 + 0.3056245148 + 0.3068540096 + 0.3080824018 + 0.3093104064 + 0.3105382919 + 0.3117617965 + 0.3129849136 + 0.3142082095 + 0.3154324889 + 0.3166567981 + 0.3178820908 + 0.3191089034 + 0.3203358054 + 0.3215647936 + 0.3227958977 + 0.3240269125 + 0.3252558112 + 0.3264834881 + 0.3277111948 + 0.3289369941 + 0.3301621974 + 0.3313874006 + 0.3326055110 + 0.3338221014 + 0.3350386918 + 0.3362470865 + 0.3374541104 + 0.3386611044 + 0.3398616016 + 0.3410609961 + 0.3422603905 + 0.3434514999 + 0.3446409106 + 0.3458304107 + 0.3470165133 + 0.3482016921 + 0.3493868113 + 0.3505715132 + 0.3517560065 + 0.3529404998 + 0.3541254103 + 0.3553107083 + 0.3564960063 + 0.3576815128 + 0.3588675857 + 0.3600535989 + 0.3612394929 + 0.3624249995 + 0.3636103868 + 0.3647958934 + 0.3659862876 + 0.3671767116 + 0.3683671057 + 0.3695602119 + 0.3707543015 + 0.3719483912 + 0.3731409013 + 0.3743312061 + 0.3755215108 + 0.3767108917 + 0.3778904974 + 0.3790701926 + 0.3802497983 + 0.3814249933 + 0.3825984001 + 0.3837718070 + 0.3849433959 + 0.3861109912 + 0.3872785866 + 0.3884460926 + 0.3896096051 + 0.3907724023 + 0.3919351995 + 0.3930951953 + 0.3942511082 + 0.3954069018 + 0.3965628147 + 0.3977113962 + 0.3988589942 + 0.4000065923 + 0.4011510909 + 0.4022890925 + 0.4034270048 + 0.4045650065 + 0.4056946933 + 0.4068213105 + 0.4079478085 + 0.4090737104 + 0.4101923108 + 0.4113109112 + 0.4124295115 + 0.4135465026 + 0.4146609008 + 0.4157753885 + 0.4168899059 + 0.4180073142 + 0.4191260040 + 0.4202446938 + 0.4213634133 + 0.4224787951 + 0.4235939085 + 0.4247091115 + 0.4258244038 + 0.4269405007 + 0.4280565977 + 0.4291726947 + 0.4302915931 + 0.4314163029 + 0.4325410128 + 0.4336656928 + 0.4347921908 + 0.4359208047 + 0.4370495081 + 0.4381780922 + 0.4393090010 + 0.4404419065 + 0.4415748119 + 0.4427076876 + 0.4438371062 + 0.4449638128 + 0.4460904002 + 0.4472169876 + 0.4483405054 + 0.4494614005 + 0.4505822957 + 0.4517031908 + 0.4528234005 + 0.4539428949 + 0.4550623894 + 0.4561819136 + 0.4572989047 + 0.4584122002 + 0.4595254064 + 0.4606387019 + 0.4617524147 + 0.4628674090 + 0.4639823139 + 0.4650971889 + 0.4662118852 + 0.4673239887 + 0.4684360921 + 0.4695481956 + 0.4706602991 + 0.4717625082 + 0.4728631973 + 0.4739638865 + 0.4750646055 + 0.4761615098 + 0.4772560000 + 0.4783504903 + 0.4794450104 + 0.4805378914 + 0.4816266894 + 0.4827154875 + 0.4838042855 + 0.4848932028 + 0.4859696925 + 0.4870451093 + 0.4881204069 + 0.4891957939 + 0.4902659059 + 0.4913307130 + 0.4923956096 + 0.4934605062 + 0.4945251942 + 0.4955861866 + 0.4966472089 + 0.4977082014 + 0.4987691939 + 0.4998275936 + 0.5008835793 + 0.5019395947 + 0.5029956102 + 0.5040516257 + 0.5051162243 + 0.5061810017 + 0.5072458982 + 0.5083106756 + 0.5093780756 + 0.5104498863 + 0.5115215778 + 0.5125933886 + 0.5136651993 + 0.5147346854 + 0.5158032179 + 0.5168716908 + 0.5179402232 + 0.5190086961 + 0.5200641155 + 0.5211194158 + 0.5221747160 + 0.5232300758 + 0.5242825747 + 0.5253263116 + 0.5263699889 + 0.5274137259 + 0.5284574032 + 0.5294985771 + 0.5305367112 + 0.5315749049 + 0.5326129794 + 0.5336511135 + 0.5346894860 + 0.5357280970 + 0.5367668271 + 0.5378053784 + 0.5388441086 + 0.5398868918 + 0.5409319997 + 0.5419769883 + 0.5430220962 + 0.5440670848 + 0.5451143980 + 0.5461627245 + 0.5472109914 + 0.5482593179 + 0.5493075848 + 0.5503467917 + 0.5513814092 + 0.5524160266 + 0.5534505844 + 0.5544852018 + 0.5555140972 + 0.5565391183 + 0.5575640798 + 0.5585891008 + 0.5596141219 + 0.5606383085 + 0.5616616011 + 0.5626850128 + 0.5637083054 + 0.5647315979 + 0.5657541752 + 0.5667750239 + 0.5677956939 + 0.5688164234 + 0.5698372126 + 0.5708575845 + 0.5718625784 + 0.5728675723 + 0.5738726258 + 0.5748776197 + 0.5758826137 + 0.5768746138 + 0.5778616071 + 0.5788486004 + 0.5798354745 + 0.5808225274 + 0.5818051100 + 0.5827798247 + 0.5837545991 + 0.5847293139 + 0.5857040882 + 0.5866789222 + 0.5876461267 + 0.5886127949 + 0.5895795822 + 0.5905464292 + 0.5915130973 + 0.5924791098 + 0.5934441090 + 0.5944091082 + 0.5953741074 + 0.5963391066 + 0.5973042250 + 0.5982726812 + 0.5992414951 + 0.6002103090 + 0.6011791825 + 0.6021479964 + 0.6031122804 + 0.6040681005 + 0.6050239205 + 0.6059796810 + 0.6069355011 + 0.6078913212 + 0.6088355184 + 0.6097744703 + 0.6107134223 + 0.6116523743 + 0.6125913858 + 0.6135302782 + 0.6144611835 + 0.6153919101 + 0.6163225174 + 0.6172531843 + 0.6181837916 + 0.6191145778 + 0.6200459003 + 0.6209772229 + 0.6219084859 + 0.6228398085 + 0.6237710118 + 0.6247057915 + 0.6256468892 + 0.6265881062 + 0.6275292039 + 0.6284703016 + 0.6294115186 + 0.6303575039 + 0.6313095093 + 0.6322615147 + 0.6332135797 + 0.6341655850 + 0.6351175904 + 0.6360645294 + 0.6370056272 + 0.6379467249 + 0.6388878822 + 0.6398289800 + 0.6407700777 + 0.6417067051 + 0.6426376104 + 0.6435685158 + 0.6444994211 + 0.6454303265 + 0.6463611126 + 0.6472914815 + 0.6482210159 + 0.6491504908 + 0.6500799060 + 0.6510093808 + 0.6519389153 + 0.6528680921 + 0.6537961960 + 0.6547242999 + 0.6556524038 + 0.6565805078 + 0.6575086713 + 0.6584367752 + 0.6593579054 + 0.6602786779 + 0.6611993909 + 0.6621202230 + 0.6630408764 + 0.6639617085 + 0.6648803949 + 0.6657980084 + 0.6667156219 + 0.6676332951 + 0.6685509086 + 0.6694685221 + 0.6703848243 + 0.6712977886 + 0.6722108126 + 0.6731237769 + 0.6740368009 + 0.6749498248 + 0.6758627892 + 0.6767727733 + 0.6776821017 + 0.6785914898 + 0.6795008779 + 0.6804103255 + 0.6813195944 + 0.6822264791 + 0.6831287146 + 0.6840307713 + 0.6849328876 + 0.6858351231 + 0.6867371798 + 0.6876392961 + 0.6885449290 + 0.6894515753 + 0.6903582811 + 0.6912649274 + 0.6921715736 + 0.6930782795 + 0.6939843893 + 0.6948862076 + 0.6957879066 + 0.6966897249 + 0.6975914836 + 0.6984933019 + 0.6993951201 + 0.7002941966 + 0.7011892796 + 0.7020843029 + 0.7029793859 + 0.7038745284 + 0.7047696114 + 0.7056646943 + 0.7065535784 + 0.7074385285 + 0.7083234191 + 0.7092083097 + 0.7100932002 + 0.7109780908 + 0.7118629813 + 0.7127363086 + 0.7136055827 + 0.7144749165 + 0.7153440714 + 0.7162134051 + 0.7170826197 + 0.7179518938 + 0.7188181877 + 0.7196837068 + 0.7205492854 + 0.7214148045 + 0.7222803831 + 0.7231459022 + 0.7240114212 + 0.7248805165 + 0.7257506251 + 0.7266206741 + 0.7274907827 + 0.7283608913 + 0.7292309999 + 0.7301011086 + 0.7309634089 + 0.7318221927 + 0.7326809168 + 0.7335395813 + 0.7343984246 + 0.7352570891 + 0.7361158133 + 0.7369657159 + 0.7378072739 + 0.7386490107 + 0.7394906282 + 0.7403321862 + 0.7411738038 + 0.7420154214 + 0.7428557277 + 0.7436921000 + 0.7445284724 + 0.7453650236 + 0.7462013960 + 0.7470378876 + 0.7478743196 + 0.7487106919 + 0.7495496869 + 0.7503886819 + 0.7512277961 + 0.7520667911 + 0.7529059052 + 0.7537449002 + 0.7545840144 + 0.7554156780 + 0.7562410831 + 0.7570664287 + 0.7578917742 + 0.7587171793 + 0.7595425844 + 0.7603678703 + 0.7611923218 + 0.7619991899 + 0.7628061175 + 0.7636129856 + 0.7644199133 + 0.7652267814 + 0.7660337090 + 0.7668405175 + 0.7676423192 + 0.7684385180 + 0.7692347169 + 0.7700309753 + 0.7708271742 + 0.7716233730 + 0.7724196911 + 0.7732158899 + 0.7740070820 + 0.7747973204 + 0.7755873799 + 0.7763776183 + 0.7771677971 + 0.7779579759 + 0.7787482142 + 0.7795379162 + 0.7803233862 + 0.7811089158 + 0.7818945050 + 0.7826799750 + 0.7834655046 + 0.7842510939 + 0.7850366235 + 0.7858232856 + 0.7866128087 + 0.7874022722 + 0.7881917953 + 0.7889813185 + 0.7897707820 + 0.7905603051 + 0.7913498282 + 0.7921416163 + 0.7929369807 + 0.7937325239 + 0.7945278883 + 0.7953233719 + 0.7961187959 + 0.7969142795 + 0.7977098227 + 0.7985072732 + 0.7993078828 + 0.8001083732 + 0.8009089828 + 0.8017095923 + 0.8025102019 + 0.8033106923 + 0.8041113019 + 0.8049136996 + 0.8057196736 + 0.8065257072 + 0.8073316813 + 0.8081377149 + 0.8089436889 + 0.8097497225 + 0.8105556965 + 0.8113610148 + 0.8121625185 + 0.8129640818 + 0.8137655854 + 0.8145672083 + 0.8153687119 + 0.8161702752 + 0.8169717789 + 0.8177734017 + 0.8185741901 + 0.8193749189 + 0.8201755881 + 0.8209763169 + 0.8217771053 + 0.8225777745 + 0.8233785033 + 0.8241791725 + 0.8249862790 + 0.8257976770 + 0.8266091943 + 0.8274207115 + 0.8282322288 + 0.8290436864 + 0.8298552036 + 0.8306667209 + 0.8314790130 + 0.8322961926 + 0.8331133723 + 0.8339306116 + 0.8347477913 + 0.8355649710 + 0.8363820910 + 0.8371992707 + 0.8380165100 + 0.8388273120 + 0.8396344185 + 0.8404415846 + 0.8412486911 + 0.8420559168 + 0.8428630233 + 0.8436701894 + 0.8444772959 + 0.8452842832 + 0.8460859060 + 0.8468874097 + 0.8476889729 + 0.8484904766 + 0.8492919803 + 0.8500936031 + 0.8508951068 + 0.8516967297 + 0.8524969816 + 0.8532947898 + 0.8540925980 + 0.8548902869 + 0.8556880951 + 0.8564857841 + 0.8572835922 + 0.8580814004 + 0.8588790894 + 0.8596730232 + 0.8604632020 + 0.8612535000 + 0.8620436788 + 0.8628339767 + 0.8636242151 + 0.8644145131 + 0.8652046919 + 0.8659949899 + 0.8667806983 + 0.8675637841 + 0.8683468103 + 0.8691297770 + 0.8699129224 + 0.8706958890 + 0.8714789152 + 0.8722620010 + 0.8730450273 + 0.8738256097 + 0.8746048808 + 0.8753840923 + 0.8761633039 + 0.8769425750 + 0.8777217865 + 0.8785009980 + 0.8792803288 + 0.8800594807 + 0.8808330894 + 0.8816019893 + 0.8823708296 + 0.8831397295 + 0.8839085102 + 0.8846774101 + 0.8854461908 + 0.8862150908 + 0.8869838715 + 0.8877493739 + 0.8885086775 + 0.8892679811 + 0.8900274038 + 0.8907867074 + 0.8915460706 + 0.8923053741 + 0.8930646777 + 0.8938241005 + 0.8945831060 + 0.8953374028 + 0.8960916996 + 0.8968459964 + 0.8976002932 + 0.8983545899 + 0.8991088867 + 0.8998631835 + 0.9006174803 + 0.9013717771 + 0.9021221995 + 0.9028707147 + 0.9036192298 + 0.9043676853 + 0.9051162004 + 0.9058647156 + 0.9066131711 + 0.9073616862 + 0.9081102014 + 0.9088572264 + 0.9095978141 + 0.9103382826 + 0.9110788703 + 0.9118193984 + 0.9125599265 + 0.9133005142 + 0.9140409827 + 0.9147815704 + 0.9155220985 + 0.9162616730 + 0.9170007110 + 0.9177396894 + 0.9184786081 + 0.9192175865 + 0.9199566245 + 0.9206956029 + 0.9214345813 + 0.9221735001 + 0.9229124784 + 0.9236471057 + 0.9243810773 + 0.9251152277 + 0.9258491993 + 0.9265832901 + 0.9273173809 + 0.9280514121 + 0.9287855029 + 0.9295194745 + 0.9302524924 + 0.9309753180 + 0.9316980839 + 0.9324210286 + 0.9331437945 + 0.9338666201 + 0.9345893860 + 0.9353122711 + 0.9360350966 + 0.9367579222 + 0.9374781847 + 0.9381874204 + 0.9388967156 + 0.9396058917 + 0.9403151274 + 0.9410244226 + 0.9417335987 + 0.9424427748 + 0.9431521297 + 0.9438613057 + 0.9445694089 + 0.9452716708 + 0.9459741116 + 0.9466764927 + 0.9473788738 + 0.9480813146 + 0.9487836957 + 0.9494860768 + 0.9501885176 + 0.9508908987 + 0.9515926838 + 0.9522830844 + 0.9529734850 + 0.9536638856 + 0.9543542862 + 0.9550446868 + 0.9557350874 + 0.9564254880 + 0.9571158886 + 0.9578062892 + 0.9584966898 + 0.9591748118 + 0.9598501921 + 0.9605255723 + 0.9612010121 + 0.9618763924 + 0.9625517726 + 0.9632272124 + 0.9639025927 + 0.9645779729 + 0.9652534127 + 0.9659177065 + 0.9665694833 + 0.9672212005 + 0.9678729773 + 0.9685248137 + 0.9691764712 + 0.9698283076 + 0.9704800248 + 0.9711318016 + 0.9717835784 + 0.9724348783 + 0.9730530977 + 0.9736713171 + 0.9742894769 + 0.9749076962 + 0.9755259752 + 0.9761441946 + 0.9767624140 + 0.9773805737 + 0.9779987931 + 0.9786170125 + 0.9792193770 + 0.9798017740 + 0.9803841710 + 0.9809666872 + 0.9815490842 + 0.9821314812 + 0.9827138782 + 0.9832963943 + 0.9838787913 + 0.9844611883 + 0.9850435853 + 0.9855896831 + 0.9861239791 + 0.9866582751 + 0.9871926904 + 0.9877269864 + 0.9882612824 + 0.9887955785 + 0.9893299937 + 0.9898642898 + 0.9903985858 + 0.9909328818 + 0.9913933873 + 0.9918504953 + 0.9923074841 + 0.9927644730 + 0.9932215214 + 0.9936786294 + 0.9941356182 + 0.9945926070 + 0.9950495958 + 0.9955067039 + 0.9959604144 + 0.9963275790 + 0.9966949224 + 0.9970620871 + 0.9974293113 + 0.9977965951 + 0.9981638193 + 0.9985311031 + 0.9988983274 + 0.9992654920 + 0.9996327758 + 1.0000000000 +} diff --git a/rpplugins/color_correction/resources/film_luts_raw/eastman_double_x_neg_4min.spi1d b/rpplugins/color_correction/resources/film_luts_raw/eastman_double_x_neg_4min.spi1d new file mode 100644 index 0000000..4835f84 --- /dev/null +++ b/rpplugins/color_correction/resources/film_luts_raw/eastman_double_x_neg_4min.spi1d @@ -0,0 +1,1030 @@ +Version 1 +From 0.0 1.0 +Length 1024 +Components 1 +{ + 0.0000000000 + 0.0023687680 + 0.0054706829 + 0.0086651789 + 0.0120176496 + 0.0158339497 + 0.0195765607 + 0.0236159302 + 0.0276366994 + 0.0318052210 + 0.0358720496 + 0.0399059989 + 0.0439607613 + 0.0478296690 + 0.0517273210 + 0.0555948503 + 0.0593124293 + 0.0629053935 + 0.0664692596 + 0.0699850023 + 0.0734276623 + 0.0768507421 + 0.0801614299 + 0.0833590478 + 0.0865080431 + 0.0895957723 + 0.0926453620 + 0.0956536904 + 0.0985890403 + 0.1014889032 + 0.1043139026 + 0.1071280017 + 0.1098439023 + 0.1126044020 + 0.1154047996 + 0.1181370020 + 0.1207929030 + 0.1234567985 + 0.1260991991 + 0.1286775023 + 0.1312310994 + 0.1338002980 + 0.1363786012 + 0.1389155984 + 0.1414254010 + 0.1439868957 + 0.1465484947 + 0.1490968019 + 0.1516236961 + 0.1540950984 + 0.1565376967 + 0.1589566022 + 0.1613540947 + 0.1637308002 + 0.1660850048 + 0.1684197038 + 0.1707345992 + 0.1730296016 + 0.1753066033 + 0.1775436997 + 0.1797461957 + 0.1819386929 + 0.1841226071 + 0.1862974018 + 0.1884626001 + 0.1906190962 + 0.1927487999 + 0.1948511004 + 0.1969520003 + 0.1990513057 + 0.2011491954 + 0.2032300979 + 0.2052827030 + 0.2073220015 + 0.2093351036 + 0.2113271952 + 0.2133180052 + 0.2153075039 + 0.2172959000 + 0.2192790955 + 0.2212336957 + 0.2231718004 + 0.2251033932 + 0.2270285040 + 0.2289548069 + 0.2309035063 + 0.2328732014 + 0.2348369956 + 0.2367957979 + 0.2387501001 + 0.2406919003 + 0.2426078022 + 0.2445061952 + 0.2464056015 + 0.2483084053 + 0.2502099872 + 0.2521064878 + 0.2539938092 + 0.2558684051 + 0.2577266097 + 0.2595650852 + 0.2613835931 + 0.2631973922 + 0.2650325000 + 0.2668823004 + 0.2687312961 + 0.2705838084 + 0.2724444866 + 0.2743074894 + 0.2761450112 + 0.2779580951 + 0.2797524035 + 0.2815274894 + 0.2832885981 + 0.2850483060 + 0.2868123949 + 0.2885822058 + 0.2903468013 + 0.2920975983 + 0.2938277125 + 0.2955364883 + 0.2972253859 + 0.2988938093 + 0.3005304933 + 0.3021554053 + 0.3037792146 + 0.3054072857 + 0.3070620894 + 0.3087309003 + 0.3104070127 + 0.3120703995 + 0.3137196898 + 0.3153668940 + 0.3170216084 + 0.3186618090 + 0.3202942014 + 0.3219175935 + 0.3235363066 + 0.3251608014 + 0.3267996013 + 0.3284519017 + 0.3301031888 + 0.3317410052 + 0.3333635926 + 0.3349764943 + 0.3365670145 + 0.3381485939 + 0.3397214115 + 0.3412905037 + 0.3428558111 + 0.3444117010 + 0.3459688127 + 0.3475267887 + 0.3490850031 + 0.3506405950 + 0.3521885872 + 0.3537277877 + 0.3552600145 + 0.3567726910 + 0.3582783937 + 0.3597534001 + 0.3612213135 + 0.3626750112 + 0.3641248941 + 0.3655717969 + 0.3670117855 + 0.3684495986 + 0.3698936105 + 0.3713377118 + 0.3727797866 + 0.3742178977 + 0.3756431937 + 0.3770616055 + 0.3784677088 + 0.3798623085 + 0.3812437057 + 0.3826156855 + 0.3839798868 + 0.3853352964 + 0.3866848946 + 0.3880395889 + 0.3893971145 + 0.3907648027 + 0.3921375871 + 0.3935118020 + 0.3948867023 + 0.3962557912 + 0.3976216912 + 0.3989877999 + 0.4003542066 + 0.4017100036 + 0.4030559957 + 0.4043887854 + 0.4057038128 + 0.4070141017 + 0.4083139896 + 0.4096128941 + 0.4109064043 + 0.4121997952 + 0.4134868085 + 0.4147739112 + 0.4160555899 + 0.4173362851 + 0.4186184108 + 0.4199014008 + 0.4211877882 + 0.4224792123 + 0.4237694144 + 0.4250515997 + 0.4263338149 + 0.4276081026 + 0.4288811088 + 0.4301379919 + 0.4313819110 + 0.4326207042 + 0.4338417947 + 0.4350628853 + 0.4362733960 + 0.4374822080 + 0.4386931062 + 0.4399060011 + 0.4411188960 + 0.4423305988 + 0.4435423911 + 0.4447481036 + 0.4459505081 + 0.4471527040 + 0.4483538866 + 0.4495550990 + 0.4507592022 + 0.4519644976 + 0.4531674981 + 0.4543609023 + 0.4555541873 + 0.4567396045 + 0.4579207897 + 0.4591009021 + 0.4602701068 + 0.4614393115 + 0.4626025856 + 0.4637596905 + 0.4649167955 + 0.4660637975 + 0.4672091901 + 0.4683555067 + 0.4695048034 + 0.4706541896 + 0.4718030095 + 0.4729512036 + 0.4740993977 + 0.4752402902 + 0.4763796926 + 0.4775182903 + 0.4786491096 + 0.4797798991 + 0.4809078872 + 0.4820297956 + 0.4831517935 + 0.4842692018 + 0.4853824079 + 0.4864956141 + 0.4876025915 + 0.4887068868 + 0.4898110926 + 0.4909138083 + 0.4920162857 + 0.4931187034 + 0.4942246974 + 0.4953309894 + 0.4964371026 + 0.4975334108 + 0.4986295998 + 0.4997260869 + 0.5008261800 + 0.5019261837 + 0.5030261278 + 0.5041244030 + 0.5052226782 + 0.5063204765 + 0.5074101090 + 0.5084996819 + 0.5095893145 + 0.5106704831 + 0.5117517710 + 0.5128329992 + 0.5139064789 + 0.5149794221 + 0.5160521865 + 0.5171185732 + 0.5181834102 + 0.5192481875 + 0.5203077197 + 0.5213642716 + 0.5224208832 + 0.5234770179 + 0.5245326161 + 0.5255880952 + 0.5266445875 + 0.5277037024 + 0.5287628174 + 0.5298218727 + 0.5308706760 + 0.5319193006 + 0.5329679847 + 0.5340090990 + 0.5350469947 + 0.5360848904 + 0.5371162891 + 0.5381368995 + 0.5391575098 + 0.5401778221 + 0.5411760211 + 0.5421741009 + 0.5431722999 + 0.5441654921 + 0.5451557040 + 0.5461459160 + 0.5471357107 + 0.5481235981 + 0.5491116047 + 0.5500994921 + 0.5510740876 + 0.5520431995 + 0.5530123115 + 0.5539786220 + 0.5549340248 + 0.5558893085 + 0.5568445921 + 0.5578002930 + 0.5587561727 + 0.5597121119 + 0.5606679916 + 0.5616241097 + 0.5625802875 + 0.5635365248 + 0.5644925237 + 0.5654482245 + 0.5664039850 + 0.5673596859 + 0.5683150887 + 0.5692703724 + 0.5702255964 + 0.5711804032 + 0.5721278787 + 0.5730754733 + 0.5740230083 + 0.5749645829 + 0.5758937001 + 0.5768228769 + 0.5777519941 + 0.5786722898 + 0.5795848966 + 0.5804976225 + 0.5814102888 + 0.5823227167 + 0.5832350850 + 0.5841473937 + 0.5850597024 + 0.5859693885 + 0.5868784785 + 0.5877876878 + 0.5886967778 + 0.5896003246 + 0.5905032754 + 0.5914062858 + 0.5923094153 + 0.5932080746 + 0.5941067934 + 0.5950053930 + 0.5959041119 + 0.5967944860 + 0.5976848006 + 0.5985751748 + 0.5994654894 + 0.6003587246 + 0.6012520790 + 0.6021453738 + 0.6030387282 + 0.6039313078 + 0.6048238277 + 0.6057162285 + 0.6066086888 + 0.6074911952 + 0.6083701849 + 0.6092491746 + 0.6101281047 + 0.6109964848 + 0.6118568778 + 0.6127172112 + 0.6135776043 + 0.6144360900 + 0.6152914166 + 0.6161466241 + 0.6170017719 + 0.6178573966 + 0.6187161803 + 0.6195750237 + 0.6204338074 + 0.6212925911 + 0.6221556067 + 0.6230198741 + 0.6238840818 + 0.6247482896 + 0.6256136894 + 0.6264808178 + 0.6273478866 + 0.6282148957 + 0.6290820241 + 0.6299490929 + 0.6308162212 + 0.6316832900 + 0.6325504780 + 0.6334146857 + 0.6342768073 + 0.6351389885 + 0.6360011101 + 0.6368619800 + 0.6377084851 + 0.6385549903 + 0.6394014955 + 0.6402480006 + 0.6410933137 + 0.6419374943 + 0.6427816749 + 0.6436259747 + 0.6444702148 + 0.6453065276 + 0.6461421847 + 0.6469779015 + 0.6478136182 + 0.6486436725 + 0.6494596004 + 0.6502755880 + 0.6510915160 + 0.6519075036 + 0.6527132988 + 0.6535121202 + 0.6543108821 + 0.6551098228 + 0.6559085846 + 0.6566948891 + 0.6574789286 + 0.6582627892 + 0.6590468287 + 0.6598308086 + 0.6606147885 + 0.6613988280 + 0.6621828079 + 0.6629667878 + 0.6637505293 + 0.6645327210 + 0.6653149128 + 0.6660971045 + 0.6668794155 + 0.6676582098 + 0.6684288979 + 0.6691997051 + 0.6699703932 + 0.6707410812 + 0.6715074182 + 0.6722648144 + 0.6730222106 + 0.6737796068 + 0.6745370030 + 0.6752945185 + 0.6760522127 + 0.6768100262 + 0.6775677204 + 0.6783254743 + 0.6790840030 + 0.6798446774 + 0.6806052923 + 0.6813660264 + 0.6821267009 + 0.6828873158 + 0.6836469769 + 0.6844068170 + 0.6851665974 + 0.6859263182 + 0.6866860986 + 0.6874372959 + 0.6881881952 + 0.6889392138 + 0.6896901131 + 0.6904410124 + 0.6911798120 + 0.6919142008 + 0.6926484704 + 0.6933829188 + 0.6941173077 + 0.6948506236 + 0.6955826283 + 0.6963145733 + 0.6970465183 + 0.6977785230 + 0.6985105276 + 0.6992424726 + 0.6999745965 + 0.7007066011 + 0.7014386058 + 0.7021707296 + 0.7028998137 + 0.7036275864 + 0.7043554187 + 0.7050831914 + 0.7058110237 + 0.7065402269 + 0.7072740197 + 0.7080078125 + 0.7087416053 + 0.7094753981 + 0.7102091908 + 0.7109380960 + 0.7116650939 + 0.7123920918 + 0.7131190896 + 0.7138460875 + 0.7145711780 + 0.7152836919 + 0.7159962058 + 0.7167087197 + 0.7174212933 + 0.7181338072 + 0.7188457847 + 0.7195572257 + 0.7202687263 + 0.7209801078 + 0.7216914892 + 0.7224029899 + 0.7231106758 + 0.7238175273 + 0.7245242000 + 0.7252308726 + 0.7259377241 + 0.7266442180 + 0.7273383141 + 0.7280324101 + 0.7287266254 + 0.7294207215 + 0.7301148772 + 0.7308074832 + 0.7314937115 + 0.7321799994 + 0.7328662276 + 0.7335523963 + 0.7342386246 + 0.7349203229 + 0.7355914712 + 0.7362626791 + 0.7369338870 + 0.7376050949 + 0.7382763028 + 0.7389466763 + 0.7396153808 + 0.7402840853 + 0.7409527898 + 0.7416214943 + 0.7422903180 + 0.7429624796 + 0.7436416745 + 0.7443209887 + 0.7450001836 + 0.7456793785 + 0.7463586926 + 0.7470390201 + 0.7477223873 + 0.7484058738 + 0.7490894198 + 0.7497729063 + 0.7504563928 + 0.7511395812 + 0.7518200874 + 0.7525004745 + 0.7531809807 + 0.7538614273 + 0.7545418739 + 0.7552223802 + 0.7558920979 + 0.7565605044 + 0.7572287917 + 0.7578970790 + 0.7585654855 + 0.7592337728 + 0.7598943114 + 0.7605494261 + 0.7612044811 + 0.7618595958 + 0.7625148296 + 0.7631698847 + 0.7638273835 + 0.7644920945 + 0.7651568055 + 0.7658215165 + 0.7664862275 + 0.7671508193 + 0.7678154707 + 0.7684820890 + 0.7691490054 + 0.7698159814 + 0.7704828978 + 0.7711498737 + 0.7718167901 + 0.7724804878 + 0.7731373906 + 0.7737944126 + 0.7744513750 + 0.7751083970 + 0.7757654190 + 0.7764223814 + 0.7770789862 + 0.7777354121 + 0.7783918977 + 0.7790483832 + 0.7797049284 + 0.7803612947 + 0.7810173035 + 0.7816702127 + 0.7823230028 + 0.7829759121 + 0.7836287022 + 0.7842816114 + 0.7849345207 + 0.7855864167 + 0.7862372994 + 0.7868881822 + 0.7875390053 + 0.7881898880 + 0.7888407707 + 0.7894915938 + 0.7901493907 + 0.7908108234 + 0.7914720774 + 0.7921335101 + 0.7927948833 + 0.7934563160 + 0.7941176295 + 0.7947735190 + 0.7954280972 + 0.7960826755 + 0.7967371941 + 0.7973917723 + 0.7980462909 + 0.7987009287 + 0.7993466258 + 0.7999910712 + 0.8006355762 + 0.8012802005 + 0.8019247055 + 0.8025692105 + 0.8032137156 + 0.8038467169 + 0.8044781089 + 0.8051096201 + 0.8057410121 + 0.8063725233 + 0.8070039153 + 0.8076354265 + 0.8082551956 + 0.8088722229 + 0.8094893098 + 0.8101062775 + 0.8107234240 + 0.8113403916 + 0.8119574785 + 0.8125758171 + 0.8131948113 + 0.8138139248 + 0.8144329190 + 0.8150519133 + 0.8156709075 + 0.8162900209 + 0.8169054985 + 0.8175162077 + 0.8181269169 + 0.8187375069 + 0.8193482161 + 0.8199589252 + 0.8205695748 + 0.8211792707 + 0.8217806220 + 0.8223819733 + 0.8229833841 + 0.8235847950 + 0.8241862059 + 0.8247876167 + 0.8253890276 + 0.8259866834 + 0.8265830278 + 0.8271793127 + 0.8277755976 + 0.8283720016 + 0.8289682865 + 0.8295645714 + 0.8301581144 + 0.8307436705 + 0.8313292861 + 0.8319149017 + 0.8325005174 + 0.8330860734 + 0.8336716890 + 0.8342573047 + 0.8348429799 + 0.8354287148 + 0.8360143900 + 0.8366001844 + 0.8371859193 + 0.8377715945 + 0.8383573294 + 0.8389438987 + 0.8395407200 + 0.8401374817 + 0.8407343030 + 0.8413311243 + 0.8419278860 + 0.8425247073 + 0.8431215286 + 0.8437163830 + 0.8443077803 + 0.8448992968 + 0.8454906940 + 0.8460822105 + 0.8466736078 + 0.8472651243 + 0.8478565216 + 0.8484436274 + 0.8490272760 + 0.8496111035 + 0.8501948714 + 0.8507785797 + 0.8513624072 + 0.8519461155 + 0.8525298834 + 0.8531131744 + 0.8536962271 + 0.8542792201 + 0.8548622131 + 0.8554453254 + 0.8560283184 + 0.8566113114 + 0.8571943045 + 0.8577736020 + 0.8583512902 + 0.8589290977 + 0.8595069051 + 0.8600847125 + 0.8606625199 + 0.8612403274 + 0.8618180752 + 0.8624026775 + 0.8629906178 + 0.8635786176 + 0.8641664982 + 0.8647544980 + 0.8653423786 + 0.8659303784 + 0.8665183187 + 0.8671081066 + 0.8676996231 + 0.8682910800 + 0.8688824773 + 0.8694739938 + 0.8700655103 + 0.8706569076 + 0.8712484241 + 0.8718379140 + 0.8724226952 + 0.8730074763 + 0.8735923171 + 0.8741770983 + 0.8747618794 + 0.8753467202 + 0.8759315014 + 0.8765162826 + 0.8770982027 + 0.8776800036 + 0.8782619238 + 0.8788437843 + 0.8794255853 + 0.8800075054 + 0.8805894256 + 0.8811712265 + 0.8817477226 + 0.8823202848 + 0.8828929067 + 0.8834654093 + 0.8840379715 + 0.8846104741 + 0.8851830959 + 0.8857555985 + 0.8863282800 + 0.8869022727 + 0.8874762058 + 0.8880501986 + 0.8886241913 + 0.8891981244 + 0.8897721171 + 0.8903459907 + 0.8909199834 + 0.8914952874 + 0.8920720220 + 0.8926486969 + 0.8932253718 + 0.8938022256 + 0.8943789005 + 0.8949555755 + 0.8955323100 + 0.8961089849 + 0.8966785073 + 0.8972461224 + 0.8978137970 + 0.8983814716 + 0.8989492059 + 0.8995168209 + 0.9000844955 + 0.9006522298 + 0.9012197256 + 0.9017801881 + 0.9023407102 + 0.9029011726 + 0.9034616947 + 0.9040222168 + 0.9045826793 + 0.9051432014 + 0.9057037234 + 0.9062626958 + 0.9068132043 + 0.9073637128 + 0.9079142213 + 0.9084647894 + 0.9090152979 + 0.9095658064 + 0.9101163149 + 0.9106668234 + 0.9112154245 + 0.9117550254 + 0.9122946858 + 0.9128342867 + 0.9133738875 + 0.9139136076 + 0.9144532084 + 0.9149928093 + 0.9155325294 + 0.9160724878 + 0.9166154861 + 0.9171584845 + 0.9177014828 + 0.9182446003 + 0.9187875986 + 0.9193305969 + 0.9198735952 + 0.9204165936 + 0.9209595919 + 0.9214972854 + 0.9220345020 + 0.9225717783 + 0.9231091142 + 0.9236463904 + 0.9241837263 + 0.9247208834 + 0.9252582192 + 0.9257954955 + 0.9263281822 + 0.9268587828 + 0.9273893833 + 0.9279199839 + 0.9284505248 + 0.9289811254 + 0.9295117259 + 0.9300423265 + 0.9305728078 + 0.9311010838 + 0.9316242933 + 0.9321475029 + 0.9326707125 + 0.9331939220 + 0.9337170720 + 0.9342402816 + 0.9347636104 + 0.9352868199 + 0.9358100295 + 0.9363203049 + 0.9368283749 + 0.9373363853 + 0.9378443956 + 0.9383524060 + 0.9388604164 + 0.9393684268 + 0.9398764968 + 0.9403845072 + 0.9408923984 + 0.9413998723 + 0.9419075251 + 0.9424151182 + 0.9429225922 + 0.9434301853 + 0.9439377785 + 0.9444453120 + 0.9449529052 + 0.9454603791 + 0.9459722042 + 0.9464867711 + 0.9470013976 + 0.9475159049 + 0.9480304718 + 0.9485449791 + 0.9490596056 + 0.9495741725 + 0.9500886798 + 0.9506033063 + 0.9511142969 + 0.9516245127 + 0.9521347880 + 0.9526450038 + 0.9531552196 + 0.9536654949 + 0.9541757107 + 0.9546859264 + 0.9551960826 + 0.9557064176 + 0.9562019110 + 0.9566963911 + 0.9571908712 + 0.9576854110 + 0.9581798911 + 0.9586743712 + 0.9591689110 + 0.9596635103 + 0.9601579905 + 0.9606524706 + 0.9611294270 + 0.9616053104 + 0.9620811939 + 0.9625570774 + 0.9630330205 + 0.9635089040 + 0.9639847875 + 0.9644606709 + 0.9649366140 + 0.9654123783 + 0.9658750892 + 0.9663354158 + 0.9667956829 + 0.9672560096 + 0.9677162170 + 0.9681764841 + 0.9686368108 + 0.9690970778 + 0.9695574045 + 0.9700176120 + 0.9704771042 + 0.9709361196 + 0.9713950753 + 0.9718540907 + 0.9723131061 + 0.9727721214 + 0.9732310772 + 0.9736900926 + 0.9741491079 + 0.9746081829 + 0.9750655293 + 0.9755191803 + 0.9759730101 + 0.9764267206 + 0.9768803716 + 0.9773342013 + 0.9777879119 + 0.9782416821 + 0.9786953926 + 0.9791491032 + 0.9796028733 + 0.9800477028 + 0.9804913998 + 0.9809350967 + 0.9813787937 + 0.9818224907 + 0.9822661877 + 0.9827098846 + 0.9831535816 + 0.9835972786 + 0.9840409756 + 0.9844785929 + 0.9849042296 + 0.9853296876 + 0.9857553244 + 0.9861809015 + 0.9866064787 + 0.9870321155 + 0.9874576926 + 0.9878833294 + 0.9883089066 + 0.9887344837 + 0.9891439080 + 0.9895455837 + 0.9899473190 + 0.9903489947 + 0.9907506704 + 0.9911524057 + 0.9915542006 + 0.9919558764 + 0.9923576117 + 0.9927592874 + 0.9931610227 + 0.9935230017 + 0.9938808084 + 0.9942384958 + 0.9945963025 + 0.9949539900 + 0.9953116775 + 0.9956694841 + 0.9960271716 + 0.9963849783 + 0.9967427254 + 0.9970995188 + 0.9973632097 + 0.9976267815 + 0.9978904724 + 0.9981542230 + 0.9984179139 + 0.9986816049 + 0.9989452958 + 0.9992089272 + 0.9994726181 + 0.9997363091 + 1.0000000000 +} diff --git a/rpplugins/color_correction/resources/film_luts_raw/eastman_double_x_neg_5min.spi1d b/rpplugins/color_correction/resources/film_luts_raw/eastman_double_x_neg_5min.spi1d new file mode 100644 index 0000000..d199eba --- /dev/null +++ b/rpplugins/color_correction/resources/film_luts_raw/eastman_double_x_neg_5min.spi1d @@ -0,0 +1,1030 @@ +Version 1 +From 0.0 1.0 +Length 1024 +Components 1 +{ + 0.0000000000 + 0.0030272121 + 0.0063094199 + 0.0098175881 + 0.0132390903 + 0.0165068507 + 0.0197617300 + 0.0230012909 + 0.0261860900 + 0.0293740109 + 0.0325979404 + 0.0358636007 + 0.0391314887 + 0.0424252301 + 0.0457398184 + 0.0491124503 + 0.0525345095 + 0.0558606908 + 0.0591593795 + 0.0623592213 + 0.0656063929 + 0.0688082799 + 0.0719619915 + 0.0750681385 + 0.0781241581 + 0.0811320320 + 0.0840930864 + 0.0869851932 + 0.0898269489 + 0.0926580206 + 0.0954112411 + 0.0981268808 + 0.1008647010 + 0.1035747007 + 0.1062444001 + 0.1088567972 + 0.1114612967 + 0.1140118018 + 0.1165103987 + 0.1189728975 + 0.1214018017 + 0.1238031015 + 0.1261426061 + 0.1285005063 + 0.1308861971 + 0.1332633942 + 0.1356558949 + 0.1380044073 + 0.1403446943 + 0.1426548958 + 0.1449654996 + 0.1472640932 + 0.1495569050 + 0.1518307030 + 0.1540544927 + 0.1562412977 + 0.1584434956 + 0.1606242061 + 0.1627897024 + 0.1649412066 + 0.1670477986 + 0.1691658944 + 0.1713186055 + 0.1734748930 + 0.1756159067 + 0.1777509004 + 0.1798588932 + 0.1819704026 + 0.1841046959 + 0.1862291992 + 0.1883134991 + 0.1904103011 + 0.1924743056 + 0.1944988072 + 0.1965171993 + 0.1985401064 + 0.2005351931 + 0.2025036067 + 0.2044758946 + 0.2064372003 + 0.2083602995 + 0.2102862000 + 0.2122135013 + 0.2141225934 + 0.2159958929 + 0.2178680003 + 0.2197511047 + 0.2216199934 + 0.2234732956 + 0.2253248990 + 0.2271879017 + 0.2290568948 + 0.2309205979 + 0.2327875942 + 0.2346781045 + 0.2365760058 + 0.2384558022 + 0.2403216064 + 0.2421821058 + 0.2440275997 + 0.2458492070 + 0.2476378977 + 0.2494101971 + 0.2511883080 + 0.2529624104 + 0.2547251880 + 0.2564688921 + 0.2581931055 + 0.2599115074 + 0.2616336942 + 0.2633337080 + 0.2650091052 + 0.2666670084 + 0.2683193982 + 0.2699855864 + 0.2716380954 + 0.2732735872 + 0.2748895884 + 0.2764844894 + 0.2780745029 + 0.2796624005 + 0.2812372148 + 0.2827902138 + 0.2843335867 + 0.2858856916 + 0.2874445021 + 0.2890088856 + 0.2905732989 + 0.2921339869 + 0.2936922908 + 0.2952659130 + 0.2968513072 + 0.2984412909 + 0.3000228107 + 0.3015750945 + 0.3031128943 + 0.3046396971 + 0.3061710894 + 0.3077040017 + 0.3092370927 + 0.3107506931 + 0.3122516870 + 0.3137294054 + 0.3152104020 + 0.3166939020 + 0.3181836009 + 0.3196648061 + 0.3211343884 + 0.3225882053 + 0.3240387142 + 0.3254922032 + 0.3269436955 + 0.3283936083 + 0.3298347890 + 0.3312718868 + 0.3326953948 + 0.3341206014 + 0.3355478048 + 0.3369952142 + 0.3384498060 + 0.3399038017 + 0.3413537145 + 0.3427903950 + 0.3442232013 + 0.3456513882 + 0.3470813930 + 0.3485122919 + 0.3499529958 + 0.3513954878 + 0.3528392911 + 0.3542819917 + 0.3557189107 + 0.3571557105 + 0.3585920930 + 0.3600325882 + 0.3614800870 + 0.3629246950 + 0.3643657863 + 0.3657987118 + 0.3672237992 + 0.3686499894 + 0.3700770140 + 0.3714995086 + 0.3729186952 + 0.3743284941 + 0.3757312894 + 0.3771198094 + 0.3784962893 + 0.3798680007 + 0.3812347949 + 0.3826048970 + 0.3839792907 + 0.3853527904 + 0.3867248893 + 0.3880946934 + 0.3894568980 + 0.3908174038 + 0.3921599090 + 0.3935025036 + 0.3948425949 + 0.3961825073 + 0.3975262940 + 0.3988716006 + 0.4002110064 + 0.4015452862 + 0.4028792977 + 0.4042125046 + 0.4055452049 + 0.4068675935 + 0.4081901014 + 0.4095175862 + 0.4108465910 + 0.4121741951 + 0.4135001898 + 0.4148246050 + 0.4161387980 + 0.4174529910 + 0.4187706113 + 0.4200890958 + 0.4214057028 + 0.4227195084 + 0.4240333140 + 0.4253349006 + 0.4266364872 + 0.4279260933 + 0.4292064011 + 0.4304861128 + 0.4317606986 + 0.4330351949 + 0.4343157113 + 0.4355998933 + 0.4368841946 + 0.4381690919 + 0.4394541085 + 0.4407306015 + 0.4420005977 + 0.4432705939 + 0.4445107877 + 0.4457508922 + 0.4469895065 + 0.4482258856 + 0.4494622052 + 0.4506838918 + 0.4519014955 + 0.4531166852 + 0.4543156028 + 0.4555146098 + 0.4567095041 + 0.4578996897 + 0.4590897858 + 0.4602785110 + 0.4614667892 + 0.4626550078 + 0.4638502896 + 0.4650456905 + 0.4662390947 + 0.4674263895 + 0.4686135948 + 0.4697979987 + 0.4709784091 + 0.4721589088 + 0.4733403027 + 0.4745222926 + 0.4757043123 + 0.4768933952 + 0.4780850112 + 0.4792765081 + 0.4804633856 + 0.4816494882 + 0.4828355014 + 0.4839955866 + 0.4851537943 + 0.4863120019 + 0.4874627888 + 0.4886133969 + 0.4897640944 + 0.4909220040 + 0.4920799136 + 0.4932379127 + 0.4943912029 + 0.4955444932 + 0.4966978133 + 0.4978221059 + 0.4989440143 + 0.5000659823 + 0.5011757016 + 0.5022830963 + 0.5033904910 + 0.5044888854 + 0.5055838823 + 0.5066789985 + 0.5077672005 + 0.5088503957 + 0.5099335909 + 0.5110126734 + 0.5120856166 + 0.5131585002 + 0.5142297745 + 0.5152938962 + 0.5163578987 + 0.5174219012 + 0.5184922814 + 0.5195631981 + 0.5206341147 + 0.5217061043 + 0.5227789283 + 0.5238515735 + 0.5249236822 + 0.5259944201 + 0.5270652175 + 0.5281358957 + 0.5291953087 + 0.5302540064 + 0.5313128233 + 0.5323665738 + 0.5334162712 + 0.5344660282 + 0.5355166197 + 0.5365738273 + 0.5376309752 + 0.5386883020 + 0.5397393703 + 0.5407869816 + 0.5418345928 + 0.5428798199 + 0.5439077020 + 0.5449357033 + 0.5459637046 + 0.5469853878 + 0.5480024219 + 0.5490195155 + 0.5500364900 + 0.5510535836 + 0.5520707965 + 0.5530878901 + 0.5541033745 + 0.5551161170 + 0.5561287999 + 0.5571414828 + 0.5581471920 + 0.5591498017 + 0.5601524115 + 0.5611549020 + 0.5621367097 + 0.5631183982 + 0.5641000271 + 0.5650776029 + 0.5660427809 + 0.5670080781 + 0.5679733753 + 0.5689417124 + 0.5699135065 + 0.5708853006 + 0.5718570948 + 0.5728263855 + 0.5737943053 + 0.5747622252 + 0.5757302046 + 0.5766975880 + 0.5776649117 + 0.5786321759 + 0.5795994997 + 0.5805698037 + 0.5815405250 + 0.5825111270 + 0.5834817886 + 0.5844538808 + 0.5854260921 + 0.5863983035 + 0.5873705745 + 0.5883414149 + 0.5893121958 + 0.5902829766 + 0.5912536979 + 0.5922099948 + 0.5931643248 + 0.5941184759 + 0.5950728059 + 0.5960159898 + 0.5969563723 + 0.5978966951 + 0.5988370776 + 0.5997706056 + 0.6007006764 + 0.6016308069 + 0.6025608182 + 0.6034846902 + 0.6044021845 + 0.6053197980 + 0.6062374115 + 0.6071522832 + 0.6080605984 + 0.6089687943 + 0.6098771095 + 0.6107851863 + 0.6116871238 + 0.6125890017 + 0.6134908795 + 0.6143928170 + 0.6152886152 + 0.6161820889 + 0.6170755029 + 0.6179689765 + 0.6188614964 + 0.6197524071 + 0.6206433773 + 0.6215342879 + 0.6224251986 + 0.6233009100 + 0.6241760254 + 0.6250510812 + 0.6259261966 + 0.6267927885 + 0.6276513934 + 0.6285099983 + 0.6293684840 + 0.6302270889 + 0.6310849786 + 0.6319429278 + 0.6328008175 + 0.6336587071 + 0.6345123053 + 0.6353611946 + 0.6362100244 + 0.6370587945 + 0.6379076838 + 0.6387491822 + 0.6395896077 + 0.6404299736 + 0.6412703991 + 0.6421101093 + 0.6429476142 + 0.6437851191 + 0.6446226835 + 0.6454601884 + 0.6463015079 + 0.6471462250 + 0.6479908824 + 0.6488355994 + 0.6496803164 + 0.6505240798 + 0.6513677835 + 0.6522114873 + 0.6530550718 + 0.6538987756 + 0.6547306180 + 0.6555622816 + 0.6563938856 + 0.6572256088 + 0.6580554843 + 0.6588743925 + 0.6596933007 + 0.6605123281 + 0.6613311768 + 0.6621484160 + 0.6629601717 + 0.6637719870 + 0.6645838022 + 0.6653956175 + 0.6662080288 + 0.6670222878 + 0.6678364873 + 0.6686508060 + 0.6694651246 + 0.6702783108 + 0.6710888147 + 0.6718993187 + 0.6727098227 + 0.6735203266 + 0.6743295789 + 0.6751338840 + 0.6759383082 + 0.6767426133 + 0.6775469780 + 0.6783509851 + 0.6791514158 + 0.6799517870 + 0.6807522774 + 0.6815527081 + 0.6823530793 + 0.6831542850 + 0.6839554906 + 0.6847568154 + 0.6855580211 + 0.6863592863 + 0.6871563792 + 0.6879516244 + 0.6887468100 + 0.6895419955 + 0.6903371215 + 0.6911249757 + 0.6919013262 + 0.6926776171 + 0.6934539080 + 0.6942301989 + 0.6950061917 + 0.6957769990 + 0.6965478063 + 0.6973184943 + 0.6980893016 + 0.6988599896 + 0.6996240020 + 0.7003840208 + 0.7011440992 + 0.7019041181 + 0.7026641965 + 0.7034214735 + 0.7041661143 + 0.7049108148 + 0.7056553960 + 0.7063999772 + 0.7071446776 + 0.7078785896 + 0.7086068988 + 0.7093350887 + 0.7100633979 + 0.7107917070 + 0.7115197182 + 0.7122437954 + 0.7129678726 + 0.7136920094 + 0.7144160867 + 0.7151402235 + 0.7158653140 + 0.7165917754 + 0.7173182964 + 0.7180448174 + 0.7187712789 + 0.7194977999 + 0.7202196121 + 0.7209396958 + 0.7216597199 + 0.7223798037 + 0.7230998874 + 0.7238199711 + 0.7245283127 + 0.7252361774 + 0.7259441018 + 0.7266520858 + 0.7273600101 + 0.7280663252 + 0.7287629247 + 0.7294594049 + 0.7301560044 + 0.7308526039 + 0.7315490842 + 0.7322456241 + 0.7329418063 + 0.7336379886 + 0.7343341708 + 0.7350304127 + 0.7357265949 + 0.7364248037 + 0.7371274829 + 0.7378302813 + 0.7385330200 + 0.7392356992 + 0.7399383783 + 0.7406404018 + 0.7413403988 + 0.7420405149 + 0.7427405119 + 0.7434405088 + 0.7441406250 + 0.7448390722 + 0.7455317974 + 0.7462245226 + 0.7469171882 + 0.7476099133 + 0.7483025789 + 0.7489954233 + 0.7496907115 + 0.7503858805 + 0.7510811090 + 0.7517763972 + 0.7524716258 + 0.7531669140 + 0.7538704872 + 0.7545759082 + 0.7552812099 + 0.7559865713 + 0.7566918731 + 0.7573972940 + 0.7581034899 + 0.7588102818 + 0.7595170736 + 0.7602239251 + 0.7609307170 + 0.7616376281 + 0.7623426914 + 0.7630413175 + 0.7637398839 + 0.7644385099 + 0.7651370764 + 0.7658355832 + 0.7665342093 + 0.7672234178 + 0.7679098845 + 0.7685962915 + 0.7692828178 + 0.7699692845 + 0.7706558108 + 0.7713416219 + 0.7720258832 + 0.7727100849 + 0.7733944058 + 0.7740787268 + 0.7747629285 + 0.7754471898 + 0.7761262059 + 0.7768033743 + 0.7774804831 + 0.7781575918 + 0.7788347006 + 0.7795119286 + 0.7801874876 + 0.7808486819 + 0.7815099955 + 0.7821711898 + 0.7828325033 + 0.7834938169 + 0.7841550112 + 0.7848129869 + 0.7854657769 + 0.7861186266 + 0.7867714167 + 0.7874242067 + 0.7880769968 + 0.7887297869 + 0.7893806100 + 0.7900301814 + 0.7906798124 + 0.7913293839 + 0.7919788957 + 0.7926285267 + 0.7932780981 + 0.7939221859 + 0.7945647836 + 0.7952073216 + 0.7958499193 + 0.7964923978 + 0.7971348763 + 0.7977774739 + 0.7984188199 + 0.7990599275 + 0.7997009754 + 0.8003420234 + 0.8009830713 + 0.8016241789 + 0.8022652864 + 0.8028982282 + 0.8035295010 + 0.8041607738 + 0.8047922254 + 0.8054234982 + 0.8060547709 + 0.8066862226 + 0.8073112965 + 0.8079345822 + 0.8085579276 + 0.8091812134 + 0.8098044991 + 0.8104277253 + 0.8110510111 + 0.8116706014 + 0.8122878075 + 0.8129050136 + 0.8135222197 + 0.8141394854 + 0.8147566915 + 0.8153738976 + 0.8159893751 + 0.8166022897 + 0.8172150850 + 0.8178278804 + 0.8184407949 + 0.8190535903 + 0.8196663857 + 0.8202791214 + 0.8208892941 + 0.8214995861 + 0.8221098781 + 0.8227202296 + 0.8233304024 + 0.8239406943 + 0.8245509863 + 0.8251606226 + 0.8257699013 + 0.8263791800 + 0.8269885182 + 0.8275977969 + 0.8282071948 + 0.8288164735 + 0.8294249773 + 0.8300309777 + 0.8306369781 + 0.8312429786 + 0.8318489790 + 0.8324549794 + 0.8330609798 + 0.8336669207 + 0.8342692852 + 0.8348699808 + 0.8354706764 + 0.8360713720 + 0.8366721272 + 0.8372727036 + 0.8378733993 + 0.8384736776 + 0.8390662074 + 0.8396586180 + 0.8402510881 + 0.8408436179 + 0.8414360881 + 0.8420284986 + 0.8426210284 + 0.8432112932 + 0.8437972069 + 0.8443831801 + 0.8449690938 + 0.8455551267 + 0.8461410999 + 0.8467270136 + 0.8473129869 + 0.8479040265 + 0.8484994769 + 0.8490949273 + 0.8496903181 + 0.8502858281 + 0.8508812189 + 0.8514766097 + 0.8520721197 + 0.8526653051 + 0.8532572985 + 0.8538494110 + 0.8544414043 + 0.8550335169 + 0.8556255102 + 0.8562176228 + 0.8568096161 + 0.8573905230 + 0.8579664230 + 0.8585423827 + 0.8591184020 + 0.8596943021 + 0.8602703214 + 0.8608462811 + 0.8614221811 + 0.8619980216 + 0.8625736833 + 0.8631494045 + 0.8637250066 + 0.8643007278 + 0.8648763895 + 0.8654521108 + 0.8660277128 + 0.8666040897 + 0.8671810031 + 0.8677579761 + 0.8683350086 + 0.8689119220 + 0.8694888949 + 0.8700659275 + 0.8706427813 + 0.8712193966 + 0.8717948198 + 0.8723701835 + 0.8729457259 + 0.8735210896 + 0.8740965128 + 0.8746719956 + 0.8752474189 + 0.8758227825 + 0.8763949871 + 0.8769670129 + 0.8775389791 + 0.8781110048 + 0.8786829710 + 0.8792549968 + 0.8798270226 + 0.8803989887 + 0.8809679747 + 0.8815342784 + 0.8821007013 + 0.8826671243 + 0.8832334876 + 0.8837999105 + 0.8843662143 + 0.8849325776 + 0.8854988217 + 0.8860610127 + 0.8866233230 + 0.8871855140 + 0.8877478242 + 0.8883100748 + 0.8888723254 + 0.8894345760 + 0.8899968266 + 0.8905580044 + 0.8911178112 + 0.8916776180 + 0.8922374249 + 0.8927971721 + 0.8933569789 + 0.8939167857 + 0.8944765925 + 0.8950363994 + 0.8955954909 + 0.8961544037 + 0.8967131972 + 0.8972721100 + 0.8978309035 + 0.8983898163 + 0.8989487290 + 0.8995075226 + 0.9000663757 + 0.9006261230 + 0.9011856914 + 0.9017453790 + 0.9023050070 + 0.9028646946 + 0.9034243226 + 0.9039840102 + 0.9045435786 + 0.9051036239 + 0.9056655169 + 0.9062274098 + 0.9067893028 + 0.9073511958 + 0.9079130888 + 0.9084749818 + 0.9090368748 + 0.9095988274 + 0.9101592898 + 0.9107123017 + 0.9112653136 + 0.9118183255 + 0.9123712182 + 0.9129241705 + 0.9134771824 + 0.9140301943 + 0.9145832062 + 0.9151350856 + 0.9156765938 + 0.9162181020 + 0.9167596102 + 0.9173009992 + 0.9178425074 + 0.9183840156 + 0.9189255238 + 0.9194669724 + 0.9200084805 + 0.9205374122 + 0.9210653901 + 0.9215933084 + 0.9221212864 + 0.9226492047 + 0.9231771827 + 0.9237051010 + 0.9242330790 + 0.9247609973 + 0.9252843857 + 0.9258053899 + 0.9263263941 + 0.9268475175 + 0.9273685217 + 0.9278895855 + 0.9284105897 + 0.9289315939 + 0.9294527173 + 0.9299737811 + 0.9304950833 + 0.9310163260 + 0.9315376282 + 0.9320588708 + 0.9325801730 + 0.9331014752 + 0.9336227179 + 0.9341440201 + 0.9346653223 + 0.9351785183 + 0.9356899858 + 0.9362015128 + 0.9367129803 + 0.9372245073 + 0.9377359748 + 0.9382475019 + 0.9387590289 + 0.9392704964 + 0.9397779703 + 0.9402741790 + 0.9407703876 + 0.9412665963 + 0.9417628050 + 0.9422590733 + 0.9427552819 + 0.9432514906 + 0.9437476993 + 0.9442439079 + 0.9447419047 + 0.9452412128 + 0.9457404017 + 0.9462395906 + 0.9467388988 + 0.9472380877 + 0.9477373958 + 0.9482365847 + 0.9487358928 + 0.9492350817 + 0.9497361183 + 0.9502375722 + 0.9507390261 + 0.9512404203 + 0.9517418742 + 0.9522433281 + 0.9527447820 + 0.9532461762 + 0.9537475705 + 0.9542490840 + 0.9547458887 + 0.9552422762 + 0.9557387233 + 0.9562351704 + 0.9567316175 + 0.9572281241 + 0.9577245116 + 0.9582208991 + 0.9587174058 + 0.9592137933 + 0.9596955180 + 0.9601761103 + 0.9606567025 + 0.9611372948 + 0.9616180062 + 0.9620985985 + 0.9625791907 + 0.9630599022 + 0.9635404944 + 0.9640210867 + 0.9644860029 + 0.9649478793 + 0.9654096961 + 0.9658715725 + 0.9663333893 + 0.9667953253 + 0.9672570825 + 0.9677190185 + 0.9681807756 + 0.9686427116 + 0.9691007733 + 0.9695566893 + 0.9700127244 + 0.9704685807 + 0.9709244967 + 0.9713804722 + 0.9718363881 + 0.9722923040 + 0.9727482200 + 0.9732041955 + 0.9736583829 + 0.9741089940 + 0.9745596051 + 0.9750102162 + 0.9754608274 + 0.9759113789 + 0.9763619900 + 0.9768124819 + 0.9772630930 + 0.9777137041 + 0.9781643152 + 0.9786108732 + 0.9790568948 + 0.9795029163 + 0.9799489975 + 0.9803950191 + 0.9808409810 + 0.9812871218 + 0.9817330837 + 0.9821791053 + 0.9826251268 + 0.9830691218 + 0.9835088253 + 0.9839485288 + 0.9843881726 + 0.9848278761 + 0.9852675796 + 0.9857072830 + 0.9861469865 + 0.9865866899 + 0.9870265126 + 0.9874662161 + 0.9878935218 + 0.9883149266 + 0.9887362719 + 0.9891576767 + 0.9895790815 + 0.9900006056 + 0.9904220104 + 0.9908434153 + 0.9912648201 + 0.9916862249 + 0.9921076298 + 0.9924955964 + 0.9928798079 + 0.9932640791 + 0.9936484098 + 0.9940326810 + 0.9944170117 + 0.9948012233 + 0.9951854944 + 0.9955698252 + 0.9959540963 + 0.9963378906 + 0.9966707826 + 0.9970036745 + 0.9973366857 + 0.9976695776 + 0.9980025291 + 0.9983354211 + 0.9986683130 + 0.9990012050 + 0.9993342161 + 0.9996671081 + 1.0000000000 +} diff --git a/rpplugins/color_correction/resources/film_luts_raw/eastman_double_x_neg_6min.spi1d b/rpplugins/color_correction/resources/film_luts_raw/eastman_double_x_neg_6min.spi1d new file mode 100644 index 0000000..1eb8066 --- /dev/null +++ b/rpplugins/color_correction/resources/film_luts_raw/eastman_double_x_neg_6min.spi1d @@ -0,0 +1,1030 @@ +Version 1 +From 0.0 1.0 +Length 1024 +Components 1 +{ + 0.0000000000 + 0.0022076759 + 0.0048505990 + 0.0077307681 + 0.0106430203 + 0.0134941395 + 0.0164271407 + 0.0193642899 + 0.0222814996 + 0.0253338106 + 0.0283298604 + 0.0312295891 + 0.0340677910 + 0.0368127897 + 0.0395192690 + 0.0422245711 + 0.0448633991 + 0.0473990701 + 0.0498608798 + 0.0522968508 + 0.0547638610 + 0.0572266914 + 0.0596168712 + 0.0619427115 + 0.0641859174 + 0.0663840473 + 0.0685592070 + 0.0707125664 + 0.0728932172 + 0.0750729963 + 0.0772423595 + 0.0793742388 + 0.0814804435 + 0.0835459232 + 0.0855793729 + 0.0876187608 + 0.0896756127 + 0.0917201489 + 0.0937488973 + 0.0957670510 + 0.0977691785 + 0.0997611210 + 0.1017474979 + 0.1037304029 + 0.1057140008 + 0.1076987982 + 0.1096796989 + 0.1116433963 + 0.1136050969 + 0.1155518964 + 0.1174954027 + 0.1194273010 + 0.1213321984 + 0.1232244000 + 0.1250977069 + 0.1269564033 + 0.1288059056 + 0.1306264997 + 0.1324591935 + 0.1342981011 + 0.1361421049 + 0.1379898936 + 0.1398337930 + 0.1416724026 + 0.1435085982 + 0.1453595012 + 0.1472201943 + 0.1490903944 + 0.1509464979 + 0.1527885944 + 0.1546380967 + 0.1564874053 + 0.1583337933 + 0.1601832062 + 0.1620080024 + 0.1638301015 + 0.1656454057 + 0.1674109995 + 0.1691544950 + 0.1708903015 + 0.1726087034 + 0.1743192971 + 0.1760134995 + 0.1776891053 + 0.1793549061 + 0.1810144931 + 0.1826763004 + 0.1843471974 + 0.1860086024 + 0.1876676977 + 0.1893319935 + 0.1910057068 + 0.1926884055 + 0.1943672001 + 0.1960387975 + 0.1977010965 + 0.1993733943 + 0.2010557055 + 0.2027229965 + 0.2043714970 + 0.2060067058 + 0.2076272964 + 0.2092293054 + 0.2108173966 + 0.2123903036 + 0.2139514983 + 0.2155003995 + 0.2170374990 + 0.2185630947 + 0.2200783044 + 0.2215853930 + 0.2230909020 + 0.2245920002 + 0.2260849029 + 0.2275708020 + 0.2290592045 + 0.2305610031 + 0.2320587039 + 0.2335456014 + 0.2350171953 + 0.2364920974 + 0.2379685044 + 0.2394436002 + 0.2409150004 + 0.2423750013 + 0.2438220978 + 0.2452608943 + 0.2466982007 + 0.2481335998 + 0.2495692968 + 0.2510060966 + 0.2524541020 + 0.2539057136 + 0.2553601861 + 0.2568137050 + 0.2582660913 + 0.2597176135 + 0.2611657083 + 0.2626079023 + 0.2640449107 + 0.2654654086 + 0.2668786049 + 0.2682839036 + 0.2696810961 + 0.2710821927 + 0.2724924982 + 0.2739025056 + 0.2753120065 + 0.2767190933 + 0.2781172097 + 0.2795062065 + 0.2808851004 + 0.2822608054 + 0.2836303115 + 0.2849979103 + 0.2863635123 + 0.2877384126 + 0.2891165912 + 0.2905051112 + 0.2918922901 + 0.2932763994 + 0.2946614027 + 0.2960470021 + 0.2974393070 + 0.2988334000 + 0.3002207875 + 0.3016053140 + 0.3029761910 + 0.3043459952 + 0.3057133853 + 0.3070785999 + 0.3084413111 + 0.3098073900 + 0.3111760020 + 0.3125430048 + 0.3139094114 + 0.3152734935 + 0.3166370094 + 0.3179858923 + 0.3193317950 + 0.3206684887 + 0.3220038116 + 0.3233413100 + 0.3246791065 + 0.3260106146 + 0.3273411989 + 0.3286638856 + 0.3299851120 + 0.3313086033 + 0.3326326013 + 0.3339475095 + 0.3352591991 + 0.3365674019 + 0.3378736973 + 0.3391835093 + 0.3404963911 + 0.3418085873 + 0.3431195915 + 0.3444280922 + 0.3457283974 + 0.3470287025 + 0.3483307958 + 0.3496328890 + 0.3509300053 + 0.3522259891 + 0.3535211980 + 0.3548158109 + 0.3561145067 + 0.3574211001 + 0.3587279022 + 0.3600377142 + 0.3613474965 + 0.3626418114 + 0.3639313877 + 0.3652200997 + 0.3665077984 + 0.3677951992 + 0.3690789044 + 0.3703626096 + 0.3716369867 + 0.3729074895 + 0.3741776943 + 0.3754476011 + 0.3767175078 + 0.3779971004 + 0.3792783916 + 0.3805550933 + 0.3818249106 + 0.3830947876 + 0.3843517900 + 0.3856075108 + 0.3868649006 + 0.3881247044 + 0.3893845975 + 0.3906409144 + 0.3918966949 + 0.3931471109 + 0.3943845928 + 0.3956221938 + 0.3968513906 + 0.3980770111 + 0.3993020058 + 0.4005202949 + 0.4017386138 + 0.4029510021 + 0.4041553140 + 0.4053595066 + 0.4065566957 + 0.4077515006 + 0.4089460075 + 0.4101307988 + 0.4113157094 + 0.4124985933 + 0.4136764109 + 0.4148542881 + 0.4160273969 + 0.4171960950 + 0.4183647931 + 0.4195275903 + 0.4206880033 + 0.4218483865 + 0.4230014086 + 0.4241535068 + 0.4253054857 + 0.4264521897 + 0.4275988936 + 0.4287458956 + 0.4298943877 + 0.4310429096 + 0.4321908951 + 0.4333373010 + 0.4344835877 + 0.4356265068 + 0.4367592037 + 0.4378919899 + 0.4390229881 + 0.4401493967 + 0.4412758946 + 0.4424026012 + 0.4435302019 + 0.4446578026 + 0.4457832873 + 0.4469003975 + 0.4480175972 + 0.4491330087 + 0.4502356052 + 0.4513381124 + 0.4524405897 + 0.4535480142 + 0.4546554983 + 0.4557628930 + 0.4568733871 + 0.4579845965 + 0.4590956867 + 0.4602054060 + 0.4613144100 + 0.4624234140 + 0.4635319114 + 0.4646396935 + 0.4657475054 + 0.4668546915 + 0.4679591954 + 0.4690637887 + 0.4701682925 + 0.4712668061 + 0.4723646045 + 0.4734624028 + 0.4745511115 + 0.4756326973 + 0.4767143130 + 0.4777936935 + 0.4788640141 + 0.4799341857 + 0.4810045063 + 0.4820767939 + 0.4831495881 + 0.4842225015 + 0.4852963984 + 0.4863724113 + 0.4874483049 + 0.4885242879 + 0.4895890057 + 0.4906522930 + 0.4917156994 + 0.4927777052 + 0.4938377142 + 0.4948976934 + 0.4959576130 + 0.4970098138 + 0.4980604947 + 0.4991110861 + 0.5001580119 + 0.5011935830 + 0.5022290945 + 0.5032647252 + 0.5042961836 + 0.5053253174 + 0.5063543916 + 0.5073835254 + 0.5083957911 + 0.5094074011 + 0.5104188919 + 0.5114263892 + 0.5124220848 + 0.5134177208 + 0.5144132972 + 0.5154060721 + 0.5163959265 + 0.5173857808 + 0.5183756948 + 0.5193517208 + 0.5203220844 + 0.5212926269 + 0.5222629905 + 0.5232200027 + 0.5241754055 + 0.5251306891 + 0.5260860920 + 0.5270460844 + 0.5280060768 + 0.5289661288 + 0.5299252272 + 0.5308769941 + 0.5318287015 + 0.5327805281 + 0.5337300897 + 0.5346677899 + 0.5356054902 + 0.5365431905 + 0.5374808908 + 0.5384188890 + 0.5393568873 + 0.5402948856 + 0.5412318110 + 0.5421609879 + 0.5430902243 + 0.5440192819 + 0.5449479818 + 0.5458660722 + 0.5467841029 + 0.5477020741 + 0.5486202240 + 0.5495285988 + 0.5504361987 + 0.5513436794 + 0.5522512794 + 0.5531492829 + 0.5540440083 + 0.5549386740 + 0.5558333993 + 0.5567305088 + 0.5576295853 + 0.5585287809 + 0.5594279766 + 0.5603266954 + 0.5612239838 + 0.5621213913 + 0.5630186796 + 0.5639160275 + 0.5648062229 + 0.5656958818 + 0.5665857196 + 0.5674753785 + 0.5683673024 + 0.5692604780 + 0.5701537132 + 0.5710470080 + 0.5719397068 + 0.5728303194 + 0.5737208724 + 0.5746114850 + 0.5755020976 + 0.5763865113 + 0.5772687793 + 0.5781511068 + 0.5790333748 + 0.5799121857 + 0.5807796121 + 0.5816469789 + 0.5825144053 + 0.5833817720 + 0.5842388868 + 0.5850911736 + 0.5859435201 + 0.5867958069 + 0.5876480937 + 0.5885003805 + 0.5893527269 + 0.5902050734 + 0.5910574198 + 0.5919092298 + 0.5927603841 + 0.5936114788 + 0.5944626927 + 0.5953139067 + 0.5961607099 + 0.5970060825 + 0.5978515148 + 0.5986968279 + 0.5995422006 + 0.6003857255 + 0.6012291908 + 0.6020725965 + 0.6029161215 + 0.6037604809 + 0.6046084166 + 0.6054564118 + 0.6063044071 + 0.6071524024 + 0.6080002189 + 0.6088476777 + 0.6096950769 + 0.6105425954 + 0.6113901138 + 0.6122344732 + 0.6130748987 + 0.6139153838 + 0.6147558093 + 0.6155961752 + 0.6164314151 + 0.6172606945 + 0.6180900931 + 0.6189194918 + 0.6197488904 + 0.6205750704 + 0.6213976741 + 0.6222202778 + 0.6230428815 + 0.6238654852 + 0.6246876121 + 0.6255089045 + 0.6263303161 + 0.6271517277 + 0.6279730201 + 0.6287912726 + 0.6296015978 + 0.6304119825 + 0.6312224269 + 0.6320326924 + 0.6328420043 + 0.6336416006 + 0.6344411969 + 0.6352407932 + 0.6360403895 + 0.6368399858 + 0.6376360059 + 0.6384313703 + 0.6392267942 + 0.6400222182 + 0.6408177018 + 0.6416134238 + 0.6424095035 + 0.6432055831 + 0.6440016031 + 0.6447976828 + 0.6455929279 + 0.6463851929 + 0.6471775770 + 0.6479700208 + 0.6487624049 + 0.6495547891 + 0.6503387094 + 0.6511209011 + 0.6519030929 + 0.6526852250 + 0.6534674168 + 0.6542478204 + 0.6550251245 + 0.6558023095 + 0.6565796137 + 0.6573567986 + 0.6581341028 + 0.6589120030 + 0.6596900225 + 0.6604681015 + 0.6612461209 + 0.6620242000 + 0.6628038287 + 0.6635876894 + 0.6643714905 + 0.6651554108 + 0.6659392715 + 0.6667230725 + 0.6675077081 + 0.6682925820 + 0.6690775156 + 0.6698623896 + 0.6706473827 + 0.6714323163 + 0.6722124815 + 0.6729924083 + 0.6737722158 + 0.6745520830 + 0.6753318906 + 0.6761127114 + 0.6768987179 + 0.6776847839 + 0.6784707904 + 0.6792567968 + 0.6800428033 + 0.6808322072 + 0.6816287041 + 0.6824250817 + 0.6832215786 + 0.6840180159 + 0.6848145127 + 0.6856052279 + 0.6863880754 + 0.6871711016 + 0.6879541278 + 0.6887369752 + 0.6895200014 + 0.6902992129 + 0.6910743713 + 0.6918495297 + 0.6926246881 + 0.6933997869 + 0.6941748857 + 0.6949504018 + 0.6957262158 + 0.6965019703 + 0.6972777843 + 0.6980537176 + 0.6988294721 + 0.6996037960 + 0.7003753781 + 0.7011470795 + 0.7019187212 + 0.7026903033 + 0.7034620047 + 0.7042315006 + 0.7049934268 + 0.7057551742 + 0.7065169811 + 0.7072789073 + 0.7080407143 + 0.7088025808 + 0.7095500827 + 0.7102975249 + 0.7110450268 + 0.7117924094 + 0.7125399113 + 0.7132872939 + 0.7140312195 + 0.7147734761 + 0.7155159116 + 0.7162582874 + 0.7170007229 + 0.7177429795 + 0.7184851170 + 0.7192267179 + 0.7199681997 + 0.7207098007 + 0.7214512825 + 0.7221928835 + 0.7229344249 + 0.7236632705 + 0.7243912816 + 0.7251192927 + 0.7258473039 + 0.7265753150 + 0.7273033261 + 0.7280253768 + 0.7287402749 + 0.7294551134 + 0.7301700115 + 0.7308847904 + 0.7315996289 + 0.7323145270 + 0.7330235839 + 0.7337319255 + 0.7344402075 + 0.7351484895 + 0.7358567715 + 0.7365651131 + 0.7372738123 + 0.7379835248 + 0.7386932969 + 0.7394030094 + 0.7401127219 + 0.7408224940 + 0.7415322065 + 0.7422450781 + 0.7429605126 + 0.7436760068 + 0.7443913817 + 0.7451068759 + 0.7458223104 + 0.7465378046 + 0.7472481728 + 0.7479571104 + 0.7486659884 + 0.7493749261 + 0.7500838041 + 0.7507926822 + 0.7515016198 + 0.7522053123 + 0.7529084086 + 0.7536116242 + 0.7543147206 + 0.7550178766 + 0.7557209730 + 0.7564241886 + 0.7571367025 + 0.7578495145 + 0.7585622072 + 0.7592749000 + 0.7599875927 + 0.7607002854 + 0.7614130974 + 0.7621260881 + 0.7628390789 + 0.7635521293 + 0.7642651200 + 0.7649781108 + 0.7656911016 + 0.7664040923 + 0.7671093941 + 0.7678139210 + 0.7685185075 + 0.7692229748 + 0.7699275017 + 0.7706320286 + 0.7713364959 + 0.7720378041 + 0.7727380991 + 0.7734382749 + 0.7741385102 + 0.7748388052 + 0.7755389810 + 0.7762392163 + 0.7769402266 + 0.7776417136 + 0.7783433199 + 0.7790448070 + 0.7797464132 + 0.7804480195 + 0.7811495066 + 0.7818514109 + 0.7825546861 + 0.7832580209 + 0.7839611769 + 0.7846645117 + 0.7853677869 + 0.7860711217 + 0.7867742777 + 0.7874720097 + 0.7881684899 + 0.7888649702 + 0.7895615101 + 0.7902579904 + 0.7909544706 + 0.7916510105 + 0.7923467755 + 0.7930412889 + 0.7937358022 + 0.7944303155 + 0.7951248288 + 0.7958192229 + 0.7965136766 + 0.7972081900 + 0.7979041934 + 0.7986006141 + 0.7992969751 + 0.7999933958 + 0.8006898165 + 0.8013861775 + 0.8020825982 + 0.8027787209 + 0.8034735918 + 0.8041685224 + 0.8048635125 + 0.8055583835 + 0.8062533140 + 0.8069481850 + 0.8076431155 + 0.8083345890 + 0.8090218902 + 0.8097093105 + 0.8103966117 + 0.8110839128 + 0.8117712736 + 0.8124585748 + 0.8131459951 + 0.8138281703 + 0.8145077229 + 0.8151872754 + 0.8158668280 + 0.8165463209 + 0.8172258139 + 0.8179054260 + 0.8185849190 + 0.8192651868 + 0.8199456930 + 0.8206261992 + 0.8213067055 + 0.8219872117 + 0.8226677179 + 0.8233482242 + 0.8240286708 + 0.8247126937 + 0.8253976107 + 0.8260825872 + 0.8267675042 + 0.8274524808 + 0.8281373978 + 0.8288223147 + 0.8295072913 + 0.8301901221 + 0.8308722973 + 0.8315544724 + 0.8322365880 + 0.8329188228 + 0.8336008787 + 0.8342831135 + 0.8349652290 + 0.8356407285 + 0.8363116980 + 0.8369827867 + 0.8376538157 + 0.8383247852 + 0.8389958143 + 0.8396669030 + 0.8403378725 + 0.8410078287 + 0.8416758180 + 0.8423439264 + 0.8430119157 + 0.8436799049 + 0.8443478942 + 0.8450158834 + 0.8456839919 + 0.8463522196 + 0.8470252752 + 0.8476983905 + 0.8483713865 + 0.8490445018 + 0.8497176170 + 0.8503906727 + 0.8510637283 + 0.8517367840 + 0.8524100780 + 0.8530836105 + 0.8537570834 + 0.8544304967 + 0.8551040292 + 0.8557773829 + 0.8564509153 + 0.8571243882 + 0.8577973843 + 0.8584672809 + 0.8591372967 + 0.8598073125 + 0.8604773283 + 0.8611472249 + 0.8618171811 + 0.8624871969 + 0.8631570935 + 0.8638226986 + 0.8644846082 + 0.8651465774 + 0.8658084869 + 0.8664703965 + 0.8671323061 + 0.8677942157 + 0.8684561253 + 0.8691179752 + 0.8697800040 + 0.8704419136 + 0.8711038828 + 0.8717659116 + 0.8724278212 + 0.8730897903 + 0.8737516999 + 0.8744137287 + 0.8750752807 + 0.8757330179 + 0.8763905764 + 0.8770483136 + 0.8777058721 + 0.8783634901 + 0.8790212274 + 0.8796787858 + 0.8803364038 + 0.8809922934 + 0.8816409111 + 0.8822894096 + 0.8829380274 + 0.8835865855 + 0.8842352033 + 0.8848837018 + 0.8855323195 + 0.8861808777 + 0.8868293166 + 0.8874773979 + 0.8881254196 + 0.8887733817 + 0.8894214034 + 0.8900694847 + 0.8907175064 + 0.8913655281 + 0.8920136094 + 0.8926612735 + 0.8933075070 + 0.8939536810 + 0.8945999742 + 0.8952462077 + 0.8958923817 + 0.8965386152 + 0.8971849084 + 0.8978310823 + 0.8984773159 + 0.8991330266 + 0.8997886777 + 0.9004443884 + 0.9011002183 + 0.9017559290 + 0.9024116993 + 0.9030674100 + 0.9037231803 + 0.9043788910 + 0.9050328135 + 0.9056859016 + 0.9063389897 + 0.9069920778 + 0.9076452851 + 0.9082983732 + 0.9089515209 + 0.9096046090 + 0.9102578163 + 0.9109084010 + 0.9115543962 + 0.9122003913 + 0.9128465056 + 0.9134925008 + 0.9141384959 + 0.9147844911 + 0.9154306054 + 0.9160766006 + 0.9167225957 + 0.9173694253 + 0.9180163145 + 0.9186632037 + 0.9193100929 + 0.9199569821 + 0.9206038713 + 0.9212508202 + 0.9218977094 + 0.9225445986 + 0.9231904149 + 0.9238339067 + 0.9244773984 + 0.9251207709 + 0.9257643223 + 0.9264076948 + 0.9270511866 + 0.9276946187 + 0.9283381104 + 0.9289816022 + 0.9296203852 + 0.9302564859 + 0.9308925867 + 0.9315286875 + 0.9321647882 + 0.9328008890 + 0.9334369898 + 0.9340732098 + 0.9347093105 + 0.9353454113 + 0.9359716177 + 0.9365960956 + 0.9372205138 + 0.9378449917 + 0.9384695292 + 0.9390940070 + 0.9397184849 + 0.9403430223 + 0.9409673810 + 0.9415919185 + 0.9422088861 + 0.9428256154 + 0.9434422851 + 0.9440590143 + 0.9446756840 + 0.9452924132 + 0.9459090829 + 0.9465258121 + 0.9471424818 + 0.9477592111 + 0.9483684897 + 0.9489774704 + 0.9495865703 + 0.9501956105 + 0.9508047104 + 0.9514136910 + 0.9520227909 + 0.9526317716 + 0.9532408714 + 0.9538499117 + 0.9544495940 + 0.9550477862 + 0.9556459785 + 0.9562441707 + 0.9568424225 + 0.9574406147 + 0.9580388069 + 0.9586369991 + 0.9592351913 + 0.9598333836 + 0.9604253769 + 0.9610139728 + 0.9616026878 + 0.9621914029 + 0.9627799988 + 0.9633687139 + 0.9639573097 + 0.9645460248 + 0.9651346803 + 0.9657232761 + 0.9663069248 + 0.9668803215 + 0.9674537182 + 0.9680271149 + 0.9686005116 + 0.9691739082 + 0.9697473049 + 0.9703207016 + 0.9708940983 + 0.9714674950 + 0.9720408916 + 0.9725995064 + 0.9731563926 + 0.9737132192 + 0.9742701054 + 0.9748269916 + 0.9753838181 + 0.9759407043 + 0.9764975905 + 0.9770544171 + 0.9776113033 + 0.9781597257 + 0.9786922932 + 0.9792249203 + 0.9797576070 + 0.9802901745 + 0.9808228016 + 0.9813554287 + 0.9818881154 + 0.9824206829 + 0.9829533100 + 0.9834858775 + 0.9840049744 + 0.9845178723 + 0.9850307703 + 0.9855437279 + 0.9860566854 + 0.9865695834 + 0.9870824814 + 0.9875953794 + 0.9881082773 + 0.9886211753 + 0.9891340733 + 0.9896370173 + 0.9901388884 + 0.9906408191 + 0.9911426902 + 0.9916446209 + 0.9921464920 + 0.9926484227 + 0.9931502938 + 0.9936522245 + 0.9941540956 + 0.9946557879 + 0.9951416850 + 0.9956275225 + 0.9961133003 + 0.9965991974 + 0.9970849752 + 0.9975708127 + 0.9980567098 + 0.9985424876 + 0.9990283251 + 0.9995142221 + 1.0000000000 +} diff --git a/rpplugins/color_correction/resources/film_luts_raw/fujifilm_f-125.spi1d b/rpplugins/color_correction/resources/film_luts_raw/fujifilm_f-125.spi1d new file mode 100644 index 0000000..eee3fc3 --- /dev/null +++ b/rpplugins/color_correction/resources/film_luts_raw/fujifilm_f-125.spi1d @@ -0,0 +1,1030 @@ +Version 1 +From 0.0 1.0 +Length 1024 +Components 3 +{ + 0.0000000000 0.0000000000 0.0000000000 + 0.0174498409 0.0158984791 0.0114764702 + 0.0361074992 0.0300892591 0.0227251798 + 0.0508534499 0.0413388014 0.0331778601 + 0.0630743131 0.0511820987 0.0424059182 + 0.0737055317 0.0595689416 0.0507076010 + 0.0831899792 0.0670762509 0.0583669208 + 0.0918336809 0.0739420429 0.0653621703 + 0.0999075696 0.0803586915 0.0719582215 + 0.1073999032 0.0863586813 0.0781143606 + 0.1143994033 0.0919513777 0.0840181410 + 0.1210075021 0.0972131789 0.0896857306 + 0.1272652000 0.1023328975 0.0950955227 + 0.1332022995 0.1073141024 0.1002841964 + 0.1389860064 0.1120809987 0.1052708998 + 0.1446685940 0.1166312024 0.1100749969 + 0.1502207965 0.1210201979 0.1147160009 + 0.1556082070 0.1252893060 0.1191812009 + 0.1608344018 0.1294762045 0.1235382035 + 0.1659597009 0.1336127967 0.1277814955 + 0.1709610969 0.1376406997 0.1319573969 + 0.1758396029 0.1415354013 0.1360505968 + 0.1805783063 0.1453579962 0.1400354058 + 0.1851565987 0.1491020024 0.1439131051 + 0.1896200031 0.1527583003 0.1477226019 + 0.1940072030 0.1563414037 0.1514364034 + 0.1983578950 0.1599265933 0.1550768018 + 0.2026146054 0.1634611934 0.1586581022 + 0.2068161964 0.1669549942 0.1621633023 + 0.2109510005 0.1704287976 0.1656109989 + 0.2149749994 0.1738846004 0.1689939946 + 0.2188791931 0.1773294955 0.1723017991 + 0.2226788998 0.1807734072 0.1755644977 + 0.2264375985 0.1841789037 0.1787340939 + 0.2301400006 0.1875509024 0.1818515062 + 0.2337515056 0.1908915937 0.1848967969 + 0.2373262048 0.1941868067 0.1878945976 + 0.2408698052 0.1974609047 0.1908354014 + 0.2443857044 0.2007011026 0.1937474012 + 0.2478293926 0.2038740963 0.1966456026 + 0.2511906028 0.2069949955 0.1995196939 + 0.2545030117 0.2100716978 0.2023606002 + 0.2577551007 0.2130948007 0.2052040994 + 0.2609705925 0.2161156982 0.2080169022 + 0.2641761005 0.2191050053 0.2107931972 + 0.2673386037 0.2220419943 0.2135623991 + 0.2704797983 0.2249206007 0.2162752002 + 0.2735692859 0.2277640998 0.2189542055 + 0.2766304910 0.2305577993 0.2216016054 + 0.2796724141 0.2333119065 0.2241947949 + 0.2826831937 0.2360485047 0.2267569005 + 0.2856605947 0.2387613952 0.2292927057 + 0.2885996997 0.2414368987 0.2317842990 + 0.2914834917 0.2441027015 0.2342378944 + 0.2943134904 0.2467696965 0.2366532981 + 0.2971065044 0.2494162023 0.2390290052 + 0.2998841107 0.2520292997 0.2413756996 + 0.3026126027 0.2546142042 0.2437071949 + 0.3053067923 0.2571905851 0.2460273951 + 0.3079755008 0.2597542107 0.2483306974 + 0.3106071949 0.2622892857 0.2506220937 + 0.3132098019 0.2647835910 0.2528899908 + 0.3157896101 0.2672505081 0.2551301122 + 0.3183388114 0.2697114050 0.2573640943 + 0.3208617866 0.2721551955 0.2595869899 + 0.3233729005 0.2745685875 0.2617990971 + 0.3258588910 0.2769567966 0.2639977038 + 0.3283306956 0.2793405056 0.2661921084 + 0.3308002055 0.2817173004 0.2683886886 + 0.3332616091 0.2840746939 0.2705698907 + 0.3356887102 0.2864069939 0.2727307081 + 0.3380911052 0.2887319922 0.2748725116 + 0.3404774070 0.2910597026 0.2769970894 + 0.3428531885 0.2933830023 0.2791089118 + 0.3452278078 0.2956911922 0.2812050879 + 0.3475916088 0.2979753911 0.2832851112 + 0.3499327898 0.3002283871 0.2853564918 + 0.3522517085 0.3024463058 0.2874124944 + 0.3545554876 0.3046588004 0.2894454896 + 0.3568528891 0.3068628013 0.2914513052 + 0.3591203094 0.3090505004 0.2934390903 + 0.3613556027 0.3112153113 0.2954114974 + 0.3635644913 0.3133526146 0.2973645031 + 0.3657538891 0.3154605031 0.2992906868 + 0.3679293990 0.3175630867 0.3012037873 + 0.3700731993 0.3196572065 0.3031010032 + 0.3722012937 0.3217284083 0.3049888909 + 0.3743169010 0.3237737119 0.3068724871 + 0.3764213026 0.3257966936 0.3087452054 + 0.3785130084 0.3278082013 0.3106024861 + 0.3805955052 0.3298071027 0.3124460876 + 0.3826780915 0.3317958117 0.3142769933 + 0.3847546875 0.3337770998 0.3160952926 + 0.3867942095 0.3357304037 0.3179017007 + 0.3888104856 0.3376702964 0.3196955025 + 0.3908145130 0.3396002054 0.3214753866 + 0.3928089142 0.3415268064 0.3232490122 + 0.3947995007 0.3434461057 0.3250178993 + 0.3967804909 0.3453572989 0.3267830908 + 0.3987523913 0.3472534120 0.3285475075 + 0.4007174075 0.3491292894 0.3303103149 + 0.4026708007 0.3509947956 0.3320707083 + 0.4046143889 0.3528488874 0.3338232934 + 0.4065484107 0.3546791077 0.3355642855 + 0.4084819853 0.3565005064 0.3372963965 + 0.4104149938 0.3583168089 0.3390068114 + 0.4123412967 0.3601278961 0.3407028019 + 0.4142560065 0.3619349003 0.3423874974 + 0.4161522090 0.3637281060 0.3440541029 + 0.4180339873 0.3655182123 0.3457126915 + 0.4199067950 0.3673050106 0.3473584950 + 0.4217523932 0.3690750003 0.3489893973 + 0.4235874116 0.3708429039 0.3506138027 + 0.4254117906 0.3726145029 0.3522236049 + 0.4272232056 0.3743841052 0.3538290858 + 0.4290306866 0.3761518002 0.3554284871 + 0.4308294058 0.3779003918 0.3570241034 + 0.4326210022 0.3796432018 0.3586181998 + 0.4344018102 0.3813720942 0.3602060080 + 0.4361707866 0.3830938041 0.3617906868 + 0.4379333854 0.3848012090 0.3633658886 + 0.4396809936 0.3864955008 0.3649328053 + 0.4414246082 0.3881793916 0.3664895892 + 0.4431430995 0.3898509145 0.3680340052 + 0.4448564947 0.3915182054 0.3695713878 + 0.4465528131 0.3931697011 0.3710972071 + 0.4482432008 0.3948189020 0.3726201952 + 0.4499239028 0.3964514136 0.3741200864 + 0.4515936971 0.3980818987 0.3756181896 + 0.4532519877 0.3997015953 0.3771077991 + 0.4548968971 0.4013178945 0.3785969913 + 0.4565317035 0.4029234946 0.3800840974 + 0.4581527114 0.4045226872 0.3815703094 + 0.4597654939 0.4061067104 0.3830527067 + 0.4613632858 0.4076885879 0.3845353127 + 0.4629530907 0.4092662036 0.3860189021 + 0.4645408094 0.4108397961 0.3874995112 + 0.4661273062 0.4124050140 0.3889681995 + 0.4677076936 0.4139649868 0.3904353082 + 0.4692842960 0.4155119956 0.3918946981 + 0.4708591998 0.4170548022 0.3933512866 + 0.4724324942 0.4185824096 0.3947859108 + 0.4739956856 0.4201084077 0.3962202072 + 0.4755468965 0.4216217101 0.3976345956 + 0.4770910144 0.4231351018 0.3990488946 + 0.4786213040 0.4246394038 0.4004501104 + 0.4801476002 0.4261435866 0.4018495977 + 0.4816561043 0.4276433885 0.4032416940 + 0.4831644893 0.4291422963 0.4046311080 + 0.4846526980 0.4306376874 0.4060145020 + 0.4861406982 0.4321312904 0.4073927999 + 0.4876179993 0.4336220026 0.4087674022 + 0.4890919924 0.4351086915 0.4101338089 + 0.4905653000 0.4365926087 0.4114997089 + 0.4920378029 0.4380624890 0.4128586948 + 0.4935061932 0.4395323992 0.4142177105 + 0.4949601889 0.4409978986 0.4155749083 + 0.4964140952 0.4424628019 0.4169315994 + 0.4978365004 0.4439246953 0.4182890952 + 0.4992552996 0.4453840852 0.4196475148 + 0.5006620884 0.4468388855 0.4210050106 + 0.5020588040 0.4482730925 0.4223509133 + 0.5034533739 0.4497072101 0.4236967862 + 0.5048360825 0.4511240125 0.4250375032 + 0.5062186718 0.4525361061 0.4263758063 + 0.5075957179 0.4539420903 0.4277085066 + 0.5089703798 0.4553368986 0.4290247858 + 0.5103421211 0.4567317963 0.4303410053 + 0.5117046833 0.4581159055 0.4316442013 + 0.5130673051 0.4594987035 0.4329437912 + 0.5144175887 0.4608711898 0.4342381954 + 0.5157638192 0.4622273147 0.4355193973 + 0.5171049237 0.4635834098 0.4368005097 + 0.5184270144 0.4649255872 0.4380722940 + 0.5197492242 0.4662652016 0.4393407106 + 0.5210537910 0.4676026106 0.4406091869 + 0.5223482847 0.4689337909 0.4418779016 + 0.5236423016 0.4702650905 0.4431464970 + 0.5249115229 0.4715861082 0.4444108009 + 0.5261808038 0.4729016125 0.4456712902 + 0.5274490118 0.4742170870 0.4469316900 + 0.5287154913 0.4755303860 0.4481886029 + 0.5299819708 0.4768437147 0.4494448900 + 0.5312492251 0.4781504869 0.4506979883 + 0.5325167775 0.4794408083 0.4519374073 + 0.5337843895 0.4807311893 0.4531767964 + 0.5350342989 0.4820165038 0.4544104934 + 0.5362828970 0.4832974970 0.4556373060 + 0.5375289917 0.4845784903 0.4568639994 + 0.5387613177 0.4858368039 0.4580819011 + 0.5399935842 0.4870882928 0.4592955112 + 0.5412209034 0.4883398116 0.4605090916 + 0.5424383879 0.4895803928 0.4617215991 + 0.5436558723 0.4908204079 0.4629341066 + 0.5448678136 0.4920594990 0.4641464949 + 0.5460734963 0.4932895899 0.4653517008 + 0.5472792983 0.4945197105 0.4665569961 + 0.5484790802 0.4957481027 0.4677614868 + 0.5496746898 0.4969693124 0.4689593911 + 0.5508701801 0.4981904924 0.4701572061 + 0.5520610809 0.4994137883 0.4713543952 + 0.5532492995 0.5006437898 0.4725480974 + 0.5544373989 0.5018737912 0.4737417102 + 0.5556218028 0.5030999184 0.4749346972 + 0.5568041205 0.5043138862 0.4761235118 + 0.5579863191 0.5055277944 0.4773122966 + 0.5591588020 0.5067374706 0.4785006046 + 0.5603247285 0.5079305172 0.4796842933 + 0.5614907146 0.5091236234 0.4808681011 + 0.5626431108 0.5103173256 0.4820516109 + 0.5637829900 0.5115153193 0.4832226932 + 0.5649229884 0.5127133131 0.4843936861 + 0.5660511851 0.5139113069 0.4855647981 + 0.5671615005 0.5151088834 0.4867219925 + 0.5682718158 0.5163065195 0.4878776968 + 0.5693790913 0.5175040960 0.4890333116 + 0.5704758167 0.5186815858 0.4901837111 + 0.5715726018 0.5198547244 0.4913321137 + 0.5726693273 0.5210276842 0.4924804866 + 0.5737720132 0.5221964717 0.4936192930 + 0.5748748183 0.5233623981 0.4947485924 + 0.5759775043 0.5245283246 0.4958778918 + 0.5770760775 0.5256924033 0.4970034957 + 0.5781732202 0.5268526077 0.4981164932 + 0.5792703032 0.5280128121 0.4992294014 + 0.5803601146 0.5291728973 0.5003424287 + 0.5814397931 0.5303236246 0.5014445186 + 0.5825194120 0.5314744115 0.5025454760 + 0.5835987926 0.5326251984 0.5036464930 + 0.5846728086 0.5337677002 0.5047429800 + 0.5857468843 0.5349056125 0.5058357120 + 0.5868209004 0.5360434055 0.5069283843 + 0.5878757238 0.5371788144 0.5080201030 + 0.5889192820 0.5383052826 0.5091047883 + 0.5899627805 0.5394318104 0.5101894736 + 0.5910035968 0.5405583978 0.5112742186 + 0.5920301080 0.5416883826 0.5123528838 + 0.5930566788 0.5428196192 0.5134283900 + 0.5940833092 0.5439507961 0.5145038962 + 0.5950983167 0.5450789928 0.5155786872 + 0.5961067080 0.5461968184 0.5166484118 + 0.5971152186 0.5473145843 0.5177180767 + 0.5981239080 0.5484325290 0.5187878013 + 0.5991356969 0.5495414734 0.5198484063 + 0.6001476049 0.5506458879 0.5209016204 + 0.6011593938 0.5517503023 0.5219547153 + 0.6021643281 0.5528541207 0.5230079293 + 0.6031603217 0.5539363027 0.5240486860 + 0.6041563749 0.5550184250 0.5250884295 + 0.6051524282 0.5561006069 0.5261281729 + 0.6061363816 0.5571805835 0.5271657705 + 0.6071165204 0.5582563877 0.5281966925 + 0.6080965996 0.5593320727 0.5292276144 + 0.6090764999 0.5604078770 0.5302584767 + 0.6100435257 0.5614696145 0.5312880278 + 0.6110104918 0.5625219941 0.5323162079 + 0.6119775176 0.5635743737 0.5333443880 + 0.6129397154 0.5646268129 0.5343726277 + 0.6138859987 0.5656726956 0.5353969932 + 0.6148322821 0.5667169094 0.5364199877 + 0.6157786250 0.5677611828 0.5374429226 + 0.6167212725 0.5688053966 0.5384659171 + 0.6176583171 0.5698326230 0.5394816995 + 0.6185953021 0.5708590150 0.5404965281 + 0.6195322871 0.5718854070 0.5415111780 + 0.6204634905 0.5729113817 0.5425258875 + 0.6213884950 0.5739294291 0.5435299873 + 0.6223133802 0.5749472976 0.5445337296 + 0.6232383251 0.5759652853 0.5455372930 + 0.6241629124 0.5769823194 0.5465409160 + 0.6250872016 0.5779896975 0.5475350022 + 0.6260113716 0.5789970756 0.5485289097 + 0.6269357204 0.5800045133 0.5495228171 + 0.6278557777 0.5810111165 0.5505167842 + 0.6287717223 0.5820034742 0.5515152216 + 0.6296874881 0.5829960108 0.5525137782 + 0.6306033731 0.5839884281 0.5535123944 + 0.6315113902 0.5849809051 0.5545110106 + 0.6324080229 0.5859525204 0.5554962158 + 0.6333045959 0.5869235992 0.5564795732 + 0.6342011094 0.5878946185 0.5574629903 + 0.6350932121 0.5888655782 0.5584464073 + 0.6359726787 0.5898336172 0.5594201088 + 0.6368522048 0.5908008814 0.5603901744 + 0.6377316713 0.5917682052 0.5613601804 + 0.6386104822 0.5927355289 0.5623303056 + 0.6394773126 0.5936999917 0.5632957816 + 0.6403442025 0.5946627259 0.5642570257 + 0.6412109733 0.5956255198 0.5652183294 + 0.6420779228 0.5965881944 0.5661795735 + 0.6429408789 0.5975462794 0.5671393871 + 0.6438030005 0.5984956026 0.5680949092 + 0.6446650028 0.5994448066 0.5690503120 + 0.6455270052 0.6003941298 0.5700057745 + 0.6463868022 0.6013432741 0.5709612966 + 0.6472437978 0.6022868752 0.5719025135 + 0.6481007934 0.6032304764 0.5728424788 + 0.6489577889 0.6041740775 0.5737825036 + 0.6498141289 0.6051176786 0.5747225285 + 0.6506562233 0.6060569286 0.5756577849 + 0.6514983177 0.6069930792 0.5765889287 + 0.6523404717 0.6079294086 0.5775198936 + 0.6531826258 0.6088656783 0.5784509182 + 0.6540184021 0.6098006964 0.5793818235 + 0.6548498273 0.6107280850 0.5803099871 + 0.6556811929 0.6116555929 0.5812382102 + 0.6565124989 0.6125831008 0.5821664929 + 0.6573433876 0.6135106087 0.5830947161 + 0.6581645012 0.6144319773 0.5840185881 + 0.6589856148 0.6153494716 0.5849387050 + 0.6598067284 0.6162670255 0.5858588219 + 0.6606277823 0.6171844006 0.5867788792 + 0.6614431739 0.6181018949 0.5876989961 + 0.6622517705 0.6190115213 0.5886114240 + 0.6630604267 0.6199212074 0.5895230770 + 0.6638690233 0.6208307743 0.5904347897 + 0.6646776199 0.6217405200 0.5913465023 + 0.6654757261 0.6226496100 0.5922542214 + 0.6662709117 0.6235576868 0.5931503177 + 0.6670660973 0.6244658232 0.5940464139 + 0.6678612828 0.6253738999 0.5949425101 + 0.6686561704 0.6262819767 0.5958386064 + 0.6694442034 0.6271823049 0.5967332721 + 0.6702321768 0.6280776262 0.5976269245 + 0.6710202098 0.6289728880 0.5985203981 + 0.6718081832 0.6298682094 0.5994138718 + 0.6725955009 0.6307634711 0.6003074050 + 0.6733806133 0.6316475272 0.6011890769 + 0.6741657257 0.6325287223 0.6020658016 + 0.6749507189 0.6334097981 0.6029425859 + 0.6757357717 0.6342908740 0.6038193703 + 0.6765164137 0.6351721287 0.6046960950 + 0.6772890091 0.6360508800 0.6055694818 + 0.6780614853 0.6369295716 0.6064420938 + 0.6788340807 0.6378083229 0.6073147058 + 0.6796066165 0.6386870146 0.6081873775 + 0.6803761721 0.6395655870 0.6090599895 + 0.6811413169 0.6404411793 0.6099300981 + 0.6819062829 0.6413165927 0.6107999086 + 0.6826714277 0.6421920061 0.6116697192 + 0.6834365129 0.6430674195 0.6125395298 + 0.6841984987 0.6439427733 0.6134092808 + 0.6849551797 0.6448048949 0.6142743230 + 0.6857119203 0.6456660032 0.6151384115 + 0.6864687204 0.6465271115 0.6160026193 + 0.6872254014 0.6473882198 0.6168667078 + 0.6879792213 0.6482493281 0.6177309155 + 0.6887251735 0.6491037011 0.6185951233 + 0.6894711256 0.6499567032 0.6194592714 + 0.6902170777 0.6508097053 0.6203234792 + 0.6909629703 0.6516628265 0.6211876869 + 0.6917080283 0.6525158286 0.6220518947 + 0.6924436092 0.6533647776 0.6229112148 + 0.6931793094 0.6542117000 0.6237667799 + 0.6939148903 0.6550586224 0.6246222854 + 0.6946504712 0.6559054852 0.6254779100 + 0.6953861117 0.6567524076 0.6263334155 + 0.6961168051 0.6575965285 0.6271870732 + 0.6968464851 0.6584361792 0.6280364990 + 0.6975762844 0.6592760086 0.6288859248 + 0.6983060241 0.6601157188 0.6297354102 + 0.6990358233 0.6609554887 0.6305847764 + 0.6997650862 0.6617947817 0.6314343214 + 0.7004939914 0.6626260877 0.6322728992 + 0.7012230158 0.6634575129 0.6331112981 + 0.7019519210 0.6642888784 0.6339496970 + 0.7026808858 0.6651203036 0.6347880960 + 0.7034088969 0.6659517288 0.6356264949 + 0.7041271925 0.6667770743 0.6364635825 + 0.7048454881 0.6675990224 0.6372997165 + 0.7055637836 0.6684209108 0.6381359100 + 0.7062821984 0.6692429185 0.6389719844 + 0.7070004940 0.6700648069 0.6398081183 + 0.7077152729 0.6708840132 0.6406437755 + 0.7084274888 0.6716861129 0.6414728165 + 0.7091398239 0.6724882722 0.6423017979 + 0.7098520994 0.6732904911 0.6431307793 + 0.7105643749 0.6740925908 0.6439598203 + 0.7112765908 0.6748948097 0.6447888017 + 0.7119773030 0.6756910086 0.6456167102 + 0.7126780152 0.6764826775 0.6464434862 + 0.7133787870 0.6772742867 0.6472703218 + 0.7140794992 0.6780658960 0.6480970979 + 0.7147802711 0.6788576245 0.6489239931 + 0.7154778838 0.6796491742 0.6497508287 + 0.7161695957 0.6804391742 0.6505677104 + 0.7168614268 0.6812291145 0.6513826251 + 0.7175530791 0.6820189953 0.6521974802 + 0.7182449102 0.6828088164 0.6530123949 + 0.7189366221 0.6835986972 0.6538271904 + 0.7196236253 0.6843873262 0.6546415091 + 0.7203075290 0.6851689219 0.6554480195 + 0.7209913731 0.6859505177 0.6562544703 + 0.7216752768 0.6867321730 0.6570609808 + 0.7223592997 0.6875138283 0.6578674912 + 0.7230432034 0.6882954240 0.6586740017 + 0.7237169147 0.6890760064 0.6594784856 + 0.7243875265 0.6898545027 0.6602771878 + 0.7250581980 0.6906331182 0.6610758901 + 0.7257289290 0.6914116144 0.6618745923 + 0.7263996005 0.6921901107 0.6626732945 + 0.7270702124 0.6929686069 0.6634719968 + 0.7277340293 0.6937432885 0.6642683744 + 0.7283964753 0.6945124269 0.6650602221 + 0.7290591002 0.6952815056 0.6658521295 + 0.7297216058 0.6960507035 0.6666439176 + 0.7303841710 0.6968197823 0.6674357057 + 0.7310466766 0.6975889206 0.6682276130 + 0.7317048907 0.6983528733 0.6690183282 + 0.7323622108 0.6991090178 0.6698067784 + 0.7330195904 0.6998651028 0.6705952883 + 0.7336769104 0.7006211877 0.6713837981 + 0.7343342900 0.7013772726 0.6721723080 + 0.7349916101 0.7021334171 0.6729608178 + 0.7356424928 0.7028859258 0.6737465262 + 0.7362912297 0.7036299109 0.6745222211 + 0.7369397879 0.7043738961 0.6752979755 + 0.7375885248 0.7051178217 0.6760736704 + 0.7382372022 0.7058618069 0.6768494844 + 0.7388858795 0.7066057920 0.6776251793 + 0.7395280004 0.7073493004 0.6784006953 + 0.7401649952 0.7080891132 0.6791678071 + 0.7408019900 0.7088289857 0.6799349785 + 0.7414389849 0.7095689178 0.6807020903 + 0.7420759201 0.7103086710 0.6814693213 + 0.7427129149 0.7110486031 0.6822363734 + 0.7433465123 0.7117884159 0.6830036044 + 0.7439708710 0.7125198841 0.6837611794 + 0.7445952892 0.7132496834 0.6845157146 + 0.7452197075 0.7139794230 0.6852701902 + 0.7458441854 0.7147092223 0.6860247254 + 0.7464686036 0.7154390216 0.6867792010 + 0.7470930219 0.7161687016 0.6875336766 + 0.7477155924 0.7168959975 0.6882864833 + 0.7483379841 0.7176201940 0.6890364885 + 0.7489603758 0.7183443904 0.6897866130 + 0.7495828271 0.7190685868 0.6905366182 + 0.7502052188 0.7197927833 0.6912866831 + 0.7508276105 0.7205169797 0.6920368075 + 0.7514470816 0.7212411761 0.6927868128 + 0.7520624995 0.7219575047 0.6935216784 + 0.7526779771 0.7226737142 0.6942551136 + 0.7532935143 0.7233898044 0.6949886084 + 0.7539088726 0.7241060138 0.6957219839 + 0.7545244098 0.7248222232 0.6964554191 + 0.7551398873 0.7255383730 0.6971887946 + 0.7557541132 0.7262521982 0.6979203224 + 0.7563681006 0.7269626856 0.6986479163 + 0.7569820881 0.7276732922 0.6993755102 + 0.7575961947 0.7283838987 0.7001032233 + 0.7582101822 0.7290943861 0.7008308172 + 0.7588242292 0.7298049927 0.7015584707 + 0.7594367266 0.7305154800 0.7022861242 + 0.7600427866 0.7312164903 0.7030051947 + 0.7606487870 0.7319142818 0.7037203908 + 0.7612549067 0.7326120138 0.7044355273 + 0.7618610263 0.7333098054 0.7051507235 + 0.7624670267 0.7340075970 0.7058659196 + 0.7630730867 0.7347053885 0.7065809965 + 0.7636762857 0.7354031801 0.7072961926 + 0.7642757297 0.7360877991 0.7080059052 + 0.7648751140 0.7367721796 0.7087152004 + 0.7654743791 0.7374566197 0.7094244957 + 0.7660738230 0.7381410003 0.7101337910 + 0.7666732073 0.7388253808 0.7108430266 + 0.7672724724 0.7395098805 0.7115523219 + 0.7678692937 0.7401931286 0.7122616172 + 0.7684640288 0.7408679724 0.7129713297 + 0.7690587044 0.7415428758 0.7136811018 + 0.7696534991 0.7422178984 0.7143908143 + 0.7702481747 0.7428928018 0.7151005268 + 0.7708429098 0.7435677052 0.7158101797 + 0.7714375854 0.7442426085 0.7165200114 + 0.7720239162 0.7449169755 0.7172291875 + 0.7726042271 0.7455884814 0.7179328203 + 0.7731844783 0.7462599874 0.7186363935 + 0.7737647891 0.7469314933 0.7193400264 + 0.7743450999 0.7476029992 0.7200435996 + 0.7749254107 0.7482745051 0.7207471728 + 0.7755057216 0.7489460111 0.7214508057 + 0.7760874033 0.7496169209 0.7221543193 + 0.7766703963 0.7502800822 0.7228549123 + 0.7772535086 0.7509431839 0.7235553861 + 0.7778365016 0.7516064048 0.7242559195 + 0.7784196138 0.7522696257 0.7249565125 + 0.7790026069 0.7529327869 0.7256569862 + 0.7795857191 0.7535960078 0.7263575196 + 0.7801663876 0.7542592287 0.7270581126 + 0.7807425261 0.7549132109 0.7277507782 + 0.7813186049 0.7555662990 0.7284420729 + 0.7818946838 0.7562193871 0.7291333079 + 0.7824708223 0.7568724751 0.7298246026 + 0.7830467820 0.7575256228 0.7305157781 + 0.7836229205 0.7581787109 0.7312070727 + 0.7841988206 0.7588317990 0.7318983078 + 0.7847698927 0.7594774961 0.7325916290 + 0.7853410840 0.7601187229 0.7332865000 + 0.7859122157 0.7607598901 0.7339814901 + 0.7864832878 0.7614011168 0.7346764207 + 0.7870544791 0.7620422840 0.7353712916 + 0.7876256108 0.7626835108 0.7360662818 + 0.7881966829 0.7633246779 0.7367612123 + 0.7887653708 0.7639619708 0.7374557853 + 0.7893326879 0.7645862103 0.7381486297 + 0.7899000049 0.7652103901 0.7388414741 + 0.7904673219 0.7658346295 0.7395343781 + 0.7910345793 0.7664586902 0.7402272224 + 0.7916018963 0.7670829296 0.7409201264 + 0.7921692133 0.7677071095 0.7416129708 + 0.7927350998 0.7683312893 0.7423058748 + 0.7932925820 0.7689499259 0.7429925799 + 0.7938501239 0.7695664763 0.7436763048 + 0.7944076061 0.7701830268 0.7443599105 + 0.7949650884 0.7707995772 0.7450435162 + 0.7955226898 0.7714161277 0.7457271814 + 0.7960801721 0.7720326185 0.7464107871 + 0.7966377139 0.7726492286 0.7470945120 + 0.7971891761 0.7732650042 0.7477774024 + 0.7977350950 0.7738748193 0.7484462857 + 0.7982810736 0.7744845152 0.7491152287 + 0.7988271117 0.7750942707 0.7497841120 + 0.7993730903 0.7757040262 0.7504529953 + 0.7999191284 0.7763137817 0.7511218786 + 0.8004651070 0.7769234776 0.7517908216 + 0.8010110259 0.7775332928 0.7524597049 + 0.8015481234 0.7781410813 0.7531278729 + 0.8020827770 0.7787457705 0.7537946105 + 0.8026174903 0.7793504000 0.7544614077 + 0.8031522036 0.7799550295 0.7551280856 + 0.8036869168 0.7805595994 0.7557948232 + 0.8042215705 0.7811642885 0.7564616203 + 0.8047562242 0.7817689180 0.7571282983 + 0.8052908778 0.7823734879 0.7577949762 + 0.8058195114 0.7829757929 0.7584580183 + 0.8063477278 0.7835758924 0.7591165900 + 0.8068758845 0.7841761112 0.7597752810 + 0.8074041009 0.7847762704 0.7604339719 + 0.8079321980 0.7853764296 0.7610926032 + 0.8084604144 0.7859765887 0.7617512941 + 0.8089885712 0.7865768075 0.7624099851 + 0.8095167875 0.7871769071 0.7630686164 + 0.8100429177 0.7877739072 0.7637246847 + 0.8105689287 0.7883684039 0.7643780708 + 0.8110948801 0.7889629006 0.7650315762 + 0.8116210103 0.7895573974 0.7656850815 + 0.8121470213 0.7901518941 0.7663385868 + 0.8126729727 0.7907463908 0.7669919729 + 0.8131991029 0.7913408279 0.7676454782 + 0.8137251139 0.7919353247 0.7682989836 + 0.8142498136 0.7925245762 0.7689477205 + 0.8147743940 0.7931082845 0.7695900202 + 0.8152989745 0.7936919928 0.7702323198 + 0.8158236146 0.7942757010 0.7708745003 + 0.8163480759 0.7948594093 0.7715167999 + 0.8168727160 0.7954431772 0.7721590996 + 0.8173972964 0.7960268855 0.7728013992 + 0.8179218769 0.7966105938 0.7734436989 + 0.8184441924 0.7971937060 0.7740848064 + 0.8189654946 0.7977755070 0.7747216821 + 0.8194869161 0.7983571887 0.7753584981 + 0.8200082183 0.7989389896 0.7759953737 + 0.8205295205 0.7995206714 0.7766323090 + 0.8210508227 0.8001024127 0.7772691846 + 0.8215721846 0.8006842136 0.7779061198 + 0.8220934868 0.8012658954 0.7785429955 + 0.8226118088 0.8018476963 0.7791798711 + 0.8231247067 0.8024280071 0.7798110843 + 0.8236376047 0.8030081987 0.7804415822 + 0.8241505027 0.8035883904 0.7810720801 + 0.8246634007 0.8041685820 0.7817025781 + 0.8251761794 0.8047488928 0.7823330760 + 0.8256890774 0.8053290844 0.7829635143 + 0.8262019753 0.8059092760 0.7835940123 + 0.8267148733 0.8064895868 0.7842245102 + 0.8272213936 0.8070695996 0.7848517895 + 0.8277270794 0.8076496124 0.7854750752 + 0.8282328844 0.8082295060 0.7860983014 + 0.8287385702 0.8088093996 0.7867215872 + 0.8292443752 0.8093892932 0.7873448730 + 0.8297501802 0.8099691868 0.7879682183 + 0.8302559257 0.8105490804 0.7885915041 + 0.8307616711 0.8111289740 0.7892147899 + 0.8312665224 0.8117089868 0.7898380160 + 0.8317692280 0.8122891188 0.7904539704 + 0.8322719932 0.8128693104 0.7910689116 + 0.8327746987 0.8134495020 0.7916837931 + 0.8332775235 0.8140296936 0.7922986746 + 0.8337802291 0.8146098852 0.7929136157 + 0.8342829943 0.8151900768 0.7935284972 + 0.8347858191 0.8157703280 0.7941433787 + 0.8352885246 0.8163505197 0.7947583199 + 0.8357869983 0.8169273734 0.7953717113 + 0.8362827897 0.8174930811 0.7959778905 + 0.8367785215 0.8180589080 0.7965841293 + 0.8372743130 0.8186246753 0.7971904278 + 0.8377701044 0.8191903830 0.7977966070 + 0.8382657766 0.8197562099 0.7984027863 + 0.8387616277 0.8203219175 0.7990090847 + 0.8392574191 0.8208876848 0.7996153235 + 0.8397530913 0.8214535117 0.8002215028 + 0.8402497172 0.8220161200 0.8008267879 + 0.8407465219 0.8225740194 0.8014301062 + 0.8412433267 0.8231317997 0.8020334840 + 0.8417400718 0.8236895800 0.8026369214 + 0.8422368765 0.8242474794 0.8032401800 + 0.8427336812 0.8248053193 0.8038436174 + 0.8432304263 0.8253630996 0.8044469953 + 0.8437271714 0.8259209991 0.8050503135 + 0.8442239761 0.8264787793 0.8056536913 + 0.8447151184 0.8270347118 0.8062539101 + 0.8452048898 0.8275880218 0.8068488240 + 0.8456946015 0.8281413913 0.8074436784 + 0.8461843133 0.8286947012 0.8080385923 + 0.8466740251 0.8292480111 0.8086336255 + 0.8471636772 0.8298013210 0.8092284799 + 0.8476533890 0.8303546906 0.8098233938 + 0.8481432199 0.8309080005 0.8104183078 + 0.8486328721 0.8314613104 0.8110132217 + 0.8491188288 0.8320134878 0.8116052747 + 0.8496029973 0.8325635791 0.8121902943 + 0.8500872850 0.8331136107 0.8127751946 + 0.8505715132 0.8336635828 0.8133600950 + 0.8510558009 0.8342136741 0.8139451146 + 0.8515400290 0.8347637057 0.8145300150 + 0.8520243168 0.8353136778 0.8151149154 + 0.8525084853 0.8358637094 0.8156998754 + 0.8529927731 0.8364138007 0.8162847757 + 0.8534749746 0.8369629979 0.8168694973 + 0.8539546728 0.8375040889 0.8174484968 + 0.8544343710 0.8380451798 0.8180274963 + 0.8549141288 0.8385862708 0.8186064959 + 0.8553938270 0.8391274214 0.8191856146 + 0.8558735251 0.8396685123 0.8197646141 + 0.8563532233 0.8402096033 0.8203436136 + 0.8568329215 0.8407506943 0.8209226131 + 0.8573125005 0.8412917852 0.8215016723 + 0.8577917814 0.8418329954 0.8220806718 + 0.8582649827 0.8423717022 0.8226525784 + 0.8587383032 0.8429095149 0.8232210875 + 0.8592115045 0.8434472084 0.8237894773 + 0.8596848249 0.8439850211 0.8243579865 + 0.8601580262 0.8445227742 0.8249264956 + 0.8606312871 0.8450605869 0.8254948854 + 0.8611046076 0.8455983996 0.8260633945 + 0.8615778089 0.8461362123 0.8266319036 + 0.8620511293 0.8466740251 0.8272002935 + 0.8625226021 0.8472099900 0.8277677298 + 0.8629927039 0.8477393985 0.8283293247 + 0.8634628057 0.8482688069 0.8288909197 + 0.8639330268 0.8487980962 0.8294523954 + 0.8644031286 0.8493275046 0.8300139904 + 0.8648731709 0.8498567939 0.8305755854 + 0.8653432727 0.8503862023 0.8311371207 + 0.8658133745 0.8509156108 0.8316987157 + 0.8662835956 0.8514449000 0.8322603106 + 0.8667536974 0.8519743085 0.8328217864 + 0.8672150970 0.8524994254 0.8333820105 + 0.8676754832 0.8530210257 0.8339408040 + 0.8681359291 0.8535426259 0.8344995975 + 0.8685963154 0.8540641069 0.8350583911 + 0.8690567017 0.8545857072 0.8356171846 + 0.8695170879 0.8551073074 0.8361760974 + 0.8699774742 0.8556289077 0.8367348909 + 0.8704379201 0.8561505079 0.8372936845 + 0.8708983064 0.8566719890 0.8378524780 + 0.8713576198 0.8571935892 0.8384112716 + 0.8718056083 0.8577103019 0.8389707208 + 0.8722537160 0.8582252860 0.8395304084 + 0.8727017045 0.8587402105 0.8400899768 + 0.8731498122 0.8592551947 0.8406497240 + 0.8735978007 0.8597701788 0.8412094116 + 0.8740459085 0.8602852225 0.8417689800 + 0.8744938970 0.8608002067 0.8423287272 + 0.8749418855 0.8613150716 0.8428884149 + 0.8753899932 0.8618301153 0.8434481025 + 0.8758366704 0.8623450994 0.8440076709 + 0.8762751818 0.8628504872 0.8445582986 + 0.8767135739 0.8633533716 0.8451061249 + 0.8771520853 0.8638563752 0.8456537724 + 0.8775904775 0.8643593192 0.8462015986 + 0.8780289888 0.8648623228 0.8467493057 + 0.8784673810 0.8653652072 0.8472970724 + 0.8789058924 0.8658682108 0.8478447795 + 0.8793442845 0.8663712144 0.8483924866 + 0.8797827959 0.8668740988 0.8489403129 + 0.8802210093 0.8673771024 0.8494880199 + 0.8806512952 0.8678756952 0.8500298858 + 0.8810817003 0.8683726192 0.8505687714 + 0.8815121055 0.8688694835 0.8511077166 + 0.8819423914 0.8693662882 0.8516464829 + 0.8823727965 0.8698632121 0.8521854281 + 0.8828032017 0.8703600764 0.8527243137 + 0.8832334876 0.8708568811 0.8532631993 + 0.8836638927 0.8713538051 0.8538020849 + 0.8840942979 0.8718507290 0.8543409705 + 0.8845247030 0.8723474741 0.8548799157 + 0.8849477172 0.8728402853 0.8554143906 + 0.8853685856 0.8733280897 0.8559429049 + 0.8857895732 0.8738158941 0.8564714193 + 0.8862105012 0.8743038177 0.8569998741 + 0.8866314888 0.8747916222 0.8575283289 + 0.8870524168 0.8752794862 0.8580567837 + 0.8874734044 0.8757672906 0.8585852981 + 0.8878942728 0.8762552142 0.8591138124 + 0.8883153200 0.8767430186 0.8596423268 + 0.8887361884 0.8772308826 0.8601707816 + 0.8891549706 0.8777185082 0.8606991768 + 0.8895698786 0.8782029152 0.8612251878 + 0.8899849057 0.8786873817 0.8617511988 + 0.8903998733 0.8791717887 0.8622772098 + 0.8908147812 0.8796561956 0.8628032804 + 0.8912298083 0.8801407218 0.8633292913 + 0.8916447759 0.8806251287 0.8638553023 + 0.8920598030 0.8811094761 0.8643813133 + 0.8924747109 0.8815940022 0.8649073243 + 0.8928896785 0.8820784092 0.8654333949 + 0.8933047056 0.8825628161 0.8659594059 + 0.8937178850 0.8830412030 0.8664832711 + 0.8941305876 0.8835136890 0.8670049906 + 0.8945432901 0.8839861751 0.8675267100 + 0.8949561119 0.8844587207 0.8680483103 + 0.8953688145 0.8849312067 0.8685700297 + 0.8957815766 0.8854036927 0.8690915704 + 0.8961942792 0.8858762980 0.8696132898 + 0.8966071010 0.8863487840 0.8701350093 + 0.8970198035 0.8868213296 0.8706566095 + 0.8974326253 0.8872938156 0.8711783290 + 0.8978449106 0.8877663016 0.8716999292 + 0.8982529044 0.8882371187 0.8722208142 + 0.8986608982 0.8887075186 0.8727415204 + 0.8990687728 0.8891779184 0.8732621074 + 0.8994768262 0.8896481991 0.8737828135 + 0.8998848200 0.8901185989 0.8743034005 + 0.9002928138 0.8905889988 0.8748241067 + 0.9007008076 0.8910593987 0.8753446937 + 0.9011088014 0.8915297985 0.8758653998 + 0.9015167952 0.8920001984 0.8763859868 + 0.9019247293 0.8924705982 0.8769065738 + 0.9023321867 0.8929408789 0.8774272799 + 0.9027374983 0.8934035897 0.8779382706 + 0.9031428099 0.8938655853 0.8784481287 + 0.9035481215 0.8943277001 0.8789578080 + 0.9039533734 0.8947896957 0.8794676065 + 0.9043586850 0.8952516913 0.8799774051 + 0.9047639966 0.8957138062 0.8804872036 + 0.9051693082 0.8961758018 0.8809968829 + 0.9055746198 0.8966377974 0.8815066814 + 0.9059798717 0.8970997930 0.8820164800 + 0.9063851833 0.8975619078 0.8825262785 + 0.9067893028 0.8980239034 0.8830360174 + 0.9071872830 0.8984869719 0.8835430741 + 0.9075853229 0.8989502788 0.8840497136 + 0.9079833031 0.8994135857 0.8845561743 + 0.9083812833 0.8998768926 0.8850628138 + 0.9087793231 0.9003401995 0.8855693936 + 0.9091774225 0.9008035064 0.8860759735 + 0.9095754027 0.9012668133 0.8865826130 + 0.9099733829 0.9017301202 0.8870890737 + 0.9103714228 0.9021934271 0.8875957131 + 0.9107694030 0.9026566744 0.8881022930 + 0.9111673832 0.9031199813 0.8886088729 + 0.9115555286 0.9035797715 0.8891084790 + 0.9119430780 0.9040381908 0.8896042705 + 0.9123308063 0.9044964910 0.8901001811 + 0.9127184153 0.9049547911 0.8905960917 + 0.9131060839 0.9054132104 0.8910920024 + 0.9134936929 0.9058715105 0.8915879130 + 0.9138813019 0.9063298106 0.8920838237 + 0.9142689705 0.9067881703 0.8925796747 + 0.9146565795 0.9072464705 0.8930755854 + 0.9150443077 0.9077047706 0.8935714960 + 0.9154319167 0.9081631899 0.8940674067 + 0.9158164263 0.9086192250 0.8945624232 + 0.9161984921 0.9090703130 0.8950551748 + 0.9165806770 0.9095214009 0.8955479264 + 0.9169628024 0.9099724889 0.8960406780 + 0.9173449874 0.9104235768 0.8965334892 + 0.9177271724 0.9108747244 0.8970261812 + 0.9181092978 0.9113258123 0.8975189924 + 0.9184914827 0.9117770195 0.8980118036 + 0.9188736081 0.9122281075 0.8985044956 + 0.9192557931 0.9126791954 0.8989973068 + 0.9196379781 0.9131302834 0.8994901180 + 0.9200199842 0.9135813713 0.8999828100 + 0.9203976989 0.9140260220 0.9004676938 + 0.9207754731 0.9144688249 0.9009500146 + 0.9211533070 0.9149116278 0.9014322758 + 0.9215310812 0.9153543711 0.9019145966 + 0.9219087958 0.9157971740 0.9023969173 + 0.9222866297 0.9162399769 0.9028791785 + 0.9226644039 0.9166827798 0.9033614993 + 0.9230421185 0.9171255827 0.9038438201 + 0.9234198928 0.9175683856 0.9043260813 + 0.9237977266 0.9180111885 0.9048084021 + 0.9241755009 0.9184539914 0.9052907228 + 0.9245520234 0.9188957214 0.9057729244 + 0.9249256849 0.9193243980 0.9062542915 + 0.9252995253 0.9197530150 0.9067355990 + 0.9256731868 0.9201816916 0.9072170258 + 0.9260470271 0.9206103086 0.9076983929 + 0.9264206886 0.9210389256 0.9081798196 + 0.9267945290 0.9214676023 0.9086611271 + 0.9271683097 0.9218962193 0.9091424942 + 0.9275419712 0.9223248959 0.9096239209 + 0.9279158115 0.9227535129 0.9101052284 + 0.9282894731 0.9231821895 0.9105865955 + 0.9286633134 0.9236108065 0.9110680223 + 0.9290362000 0.9240378141 0.9115486741 + 0.9294080734 0.9244576097 0.9120259881 + 0.9297800064 0.9248775244 0.9125033021 + 0.9301518798 0.9252973199 0.9129806757 + 0.9305236936 0.9257171154 0.9134579897 + 0.9308956265 0.9261369109 0.9139353037 + 0.9312674999 0.9265568256 0.9144126773 + 0.9316393733 0.9269766212 0.9148899913 + 0.9320111871 0.9273964167 0.9153673053 + 0.9323831201 0.9278162718 0.9158446193 + 0.9327549934 0.9282361269 0.9163219929 + 0.9331269264 0.9286559224 0.9167993069 + 0.9334965944 0.9290750027 0.9172763824 + 0.9338625073 0.9294890165 0.9177514911 + 0.9342283010 0.9299029708 0.9182265997 + 0.9345940948 0.9303171039 0.9187017083 + 0.9349600077 0.9307311177 0.9191766977 + 0.9353258014 0.9311450720 0.9196518064 + 0.9356915951 0.9315592051 0.9201269150 + 0.9360575080 0.9319732189 0.9206020236 + 0.9364233017 0.9323871732 0.9210770726 + 0.9367890954 0.9328011870 0.9215521812 + 0.9371550083 0.9332153201 0.9220272899 + 0.9375208020 0.9336292744 0.9225023985 + 0.9378861189 0.9340432882 0.9229773879 + 0.9382457137 0.9344478846 0.9234445095 + 0.9386053085 0.9348514080 0.9239102006 + 0.9389649034 0.9352548122 0.9243760109 + 0.9393244982 0.9356582165 0.9248417020 + 0.9396840930 0.9360616207 0.9253073931 + 0.9400436878 0.9364650846 0.9257732034 + 0.9404032826 0.9368684888 0.9262388945 + 0.9407628775 0.9372718930 0.9267047048 + 0.9411224723 0.9376752973 0.9271703959 + 0.9414821267 0.9380788207 0.9276362062 + 0.9418417215 0.9384822249 0.9281018972 + 0.9422013164 0.9388856292 0.9285677075 + 0.9425578713 0.9392852187 0.9290300012 + 0.9429129958 0.9396802187 0.9294880033 + 0.9432681203 0.9400752783 0.9299458861 + 0.9436231852 0.9404702783 0.9304038882 + 0.9439783096 0.9408653975 0.9308617711 + 0.9443333149 0.9412603974 0.9313197732 + 0.9446883798 0.9416555166 0.9317777753 + 0.9450435042 0.9420505762 0.9322357178 + 0.9453986287 0.9424455762 0.9326937199 + 0.9457536936 0.9428406954 0.9331517220 + 0.9461086988 0.9432356954 0.9336096048 + 0.9464638233 0.9436308146 0.9340676069 + 0.9468188286 0.9440258145 0.9345256090 + 0.9471713901 0.9444158077 0.9349750280 + 0.9475240111 0.9448049068 0.9354225993 + 0.9478765726 0.9451941252 0.9358702898 + 0.9482290745 0.9455832243 0.9363179803 + 0.9485816956 0.9459723234 0.9367656112 + 0.9489343166 0.9463614225 0.9372133017 + 0.9492868781 0.9467505217 0.9376609921 + 0.9496394992 0.9471396804 0.9381086826 + 0.9499921203 0.9475287795 0.9385563135 + 0.9503446817 0.9479178786 0.9390040040 + 0.9506971836 0.9483069777 0.9394516945 + 0.9510498047 0.9486961961 0.9398993254 + 0.9514018297 0.9490848184 0.9403468966 + 0.9517515898 0.9494650960 0.9407904744 + 0.9521014094 0.9498453736 0.9412341118 + 0.9524511099 0.9502257109 0.9416778088 + 0.9528009295 0.9506059885 0.9421213865 + 0.9531506896 0.9509863257 0.9425650239 + 0.9535005093 0.9513666034 0.9430087209 + 0.9538503289 0.9517468810 0.9434522986 + 0.9542000890 0.9521272182 0.9438959956 + 0.9545499086 0.9525074959 0.9443395734 + 0.9548997283 0.9528877735 0.9447832108 + 0.9552494287 0.9532681704 0.9452269077 + 0.9555991888 0.9536485076 0.9456704855 + 0.9559475183 0.9540281892 0.9461137056 + 0.9562901855 0.9543992281 0.9465476871 + 0.9566329122 0.9547703266 0.9469817877 + 0.9569756985 0.9551414251 0.9474158287 + 0.9573184252 0.9555124044 0.9478498101 + 0.9576610923 0.9558835030 0.9482839108 + 0.9580038786 0.9562546015 0.9487178922 + 0.9583466053 0.9566255808 0.9491519928 + 0.9586892724 0.9569966793 0.9495859742 + 0.9590321183 0.9573677778 0.9500200152 + 0.9593747854 0.9577388167 0.9504541159 + 0.9597175121 0.9581099153 0.9508880973 + 0.9600601792 0.9584810138 0.9513220787 + 0.9604027271 0.9588519931 0.9517561793 + 0.9607350230 0.9592133760 0.9521834254 + 0.9610671997 0.9595736265 0.9526095986 + 0.9613994956 0.9599336982 0.9530358911 + 0.9617316723 0.9602938294 0.9534621239 + 0.9620639086 0.9606539011 0.9538882971 + 0.9623962045 0.9610139728 0.9543144703 + 0.9627283812 0.9613741040 0.9547407031 + 0.9630606174 0.9617341757 0.9551668763 + 0.9633929133 0.9620944262 0.9555931091 + 0.9637250900 0.9624544978 0.9560192823 + 0.9640573859 0.9628146291 0.9564455152 + 0.9643896222 0.9631747007 0.9568716884 + 0.9647217989 0.9635347724 0.9572979212 + 0.9650493860 0.9638900161 0.9577190876 + 0.9653742909 0.9642401934 0.9581351280 + 0.9656991959 0.9645903707 0.9585509896 + 0.9660241008 0.9649404883 0.9589669704 + 0.9663490057 0.9652907252 0.9593828917 + 0.9666739106 0.9656409025 0.9597988725 + 0.9669988155 0.9659910798 0.9602147937 + 0.9673237205 0.9663413167 0.9606307745 + 0.9676485062 0.9666914940 0.9610466957 + 0.9679734111 0.9670416713 0.9614626765 + 0.9682983160 0.9673919082 0.9618785977 + 0.9686232209 0.9677420855 0.9622945786 + 0.9689481258 0.9680922031 0.9627104998 + 0.9692727923 0.9684423804 0.9631264806 + 0.9695920944 0.9687845111 0.9635347724 + 0.9699112773 0.9691258073 0.9639422894 + 0.9702305794 0.9694671035 0.9643498063 + 0.9705498815 0.9698083997 0.9647573233 + 0.9708691835 0.9701496959 0.9651647806 + 0.9711884260 0.9704909921 0.9655722976 + 0.9715077281 0.9708322883 0.9659798741 + 0.9718269706 0.9711735845 0.9663873911 + 0.9721462131 0.9715148807 0.9667949080 + 0.9724655151 0.9718561769 0.9672024250 + 0.9727848172 0.9721974730 0.9676098824 + 0.9731040001 0.9725388288 0.9680173993 + 0.9734233022 0.9728801250 0.9684249163 + 0.9737418890 0.9732202291 0.9688311219 + 0.9740585089 0.9735528827 0.9692280293 + 0.9743750095 0.9738854766 0.9696248770 + 0.9746916294 0.9742181897 0.9700219035 + 0.9750080705 0.9745507836 0.9704188108 + 0.9753245711 0.9748834968 0.9708157182 + 0.9756411910 0.9752160907 0.9712126255 + 0.9759576917 0.9755488038 0.9716095924 + 0.9762743115 0.9758813977 0.9720064998 + 0.9765908122 0.9762141109 0.9724034071 + 0.9769073129 0.9765467048 0.9728003144 + 0.9772238731 0.9768794179 0.9731972814 + 0.9775403738 0.9772120118 0.9735941887 + 0.9778568745 0.9775447249 0.9739910960 + 0.9781730771 0.9778758287 0.9743868709 + 0.9784877896 0.9781979918 0.9747753739 + 0.9788025022 0.9785202742 0.9751638770 + 0.9791172147 0.9788424969 0.9755523801 + 0.9794319868 0.9791647196 0.9759408832 + 0.9797466993 0.9794870019 0.9763293862 + 0.9800614119 0.9798092246 0.9767180085 + 0.9803761244 0.9801315069 0.9771065116 + 0.9806908965 0.9804537296 0.9774950147 + 0.9810056090 0.9807758927 0.9778835177 + 0.9813203216 0.9810981750 0.9782720208 + 0.9816349745 0.9814203978 0.9786605239 + 0.9819498062 0.9817426801 0.9790490866 + 0.9822645187 0.9820649028 0.9794375896 + 0.9825791121 0.9823871255 0.9798260927 + 0.9828888774 0.9827020764 0.9802024961 + 0.9831985831 0.9830166101 0.9805781245 + 0.9835082889 0.9833310843 0.9809536934 + 0.9838181138 0.9836456776 0.9813293219 + 0.9841278195 0.9839602113 0.9817048907 + 0.9844375253 0.9842746854 0.9820805192 + 0.9847471714 0.9845892191 0.9824560881 + 0.9850569963 0.9849038124 0.9828317761 + 0.9853667021 0.9852182865 0.9832074046 + 0.9856764078 0.9855328202 0.9835829735 + 0.9859861732 0.9858472943 0.9839586020 + 0.9862958789 0.9861618876 0.9843341708 + 0.9866055846 0.9864764214 0.9847097993 + 0.9869154096 0.9867908955 0.9850854278 + 0.9872199893 0.9871007800 0.9854502082 + 0.9875209928 0.9874067903 0.9858055115 + 0.9878221154 0.9877126813 0.9861608148 + 0.9881231189 0.9880186915 0.9865159988 + 0.9884241223 0.9883245826 0.9868713021 + 0.9887251854 0.9886305928 0.9872264862 + 0.9890261889 0.9889364839 0.9875817895 + 0.9893273115 0.9892424941 0.9879369736 + 0.9896283150 0.9895483851 0.9882922769 + 0.9899293780 0.9898543954 0.9886475801 + 0.9902303815 0.9901602864 0.9890028238 + 0.9905313849 0.9904662967 0.9893581271 + 0.9908325076 0.9907721877 0.9897133112 + 0.9911335111 0.9910781980 0.9900686145 + 0.9914345741 0.9913840890 0.9904237986 + 0.9917227030 0.9916865230 0.9907621741 + 0.9920099974 0.9919885993 0.9910988212 + 0.9922972918 0.9922906160 0.9914355278 + 0.9925847054 0.9925926924 0.9917721152 + 0.9928719997 0.9928947091 0.9921088219 + 0.9931594133 0.9931967854 0.9924454093 + 0.9934467077 0.9934988022 0.9927819967 + 0.9937341213 0.9938008785 0.9931187034 + 0.9940214157 0.9941028953 0.9934552908 + 0.9943088293 0.9944049716 0.9937918782 + 0.9945961237 0.9947069883 0.9941285849 + 0.9948834777 0.9950091243 0.9944651723 + 0.9951707721 0.9953110814 0.9948018789 + 0.9954581857 0.9956132174 0.9951385260 + 0.9957451820 0.9959133267 0.9954729080 + 0.9960289001 0.9961857200 0.9957746863 + 0.9963124990 0.9964581728 0.9960765243 + 0.9965962172 0.9967306256 0.9963783026 + 0.9968798161 0.9970030785 0.9966800809 + 0.9971634746 0.9972754717 0.9969819188 + 0.9974470735 0.9975479841 0.9972836971 + 0.9977307916 0.9978203773 0.9975854754 + 0.9980143905 0.9980928898 0.9978873134 + 0.9982981086 0.9983652830 0.9981892109 + 0.9985817075 0.9986377954 0.9984909892 + 0.9988654256 0.9989101887 0.9987928271 + 0.9991490245 0.9991827011 0.9990946054 + 0.9994326830 0.9994550943 0.9993963838 + 0.9997162819 0.9997276068 0.9996982217 + 1.0000000000 1.0000000000 1.0000000000 +} diff --git a/rpplugins/color_correction/resources/film_luts_raw/fujifilm_f-250.spi1d b/rpplugins/color_correction/resources/film_luts_raw/fujifilm_f-250.spi1d new file mode 100644 index 0000000..cf2405a --- /dev/null +++ b/rpplugins/color_correction/resources/film_luts_raw/fujifilm_f-250.spi1d @@ -0,0 +1,1030 @@ +Version 1 +From 0.0 1.0 +Length 1024 +Components 3 +{ + 0.0000000000 0.0000000000 0.0000000000 + 0.0340563506 0.0275065694 0.0159309693 + 0.0581281595 0.0446017683 0.0286259800 + 0.0766732469 0.0585205704 0.0393032692 + 0.0912864283 0.0693459511 0.0486846492 + 0.1037112027 0.0783905834 0.0571168698 + 0.1149740964 0.0866255537 0.0647848472 + 0.1255443990 0.0943730623 0.0718255714 + 0.1358117014 0.1018529013 0.0783746019 + 0.1458894014 0.1092692986 0.0845360085 + 0.1554104984 0.1165430993 0.0902841464 + 0.1642753929 0.1235136986 0.0956311375 + 0.1725185066 0.1300638020 0.1007089019 + 0.1802159995 0.1362310052 0.1055677980 + 0.1874677986 0.1420270056 0.1101925969 + 0.1943995059 0.1475103050 0.1146183014 + 0.2010439038 0.1526764929 0.1188452989 + 0.2075248957 0.1576137990 0.1229263991 + 0.2138666064 0.1623017043 0.1268835962 + 0.2200817019 0.1667637974 0.1307622045 + 0.2262571007 0.1710768938 0.1345600933 + 0.2322959006 0.1752613038 0.1383388937 + 0.2381743044 0.1792901009 0.1420553029 + 0.2439599037 0.1831696928 0.1457192004 + 0.2495301962 0.1869384944 0.1493068933 + 0.2549104095 0.1905891001 0.1528359056 + 0.2600974143 0.1941210032 0.1562989056 + 0.2651267946 0.1975311041 0.1596667022 + 0.2699950933 0.2007963061 0.1629731953 + 0.2746872902 0.2039687932 0.1662473977 + 0.2792500854 0.2070634067 0.1694674939 + 0.2837044001 0.2100957930 0.1726872027 + 0.2880541086 0.2130752951 0.1758597940 + 0.2922781110 0.2160121948 0.1789810956 + 0.2963983119 0.2189164013 0.1820618957 + 0.3004223108 0.2217878997 0.1850834042 + 0.3043056130 0.2246080041 0.1880794019 + 0.3080697954 0.2273644060 0.1910150051 + 0.3117355108 0.2300619930 0.1939160973 + 0.3153220117 0.2327065021 0.1967920959 + 0.3188439906 0.2353048027 0.1996531039 + 0.3223091066 0.2378443033 0.2024717033 + 0.3257097900 0.2403286994 0.2052704990 + 0.3290207982 0.2427732944 0.2080609947 + 0.3322731853 0.2452045977 0.2108310014 + 0.3354865909 0.2476018071 0.2135528028 + 0.3386512101 0.2499758005 0.2162420005 + 0.3417851031 0.2523289025 0.2188850939 + 0.3448846936 0.2546671927 0.2214843929 + 0.3479135036 0.2569605112 0.2240575999 + 0.3508971930 0.2591898143 0.2266031057 + 0.3538430929 0.2613660097 0.2291243970 + 0.3567287922 0.2634985149 0.2316229939 + 0.3595845103 0.2655822933 0.2340888977 + 0.3624258935 0.2676230967 0.2365391999 + 0.3652456105 0.2696104944 0.2389807999 + 0.3680748940 0.2715514004 0.2413962036 + 0.3708611131 0.2734310031 0.2437824011 + 0.3735972047 0.2752597928 0.2461562008 + 0.3762691021 0.2770377994 0.2485167980 + 0.3789086044 0.2787886858 0.2508699000 + 0.3814966083 0.2805095911 0.2532047033 + 0.3840735853 0.2822039127 0.2555142939 + 0.3866173923 0.2838774920 0.2578059137 + 0.3891361058 0.2855109870 0.2600739002 + 0.3916285038 0.2871398032 0.2623229921 + 0.3941093087 0.2887691855 0.2645553052 + 0.3965596855 0.2904030979 0.2667697966 + 0.3989767134 0.2920188010 0.2689580023 + 0.4013713896 0.2936233878 0.2711285055 + 0.4037455022 0.2952230871 0.2732937932 + 0.4060991108 0.2968241870 0.2754479051 + 0.4084275067 0.2984308898 0.2775818110 + 0.4107517004 0.3000445962 0.2796877921 + 0.4130510986 0.3016583025 0.2817656994 + 0.4153209031 0.3032869101 0.2838352919 + 0.4175666869 0.3049050868 0.2858906984 + 0.4197983146 0.3065397143 0.2879244983 + 0.4220117033 0.3081744909 0.2899451852 + 0.4241906106 0.3098129034 0.2919526100 + 0.4263457954 0.3114565909 0.2939467132 + 0.4284875989 0.3130967915 0.2959286869 + 0.4306012988 0.3147349954 0.2978995144 + 0.4326950014 0.3163720965 0.2998577058 + 0.4347662032 0.3180099130 0.3018037975 + 0.4368287027 0.3196572065 0.3037435114 + 0.4388831854 0.3213165104 0.3056769073 + 0.4409214854 0.3229748011 0.3075988889 + 0.4429436028 0.3246040940 0.3095020056 + 0.4449625909 0.3262285888 0.3113960922 + 0.4469791055 0.3278538883 0.3132843077 + 0.4489935935 0.3294833004 0.3151693940 + 0.4509986937 0.3311119974 0.3170453012 + 0.4529815018 0.3327403069 0.3189097047 + 0.4549526870 0.3343681991 0.3207617104 + 0.4569247961 0.3359952867 0.3225966990 + 0.4588770866 0.3376198113 0.3244307935 + 0.4608316123 0.3392421007 0.3262627125 + 0.4627926052 0.3408617973 0.3280918002 + 0.4647417963 0.3424758017 0.3298951089 + 0.4666925967 0.3440926969 0.3316844106 + 0.4686441123 0.3457145989 0.3334603012 + 0.4705764949 0.3473288119 0.3352111876 + 0.4724830091 0.3489370942 0.3369530141 + 0.4743657112 0.3505378962 0.3386858106 + 0.4762322009 0.3521256149 0.3404065073 + 0.4780816138 0.3537108004 0.3421171010 + 0.4799089134 0.3552944958 0.3438138068 + 0.4817309082 0.3568659127 0.3454996943 + 0.4835452139 0.3584319055 0.3471781015 + 0.4853380024 0.3599914014 0.3488380909 + 0.4871332943 0.3615401089 0.3504877090 + 0.4889298975 0.3630783856 0.3521300852 + 0.4907036126 0.3646185100 0.3537611961 + 0.4924693108 0.3661572933 0.3553892970 + 0.4942173064 0.3676883876 0.3570109904 + 0.4959532917 0.3692195117 0.3586300910 + 0.4976806045 0.3707506955 0.3602473140 + 0.4994089901 0.3722806871 0.3618556857 + 0.5011367202 0.3738102019 0.3634608984 + 0.5028569102 0.3753306866 0.3650502861 + 0.5045688748 0.3768486083 0.3666361868 + 0.5062633157 0.3783572018 0.3682140112 + 0.5079504251 0.3798607886 0.3697811067 + 0.5096306801 0.3813571036 0.3713372052 + 0.5112873912 0.3828429878 0.3728885055 + 0.5129328966 0.3843210936 0.3744373918 + 0.5145742297 0.3857963085 0.3759793937 + 0.5162146091 0.3872702122 0.3775196970 + 0.5178315043 0.3887482882 0.3790464103 + 0.5194466114 0.3902272880 0.3805716932 + 0.5210654736 0.3916977048 0.3820922077 + 0.5226833224 0.3931671977 0.3836125135 + 0.5242862105 0.3946341872 0.3851282001 + 0.5258901119 0.3961010873 0.3866432905 + 0.5275049806 0.3975507915 0.3881508112 + 0.5291187763 0.3990002871 0.3896571100 + 0.5307204127 0.4004558921 0.3911463916 + 0.5323221087 0.4019115865 0.3926354945 + 0.5339249969 0.4033721089 0.3941121101 + 0.5355278850 0.4048328102 0.3955886960 + 0.5371186137 0.4062801898 0.3970466852 + 0.5387089849 0.4077258110 0.3985038996 + 0.5402762294 0.4091561139 0.3999438882 + 0.5418404937 0.4105820954 0.4013813138 + 0.5433958173 0.4120019972 0.4028140903 + 0.5449482799 0.4134188890 0.4042451978 + 0.5464795232 0.4148291945 0.4056676030 + 0.5479968190 0.4162329137 0.4070835114 + 0.5495104194 0.4176310897 0.4084953070 + 0.5510190725 0.4190171063 0.4099004865 + 0.5525225997 0.4204013050 0.4113028049 + 0.5540046096 0.4217655063 0.4126909971 + 0.5554866195 0.4231297076 0.4140791893 + 0.5569679737 0.4244849980 0.4154512882 + 0.5584493279 0.4258384109 0.4168216884 + 0.5599154234 0.4271919131 0.4181849957 + 0.5613729954 0.4285452962 0.4195438027 + 0.5628271103 0.4298977852 0.4209015071 + 0.5642738938 0.4312470853 0.4222564995 + 0.5657206774 0.4325963855 0.4236116111 + 0.5671554208 0.4339382946 0.4249607027 + 0.5685896277 0.4352790117 0.4263094068 + 0.5700142980 0.4366140068 0.4276516140 + 0.5714316964 0.4379422963 0.4289883971 + 0.5728462934 0.4392705858 0.4303236902 + 0.5742422938 0.4405961931 0.4316473901 + 0.5756382942 0.4419218898 0.4329712093 + 0.5770087838 0.4432437122 0.4342881143 + 0.5783665776 0.4445624053 0.4356010854 + 0.5797222257 0.4458796084 0.4369125068 + 0.5810663104 0.4471733868 0.4382139146 + 0.5824103951 0.4484671950 0.4395152032 + 0.5837360024 0.4497536123 0.4408144057 + 0.5850501060 0.4510329962 0.4421119988 + 0.5863640904 0.4523124993 0.4434092939 + 0.5876724124 0.4535883069 0.4446893036 + 0.5889807940 0.4548639953 0.4459693134 + 0.5902798176 0.4561336040 0.4472444057 + 0.5915662050 0.4573903978 0.4485121965 + 0.5928525925 0.4586473107 0.4497799873 + 0.5941187143 0.4598957002 0.4510425925 + 0.5953786969 0.4611397982 0.4523034990 + 0.5966371894 0.4623838067 0.4535635114 + 0.5978767872 0.4636138082 0.4548071027 + 0.5991163850 0.4648432136 0.4560508132 + 0.6003507972 0.4660690129 0.4572936893 + 0.6015748978 0.4672825933 0.4585348964 + 0.6027989984 0.4684962034 0.4597761929 + 0.6040027738 0.4697115123 0.4610106051 + 0.6051900983 0.4709289968 0.4622390866 + 0.6063774228 0.4721465111 0.4634675980 + 0.6075572968 0.4733569920 0.4646885097 + 0.6087344885 0.4745635092 0.4659062028 + 0.6099116802 0.4757699072 0.4671239853 + 0.6110656857 0.4769654870 0.4683316052 + 0.6122164130 0.4781579971 0.4695374966 + 0.6133670807 0.4793503881 0.4707433879 + 0.6145061851 0.4805291891 0.4719372094 + 0.6156448722 0.4817059934 0.4731302857 + 0.6167832017 0.4828827083 0.4743235111 + 0.6179025769 0.4840502143 0.4755181074 + 0.6190220714 0.4852168858 0.4767127037 + 0.6201403141 0.4863835871 0.4779073000 + 0.6212201118 0.4875405133 0.4790931046 + 0.6222999096 0.4886966050 0.4802789986 + 0.6233797073 0.4898526967 0.4814648926 + 0.6244452000 0.4909954071 0.4826442897 + 0.6255105734 0.4921365082 0.4838235974 + 0.6265758872 0.4932776093 0.4850027859 + 0.6276177168 0.4943977892 0.4861753881 + 0.6286571026 0.4955132902 0.4873471856 + 0.6296964884 0.4966287911 0.4885190129 + 0.6307348013 0.4977380931 0.4896813035 + 0.6317728162 0.4988445044 0.4908406138 + 0.6328107715 0.4999508858 0.4919998944 + 0.6338409781 0.5010526180 0.4931561053 + 0.6348659992 0.5021498799 0.4943102002 + 0.6358910799 0.5032472014 0.4954642057 + 0.6369110942 0.5043411851 0.4966160059 + 0.6379228830 0.5054274201 0.4977641106 + 0.6389346719 0.5065134764 0.4989121854 + 0.6399447918 0.5075992942 0.5000599027 + 0.6409429908 0.5086715221 0.5012037158 + 0.6419411898 0.5097436905 0.5023475885 + 0.6429393291 0.5108159184 0.5034914017 + 0.6439177990 0.5118789077 0.5046312809 + 0.6448913813 0.5129379034 0.5057700872 + 0.6458649039 0.5139970183 0.5069088936 + 0.6468328834 0.5150539875 0.5080435872 + 0.6477934122 0.5161070824 0.5091723204 + 0.6487538815 0.5171602964 0.5103009939 + 0.6497141719 0.5182133913 0.5114297271 + 0.6506603956 0.5192496181 0.5125468969 + 0.6516065001 0.5202844143 0.5136641264 + 0.6525526047 0.5213190913 0.5147812963 + 0.6534926891 0.5223445892 0.5158960819 + 0.6544277072 0.5233588815 0.5170087814 + 0.6553627253 0.5243731141 0.5181214809 + 0.6562976837 0.5253874063 0.5192341805 + 0.6572293043 0.5263924003 0.5203433037 + 0.6581609249 0.5273966789 0.5214524269 + 0.6590924859 0.5284010172 0.5225614905 + 0.6600255966 0.5294005275 0.5236659050 + 0.6609606147 0.5303912163 0.5247640014 + 0.6618955731 0.5313820243 0.5258620977 + 0.6628304720 0.5323727131 0.5269600749 + 0.6637492776 0.5333474278 0.5280525088 + 0.6646643877 0.5343161225 0.5291435122 + 0.6655796170 0.5352846980 0.5302343965 + 0.6664931774 0.5362530947 0.5313249230 + 0.6673964858 0.5372167230 0.5324121714 + 0.6682997942 0.5381802917 0.5334994793 + 0.6692031026 0.5391438007 0.5345867276 + 0.6701043844 0.5401027799 0.5356699824 + 0.6710026860 0.5410515070 0.5367466807 + 0.6719009876 0.5420001745 0.5378234982 + 0.6727992892 0.5429489017 0.5389001966 + 0.6736878753 0.5438944101 0.5399749279 + 0.6745703220 0.5448371172 0.5410481095 + 0.6754528284 0.5457797050 0.5421212912 + 0.6763352156 0.5467222929 0.5431944728 + 0.6772043705 0.5476604104 0.5442599058 + 0.6780694127 0.5485960841 0.5453224778 + 0.6789343953 0.5495318174 0.5463851094 + 0.6797993779 0.5504674911 0.5474476814 + 0.6806520224 0.5513973236 0.5485045910 + 0.6815025806 0.5523251891 0.5495604277 + 0.6823530793 0.5532531142 0.5506160855 + 0.6832036972 0.5541810989 0.5516719222 + 0.6840479970 0.5551018715 0.5527248979 + 0.6848915219 0.5560209155 0.5537775159 + 0.6857351065 0.5569398999 0.5548300743 + 0.6865785718 0.5578588843 0.5558826923 + 0.6874216795 0.5587705970 0.5569267869 + 0.6882647872 0.5596801043 0.5579692721 + 0.6891077757 0.5605894923 0.5590118766 + 0.6899508238 0.5614989996 0.5600544214 + 0.6907768250 0.5624088049 0.5610944033 + 0.6915978789 0.5633186102 0.5621334910 + 0.6924189925 0.5642284751 0.5631725788 + 0.6932401061 0.5651383996 0.5642117262 + 0.6940519214 0.5660479069 0.5652444959 + 0.6948580742 0.5669571161 0.5662732720 + 0.6956644058 0.5678663254 0.5673021078 + 0.6964706779 0.5687754750 0.5683308840 + 0.6972733736 0.5696833730 0.5693569779 + 0.6980714798 0.5705887079 0.5703790784 + 0.6988695264 0.5714939833 0.5714011788 + 0.6996675134 0.5723993182 0.5724232793 + 0.7004622221 0.5733036995 0.5734450221 + 0.7012382150 0.5741962790 0.5744643211 + 0.7020143270 0.5750889182 0.5754836798 + 0.7027903795 0.5759814978 0.5765029788 + 0.7035663724 0.5768741965 0.5775223970 + 0.7043431997 0.5777689219 0.5785338283 + 0.7051200867 0.5786644220 0.5795432925 + 0.7058969736 0.5795599818 0.5805526972 + 0.7066739202 0.5804554820 0.5815622211 + 0.7074453831 0.5813494921 0.5825701952 + 0.7082093954 0.5822402835 0.5835762024 + 0.7089732885 0.5831311941 0.5845820904 + 0.7097373009 0.5840221047 0.5855880976 + 0.7105011940 0.5849128962 0.5865939856 + 0.7112401128 0.5857965946 0.5875905156 + 0.7119778991 0.5866792202 0.5885863900 + 0.7127156258 0.5875617862 0.5895823240 + 0.7134532928 0.5884444714 0.5905781984 + 0.7141891718 0.5893244147 0.5915713906 + 0.7149226069 0.5901988745 0.5925608873 + 0.7156559825 0.5910735130 0.5935503244 + 0.7163894176 0.5919480920 0.5945397019 + 0.7171227932 0.5928226709 0.5955291986 + 0.7178444862 0.5936961174 0.5965164900 + 0.7185636759 0.5945690870 0.5975033045 + 0.7192828059 0.5954421759 0.5984901190 + 0.7200019956 0.5963152051 0.5994768739 + 0.7207183242 0.5971875191 0.6004620194 + 0.7214186788 0.5980507731 0.6014366150 + 0.7221192122 0.5989142060 0.6024110913 + 0.7228196263 0.5997775197 0.6033856869 + 0.7235201001 0.6006407738 0.6043602824 + 0.7242172956 0.6015027165 0.6053301096 + 0.7249100804 0.6023617983 0.6062927842 + 0.7256028056 0.6032208800 0.6072555184 + 0.7262955904 0.6040800214 0.6082183123 + 0.7269883156 0.6049389839 0.6091809869 + 0.7276725173 0.6057918072 0.6101375222 + 0.7283511758 0.6066387892 0.6110895872 + 0.7290298939 0.6074858904 0.6120417714 + 0.7297086120 0.6083328724 0.6129938960 + 0.7303872705 0.6091799736 0.6139460802 + 0.7310575843 0.6100224853 0.6148930788 + 0.7317247987 0.6108626127 0.6158381104 + 0.7323920727 0.6117026210 0.6167830825 + 0.7330592871 0.6125426888 0.6177281737 + 0.7337265015 0.6133828163 0.6186732054 + 0.7343794703 0.6142179966 0.6196153164 + 0.7350285053 0.6150509715 0.6205565929 + 0.7356774211 0.6158841252 0.6214978099 + 0.7363263965 0.6167172194 0.6224390864 + 0.7369753718 0.6175503135 0.6233803034 + 0.7376106977 0.6183786988 0.6243141890 + 0.7382416129 0.6192048192 0.6252453923 + 0.7388725281 0.6200309992 0.6261765957 + 0.7395033836 0.6208571196 0.6271077991 + 0.7401342988 0.6216832995 0.6280390024 + 0.7407568097 0.6225084066 0.6289677024 + 0.7413746715 0.6233326197 0.6298949122 + 0.7419925928 0.6241568923 0.6308221221 + 0.7426105142 0.6249812245 0.6317493916 + 0.7432283759 0.6258054972 0.6326766014 + 0.7438343167 0.6266260743 0.6335960031 + 0.7444267869 0.6274409294 0.6345061064 + 0.7450193167 0.6282557249 0.6354162097 + 0.7456117868 0.6290705204 0.6363263130 + 0.7462043166 0.6298853159 0.6372364163 + 0.7467948198 0.6306993961 0.6381446719 + 0.7473781109 0.6315096021 0.6390461922 + 0.7479612827 0.6323196888 0.6399477124 + 0.7485445142 0.6331298947 0.6408491731 + 0.7491278052 0.6339399815 0.6417506933 + 0.7497109771 0.6347501874 0.6426522136 + 0.7502849102 0.6355507970 0.6435450912 + 0.7508574128 0.6363490820 0.6444365978 + 0.7514299750 0.6371474862 0.6453281045 + 0.7520025969 0.6379457712 0.6462196112 + 0.7525750995 0.6387441158 0.6471111178 + 0.7531384230 0.6395425200 0.6479977965 + 0.7536910176 0.6403411031 0.6488788128 + 0.7542436123 0.6411396861 0.6497598290 + 0.7547962070 0.6419383287 0.6506407857 + 0.7553488016 0.6427369118 0.6515218019 + 0.7559013963 0.6435353756 0.6524028182 + 0.7564553022 0.6443219781 0.6532747746 + 0.7570090890 0.6451072097 0.6541464925 + 0.7575628757 0.6458923221 0.6550180912 + 0.7581167817 0.6466773748 0.6558898091 + 0.7586706281 0.6474626064 0.6567614079 + 0.7592213154 0.6482473016 0.6576269865 + 0.7597671151 0.6490309238 0.6584824920 + 0.7603129745 0.6498146057 0.6593379974 + 0.7608588934 0.6505982876 0.6601936221 + 0.7614046931 0.6513819098 0.6610491276 + 0.7619506121 0.6521655917 0.6619045734 + 0.7624893785 0.6529437900 0.6627510786 + 0.7630257010 0.6537193060 0.6635940075 + 0.7635619044 0.6544947028 0.6644368768 + 0.7640982270 0.6552700996 0.6652798057 + 0.7646344900 0.6560454965 0.6661226749 + 0.7651708126 0.6568210125 0.6669656038 + 0.7657119036 0.6575928926 0.6677941084 + 0.7662529945 0.6583644748 0.6686221957 + 0.7667940855 0.6591361761 0.6694504023 + 0.7673352957 0.6599078178 0.6702784896 + 0.7678763866 0.6606794000 0.6711065769 + 0.7684165239 0.6614500880 0.6719334722 + 0.7689508796 0.6622111201 0.6727535725 + 0.7694852948 0.6629719734 0.6735736132 + 0.7700197101 0.6637328863 0.6743935943 + 0.7705541849 0.6644939184 0.6752135754 + 0.7710886002 0.6652547717 0.6760336161 + 0.7716192007 0.6660150290 0.6768512130 + 0.7721378803 0.6667712927 0.6776608229 + 0.7726566792 0.6675274968 0.6784703732 + 0.7731754184 0.6682838202 0.6792799830 + 0.7736940980 0.6690400839 0.6800895929 + 0.7742128968 0.6697964072 0.6808992028 + 0.7747325897 0.6705529094 0.6817058921 + 0.7752555013 0.6713106036 0.6825023890 + 0.7757782936 0.6720684171 0.6832988858 + 0.7763012052 0.6728261113 0.6840953827 + 0.7768241167 0.6735839248 0.6848918796 + 0.7773470283 0.6743416190 0.6856883764 + 0.7778692245 0.6750988960 0.6864832044 + 0.7783874273 0.6758496761 0.6872665882 + 0.7789055705 0.6766005158 0.6880499721 + 0.7794237733 0.6773511767 0.6888334155 + 0.7799419165 0.6781020164 0.6896167994 + 0.7804601192 0.6788527966 0.6904001832 + 0.7809783220 0.6796035767 0.6911836267 + 0.7814986110 0.6803464890 0.6919562221 + 0.7820190191 0.6810883880 0.6927281022 + 0.7825394273 0.6818302870 0.6934999824 + 0.7830597758 0.6825721860 0.6942719221 + 0.7835801840 0.6833140850 0.6950438023 + 0.7841004729 0.6840559840 0.6958156824 + 0.7846269011 0.6847928166 0.6965779066 + 0.7851561904 0.6855260730 0.6973350048 + 0.7856854796 0.6862595081 0.6980922222 + 0.7862148285 0.6869928837 0.6988493204 + 0.7867441177 0.6877261996 0.6996064186 + 0.7872734070 0.6884595752 0.7003635764 + 0.7878013253 0.6891936064 0.7011185288 + 0.7883257270 0.6899294853 0.7018678784 + 0.7888501287 0.6906654835 0.7026172876 + 0.7893745899 0.6914014816 0.7033666968 + 0.7898989916 0.6921374202 0.7041161060 + 0.7904235125 0.6928734183 0.7048655152 + 0.7909479141 0.6936092973 0.7056149244 + 0.7914677858 0.6943377256 0.7063497901 + 0.7919868231 0.6950635910 0.7070816159 + 0.7925058007 0.6957895756 0.7078133821 + 0.7930247784 0.6965156198 0.7085452080 + 0.7935438156 0.6972414851 0.7092769742 + 0.7940626740 0.6979675293 0.7100086808 + 0.7945836782 0.6986932755 0.7107384205 + 0.7951102257 0.6994187832 0.7114617229 + 0.7956367135 0.7001444101 0.7121850252 + 0.7961632013 0.7008699179 0.7129083276 + 0.7966896892 0.7015954256 0.7136315703 + 0.7972161770 0.7023208737 0.7143548727 + 0.7977427244 0.7030463815 0.7150781751 + 0.7982670069 0.7037687898 0.7157930732 + 0.7987899780 0.7044885755 0.7165021896 + 0.7993130088 0.7052084208 0.7172113061 + 0.7998359799 0.7059280872 0.7179204226 + 0.8003590107 0.7066478729 0.7186294198 + 0.8008819818 0.7073677182 0.7193384767 + 0.8014048934 0.7080873847 0.7200475931 + 0.8019158244 0.7088059783 0.7207496762 + 0.8024243116 0.7095242143 0.7214503884 + 0.8029329181 0.7102422714 0.7221511006 + 0.8034414053 0.7109605074 0.7228518128 + 0.8039500117 0.7116786838 0.7235525250 + 0.8044584990 0.7123969197 0.7242532969 + 0.8049671054 0.7131149769 0.7249540091 + 0.8054732084 0.7138308883 0.7256454825 + 0.8059793115 0.7145465016 0.7263367176 + 0.8064854145 0.7152621150 0.7270278931 + 0.8069915175 0.7159777284 0.7277191877 + 0.8074976206 0.7166932821 0.7284104228 + 0.8080037236 0.7174088955 0.7291015983 + 0.8085097075 0.7181245089 0.7297927737 + 0.8090131879 0.7188358903 0.7304673791 + 0.8095167279 0.7195469737 0.7311419249 + 0.8100202084 0.7202581167 0.7318164706 + 0.8105236888 0.7209693193 0.7324910164 + 0.8110272288 0.7216804028 0.7331656218 + 0.8115307093 0.7223916054 0.7338401079 + 0.8120341897 0.7231026888 0.7345147133 + 0.8125367761 0.7238088846 0.7351782918 + 0.8130393028 0.7245143056 0.7358410954 + 0.8135418892 0.7252197862 0.7365038991 + 0.8140444160 0.7259252071 0.7371665835 + 0.8145468831 0.7266306877 0.7378293872 + 0.8150494099 0.7273361087 0.7384921908 + 0.8155519962 0.7280415893 0.7391549945 + 0.8160499930 0.7287421227 0.7398017049 + 0.8165466189 0.7294405103 0.7404432297 + 0.8170431852 0.7301387787 0.7410846949 + 0.8175398111 0.7308372259 0.7417262197 + 0.8180363774 0.7315356135 0.7423676848 + 0.8185330033 0.7322340012 0.7430092096 + 0.8190296888 0.7329323888 0.7436506748 + 0.8195242286 0.7336298227 0.7442870736 + 0.8200165033 0.7343257070 0.7449178100 + 0.8205088973 0.7350217104 0.7455484867 + 0.8210011721 0.7357177138 0.7461792231 + 0.8214935064 0.7364135981 0.7468098998 + 0.8219857812 0.7371096015 0.7474406958 + 0.8224781752 0.7378056049 0.7480713725 + 0.8229702115 0.7385014892 0.7487009168 + 0.8234596252 0.7391961217 0.7493168712 + 0.8239489794 0.7398905754 0.7499328852 + 0.8244382739 0.7405852079 0.7505488992 + 0.8249276876 0.7412797809 0.7511649132 + 0.8254171014 0.7419744134 0.7517809272 + 0.8259065151 0.7426689267 0.7523968816 + 0.8263958097 0.7433634996 0.7530128956 + 0.8268806934 0.7440590262 0.7536231279 + 0.8273624778 0.7447553277 0.7542291880 + 0.8278442025 0.7454516888 0.7548351884 + 0.8283259869 0.7461479902 0.7554411888 + 0.8288077116 0.7468442917 0.7560473084 + 0.8292894959 0.7475407124 0.7566533089 + 0.8297712207 0.7482370138 0.7572593093 + 0.8302530050 0.7489333153 0.7578654289 + 0.8307291269 0.7496249080 0.7584576011 + 0.8312050104 0.7503160834 0.7590492964 + 0.8316810131 0.7510071993 0.7596409917 + 0.8321568966 0.7516983747 0.7602326870 + 0.8326328993 0.7523894906 0.7608243823 + 0.8331087828 0.7530807257 0.7614160776 + 0.8335847259 0.7537717819 0.7620077729 + 0.8340600729 0.7544625998 0.7625957727 + 0.8345336914 0.7551519275 0.7631717920 + 0.8350073099 0.7558411956 0.7637478113 + 0.8354809284 0.7565305233 0.7643237710 + 0.8359544873 0.7572197914 0.7648997903 + 0.8364281058 0.7579091191 0.7654758096 + 0.8369017243 0.7585983872 0.7660518289 + 0.8373752832 0.7592877150 0.7666277885 + 0.8378481865 0.7599760294 0.7671977878 + 0.8383200169 0.7606624961 0.7677584291 + 0.8387917876 0.7613489032 0.7683190107 + 0.8392636776 0.7620353103 0.7688795924 + 0.8397355080 0.7627217770 0.7694401741 + 0.8402072787 0.7634081841 0.7700008154 + 0.8406791091 0.7640945911 0.7705613971 + 0.8411508799 0.7647809982 0.7711219788 + 0.8416199088 0.7654656768 0.7716754079 + 0.8420853019 0.7661474943 0.7722191811 + 0.8425505757 0.7668293118 0.7727630734 + 0.8430159092 0.7675111294 0.7733069062 + 0.8434813023 0.7681930065 0.7738506794 + 0.8439465761 0.7688748240 0.7743945122 + 0.8444120288 0.7695565820 0.7749384046 + 0.8448773026 0.7702383995 0.7754821777 + 0.8453407288 0.7709181905 0.7760233283 + 0.8458008170 0.7715933919 0.7765594125 + 0.8462607861 0.7722684741 0.7770954967 + 0.8467208147 0.7729436755 0.7776315808 + 0.8471809030 0.7736188173 0.7781677246 + 0.8476408720 0.7742940187 0.7787038088 + 0.8481009007 0.7749692202 0.7792398930 + 0.8485609889 0.7756443024 0.7797759771 + 0.8490195274 0.7763193250 0.7803099751 + 0.8494699001 0.7769930959 0.7808322906 + 0.8499203920 0.7776669264 0.7813544869 + 0.8503708243 0.7783406973 0.7818766832 + 0.8508211970 0.7790145278 0.7823989987 + 0.8512716889 0.7796882987 0.7829211950 + 0.8517221212 0.7803621292 0.7834433913 + 0.8521726131 0.7810359001 0.7839657068 + 0.8526229858 0.7817096710 0.7844879031 + 0.8530669808 0.7823808193 0.7850015163 + 0.8535096049 0.7830513120 0.7855132818 + 0.8539522886 0.7837216854 0.7860249877 + 0.8543949723 0.7843921781 0.7865368128 + 0.8548377156 0.7850626111 0.7870485187 + 0.8552803993 0.7857329845 0.7875602841 + 0.8557230234 0.7864034772 0.7880721092 + 0.8561657071 0.7870739102 0.7885838151 + 0.8566074967 0.7877444029 0.7890909910 + 0.8570477962 0.7884148955 0.7895907760 + 0.8574879766 0.7890855074 0.7900906205 + 0.8579282761 0.7897560000 0.7905902863 + 0.8583685756 0.7904264927 0.7910900712 + 0.8588088751 0.7910971045 0.7915899158 + 0.8592491746 0.7917675972 0.7920895815 + 0.8596894741 0.7924380898 0.7925894260 + 0.8601297736 0.7931085825 0.7930892110 + 0.8605728149 0.7937740088 0.7935796976 + 0.8610163927 0.7944378257 0.7940679789 + 0.8614599705 0.7951015830 0.7945562005 + 0.8619036078 0.7957653999 0.7950444818 + 0.8623471856 0.7964292169 0.7955328226 + 0.8627907038 0.7970929742 0.7960211039 + 0.8632342815 0.7977567911 0.7965093255 + 0.8636779189 0.7984206080 0.7969976068 + 0.8641206026 0.7990841866 0.7974848747 + 0.8645566106 0.7997450233 0.7979636192 + 0.8649924994 0.8004058003 0.7984423041 + 0.8654283881 0.8010665774 0.7989211082 + 0.8658643961 0.8017274141 0.7993997931 + 0.8663002849 0.8023881912 0.7998784781 + 0.8667361736 0.8030490279 0.8003572226 + 0.8671721816 0.8037098050 0.8008359075 + 0.8676080704 0.8043705821 0.8013145924 + 0.8680428267 0.8050302267 0.8017914295 + 0.8684741855 0.8056855798 0.8022627234 + 0.8689056039 0.8063411117 0.8027340770 + 0.8693370223 0.8069965243 0.8032054901 + 0.8697683811 0.8076519966 0.8036769032 + 0.8701997995 0.8083074093 0.8041483164 + 0.8706312180 0.8089628220 0.8046196103 + 0.8710625768 0.8096182942 0.8050910234 + 0.8714941144 0.8102737069 0.8055623770 + 0.8719242811 0.8109272718 0.8060321212 + 0.8723520041 0.8115758896 0.8064982295 + 0.8727797270 0.8122243881 0.8069642782 + 0.8732073903 0.8128730059 0.8074303865 + 0.8736351132 0.8135215044 0.8078963757 + 0.8740627766 0.8141701221 0.8083624840 + 0.8744904995 0.8148186207 0.8088285923 + 0.8749181032 0.8154671788 0.8092945814 + 0.8753458261 0.8161156774 0.8097606897 + 0.8757717013 0.8167629242 0.8102260828 + 0.8761911988 0.8174033165 0.8106889725 + 0.8766106963 0.8180438280 0.8111518025 + 0.8770301938 0.8186842203 0.8116146922 + 0.8774496913 0.8193246126 0.8120775819 + 0.8778691888 0.8199651241 0.8125404119 + 0.8782886863 0.8206055164 0.8130033016 + 0.8787081838 0.8212460279 0.8134661913 + 0.8791276813 0.8218864202 0.8139290214 + 0.8795471787 0.8225268722 0.8143919110 + 0.8799598813 0.8231630921 0.8148487806 + 0.8803725243 0.8237990737 0.8153055906 + 0.8807851076 0.8244349957 0.8157624006 + 0.8811976910 0.8250709772 0.8162190914 + 0.8816102743 0.8257070184 0.8166759014 + 0.8820229173 0.8263429999 0.8171327114 + 0.8824356198 0.8269789219 0.8175895214 + 0.8828482032 0.8276149035 0.8180462718 + 0.8832607865 0.8282508850 0.8185030818 + 0.8836668730 0.8288804889 0.8189595938 + 0.8840687871 0.8295053840 0.8194159269 + 0.8844708204 0.8301302791 0.8198722005 + 0.8848727942 0.8307551146 0.8203284740 + 0.8852748275 0.8313800097 0.8207848072 + 0.8856766820 0.8320049047 0.8212410808 + 0.8860787153 0.8326296806 0.8216974139 + 0.8864806890 0.8332545757 0.8221536875 + 0.8868827224 0.8338794708 0.8226100206 + 0.8872836828 0.8345038891 0.8230658770 + 0.8876764178 0.8351209760 0.8235191107 + 0.8880689740 0.8357381225 0.8239722848 + 0.8884617090 0.8363550901 0.8244253993 + 0.8888543844 0.8369721770 0.8248785734 + 0.8892471194 0.8375893235 0.8253316879 + 0.8896397948 0.8382064104 0.8257849216 + 0.8900324702 0.8388234973 0.8262379766 + 0.8904250860 0.8394405842 0.8266912103 + 0.8908178210 0.8400576711 0.8271443248 + 0.8912085891 0.8406690955 0.8275967836 + 0.8915970922 0.8412722945 0.8280482888 + 0.8919855952 0.8418754935 0.8284997940 + 0.8923739791 0.8424786925 0.8289512992 + 0.8927624822 0.8430818915 0.8294028044 + 0.8931509852 0.8436850905 0.8298543096 + 0.8935394287 0.8442882895 0.8303058147 + 0.8939278722 0.8448914886 0.8307573199 + 0.8943163753 0.8454946876 0.8312088251 + 0.8947048783 0.8460978866 0.8316602707 + 0.8950937986 0.8466901183 0.8321077824 + 0.8954830170 0.8472754955 0.8325530887 + 0.8958721757 0.8478608131 0.8329983950 + 0.8962613940 0.8484461904 0.8334437013 + 0.8966506124 0.8490315080 0.8338890076 + 0.8970397711 0.8496168852 0.8343343139 + 0.8974289894 0.8502022028 0.8347796202 + 0.8978182077 0.8507875204 0.8352249265 + 0.8982074261 0.8513728976 0.8356701732 + 0.8985965848 0.8519582152 0.8361154795 + 0.8989794254 0.8525332212 0.8365576863 + 0.8993595839 0.8531031013 0.8369985819 + 0.8997398019 0.8536729217 0.8374395967 + 0.9001200199 0.8542428017 0.8378804922 + 0.9005001783 0.8548126817 0.8383213878 + 0.9008803964 0.8553825021 0.8387622833 + 0.9012606144 0.8559523821 0.8392031789 + 0.9016407728 0.8565223217 0.8396441936 + 0.9020209908 0.8570920825 0.8400850892 + 0.9024012089 0.8576620221 0.8405259848 + 0.9027789235 0.8582289219 0.8409655094 + 0.9031550288 0.8587936759 0.8414040208 + 0.9035310745 0.8593583703 0.8418424726 + 0.9039072990 0.8599231839 0.8422811031 + 0.9042834044 0.8604879975 0.8427196145 + 0.9046595097 0.8610526919 0.8431581855 + 0.9050356150 0.8616175056 0.8435966969 + 0.9054117799 0.8621823192 0.8440352082 + 0.9057878852 0.8627470136 0.8444737792 + 0.9061639905 0.8633118272 0.8449122906 + 0.9065403938 0.8638728857 0.8453506231 + 0.9069172144 0.8644266129 0.8457884789 + 0.9072939754 0.8649802804 0.8462263942 + 0.9076709151 0.8655340075 0.8466644287 + 0.9080476761 0.8660876751 0.8471022844 + 0.9084244967 0.8666414022 0.8475401998 + 0.9088013172 0.8671951294 0.8479781151 + 0.9091781974 0.8677487969 0.8484159708 + 0.9095550179 0.8683025241 0.8488538861 + 0.9099317789 0.8688561916 0.8492919207 + 0.9103087187 0.8694099188 0.8497297764 + 0.9106770158 0.8699470162 0.8501740098 + 0.9110450745 0.8704831004 0.8506183028 + 0.9114131927 0.8710191846 0.8510627151 + 0.9117813110 0.8715553284 0.8515071273 + 0.9121494293 0.8720914125 0.8519514799 + 0.9125174880 0.8726274967 0.8523958921 + 0.9128857255 0.8731635213 0.8528403044 + 0.9132537842 0.8736996055 0.8532845974 + 0.9136219025 0.8742356896 0.8537290096 + 0.9139900208 0.8747717738 0.8541734219 + 0.9143564105 0.8753021955 0.8546187878 + 0.9147205949 0.8758236766 0.8550655246 + 0.9150847793 0.8763452768 0.8555122018 + 0.9154489040 0.8768668175 0.8559588790 + 0.9158130884 0.8773882985 0.8564056158 + 0.9161772728 0.8779098988 0.8568522930 + 0.9165413976 0.8784313798 0.8572989702 + 0.9169055820 0.8789529204 0.8577457070 + 0.9172698259 0.8794744015 0.8581923842 + 0.9176338911 0.8799960017 0.8586391807 + 0.9179980755 0.8805174828 0.8590859175 + 0.9183627963 0.8810274005 0.8595321178 + 0.9187275767 0.8815318942 0.8599780798 + 0.9190924168 0.8820363283 0.8604242206 + 0.9194573164 0.8825408220 0.8608701825 + 0.9198220968 0.8830453157 0.8613162041 + 0.9201869965 0.8835498095 0.8617622852 + 0.9205517769 0.8840541840 0.8622083068 + 0.9209166765 0.8845586777 0.8626543283 + 0.9212815166 0.8850631714 0.8631004095 + 0.9216464162 0.8855676055 0.8635463715 + 0.9220111966 0.8860720992 0.8639923930 + 0.9223688841 0.8865699172 0.8644400239 + 0.9227253199 0.8870661259 0.8648878932 + 0.9230818152 0.8875622749 0.8653358221 + 0.9234381914 0.8880584836 0.8657836914 + 0.9237946272 0.8885546923 0.8662316203 + 0.9241510034 0.8890509009 0.8666793704 + 0.9245073795 0.8895472288 0.8671272993 + 0.9248638153 0.8900433779 0.8675752282 + 0.9252201915 0.8905395865 0.8680230975 + 0.9255766869 0.8910357952 0.8684710264 + 0.9259331226 0.8915320039 0.8689187765 + 0.9262825251 0.8920152187 0.8693681955 + 0.9266303778 0.8924947977 0.8698179722 + 0.9269781709 0.8929743767 0.8702676892 + 0.9273260832 0.8934540153 0.8707175255 + 0.9276738763 0.8939337134 0.8711671829 + 0.9280217886 0.8944132924 0.8716170192 + 0.9283695817 0.8948928714 0.8720666766 + 0.9287174940 0.8953725100 0.8725165129 + 0.9290654063 0.8958520889 0.8729661703 + 0.9294131994 0.8963317275 0.8734158874 + 0.9297611117 0.8968113065 0.8738657236 + 0.9301087260 0.8972867727 0.8743184805 + 0.9304562211 0.8977593184 0.8747732043 + 0.9308035970 0.8982318044 0.8752279282 + 0.9311510921 0.8987044096 0.8756825924 + 0.9314985871 0.8991768956 0.8761373162 + 0.9318460226 0.8996493816 0.8765919805 + 0.9321935177 0.9001219869 0.8770467043 + 0.9325410128 0.9005944729 0.8775014281 + 0.9328885078 0.9010670781 0.8779560924 + 0.9332358837 0.9015396237 0.8784108758 + 0.9335833788 0.9020121098 0.8788655996 + 0.9339289069 0.9024819732 0.8793206811 + 0.9342687130 0.9029427171 0.8797768950 + 0.9346085787 0.9034032822 0.8802332282 + 0.9349483848 0.9038640261 0.8806893826 + 0.9352881908 0.9043247104 0.8811457157 + 0.9356281161 0.9047853947 0.8816019893 + 0.9359679222 0.9052460194 0.8820582032 + 0.9363077283 0.9057067037 0.8825144768 + 0.9366474748 0.9061673880 0.8829706907 + 0.9369874001 0.9066280723 0.8834270239 + 0.9373272061 0.9070886970 0.8838832974 + 0.9376670122 0.9075493813 0.8843395114 + 0.9379975200 0.9080064297 0.8847972751 + 0.9383242726 0.9084616899 0.8852556944 + 0.9386510849 0.9089168906 0.8857141137 + 0.9389780164 0.9093722105 0.8861724734 + 0.9393048286 0.9098274708 0.8866308928 + 0.9396315813 0.9102827907 0.8870893121 + 0.9399585128 0.9107381105 0.8875476718 + 0.9402853251 0.9111933708 0.8880060911 + 0.9406121969 0.9116486907 0.8884645104 + 0.9409390092 0.9121040106 0.8889229298 + 0.9412658215 0.9125592709 0.8893812895 + 0.9415925741 0.9130145907 0.8898397088 + 0.9419143200 0.9134653211 0.8903028965 + 0.9422358871 0.9139158130 0.8907660246 + 0.9425575733 0.9143664241 0.8912292123 + 0.9428793192 0.9148169756 0.8916922808 + 0.9432010055 0.9152675271 0.8921554089 + 0.9435225725 0.9157180786 0.8926185966 + 0.9438443184 0.9161686897 0.8930817246 + 0.9441660047 0.9166191816 0.8935449123 + 0.9444875717 0.9170697927 0.8940079808 + 0.9448093176 0.9175204039 0.8944711089 + 0.9451310039 0.9179708958 0.8949342966 + 0.9454516768 0.9184200168 0.8953979015 + 0.9457663298 0.9188566804 0.8958650827 + 0.9460809231 0.9192935228 0.8963323236 + 0.9463955164 0.9197301865 0.8967995048 + 0.9467101097 0.9201670289 0.8972666860 + 0.9470247030 0.9206036925 0.8977338076 + 0.9473394156 0.9210404158 0.8982009888 + 0.9476540089 0.9214771986 0.8986682296 + 0.9479686022 0.9219139218 0.8991354108 + 0.9482831955 0.9223507047 0.8996024728 + 0.9485977888 0.9227874279 0.9000697136 + 0.9489123821 0.9232240915 0.9005368948 + 0.9492262006 0.9236606956 0.9010049105 + 0.9495301247 0.9240928888 0.9014831781 + 0.9498339891 0.9245252013 0.9019615054 + 0.9501379132 0.9249575138 0.9024397731 + 0.9504417777 0.9253897071 0.9029181004 + 0.9507457018 0.9258220196 0.9033964276 + 0.9510496259 0.9262542725 0.9038746953 + 0.9513534904 0.9266865253 0.9043530226 + 0.9516574144 0.9271187782 0.9048312902 + 0.9519612789 0.9275510907 0.9053096175 + 0.9522652030 0.9279832840 0.9057878852 + 0.9525691271 0.9284155965 0.9062662125 + 0.9528729916 0.9288479090 0.9067444801 + 0.9531697035 0.9292709231 0.9072285891 + 0.9534651041 0.9296919107 0.9077138901 + 0.9537603855 0.9301127791 0.9081990719 + 0.9540557265 0.9305338264 0.9086843729 + 0.9543510079 0.9309548140 0.9091696739 + 0.9546462893 0.9313756824 0.9096549749 + 0.9549415708 0.9317967296 0.9101402760 + 0.9552369118 0.9322175980 0.9106255770 + 0.9555321932 0.9326385856 0.9111108780 + 0.9558275938 0.9330595732 0.9115961194 + 0.9561228752 0.9334805012 0.9120814204 + 0.9564182162 0.9339014888 0.9125667214 + 0.9567111731 0.9343215823 0.9130539894 + 0.9570007920 0.9347404242 0.9135441184 + 0.9572904706 0.9351593256 0.9140341878 + 0.9575802088 0.9355781078 0.9145243168 + 0.9578698874 0.9359970093 0.9150145054 + 0.9581596255 0.9364159107 0.9155045748 + 0.9584493041 0.9368346930 0.9159947038 + 0.9587389827 0.9372535944 0.9164847732 + 0.9590287209 0.9376723766 0.9169749022 + 0.9593183994 0.9380912781 0.9174650908 + 0.9596080780 0.9385101199 0.9179552197 + 0.9598978162 0.9389290214 0.9184452891 + 0.9601874948 0.9393478036 0.9189354181 + 0.9604712129 0.9397596717 0.9194250703 + 0.9607533813 0.9401696920 0.9199147224 + 0.9610357285 0.9405797124 0.9204041958 + 0.9613178968 0.9409896135 0.9208937883 + 0.9616001844 0.9413995743 0.9213833809 + 0.9618824124 0.9418095946 0.9218729138 + 0.9621647000 0.9422196150 0.9223625064 + 0.9624469280 0.9426295757 0.9228520989 + 0.9627290964 0.9430395961 0.9233415723 + 0.9630113840 0.9434496164 0.9238312244 + 0.9632936120 0.9438595772 0.9243208170 + 0.9635758996 0.9442695975 0.9248104095 + 0.9638580084 0.9446796179 0.9252998829 + 0.9641314745 0.9450818896 0.9257894158 + 0.9644048810 0.9454842806 0.9262788892 + 0.9646784067 0.9458866119 0.9267684221 + 0.9649518728 0.9462888837 0.9272578955 + 0.9652252793 0.9466912150 0.9277474284 + 0.9654988050 0.9470934868 0.9282369018 + 0.9657722712 0.9474958181 0.9287263751 + 0.9660456777 0.9478980899 0.9292159081 + 0.9663192034 0.9483004808 0.9297053814 + 0.9665926099 0.9487028122 0.9301949143 + 0.9668660760 0.9491050839 0.9306843281 + 0.9671396017 0.9495074153 0.9311738014 + 0.9674128294 0.9499096274 0.9316633940 + 0.9676774144 0.9503046274 0.9321550131 + 0.9679421186 0.9506996274 0.9326465726 + 0.9682067037 0.9510946274 0.9331381917 + 0.9684712887 0.9514895082 0.9336298108 + 0.9687359929 0.9518845081 0.9341213703 + 0.9690005779 0.9522795081 0.9346129894 + 0.9692652225 0.9526745081 0.9351046085 + 0.9695299268 0.9530693889 0.9355962276 + 0.9697945118 0.9534643888 0.9360877872 + 0.9700590968 0.9538593888 0.9365794063 + 0.9703238010 0.9542543888 0.9370710254 + 0.9705883861 0.9546493292 0.9375625849 + 0.9708530903 0.9550443292 0.9380542040 + 0.9711099863 0.9554365277 0.9385489821 + 0.9713655114 0.9558281898 0.9390444160 + 0.9716209769 0.9562199116 0.9395396709 + 0.9718766212 0.9566115141 0.9400351048 + 0.9721320868 0.9570031762 0.9405304790 + 0.9723876119 0.9573948979 0.9410259128 + 0.9726430774 0.9577865005 0.9415212870 + 0.9728987217 0.9581782222 0.9420167208 + 0.9731541872 0.9585698247 0.9425120950 + 0.9734097123 0.9589614868 0.9430075288 + 0.9736652970 0.9593532085 0.9435027838 + 0.9739208221 0.9597448111 0.9439982176 + 0.9741762877 0.9601364732 0.9444935918 + 0.9744294882 0.9605246186 0.9449895024 + 0.9746801257 0.9609082937 0.9454861283 + 0.9749307036 0.9612920880 0.9459825754 + 0.9751814008 0.9616758823 0.9464792013 + 0.9754319787 0.9620596170 0.9469757080 + 0.9756826162 0.9624434114 0.9474722147 + 0.9759331942 0.9628272057 0.9479687810 + 0.9761837721 0.9632108808 0.9484652877 + 0.9764344096 0.9635946751 0.9489619136 + 0.9766849875 0.9639785290 0.9494584203 + 0.9769356251 0.9643622041 0.9499549270 + 0.9771862030 0.9647459984 0.9504514933 + 0.9774367809 0.9651297927 0.9509480000 + 0.9776874185 0.9655135274 0.9514446259 + 0.9779301882 0.9658905268 0.9519404769 + 0.9781720042 0.9662665129 0.9524363279 + 0.9784138203 0.9666424990 0.9529321790 + 0.9786555767 0.9670186043 0.9534279704 + 0.9788973927 0.9673945904 0.9539238811 + 0.9791392088 0.9677705765 0.9544196725 + 0.9793810248 0.9681466222 0.9549155831 + 0.9796229005 0.9685227275 0.9554113746 + 0.9798647165 0.9688987136 0.9559072852 + 0.9801064730 0.9692746997 0.9564030766 + 0.9803482890 0.9696506858 0.9568989873 + 0.9805901051 0.9700267911 0.9573947787 + 0.9808319211 0.9704027772 0.9578906894 + 0.9810727835 0.9707782269 0.9583864808 + 0.9813064933 0.9711478949 0.9588822722 + 0.9815400839 0.9715176225 0.9593781233 + 0.9817737937 0.9718871713 0.9598739147 + 0.9820073843 0.9722568989 0.9603695869 + 0.9822410941 0.9726266265 0.9608653784 + 0.9824746847 0.9729962945 0.9613612294 + 0.9827083945 0.9733660221 0.9618570209 + 0.9829419851 0.9737356901 0.9623526931 + 0.9831756949 0.9741054177 0.9628484845 + 0.9834094048 0.9744750857 0.9633442760 + 0.9836429954 0.9748448133 0.9638401270 + 0.9838767052 0.9752144814 0.9643357992 + 0.9841102958 0.9755842090 0.9648315907 + 0.9843431711 0.9759528041 0.9653275013 + 0.9845708013 0.9763129950 0.9658238292 + 0.9847983718 0.9766731858 0.9663200974 + 0.9850260019 0.9770334959 0.9668164253 + 0.9852535725 0.9773936868 0.9673126936 + 0.9854812026 0.9777538776 0.9678090215 + 0.9857087731 0.9781141877 0.9683052897 + 0.9859364033 0.9784743786 0.9688016176 + 0.9861639738 0.9788346291 0.9692978859 + 0.9863917232 0.9791948795 0.9697942138 + 0.9866192937 0.9795550704 0.9702904820 + 0.9868469238 0.9799153209 0.9707868099 + 0.9870744944 0.9802755713 0.9712830782 + 0.9873021245 0.9806358218 0.9717794061 + 0.9875296950 0.9809960127 0.9722756743 + 0.9877505898 0.9813417196 0.9727702737 + 0.9879710078 0.9816861153 0.9732648134 + 0.9881914258 0.9820305109 0.9737592936 + 0.9884117246 0.9823750257 0.9742537141 + 0.9886320829 0.9827194214 0.9747481942 + 0.9888525009 0.9830638170 0.9752426147 + 0.9890729189 0.9834082723 0.9757370949 + 0.9892932773 0.9837527275 0.9762315750 + 0.9895136952 0.9840971231 0.9767259955 + 0.9897341132 0.9844415188 0.9772204757 + 0.9899544716 0.9847859740 0.9777150154 + 0.9901748896 0.9851304293 0.9782093763 + 0.9903953075 0.9854748249 0.9787039161 + 0.9906157255 0.9858192801 0.9791983962 + 0.9908351898 0.9861568809 0.9796867967 + 0.9910538197 0.9864884019 0.9801697135 + 0.9912725091 0.9868198037 0.9806526899 + 0.9914911985 0.9871512055 0.9811356068 + 0.9917098284 0.9874826074 0.9816185832 + 0.9919285178 0.9878140092 0.9821015000 + 0.9921472073 0.9881454110 0.9825844765 + 0.9923658967 0.9884768724 0.9830673933 + 0.9925845265 0.9888082743 0.9835504293 + 0.9928032160 0.9891396761 0.9840332866 + 0.9930219054 0.9894710779 0.9845163226 + 0.9932404757 0.9898024797 0.9849991798 + 0.9934592247 0.9901340008 0.9854822159 + 0.9936779141 0.9904654026 0.9859650731 + 0.9938964844 0.9907968044 0.9864481091 + 0.9941064715 0.9911096096 0.9869107008 + 0.9943155050 0.9914203286 0.9873710275 + 0.9945245981 0.9917309880 0.9878314137 + 0.9947335720 0.9920417070 0.9882918000 + 0.9949426055 0.9923524261 0.9887521863 + 0.9951516986 0.9926630855 0.9892125726 + 0.9953606725 0.9929738045 0.9896730185 + 0.9955697060 0.9932845235 0.9901334047 + 0.9957787991 0.9935951829 0.9905936718 + 0.9959877729 0.9939059019 0.9910541177 + 0.9961968064 0.9942166209 0.9915145040 + 0.9964057803 0.9945272803 0.9919748902 + 0.9966148734 0.9948379993 0.9924352765 + 0.9968239069 0.9951487184 0.9928957224 + 0.9970322251 0.9954589009 0.9933549762 + 0.9972301126 0.9957615733 0.9937980175 + 0.9974278808 0.9960644245 0.9942409992 + 0.9976258278 0.9963670969 0.9946839809 + 0.9978235960 0.9966698885 0.9951270223 + 0.9980214834 0.9969726205 0.9955700040 + 0.9982193112 0.9972752929 0.9960129857 + 0.9984171987 0.9975780845 0.9964560270 + 0.9986150265 0.9978808165 0.9968990088 + 0.9988129139 0.9981836081 0.9973419905 + 0.9990106821 0.9984862804 0.9977849722 + 0.9992086291 0.9987890124 0.9982280135 + 0.9994063973 0.9990918040 0.9986709952 + 0.9996042848 0.9993944764 0.9991139770 + 0.9998021126 0.9996973276 0.9995570183 + 1.0000000000 1.0000000000 1.0000000000 +} diff --git a/rpplugins/color_correction/resources/film_luts_raw/fujifilm_f-400.spi1d b/rpplugins/color_correction/resources/film_luts_raw/fujifilm_f-400.spi1d new file mode 100644 index 0000000..bd32b36 --- /dev/null +++ b/rpplugins/color_correction/resources/film_luts_raw/fujifilm_f-400.spi1d @@ -0,0 +1,1030 @@ +Version 1 +From 0.0 1.0 +Length 1024 +Components 3 +{ + 0.0000000000 0.0000000000 0.0000000000 + 0.0603632890 0.0454680510 0.0325050801 + 0.0916145369 0.0672334507 0.0560519211 + 0.1141282991 0.0832497999 0.0737638026 + 0.1319569051 0.0963873789 0.0874102712 + 0.1474671066 0.1078206971 0.0974757820 + 0.1610251069 0.1180547997 0.1053474993 + 0.1732669026 0.1273127049 0.1128624976 + 0.1844484061 0.1358955950 0.1203550026 + 0.1948004961 0.1437651068 0.1278492957 + 0.2044326067 0.1510639042 0.1352435946 + 0.2135390937 0.1580073982 0.1424624026 + 0.2222227007 0.1645933986 0.1493878067 + 0.2305278927 0.1708792001 0.1560759991 + 0.2384292036 0.1768720001 0.1626075953 + 0.2459527999 0.1825958937 0.1688462943 + 0.2531175911 0.1880602986 0.1748789996 + 0.2599833906 0.1933407038 0.1807505935 + 0.2665782869 0.1983918995 0.1864421070 + 0.2729392946 0.2032617927 0.1920263022 + 0.2790789902 0.2080129981 0.1974907964 + 0.2850643992 0.2126218975 0.2027806044 + 0.2908408046 0.2170598060 0.2078876942 + 0.2965438068 0.2213744968 0.2128470987 + 0.3020817935 0.2255962938 0.2176713943 + 0.3074505031 0.2297365963 0.2223367989 + 0.3126476109 0.2337452024 0.2268441021 + 0.3176782131 0.2376385927 0.2312131971 + 0.3225966990 0.2414472997 0.2354972064 + 0.3274005949 0.2451924980 0.2396982014 + 0.3320432901 0.2488888949 0.2437300980 + 0.3365654051 0.2524788976 0.2476260960 + 0.3410258889 0.2559857070 0.2514533103 + 0.3453224003 0.2594096065 0.2552187145 + 0.3495548964 0.2627862990 0.2589012980 + 0.3537135124 0.2661119998 0.2625198960 + 0.3577654064 0.2694039047 0.2660697997 + 0.3617587984 0.2726261914 0.2695469856 + 0.3657540083 0.2757805884 0.2729555070 + 0.3696199059 0.2788713872 0.2763257921 + 0.3734039068 0.2819064856 0.2796599865 + 0.3770940006 0.2849085927 0.2829268873 + 0.3806684911 0.2878705859 0.2861185074 + 0.3841705024 0.2907994092 0.2892411947 + 0.3875944912 0.2937094867 0.2923243046 + 0.3909009099 0.2965498865 0.2953714132 + 0.3941605091 0.2993265986 0.2983838916 + 0.3973405063 0.3020490110 0.3013431132 + 0.4004949033 0.3047288954 0.3042708039 + 0.4036108851 0.3073731959 0.3071705103 + 0.4066615999 0.3100095093 0.3100284040 + 0.4096829891 0.3126212955 0.3128500879 + 0.4127061069 0.3152045012 0.3156496882 + 0.4156985879 0.3177570999 0.3184089959 + 0.4186556935 0.3202543855 0.3211377859 + 0.4215945005 0.3227119148 0.3238492906 + 0.4244618118 0.3251400888 0.3265129030 + 0.4272699058 0.3275529146 0.3291609883 + 0.4300499856 0.3299373984 0.3317633867 + 0.4328002036 0.3323051929 0.3343206048 + 0.4354938865 0.3346739113 0.3368437886 + 0.4381406009 0.3370254934 0.3393223882 + 0.4407618046 0.3393487930 0.3417755067 + 0.4433783889 0.3416441083 0.3441849053 + 0.4459331930 0.3439005911 0.3465532959 + 0.4484468997 0.3461334109 0.3488821089 + 0.4509404898 0.3483205140 0.3511759937 + 0.4534223080 0.3504905999 0.3534452021 + 0.4558776915 0.3526290059 0.3557046950 + 0.4582909048 0.3547618091 0.3579384089 + 0.4606809914 0.3568730056 0.3601483107 + 0.4630529881 0.3589904904 0.3623368144 + 0.4653714001 0.3610835075 0.3645074964 + 0.4676778913 0.3631530106 0.3666630983 + 0.4699575007 0.3652003109 0.3688057065 + 0.4722292125 0.3671888113 0.3709379137 + 0.4745065868 0.3691641092 0.3730610013 + 0.4767518938 0.3711192012 0.3751786053 + 0.4789671004 0.3730652034 0.3772909939 + 0.4811646044 0.3749937117 0.3793990016 + 0.4833407998 0.3769024014 0.3814974129 + 0.4854697883 0.3788143098 0.3835780919 + 0.4875837862 0.3807007074 0.3856568933 + 0.4896746874 0.3826003969 0.3877165020 + 0.4917361140 0.3844895065 0.3897739947 + 0.4937821031 0.3863629997 0.3918241858 + 0.4958266914 0.3882220984 0.3938601017 + 0.4978322089 0.3900676966 0.3958753943 + 0.4998154044 0.3919059038 0.3978557885 + 0.5017874837 0.3937377036 0.3998196125 + 0.5037454963 0.3955607116 0.4017657936 + 0.5056617856 0.3973649144 0.4036836028 + 0.5075917840 0.3991670012 0.4055893123 + 0.5095139742 0.4009510875 0.4074887931 + 0.5114189982 0.4027169943 0.4093823135 + 0.5132684112 0.4044859111 0.4112665951 + 0.5151203871 0.4062362909 0.4131282866 + 0.5169649720 0.4079819024 0.4149852991 + 0.5187842846 0.4097360075 0.4168485999 + 0.5205675960 0.4114727974 0.4186882079 + 0.5223402977 0.4132055044 0.4205282927 + 0.5241093040 0.4149374068 0.4223743081 + 0.5258463025 0.4166536033 0.4241972864 + 0.5275856256 0.4183549881 0.4260225892 + 0.5293406248 0.4200339913 0.4278545082 + 0.5310854912 0.4217008948 0.4296846986 + 0.5328161120 0.4233531058 0.4315181971 + 0.5345103741 0.4249719083 0.4333597124 + 0.5362126827 0.4265843928 0.4351972938 + 0.5379176140 0.4281908870 0.4370343983 + 0.5396010876 0.4297637045 0.4388785958 + 0.5412700772 0.4313359857 0.4407181144 + 0.5429202914 0.4329077005 0.4425528049 + 0.5445725918 0.4344569147 0.4443916082 + 0.5462222099 0.4360015094 0.4462321103 + 0.5478432775 0.4375520945 0.4480772018 + 0.5494470000 0.4390931129 0.4499236941 + 0.5510246158 0.4406209886 0.4517717957 + 0.5525965095 0.4421330988 0.4536193013 + 0.5541654825 0.4436380863 0.4554666877 + 0.5557032228 0.4451265037 0.4573141932 + 0.5572413206 0.4466089010 0.4591605067 + 0.5587986708 0.4480651915 0.4610021114 + 0.5603525043 0.4495176077 0.4628401995 + 0.5618990064 0.4509631097 0.4646731913 + 0.5634241104 0.4523977935 0.4664989114 + 0.5649273992 0.4538224936 0.4683187902 + 0.5664381981 0.4552442133 0.4701269865 + 0.5679532290 0.4566642940 0.4719302058 + 0.5694528818 0.4580616951 0.4737173021 + 0.5709474087 0.4594523013 0.4755006135 + 0.5723990798 0.4608454108 0.4772619009 + 0.5738419890 0.4622389972 0.4790205061 + 0.5752863288 0.4636129141 0.4807558954 + 0.5767307281 0.4649848938 0.4824900925 + 0.5781518221 0.4663662910 0.4842281938 + 0.5795705914 0.4677484035 0.4859664142 + 0.5809577703 0.4691171050 0.4876765907 + 0.5823417902 0.4704849124 0.4893858135 + 0.5837211013 0.4718532860 0.4910922945 + 0.5850995779 0.4732218087 0.4927985966 + 0.5864555240 0.4745810032 0.4944742918 + 0.5878059864 0.4759384096 0.4961453974 + 0.5891577005 0.4772793949 0.4978106916 + 0.5905098915 0.4786145985 0.4994742870 + 0.5918568969 0.4799452126 0.5011221766 + 0.5932002068 0.4812729955 0.5027614236 + 0.5945292115 0.4825868905 0.5043945909 + 0.5958389044 0.4838840961 0.5060214996 + 0.5971521139 0.4851810038 0.5076392889 + 0.5984765887 0.4864774048 0.5092359781 + 0.5998010039 0.4877730906 0.5108314157 + 0.6011152864 0.4890460968 0.5124111176 + 0.6024296284 0.4903191030 0.5139907002 + 0.6037279963 0.4915966988 0.5155413747 + 0.6050211787 0.4928756058 0.5170856118 + 0.6063179970 0.4941464067 0.5186198950 + 0.6076188087 0.4954087138 0.5201451778 + 0.6089168191 0.4966705143 0.5216658711 + 0.6101980805 0.4979301095 0.5231689811 + 0.6114792824 0.4991895854 0.5246720910 + 0.6127241850 0.5004386902 0.5261573792 + 0.6139590144 0.5016852021 0.5276395082 + 0.6151936054 0.5029277205 0.5291115046 + 0.6164277196 0.5041645765 0.5305709839 + 0.6176617742 0.5054013729 0.5320304036 + 0.6188758016 0.5066292882 0.5334817767 + 0.6200888753 0.5078570247 0.5349332094 + 0.6212956905 0.5090678930 0.5363718271 + 0.6224961281 0.5102629066 0.5378000140 + 0.6236965060 0.5114579201 0.5392268896 + 0.6248922944 0.5126475096 0.5406283140 + 0.6260880828 0.5138370991 0.5420296192 + 0.6272730827 0.5150145888 0.5434191227 + 0.6284447908 0.5161781907 0.5447971225 + 0.6296163797 0.5173417926 0.5461751223 + 0.6307746768 0.5185059905 0.5475438237 + 0.6319308877 0.5196703076 0.5489118099 + 0.6330848932 0.5208293200 0.5502725840 + 0.6342328191 0.5219740868 0.5516172051 + 0.6353806257 0.5231189132 0.5529618263 + 0.6365122199 0.5242677927 0.5542978048 + 0.6376327872 0.5254191756 0.5556291938 + 0.6387532949 0.5265706778 0.5569607019 + 0.6398714185 0.5277099013 0.5582699180 + 0.6409891248 0.5288481116 0.5595781803 + 0.6421049833 0.5299884081 0.5608838797 + 0.6432113051 0.5311387777 0.5621806979 + 0.6443176270 0.5322890878 0.5634775162 + 0.6454114914 0.5334355235 0.5647640824 + 0.6464858055 0.5345761180 0.5660377741 + 0.6475601792 0.5357167125 0.5673115849 + 0.6486206055 0.5368447900 0.5685880780 + 0.6496704817 0.5379639268 0.5698662996 + 0.6507204175 0.5390831232 0.5711445212 + 0.6517605186 0.5401955843 0.5724067092 + 0.6527966261 0.5413054824 0.5736641288 + 0.6538326740 0.5424153805 0.5749214292 + 0.6548563242 0.5435019732 0.5761708021 + 0.6558768749 0.5445836782 0.5774188042 + 0.6568974853 0.5456653237 0.5786669254 + 0.6579241753 0.5467439890 0.5798960924 + 0.6589519978 0.5478222966 0.5811234713 + 0.6599798203 0.5489006042 0.5823509097 + 0.6609984040 0.5499593019 0.5835713744 + 0.6620156169 0.5510154963 0.5847914219 + 0.6630328894 0.5520715714 0.5860112906 + 0.6640465260 0.5531296730 0.5872145891 + 0.6650593877 0.5541881919 0.5884156823 + 0.6660723090 0.5552465916 0.5896167755 + 0.6670761704 0.5562924743 0.5908033848 + 0.6680768728 0.5573346019 0.5919865966 + 0.6690776944 0.5583767295 0.5931698084 + 0.6700693965 0.5594154000 0.5943410993 + 0.6710556746 0.5604522824 0.5955067277 + 0.6720418930 0.5614892244 0.5966722965 + 0.6730256081 0.5625199080 0.5978301167 + 0.6740061045 0.5635436177 0.5989803076 + 0.6749866009 0.5645673275 0.6001303792 + 0.6759673953 0.5655882955 0.6012763977 + 0.6769493818 0.5666012168 0.6024119258 + 0.6779313087 0.5676140785 0.6035472751 + 0.6789131761 0.5686269999 0.6046826243 + 0.6798806787 0.5696319938 0.6058049798 + 0.6808475256 0.5706369281 0.6069275141 + 0.6818143129 0.5716418028 0.6080499887 + 0.6827753782 0.5726358294 0.6091644168 + 0.6837335229 0.5736240149 0.6102753282 + 0.6846914887 0.5746123195 0.6113861203 + 0.6856489778 0.5755988955 0.6124936938 + 0.6866049767 0.5765814185 0.6135942936 + 0.6875609756 0.5775640011 0.6146950126 + 0.6885170937 0.5785465240 0.6157956719 + 0.6894577146 0.5795089006 0.6168872714 + 0.6903957129 0.5804682970 0.6179779172 + 0.6913337111 0.5814276934 0.6190685034 + 0.6922674179 0.5823866725 0.6201496124 + 0.6931942105 0.5833454132 0.6212183833 + 0.6941210032 0.5843039751 0.6222872138 + 0.6950476766 0.5852625966 0.6233559847 + 0.6959589720 0.5862057209 0.6244189143 + 0.6968678236 0.5871466994 0.6254813075 + 0.6977766156 0.5880876780 0.6265437007 + 0.6986793280 0.5890266895 0.6276041269 + 0.6995667219 0.5899611712 0.6286605000 + 0.7004541159 0.5908957720 0.6297169924 + 0.7013415098 0.5918303132 0.6307734251 + 0.7022203803 0.5927559733 0.6318181753 + 0.7030950189 0.5936775208 0.6328582764 + 0.7039695978 0.5945990086 0.6338983774 + 0.7048441172 0.5955204964 0.6349384189 + 0.7057145834 0.5964314938 0.6359745860 + 0.7065848708 0.5973424911 0.6370108128 + 0.7074552178 0.5982534289 0.6380469203 + 0.7083240151 0.5991623998 0.6390789747 + 0.7091879845 0.6000658870 0.6401014924 + 0.7100520134 0.6009693146 0.6411240101 + 0.7109159827 0.6018726826 0.6421465278 + 0.7117736936 0.6027743220 0.6431624889 + 0.7126240134 0.6036738157 0.6441721916 + 0.7134742141 0.6045733094 0.6451817751 + 0.7143244743 0.6054729223 0.6461914778 + 0.7151702046 0.6063696742 0.6471874118 + 0.7160130143 0.6072648764 0.6481761932 + 0.7168557048 0.6081600785 0.6491649151 + 0.7176983953 0.6090552807 0.6501536965 + 0.7185257077 0.6099364161 0.6511443853 + 0.7193462253 0.6108118892 0.6521357298 + 0.7201668024 0.6116873026 0.6531270146 + 0.7209873199 0.6125627756 0.6541182995 + 0.7217960954 0.6134387851 0.6550964117 + 0.7226005793 0.6143149137 0.6560708880 + 0.7234051228 0.6151911020 0.6570454240 + 0.7242096066 0.6160672903 0.6580199003 + 0.7250012755 0.6169329286 0.6589906216 + 0.7257876992 0.6177945137 0.6599599719 + 0.7265741825 0.6186562181 0.6609295011 + 0.7273607254 0.6195178032 0.6618989706 + 0.7281492949 0.6203829050 0.6628596187 + 0.7289391756 0.6212499738 0.6638159752 + 0.7297291160 0.6221169829 0.6647723913 + 0.7305189967 0.6229839921 0.6657288074 + 0.7313020229 0.6238461137 0.6666783094 + 0.7320774198 0.6247032285 0.6676219106 + 0.7328528762 0.6255602837 0.6685655117 + 0.7336283922 0.6264173985 0.6695091128 + 0.7344021201 0.6272711754 0.6704490185 + 0.7351711988 0.6281173825 0.6713812947 + 0.7359403968 0.6289635897 0.6723136902 + 0.7367094755 0.6298096776 0.6732460856 + 0.7374784946 0.6306557059 0.6741766930 + 0.7382401228 0.6314933896 0.6750792861 + 0.7390015721 0.6323310733 0.6759818792 + 0.7397632003 0.6331688166 0.6768844724 + 0.7405247092 0.6340065002 0.6777871251 + 0.7412760854 0.6348341107 0.6786838174 + 0.7420225143 0.6356573105 0.6795783043 + 0.7427688837 0.6364803910 0.6804727912 + 0.7435153127 0.6373035908 0.6813672781 + 0.7442601919 0.6381258965 0.6822535992 + 0.7450010777 0.6389461756 0.6831231713 + 0.7457420230 0.6397663951 0.6839928031 + 0.7464829087 0.6405866742 0.6848623753 + 0.7472237945 0.6414070129 0.6857320070 + 0.7479677796 0.6422203183 0.6865984797 + 0.7487124205 0.6430320740 0.6874645948 + 0.7494571209 0.6438438892 0.6883307099 + 0.7502018213 0.6446557045 0.6891968250 + 0.7509424090 0.6454676986 0.6900563836 + 0.7516725063 0.6462804079 0.6909027100 + 0.7524024844 0.6470929980 0.6917490959 + 0.7531325817 0.6479057074 0.6925954223 + 0.7538626790 0.6487182975 0.6934418082 + 0.7545816898 0.6495214105 0.6942890882 + 0.7552953959 0.6503202915 0.6951367855 + 0.7560091019 0.6511192918 0.6959844828 + 0.7567229271 0.6519181728 0.6968321800 + 0.7574365735 0.6527169943 0.6976789236 + 0.7581534982 0.6535111070 0.6985118985 + 0.7588703036 0.6543052197 0.6993448734 + 0.7595872283 0.6550993919 0.7001779079 + 0.7603039742 0.6558935046 0.7010108829 + 0.7610172033 0.6566845775 0.7018424273 + 0.7617210150 0.6574687958 0.7026708722 + 0.7624248266 0.6582528949 0.7034993768 + 0.7631285191 0.6590371132 0.7043278813 + 0.7638322711 0.6598212123 0.7051563859 + 0.7645226121 0.6606013775 0.7059795260 + 0.7651978135 0.6613773108 0.7067975998 + 0.7658728957 0.6621533036 0.7076157928 + 0.7665480971 0.6629291773 0.7084339857 + 0.7672232985 0.6637052298 0.7092521191 + 0.7678937912 0.6644771099 0.7100641727 + 0.7685611248 0.6652464867 0.7108727098 + 0.7692285180 0.6660159230 0.7116813064 + 0.7698957920 0.6667852998 0.7124899030 + 0.7705631256 0.6675546765 0.7132984996 + 0.7712234855 0.6683161855 0.7141026258 + 0.7718799114 0.6690734029 0.7149047256 + 0.7725363970 0.6698306799 0.7157067060 + 0.7731928825 0.6705878973 0.7165088058 + 0.7738493085 0.6713451743 0.7173109055 + 0.7744975090 0.6721003056 0.7181041241 + 0.7751405239 0.6728541255 0.7188926935 + 0.7757834792 0.6736080050 0.7196813822 + 0.7764264941 0.6743618250 0.7204700112 + 0.7770696282 0.6751157045 0.7212585807 + 0.7777153850 0.6758605838 0.7220466137 + 0.7783638835 0.6765974164 0.7228341103 + 0.7790123820 0.6773343086 0.7236214876 + 0.7796608806 0.6780712008 0.7244089842 + 0.7803093791 0.6788079739 0.7251964808 + 0.7809547782 0.6795421243 0.7259809971 + 0.7815937996 0.6802709103 0.7267609239 + 0.7822328806 0.6809996963 0.7275406718 + 0.7828719020 0.6817284822 0.7283204794 + 0.7835109830 0.6824573278 0.7291004062 + 0.7841491103 0.6831848025 0.7298780084 + 0.7847760916 0.6839002967 0.7306407094 + 0.7854030132 0.6846157908 0.7314034104 + 0.7860299945 0.6853312850 0.7321661711 + 0.7866569757 0.6860468984 0.7329288721 + 0.7872840166 0.6867623925 0.7336915731 + 0.7879158854 0.6874758005 0.7344440222 + 0.7885494828 0.6881886125 0.7351937890 + 0.7891830206 0.6889013052 0.7359436154 + 0.7898166180 0.6896141171 0.7366933227 + 0.7904502153 0.6903269291 0.7374430895 + 0.7910810709 0.6910367012 0.7381889224 + 0.7917066216 0.6917409897 0.7389283180 + 0.7923321128 0.6924453974 0.7396677136 + 0.7929577231 0.6931496859 0.7404071093 + 0.7935832143 0.6938540936 0.7411465049 + 0.7942087054 0.6945583820 0.7418857813 + 0.7948155999 0.6952574253 0.7426193953 + 0.7954189181 0.6959553957 0.7433521152 + 0.7960221171 0.6966534257 0.7440848947 + 0.7966253757 0.6973515153 0.7448176146 + 0.7972286940 0.6980494857 0.7455503941 + 0.7978311181 0.6987463832 0.7462819219 + 0.7984310985 0.6994404197 0.7470108271 + 0.7990310788 0.7001342773 0.7477396131 + 0.7996311188 0.7008281946 0.7484685183 + 0.8002310991 0.7015221715 0.7491973042 + 0.8008310795 0.7022160888 0.7499262094 + 0.8014271259 0.7029095888 0.7506538033 + 0.8020204902 0.7036026716 0.7513806820 + 0.8026139140 0.7042958140 0.7521076202 + 0.8032072783 0.7049888968 0.7528346181 + 0.8038007021 0.7056819797 0.7535614967 + 0.8043941855 0.7063751221 0.7542883754 + 0.8049713969 0.7070598006 0.7550076842 + 0.8055459857 0.7077432871 0.7557262182 + 0.8061205745 0.7084268928 0.7564446926 + 0.8066952229 0.7091103792 0.7571632266 + 0.8072698712 0.7097939253 0.7578817010 + 0.8078448176 0.7104768157 0.7585989237 + 0.8084272742 0.7111461759 0.7593011260 + 0.8090099096 0.7118155956 0.7600033879 + 0.8095924258 0.7124850154 0.7607055902 + 0.8101750016 0.7131544948 0.7614077926 + 0.8107575178 0.7138239145 0.7621099949 + 0.8113396168 0.7144926786 0.7628099918 + 0.8119179010 0.7151576281 0.7634986043 + 0.8124963045 0.7158225179 0.7641872764 + 0.8130745888 0.7164874077 0.7648758888 + 0.8136529922 0.7171524167 0.7655645013 + 0.8142312765 0.7178173065 0.7662531137 + 0.8148078918 0.7184810042 0.7669401169 + 0.8153703213 0.7191364169 0.7676184177 + 0.8159328103 0.7197918892 0.7682967782 + 0.8164951801 0.7204474211 0.7689750791 + 0.8170577288 0.7211027741 0.7696533799 + 0.8176200986 0.7217583060 0.7703316808 + 0.8181825876 0.7224134803 0.7710090876 + 0.8187462091 0.7230613232 0.7716705799 + 0.8193098903 0.7237089872 0.7723321915 + 0.8198735714 0.7243567705 0.7729938030 + 0.8204373121 0.7250046134 0.7736552954 + 0.8210009933 0.7256522775 0.7743169069 + 0.8215646148 0.7263001204 0.7749783993 + 0.8221263289 0.7269431949 0.7756360173 + 0.8226876259 0.7275854945 0.7762929201 + 0.8232489228 0.7282276750 0.7769498825 + 0.8238101006 0.7288699746 0.7776067853 + 0.8243713975 0.7295122743 0.7782638073 + 0.8249326944 0.7301545143 0.7789208293 + 0.8254861832 0.7307953238 0.7795671821 + 0.8260335922 0.7314348221 0.7802065015 + 0.8265808821 0.7320743799 0.7808458209 + 0.8271281719 0.7327139974 0.7814850807 + 0.8276755810 0.7333536148 0.7821244001 + 0.8282228708 0.7339931130 0.7827637196 + 0.8287672997 0.7346323729 0.7834032774 + 0.8292987943 0.7352702022 0.7840442061 + 0.8298302293 0.7359080911 0.7846850157 + 0.8303616047 0.7365459800 0.7853258848 + 0.8308929801 0.7371838093 0.7859666944 + 0.8314244747 0.7378216982 0.7866076231 + 0.8319559097 0.7384595275 0.7872483730 + 0.8324869275 0.7390930057 0.7878805995 + 0.8330175877 0.7397248745 0.7885100245 + 0.8335484266 0.7403566837 0.7891393900 + 0.8340792060 0.7409886122 0.7897688150 + 0.8346099257 0.7416204810 0.7903981805 + 0.8351407051 0.7422522902 0.7910276055 + 0.8356696963 0.7428832054 0.7916554809 + 0.8361886144 0.7435089946 0.7922765017 + 0.8367075920 0.7441349030 0.7928975821 + 0.8372265100 0.7447606921 0.7935186028 + 0.8377454281 0.7453864813 0.7941396832 + 0.8382642865 0.7460123897 0.7947607040 + 0.8387833238 0.7466381788 0.7953817844 + 0.8392910957 0.7472589016 0.7959994078 + 0.8397874236 0.7478746176 0.7966139913 + 0.8402836919 0.7484902740 0.7972285748 + 0.8407800198 0.7491058707 0.7978432178 + 0.8412762880 0.7497215867 0.7984578013 + 0.8417726159 0.7503373027 0.7990723848 + 0.8422688842 0.7509530187 0.7996870279 + 0.8427659869 0.7515618801 0.8002871871 + 0.8432633877 0.7521684170 0.8008829951 + 0.8437607884 0.7527748942 0.8014789224 + 0.8442581892 0.7533814907 0.8020746708 + 0.8447555900 0.7539880276 0.8026704788 + 0.8452529907 0.7545946240 0.8032664061 + 0.8457503915 0.7552011013 0.8038622141 + 0.8462408781 0.7558019757 0.8044577241 + 0.8467301726 0.7564020753 0.8050531149 + 0.8472195864 0.7570022941 0.8056485057 + 0.8477090001 0.7576023936 0.8062438965 + 0.8481984138 0.7582024932 0.8068394065 + 0.8486878276 0.7588025928 0.8074347973 + 0.8491771817 0.7594026923 0.8080301881 + 0.8496577144 0.7599987984 0.8086149096 + 0.8501371741 0.7605946064 0.8091987967 + 0.8506168127 0.7611902952 0.8097828031 + 0.8510962725 0.7617859840 0.8103666902 + 0.8515759110 0.7623817921 0.8109506965 + 0.8520553708 0.7629774809 0.8115345836 + 0.8525350094 0.7635732293 0.8121185899 + 0.8530108929 0.7641665936 0.8127080798 + 0.8534861207 0.7647594213 0.8132985234 + 0.8539612889 0.7653523088 0.8138889074 + 0.8544363976 0.7659451962 0.8144792914 + 0.8549116254 0.7665380836 0.8150696754 + 0.8553867936 0.7671309114 0.8156599998 + 0.8558620214 0.7677237988 0.8162503839 + 0.8563336730 0.7683117986 0.8168362975 + 0.8568035960 0.7688974142 0.8174201250 + 0.8572735190 0.7694829702 0.8180038929 + 0.8577435017 0.7700685859 0.8185877204 + 0.8582134247 0.7706542015 0.8191714883 + 0.8586832881 0.7712398171 0.8197553754 + 0.8591532111 0.7718253732 0.8203392029 + 0.8596208096 0.7724086046 0.8209149837 + 0.8600844741 0.7729880810 0.8214796185 + 0.8605483174 0.7735676765 0.8220440745 + 0.8610121012 0.7741472125 0.8226085901 + 0.8614758253 0.7747266889 0.8231731057 + 0.8619396091 0.7753062248 0.8237376213 + 0.8624032736 0.7758857012 0.8243020773 + 0.8628671169 0.7764651775 0.8248665929 + 0.8633220196 0.7770413160 0.8254293203 + 0.8637769222 0.7776173949 0.8259919882 + 0.8642318249 0.7781934738 0.8265547752 + 0.8646866083 0.7787696123 0.8271175027 + 0.8651415110 0.7793456912 0.8276802897 + 0.8655962944 0.7799218297 0.8282430172 + 0.8660511971 0.7804979086 0.8288056850 + 0.8665007949 0.7810693979 0.8293619752 + 0.8669447899 0.7816361785 0.8299123049 + 0.8673887849 0.7822030187 0.8304625750 + 0.8678327799 0.7827697992 0.8310130239 + 0.8682768941 0.7833365202 0.8315632939 + 0.8687208891 0.7839033008 0.8321136236 + 0.8691648841 0.7844700813 0.8326638937 + 0.8696088791 0.7850369215 0.8332142234 + 0.8700435758 0.7855976820 0.8337548971 + 0.8704770207 0.7861577868 0.8342946172 + 0.8709102869 0.7867177725 0.8348342776 + 0.8713436127 0.7872778773 0.8353739977 + 0.8717769980 0.7878379226 0.8359137177 + 0.8722103238 0.7883980274 0.8364533782 + 0.8726437092 0.7889580131 0.8369930983 + 0.8730763793 0.7895172834 0.8375316858 + 0.8735055923 0.7900726795 0.8380653262 + 0.8739346862 0.7906280756 0.8385987878 + 0.8743638992 0.7911834717 0.8391324282 + 0.8747929931 0.7917389274 0.8396660089 + 0.8752222061 0.7922942042 0.8401995897 + 0.8756513000 0.7928496003 0.8407331705 + 0.8760805130 0.7934049964 0.8412668109 + 0.8765051961 0.7939593196 0.8417996168 + 0.8769198060 0.7945113182 0.8423308134 + 0.8773342967 0.7950633168 0.8428620100 + 0.8777489066 0.7956153154 0.8433932066 + 0.8781633973 0.7961671948 0.8439245224 + 0.8785778880 0.7967191935 0.8444557190 + 0.8789924979 0.7972711921 0.8449869156 + 0.8794069886 0.7978231907 0.8455181122 + 0.8798193932 0.7983725071 0.8460463881 + 0.8802276850 0.7989166975 0.8465698957 + 0.8806359768 0.7994610071 0.8470934033 + 0.8810443282 0.8000053167 0.8476169109 + 0.8814526200 0.8005495071 0.8481404185 + 0.8818609118 0.8010938168 0.8486639261 + 0.8822692037 0.8016381264 0.8491873741 + 0.8826774955 0.8021823764 0.8497108817 + 0.8830862045 0.8027231097 0.8502314091 + 0.8834958076 0.8032547235 0.8507447243 + 0.8839054704 0.8037862182 0.8512579799 + 0.8843150735 0.8043177724 0.8517714143 + 0.8847246766 0.8048493266 0.8522847295 + 0.8851343989 0.8053808808 0.8527981043 + 0.8855440021 0.8059123755 0.8533114195 + 0.8859536052 0.8064439893 0.8538246751 + 0.8863626719 0.8069751859 0.8543373942 + 0.8867633939 0.8075023293 0.8548439145 + 0.8871641159 0.8080292940 0.8553503752 + 0.8875647783 0.8085563779 0.8558567762 + 0.8879655004 0.8090834022 0.8563632965 + 0.8883662820 0.8096104860 0.8568698168 + 0.8887670040 0.8101376295 0.8573762774 + 0.8891677260 0.8106645942 0.8578827977 + 0.8895683885 0.8111916780 0.8583891988 + 0.8899617195 0.8117120862 0.8588874936 + 0.8903526068 0.8122305274 0.8593834043 + 0.8907433748 0.8127487898 0.8598793149 + 0.8911342025 0.8132671118 0.8603752255 + 0.8915249705 0.8137853742 0.8608711958 + 0.8919157982 0.8143036962 0.8613671064 + 0.8923066854 0.8148220778 0.8618630171 + 0.8926975131 0.8153403997 0.8623589277 + 0.8930876851 0.8158568144 0.8628520966 + 0.8934766054 0.8163688183 0.8633397818 + 0.8938655853 0.8168808818 0.8638275266 + 0.8942545056 0.8173928857 0.8643152118 + 0.8946434259 0.8179048896 0.8648028970 + 0.8950322866 0.8184170127 0.8652905822 + 0.8954212070 0.8189290166 0.8657783270 + 0.8958101869 0.8194410801 0.8662660122 + 0.8961991072 0.8199530840 0.8667536974 + 0.8965854049 0.8204619288 0.8672325015 + 0.8969708085 0.8209697008 0.8677083850 + 0.8973562121 0.8214774132 0.8681843281 + 0.8977414966 0.8219851255 0.8686602116 + 0.8981269002 0.8224927783 0.8691360950 + 0.8985123038 0.8230004907 0.8696119785 + 0.8988977075 0.8235082030 0.8700879216 + 0.8992829919 0.8240159154 0.8705638051 + 0.8996679783 0.8245236278 0.8710392118 + 0.9000402093 0.8250293732 0.8715068102 + 0.9004123807 0.8255351782 0.8719742894 + 0.9007844925 0.8260409832 0.8724418879 + 0.9011567235 0.8265467882 0.8729094267 + 0.9015287757 0.8270524740 0.8733770251 + 0.9019010067 0.8275582790 0.8738445044 + 0.9022731781 0.8280640841 0.8743121028 + 0.9026452899 0.8285698891 0.8747795820 + 0.9030135274 0.8290756941 0.8752462268 + 0.9033654928 0.8295813203 0.8757094145 + 0.9037175179 0.8300868869 0.8761726022 + 0.9040694833 0.8305925131 0.8766359091 + 0.9044215083 0.8310980797 0.8770990968 + 0.9047734737 0.8316035867 0.8775622845 + 0.9051254988 0.8321092129 0.8780254722 + 0.9054775238 0.8326147795 0.8784887791 + 0.9058294892 0.8331204057 0.8789520264 + 0.9061816931 0.8336247802 0.8794112802 + 0.9065344930 0.8341253996 0.8798596859 + 0.9068872929 0.8346260190 0.8803079724 + 0.9072400928 0.8351265788 0.8807563782 + 0.9075930119 0.8356270790 0.8812047243 + 0.9079458117 0.8361276984 0.8816530704 + 0.9082986116 0.8366283178 0.8821014762 + 0.9086514115 0.8371288776 0.8825498223 + 0.9090042114 0.8376294971 0.8829982281 + 0.9093561769 0.8381295800 0.8834459186 + 0.9097027183 0.8386269808 0.8838903904 + 0.9100490808 0.8391245008 0.8843349218 + 0.9103956223 0.8396219015 0.8847793937 + 0.9107421041 0.8401193023 0.8852239251 + 0.9110885859 0.8406167030 0.8856683969 + 0.9114350080 0.8411141038 0.8861129880 + 0.9117814898 0.8416115046 0.8865575194 + 0.9121279716 0.8421089053 0.8870019913 + 0.9124745131 0.8426063061 0.8874465227 + 0.9128088951 0.8430963159 0.8878840804 + 0.9131420851 0.8435854912 0.8883212209 + 0.9134753942 0.8440747857 0.8887583017 + 0.9138085842 0.8445640802 0.8891953826 + 0.9141417742 0.8450533748 0.8896325231 + 0.9144750237 0.8455426097 0.8900696039 + 0.9148082137 0.8460319042 0.8905066848 + 0.9151415229 0.8465211987 0.8909438252 + 0.9154747128 0.8470103741 0.8913809061 + 0.9158115983 0.8474963903 0.8918085098 + 0.9161515832 0.8479797244 0.8922289014 + 0.9164916277 0.8484628797 0.8926492929 + 0.9168316126 0.8489462137 0.8930696249 + 0.9171715975 0.8494294286 0.8934900165 + 0.9175117016 0.8499127030 0.8939104080 + 0.9178516865 0.8503959179 0.8943307996 + 0.9181916714 0.8508791924 0.8947511911 + 0.9185317159 0.8513624072 0.8951715827 + 0.9188717008 0.8518455029 0.8955916166 + 0.9192115068 0.8523247838 0.8960055113 + 0.9195513129 0.8528040051 0.8964195251 + 0.9198911190 0.8532832265 0.8968334198 + 0.9202309847 0.8537623882 0.8972473741 + 0.9205707908 0.8542416096 0.8976613283 + 0.9209105968 0.8547207713 0.8980752230 + 0.9212504029 0.8552001119 0.8984891772 + 0.9215902090 0.8556792736 0.8989030719 + 0.9219300151 0.8561584949 0.8993170261 + 0.9222667813 0.8566346169 0.8997275829 + 0.9225986004 0.8571056724 0.9001333117 + 0.9229304194 0.8575767875 0.9005389214 + 0.9232621193 0.8580479026 0.9009444714 + 0.9235938787 0.8585190177 0.9013502002 + 0.9239256978 0.8589900732 0.9017558098 + 0.9242575169 0.8594611883 0.9021614194 + 0.9245892763 0.8599323034 0.9025670886 + 0.9249210954 0.8604034185 0.9029726982 + 0.9252529144 0.8608745933 0.9033783078 + 0.9255800247 0.8613454103 0.9037811160 + 0.9259036779 0.8618162274 0.9041818976 + 0.9262273908 0.8622869253 0.9045827985 + 0.9265511036 0.8627576232 0.9049836993 + 0.9268748164 0.8632283211 0.9053844810 + 0.9271985292 0.8636990190 0.9057853818 + 0.9275221825 0.8641697764 0.9061862826 + 0.9278460145 0.8646404743 0.9065871239 + 0.9281697273 0.8651111722 0.9069880247 + 0.9284933805 0.8655819297 0.9073889256 + 0.9288159013 0.8660464287 0.9077849984 + 0.9291377068 0.8665074706 0.9081788063 + 0.9294595122 0.8669685721 0.9085724950 + 0.9297813773 0.8674296737 0.9089663029 + 0.9301031828 0.8678907752 0.9093599916 + 0.9304249883 0.8683518767 0.9097537994 + 0.9307467937 0.8688129783 0.9101474881 + 0.9310687184 0.8692740798 0.9105412960 + 0.9313905239 0.8697351813 0.9109349847 + 0.9317123294 0.8701962829 0.9113287926 + 0.9320325851 0.8706560135 0.9117175937 + 0.9323515892 0.8711144924 0.9121026993 + 0.9326705933 0.8715730906 0.9124878049 + 0.9329895973 0.8720316887 0.9128729105 + 0.9333087206 0.8724902272 0.9132580161 + 0.9336277246 0.8729488254 0.9136431217 + 0.9339467287 0.8734074235 0.9140282273 + 0.9342656732 0.8738659024 0.9144132733 + 0.9345846772 0.8743245006 0.9147983789 + 0.9349036813 0.8747830987 0.9151834846 + 0.9352200031 0.8752396703 0.9155669212 + 0.9355298877 0.8756920099 0.9159467816 + 0.9358398914 0.8761444092 0.9163267016 + 0.9361498952 0.8765966892 0.9167066216 + 0.9364597797 0.8770490885 0.9170864820 + 0.9367697835 0.8775014877 0.9174664021 + 0.9370797873 0.8779538274 0.9178462029 + 0.9373897910 0.8784062266 0.9182261229 + 0.9376996756 0.8788586259 0.9186059833 + 0.9380096793 0.8793109059 0.9189859033 + 0.9383196831 0.8797633052 0.9193658233 + 0.9386215210 0.8802114129 0.9197325110 + 0.9389225245 0.8806591034 0.9200983047 + 0.9392235279 0.8811067939 0.9204640985 + 0.9395244718 0.8815544844 0.9208298922 + 0.9398255944 0.8820021749 0.9211956859 + 0.9401265979 0.8824499249 0.9215614796 + 0.9404276013 0.8828976154 0.9219272733 + 0.9407287240 0.8833453059 0.9222931266 + 0.9410297275 0.8837931156 0.9226589203 + 0.9413306713 0.8842408061 0.9230247140 + 0.9416282177 0.8846876025 0.9233872294 + 0.9419195056 0.8851327896 0.9237444997 + 0.9422109127 0.8855779767 0.9241018295 + 0.9425022006 0.8860232830 0.9244589806 + 0.9427934885 0.8864685297 0.9248163104 + 0.9430847764 0.8869137764 0.9251735210 + 0.9433761239 0.8873590231 0.9255307913 + 0.9436674714 0.8878043294 0.9258880019 + 0.9439588189 0.8882495165 0.9262452722 + 0.9442501068 0.8886947036 0.9266026020 + 0.9445413947 0.8891400099 0.9269598126 + 0.9448264241 0.8895812035 0.9273141026 + 0.9451081157 0.8900203109 0.9276670814 + 0.9453896880 0.8904594779 0.9280200005 + 0.9456713796 0.8908985853 0.9283729792 + 0.9459530115 0.8913378119 0.9287258983 + 0.9462347031 0.8917769194 0.9290788770 + 0.9465163946 0.8922160864 0.9294317961 + 0.9467980266 0.8926551938 0.9297847748 + 0.9470797181 0.8930943012 0.9301376939 + 0.9473612905 0.8935335279 0.9304906726 + 0.9476429820 0.8939725757 0.9308435917 + 0.9479179978 0.8944123983 0.9311866164 + 0.9481912255 0.8948522806 0.9315270782 + 0.9484645128 0.8952922225 0.9318677187 + 0.9487376809 0.8957322240 0.9322082996 + 0.9490109086 0.8961721063 0.9325488806 + 0.9492841959 0.8966119885 0.9328895211 + 0.9495574236 0.8970518708 0.9332301021 + 0.9498305917 0.8974918127 0.9335706830 + 0.9501038790 0.8979318142 0.9339113235 + 0.9503771067 0.8983716965 0.9342517853 + 0.9506502748 0.8988115788 0.9345924258 + 0.9509218931 0.8992447257 0.9349266291 + 0.9511929750 0.8996757269 0.9352591038 + 0.9514641166 0.9001067281 0.9355915189 + 0.9517351985 0.9005377293 0.9359238744 + 0.9520063996 0.9009686708 0.9362562895 + 0.9522774816 0.9013996720 0.9365887046 + 0.9525486231 0.9018306732 0.9369211197 + 0.9528197050 0.9022616744 0.9372535944 + 0.9530907869 0.9026926756 0.9375860095 + 0.9533619285 0.9031236768 0.9379184246 + 0.9536330104 0.9035546780 0.9382507801 + 0.9538990855 0.9039816856 0.9385809898 + 0.9541615248 0.9044054747 0.9389094710 + 0.9544237852 0.9048293829 0.9392380118 + 0.9546862245 0.9052531719 0.9395664930 + 0.9549484849 0.9056770802 0.9398950934 + 0.9552109241 0.9061009884 0.9402235746 + 0.9554733038 0.9065247774 0.9405521154 + 0.9557356238 0.9069486856 0.9408807158 + 0.9559980035 0.9073724747 0.9412091970 + 0.9562603235 0.9077963829 0.9415376782 + 0.9565227032 0.9082202911 0.9418662190 + 0.9567822218 0.9086430073 0.9421923161 + 0.9570304155 0.9090616107 0.9425098896 + 0.9572787285 0.9094802141 0.9428274035 + 0.9575269818 0.9098988175 0.9431449771 + 0.9577752948 0.9103174210 0.9434624910 + 0.9580236077 0.9107360244 0.9437801242 + 0.9582718015 0.9111546278 0.9440975785 + 0.9585201144 0.9115732908 0.9444152117 + 0.9587684274 0.9119918942 0.9447327256 + 0.9590166807 0.9124104977 0.9450501800 + 0.9592649937 0.9128291011 0.9453678131 + 0.9595133066 0.9132477045 0.9456853271 + 0.9597612023 0.9136605859 0.9459949136 + 0.9600089192 0.9140707254 0.9463008046 + 0.9602565765 0.9144809246 0.9466066957 + 0.9605042934 0.9148911238 0.9469127059 + 0.9607520103 0.9153013229 0.9472185969 + 0.9609997272 0.9157114029 0.9475244880 + 0.9612473845 0.9161216021 0.9478303790 + 0.9614952207 0.9165318012 0.9481363893 + 0.9617428780 0.9169420004 0.9484422803 + 0.9619905949 0.9173520803 0.9487481713 + 0.9622383118 0.9177622795 0.9490541816 + 0.9624860287 0.9181724787 0.9493600726 + 0.9627341032 0.9185807109 0.9496526122 + 0.9629822969 0.9189888239 0.9499449730 + 0.9632303715 0.9193968773 0.9502373934 + 0.9634785056 0.9198051095 0.9505296946 + 0.9637266994 0.9202132225 0.9508221149 + 0.9639747739 0.9206213951 0.9511144161 + 0.9642229080 0.9210295081 0.9514067769 + 0.9644711018 0.9214376211 0.9516991973 + 0.9647191763 0.9218457937 0.9519914985 + 0.9649673104 0.9222539067 0.9522839189 + 0.9652153850 0.9226620197 0.9525762200 + 0.9654629827 0.9230692983 0.9528676867 + 0.9657052755 0.9234678149 0.9531521797 + 0.9659475088 0.9238663912 0.9534366727 + 0.9661898017 0.9242649078 0.9537212253 + 0.9664319754 0.9246634841 0.9540057182 + 0.9666743279 0.9250620008 0.9542902112 + 0.9669165015 0.9254605770 0.9545747042 + 0.9671587944 0.9258590937 0.9548591971 + 0.9674010277 0.9262577295 0.9551436901 + 0.9676433206 0.9266563058 0.9554281235 + 0.9678854942 0.9270548224 0.9557126164 + 0.9681277871 0.9274533987 0.9559971094 + 0.9683696032 0.9278519750 0.9562814832 + 0.9685997963 0.9282519817 0.9565635920 + 0.9688299894 0.9286519885 0.9568457007 + 0.9690603018 0.9290519953 0.9571278095 + 0.9692904949 0.9294521213 0.9574099779 + 0.9695206881 0.9298521280 0.9576920867 + 0.9697510004 0.9302520752 0.9579741955 + 0.9699811935 0.9306520820 0.9582563043 + 0.9702113867 0.9310522079 0.9585384130 + 0.9704415798 0.9314522147 0.9588205814 + 0.9706718922 0.9318522215 0.9591026902 + 0.9709020853 0.9322522283 0.9593847990 + 0.9711322784 0.9326522946 0.9596669078 + 0.9713497162 0.9330475926 0.9599413872 + 0.9715638161 0.9334416986 0.9602140784 + 0.9717779160 0.9338359237 0.9604868889 + 0.9719918966 0.9342300296 0.9607595801 + 0.9722059965 0.9346240759 0.9610322714 + 0.9724200964 0.9350183010 0.9613050222 + 0.9726341963 0.9354124069 0.9615777731 + 0.9728482962 0.9358065724 0.9618505239 + 0.9730623960 0.9362006783 0.9621232152 + 0.9732764959 0.9365949035 0.9623959064 + 0.9734905958 0.9369890094 0.9626687169 + 0.9737046957 0.9373831749 0.9629414082 + 0.9739152193 0.9377775788 0.9632083178 + 0.9741197228 0.9381725192 0.9634661078 + 0.9743241072 0.9385674000 0.9637240171 + 0.9745286107 0.9389622211 0.9639819264 + 0.9747331142 0.9393571019 0.9642397761 + 0.9749376178 0.9397519827 0.9644976258 + 0.9751421213 0.9401469231 0.9647554755 + 0.9753466249 0.9405416846 0.9650133848 + 0.9755511284 0.9409366250 0.9652711749 + 0.9757555723 0.9413315058 0.9655290842 + 0.9759600759 0.9417263865 0.9657869935 + 0.9761645794 0.9421213269 0.9660447836 + 0.9763690233 0.9425160885 0.9663026929 + 0.9765669107 0.9429088235 0.9665576220 + 0.9767628908 0.9433009028 0.9668117166 + 0.9769588113 0.9436929822 0.9670658112 + 0.9771547914 0.9440850019 0.9673200250 + 0.9773507118 0.9444770813 0.9675741196 + 0.9775466919 0.9448692203 0.9678282142 + 0.9777426124 0.9452611804 0.9680823088 + 0.9779385924 0.9456533194 0.9683364034 + 0.9781345129 0.9460453987 0.9685904980 + 0.9783304930 0.9464374781 0.9688445926 + 0.9785264134 0.9468294978 0.9690986872 + 0.9787223935 0.9472215772 0.9693527818 + 0.9789183140 0.9476137161 0.9696068764 + 0.9791035056 0.9479907155 0.9698532224 + 0.9792885184 0.9483674169 0.9700992703 + 0.9794734120 0.9487441778 0.9703454971 + 0.9796584249 0.9491209984 0.9705916047 + 0.9798433781 0.9494978189 0.9708377719 + 0.9800283909 0.9498745203 0.9710839987 + 0.9802134037 0.9502512813 0.9713301063 + 0.9803982973 0.9506281018 0.9715762734 + 0.9805833101 0.9510049224 0.9718223810 + 0.9807683229 0.9513816237 0.9720686078 + 0.9809532762 0.9517583847 0.9723147750 + 0.9811382890 0.9521352053 0.9725608826 + 0.9813233018 0.9525119066 0.9728069901 + 0.9815040231 0.9528858066 0.9730427265 + 0.9816848040 0.9532597065 0.9732784033 + 0.9818655849 0.9536336064 0.9735140800 + 0.9820463061 0.9540073872 0.9737498760 + 0.9822270870 0.9543812871 0.9739856124 + 0.9824079275 0.9547551870 0.9742212892 + 0.9825885892 0.9551290274 0.9744570255 + 0.9827694297 0.9555029273 0.9746928215 + 0.9829502106 0.9558768272 0.9749284983 + 0.9831308722 0.9562507272 0.9751641750 + 0.9833117127 0.9566245079 0.9753999114 + 0.9834924936 0.9569984078 0.9756355882 + 0.9836732149 0.9573723078 0.9758713841 + 0.9838451743 0.9577409029 0.9761005044 + 0.9840152264 0.9581084251 0.9763283134 + 0.9841852784 0.9584758878 0.9765561223 + 0.9843552709 0.9588434100 0.9767838717 + 0.9845253229 0.9592108130 0.9770116806 + 0.9846953750 0.9595782757 0.9772394896 + 0.9848654270 0.9599457979 0.9774672985 + 0.9850354791 0.9603133202 0.9776951075 + 0.9852054715 0.9606807828 0.9779229164 + 0.9853755832 0.9610483050 0.9781507254 + 0.9855455756 0.9614158273 0.9783784747 + 0.9857156277 0.9617832899 0.9786062837 + 0.9858856797 0.9621506929 0.9788340926 + 0.9860520959 0.9625151753 0.9790583253 + 0.9862139821 0.9628759027 0.9792780876 + 0.9863759875 0.9632365704 0.9794977903 + 0.9865378737 0.9635972977 0.9797176123 + 0.9866998792 0.9639580250 0.9799373746 + 0.9868618250 0.9643186927 0.9801570773 + 0.9870237112 0.9646794200 0.9803768992 + 0.9871857166 0.9650400877 0.9805967212 + 0.9873476028 0.9654006958 0.9808164239 + 0.9875096083 0.9657614231 0.9810361862 + 0.9876714945 0.9661220908 0.9812560081 + 0.9878333807 0.9664828181 0.9814757109 + 0.9879953861 0.9668434858 0.9816954732 + 0.9881572723 0.9672042131 0.9819152951 + 0.9883103967 0.9675583243 0.9821261764 + 0.9884620905 0.9679114223 0.9823359251 + 0.9886137843 0.9682645202 0.9825456142 + 0.9887655973 0.9686176181 0.9827553034 + 0.9889172912 0.9689707160 0.9829649925 + 0.9890691042 0.9693238139 0.9831746817 + 0.9892207980 0.9696769118 0.9833843708 + 0.9893726110 0.9700300097 0.9835941195 + 0.9895243049 0.9703831077 0.9838038087 + 0.9896761179 0.9707363248 0.9840136170 + 0.9898278117 0.9710894227 0.9842233062 + 0.9899795055 0.9714425206 0.9844329953 + 0.9901313186 0.9717956185 0.9846426845 + 0.9902822971 0.9721478224 0.9848514795 + 0.9904264808 0.9724920988 0.9850528240 + 0.9905707240 0.9728363752 0.9852542281 + 0.9907147884 0.9731807113 0.9854555130 + 0.9908589721 0.9735249281 0.9856567979 + 0.9910032153 0.9738692045 0.9858580828 + 0.9911473989 0.9742134809 0.9860594273 + 0.9912915230 0.9745578170 0.9862607121 + 0.9914357066 0.9749019742 0.9864619970 + 0.9915798903 0.9752463102 0.9866632819 + 0.9917240739 0.9755905867 0.9868646264 + 0.9918681979 0.9759349227 0.9870659113 + 0.9920123816 0.9762790799 0.9872671962 + 0.9921566248 0.9766234159 0.9874684811 + 0.9922997952 0.9769669175 0.9876685143 + 0.9924352765 0.9773039818 0.9878587723 + 0.9925708771 0.9776411057 0.9880490899 + 0.9927064180 0.9779782295 0.9882394075 + 0.9928418994 0.9783154130 0.9884296060 + 0.9929775000 0.9786524773 0.9886199236 + 0.9931129813 0.9789896011 0.9888101816 + 0.9932485223 0.9793267250 0.9890004992 + 0.9933841228 0.9796637893 0.9891908169 + 0.9935196042 0.9800009727 0.9893810153 + 0.9936550856 0.9803380966 0.9895712733 + 0.9937906861 0.9806752205 0.9897615910 + 0.9939262271 0.9810122848 0.9899519086 + 0.9940617085 0.9813494086 0.9901422262 + 0.9941973090 0.9816865921 0.9903324246 + 0.9943200946 0.9820179939 0.9905114174 + 0.9944419265 0.9823489785 0.9906893969 + 0.9945635796 0.9826800227 0.9908673167 + 0.9946854115 0.9830108881 0.9910452962 + 0.9948071241 0.9833418727 0.9912232757 + 0.9949287772 0.9836729169 0.9914013147 + 0.9950506091 0.9840037823 0.9915792942 + 0.9951723218 0.9843348265 0.9917572737 + 0.9952940941 0.9846658111 0.9919353127 + 0.9954158068 0.9849967957 0.9921132922 + 0.9955375791 0.9853277206 0.9922912717 + 0.9956592917 0.9856587052 0.9924693108 + 0.9957811236 0.9859896898 0.9926472902 + 0.9959027767 0.9863206148 0.9928253293 + 0.9960159063 0.9866454005 0.9930018783 + 0.9961208105 0.9869645238 0.9931772947 + 0.9962257147 0.9872835279 0.9933525920 + 0.9963306785 0.9876025915 0.9935278893 + 0.9964355826 0.9879215956 0.9937033057 + 0.9965404868 0.9882405996 0.9938786030 + 0.9966455102 0.9885597229 0.9940540195 + 0.9967504144 0.9888787270 0.9942293167 + 0.9968553185 0.9891976714 0.9944046736 + 0.9969602823 0.9895167947 0.9945799708 + 0.9970651865 0.9898357987 0.9947553873 + 0.9971700907 0.9901549220 0.9949306846 + 0.9972751141 0.9904739261 0.9951061010 + 0.9973800182 0.9907928705 0.9952813983 + 0.9974849224 0.9911119938 0.9954568148 + 0.9975774884 0.9914191961 0.9956181049 + 0.9976686239 0.9917250276 0.9957777858 + 0.9977596998 0.9920307994 0.9959375858 + 0.9978507757 0.9923365712 0.9960973263 + 0.9979419708 0.9926424026 0.9962570071 + 0.9980331063 0.9929481745 0.9964166880 + 0.9981241822 0.9932541251 0.9965764880 + 0.9982153177 0.9935598969 0.9967362285 + 0.9983065128 0.9938657284 0.9968959093 + 0.9983975887 0.9941715002 0.9970557094 + 0.9984887242 0.9944772720 0.9972153902 + 0.9985798001 0.9947832227 0.9973750710 + 0.9986709952 0.9950889945 0.9975348711 + 0.9987620711 0.9953948259 0.9976946115 + 0.9988523722 0.9956995249 0.9978532791 + 0.9989289045 0.9959862232 0.9979965091 + 0.9990053773 0.9962729216 0.9981396198 + 0.9990819097 0.9965596199 0.9982826710 + 0.9991583824 0.9968463182 0.9984257817 + 0.9992349148 0.9971330166 0.9985688925 + 0.9993113875 0.9974197149 0.9987120032 + 0.9993879199 0.9977064133 0.9988551140 + 0.9994643927 0.9979931116 0.9989982247 + 0.9995409250 0.9982798100 0.9991412759 + 0.9996175170 0.9985665083 0.9992843866 + 0.9996939898 0.9988532066 0.9994276166 + 0.9997705221 0.9991399050 0.9995707273 + 0.9998469949 0.9994266033 0.9997137785 + 0.9999235272 0.9997133017 0.9998568892 + 1.0000000000 1.0000000000 1.0000000000 +} diff --git a/rpplugins/color_correction/resources/film_luts_raw/fujifilm_fci.spi1d b/rpplugins/color_correction/resources/film_luts_raw/fujifilm_fci.spi1d new file mode 100644 index 0000000..c4ba530 --- /dev/null +++ b/rpplugins/color_correction/resources/film_luts_raw/fujifilm_fci.spi1d @@ -0,0 +1,1030 @@ +Version 1 +From 0.0 1.0 +Length 1024 +Components 3 +{ + 0.0000000000 0.0000000000 0.0000000000 + 0.0033529000 0.0050222902 0.0032476850 + 0.0072128819 0.0108181098 0.0077999481 + 0.0113698002 0.0162938796 0.0123000797 + 0.0156070897 0.0214859303 0.0166385006 + 0.0199807901 0.0263246894 0.0207970906 + 0.0243835095 0.0308334995 0.0247384906 + 0.0286132805 0.0350737683 0.0284963101 + 0.0324965417 0.0390635394 0.0320877396 + 0.0360950083 0.0428937711 0.0354904681 + 0.0395800695 0.0465790592 0.0387074091 + 0.0429466292 0.0501471013 0.0416742302 + 0.0462706387 0.0536180995 0.0443837605 + 0.0495057292 0.0570361391 0.0468798988 + 0.0526856817 0.0603578687 0.0492865406 + 0.0557528697 0.0635878816 0.0516750701 + 0.0587552190 0.0667311326 0.0540582016 + 0.0617134199 0.0698272586 0.0564595386 + 0.0646046400 0.0728573427 0.0588268489 + 0.0674475282 0.0758241564 0.0611601882 + 0.0702735782 0.0787356123 0.0634666085 + 0.0730631575 0.0815977603 0.0657490194 + 0.0758077726 0.0844080597 0.0680202469 + 0.0785278529 0.0871943235 0.0702772215 + 0.0811867565 0.0899614617 0.0725171790 + 0.0838195309 0.0926874802 0.0747344568 + 0.0863845199 0.0953808501 0.0769255832 + 0.0889284089 0.0980331302 0.0790845528 + 0.0914222598 0.1006408036 0.0812203065 + 0.0939096585 0.1032157987 0.0833272487 + 0.0963765979 0.1057695001 0.0854128227 + 0.0988149419 0.1082855985 0.0874713212 + 0.1012422964 0.1107629016 0.0895218775 + 0.1036200002 0.1132119000 0.0915501490 + 0.1059933975 0.1156331003 0.0935597792 + 0.1083453968 0.1180197969 0.0955581069 + 0.1106605977 0.1203960031 0.0975283831 + 0.1129731014 0.1227459982 0.0994904488 + 0.1152468994 0.1250717044 0.1014442965 + 0.1174897999 0.1273722053 0.1033670977 + 0.1197345033 0.1296402067 0.1052874029 + 0.1219704002 0.1319027990 0.1072127968 + 0.1241703033 0.1341574937 0.1091049984 + 0.1263649017 0.1363900006 0.1109855026 + 0.1285486072 0.1386093944 0.1128652021 + 0.1306926012 0.1408098936 0.1147162989 + 0.1328168064 0.1429897994 0.1165445000 + 0.1349381059 0.1451606005 0.1183724999 + 0.1370306015 0.1473139971 0.1202073991 + 0.1390942931 0.1494463980 0.1220164970 + 0.1411485970 0.1515574008 0.1238055974 + 0.1432065070 0.1536653936 0.1255939007 + 0.1452423036 0.1557527035 0.1273798943 + 0.1472520977 0.1578146964 0.1291383952 + 0.1492526978 0.1598653048 0.1308757067 + 0.1512524039 0.1619043052 0.1326085031 + 0.1532357931 0.1639177054 0.1343494058 + 0.1552000046 0.1659058034 0.1360910982 + 0.1571528018 0.1678874046 0.1378227025 + 0.1591075957 0.1698614955 0.1395412982 + 0.1610587984 0.1718100011 0.1412588060 + 0.1629907042 0.1737367064 0.1429695040 + 0.1649049968 0.1756578982 0.1446525007 + 0.1668141931 0.1775816977 0.1463117003 + 0.1687301993 0.1794971973 0.1479572952 + 0.1706393063 0.1813943982 0.1495992988 + 0.1725254953 0.1832813025 0.1512472928 + 0.1743942946 0.1851720065 0.1529006958 + 0.1762564927 0.1870612949 0.1545381993 + 0.1781218946 0.1889400929 0.1561595052 + 0.1799844950 0.1908051968 0.1577727944 + 0.1818296015 0.1926642060 0.1593860984 + 0.1836557984 0.1945220977 0.1609999985 + 0.1854719967 0.1963763982 0.1625989974 + 0.1872864068 0.1982188970 0.1641764939 + 0.1891041994 0.2000444978 0.1657395959 + 0.1909209043 0.2018636018 0.1672948003 + 0.1927119941 0.2036861926 0.1688483953 + 0.1944850981 0.2054955065 0.1704075038 + 0.1962500066 0.2072805017 0.1719689965 + 0.1980129927 0.2090491951 0.1735302061 + 0.1997700036 0.2108096033 0.1750829965 + 0.2015154958 0.2125660926 0.1766262054 + 0.2032480985 0.2143186033 0.1781643927 + 0.2049618065 0.2160613984 0.1797035038 + 0.2066676021 0.2177938968 0.1812402010 + 0.2083701938 0.2195162028 0.1827660948 + 0.2100692987 0.2212309986 0.1842781007 + 0.2117556036 0.2229442000 0.1857748926 + 0.2134384066 0.2246554941 0.1872583032 + 0.2151104063 0.2263627946 0.1887380928 + 0.2167720050 0.2280618995 0.1902170032 + 0.2184257954 0.2297437936 0.1916978061 + 0.2200689018 0.2314164937 0.1931888014 + 0.2217032015 0.2330885977 0.1946718991 + 0.2233294994 0.2347614020 0.1961459965 + 0.2249525934 0.2364338040 0.1976051033 + 0.2265653014 0.2380886972 0.1990566999 + 0.2281704992 0.2397311032 0.2005050927 + 0.2297694981 0.2413610071 0.2019519955 + 0.2313688993 0.2429879010 0.2034036070 + 0.2329650968 0.2446155995 0.2048534006 + 0.2345501930 0.2462483943 0.2062973976 + 0.2361329943 0.2478673011 0.2077303976 + 0.2377143055 0.2494771034 0.2091592997 + 0.2392926067 0.2510702908 0.2105841041 + 0.2408663034 0.2526575029 0.2120015025 + 0.2424364984 0.2542414963 0.2134159952 + 0.2439859062 0.2558271885 0.2148285061 + 0.2455307990 0.2574067116 0.2162439972 + 0.2470698953 0.2589786947 0.2176620960 + 0.2486097962 0.2605280876 0.2190825939 + 0.2501479089 0.2620697916 0.2204976976 + 0.2516750991 0.2635981143 0.2218970954 + 0.2531996965 0.2651236951 0.2232882977 + 0.2547213137 0.2666468024 0.2246735990 + 0.2562285066 0.2681731880 0.2260529995 + 0.2577311993 0.2696993053 0.2274315953 + 0.2592264116 0.2712090015 0.2288105935 + 0.2607224882 0.2727130949 0.2301889062 + 0.2622207999 0.2742044926 0.2315658033 + 0.2637135983 0.2756915987 0.2329387963 + 0.2652012110 0.2771748006 0.2343091965 + 0.2666864991 0.2786591947 0.2356632948 + 0.2681710124 0.2801440060 0.2370133996 + 0.2696504891 0.2816297114 0.2383510023 + 0.2711291909 0.2831149995 0.2396876067 + 0.2726014853 0.2845805883 0.2410192937 + 0.2740728855 0.2860446870 0.2423513979 + 0.2755376995 0.2874991000 0.2436847985 + 0.2770003974 0.2889532149 0.2450177968 + 0.2784548104 0.2904062867 0.2463497967 + 0.2799058855 0.2918587029 0.2476796955 + 0.2813473046 0.2933095098 0.2490058988 + 0.2827846110 0.2947534919 0.2503249049 + 0.2842110097 0.2961812913 0.2516323030 + 0.2856361866 0.2976050079 0.2529352903 + 0.2870579064 0.2990190089 0.2542308867 + 0.2884807885 0.3004320860 0.2555251122 + 0.2899079919 0.3018426001 0.2568162084 + 0.2913340926 0.3032543063 0.2581079900 + 0.2927548885 0.3046708107 0.2594015896 + 0.2941757143 0.3060868084 0.2606950998 + 0.2955969870 0.3074971139 0.2619884014 + 0.2970184088 0.3089073896 0.2632819116 + 0.2984277010 0.3103012145 0.2645807862 + 0.2998363078 0.3116944134 0.2658798099 + 0.3012431860 0.3130815029 0.2671642900 + 0.3026494980 0.3144671023 0.2684471011 + 0.3040472865 0.3158538043 0.2697230875 + 0.3054392934 0.3172411919 0.2709963024 + 0.3068284094 0.3186290860 0.2722682953 + 0.3082126975 0.3200176060 0.2735388875 + 0.3095946908 0.3214035928 0.2748104036 + 0.3109588921 0.3227730095 0.2760851979 + 0.3123230934 0.3241423070 0.2773601115 + 0.3136793077 0.3255028129 0.2786275148 + 0.3150336146 0.3268615901 0.2798944116 + 0.3163881004 0.3282201886 0.2811588943 + 0.3177425861 0.3295786977 0.2824218869 + 0.3190953135 0.3309383988 0.2836810946 + 0.3204368949 0.3323050141 0.2849281132 + 0.3217783868 0.3336715996 0.2861750126 + 0.3231084049 0.3350208998 0.2874141932 + 0.3244343996 0.3363648057 0.2886519134 + 0.3257552087 0.3377039135 0.2898885906 + 0.3270645142 0.3390335143 0.2911236882 + 0.3283737898 0.3403630853 0.2923589051 + 0.3296771944 0.3416889906 0.2935976982 + 0.3309794068 0.3430142105 0.2948367894 + 0.3322823942 0.3443411887 0.2960684001 + 0.3335868120 0.3456712961 0.2972904146 + 0.3348912001 0.3470014036 0.2985123992 + 0.3361887038 0.3483262956 0.2997243106 + 0.3374845088 0.3496501148 0.3009350896 + 0.3387758136 0.3509699106 0.3021413982 + 0.3400512934 0.3522767127 0.3033381999 + 0.3413268030 0.3535835147 0.3045350015 + 0.3425957859 0.3548851907 0.3057265878 + 0.3438603878 0.3561838865 0.3069159091 + 0.3451249003 0.3574824929 0.3081052899 + 0.3463880122 0.3587825894 0.3092936873 + 0.3476510942 0.3600828052 0.3104822040 + 0.3489136994 0.3613828123 0.3116725981 + 0.3501749933 0.3626824915 0.3128665984 + 0.3514364064 0.3639822900 0.3140606880 + 0.3526903093 0.3652707934 0.3152511120 + 0.3539369106 0.3665491939 0.3164390028 + 0.3551836014 0.3678277135 0.3176268935 + 0.3564186096 0.3690966964 0.3188065886 + 0.3576493859 0.3703624904 0.3199844956 + 0.3588801026 0.3716283143 0.3211624026 + 0.3601047099 0.3728910983 0.3223274946 + 0.3613288105 0.3741537035 0.3234925866 + 0.3625529110 0.3754166067 0.3246566951 + 0.3637793064 0.3766838908 0.3258154094 + 0.3650057018 0.3779512048 0.3269740045 + 0.3662337065 0.3792163134 0.3281326890 + 0.3674710095 0.3804695904 0.3292913139 + 0.3687084019 0.3817228973 0.3304499090 + 0.3699420094 0.3829731941 0.3316102922 + 0.3711602986 0.3842121959 0.3327750862 + 0.3723787069 0.3854511976 0.3339399993 + 0.3735949099 0.3866888881 0.3351032138 + 0.3748030066 0.3879219890 0.3362624049 + 0.3760110140 0.3891550899 0.3374215961 + 0.3772188127 0.3903886080 0.3385764062 + 0.3784255981 0.3916240931 0.3397186995 + 0.3796324134 0.3928596079 0.3408609927 + 0.3808397949 0.3940944076 0.3420014083 + 0.3820542097 0.3953225017 0.3431330025 + 0.3832687140 0.3965505064 0.3442645073 + 0.3844830990 0.3977786005 0.3453958035 + 0.3856852055 0.3989897966 0.3465226889 + 0.3868865967 0.4002004862 0.3476496041 + 0.3880881071 0.4014112055 0.3487764895 + 0.3892784119 0.4026145041 0.3499045968 + 0.3904655874 0.4038158953 0.3510330021 + 0.3916527927 0.4050172865 0.3521612883 + 0.3928368986 0.4062179923 0.3532944024 + 0.3940187097 0.4074181020 0.3544299901 + 0.3952004015 0.4086182117 0.3555656970 + 0.3963829875 0.4098179936 0.3566969037 + 0.3975678086 0.4110169113 0.3578208089 + 0.3987526894 0.4122158885 0.3589447141 + 0.3999375105 0.4134148955 0.3600678146 + 0.4011155963 0.4145950079 0.3611775935 + 0.4022935033 0.4157749116 0.3622873127 + 0.4034712911 0.4169546962 0.3633970916 + 0.4046387970 0.4181272984 0.3645012081 + 0.4057992101 0.4192951918 0.3656027913 + 0.4069595933 0.4204632044 0.3667044044 + 0.4081184864 0.4216302931 0.3678053021 + 0.4092698991 0.4227936864 0.3689045906 + 0.4104213119 0.4239571989 0.3700039089 + 0.4115728140 0.4251207113 0.3711032867 + 0.4127238989 0.4262751043 0.3721981943 + 0.4138750136 0.4274260998 0.3732920885 + 0.4150260091 0.4285770059 0.3743860126 + 0.4161767960 0.4297257066 0.3754799068 + 0.4173265100 0.4308654070 0.3765740991 + 0.4184763134 0.4320049882 0.3776682913 + 0.4196259975 0.4331446886 0.3787625134 + 0.4207628965 0.4342770875 0.3798545003 + 0.4218915105 0.4354051948 0.3809455037 + 0.4230200946 0.4365333021 0.3820365965 + 0.4241487980 0.4376614094 0.3831265867 + 0.4252648056 0.4387851059 0.3842037916 + 0.4263804853 0.4399087131 0.3852809966 + 0.4274963140 0.4410324097 0.3863582909 + 0.4286107123 0.4421544969 0.3874323070 + 0.4297220111 0.4432731867 0.3885014951 + 0.4308333099 0.4443919063 0.3895707130 + 0.4319446087 0.4455106854 0.3906398118 + 0.4330579937 0.4466271102 0.3917075098 + 0.4341728985 0.4477419853 0.3927743137 + 0.4352878034 0.4488568008 0.3938410878 + 0.4364027083 0.4499715865 0.3949080110 + 0.4375129938 0.4510774016 0.3959777057 + 0.4386217892 0.4521808028 0.3970479965 + 0.4397307038 0.4532842040 0.3981181979 + 0.4408395886 0.4543874860 0.3991884887 + 0.4419341087 0.4554865062 0.4002597928 + 0.4430272877 0.4565851986 0.4013310969 + 0.4441205859 0.4576838911 0.4024024010 + 0.4452137053 0.4587827027 0.4034720063 + 0.4462993145 0.4598833919 0.4045264125 + 0.4473848939 0.4609842002 0.4055807889 + 0.4484705031 0.4620848894 0.4066353142 + 0.4495561123 0.4631853998 0.4076882005 + 0.4506419003 0.4642808139 0.4087311029 + 0.4517278075 0.4653762877 0.4097740948 + 0.4528135955 0.4664717019 0.4108170867 + 0.4538995028 0.4675666988 0.4118593931 + 0.4549854994 0.4686492980 0.4128966033 + 0.4560714960 0.4697318971 0.4139338136 + 0.4571574926 0.4708144069 0.4149709940 + 0.4582434893 0.4718970060 0.4160081148 + 0.4593130946 0.4729729891 0.4170450866 + 0.4603815079 0.4740487039 0.4180820882 + 0.4614498913 0.4751243889 0.4191190898 + 0.4625183940 0.4762001038 0.4201560915 + 0.4635789990 0.4772703052 0.4211978018 + 0.4646374881 0.4783391058 0.4222402871 + 0.4656960070 0.4794079065 0.4232827127 + 0.4667544961 0.4804767072 0.4243251085 + 0.4678117931 0.4815419912 0.4253644943 + 0.4688681960 0.4826048911 0.4264025092 + 0.4699246883 0.4836677015 0.4274404049 + 0.4709810913 0.4847306013 0.4284783900 + 0.4720368981 0.4857918918 0.4295131862 + 0.4730910957 0.4868499935 0.4305432141 + 0.4741452932 0.4879080951 0.4315730929 + 0.4751994908 0.4889661968 0.4326030910 + 0.4762536883 0.4900242984 0.4336324930 + 0.4772971869 0.4910764992 0.4346519113 + 0.4783403873 0.4921286106 0.4356713891 + 0.4793835878 0.4931806922 0.4366908967 + 0.4804266989 0.4942328036 0.4377104044 + 0.4814636111 0.4952807128 0.4387266040 + 0.4824956954 0.4963257015 0.4397411942 + 0.4835278988 0.4973706007 0.4407558143 + 0.4845600128 0.4984155893 0.4417704046 + 0.4855917990 0.4994598031 0.4427852035 + 0.4866203964 0.5004987717 0.4438005090 + 0.4876489937 0.5015376806 0.4448158145 + 0.4886775911 0.5025765896 0.4458310902 + 0.4897061884 0.5036156178 0.4468463957 + 0.4907324910 0.5046514869 0.4478605092 + 0.4917572141 0.5056853294 0.4488740861 + 0.4927819073 0.5067191720 0.4498876035 + 0.4938066006 0.5077530146 0.4509010911 + 0.4948312938 0.5087867975 0.4519143999 + 0.4958443046 0.5098149776 0.4529229105 + 0.4968571067 0.5108430982 0.4539315104 + 0.4978697896 0.5118712783 0.4549399912 + 0.4988825917 0.5128993988 0.4559485912 + 0.4998916090 0.5139253736 0.4569540024 + 0.5008922219 0.5149468184 0.4579545856 + 0.5018928051 0.5159683228 0.4589551985 + 0.5028933883 0.5169898272 0.4599558115 + 0.5038939714 0.5180112123 0.4609563947 + 0.5048918128 0.5190292001 0.4619503915 + 0.5058875084 0.5200446248 0.4629409909 + 0.5068832040 0.5210601091 0.4639315009 + 0.5078788996 0.5220755935 0.4649220109 + 0.5088744760 0.5230910182 0.4659124911 + 0.5098662972 0.5240967274 0.4668990970 + 0.5108568072 0.5250995159 0.4678849876 + 0.5118473172 0.5261024237 0.4688709080 + 0.5128378868 0.5271052122 0.4698567986 + 0.5138283968 0.5281080008 0.4708425999 + 0.5148209929 0.5291042924 0.4718292058 + 0.5158140063 0.5300996900 0.4728156924 + 0.5168069005 0.5310950875 0.4738022983 + 0.5177997947 0.5320904851 0.4747888148 + 0.5187928081 0.5330858827 0.4757753909 + 0.5197734237 0.5340675712 0.4767676890 + 0.5207530260 0.5350484252 0.4777599871 + 0.5217326283 0.5360292196 0.4787522852 + 0.5227121115 0.5370100141 0.4797446132 + 0.5236917138 0.5379908085 0.4807369113 + 0.5246657729 0.5389664173 0.4817185104 + 0.5256392956 0.5399416089 0.4826998115 + 0.5266126990 0.5409168005 0.4836811125 + 0.5275862217 0.5418918729 0.4846624136 + 0.5285596251 0.5428671241 0.4856437147 + 0.5295339823 0.5438383222 0.4866138101 + 0.5305086970 0.5448085070 0.4875822067 + 0.5314832926 0.5457786918 0.4885506034 + 0.5324578881 0.5467488766 0.4895190895 + 0.5334326029 0.5477191806 0.4904874861 + 0.5344074965 0.5486854911 0.4914506078 + 0.5353826284 0.5496494770 0.4924111962 + 0.5363577008 0.5506135225 0.4933719039 + 0.5373327732 0.5515775084 0.4943326116 + 0.5383079052 0.5525414944 0.4952932000 + 0.5392804146 0.5535004735 0.4962526858 + 0.5402482152 0.5544509292 0.4972105920 + 0.5412160158 0.5554013848 0.4981685877 + 0.5421838164 0.5563517809 0.4991264939 + 0.5431516171 0.5573021770 0.5000844002 + 0.5441191792 0.5582525134 0.5010424852 + 0.5450795889 0.5591980219 0.5020027161 + 0.5460399985 0.5601435900 0.5029628873 + 0.5470004082 0.5610890985 0.5039231181 + 0.5479608178 0.5620347261 0.5048832297 + 0.5489212275 0.5629801750 0.5058434010 + 0.5498812795 0.5639281273 0.5067989230 + 0.5508412719 0.5648773909 0.5077521801 + 0.5518013239 0.5658267140 0.5087053776 + 0.5527613759 0.5667759776 0.5096586943 + 0.5537214279 0.5677253008 0.5106120110 + 0.5546813011 0.5686742067 0.5115646720 + 0.5556406975 0.5696194172 0.5125145912 + 0.5566000938 0.5705646276 0.5134643912 + 0.5575594902 0.5715097785 0.5144143105 + 0.5585188866 0.5724549890 0.5153642297 + 0.5594782829 0.5734001994 0.5163140893 + 0.5604329705 0.5743389726 0.5172604918 + 0.5613837242 0.5752723813 0.5182046294 + 0.5623344183 0.5762056708 0.5191487074 + 0.5632849932 0.5771390796 0.5200927854 + 0.5642356873 0.5780724883 0.5210369825 + 0.5651863813 0.5790058970 0.5219811201 + 0.5661293268 0.5799363256 0.5229173899 + 0.5670710802 0.5808663964 0.5238531828 + 0.5680128932 0.5817964077 0.5247889757 + 0.5689548254 0.5827264190 0.5257248878 + 0.5698965788 0.5836563706 0.5266606808 + 0.5708373189 0.5845860243 0.5275958776 + 0.5717707872 0.5855131745 0.5285283923 + 0.5727043152 0.5864403844 0.5294609070 + 0.5736377239 0.5873675942 0.5303934813 + 0.5745711923 0.5882948041 0.5313259959 + 0.5755046010 0.5892218947 0.5322586298 + 0.5764377117 0.5901458859 0.5331916809 + 0.5773698092 0.5910627246 0.5341259241 + 0.5783019066 0.5919793844 0.5350601077 + 0.5792340040 0.5928962231 0.5359942913 + 0.5801661015 0.5938128829 0.5369284749 + 0.5810983181 0.5947296023 0.5378627181 + 0.5820268989 0.5956423879 0.5387967229 + 0.5829498768 0.5965489149 0.5397306085 + 0.5838727951 0.5974555016 0.5406643748 + 0.5847957134 0.5983620286 0.5415983200 + 0.5857185721 0.5992684960 0.5425322056 + 0.5866414905 0.6001750231 0.5434659719 + 0.5875610113 0.6010807753 0.5443956852 + 0.5884745121 0.6019853950 0.5453197956 + 0.5893880129 0.6028900146 0.5462440252 + 0.5903015137 0.6037945747 0.5471680760 + 0.5912150145 0.6046991944 0.5480923057 + 0.5921285152 0.6056038141 0.5490164757 + 0.5930395126 0.6065080166 0.5499367118 + 0.5939435959 0.6074110866 0.5508491993 + 0.5948476791 0.6083140969 0.5517616868 + 0.5957517028 0.6092172265 0.5526741743 + 0.5966557860 0.6101201773 0.5535867810 + 0.5975599289 0.6110233068 0.5544993281 + 0.5984631777 0.6119254827 0.5554108024 + 0.5993574858 0.6128194928 0.5563166142 + 0.6002519131 0.6137136221 0.5572223067 + 0.6011462808 0.6146075726 0.5581281185 + 0.6020405889 0.6155017018 0.5590338111 + 0.6029350162 0.6163957119 0.5599395037 + 0.6038293242 0.6172897816 0.5608453155 + 0.6047170162 0.6181768179 0.5617492795 + 0.6056030989 0.6190621853 0.5626531243 + 0.6064891219 0.6199476123 0.5635567904 + 0.6073752046 0.6208329797 0.5644605756 + 0.6082612276 0.6217185259 0.5653644204 + 0.6091471910 0.6226038933 0.5662680864 + 0.6100293994 0.6234887838 0.5671733022 + 0.6109064221 0.6243731976 0.5680798888 + 0.6117833257 0.6252574921 0.5689864159 + 0.6126602888 0.6261419058 0.5698930025 + 0.6135371923 0.6270262003 0.5707995892 + 0.6144142151 0.6279106140 0.5717061758 + 0.6152911782 0.6287949085 0.5726128221 + 0.6161587834 0.6296725273 0.5735203028 + 0.6170259714 0.6305497885 0.5744279027 + 0.6178932190 0.6314271092 0.5753353834 + 0.6187602878 0.6323043704 0.5762429237 + 0.6196274757 0.6331816912 0.5771505237 + 0.6204947233 0.6340590119 0.5780580044 + 0.6213582158 0.6349307895 0.5789619088 + 0.6222159863 0.6357945204 0.5798614025 + 0.6230738163 0.6366583109 0.5807610154 + 0.6239315867 0.6375219822 0.5816605091 + 0.6247894168 0.6383857131 0.5825600028 + 0.6256471872 0.6392493844 0.5834594965 + 0.6265048981 0.6401131153 0.5843591094 + 0.6273571253 0.6409724951 0.5852504969 + 0.6282070279 0.6418303847 0.5861397982 + 0.6290569901 0.6426882148 0.5870289803 + 0.6299068928 0.6435461044 0.5879182816 + 0.6307569146 0.6444038749 0.5888075829 + 0.6316068172 0.6452617049 0.5896968842 + 0.6324567795 0.6461195946 0.5905860066 + 0.6333056092 0.6469790936 0.5914697051 + 0.6341544986 0.6478387117 0.5923534036 + 0.6350033283 0.6486982107 0.5932369828 + 0.6358520985 0.6495578289 0.5941206813 + 0.6367009282 0.6504173279 0.5950043797 + 0.6375498176 0.6512768865 0.5958880782 + 0.6383976936 0.6521351933 0.5967717171 + 0.6392375231 0.6529834867 0.5976545215 + 0.6400774121 0.6538317800 0.5985373855 + 0.6409171820 0.6546800733 0.5994203091 + 0.6417570114 0.6555284262 0.6003031135 + 0.6425967813 0.6563767195 0.6011859775 + 0.6434366107 0.6572250128 0.6020689011 + 0.6442754269 0.6580716968 0.6029512286 + 0.6451067924 0.6589083076 0.6038312912 + 0.6459382772 0.6597449780 0.6047112942 + 0.6467698216 0.6605815887 0.6055914164 + 0.6476011872 0.6614183187 0.6064714193 + 0.6484326720 0.6622549295 0.6073514819 + 0.6492642164 0.6630915999 0.6082314849 + 0.6500955820 0.6639279723 0.6091110110 + 0.6509268880 0.6647610068 0.6099858880 + 0.6517581940 0.6655939817 0.6108608842 + 0.6525893807 0.6664270163 0.6117358208 + 0.6534206867 0.6672599912 0.6126108170 + 0.6542518735 0.6680930853 0.6134856939 + 0.6550831795 0.6689261198 0.6143606901 + 0.6559144855 0.6697590947 0.6152356267 + 0.6567456722 0.6705949903 0.6160972714 + 0.6575769782 0.6714311838 0.6169580817 + 0.6584082246 0.6722674966 0.6178188920 + 0.6592394710 0.6731036901 0.6186797023 + 0.6600707769 0.6739400029 0.6195405126 + 0.6609020233 0.6747761965 0.6204013228 + 0.6617333293 0.6756125093 0.6212620735 + 0.6625599861 0.6764392257 0.6221166849 + 0.6633837223 0.6772598028 0.6229680777 + 0.6642073989 0.6780803204 0.6238194704 + 0.6650310755 0.6789008975 0.6246708035 + 0.6658548117 0.6797214150 0.6255221963 + 0.6666784883 0.6805419922 0.6263735294 + 0.6675022244 0.6813625097 0.6272249222 + 0.6683244705 0.6821811795 0.6280750036 + 0.6691414714 0.6829928756 0.6289216280 + 0.6699584723 0.6838045716 0.6297681928 + 0.6707754731 0.6846163869 0.6306148171 + 0.6715924740 0.6854280829 0.6314613819 + 0.6724094748 0.6862397790 0.6323080063 + 0.6732264757 0.6870514750 0.6331545711 + 0.6740434766 0.6878631711 0.6340011954 + 0.6748613715 0.6886737943 0.6348477006 + 0.6756796837 0.6894840002 0.6356942058 + 0.6764978766 0.6902940869 0.6365405917 + 0.6773161888 0.6911042929 0.6373870969 + 0.6781343818 0.6919143796 0.6382334828 + 0.6789526939 0.6927245855 0.6390799880 + 0.6797710061 0.6935346723 0.6399263740 + 0.6805893183 0.6943448186 0.6407734752 + 0.6814084053 0.6951546073 0.6416242123 + 0.6822274923 0.6959642768 0.6424750090 + 0.6830466986 0.6967741251 0.6433258057 + 0.6838657856 0.6975837946 0.6441764832 + 0.6846848726 0.6983935833 0.6450272799 + 0.6855040193 0.6992033124 0.6458780169 + 0.6863232255 0.7000131011 0.6467288136 + 0.6871380806 0.7008184195 0.6475781798 + 0.6879450083 0.7016159892 0.6484256983 + 0.6887519956 0.7024134994 0.6492732167 + 0.6895589828 0.7032110095 0.6501206756 + 0.6903660297 0.7040085793 0.6509681940 + 0.6911730170 0.7048060894 0.6518155932 + 0.6919798851 0.7056037188 0.6526631117 + 0.6927868724 0.7064012289 0.6535105705 + 0.6935915947 0.7071955800 0.6543517113 + 0.6943939924 0.7079871893 0.6551877260 + 0.6951963902 0.7087786794 0.6560238004 + 0.6959987879 0.7095702291 0.6568598151 + 0.6968013048 0.7103617787 0.6576958895 + 0.6976037025 0.7111533284 0.6585319042 + 0.6984061003 0.7119448185 0.6593679786 + 0.6992084980 0.7127364278 0.6602039933 + 0.7000085711 0.7135254145 0.6610358953 + 0.7008067966 0.7143123150 0.6618649960 + 0.7016050220 0.7150992155 0.6626940966 + 0.7024031878 0.7158861160 0.6635231972 + 0.7032014132 0.7166730165 0.6643521786 + 0.7039995790 0.7174599767 0.6651812792 + 0.7047978044 0.7182468772 0.6660103798 + 0.7055960298 0.7190337777 0.6668394804 + 0.7063922286 0.7198162079 0.6676673889 + 0.7071862221 0.7205935717 0.6684942245 + 0.7079802155 0.7213708758 0.6693210006 + 0.7087742090 0.7221482992 0.6701477766 + 0.7095682025 0.7229256034 0.6709744930 + 0.7103621960 0.7237030268 0.6718013287 + 0.7111561894 0.7244802713 0.6726281047 + 0.7119501829 0.7252575755 0.6734548807 + 0.7127416134 0.7260324955 0.6742823720 + 0.7135254741 0.7268006802 0.6751112938 + 0.7143093944 0.7275689244 0.6759402752 + 0.7150933146 0.7283371091 0.6767693162 + 0.7158772945 0.7291052938 0.6775982976 + 0.7166612148 0.7298734784 0.6784272790 + 0.7174450755 0.7306417227 0.6792562008 + 0.7182289958 0.7314097881 0.6800851822 + 0.7190129757 0.7321779728 0.6809142232 + 0.7197942138 0.7329385281 0.6817373037 + 0.7205750942 0.7336984277 0.6825603843 + 0.7213560939 0.7344583869 0.6833835244 + 0.7221370935 0.7352182865 0.6842064857 + 0.7229180932 0.7359783053 0.6850296259 + 0.7236990929 0.7367382050 0.6858527064 + 0.7244800925 0.7374982238 0.6866757870 + 0.7252609730 0.7382581234 0.6874988079 + 0.7260380983 0.7390146852 0.6883146763 + 0.7268108726 0.7397677898 0.6891244054 + 0.7275837064 0.7405210137 0.6899340749 + 0.7283565998 0.7412741184 0.6907438040 + 0.7291293740 0.7420272231 0.6915534735 + 0.7299022079 0.7427803278 0.6923632026 + 0.7306751013 0.7435334921 0.6931728721 + 0.7314478755 0.7442865968 0.6939826012 + 0.7322207093 0.7450397015 0.6947922707 + 0.7329800129 0.7457880974 0.6955934167 + 0.7337378860 0.7465360761 0.6963940263 + 0.7344958186 0.7472841740 0.6971946955 + 0.7352536917 0.7480322123 0.6979954243 + 0.7360116243 0.7487801909 0.6987960935 + 0.7367694974 0.7495282292 0.6995967031 + 0.7375273705 0.7502762079 0.7003973722 + 0.7382853031 0.7510241866 0.7011981010 + 0.7390416265 0.7517700195 0.7019975781 + 0.7397916913 0.7525079250 0.7027937174 + 0.7405418754 0.7532457709 0.7035897970 + 0.7412921190 0.7539836168 0.7043858767 + 0.7420421839 0.7547215223 0.7051818967 + 0.7427924275 0.7554594278 0.7059779763 + 0.7435424924 0.7561972141 0.7067741156 + 0.7442926764 0.7569351196 0.7075701952 + 0.7450429201 0.7576729059 0.7083662748 + 0.7457928061 0.7584072948 0.7091622949 + 0.7465423942 0.7591359019 0.7099583149 + 0.7472919226 0.7598643899 0.7107542157 + 0.7480415106 0.7605929971 0.7115501761 + 0.7487909794 0.7613216043 0.7123461962 + 0.7495406270 0.7620502114 0.7131420970 + 0.7502900958 0.7627788186 0.7139381170 + 0.7510396838 0.7635074258 0.7147340178 + 0.7517892122 0.7642359138 0.7155299783 + 0.7525364161 0.7649617195 0.7163277864 + 0.7532799244 0.7656834722 0.7171276808 + 0.7540233731 0.7664054036 0.7179276943 + 0.7547670007 0.7671272159 0.7187277079 + 0.7555105090 0.7678490281 0.7195277214 + 0.7562540770 0.7685709000 0.7203276157 + 0.7569975853 0.7692927122 0.7211276293 + 0.7577412128 0.7700145245 0.7219275832 + 0.7584847212 0.7707362771 0.7227275968 + 0.7592245936 0.7714542747 0.7235243917 + 0.7599560022 0.7721639276 0.7243157029 + 0.7606874108 0.7728734016 0.7251068950 + 0.7614188790 0.7735829949 0.7258980870 + 0.7621502876 0.7742925286 0.7266892791 + 0.7628818154 0.7750021219 0.7274805903 + 0.7636132240 0.7757117152 0.7282717824 + 0.7643446922 0.7764211893 0.7290629745 + 0.7650761008 0.7771307826 0.7298542261 + 0.7658072114 0.7778394818 0.7306442261 + 0.7665333748 0.7785378098 0.7314252257 + 0.7672595978 0.7792360783 0.7322061062 + 0.7679858208 0.7799345255 0.7329869866 + 0.7687121034 0.7806327939 0.7337679267 + 0.7694383264 0.7813311815 0.7345489264 + 0.7701644897 0.7820295095 0.7353298068 + 0.7708907127 0.7827278972 0.7361106873 + 0.7716168761 0.7834262252 0.7368916869 + 0.7723432183 0.7841246128 0.7376726270 + 0.7730664015 0.7848206162 0.7384489775 + 0.7737882733 0.7855157256 0.7392237782 + 0.7745103240 0.7862107754 0.7399985790 + 0.7752321959 0.7869058847 0.7407733798 + 0.7759541869 0.7876011133 0.7415481806 + 0.7766761184 0.7882962227 0.7423229814 + 0.7773981094 0.7889912724 0.7430977821 + 0.7781199813 0.7896863818 0.7438725829 + 0.7788419724 0.7903814912 0.7446473837 + 0.7795621753 0.7910752892 0.7454218268 + 0.7802751064 0.7917634845 0.7461947799 + 0.7809879780 0.7924516201 0.7469677925 + 0.7817009091 0.7931398153 0.7477408051 + 0.7824137807 0.7938280106 0.7485138178 + 0.7831267118 0.7945162058 0.7492867708 + 0.7838395834 0.7952044010 0.7500599027 + 0.7845525146 0.7958925962 0.7508329153 + 0.7852653861 0.7965807915 0.7516059279 + 0.7859783173 0.7972689867 0.7523788810 + 0.7866867781 0.7979509234 0.7531532049 + 0.7873914838 0.7986276150 0.7539284229 + 0.7880961895 0.7993041873 0.7547037005 + 0.7888008952 0.7999808192 0.7554789782 + 0.7895056009 0.8006573915 0.7562541962 + 0.7902103066 0.8013340831 0.7570294738 + 0.7909150124 0.8020107150 0.7578048110 + 0.7916197181 0.8026872873 0.7585800290 + 0.7923244238 0.8033639193 0.7593553066 + 0.7930291295 0.8040404916 0.7601305246 + 0.7937325239 0.8047140241 0.7609025836 + 0.7944355011 0.8053864241 0.7616736889 + 0.7951384783 0.8060588241 0.7624449134 + 0.7958415151 0.8067312241 0.7632160187 + 0.7965444922 0.8074036241 0.7639871240 + 0.7972475290 0.8080759048 0.7647582889 + 0.7979503870 0.8087483048 0.7655293941 + 0.7986534238 0.8094207048 0.7663004994 + 0.7993564010 0.8100931048 0.7670717239 + 0.8000593781 0.8107655048 0.7678428292 + 0.8007569909 0.8114361167 0.7686048746 + 0.8014531732 0.8121061921 0.7693650126 + 0.8021494150 0.8127763867 0.7701252103 + 0.8028455973 0.8134465218 0.7708852887 + 0.8035417795 0.8141167164 0.7716454864 + 0.8042379022 0.8147869110 0.7724056244 + 0.8049340844 0.8154569864 0.7731658220 + 0.8056303263 0.8161271811 0.7739259005 + 0.8063265085 0.8167973161 0.7746859789 + 0.8070226908 0.8174675107 0.7754461765 + 0.8077152967 0.8181294799 0.7762011886 + 0.8084064126 0.8187881112 0.7769542933 + 0.8090974092 0.8194466233 0.7777075171 + 0.8097885251 0.8201050758 0.7784606218 + 0.8104795218 0.8207635880 0.7792137265 + 0.8111705780 0.8214221001 0.7799667716 + 0.8118615746 0.8220806718 0.7807198763 + 0.8125526905 0.8227391839 0.7814729810 + 0.8132436872 0.8233976960 0.7822262049 + 0.8139348030 0.8240562081 0.7829793096 + 0.8146215081 0.8247125745 0.7837309837 + 0.8153027892 0.8253661990 0.7844812274 + 0.8159840703 0.8260198832 0.7852314115 + 0.8166654706 0.8266735077 0.7859815955 + 0.8173468113 0.8273271918 0.7867317796 + 0.8180280924 0.8279808760 0.7874820232 + 0.8187093735 0.8286345005 0.7882322073 + 0.8193907142 0.8292881846 0.7889823914 + 0.8200719953 0.8299418092 0.7897325754 + 0.8207532763 0.8305954933 0.7904828191 + 0.8214341998 0.8312489986 0.7912325859 + 0.8221067190 0.8318998218 0.7919784188 + 0.8227791786 0.8325507045 0.7927241921 + 0.8234515786 0.8332015276 0.7934700251 + 0.8241240978 0.8338522911 0.7942157984 + 0.8247966170 0.8345031738 0.7949615717 + 0.8254690766 0.8351539969 0.7957074046 + 0.8261414766 0.8358048797 0.7964531779 + 0.8268139958 0.8364557028 0.7971988916 + 0.8274865150 0.8371065259 0.7979447246 + 0.8281589150 0.8377574086 0.7986904979 + 0.8288310170 0.8384053111 0.7994338274 + 0.8295025229 0.8390501738 0.8001747727 + 0.8301740885 0.8396950960 0.8009157777 + 0.8308455944 0.8403400183 0.8016567826 + 0.8315172195 0.8409848809 0.8023977876 + 0.8321887255 0.8416298032 0.8031387925 + 0.8328602910 0.8422747254 0.8038797975 + 0.8335317969 0.8429197073 0.8046206832 + 0.8342034221 0.8435646296 0.8053616881 + 0.8348749280 0.8442094922 0.8061026931 + 0.8355464935 0.8448544145 0.8068436980 + 0.8362092972 0.8454958797 0.8075804114 + 0.8368695974 0.8461365104 0.8083159924 + 0.8375298977 0.8467770815 0.8090516925 + 0.8381903172 0.8474177122 0.8097872734 + 0.8388506174 0.8480582237 0.8105229735 + 0.8395109177 0.8486987948 0.8112586141 + 0.8401712775 0.8493394256 0.8119943142 + 0.8408315778 0.8499799967 0.8127298951 + 0.8414918780 0.8506206274 0.8134655952 + 0.8421522975 0.8512610793 0.8142011762 + 0.8428125978 0.8519017100 0.8149368763 + 0.8434634209 0.8525397778 0.8156663179 + 0.8441131711 0.8531776071 0.8163954020 + 0.8447631001 0.8538153768 0.8171244860 + 0.8454129100 0.8544532061 0.8178536296 + 0.8460627794 0.8550910950 0.8185827136 + 0.8467125893 0.8557289243 0.8193116784 + 0.8473623991 0.8563666940 0.8200408220 + 0.8480123281 0.8570045233 0.8207699060 + 0.8486620784 0.8576422930 0.8214989901 + 0.8493120074 0.8582801223 0.8222280741 + 0.8499618173 0.8589180112 0.8229570985 + 0.8506091237 0.8595502973 0.8236836791 + 0.8512560725 0.8601819873 0.8244099021 + 0.8519030809 0.8608136177 0.8251361847 + 0.8525500894 0.8614451885 0.8258624077 + 0.8531970978 0.8620768189 0.8265886903 + 0.8538441062 0.8627085090 0.8273149133 + 0.8544911146 0.8633400798 0.8280411959 + 0.8551381230 0.8639717102 0.8287674189 + 0.8557850718 0.8646034002 0.8294937015 + 0.8564320803 0.8652349710 0.8302199244 + 0.8570790291 0.8658666015 0.8309462070 + 0.8577216268 0.8664917946 0.8316696286 + 0.8583620787 0.8671138883 0.8323917985 + 0.8590025902 0.8677359819 0.8331140280 + 0.8596431017 0.8683581948 0.8338361979 + 0.8602834940 0.8689802885 0.8345584869 + 0.8609240055 0.8696023822 0.8352807164 + 0.8615645170 0.8702244759 0.8360028863 + 0.8622049093 0.8708466291 0.8367251158 + 0.8628454208 0.8714687824 0.8374474049 + 0.8634858727 0.8720908761 0.8381695747 + 0.8641263843 0.8727130294 0.8388918042 + 0.8647633195 0.8733326197 0.8396124840 + 0.8653923869 0.8739467263 0.8403300047 + 0.8660213947 0.8745607734 0.8410475850 + 0.8666505218 0.8751748800 0.8417651057 + 0.8672795296 0.8757889867 0.8424826860 + 0.8679085970 0.8764030933 0.8432003260 + 0.8685376048 0.8770172000 0.8439177871 + 0.8691666722 0.8776313066 0.8446354270 + 0.8697956800 0.8782454133 0.8453528881 + 0.8704248071 0.8788595200 0.8460705280 + 0.8710538149 0.8794736266 0.8467881083 + 0.8716828823 0.8800876737 0.8475056291 + 0.8723050952 0.8806946278 0.8482186794 + 0.8729252815 0.8812993169 0.8489307165 + 0.8735455275 0.8819040060 0.8496426940 + 0.8741655946 0.8825086951 0.8503546715 + 0.8747857809 0.8831133842 0.8510667086 + 0.8754060268 0.8837180734 0.8517786860 + 0.8760262132 0.8843228817 0.8524907231 + 0.8766463995 0.8849275708 0.8532027006 + 0.8772665262 0.8855323195 0.8539146781 + 0.8778867126 0.8861370087 0.8546267152 + 0.8785068989 0.8867416978 0.8553386927 + 0.8791267276 0.8873459101 0.8560500741 + 0.8797398210 0.8879420161 0.8567556143 + 0.8803529739 0.8885381818 0.8574609756 + 0.8809661865 0.8891344070 0.8581665158 + 0.8815793991 0.8897305727 0.8588718772 + 0.8821926117 0.8903266788 0.8595774174 + 0.8828057051 0.8909229040 0.8602827787 + 0.8834189177 0.8915191293 0.8609883189 + 0.8840320706 0.8921152949 0.8616936803 + 0.8846452832 0.8927114010 0.8623992205 + 0.8852584958 0.8933076262 0.8631045818 + 0.8858715892 0.8939037919 0.8638101220 + 0.8864827156 0.8944979906 0.8645150065 + 0.8870841861 0.8950834274 0.8652176857 + 0.8876857162 0.8956688046 0.8659204841 + 0.8882871866 0.8962541223 0.8666232228 + 0.8888887167 0.8968394995 0.8673259020 + 0.8894901872 0.8974248767 0.8680287004 + 0.8900917768 0.8980103135 0.8687313795 + 0.8906933069 0.8985956907 0.8694341779 + 0.8912947774 0.8991811275 0.8701369166 + 0.8918963075 0.8997665048 0.8708395958 + 0.8924977779 0.9003518224 0.8715423942 + 0.8930993080 0.9009371996 0.8722450733 + 0.8936997056 0.9015216231 0.8729472756 + 0.8942915797 0.9020984173 0.8736460209 + 0.8948835135 0.9026752114 0.8743448257 + 0.8954755068 0.9032518864 0.8750435114 + 0.8960673809 0.9038286805 0.8757423162 + 0.8966593742 0.9044054747 0.8764410019 + 0.8972513080 0.9049823284 0.8771396875 + 0.8978431821 0.9055591226 0.8778384924 + 0.8984351754 0.9061359167 0.8785371780 + 0.8990271091 0.9067127109 0.8792359829 + 0.8996191025 0.9072895050 0.8799347281 + 0.9002109766 0.9078662992 0.8806334138 + 0.9008030295 0.9084430933 0.8813322186 + 0.9013879895 0.9090055823 0.8820266724 + 0.9019721150 0.9095662236 0.8827208281 + 0.9025561810 0.9101268053 0.8834148049 + 0.9031403065 0.9106875062 0.8841089010 + 0.9037243724 0.9112480879 0.8848029971 + 0.9043084979 0.9118087292 0.8854969740 + 0.9048926234 0.9123693109 0.8861911297 + 0.9054766893 0.9129298925 0.8868852258 + 0.9060608149 0.9134904742 0.8875792027 + 0.9066448808 0.9140511155 0.8882732987 + 0.9072290063 0.9146116972 0.8889672756 + 0.9078130722 0.9151722789 0.8896613717 + 0.9083930254 0.9157286882 0.8903554082 + 0.9089676142 0.9162800908 0.8910493851 + 0.9095423222 0.9168314934 0.8917434216 + 0.9101169705 0.9173828959 0.8924373984 + 0.9106916189 0.9179342985 0.8931313753 + 0.9112663269 0.9184857011 0.8938252926 + 0.9118409753 0.9190371037 0.8945193291 + 0.9124156237 0.9195885062 0.8952133060 + 0.9129902720 0.9201399088 0.8959072828 + 0.9135649800 0.9206913114 0.8966013193 + 0.9141396880 0.9212427139 0.8972951770 + 0.9147142768 0.9217941165 0.8979892135 + 0.9152889848 0.9223455191 0.8986831903 + 0.9158567786 0.9228839278 0.8993654251 + 0.9164233804 0.9234200716 0.9000456929 + 0.9169899821 0.9239562154 0.9007260203 + 0.9175565839 0.9244924188 0.9014064074 + 0.9181231260 0.9250285029 0.9020866752 + 0.9186897278 0.9255647063 0.9027670026 + 0.9192563295 0.9261007905 0.9034472704 + 0.9198228717 0.9266369939 0.9041275978 + 0.9203894734 0.9271730781 0.9048079848 + 0.9209560156 0.9277092814 0.9054883122 + 0.9215226173 0.9282454252 0.9061685801 + 0.9220892191 0.9287816286 0.9068489075 + 0.9226552248 0.9293168783 0.9075281024 + 0.9232082963 0.9298372269 0.9081909060 + 0.9237614274 0.9303573966 0.9088537097 + 0.9243146181 0.9308776855 0.9095163941 + 0.9248676896 0.9313979745 0.9101791978 + 0.9254208207 0.9319182038 0.9108420014 + 0.9259738922 0.9324384928 0.9115046859 + 0.9265270829 0.9329587817 0.9121674895 + 0.9270802140 0.9334790111 0.9128302932 + 0.9276332855 0.9339993000 0.9134930968 + 0.9281864762 0.9345195889 0.9141557813 + 0.9287396073 0.9350398779 0.9148185849 + 0.9292926788 0.9355601072 0.9154813886 + 0.9298455119 0.9360799193 0.9161437750 + 0.9303920269 0.9365919232 0.9168015718 + 0.9309384823 0.9371039271 0.9174593091 + 0.9314851165 0.9376158118 0.9181171060 + 0.9320315719 0.9381278157 0.9187749028 + 0.9325782061 0.9386398196 0.9194325805 + 0.9331247211 0.9391518235 0.9200903773 + 0.9336711764 0.9396638274 0.9207481146 + 0.9342178106 0.9401757717 0.9214059114 + 0.9347643256 0.9406877756 0.9220637083 + 0.9353107810 0.9411997199 0.9227213860 + 0.9358574152 0.9417117238 0.9233791828 + 0.9364038706 0.9422237277 0.9240369797 + 0.9369503856 0.9427356720 0.9246947169 + 0.9374883771 0.9432380795 0.9253485203 + 0.9380251169 0.9437391758 0.9260017276 + 0.9385617971 0.9442402720 0.9266549945 + 0.9390985966 0.9447414279 0.9273082018 + 0.9396352768 0.9452425241 0.9279615283 + 0.9401720166 0.9457436204 0.9286146760 + 0.9407088161 0.9462447166 0.9292680025 + 0.9412454963 0.9467458129 0.9299212098 + 0.9417821765 0.9472469091 0.9305744767 + 0.9423189163 0.9477481246 0.9312276840 + 0.9428557158 0.9482492208 0.9318810105 + 0.9433923960 0.9487503171 0.9325342178 + 0.9439290762 0.9492514133 0.9331874847 + 0.9444622993 0.9497454166 0.9338380098 + 0.9449920058 0.9502323866 0.9344856739 + 0.9455215931 0.9507192969 0.9351335168 + 0.9460512996 0.9512062073 0.9357813001 + 0.9465808868 0.9516931772 0.9364290833 + 0.9471105933 0.9521800876 0.9370768070 + 0.9476401806 0.9526671171 0.9377245903 + 0.9481698275 0.9531540275 0.9383723736 + 0.9486994743 0.9536408782 0.9390202165 + 0.9492291212 0.9541279078 0.9396679997 + 0.9497588277 0.9546148181 0.9403157234 + 0.9502884150 0.9551017880 0.9409635067 + 0.9508181214 0.9555886984 0.9416112900 + 0.9513477087 0.9560756087 0.9422590733 + 0.9518715739 0.9565510750 0.9428948164 + 0.9523950815 0.9570255280 0.9435294867 + 0.9529185295 0.9574998021 0.9441642165 + 0.9534419179 0.9579741955 0.9447988868 + 0.9539653063 0.9584485888 0.9454336166 + 0.9544886947 0.9589229822 0.9460684061 + 0.9550120831 0.9593973756 0.9467030764 + 0.9555354714 0.9598717093 0.9473378062 + 0.9560589194 0.9603461027 0.9479724765 + 0.9565823078 0.9608204961 0.9486072063 + 0.9571056962 0.9612948895 0.9492419958 + 0.9576292038 0.9617692828 0.9498767257 + 0.9581525922 0.9622436166 0.9505113959 + 0.9586743712 0.9627162218 0.9511442780 + 0.9591860175 0.9631766081 0.9517663717 + 0.9596974850 0.9636369944 0.9523884058 + 0.9602090716 0.9640974998 0.9530103803 + 0.9607207179 0.9645578861 0.9536324739 + 0.9612321854 0.9650183916 0.9542545080 + 0.9617437720 0.9654787779 0.9548764825 + 0.9622554183 0.9659392238 0.9554985762 + 0.9627668858 0.9663997293 0.9561206102 + 0.9632784724 0.9668601155 0.9567425847 + 0.9637901187 0.9673205018 0.9573646784 + 0.9643015862 0.9677810073 0.9579867125 + 0.9648131728 0.9682413936 0.9586086869 + 0.9653248191 0.9687018991 0.9592307210 + 0.9658346176 0.9691603184 0.9598506093 + 0.9663344026 0.9696068764 0.9604582787 + 0.9668341279 0.9700533748 0.9610658884 + 0.9673337936 0.9704999924 0.9616736174 + 0.9678335786 0.9709466100 0.9622812271 + 0.9683333039 0.9713931084 0.9628888965 + 0.9688330293 0.9718397260 0.9634965062 + 0.9693328142 0.9722862840 0.9641041756 + 0.9698324800 0.9727329016 0.9647119045 + 0.9703322053 0.9731794000 0.9653195143 + 0.9708318710 0.9736260176 0.9659271836 + 0.9713317156 0.9740725756 0.9665347934 + 0.9718313813 0.9745190740 0.9671425223 + 0.9723311067 0.9749656916 0.9677500725 + 0.9728308916 0.9754123092 0.9683578014 + 0.9733167291 0.9758465290 0.9689434767 + 0.9738017917 0.9762800932 0.9695280790 + 0.9742867947 0.9767135978 0.9701126814 + 0.9747719169 0.9771471024 0.9706972241 + 0.9752569795 0.9775807261 0.9712818265 + 0.9757419825 0.9780141711 0.9718664289 + 0.9762271047 0.9784476757 0.9724509716 + 0.9767121077 0.9788812995 0.9730355740 + 0.9771971703 0.9793148041 0.9736201763 + 0.9776821733 0.9797484279 0.9742047787 + 0.9781672955 0.9801818728 0.9747893214 + 0.9786522985 0.9806153774 0.9753739238 + 0.9791374207 0.9810490012 0.9759585261 + 0.9796224236 0.9814825058 0.9765431285 + 0.9801008105 0.9819086790 0.9771106243 + 0.9805731773 0.9823285937 0.9776636958 + 0.9810456038 0.9827483892 0.9782167077 + 0.9815180898 0.9831681848 0.9787697196 + 0.9819905162 0.9835880995 0.9793226719 + 0.9824628830 0.9840078950 0.9798758030 + 0.9829354286 0.9844278097 0.9804288149 + 0.9834077954 0.9848476052 0.9809818268 + 0.9838802814 0.9852675200 0.9815347791 + 0.9843527079 0.9856873155 0.9820877910 + 0.9848250747 0.9861071706 0.9826409221 + 0.9852976203 0.9865270257 0.9831938744 + 0.9857699871 0.9869468212 0.9837468863 + 0.9862424731 0.9873666763 0.9842998981 + 0.9867148995 0.9877864718 0.9848530293 + 0.9871708751 0.9882004857 0.9853777289 + 0.9876251817 0.9886139035 0.9858996868 + 0.9880794883 0.9890273213 0.9864217043 + 0.9885339141 0.9894406796 0.9869437218 + 0.9889882207 0.9898540974 0.9874656796 + 0.9894425273 0.9902675152 0.9879876971 + 0.9898968935 0.9906808734 0.9885097146 + 0.9903512001 0.9910942912 0.9890317917 + 0.9908055067 0.9915077090 0.9895538092 + 0.9912598729 0.9919211268 0.9900758266 + 0.9917141795 0.9923344851 0.9905977845 + 0.9921684861 0.9927479029 0.9911198020 + 0.9926229119 0.9931613207 0.9916418195 + 0.9930772185 0.9935746789 0.9921637774 + 0.9935299754 0.9939873219 0.9926834702 + 0.9939612746 0.9943881035 0.9931712747 + 0.9943926930 0.9947890043 0.9936590791 + 0.9948239923 0.9951897860 0.9941468239 + 0.9952552915 0.9955906868 0.9946346283 + 0.9956867099 0.9959915280 0.9951223731 + 0.9961180091 0.9963924289 0.9956101179 + 0.9965493083 0.9967932105 0.9960979223 + 0.9969807267 0.9971941113 0.9965857267 + 0.9974120259 0.9975948930 0.9970734119 + 0.9978433251 0.9979957938 0.9975612164 + 0.9982746840 0.9983965755 0.9980489016 + 0.9987059832 0.9987974763 0.9985367060 + 0.9991372824 0.9991983175 0.9990245104 + 0.9995687008 0.9995992184 0.9995121956 + 1.0000000000 1.0000000000 1.0000000000 +} diff --git a/rpplugins/color_correction/resources/film_luts_raw/fujifilm_fp2900z.spi1d b/rpplugins/color_correction/resources/film_luts_raw/fujifilm_fp2900z.spi1d new file mode 100644 index 0000000..4d2caa3 --- /dev/null +++ b/rpplugins/color_correction/resources/film_luts_raw/fujifilm_fp2900z.spi1d @@ -0,0 +1,1030 @@ +Version 1 +From 0.0 1.0 +Length 1024 +Components 3 +{ + 0.0000000000 0.0000000000 0.0000000000 + 0.0008503073 0.0060487022 0.0064002438 + 0.0031247020 0.0077070072 0.0084807090 + 0.0065889051 0.0093767531 0.0092614815 + 0.0087466193 0.0171994604 0.0101535600 + 0.0108801499 0.0271614902 0.0109591102 + 0.0145162800 0.0324796699 0.0117238201 + 0.0193788800 0.0365465991 0.0124966996 + 0.0240556896 0.0401393399 0.0133267604 + 0.0285850298 0.0431072004 0.0142630199 + 0.0330653489 0.0448529907 0.0153544797 + 0.0372812003 0.0457478799 0.0166501496 + 0.0410104282 0.0465190299 0.0183483995 + 0.0442945287 0.0478400812 0.0208099205 + 0.0474888906 0.0510223396 0.0238338206 + 0.0509595312 0.0559057482 0.0271846093 + 0.0551288798 0.0616184585 0.0307629295 + 0.0602344498 0.0672886521 0.0349612683 + 0.0657841787 0.0724673122 0.0396671183 + 0.0712287277 0.0778958723 0.0446968898 + 0.0760187581 0.0834463537 0.0498669893 + 0.0797053277 0.0889106467 0.0549938083 + 0.0827539414 0.0940806195 0.0598937795 + 0.0854174793 0.0987935290 0.0646180511 + 0.0878179371 0.1031830981 0.0695652813 + 0.0900772810 0.1073582023 0.0744954869 + 0.0923174620 0.1114075035 0.0791333169 + 0.0946604684 0.1154199019 0.0832034126 + 0.0972282588 0.1194840968 0.0864467174 + 0.1001427993 0.1236867979 0.0890749767 + 0.1034547016 0.1279577017 0.0913295001 + 0.1070737988 0.1322295070 0.0933255404 + 0.1109554023 0.1365102977 0.0951783583 + 0.1150562018 0.1408081055 0.0970032215 + 0.1193327978 0.1451306939 0.0989153683 + 0.1237417012 0.1494861990 0.1010300964 + 0.1282396019 0.1538825035 0.1034625992 + 0.1330090016 0.1583275944 0.1061728969 + 0.1381776035 0.1628293991 0.1090466008 + 0.1436399072 0.1673959941 0.1120757982 + 0.1492906064 0.1720408946 0.1152525023 + 0.1550242007 0.1768026054 0.1185685992 + 0.1607352942 0.1816647947 0.1220161989 + 0.1663185954 0.1866011024 0.1255874038 + 0.1716686040 0.1915850043 0.1292741001 + 0.1766799986 0.1965896934 0.1330682933 + 0.1812472045 0.2015890032 0.1369619966 + 0.1853772998 0.2065560967 0.1409474015 + 0.1893154979 0.2114645988 0.1450162977 + 0.1930917948 0.2164134979 0.1491608024 + 0.1967224926 0.2215435952 0.1533937007 + 0.2002238035 0.2267996967 0.1579982042 + 0.2036122978 0.2321251035 0.1629922986 + 0.2069043070 0.2374628037 0.1682806015 + 0.2101161033 0.2427562028 0.1737675965 + 0.2132640928 0.2479483038 0.1793580055 + 0.2163646966 0.2529824078 0.1849561036 + 0.2194342017 0.2578017116 0.1904667020 + 0.2224891037 0.2623493075 0.1957941055 + 0.2255457044 0.2665685117 0.2008430064 + 0.2286203057 0.2704024017 0.2055179030 + 0.2317294031 0.2737948895 0.2097503990 + 0.2348892987 0.2768653929 0.2138119936 + 0.2381162941 0.2797451913 0.2177951038 + 0.2414056957 0.2824516892 0.2216964066 + 0.2446805984 0.2850024104 0.2255128026 + 0.2479368001 0.2874149084 0.2292409986 + 0.2511793077 0.2897064984 0.2328778058 + 0.2544130981 0.2918949127 0.2364200950 + 0.2576431930 0.2939974070 0.2398646027 + 0.2608745992 0.2960315943 0.2432080954 + 0.2641122043 0.2980149090 0.2464473993 + 0.2673611939 0.2999647856 0.2495792955 + 0.2706263959 0.3018988967 0.2526006103 + 0.2739129066 0.3038344979 0.2555082142 + 0.2772257030 0.3057892025 0.2582986951 + 0.2805697918 0.3077805042 0.2609690130 + 0.2839502096 0.3098258972 0.2635160089 + 0.2874231935 0.3119427860 0.2659429908 + 0.2910543084 0.3141488135 0.2682636976 + 0.2948203087 0.3164612055 0.2704857886 + 0.2986972034 0.3188976943 0.2726168931 + 0.3026610911 0.3214755952 0.2746646106 + 0.3066878021 0.3242133856 0.2766366005 + 0.3107534945 0.3271133900 0.2785406113 + 0.3148340881 0.3301571906 0.2803840935 + 0.3189055920 0.3333252966 0.2821748853 + 0.3229441047 0.3365986049 0.2839204967 + 0.3269253969 0.3399577141 0.2856287062 + 0.3308256865 0.3433833122 0.2873069942 + 0.3346208036 0.3468560874 0.2889631093 + 0.3382869065 0.3503566980 0.2906045914 + 0.3417999148 0.3538660109 0.2922393084 + 0.3451356888 0.3573645949 0.2938747108 + 0.3482705057 0.3608331978 0.2955183983 + 0.3511801958 0.3642525077 0.2971782088 + 0.3538407981 0.3676030934 0.2988617122 + 0.3562282920 0.3708657920 0.3005765080 + 0.3583298028 0.3740212917 0.3023301959 + 0.3602797091 0.3770503104 0.3041304946 + 0.3621290028 0.3799622953 0.3059850931 + 0.3638837039 0.3828690052 0.3079015911 + 0.3655497134 0.3857800961 0.3098875880 + 0.3671329916 0.3886910081 0.3119508028 + 0.3686397970 0.3915975094 0.3140988052 + 0.3700759113 0.3944953084 0.3163442016 + 0.3714475036 0.3973797858 0.3187192976 + 0.3727603853 0.4002467990 0.3212150037 + 0.3740208149 0.4030919075 0.3238149881 + 0.3752345145 0.4059107900 0.3265028894 + 0.3764077127 0.4086990058 0.3292626143 + 0.3775463104 0.4114522040 0.3320775926 + 0.3786563873 0.4141660929 0.3349316120 + 0.3797439933 0.4168362021 0.3378083110 + 0.3808149099 0.4194582105 0.3406915069 + 0.3818753958 0.4220277965 0.3435646892 + 0.3829312921 0.4245404899 0.3464117050 + 0.3839887977 0.4269919991 0.3492161930 + 0.3850536942 0.4293780029 0.3519617915 + 0.3861320913 0.4316940010 0.3546322882 + 0.3872300982 0.4339357018 0.3572112024 + 0.3883534968 0.4360988140 0.3596824110 + 0.3895084858 0.4381788075 0.3620485067 + 0.3907010853 0.4401713908 0.3643788993 + 0.3919371068 0.4420722127 0.3666825891 + 0.3932228088 0.4438770115 0.3689602911 + 0.3945640028 0.4456013143 0.3712129891 + 0.3959667087 0.4472714067 0.3734416068 + 0.3974370956 0.4488897026 0.3756470084 + 0.3989810050 0.4504584968 0.3778300881 + 0.4006046057 0.4519804120 0.3799915910 + 0.4023137093 0.4534575939 0.3821327090 + 0.4041146040 0.4548926055 0.3842540085 + 0.4060753882 0.4562878013 0.3863565922 + 0.4082339108 0.4576455057 0.3884412050 + 0.4105701149 0.4589681923 0.3905088902 + 0.4130640924 0.4602581859 0.3925603926 + 0.4156959951 0.4615179896 0.3945967853 + 0.4184457064 0.4627498090 0.3966186941 + 0.4212931991 0.4639562070 0.3986273110 + 0.4242187142 0.4651395082 0.4006232023 + 0.4272021055 0.4663020968 0.4026075006 + 0.4302234948 0.4674463868 0.4045810997 + 0.4332629144 0.4685747921 0.4065446854 + 0.4363003075 0.4696896076 0.4084993005 + 0.4393157065 0.4707933962 0.4104458094 + 0.4422892928 0.4718883038 0.4123851061 + 0.4452010095 0.4729770124 0.4143181145 + 0.4480308890 0.4740616977 0.4162456095 + 0.4507589042 0.4751448035 0.4181686044 + 0.4533652067 0.4762287140 0.4200878143 + 0.4558297098 0.4773159027 0.4220044017 + 0.4581323862 0.4784086943 0.4239189923 + 0.4602535069 0.4795095026 0.4258325994 + 0.4622519016 0.4806207120 0.4277462065 + 0.4642114937 0.4817445874 0.4296604991 + 0.4661338031 0.4828838110 0.4315764010 + 0.4680199921 0.4840404987 0.4334949851 + 0.4698711932 0.4852172136 0.4354169965 + 0.4716886878 0.4864163101 0.4373432994 + 0.4734737873 0.4876401126 0.4392806888 + 0.4752275944 0.4888910949 0.4412496090 + 0.4769513011 0.4901716113 0.4432489872 + 0.4786463082 0.4914839864 0.4452759027 + 0.4803135991 0.4928306937 0.4473274052 + 0.4819546044 0.4942142069 0.4494006038 + 0.4835703969 0.4956367016 0.4514926076 + 0.4851622880 0.4971008003 0.4536004961 + 0.4867314994 0.4986090064 0.4557211995 + 0.4882791936 0.5001742244 0.4578520060 + 0.4898067117 0.5017988086 0.4599897861 + 0.4913150966 0.5034782290 0.4621317089 + 0.4928056002 0.5052075982 0.4642749131 + 0.4942795932 0.5069822073 0.4664162993 + 0.4957382083 0.5087974072 0.4685530961 + 0.4971826971 0.5106484294 0.4706822038 + 0.4986141920 0.5125305057 0.4728009105 + 0.5000339746 0.5144389868 0.4749062061 + 0.5014433265 0.5163691044 0.4769951105 + 0.5028433204 0.5183159709 0.4790647030 + 0.5042353272 0.5202751756 0.4811120927 + 0.5056204796 0.5222417116 0.4831343889 + 0.5070000291 0.5242109895 0.4851284921 + 0.5083752275 0.5261781812 0.4870916903 + 0.5097472072 0.5281386971 0.4890210032 + 0.5111172199 0.5300877094 0.4909133911 + 0.5124865770 0.5320205092 0.4927659929 + 0.5138564110 0.5339323282 0.4945758879 + 0.5152279735 0.5358185172 0.4963401854 + 0.5166025162 0.5376741886 0.4980559051 + 0.5179811716 0.5394948125 0.4997201860 + 0.5193653107 0.5412756205 0.5013300180 + 0.5207560062 0.5430117249 0.5028824806 + 0.5221545100 0.5446984768 0.5043746829 + 0.5235620141 0.5463312864 0.5058037043 + 0.5249798894 0.5479233265 0.5071665049 + 0.5264092088 0.5495030880 0.5084602833 + 0.5278512836 0.5510712266 0.5096821785 + 0.5293071866 0.5526280999 0.5108290911 + 0.5307784081 0.5541737080 0.5118982196 + 0.5322659016 0.5557085276 0.5128865242 + 0.5337721109 0.5572324991 0.5137987733 + 0.5353026986 0.5587460995 0.5146775842 + 0.5368571877 0.5602493286 0.5155304074 + 0.5384340286 0.5617424846 0.5163580179 + 0.5400314927 0.5632258058 0.5171611905 + 0.5416480899 0.5646995902 0.5179405808 + 0.5432822704 0.5661638975 0.5186970830 + 0.5449323058 0.5676190257 0.5194314122 + 0.5465967059 0.5690650940 0.5201442242 + 0.5482738018 0.5705024004 0.5208364129 + 0.5499621034 0.5719311833 0.5215085745 + 0.5516598821 0.5733516812 0.5221616030 + 0.5533655882 0.5747640133 0.5227962136 + 0.5550776720 0.5761684775 0.5234131217 + 0.5567945242 0.5775651932 0.5240131021 + 0.5585144758 0.5789545178 0.5245969892 + 0.5602360964 0.5803365111 0.5251653790 + 0.5619575977 0.5817114711 0.5257192254 + 0.5636774898 0.5830796957 0.5262590051 + 0.5653942227 0.5844413042 0.5267856717 + 0.5671060085 0.5857964754 0.5273000002 + 0.5688114166 0.5871455073 0.5278027058 + 0.5705088973 0.5884885788 0.5282945037 + 0.5721967220 0.5898259282 0.5287762284 + 0.5738732815 0.5911576748 0.5292484164 + 0.5755370855 0.5924841762 0.5297120810 + 0.5771865249 0.5938054919 0.5301678181 + 0.5788199902 0.5951220989 0.5306165218 + 0.5804358125 0.5964338779 0.5310587883 + 0.5820325017 0.5977414250 0.5314955115 + 0.5836083889 0.5990446210 0.5319272876 + 0.5851619244 0.6003437042 0.5323550105 + 0.5866914988 0.6016390920 0.5327793956 + 0.5881955028 0.6029310226 0.5332012177 + 0.5896723866 0.6042193770 0.5336210728 + 0.5911204815 0.6055046916 0.5340399146 + 0.5925382972 0.6067870855 0.5344585180 + 0.5939241052 0.6080667973 0.5348774195 + 0.5952764153 0.6093440056 0.5352975130 + 0.5965934992 0.6106188893 0.5357195735 + 0.5978739262 0.6118916869 0.5361443162 + 0.5991160274 0.6131626964 0.5365725160 + 0.6003181934 0.6144319773 0.5370048285 + 0.6014788747 0.6157000065 0.5374420881 + 0.6025965214 0.6169667244 0.5378851295 + 0.6036692858 0.6182324886 0.5383346081 + 0.6046959162 0.6194974780 0.5387912989 + 0.6056745052 0.6207618713 0.5392559171 + 0.6066036820 0.6220260262 0.5397291780 + 0.6074817777 0.6232900023 0.5402120948 + 0.6083071828 0.6245540977 0.5407050848 + 0.6090785265 0.6258184910 0.5412091017 + 0.6098169088 0.6270834804 0.5417249203 + 0.6105371714 0.6283515096 0.5422530770 + 0.6112400889 0.6296306252 0.5427945852 + 0.6119259000 0.6309205890 0.5433501005 + 0.6125950217 0.6322209239 0.5439202785 + 0.6132478714 0.6335307956 0.5445060134 + 0.6138849854 0.6348494887 0.5451080203 + 0.6145066023 0.6361764073 0.5457270145 + 0.6151131988 0.6375107765 0.5463637114 + 0.6157053113 0.6388520002 0.5470190048 + 0.6162831783 0.6401991844 0.5476934910 + 0.6168472767 0.6415519118 0.5483881235 + 0.6173980832 0.6429092288 0.5491034985 + 0.6179360747 0.6442704797 0.5498402715 + 0.6184614897 0.6456350088 0.5505995154 + 0.6189749241 0.6470022202 0.5513817072 + 0.6194766164 0.6483712792 0.5521876812 + 0.6199671030 0.6497414708 0.5530344248 + 0.6204468012 0.6511121988 0.5539386868 + 0.6209161282 0.6524828076 0.5548986197 + 0.6213753819 0.6538524032 0.5559120178 + 0.6218250990 0.6552203894 0.5569766164 + 0.6222656965 0.6565861106 0.5580903888 + 0.6226975918 0.6579487920 0.5592513084 + 0.6231212020 0.6593078971 0.5604572296 + 0.6235368848 0.6606624722 0.5617058873 + 0.6239451170 0.6620119810 0.5629951954 + 0.6243463159 0.6633557081 0.5643231869 + 0.6247407794 0.6646929979 0.5656875968 + 0.6251292229 0.6660230160 0.5670863986 + 0.6255117059 0.6673452258 0.5685173273 + 0.6258888841 0.6686587930 0.5699784160 + 0.6262611151 0.6699631214 0.5714673996 + 0.6266288161 0.6712573767 0.5729821920 + 0.6269922853 0.6725410223 0.5745208263 + 0.6273521781 0.6738132238 0.5760809779 + 0.6277086735 0.6750733852 0.5776606202 + 0.6280624270 0.6763207912 0.5792576075 + 0.6284136772 0.6775547266 0.5808697939 + 0.6287629008 0.6787744164 0.5824952126 + 0.6291105151 0.6799793243 0.5841314793 + 0.6294568777 0.6811686158 0.5857766271 + 0.6298025250 0.6823415756 0.5874286294 + 0.6301478148 0.6834977269 0.5890851021 + 0.6304932237 0.6846361160 0.5907440782 + 0.6308389902 0.6857560873 0.5924034715 + 0.6311857104 0.6868569851 0.5940610766 + 0.6315336823 0.6879382133 0.5957149267 + 0.6318835020 0.6889989972 0.5973626971 + 0.6322354078 0.6900386214 0.5990023017 + 0.6325898767 0.6910563111 0.6006317139 + 0.6329473853 0.6920514703 0.6022487283 + 0.6333082914 0.6930233836 0.6038513184 + 0.6336730123 0.6939712763 0.6054372191 + 0.6340420246 0.6948946714 0.6070044041 + 0.6344156265 0.6957926154 0.6085507870 + 0.6347942948 0.6966645122 0.6100741029 + 0.6351785064 0.6975097060 0.6115723848 + 0.6355686188 0.6983274817 0.6130434275 + 0.6359649897 0.6991170049 0.6144850850 + 0.6363682151 0.6998777986 0.6158952713 + 0.6367785931 0.7006090283 0.6172720194 + 0.6371966004 0.7013099790 0.6186128855 + 0.6376225948 0.7019799948 0.6199159026 + 0.6380569935 0.7026184201 0.6211791039 + 0.6385002136 0.7032272816 0.6224001050 + 0.6389526725 0.7038217783 0.6235768795 + 0.6394149065 0.7044044733 0.6247074008 + 0.6398872137 0.7049757838 0.6257894039 + 0.6403700113 0.7055358291 0.6268209219 + 0.6408637762 0.7060847282 0.6277996898 + 0.6413689256 0.7066227794 0.6287239790 + 0.6418856978 0.7071502209 0.6296194792 + 0.6424148083 0.7076671720 0.6305025220 + 0.6429564953 0.7081741095 0.6313732862 + 0.6435111761 0.7086709738 0.6322320104 + 0.6440793276 0.7091581821 0.6330789924 + 0.6446613073 0.7096359134 0.6339144111 + 0.6452575922 0.7101042867 0.6347385049 + 0.6458685994 0.7105637193 0.6355515718 + 0.6464946866 0.7110142112 0.6363537908 + 0.6471362710 0.7114561200 0.6371454000 + 0.6477938890 0.7118896246 0.6379265785 + 0.6484678984 0.7123149037 0.6386976838 + 0.6491587162 0.7127323151 0.6394590139 + 0.6498693228 0.7131419778 0.6402105093 + 0.6506212950 0.7135441899 0.6409527063 + 0.6514183879 0.7139390707 0.6416856050 + 0.6522591114 0.7143269181 0.6424096227 + 0.6531423926 0.7147079110 0.6431248784 + 0.6540668011 0.7150822878 0.6438316703 + 0.6550312042 0.7154504061 0.6445302963 + 0.6560341716 0.7158122063 0.6452208161 + 0.6570745707 0.7161681056 0.6459035873 + 0.6581510901 0.7165182829 0.6465789080 + 0.6592624187 0.7168630958 0.6472467780 + 0.6604073048 0.7172024846 0.6479076743 + 0.6615846157 0.7175369263 0.6485617161 + 0.6627929211 0.7178664804 0.6492090821 + 0.6640309095 0.7181913853 0.6498501897 + 0.6652973890 0.7185119987 0.6504852176 + 0.6665912271 0.7188284993 0.6511142254 + 0.6679108739 0.7191410065 0.6517375708 + 0.6692553163 0.7194498181 0.6523556113 + 0.6706231833 0.7197551131 0.6529684067 + 0.6720132232 0.7200570703 0.6535763144 + 0.6734240055 0.7203561068 0.6541793942 + 0.6748545170 0.7206522822 0.6547781229 + 0.6763033271 0.7209458947 0.6553725004 + 0.6777691841 0.7212371230 0.6559628844 + 0.6792508960 0.7215262055 0.6565495729 + 0.6807470918 0.7218133807 0.6571326852 + 0.6822565198 0.7220988274 0.6577125192 + 0.6837779880 0.7223827839 0.6582891941 + 0.6853101850 0.7226654887 0.6588631272 + 0.6868517995 0.7229471207 0.6594343781 + 0.6884016991 0.7232279778 0.6600034237 + 0.6899583936 0.7235082984 0.6605702043 + 0.6915208101 0.7237882018 0.6611351967 + 0.6930875182 0.7240679264 0.6616984010 + 0.6946573853 0.7243477702 0.6622602940 + 0.6962291002 0.7246279120 0.6628209949 + 0.6978012919 0.7249085903 0.6633808017 + 0.6993728876 0.7251899838 0.6639397740 + 0.7009423971 0.7254723907 0.6644983888 + 0.7025088072 0.7257559896 0.6650567055 + 0.7040706277 0.7260410190 0.6656150222 + 0.7056266069 0.7263275981 0.6661735773 + 0.7071756124 0.7266160846 0.6667326093 + 0.7087162733 0.7269067168 0.6672922969 + 0.7102472782 0.7271996140 0.6678529978 + 0.7117674947 0.7274950743 0.6684147716 + 0.7132756114 0.7277932763 0.6689779758 + 0.7147703171 0.7280943990 0.6695429087 + 0.7162501812 0.7283987999 0.6701096892 + 0.7177143097 0.7287065983 0.6706784964 + 0.7191610932 0.7290180922 0.6712498069 + 0.7205895185 0.7293334007 0.6718236208 + 0.7219980955 0.7296528220 0.6724001765 + 0.7233856916 0.7299764752 0.6729798913 + 0.7247509956 0.7303047776 0.6735628843 + 0.7260926962 0.7306377888 0.6741493940 + 0.7274097204 0.7309758067 0.6747397184 + 0.7287005186 0.7313190103 0.6753339767 + 0.7299638987 0.7316675782 0.6759325266 + 0.7311987281 0.7320219278 0.6765354276 + 0.7324035764 0.7323821187 0.6771430969 + 0.7335773706 0.7327483892 0.6777557731 + 0.7347186208 0.7331209779 0.6783735752 + 0.7358261943 0.7335001230 0.6789968014 + 0.7368987799 0.7338860035 0.6796255708 + 0.7379351258 0.7342789173 0.6802604198 + 0.7389339209 0.7346789837 0.6809012294 + 0.7398939133 0.7350866199 0.6815484166 + 0.7408269048 0.7355018258 0.6821988821 + 0.7417528033 0.7359247804 0.6828476787 + 0.7426717877 0.7363560200 0.6834948063 + 0.7435839772 0.7367956042 0.6841400862 + 0.7444893718 0.7372435927 0.6847838163 + 0.7453880906 0.7377005219 0.6854259968 + 0.7462803125 0.7381662726 0.6860665083 + 0.7471659184 0.7386413813 0.6867055893 + 0.7480450869 0.7391259074 0.6873431802 + 0.7489178777 0.7396200895 0.6879792809 + 0.7497844100 0.7401241064 0.6886140704 + 0.7506446242 0.7406383157 0.6892474890 + 0.7514986992 0.7411627769 0.6898795962 + 0.7523466945 0.7416979074 0.6905105114 + 0.7531886101 0.7422437072 0.6911401153 + 0.7540246844 0.7428004742 0.6917685866 + 0.7548547983 0.7433686256 0.6923959255 + 0.7556790709 0.7439481020 0.6930220723 + 0.7564978004 0.7445440292 0.6936473250 + 0.7573106885 0.7451735139 0.6942713857 + 0.7581180930 0.7458376884 0.6948946118 + 0.7589198947 0.7465357184 0.6955168843 + 0.7597163916 0.7472668290 0.6961382031 + 0.7605074048 0.7480301857 0.6967588067 + 0.7612931728 0.7488250732 0.6973785162 + 0.7620736957 0.7496505976 0.6979975104 + 0.7628490925 0.7505061030 0.6986157894 + 0.7636194229 0.7513905764 0.6992332935 + 0.7643846869 0.7523034215 0.6998503208 + 0.7651450038 0.7532438040 0.7004666924 + 0.7659006119 0.7542108297 0.7010825276 + 0.7666512728 0.7552037239 0.7016978264 + 0.7673972845 0.7562217712 0.7023125887 + 0.7681385875 0.7572641969 0.7029271126 + 0.7688754201 0.7583301067 0.7035411000 + 0.7696077228 0.7594187260 0.7041547894 + 0.7703356147 0.7605292797 0.7047681808 + 0.7710590959 0.7616609931 0.7053813934 + 0.7717784047 0.7628129721 0.7059943080 + 0.7724934220 0.7639846206 0.7066071033 + 0.7732043266 0.7651749253 0.7072197199 + 0.7739111781 0.7663831711 0.7078322768 + 0.7746139765 0.7676087022 0.7084447742 + 0.7753129005 0.7688505054 0.7090572715 + 0.7760080099 0.7701079249 0.7096698880 + 0.7766993046 0.7713800073 0.7102825046 + 0.7773869038 0.7726660967 0.7108952999 + 0.7780709267 0.7739654779 0.7115082145 + 0.7787513733 0.7752770782 0.7121213078 + 0.7794283032 0.7766004205 0.7127346992 + 0.7801018953 0.7779344916 0.7133483887 + 0.7807720900 0.7792785764 0.7139623761 + 0.7814390063 0.7806318998 0.7145767808 + 0.7821028233 0.7819936275 0.7151916027 + 0.7827634215 0.7833629251 0.7158069015 + 0.7834209800 0.7847390175 0.7164226174 + 0.7840756178 0.7861210704 0.7170389891 + 0.7847272754 0.7875084877 0.7176558971 + 0.7853761911 0.7889003158 0.7182734013 + 0.7860223055 0.7902957201 0.7188916206 + 0.7866656780 0.7916939855 0.7195104957 + 0.7873066068 0.7930942774 0.7201302052 + 0.7879447937 0.7944958806 0.7207505703 + 0.7885807157 0.7958979011 0.7213718891 + 0.7892140746 0.7972996235 0.7219941020 + 0.7898452282 0.7987000942 0.7226172090 + 0.7904739976 0.8000987172 0.7232413292 + 0.7911006808 0.8014945984 0.7238664031 + 0.7917252779 0.8028869033 0.7244924903 + 0.7923477888 0.8042749166 0.7251197100 + 0.7929683924 0.8056578040 0.7257481217 + 0.7935870886 0.8070347905 0.7263776064 + 0.7942039967 0.8084051013 0.7270082831 + 0.7948191166 0.8097679019 0.7276402712 + 0.7954326272 0.8111224174 0.7282735705 + 0.7960445285 0.8124678135 0.7289083004 + 0.7966548204 0.8138033152 0.7295442820 + 0.7972636819 0.8151280880 0.7301818132 + 0.7978711724 0.8164414167 0.7308207154 + 0.7984774113 0.8177425265 0.7314611077 + 0.7990823984 0.8190305233 0.7321031094 + 0.7996861935 0.8203045726 0.7327467203 + 0.8002889752 0.8215640187 0.7333918810 + 0.8008906841 0.8228080273 0.7340387702 + 0.8014913797 0.8240358233 0.7346873879 + 0.8020913005 0.8252465129 0.7353377938 + 0.8026903868 0.8264393210 0.7359899879 + 0.8032888174 0.8276134729 0.7366440296 + 0.8038864732 0.8287683129 0.7372999787 + 0.8044837117 0.8299028277 0.7379577756 + 0.8050802946 0.8310164213 0.7386177182 + 0.8056765199 0.8321080804 0.7392795086 + 0.8062723279 0.8331770897 0.7399433851 + 0.8068677783 0.8342227936 0.7406094074 + 0.8074631095 0.8352441788 0.7412775755 + 0.8080583215 0.8362407088 0.7419478893 + 0.8086534142 0.8372113109 0.7426204085 + 0.8092485070 0.8381553888 0.7432953119 + 0.8098437190 0.8390719891 0.7439724207 + 0.8104389906 0.8399605155 0.7446519136 + 0.8110345006 0.8408200145 0.7453336716 + 0.8116303086 0.8416497111 0.7460181117 + 0.8122264743 0.8424487710 0.7467048168 + 0.8128219247 0.8432167172 0.7473942041 + 0.8134155869 0.8439698815 0.7480859756 + 0.8140075803 0.8447198272 0.7487804890 + 0.8145980835 0.8454664946 0.7494776249 + 0.8151867986 0.8462098837 0.7501773834 + 0.8157740235 0.8469501138 0.7508800030 + 0.8163595200 0.8476870060 0.7515853047 + 0.8169434071 0.8484206796 0.7522934079 + 0.8175256848 0.8491510749 0.7530043721 + 0.8181064725 0.8498781919 0.7537181973 + 0.8186855912 0.8506020904 0.7544351220 + 0.8192632198 0.8513227105 0.7551549077 + 0.8198392987 0.8520401120 0.7558776736 + 0.8204138279 0.8527541161 0.7566035986 + 0.8209868073 0.8534649014 0.7573326230 + 0.8215582967 0.8541724086 0.7580646873 + 0.8221281767 0.8548766971 0.7588000894 + 0.8226966858 0.8555775881 0.7595385909 + 0.8232637048 0.8562753201 0.7602804899 + 0.8238291740 0.8569697142 0.7610256076 + 0.8243932724 0.8576607704 0.7617741823 + 0.8249558806 0.8583486080 0.7625260949 + 0.8255169988 0.8590331078 0.7632815242 + 0.8260768056 0.8597143292 0.7640402913 + 0.8266351223 0.8603922129 0.7648026943 + 0.8271920085 0.8610668182 0.7655686736 + 0.8277475238 0.8617380857 0.7663382292 + 0.8283016086 0.8624060750 0.7671114802 + 0.8288543820 0.8630707860 0.7678884268 + 0.8294057846 0.8637322187 0.7686690092 + 0.8299558163 0.8643901944 0.7694535255 + 0.8305044770 0.8650450110 0.7702416778 + 0.8310518861 0.8656963706 0.7710338831 + 0.8315979838 0.8663445115 0.7718299031 + 0.8321427107 0.8669893146 0.7726336718 + 0.8326861858 0.8676307797 0.7734528184 + 0.8332284093 0.8682689071 0.7742872238 + 0.8337693214 0.8689036965 0.7751364708 + 0.8343089223 0.8695350885 0.7760004997 + 0.8348472714 0.8701633215 0.7768787146 + 0.8353844285 0.8707880974 0.7777708173 + 0.8359202743 0.8714094758 0.7786765099 + 0.8364549875 0.8720275760 0.7795954943 + 0.8369885087 0.8726423979 0.7805274129 + 0.8375207782 0.8732538223 0.7814719081 + 0.8380519152 0.8738619089 0.7824286222 + 0.8385819197 0.8744665980 0.7833971977 + 0.8391106129 0.8750680089 0.7843773961 + 0.8396382928 0.8756660223 0.7853689194 + 0.8401647210 0.8762605786 0.7863711715 + 0.8406900764 0.8768519163 0.7873840928 + 0.8412142992 0.8774397969 0.7884072065 + 0.8417373896 0.8780243993 0.7894402146 + 0.8422595263 0.8786056042 0.7904826999 + 0.8427804112 0.8791834116 0.7915344834 + 0.8433002830 0.8797578216 0.7925950885 + 0.8438190818 0.8803288937 0.7936642766 + 0.8443368077 0.8808965087 0.7947415709 + 0.8448535800 0.8814607859 0.7958269119 + 0.8453692198 0.8820217848 0.7969195843 + 0.8458839059 0.8825793266 0.7980195880 + 0.8463975787 0.8831334114 0.7991263866 + 0.8469101787 0.8836842179 0.8002396822 + 0.8474218845 0.8842315078 0.8013591766 + 0.8479325771 0.8847755194 0.8024845123 + 0.8484423161 0.8853160739 0.8036152720 + 0.8489511013 0.8858531713 0.8047512770 + 0.8494588733 0.8863869905 0.8058922291 + 0.8499658704 0.8869172931 0.8070374727 + 0.8504719138 0.8874443173 0.8081870079 + 0.8509768844 0.8879678249 0.8093402982 + 0.8514810801 0.8884878755 0.8104971051 + 0.8519843817 0.8890047073 0.8116570711 + 0.8524867892 0.8895179033 0.8128197789 + 0.8529884219 0.8900278211 0.8139849901 + 0.8534891009 0.8905342817 0.8151524067 + 0.8539890051 0.8910372853 0.8163216114 + 0.8544880152 0.8915368915 0.8174921870 + 0.8549861908 0.8920329809 0.8186638951 + 0.8554837108 0.8925257921 0.8198364973 + 0.8559802771 0.8930150867 0.8210095167 + 0.8564761281 0.8935009241 0.8221825957 + 0.8569710851 0.8939834237 0.8233553767 + 0.8574653864 0.8944622874 0.8245278001 + 0.8579589725 0.8949378729 0.8256992102 + 0.8584517241 0.8954100013 0.8268694282 + 0.8589438200 0.8958786130 0.8280379772 + 0.8594350815 0.8963438272 0.8292046785 + 0.8599258065 0.8968055248 0.8303691745 + 0.8604156971 0.8972638249 0.8315311074 + 0.8609049916 0.8977186084 0.8326901197 + 0.8613935113 0.8981699944 0.8338457942 + 0.8618813753 0.8986179233 0.8349978924 + 0.8623687029 0.8990622759 0.8361461163 + 0.8628553152 0.8995032907 0.8372901082 + 0.8633412719 0.8999407887 0.8384293914 + 0.8638265729 0.9003748298 0.8395637870 + 0.8643113971 0.9008052945 0.8406928778 + 0.8647955060 0.9012324214 0.8418164253 + 0.8652790785 0.9016559720 0.8429340124 + 0.8657621145 0.9020761251 0.8440452218 + 0.8662444949 0.9024927020 0.8451498747 + 0.8667263985 0.9029058218 0.8462476134 + 0.8672077060 0.9033154845 0.8473380208 + 0.8676884770 0.9037215710 0.8484206796 + 0.8681687713 0.9041243196 0.8494954705 + 0.8686485291 0.9045233727 0.8505619764 + 0.8691278100 0.9049190879 0.8516197801 + 0.8696066141 0.9053112268 0.8526687026 + 0.8700848818 0.9056999087 0.8537082076 + 0.8705626726 0.9060850143 0.8547381163 + 0.8710401058 0.9064666033 0.8557580113 + 0.8715170026 0.9068447948 0.8567674756 + 0.8719936013 0.9072194099 0.8577663898 + 0.8724696040 0.9075905085 0.8587542772 + 0.8729453087 0.9079579711 0.8597307801 + 0.8734205961 0.9083220959 0.8606957197 + 0.8738955259 0.9086825848 0.8616485000 + 0.8743699789 0.9090396166 0.8625890017 + 0.8748440742 0.9093930721 0.8635169268 + 0.8753178716 0.9097430110 0.8644316196 + 0.8757913709 0.9100893736 0.8653330803 + 0.8762645125 0.9104322791 0.8662207723 + 0.8767372966 0.9107716084 0.8670945168 + 0.8772097826 0.9111074209 0.8679537773 + 0.8776819706 0.9114395976 0.8687983751 + 0.8781539202 0.9117683172 0.8696280122 + 0.8786255121 0.9120935202 0.8704422116 + 0.8790968060 0.9124150872 0.8712406158 + 0.8795679212 0.9127336144 0.8720229864 + 0.8800387979 0.9130501151 0.8727890253 + 0.8805093765 0.9133645296 0.8735383153 + 0.8809797764 0.9136769176 0.8742704988 + 0.8814499974 0.9139872789 0.8749852777 + 0.8819199800 0.9142956734 0.8756824136 + 0.8823897839 0.9146021008 0.8763614297 + 0.8828594089 0.9149065018 0.8770220280 + 0.8833289146 0.9152089953 0.8776637912 + 0.8837981820 0.9155095220 0.8782864809 + 0.8842672706 0.9158080816 0.8788897991 + 0.8847364187 0.9161047935 0.8794733882 + 0.8852053285 0.9163995981 0.8800367713 + 0.8856741190 0.9166926146 0.8805798292 + 0.8861427903 0.9169837236 0.8811022043 + 0.8866114020 0.9172729254 0.8816139102 + 0.8870798945 0.9175602794 0.8821213841 + 0.8875483871 0.9178459048 0.8826246262 + 0.8880168200 0.9181296825 0.8831235766 + 0.8884850740 0.9184116721 0.8836184740 + 0.8889533877 0.9186918736 0.8841090798 + 0.8894217014 0.9189704061 0.8845956922 + 0.8898900151 0.9192472100 0.8850781918 + 0.8903583288 0.9195222259 0.8855566978 + 0.8908265829 0.9197955132 0.8860313296 + 0.8912950158 0.9200671911 0.8865017891 + 0.8917633295 0.9203370810 0.8869684935 + 0.8922317028 0.9206054211 0.8874313235 + 0.8927001953 0.9208720922 0.8878902197 + 0.8931686878 0.9211370945 0.8883454204 + 0.8936372995 0.9214004874 0.8887968063 + 0.8941059709 0.9216622710 0.8892444968 + 0.8945748210 0.9219225049 0.8896884918 + 0.8950436711 0.9221811891 0.8901289105 + 0.8955127001 0.9224383235 0.8905656934 + 0.8959817886 0.9226939082 0.8909990191 + 0.8964511156 0.9229478836 0.8914287090 + 0.8969206214 0.9232004881 0.8918548822 + 0.8973901868 0.9234514832 0.8922777176 + 0.8978599906 0.9237011075 0.8926969767 + 0.8983299732 0.9239491820 0.8931130171 + 0.8988000751 0.9241958857 0.8935257196 + 0.8992708921 0.9244412184 0.8939350843 + 0.8997430205 0.9246850014 0.8943411708 + 0.9002165794 0.9249274731 0.8947440982 + 0.9006915092 0.9251685143 0.8951439261 + 0.9011679292 0.9254081845 0.8955404758 + 0.9016454816 0.9256466031 0.8959339857 + 0.9021244049 0.9258835912 0.8963243961 + 0.9026045203 0.9261192083 0.8967118263 + 0.9030858278 0.9263535738 0.8970962763 + 0.9035682082 0.9265866876 0.8974778056 + 0.9040517807 0.9268184900 0.8978564143 + 0.9045363069 0.9270491004 0.8982321024 + 0.9050219059 0.9272783995 0.8986049891 + 0.9055085182 0.9275065064 0.8989750743 + 0.9059960246 0.9277334213 0.8993424177 + 0.9064844251 0.9279590845 0.8997070789 + 0.9069736004 0.9281836152 0.9000691175 + 0.9074636102 0.9284068942 0.9004284143 + 0.9079543948 0.9286291003 0.9007850885 + 0.9084458947 0.9288501143 0.9011393189 + 0.9089381099 0.9290701151 0.9014909267 + 0.9094309211 0.9292889237 0.9018400908 + 0.9099243283 0.9295065999 0.9021868110 + 0.9104182720 0.9297233224 0.9025312066 + 0.9109126925 0.9299389124 0.9028730989 + 0.9114075899 0.9301534891 0.9032127857 + 0.9119029045 0.9303669930 0.9035500884 + 0.9123986959 0.9305794835 0.9038851857 + 0.9128947258 0.9307910800 0.9042180777 + 0.9133909941 0.9310016036 0.9045488238 + 0.9138876200 0.9312111735 0.9048773050 + 0.9143844247 0.9314197898 0.9052038193 + 0.9148814082 0.9316275120 0.9055281878 + 0.9153785110 0.9318342805 0.9058505893 + 0.9158756733 0.9320402145 0.9061710238 + 0.9163728952 0.9322451949 0.9064894915 + 0.9168701172 0.9324492812 0.9068061113 + 0.9173672795 0.9326525927 0.9071208239 + 0.9178643823 0.9328550100 0.9074336886 + 0.9183613062 0.9330565929 0.9077448249 + 0.9188581109 0.9332574010 0.9080541134 + 0.9193546772 0.9334573746 0.9083616734 + 0.9198510051 0.9336565733 0.9086676836 + 0.9203469753 0.9338549972 0.9089720249 + 0.9208427072 0.9340527058 0.9092746973 + 0.9213380218 0.9342496991 0.9095758796 + 0.9218327999 0.9344459176 0.9098755717 + 0.9223272204 0.9346414804 0.9101737142 + 0.9228211045 0.9348363280 0.9104704857 + 0.9233145118 0.9350305200 0.9107658267 + 0.9238072038 0.9352239966 0.9110596776 + 0.9242992997 0.9354168773 0.9113523960 + 0.9247906804 0.9356092215 0.9116436839 + 0.9252815247 0.9358007908 0.9119337797 + 0.9257714152 0.9359918833 0.9122226834 + 0.9262604713 0.9361823797 0.9125103951 + 0.9267488122 0.9363722801 0.9127969742 + 0.9272361994 0.9365615845 0.9130824804 + 0.9277226925 0.9367504716 0.9133669734 + 0.9282081723 0.9369388223 0.9136503935 + 0.9286926985 0.9371265769 0.9139328003 + 0.9291760921 0.9373139143 0.9142143130 + 0.9296584129 0.9375007749 0.9144948721 + 0.9301396012 0.9376872182 0.9147745967 + 0.9306195974 0.9378731251 0.9150534868 + 0.9310984015 0.9380586743 0.9153317213 + 0.9315758944 0.9382438064 0.9156090021 + 0.9320520163 0.9384285212 0.9158856869 + 0.9325268865 0.9386128783 0.9161617160 + 0.9330003262 0.9387968779 0.9164370894 + 0.9334722757 0.9389805198 0.9167118073 + 0.9339427948 0.9391639233 0.9169859886 + 0.9344118237 0.9393469095 0.9172596931 + 0.9348791838 0.9395294785 0.9175329804 + 0.9353449941 0.9397119880 0.9178056717 + 0.9358091950 0.9398940802 0.9180781245 + 0.9362716079 0.9400759935 0.9183501005 + 0.9367324114 0.9402576089 0.9186217785 + 0.9371913075 0.9404391050 0.9188932180 + 0.9376484752 0.9406203032 0.9191644192 + 0.9381036758 0.9408013225 0.9194353223 + 0.9385570884 0.9409821033 0.9197061062 + 0.9390084743 0.9411628246 0.9199767709 + 0.9394578934 0.9413434267 0.9202473164 + 0.9399052858 0.9415237904 0.9205178022 + 0.9403507113 0.9417039752 0.9207882881 + 0.9407938719 0.9418842196 0.9210587740 + 0.9412348866 0.9420642853 0.9213293791 + 0.9416738153 0.9422444105 0.9216001034 + 0.9421104193 0.9424244165 0.9218708873 + 0.9425446987 0.9426043034 0.9221419096 + 0.9429767132 0.9427841902 0.9224131107 + 0.9434064031 0.9429640770 0.9226844907 + 0.9438335896 0.9431440234 0.9229562879 + 0.9442583919 0.9433240294 0.9232283831 + 0.9446805716 0.9435039759 0.9235007763 + 0.9451004267 0.9436839819 0.9237737060 + 0.9455174804 0.9438641071 0.9240469933 + 0.9459319711 0.9440442920 0.9243208170 + 0.9463438988 0.9442245960 0.9245951176 + 0.9467530251 0.9444050193 0.9248698950 + 0.9471595287 0.9445855021 0.9251453876 + 0.9475631118 0.9447662234 0.9254214764 + 0.9479637742 0.9449470043 0.9256982803 + 0.9483616948 0.9451280832 0.9259757996 + 0.9487566948 0.9453092813 0.9262540936 + 0.9491487741 0.9454907179 0.9265332222 + 0.9495378137 0.9456723928 0.9268131256 + 0.9499238133 0.9458541870 0.9270938039 + 0.9503065944 0.9460363984 0.9273754954 + 0.9506863952 0.9462187886 0.9276580811 + 0.9510629773 0.9464014769 0.9279416800 + 0.9514362812 0.9465845227 0.9282262921 + 0.9518064857 0.9467678070 0.9285119772 + 0.9521732926 0.9469515085 0.9287987947 + 0.9525367022 0.9471355081 0.9290868044 + 0.9528967738 0.9473198056 0.9293758869 + 0.9532535076 0.9475045204 0.9296662211 + 0.9536067247 0.9476897120 0.9299578071 + 0.9539564252 0.9478752017 0.9302507043 + 0.9543024898 0.9480612278 0.9305449128 + 0.9546449780 0.9482476115 0.9308404922 + 0.9549838901 0.9484344125 0.9311375022 + 0.9553192258 0.9486218095 0.9314358830 + 0.9556506872 0.9488096237 0.9317358136 + 0.9559783936 0.9489979148 0.9320372939 + 0.9563022852 0.9491868019 0.9323403239 + 0.9566224217 0.9493761063 0.9326449037 + 0.9569386244 0.9495660067 0.9329512119 + 0.9572507739 0.9497565031 0.9332591891 + 0.9575591087 0.9499475956 0.9335687757 + 0.9578633904 0.9501392245 0.9338802099 + 0.9581636190 0.9503315091 0.9341934919 + 0.9584596753 0.9505243897 0.9345085025 + 0.9587516189 0.9507179260 0.9348254204 + 0.9590393901 0.9509121180 0.9351443052 + 0.9593229294 0.9511070251 0.9354649782 + 0.9596030712 0.9513025284 0.9357873797 + 0.9598832726 0.9514988065 0.9361097813 + 0.9601637125 0.9516956806 0.9364321828 + 0.9604443908 0.9518933892 0.9367544055 + 0.9607254267 0.9520918727 0.9370766282 + 0.9610065818 0.9522910714 0.9373986721 + 0.9612880945 0.9524911046 0.9377207160 + 0.9615697265 0.9526919127 0.9380425811 + 0.9618514776 0.9528934956 0.9383645058 + 0.9621335864 0.9530959129 0.9386863112 + 0.9624156952 0.9532992244 0.9390078783 + 0.9626979828 0.9535033107 0.9393295050 + 0.9629803896 0.9537082911 0.9396510720 + 0.9632629752 0.9539142251 0.9399725199 + 0.9635456204 0.9541209936 0.9402939081 + 0.9638283253 0.9543287158 0.9406151175 + 0.9641110897 0.9545372725 0.9409363270 + 0.9643939137 0.9547469020 0.9412574172 + 0.9646766782 0.9549574852 0.9415785074 + 0.9649596214 0.9551690221 0.9418994188 + 0.9652423859 0.9553815126 0.9422202706 + 0.9655252099 0.9555950761 0.9425410032 + 0.9658079743 0.9558095932 0.9428616762 + 0.9660906792 0.9560251832 0.9431822896 + 0.9663733840 0.9562419057 0.9435027838 + 0.9666560292 0.9564597011 0.9438232780 + 0.9669383764 0.9566785097 0.9441435933 + 0.9672207832 0.9568983912 0.9444639087 + 0.9675030112 0.9571195245 0.9447841048 + 0.9677850008 0.9573416710 0.9451041818 + 0.9680668712 0.9575650096 0.9454241991 + 0.9683486223 0.9577894807 0.9457440972 + 0.9686300755 0.9580152035 0.9460639954 + 0.9689114094 0.9582421184 0.9463837147 + 0.9691925049 0.9584702253 0.9467033744 + 0.9694733024 0.9586989880 0.9470229745 + 0.9697538018 0.9589279294 0.9473425150 + 0.9700341225 0.9591571093 0.9476618767 + 0.9703140259 0.9593864083 0.9479812980 + 0.9705935717 0.9596158862 0.9483004808 + 0.9708729982 0.9598456025 0.9486197233 + 0.9711518884 0.9600754976 0.9489387274 + 0.9714304805 0.9603055716 0.9492576718 + 0.9717087150 0.9605358243 0.9495766163 + 0.9719864726 0.9607661963 0.9498953819 + 0.9722638726 0.9609969258 0.9502142072 + 0.9725409150 0.9612277150 0.9505327940 + 0.9728174210 0.9614586830 0.9508513808 + 0.9730935097 0.9616897702 0.9511697888 + 0.9733691216 0.9619212151 0.9514881968 + 0.9736441970 0.9621527195 0.9518064857 + 0.9739187956 0.9623845220 0.9521247149 + 0.9741927981 0.9626163840 0.9524428248 + 0.9744663835 0.9628484249 0.9527608752 + 0.9747393131 0.9630807042 0.9530788064 + 0.9750117064 0.9633131027 0.9533966780 + 0.9752835035 0.9635457993 0.9537143707 + 0.9755547047 0.9637786150 0.9540321231 + 0.9758251905 0.9640114903 0.9543496966 + 0.9760950804 0.9642447233 0.9546672106 + 0.9763643742 0.9644780159 0.9549846053 + 0.9766330123 0.9647116065 0.9553018808 + 0.9769008756 0.9649453163 0.9556190968 + 0.9771680832 0.9651790857 0.9559363127 + 0.9774345160 0.9654132128 0.9562532902 + 0.9777001739 0.9656473994 0.9565703273 + 0.9779651761 0.9658818245 0.9568871856 + 0.9782294035 0.9661164284 0.9572039843 + 0.9784927964 0.9663510919 0.9575207233 + 0.9787554145 0.9665859938 0.9578372836 + 0.9790171981 0.9668210745 0.9581537843 + 0.9792782068 0.9670563936 0.9584702253 + 0.9795383215 0.9672918916 0.9587864876 + 0.9797974825 0.9675275087 0.9591028094 + 0.9800559282 0.9677633047 0.9594188929 + 0.9803133011 0.9679992199 0.9597349763 + 0.9805697799 0.9682353735 0.9600510001 + 0.9808254242 0.9684717059 0.9603667855 + 0.9810799956 0.9687082171 0.9606825709 + 0.9813336730 0.9689447880 0.9609982967 + 0.9815863967 0.9691815972 0.9613139033 + 0.9818381071 0.9694185853 0.9616295099 + 0.9820888042 0.9696558118 0.9619448781 + 0.9823384285 0.9698930979 0.9622601867 + 0.9825869799 0.9701306224 0.9625753760 + 0.9828345180 0.9703683257 0.9628906250 + 0.9830809832 0.9706060886 0.9632055759 + 0.9833263755 0.9708440900 0.9635205865 + 0.9835705757 0.9710823298 0.9638354778 + 0.9838137031 0.9713206291 0.9641503096 + 0.9840556979 0.9715592265 0.9644649029 + 0.9842965007 0.9717978239 0.9647794962 + 0.9845361114 0.9720367193 0.9650939703 + 0.9847744703 0.9722756743 0.9654083848 + 0.9850116968 0.9725148082 0.9657226801 + 0.9852476716 0.9727541804 0.9660369754 + 0.9854825139 0.9729936719 0.9663510919 + 0.9857159853 0.9732332826 0.9666650891 + 0.9859482050 0.9734731913 0.9669790864 + 0.9861791134 0.9737132192 0.9672929049 + 0.9864087105 0.9739533067 0.9676066041 + 0.9866369963 0.9741935730 0.9679203033 + 0.9868639112 0.9744340777 0.9682338834 + 0.9870895147 0.9746747017 0.9685472846 + 0.9873136878 0.9749155045 0.9688606858 + 0.9875364900 0.9751564860 0.9691740274 + 0.9877579212 0.9753975868 0.9694871902 + 0.9879779220 0.9756389260 0.9698001742 + 0.9881964922 0.9758803844 0.9701132178 + 0.9884135723 0.9761220217 0.9704260826 + 0.9886292219 0.9763637185 0.9707388878 + 0.9888433218 0.9766055942 0.9710515738 + 0.9890559912 0.9768477082 0.9713642001 + 0.9892671108 0.9770898819 0.9716768265 + 0.9894766212 0.9773322940 0.9719892144 + 0.9896847010 0.9775748849 0.9723014832 + 0.9898911119 0.9778175950 0.9726136923 + 0.9900959730 0.9780604839 0.9729259014 + 0.9902992249 0.9783034921 0.9732378721 + 0.9905009270 0.9785466790 0.9735497832 + 0.9907009006 0.9787899852 0.9738616943 + 0.9908992052 0.9790335298 0.9741734266 + 0.9910959005 0.9792770743 0.9744849801 + 0.9912909269 0.9795209169 0.9747965932 + 0.9914842248 0.9797648787 0.9751080275 + 0.9916757941 0.9800090194 0.9754194021 + 0.9918656945 0.9802532196 0.9757305980 + 0.9920538068 0.9804975986 0.9760417938 + 0.9922400713 0.9807422161 0.9763528705 + 0.9924247265 0.9809868932 0.9766638279 + 0.9926074743 0.9812318087 0.9769747257 + 0.9927883744 0.9814767838 0.9772855043 + 0.9929674864 0.9817218781 0.9775961041 + 0.9931448102 0.9819672704 0.9779067039 + 0.9933202267 0.9822127223 0.9782171845 + 0.9934937954 0.9824582934 0.9785274863 + 0.9936653972 0.9827041030 0.9788377881 + 0.9938350916 0.9829499722 0.9791479707 + 0.9940028787 0.9831960797 0.9794579744 + 0.9941688180 0.9834423065 0.9797679782 + 0.9943326712 0.9836885929 0.9800779223 + 0.9944946170 0.9839351177 0.9803876877 + 0.9946544766 0.9841818213 0.9806972742 + 0.9948124290 0.9844285846 0.9810069203 + 0.9949682951 0.9846755266 0.9813163877 + 0.9951221943 0.9849225879 0.9816257954 + 0.9952740073 0.9851698279 0.9819350243 + 0.9954236746 0.9854171872 0.9822441936 + 0.9955713153 0.9856647253 0.9825533032 + 0.9957168102 0.9859123826 0.9828622937 + 0.9958602190 0.9861602187 0.9831711054 + 0.9960014820 0.9864081740 0.9834799170 + 0.9961404800 0.9866563082 0.9837886095 + 0.9962775111 0.9869045019 0.9840971828 + 0.9964122176 0.9871528745 0.9844055772 + 0.9965447187 0.9874014258 0.9847139716 + 0.9966750145 0.9876500964 0.9850223064 + 0.9968031049 0.9878988862 0.9853304029 + 0.9969288707 0.9881477952 0.9856384993 + 0.9970524907 0.9883968830 0.9859464169 + 0.9971737266 0.9886462092 0.9862542748 + 0.9972926974 0.9888954759 0.9865620136 + 0.9974092841 0.9891449809 0.9868696928 + 0.9975237250 0.9893947244 0.9871771932 + 0.9976356030 0.9896445274 0.9874846935 + 0.9977452159 0.9898943901 0.9877920151 + 0.9978523850 0.9901443720 0.9880992770 + 0.9979572296 0.9903945923 0.9884064198 + 0.9980595708 0.9906449914 0.9887135029 + 0.9981595278 0.9908953905 0.9890204072 + 0.9982569814 0.9911460280 0.9893271923 + 0.9983521104 0.9913967848 0.9896339178 + 0.9984446168 0.9916477203 0.9899405837 + 0.9985346794 0.9918987155 0.9902470708 + 0.9986221790 0.9921497703 0.9905534983 + 0.9987071753 0.9924011230 0.9908598065 + 0.9987897277 0.9926524758 0.9911659956 + 0.9988695979 0.9929041266 0.9914721251 + 0.9989469051 0.9931557178 0.9917780757 + 0.9990215898 0.9934074879 0.9920840263 + 0.9990937710 0.9936594963 0.9923897982 + 0.9991632104 0.9939116240 0.9926955104 + 0.9992300868 0.9941638112 0.9930009842 + 0.9992942810 0.9944161177 0.9933065176 + 0.9993557930 0.9946686029 0.9936118722 + 0.9994146228 0.9949212074 0.9939171076 + 0.9994707108 0.9951738715 0.9942222834 + 0.9995239973 0.9954267740 0.9945272803 + 0.9995747209 0.9956797957 0.9948322773 + 0.9996225238 0.9959328771 0.9951370955 + 0.9996675849 0.9961860776 0.9954419136 + 0.9997099042 0.9964395165 0.9957464933 + 0.9997494221 0.9966930151 0.9960510135 + 0.9997860789 0.9969465733 0.9963554144 + 0.9998199940 0.9972004294 0.9966596961 + 0.9998509288 0.9974542856 0.9969639182 + 0.9998790026 0.9977083206 0.9972680211 + 0.9999042153 0.9979624152 0.9975720048 + 0.9999266267 0.9982166886 0.9978759289 + 0.9999458790 0.9984710813 0.9981796145 + 0.9999623895 0.9987255931 0.9984833002 + 0.9999759197 0.9989802241 0.9987869263 + 0.9999864101 0.9992349744 0.9990903139 + 0.9999939799 0.9994899035 0.9993935823 + 0.9999985099 0.9997448921 0.9996969104 + 1.0000000000 1.0000000000 1.0000000000 +} diff --git a/rpplugins/color_correction/resources/film_luts_raw/kodak_dscs_3151.spi1d b/rpplugins/color_correction/resources/film_luts_raw/kodak_dscs_3151.spi1d new file mode 100644 index 0000000..3fe7c93 --- /dev/null +++ b/rpplugins/color_correction/resources/film_luts_raw/kodak_dscs_3151.spi1d @@ -0,0 +1,1030 @@ +Version 1 +From 0.0 1.0 +Length 1024 +Components 3 +{ + 0.0000000000 0.0000000000 0.0000000000 + 0.0037204761 0.0029971090 0.0034317160 + 0.0074409521 0.0059942179 0.0068634320 + 0.0112108104 0.0089913281 0.0103168199 + 0.0150894802 0.0121837398 0.0140005304 + 0.0189681500 0.0154752200 0.0176842492 + 0.0229456108 0.0187666994 0.0214565806 + 0.0269588791 0.0222466905 0.0253789201 + 0.0309982002 0.0258396305 0.0293012708 + 0.0351190008 0.0294325706 0.0334015414 + 0.0392398089 0.0332778692 0.0375403687 + 0.0434244089 0.0371704884 0.0417546108 + 0.0476234518 0.0411414988 0.0460793190 + 0.0518433899 0.0453211293 0.0504178591 + 0.0560905896 0.0495007597 0.0548906699 + 0.0603392683 0.0539112613 0.0593634807 + 0.0646051764 0.0583530813 0.0639266223 + 0.0688710883 0.0629366115 0.0685047507 + 0.0731304884 0.0676036403 0.0731234923 + 0.0773875490 0.0723571181 0.0777619109 + 0.0816316605 0.0772018284 0.0824085474 + 0.0858552009 0.0820983425 0.0870628431 + 0.0900777131 0.0870656669 0.0917078033 + 0.0942465588 0.0920592695 0.0963367820 + 0.0984154195 0.0970907733 0.1009529978 + 0.1025395989 0.1021251008 0.1055205986 + 0.1066365018 0.1071633995 0.1100865975 + 0.1107179970 0.1121815965 0.1145633981 + 0.1147293970 0.1171742007 0.1190401986 + 0.1187407970 0.1221275032 0.1234276965 + 0.1226869002 0.1270297021 0.1277907938 + 0.1266030073 0.1318825036 0.1320898980 + 0.1305056065 0.1366591007 0.1363231987 + 0.1343199015 0.1413903981 0.1405382007 + 0.1381341964 0.1460158974 0.1446315050 + 0.1418946981 0.1506181061 0.1487247944 + 0.1456034929 0.1550758928 0.1527182013 + 0.1493123025 0.1595336050 0.1566662937 + 0.1529341042 0.1638332009 0.1605917066 + 0.1565361023 0.1681143939 0.1643936932 + 0.1601340026 0.1722953022 0.1681956053 + 0.1636296958 0.1763972044 0.1719217002 + 0.1671254039 0.1804776043 0.1755793989 + 0.1706026942 0.1844025999 0.1792372018 + 0.1739941984 0.1883275062 0.1827841997 + 0.1773857027 0.1921540052 0.1863020957 + 0.1807540953 0.1959075928 0.1898200065 + 0.1840445995 0.1996611059 0.1932110041 + 0.1873351038 0.2032658011 0.1965949982 + 0.1906071007 0.2068558931 0.1999790967 + 0.1938004941 0.2104267031 0.2032371014 + 0.1969940066 0.2138625979 0.2064943016 + 0.2001820058 0.2172984928 0.2097516060 + 0.2032828927 0.2207036018 0.2128987014 + 0.2063837051 0.2239954025 0.2160367072 + 0.2094846070 0.2272873074 0.2191746980 + 0.2125124037 0.2305555940 0.2222305983 + 0.2155255973 0.2337138951 0.2252573073 + 0.2185387015 0.2368721068 0.2282838970 + 0.2215092927 0.2400290966 0.2312657982 + 0.2244399041 0.2430640012 0.2341890037 + 0.2273703963 0.2460989058 0.2371121943 + 0.2302929014 0.2491337955 0.2400342971 + 0.2331458032 0.2520878017 0.2428618073 + 0.2359987050 0.2550094128 0.2456893027 + 0.2388516068 0.2579309940 0.2485169023 + 0.2416612059 0.2608223855 0.2513025105 + 0.2444415987 0.2636403143 0.2540419102 + 0.2472219020 0.2664583027 0.2567811906 + 0.2500022054 0.2692762017 0.2595205903 + 0.2527149916 0.2720237970 0.2621931136 + 0.2554276884 0.2747471035 0.2648515105 + 0.2581403852 0.2774704993 0.2675099075 + 0.2608334124 0.2801876962 0.2701635957 + 0.2634831965 0.2828249037 0.2727478147 + 0.2661330998 0.2854621112 0.2753320038 + 0.2687830031 0.2880992889 0.2779161930 + 0.2714012861 0.2907147110 0.2804872990 + 0.2739928961 0.2932738066 0.2830036879 + 0.2765845060 0.2958329022 0.2855201960 + 0.2791759968 0.2983919084 0.2880367041 + 0.2817308009 0.3009246886 0.2905395031 + 0.2842684984 0.3034130037 0.2929942906 + 0.2868061066 0.3059012890 0.2954489887 + 0.2893437147 0.3083896041 0.2979038060 + 0.2918444872 0.3108552992 0.3003503084 + 0.2943322957 0.3132796884 0.3027490079 + 0.2968201041 0.3157039881 0.3051475883 + 0.2993079126 0.3181284070 0.3075462878 + 0.3017626107 0.3205395937 0.3099448979 + 0.3042044938 0.3229064047 0.3122938871 + 0.3066464067 0.3252730966 0.3146417141 + 0.3090882897 0.3276399076 0.3169896007 + 0.3115035892 0.3300065100 0.3193373978 + 0.3139032125 0.3323214948 0.3216522038 + 0.3163028061 0.3346365094 0.3239541054 + 0.3187023997 0.3369514942 0.3262560070 + 0.3210841119 0.3392665088 0.3285579085 + 0.3234448135 0.3415498137 0.3308443129 + 0.3258054852 0.3438183963 0.3331047893 + 0.3281661868 0.3460870087 0.3353652954 + 0.3305189013 0.3483555913 0.3376257122 + 0.3328438103 0.3506127894 0.3398861885 + 0.3351686895 0.3528400064 0.3421114087 + 0.3374935985 0.3550671935 0.3443346918 + 0.3398185074 0.3572942913 0.3465578854 + 0.3421131074 0.3595215082 0.3487811983 + 0.3444052041 0.3617197871 0.3509894013 + 0.3466972113 0.3639101088 0.3531793952 + 0.3489891887 0.3661004007 0.3553692997 + 0.3512642980 0.3682906926 0.3575592935 + 0.3535260856 0.3704738915 0.3597491980 + 0.3557879031 0.3726314902 0.3619127870 + 0.3580496907 0.3747890890 0.3640730083 + 0.3603076935 0.3769468069 0.3662331998 + 0.3625417054 0.3791044056 0.3683933914 + 0.3647755980 0.3812451065 0.3705467880 + 0.3670096099 0.3833738863 0.3726806045 + 0.3692435026 0.3855026960 0.3748143017 + 0.3714604974 0.3876315057 0.3769479990 + 0.3736687899 0.3897601962 0.3790816963 + 0.3758769929 0.3918665051 0.3812020123 + 0.3780852854 0.3939698935 0.3833121955 + 0.3802903891 0.3960733116 0.3854224086 + 0.3824748993 0.3981766999 0.3875325918 + 0.3846592903 0.4002771080 0.3896428049 + 0.3868438005 0.4023582935 0.3917357028 + 0.3890283108 0.4044393897 0.3938251138 + 0.3912005126 0.4065206051 0.3959144950 + 0.3933627903 0.4086017013 0.3980039060 + 0.3955250978 0.4106765091 0.4000923932 + 0.3976874053 0.4127382934 0.4021633863 + 0.3998498023 0.4148001075 0.4042344093 + 0.4019927979 0.4168618023 0.4063053131 + 0.4041343033 0.4189235866 0.4083763063 + 0.4062758982 0.4209772944 0.4104438126 + 0.4084174931 0.4230220914 0.4124985039 + 0.4105539024 0.4250670075 0.4145531058 + 0.4126757979 0.4271118045 0.4166077971 + 0.4147978127 0.4291566908 0.4186624885 + 0.4169197083 0.4311929047 0.4207122028 + 0.4190416038 0.4332230985 0.4227524102 + 0.4211533070 0.4352532029 0.4247925878 + 0.4232563972 0.4372833967 0.4268329144 + 0.4253596067 0.4393135011 0.4288730919 + 0.4274626970 0.4413351119 0.4309074879 + 0.4295659065 0.4433524013 0.4329349101 + 0.4316546023 0.4453696907 0.4349622130 + 0.4337396026 0.4473870099 0.4369894862 + 0.4358245134 0.4494042993 0.4390167892 + 0.4379095137 0.4514135122 0.4410381019 + 0.4399943948 0.4534195065 0.4430536926 + 0.4420616031 0.4554254115 0.4450694025 + 0.4441286922 0.4574314058 0.4470849931 + 0.4461956918 0.4594373107 0.4491006136 + 0.4482628107 0.4614359140 0.4511103034 + 0.4503270090 0.4634316862 0.4531151056 + 0.4523763061 0.4654273987 0.4551199973 + 0.4544255137 0.4674232006 0.4571247995 + 0.4564746916 0.4694189131 0.4591296911 + 0.4585238993 0.4714080989 0.4611288011 + 0.4605681002 0.4733943939 0.4631234109 + 0.4625990987 0.4753808081 0.4651181102 + 0.4646301866 0.4773671925 0.4671126902 + 0.4666613042 0.4793536067 0.4691073895 + 0.4686923921 0.4813339114 0.4710964859 + 0.4707168043 0.4833112955 0.4730812013 + 0.4727292955 0.4852887094 0.4750658870 + 0.4747416973 0.4872662127 0.4770506024 + 0.4767540991 0.4892435968 0.4790352881 + 0.4787665009 0.4912154973 0.4810147882 + 0.4807713032 0.4931839108 0.4829894006 + 0.4827642143 0.4951524138 0.4849640131 + 0.4847570956 0.4971208870 0.4869385958 + 0.4867500067 0.4990893006 0.4889132082 + 0.4887427986 0.5010527968 0.4908829927 + 0.4907281101 0.5030118823 0.4928469956 + 0.4927003086 0.5049710274 0.4948109984 + 0.4946725965 0.5069301128 0.4967750013 + 0.4966447949 0.5088893175 0.4987390041 + 0.4986169934 0.5108439922 0.5006989241 + 0.5005825758 0.5127928853 0.5026513934 + 0.5025327802 0.5147417784 0.5046039224 + 0.5044829845 0.5166907907 0.5065565109 + 0.5064331293 0.5186396837 0.5085089803 + 0.5083832741 0.5205851197 0.5104585290 + 0.5103294253 0.5225226283 0.5123981833 + 0.5122557878 0.5244600177 0.5143380165 + 0.5141823292 0.5263975263 0.5162776709 + 0.5161086917 0.5283349156 0.5182175040 + 0.5180351138 0.5302705169 0.5201560855 + 0.5199615955 0.5321947932 0.5220813751 + 0.5218629241 0.5341190100 0.5240067244 + 0.5237637162 0.5360432863 0.5259320140 + 0.5256645083 0.5379675031 0.5278573036 + 0.5275653005 0.5398917198 0.5297827125 + 0.5294660926 0.5418013930 0.5316932797 + 0.5313469172 0.5437102914 0.5336021781 + 0.5332199931 0.5456190705 0.5355110168 + 0.5350930095 0.5475279093 0.5374197960 + 0.5369660854 0.5494368076 0.5393285751 + 0.5388391018 0.5513328910 0.5412250757 + 0.5407006741 0.5532237291 0.5431150198 + 0.5425437093 0.5551146269 0.5450049043 + 0.5443866849 0.5570054054 0.5468947887 + 0.5462297201 0.5588961840 0.5487846732 + 0.5480726957 0.5607783198 0.5506668091 + 0.5499156117 0.5626481175 0.5525349975 + 0.5517275929 0.5645177960 0.5544031262 + 0.5535380840 0.5663875937 0.5562713146 + 0.5553485155 0.5682573915 0.5581395030 + 0.5571590066 0.5701255202 0.5600075126 + 0.5589694977 0.5719708800 0.5618509054 + 0.5607649088 0.5738161802 0.5636942983 + 0.5625402927 0.5756615996 0.5655375719 + 0.5643156767 0.5775070190 0.5673810244 + 0.5660911202 0.5793523192 0.5692244172 + 0.5678665042 0.5811793804 0.5710514784 + 0.5696418881 0.5829967260 0.5728666782 + 0.5713872910 0.5848138928 0.5746818781 + 0.5731251240 0.5866311789 0.5764971972 + 0.5748628974 0.5884484053 0.5783123970 + 0.5766006112 0.5902609825 0.5801253915 + 0.5783383846 0.5920462012 0.5819090009 + 0.5800744295 0.5938314199 0.5836926103 + 0.5817720294 0.5956165791 0.5854762197 + 0.5834695101 0.5974019170 0.5872597098 + 0.5851671100 0.5991870761 0.5890433192 + 0.5868647099 0.6009526253 0.5908104777 + 0.5885621905 0.6027017832 0.5925588012 + 0.5902531743 0.6044508815 0.5943070054 + 0.5919080973 0.6062000990 0.5960553288 + 0.5935629010 0.6079491973 0.5978035927 + 0.5952177048 0.6096982956 0.5995517969 + 0.5968725085 0.6114141941 0.6012710929 + 0.5985273123 0.6131231785 0.6029803753 + 0.6001772285 0.6148322225 0.6046897173 + 0.6017869115 0.6165410876 0.6063989997 + 0.6033965945 0.6182500720 0.6081082821 + 0.6050062776 0.6199591160 0.6098175049 + 0.6066160202 0.6216248870 0.6114888191 + 0.6082255840 0.6232897043 0.6131554842 + 0.6098353267 0.6249545217 0.6148222089 + 0.6114025116 0.6266192198 0.6164888144 + 0.6129649282 0.6282839775 0.6181554794 + 0.6145272255 0.6299487948 0.6198222041 + 0.6160895824 0.6315670013 0.6214476824 + 0.6176518798 0.6331837177 0.6230683923 + 0.6192142963 0.6348004937 0.6246889830 + 0.6207520962 0.6364172101 0.6263095737 + 0.6222651005 0.6380339265 0.6279302239 + 0.6237781048 0.6396507025 0.6295508146 + 0.6252911091 0.6412270069 0.6311358213 + 0.6268041134 0.6427921057 0.6327071190 + 0.6283171177 0.6443573236 0.6342784762 + 0.6298301220 0.6459224224 0.6358497739 + 0.6312978268 0.6474875808 0.6374210715 + 0.6327596903 0.6490526795 0.6389924288 + 0.6342216730 0.6505963206 0.6405450106 + 0.6356835961 0.6521067023 0.6420642138 + 0.6371455789 0.6536170840 0.6435832977 + 0.6386075020 0.6551274061 0.6451023817 + 0.6400669813 0.6566377878 0.6466215849 + 0.6414763927 0.6581482291 0.6481407285 + 0.6428859234 0.6596586108 0.6496598125 + 0.6442952752 0.6611245275 0.6511365175 + 0.6457048059 0.6625775099 0.6526008844 + 0.6471142769 0.6640303731 0.6540653110 + 0.6485236883 0.6654832959 0.6555296779 + 0.6499332190 0.6669362783 0.6569941044 + 0.6512916088 0.6683892012 0.6584585905 + 0.6526474953 0.6698421240 0.6599230170 + 0.6540033817 0.6712418795 0.6613336205 + 0.6553593278 0.6726351976 0.6627411842 + 0.6567150950 0.6740285158 0.6641489267 + 0.6580709815 0.6754218936 0.6655564904 + 0.6594269276 0.6768152118 0.6669641733 + 0.6607514024 0.6782084703 0.6683717966 + 0.6620529890 0.6796017885 0.6697794795 + 0.6633545756 0.6809514165 0.6711379290 + 0.6646561027 0.6822834015 0.6724871993 + 0.6659576893 0.6836155057 0.6738365293 + 0.6672592163 0.6849476099 0.6751857996 + 0.6685608029 0.6862797141 0.6765351295 + 0.6698623896 0.6876118183 0.6778843999 + 0.6711149812 0.6889439225 0.6792336702 + 0.6723617911 0.6902630925 0.6805573106 + 0.6736087203 0.6915329099 0.6818472147 + 0.6748554707 0.6928027868 0.6831371188 + 0.6761022806 0.6940726042 0.6844270229 + 0.6773492098 0.6953424811 0.6857169271 + 0.6785960197 0.6966122985 0.6870067716 + 0.6798428893 0.6978821754 0.6882966161 + 0.6810417771 0.6991519928 0.6895865202 + 0.6822339296 0.7004011273 0.6908357143 + 0.6834260225 0.7016083002 0.6920655966 + 0.6846179962 0.7028154731 0.6932954788 + 0.6858100891 0.7040227056 0.6945254803 + 0.6870021820 0.7052298784 0.6957554221 + 0.6881942153 0.7064371109 0.6969853044 + 0.6893863082 0.7076442838 0.6982151866 + 0.6905518770 0.7088515162 0.6994451880 + 0.6916894913 0.7100557089 0.7006422281 + 0.6928271055 0.7112004161 0.7018120885 + 0.6939646006 0.7123451233 0.7029820085 + 0.6951022148 0.7134897709 0.7041519284 + 0.6962398291 0.7146344781 0.7053217888 + 0.6973773837 0.7157791853 0.7064917088 + 0.6985148787 0.7169238925 0.7076616883 + 0.6996524930 0.7180685997 0.7088316083 + 0.7007526159 0.7192133069 0.7100014091 + 0.7018362880 0.7203385830 0.7111117244 + 0.7029200196 0.7214214802 0.7122220993 + 0.7040035725 0.7225043178 0.7133324146 + 0.7050873041 0.7235872149 0.7144426703 + 0.7061709762 0.7246699929 0.7155529857 + 0.7072547078 0.7257528901 0.7166634202 + 0.7083383203 0.7268357873 0.7177736759 + 0.7094219923 0.7279186249 0.7188839912 + 0.7104809284 0.7290015221 0.7199943066 + 0.7115116119 0.7300795913 0.7210462093 + 0.7125421762 0.7311016917 0.7220978141 + 0.7135729194 0.7321239114 0.7231494188 + 0.7146034837 0.7331460118 0.7242009044 + 0.7156342268 0.7341681719 0.7252525091 + 0.7166647911 0.7351902723 0.7263041139 + 0.7176954746 0.7362124920 0.7273557186 + 0.7187260985 0.7372345924 0.7284073234 + 0.7197567225 0.7382566929 0.7294588089 + 0.7207477093 0.7392789125 0.7304825187 + 0.7217264771 0.7402836084 0.7314764857 + 0.7227051854 0.7412465811 0.7324705720 + 0.7236840129 0.7422094941 0.7334647179 + 0.7246627808 0.7431725264 0.7344586849 + 0.7256414890 0.7441354990 0.7354527712 + 0.7266203165 0.7450984120 0.7364467978 + 0.7275990248 0.7460613847 0.7374408841 + 0.7285777926 0.7470242977 0.7384349704 + 0.7295565009 0.7479872704 0.7394289970 + 0.7305076122 0.7489503026 0.7403993011 + 0.7314357758 0.7499132156 0.7413372993 + 0.7323639989 0.7508239746 0.7422754169 + 0.7332922220 0.7517297268 0.7432134748 + 0.7342203856 0.7526353002 0.7441515923 + 0.7351486087 0.7535409927 0.7450897098 + 0.7360768914 0.7544466257 0.7460278273 + 0.7370051146 0.7553523183 0.7469658852 + 0.7379332781 0.7562578917 0.7479040027 + 0.7388615012 0.7571635842 0.7488421202 + 0.7397897243 0.7580692172 0.7497801781 + 0.7406799793 0.7589749098 0.7506768107 + 0.7415592074 0.7598804832 0.7515608072 + 0.7424383759 0.7607383132 0.7524446845 + 0.7433176041 0.7615888119 0.7533286810 + 0.7441967130 0.7624391913 0.7542126179 + 0.7450758815 0.7632896900 0.7550964952 + 0.7459551096 0.7641401887 0.7559804916 + 0.7468342781 0.7649906874 0.7568644285 + 0.7477135062 0.7658411264 0.7577484250 + 0.7485926747 0.7666916251 0.7586323023 + 0.7494719028 0.7675421238 0.7595162988 + 0.7503321767 0.7683925033 0.7603765726 + 0.7511640787 0.7692430019 0.7612084746 + 0.7519959211 0.7700877190 0.7620403171 + 0.7528278232 0.7708852887 0.7628720999 + 0.7536597252 0.7716829181 0.7637040019 + 0.7544915080 0.7724806070 0.7645357847 + 0.7553234100 0.7732781768 0.7653676271 + 0.7561553121 0.7740758061 0.7661995292 + 0.7569870949 0.7748734951 0.7670313120 + 0.7578189969 0.7756711245 0.7678630948 + 0.7586507797 0.7764686942 0.7686949968 + 0.7594826818 0.7772663832 0.7695267797 + 0.7602974176 0.7780640125 0.7703371048 + 0.7610837221 0.7788615823 0.7711189985 + 0.7618700266 0.7796592712 0.7719008923 + 0.7626562715 0.7804281116 0.7726829052 + 0.7634426951 0.7811753154 0.7734647989 + 0.7642289996 0.7819225788 0.7742466927 + 0.7650153041 0.7826699018 0.7750285864 + 0.7658017278 0.7834171057 0.7758104801 + 0.7665879726 0.7841644287 0.7765923738 + 0.7673742771 0.7849116921 0.7773743272 + 0.7681607008 0.7856588960 0.7781562805 + 0.7689470053 0.7864062190 0.7789381742 + 0.7697333097 0.7871534824 0.7797201276 + 0.7704908252 0.7879006863 0.7804713845 + 0.7712334991 0.7886480093 0.7812057137 + 0.7719761729 0.7893952727 0.7819399834 + 0.7727187872 0.7901334167 0.7826743126 + 0.7734615207 0.7908328772 0.7834085822 + 0.7742041945 0.7915323973 0.7841429114 + 0.7749469280 0.7922317982 0.7848771811 + 0.7756894827 0.7929313183 0.7856115103 + 0.7764322162 0.7936307788 0.7863457799 + 0.7771748900 0.7943302989 0.7870801091 + 0.7779176235 0.7950296998 0.7878143787 + 0.7786601782 0.7957292199 0.7885487080 + 0.7794029117 0.7964286804 0.7892829776 + 0.7801374197 0.7971280813 0.7900161743 + 0.7808383703 0.7978276014 0.7907052040 + 0.7815393209 0.7985271215 0.7913942933 + 0.7822402716 0.7992265224 0.7920833230 + 0.7829412222 0.7999259830 0.7927722931 + 0.7836421728 0.8005850911 0.7934613824 + 0.7843431234 0.8012393117 0.7941504121 + 0.7850440741 0.8018935919 0.7948395014 + 0.7857450843 0.8025478721 0.7955284715 + 0.7864459753 0.8032020926 0.7962175012 + 0.7871469855 0.8038563728 0.7969065905 + 0.7878478765 0.8045107126 0.7975956202 + 0.7885488868 0.8051649928 0.7982845902 + 0.7892497778 0.8058192134 0.7989736795 + 0.7899507880 0.8064734936 0.7996627092 + 0.7906147838 0.8071277738 0.8003299236 + 0.7912759781 0.8077819943 0.8009759784 + 0.7919371128 0.8084362745 0.8016222119 + 0.7925983071 0.8090906143 0.8022683859 + 0.7932595015 0.8097448945 0.8029146194 + 0.7939206958 0.8103731275 0.8035606742 + 0.7945818901 0.8109847903 0.8042069077 + 0.7952430844 0.8115965128 0.8048530817 + 0.7959042788 0.8122081757 0.8054991961 + 0.7965654731 0.8128197789 0.8061454296 + 0.7972267270 0.8134315014 0.8067916036 + 0.7978879213 0.8140432239 0.8074377775 + 0.7985491157 0.8146548271 0.8080838919 + 0.7992103100 0.8152664900 0.8087301254 + 0.7998715043 0.8158782125 0.8093762994 + 0.8005021811 0.8164898157 0.8100209832 + 0.8011255860 0.8171014786 0.8106266856 + 0.8017489910 0.8177132010 0.8112323880 + 0.8023723960 0.8183249235 0.8118380904 + 0.8029958010 0.8189365268 0.8124437928 + 0.8036192060 0.8195481896 0.8130494952 + 0.8042424917 0.8201494217 0.8136551976 + 0.8048658967 0.8207209706 0.8142609000 + 0.8054893017 0.8212926984 0.8148664832 + 0.8061127067 0.8218643069 0.8154721856 + 0.8067361116 0.8224359155 0.8160778880 + 0.8073595166 0.8230075836 0.8166835904 + 0.8079829216 0.8235791922 0.8172892928 + 0.8086063266 0.8241508007 0.8178949952 + 0.8092296720 0.8247225285 0.8185006976 + 0.8098530769 0.8252940774 0.8191064000 + 0.8104491234 0.8258656859 0.8197119832 + 0.8110365868 0.8264374137 0.8202977180 + 0.8116241097 0.8270090222 0.8208652735 + 0.8122116923 0.8275805712 0.8214328289 + 0.8127992153 0.8281521797 0.8220003843 + 0.8133867979 0.8287239075 0.8225678802 + 0.8139743209 0.8292955160 0.8231354952 + 0.8145617843 0.8298671246 0.8237029910 + 0.8151494265 0.8304100037 0.8242706060 + 0.8157368898 0.8309440017 0.8248381019 + 0.8163244724 0.8314781189 0.8254057169 + 0.8169119954 0.8320121765 0.8259732127 + 0.8174995184 0.8325462937 0.8265408278 + 0.8180871010 0.8330804110 0.8271083236 + 0.8186746240 0.8336145282 0.8276758790 + 0.8192622066 0.8341485858 0.8282433748 + 0.8198497295 0.8346827030 0.8288109899 + 0.8204119802 0.8352168202 0.8293784857 + 0.8209655881 0.8357508779 0.8299461007 + 0.8215191960 0.8362848759 0.8304811716 + 0.8220728040 0.8368189931 0.8310129046 + 0.8226264119 0.8373531103 0.8315445781 + 0.8231800199 0.8378872275 0.8320763111 + 0.8237336278 0.8384212852 0.8326079845 + 0.8242871761 0.8389554024 0.8331397176 + 0.8248407841 0.8394895196 0.8336713910 + 0.8253943920 0.8400220275 0.8342031240 + 0.8259480000 0.8405209780 0.8347347975 + 0.8265016079 0.8410199881 0.8352664709 + 0.8270552158 0.8415188789 0.8357982039 + 0.8276088238 0.8420178890 0.8363298774 + 0.8281623721 0.8425168991 0.8368616104 + 0.8287159801 0.8430157900 0.8373932838 + 0.8292695880 0.8435148001 0.8379250169 + 0.8298231959 0.8440138102 0.8384566903 + 0.8303549886 0.8445127010 0.8389884233 + 0.8308765292 0.8450117111 0.8395200968 + 0.8313980103 0.8455106020 0.8400486112 + 0.8319196105 0.8460096121 0.8405466080 + 0.8324410915 0.8465086222 0.8410447240 + 0.8329625726 0.8470075130 0.8415427804 + 0.8334841132 0.8475065231 0.8420407772 + 0.8340057135 0.8480054736 0.8425388932 + 0.8345271945 0.8485044241 0.8430370092 + 0.8350486755 0.8490033746 0.8435351253 + 0.8355702758 0.8495023847 0.8440331221 + 0.8360918164 0.8500012159 0.8445311785 + 0.8366132975 0.8504673839 0.8450292945 + 0.8371348977 0.8509336114 0.8455272913 + 0.8376563787 0.8513997197 0.8460254073 + 0.8381779194 0.8518658876 0.8465235233 + 0.8386995196 0.8523319960 0.8470215201 + 0.8392210007 0.8527982235 0.8475195765 + 0.8397424817 0.8532642722 0.8480176926 + 0.8402487040 0.8537304997 0.8485158086 + 0.8407400250 0.8541966081 0.8490138054 + 0.8412312865 0.8546627760 0.8495119214 + 0.8417226076 0.8551290035 0.8500093222 + 0.8422138095 0.8555951118 0.8504759073 + 0.8427050710 0.8560612798 0.8509424925 + 0.8431963921 0.8565273881 0.8514090180 + 0.8436875939 0.8569936156 0.8518756032 + 0.8441789150 0.8574597239 0.8523421884 + 0.8446701765 0.8579258919 0.8528087735 + 0.8451614976 0.8583920002 0.8532752991 + 0.8456526995 0.8588582277 0.8537418842 + 0.8461440206 0.8593243957 0.8542085290 + 0.8466352820 0.8597905040 0.8546749949 + 0.8471266031 0.8602398038 0.8551415801 + 0.8476178050 0.8606753945 0.8556082249 + 0.8481091261 0.8611109257 0.8560746908 + 0.8486003876 0.8615465164 0.8565412760 + 0.8490915895 0.8619819880 0.8570079207 + 0.8495829105 0.8624175787 0.8574743867 + 0.8500698805 0.8628532290 0.8579409719 + 0.8505327106 0.8632887006 0.8584076166 + 0.8509954214 0.8637242913 0.8588742018 + 0.8514581919 0.8641598225 0.8593407273 + 0.8519209027 0.8645954132 0.8598073125 + 0.8523836732 0.8650308847 0.8602566123 + 0.8528465033 0.8654664755 0.8606936932 + 0.8533092141 0.8659020066 0.8611307740 + 0.8537719846 0.8663375974 0.8615679145 + 0.8542348146 0.8667731285 0.8620049953 + 0.8546975255 0.8672087193 0.8624420762 + 0.8551602960 0.8676443100 0.8628792167 + 0.8556230068 0.8680797815 0.8633162975 + 0.8560857773 0.8685153723 0.8637533784 + 0.8565486073 0.8689509034 0.8641905189 + 0.8570113182 0.8693864942 0.8646275997 + 0.8574740887 0.8698220253 0.8650646806 + 0.8579369187 0.8702406883 0.8655018210 + 0.8583996296 0.8706477880 0.8659389019 + 0.8588624001 0.8710548282 0.8663759828 + 0.8593251705 0.8714619279 0.8668131232 + 0.8597878814 0.8718689084 0.8672502041 + 0.8602361083 0.8722760081 0.8676872849 + 0.8606721163 0.8726829886 0.8681244254 + 0.8611080050 0.8730900884 0.8685615063 + 0.8615438938 0.8734971285 0.8689985871 + 0.8619799018 0.8739041090 0.8694357276 + 0.8624157906 0.8743112087 0.8698728085 + 0.8628516793 0.8747181892 0.8702903986 + 0.8632876873 0.8751252890 0.8706998825 + 0.8637235761 0.8755323291 0.8711094856 + 0.8641595244 0.8759394288 0.8715190887 + 0.8645954728 0.8763464093 0.8719285727 + 0.8650314212 0.8767535090 0.8723381758 + 0.8654673100 0.8771604896 0.8727477789 + 0.8659031987 0.8775675893 0.8731573224 + 0.8663392067 0.8779746294 0.8735669255 + 0.8667750955 0.8783817291 0.8739765286 + 0.8672109842 0.8787887096 0.8743860126 + 0.8676469922 0.8791958094 0.8747956157 + 0.8680828810 0.8796027899 0.8752052188 + 0.8685188293 0.8800091743 0.8756147027 + 0.8689547777 0.8803896904 0.8760243058 + 0.8693907261 0.8807702065 0.8764339089 + 0.8698266149 0.8811507821 0.8768433928 + 0.8702474236 0.8815312982 0.8772529960 + 0.8706580997 0.8819118142 0.8776625991 + 0.8710687757 0.8822922707 0.8780720830 + 0.8714795113 0.8826727867 0.8784816861 + 0.8718901873 0.8830533028 0.8788912892 + 0.8723009229 0.8834338188 0.8793007731 + 0.8727115989 0.8838143945 0.8797103763 + 0.8731222749 0.8841949105 0.8801124096 + 0.8735330105 0.8845754266 0.8804963231 + 0.8739436865 0.8849558830 0.8808801770 + 0.8743544221 0.8853363991 0.8812639713 + 0.8747650981 0.8857169151 0.8816478848 + 0.8751757741 0.8860973716 0.8820317984 + 0.8755865097 0.8864778876 0.8824155927 + 0.8759971857 0.8868585229 0.8827995062 + 0.8764079213 0.8872389793 0.8831834197 + 0.8768185973 0.8876194954 0.8835672140 + 0.8772292733 0.8880000114 0.8839511275 + 0.8776400089 0.8883805275 0.8843349218 + 0.8780506849 0.8887609839 0.8847187757 + 0.8784614205 0.8891415000 0.8851026893 + 0.8788720965 0.8895220757 0.8854864836 + 0.8792827725 0.8899025917 0.8858703971 + 0.8796935081 0.8902646899 0.8862543106 + 0.8800982237 0.8906205893 0.8866381049 + 0.8804851770 0.8909764290 0.8870220184 + 0.8808721900 0.8913322091 0.8874058127 + 0.8812592030 0.8916881084 0.8877897263 + 0.8816462159 0.8920438886 0.8881735802 + 0.8820331097 0.8923997879 0.8885573745 + 0.8824201226 0.8927556276 0.8889412880 + 0.8828070760 0.8931114078 0.8893252015 + 0.8831940889 0.8934673071 0.8897089958 + 0.8835811019 0.8938230872 0.8900871277 + 0.8839681149 0.8941789269 0.8904470205 + 0.8843551278 0.8945348263 0.8908069134 + 0.8847420812 0.8948906064 0.8911666870 + 0.8851290941 0.8952463865 0.8915265799 + 0.8855161071 0.8956022859 0.8918864727 + 0.8859031200 0.8959581256 0.8922464252 + 0.8862900734 0.8963140249 0.8926063180 + 0.8866770864 0.8966698050 0.8929662108 + 0.8870640993 0.8970255852 0.8933259845 + 0.8874511123 0.8973814845 0.8936858773 + 0.8878381252 0.8977373242 0.8940458298 + 0.8882250786 0.8980931044 0.8944057226 + 0.8886120915 0.8984490037 0.8947656155 + 0.8889991045 0.8988047838 0.8951255083 + 0.8893861175 0.8991606832 0.8954852819 + 0.8897730708 0.8995165229 0.8958451748 + 0.8901509047 0.8998723030 0.8962051272 + 0.8905156255 0.9002134800 0.8965650201 + 0.8908804059 0.9005463719 0.8969249129 + 0.8912451267 0.9008792043 0.8972848058 + 0.8916099072 0.9012120962 0.8976445794 + 0.8919746280 0.9015449882 0.8980044723 + 0.8923392892 0.9018778801 0.8983644247 + 0.8927041292 0.9022107720 0.8987243176 + 0.8930687904 0.9025437236 0.8990842104 + 0.8934335709 0.9028766155 0.8994441032 + 0.8937982917 0.9032095075 0.8998038769 + 0.8941630721 0.9035423994 0.9001536965 + 0.8945277929 0.9038752913 0.9004911780 + 0.8948925138 0.9042081833 0.9008287191 + 0.8952572942 0.9045410752 0.9011662006 + 0.8956220150 0.9048740268 0.9015038013 + 0.8959867954 0.9052069187 0.9018412828 + 0.8963515162 0.9055398107 0.9021788239 + 0.8967161775 0.9058727026 0.9025163054 + 0.8970810175 0.9062055945 0.9028539062 + 0.8974456787 0.9065384865 0.9031913877 + 0.8978105187 0.9068713784 0.9035289288 + 0.8981751800 0.9072042704 0.9038664103 + 0.8985400200 0.9075372219 0.9042040110 + 0.8989046812 0.9078701138 0.9045414925 + 0.8992694020 0.9082030058 0.9048789740 + 0.8996341825 0.9085358977 0.9052165747 + 0.8999989033 0.9088687897 0.9055541158 + 0.9003428221 0.9092016816 0.9058915973 + 0.9006866813 0.9095345736 0.9062290788 + 0.9010306001 0.9098675251 0.9065666795 + 0.9013743997 0.9101876020 0.9069042206 + 0.9017183185 0.9104992151 0.9072417021 + 0.9020621181 0.9108107090 0.9075791836 + 0.9024059772 0.9111223221 0.9079167843 + 0.9027498960 0.9114338756 0.9082543254 + 0.9030936956 0.9117454886 0.9085918069 + 0.9034376144 0.9120571017 0.9089292884 + 0.9037814140 0.9123687148 0.9092668891 + 0.9041252732 0.9126802087 0.9096043706 + 0.9044691920 0.9129918218 0.9099419117 + 0.9048129916 0.9133033752 0.9102622271 + 0.9051569104 0.9136149883 0.9105789065 + 0.9055007100 0.9139266014 0.9108955860 + 0.9058446288 0.9142382145 0.9112123251 + 0.9061884284 0.9145497084 0.9115288854 + 0.9065322876 0.9148613214 0.9118456244 + 0.9068762064 0.9151728749 0.9121623039 + 0.9072200060 0.9154844880 0.9124789834 + 0.9075639248 0.9157961011 0.9127957225 + 0.9079077244 0.9161077142 0.9131124020 + 0.9082515836 0.9164192080 0.9134290814 + 0.9085955024 0.9167308211 0.9137458205 + 0.9089393020 0.9170423746 0.9140625000 + 0.9092832208 0.9173539877 0.9143791199 + 0.9096270204 0.9176656008 0.9146957994 + 0.9099708796 0.9179772139 0.9150124788 + 0.9102967978 0.9182887077 0.9153292179 + 0.9106211066 0.9186003208 0.9156458974 + 0.9109454155 0.9189118743 0.9159625769 + 0.9112696052 0.9192234874 0.9162793159 + 0.9115939140 0.9195351005 0.9165959954 + 0.9119182229 0.9198467135 0.9169126749 + 0.9122424126 0.9201481938 0.9172292948 + 0.9125667214 0.9204400182 0.9175459743 + 0.9128909707 0.9207317829 0.9178627133 + 0.9132152200 0.9210234880 0.9181793928 + 0.9135395288 0.9213153124 0.9184960723 + 0.9138637781 0.9216070771 0.9188128114 + 0.9141880274 0.9218989015 0.9191294909 + 0.9145122766 0.9221907258 0.9194461703 + 0.9148365855 0.9224824905 0.9197629094 + 0.9151608944 0.9227741957 0.9200747013 + 0.9154850841 0.9230660200 0.9203718901 + 0.9158093929 0.9233577847 0.9206691980 + 0.9161337018 0.9236496091 0.9209665060 + 0.9164578915 0.9239413738 0.9212638140 + 0.9167822003 0.9242331982 0.9215610027 + 0.9171065092 0.9245249033 0.9218583107 + 0.9174306989 0.9248167276 0.9221556187 + 0.9177550077 0.9251084924 0.9224528074 + 0.9180793166 0.9254003167 0.9227501154 + 0.9184035063 0.9256920815 0.9230474234 + 0.9187278152 0.9259837866 0.9233446717 + 0.9190521240 0.9262756109 0.9236419201 + 0.9193763733 0.9265673757 0.9239392281 + 0.9197006226 0.9268592000 0.9242364764 + 0.9200235009 0.9271510243 0.9245337844 + 0.9203293920 0.9274427891 0.9248309731 + 0.9206352830 0.9277344942 0.9251282811 + 0.9209411740 0.9280263186 0.9254255891 + 0.9212471247 0.9283180833 0.9257227778 + 0.9215530157 0.9286099076 0.9260200858 + 0.9218589067 0.9289016724 0.9263173938 + 0.9221647978 0.9291934967 0.9266147017 + 0.9224706888 0.9294852018 0.9269118905 + 0.9227765799 0.9297770262 0.9272091985 + 0.9230824709 0.9300644994 0.9275065064 + 0.9233884215 0.9303379059 0.9278036952 + 0.9236943126 0.9306111932 0.9281010032 + 0.9240002036 0.9308845997 0.9283983111 + 0.9243060946 0.9311580062 0.9286956191 + 0.9246119857 0.9314314127 0.9289928079 + 0.9249178767 0.9317048192 0.9292901158 + 0.9252238274 0.9319782257 0.9295874238 + 0.9255297184 0.9322515726 0.9298846722 + 0.9258356094 0.9325249791 0.9301708937 + 0.9261415005 0.9327983856 0.9304500222 + 0.9264473915 0.9330717921 0.9307292104 + 0.9267532825 0.9333450794 0.9310083985 + 0.9270591736 0.9336184859 0.9312875867 + 0.9273651242 0.9338918924 0.9315667748 + 0.9276710153 0.9341652989 0.9318460226 + 0.9279769063 0.9344387054 0.9321250916 + 0.9282827973 0.9347121119 0.9324042797 + 0.9285886884 0.9349855185 0.9326835275 + 0.9288945794 0.9352589250 0.9329627156 + 0.9292004704 0.9355322719 0.9332419038 + 0.9295064211 0.9358056188 0.9335210919 + 0.9298123121 0.9360790253 0.9338002205 + 0.9301115274 0.9363523722 0.9340794086 + 0.9304001927 0.9366257787 0.9343585968 + 0.9306889176 0.9368991852 0.9346377850 + 0.9309775829 0.9371725917 0.9349169731 + 0.9312661886 0.9374459982 0.9351962209 + 0.9315549135 0.9377194047 0.9354752898 + 0.9318435788 0.9379928112 0.9357544780 + 0.9321323037 0.9382662177 0.9360337257 + 0.9324209094 0.9385395050 0.9363129139 + 0.9327095747 0.9388129115 0.9365921021 + 0.9329982996 0.9390863180 0.9368712902 + 0.9332870245 0.9393597245 0.9371504188 + 0.9335756898 0.9396330714 0.9374296069 + 0.9338642955 0.9399064779 0.9377087951 + 0.9341530204 0.9401686192 0.9379879832 + 0.9344416857 0.9404249191 0.9382671714 + 0.9347304106 0.9406812787 0.9385464191 + 0.9350190163 0.9409375787 0.9388254881 + 0.9353076816 0.9411938787 0.9391046762 + 0.9355964065 0.9414501786 0.9393839240 + 0.9358850718 0.9417064786 0.9396631122 + 0.9361737967 0.9419627786 0.9399423003 + 0.9364624023 0.9422190785 0.9402080774 + 0.9367511272 0.9424753785 0.9404703975 + 0.9370397925 0.9427316785 0.9407327771 + 0.9373285174 0.9429879785 0.9409950972 + 0.9376171827 0.9432442784 0.9412574172 + 0.9379057884 0.9435005784 0.9415196776 + 0.9381945133 0.9437568784 0.9417821169 + 0.9384831786 0.9440131783 0.9420443773 + 0.9387719035 0.9442694783 0.9423066974 + 0.9390605092 0.9445257783 0.9425690770 + 0.9393491745 0.9447820783 0.9428313971 + 0.9396378994 0.9450383782 0.9430937171 + 0.9399266243 0.9452946782 0.9433560967 + 0.9402031898 0.9455509782 0.9436184168 + 0.9404757023 0.9458072782 0.9438806772 + 0.9407482743 0.9460635781 0.9441431165 + 0.9410207868 0.9463198781 0.9444053769 + 0.9412932992 0.9465761781 0.9446676970 + 0.9415658712 0.9468324780 0.9449300170 + 0.9418383837 0.9470888972 0.9451923966 + 0.9421108961 0.9473451972 0.9454547167 + 0.9423835278 0.9476014972 0.9457169771 + 0.9426559806 0.9478577971 0.9459794164 + 0.9429286122 0.9481140971 0.9462416768 + 0.9432011247 0.9483703971 0.9465039968 + 0.9434735775 0.9486266971 0.9467663765 + 0.9437462091 0.9488829970 0.9470286965 + 0.9440187216 0.9491392970 0.9472910166 + 0.9442911744 0.9493955970 0.9475533962 + 0.9445638061 0.9496518970 0.9478157163 + 0.9448363185 0.9499081969 0.9480779767 + 0.9451087713 0.9501543045 0.9483402967 + 0.9453814030 0.9503946900 0.9486026764 + 0.9456539154 0.9506351948 0.9488649964 + 0.9459264278 0.9508755803 0.9491273165 + 0.9461989999 0.9511160254 0.9493896961 + 0.9464715123 0.9513564706 0.9496520162 + 0.9467440248 0.9515969157 0.9499142766 + 0.9470165968 0.9518373013 0.9501661062 + 0.9472891092 0.9520778060 0.9504126906 + 0.9475616217 0.9523181915 0.9506592751 + 0.9478341937 0.9525585771 0.9509059787 + 0.9481067061 0.9527990818 0.9511526227 + 0.9483792186 0.9530395269 0.9513992071 + 0.9486517906 0.9532799125 0.9516459107 + 0.9489243031 0.9535202980 0.9518924952 + 0.9491968155 0.9537608027 0.9521390796 + 0.9494693875 0.9540011883 0.9523857832 + 0.9497419000 0.9542415738 0.9526324272 + 0.9500135779 0.9544820786 0.9528790116 + 0.9502710104 0.9547225237 0.9531255960 + 0.9505283833 0.9549629092 0.9533722997 + 0.9507858157 0.9552034140 0.9536188841 + 0.9510431886 0.9554437995 0.9538655281 + 0.9513006210 0.9556841850 0.9541121721 + 0.9515579939 0.9559246898 0.9543588161 + 0.9518154263 0.9561650753 0.9546054006 + 0.9520727992 0.9564055204 0.9548519850 + 0.9523301721 0.9566460252 0.9550986886 + 0.9525876045 0.9568864107 0.9553452730 + 0.9528449774 0.9571267962 0.9555919170 + 0.9531024098 0.9573671818 0.9558386207 + 0.9533597827 0.9576076865 0.9560852051 + 0.9536172152 0.9578480721 0.9563317895 + 0.9538745880 0.9580885172 0.9565784931 + 0.9541320205 0.9583290219 0.9568250775 + 0.9543893933 0.9585694075 0.9570717216 + 0.9546468258 0.9588097930 0.9573183060 + 0.9549041986 0.9590502977 0.9575650096 + 0.9551615715 0.9592906833 0.9578115940 + 0.9554190040 0.9595311284 0.9580581784 + 0.9556763768 0.9597715735 0.9583048820 + 0.9559338093 0.9600113034 0.9585515261 + 0.9561911821 0.9602369070 0.9587981105 + 0.9564486146 0.9604626298 0.9590448141 + 0.9567059875 0.9606882930 0.9592913985 + 0.9569634199 0.9609140158 0.9595379829 + 0.9572207928 0.9611396790 0.9597846270 + 0.9574782252 0.9613652825 0.9600294232 + 0.9577355981 0.9615910053 0.9602614045 + 0.9579929709 0.9618167281 0.9604933858 + 0.9582504034 0.9620423913 0.9607254267 + 0.9585077763 0.9622681141 0.9609574080 + 0.9587652087 0.9624937773 0.9611893892 + 0.9590225816 0.9627193809 0.9614213705 + 0.9592800140 0.9629451036 0.9616534114 + 0.9595373869 0.9631708264 0.9618853927 + 0.9597948194 0.9633964896 0.9621173739 + 0.9600493908 0.9636222124 0.9623494148 + 0.9602925777 0.9638478160 0.9625813961 + 0.9605358243 0.9640734792 0.9628133774 + 0.9607790112 0.9642992020 0.9630454183 + 0.9610221982 0.9645249248 0.9632773995 + 0.9612653852 0.9647505879 0.9635093808 + 0.9615085721 0.9649763107 0.9637414217 + 0.9617518187 0.9652019143 0.9639734030 + 0.9619951248 0.9654275775 0.9642053843 + 0.9622383118 0.9656533003 0.9644374251 + 0.9624814987 0.9658790231 0.9646694064 + 0.9627246857 0.9661046863 0.9649013877 + 0.9629678726 0.9663304090 0.9651334286 + 0.9632111192 0.9665560126 0.9653654099 + 0.9634543061 0.9667816758 0.9655973911 + 0.9636976123 0.9670073986 0.9658293724 + 0.9639407992 0.9672331214 0.9660614133 + 0.9641839862 0.9674587846 0.9662933946 + 0.9644271731 0.9676843882 0.9665253758 + 0.9646704197 0.9679101110 0.9667574167 + 0.9649136066 0.9681357741 0.9669893980 + 0.9651567936 0.9683614969 0.9672213793 + 0.9654000998 0.9685872197 0.9674534202 + 0.9656432867 0.9688128829 0.9676854014 + 0.9658864737 0.9690384865 0.9679173827 + 0.9661297202 0.9692642093 0.9681494236 + 0.9663729072 0.9694898725 0.9683814049 + 0.9666160941 0.9697155952 0.9686133862 + 0.9668592811 0.9699413180 0.9688454270 + 0.9671025276 0.9701567888 0.9690774083 + 0.9673457742 0.9703688025 0.9693093896 + 0.9675890207 0.9705808163 0.9695413709 + 0.9678322077 0.9707927108 0.9697734118 + 0.9680753946 0.9710047245 0.9700049758 + 0.9683185816 0.9712166786 0.9702234268 + 0.9685618281 0.9714285731 0.9704418182 + 0.9688050151 0.9716405869 0.9706600904 + 0.9690483212 0.9718526006 0.9708784819 + 0.9692915082 0.9720646143 0.9710968733 + 0.9695346951 0.9722765088 0.9713152051 + 0.9697778821 0.9724885225 0.9715335965 + 0.9700199962 0.9727004766 0.9717519283 + 0.9702498913 0.9729124904 0.9719703197 + 0.9704797864 0.9731243849 0.9721887112 + 0.9707096815 0.9733363986 0.9724069834 + 0.9709395766 0.9735484123 0.9726253748 + 0.9711694717 0.9737603068 0.9728438258 + 0.9713994265 0.9739723206 0.9730620980 + 0.9716293812 0.9741842747 0.9732804894 + 0.9718592763 0.9743962884 0.9734988213 + 0.9720891714 0.9746081829 0.9737172127 + 0.9723191261 0.9748201966 0.9739356041 + 0.9725490212 0.9750322104 0.9741538763 + 0.9727789164 0.9752442241 0.9743723273 + 0.9730088115 0.9754561186 0.9745907187 + 0.9732388258 0.9756680727 0.9748089910 + 0.9734687209 0.9758800864 0.9750273824 + 0.9736986160 0.9760921001 0.9752457142 + 0.9739285111 0.9763039947 0.9754641056 + 0.9741584063 0.9765160084 0.9756824970 + 0.9743883014 0.9767280221 0.9759008288 + 0.9746181965 0.9769399166 0.9761192203 + 0.9748480916 0.9771518707 0.9763376117 + 0.9750781059 0.9773638844 0.9765558839 + 0.9753080010 0.9775758982 0.9767742753 + 0.9755378962 0.9777877927 0.9769926071 + 0.9757677913 0.9779998064 0.9772109985 + 0.9759976864 0.9782118201 0.9774293900 + 0.9762275815 0.9784237742 0.9776477218 + 0.9764574766 0.9786357284 0.9778661132 + 0.9766874909 0.9788476825 0.9780845046 + 0.9769173861 0.9790596962 0.9783027768 + 0.9771472812 0.9792717099 0.9785212278 + 0.9773771763 0.9794836044 0.9787395000 + 0.9776070714 0.9796956182 0.9789578915 + 0.9778370261 0.9799075723 0.9791762829 + 0.9780669212 0.9801123738 0.9793946147 + 0.9782968760 0.9803115726 0.9796130061 + 0.9785267711 0.9805107713 0.9798313975 + 0.9787567258 0.9807100296 0.9800468087 + 0.9789866209 0.9809092879 0.9802525043 + 0.9792165160 0.9811084867 0.9804580808 + 0.9794464111 0.9813076854 0.9806637764 + 0.9796763062 0.9815068841 0.9808694124 + 0.9799063206 0.9817062020 0.9810751081 + 0.9801288247 0.9819054008 0.9812806845 + 0.9803462029 0.9821045995 0.9814863801 + 0.9805637002 0.9823039174 0.9816920161 + 0.9807810783 0.9825031161 0.9818977118 + 0.9809985757 0.9827023149 0.9821032882 + 0.9812160134 0.9829015136 0.9823089838 + 0.9814333916 0.9831007719 0.9825146198 + 0.9816508889 0.9832999706 0.9827203155 + 0.9818683267 0.9834992290 0.9829258919 + 0.9820858240 0.9836984277 0.9831315875 + 0.9823032022 0.9838976860 0.9833372235 + 0.9825206995 0.9840968847 0.9835429192 + 0.9827380776 0.9842960835 0.9837484956 + 0.9829555154 0.9844954014 0.9839541912 + 0.9831730127 0.9846946001 0.9841598272 + 0.9833903909 0.9848937988 0.9843655229 + 0.9836078882 0.9850929976 0.9845710993 + 0.9838253260 0.9852923155 0.9847767949 + 0.9840428233 0.9854915142 0.9849823713 + 0.9842602015 0.9856907129 0.9851881266 + 0.9844775796 0.9858899117 0.9853937030 + 0.9846950769 0.9860892296 0.9855993986 + 0.9849125147 0.9862884283 0.9858049750 + 0.9851300120 0.9864876270 0.9860106707 + 0.9853473902 0.9866868854 0.9862163067 + 0.9855648875 0.9868860841 0.9864220023 + 0.9857823253 0.9870852828 0.9866275787 + 0.9859997034 0.9872844815 0.9868332744 + 0.9862172008 0.9874837995 0.9870389104 + 0.9864345789 0.9876829982 0.9872446060 + 0.9866520762 0.9878821969 0.9874501824 + 0.9868695140 0.9880813956 0.9876558781 + 0.9870870113 0.9882807136 0.9878615141 + 0.9873043895 0.9884799123 0.9880672097 + 0.9875218272 0.9886791110 0.9882727861 + 0.9877393246 0.9888783097 0.9884784818 + 0.9879567027 0.9890776277 0.9886841178 + 0.9881742001 0.9892768264 0.9888898134 + 0.9883915782 0.9894760251 0.9890953898 + 0.9886090755 0.9896752834 0.9893010855 + 0.9888265133 0.9898744822 0.9895067215 + 0.9890438914 0.9900693297 0.9897124171 + 0.9892613888 0.9902567267 0.9899179935 + 0.9894788265 0.9904441237 0.9901164770 + 0.9896963239 0.9906314015 0.9903103113 + 0.9899137020 0.9908187985 0.9905040860 + 0.9901241064 0.9910061955 0.9906979203 + 0.9903299212 0.9911935925 0.9908916950 + 0.9905356169 0.9913808703 0.9910855293 + 0.9907413721 0.9915683270 0.9912793040 + 0.9909471273 0.9917557240 0.9914730787 + 0.9911528230 0.9919430017 0.9916669130 + 0.9913585782 0.9921303988 0.9918606877 + 0.9915642738 0.9923177958 0.9920545220 + 0.9917700887 0.9925051928 0.9922482967 + 0.9919757843 0.9926924706 0.9924420118 + 0.9921815991 0.9928799272 0.9926357865 + 0.9923872948 0.9930673242 0.9928296208 + 0.9925931096 0.9932546020 0.9930233955 + 0.9927988052 0.9934419990 0.9932171702 + 0.9930046201 0.9936293960 0.9934110045 + 0.9932103157 0.9938166738 0.9936047792 + 0.9934160709 0.9940040708 0.9937986135 + 0.9936218262 0.9941915274 0.9939923882 + 0.9938275814 0.9943789244 0.9941862226 + 0.9940332770 0.9945662022 0.9943799973 + 0.9942390919 0.9947535992 0.9945737720 + 0.9944447875 0.9949409962 0.9947676063 + 0.9946506023 0.9951282740 0.9949613810 + 0.9948562980 0.9953156710 0.9951552153 + 0.9950621128 0.9955031276 0.9953489900 + 0.9952678084 0.9956905246 0.9955427051 + 0.9954735041 0.9958778024 0.9957364798 + 0.9956793189 0.9960651994 0.9959303141 + 0.9958850145 0.9962525964 0.9961240888 + 0.9960908294 0.9964398742 0.9963179231 + 0.9962965250 0.9966272712 0.9965116978 + 0.9965022802 0.9968147278 0.9967054725 + 0.9967079759 0.9970021248 0.9968993068 + 0.9969137907 0.9971894026 0.9970930815 + 0.9971194863 0.9973767996 0.9972869158 + 0.9973253012 0.9975641966 0.9974806905 + 0.9975309968 0.9977514744 0.9976745248 + 0.9977368116 0.9979388714 0.9978682995 + 0.9979425073 0.9981263280 0.9980620742 + 0.9981483221 0.9983137250 0.9982559085 + 0.9983540177 0.9985010028 0.9984496832 + 0.9985597730 0.9986883998 0.9986433983 + 0.9987655282 0.9988757968 0.9988371730 + 0.9989712834 0.9990630746 0.9990310073 + 0.9991769791 0.9992504716 0.9992247820 + 0.9993827939 0.9994379282 0.9994186163 + 0.9995884895 0.9996253252 0.9996123910 + 0.9997943044 0.9998126030 0.9998062253 + 1.0000000000 1.0000000000 1.0000000000 +} diff --git a/rpplugins/color_correction/resources/film_luts_raw/kodak_dscs_3152.spi1d b/rpplugins/color_correction/resources/film_luts_raw/kodak_dscs_3152.spi1d new file mode 100644 index 0000000..a144a4e --- /dev/null +++ b/rpplugins/color_correction/resources/film_luts_raw/kodak_dscs_3152.spi1d @@ -0,0 +1,1030 @@ +Version 1 +From 0.0 1.0 +Length 1024 +Components 3 +{ + 0.0000000000 0.0000000000 0.0000000000 + 0.0031291239 0.0033278200 0.0041153808 + 0.0062582470 0.0066556409 0.0082307607 + 0.0093873711 0.0099834614 0.0125252204 + 0.0128003703 0.0136352098 0.0169547293 + 0.0162824895 0.0172885899 0.0214768499 + 0.0197646003 0.0210279003 0.0262027308 + 0.0235934593 0.0250145998 0.0309809893 + 0.0274474602 0.0290013105 0.0359734409 + 0.0314300507 0.0332363509 0.0410094596 + 0.0356648304 0.0375544094 0.0462271497 + 0.0398996100 0.0420100689 0.0514931008 + 0.0445012413 0.0466454811 0.0568850897 + 0.0491117798 0.0513610095 0.0623264983 + 0.0540077388 0.0562863797 0.0678355098 + 0.0589718111 0.0612730384 0.0733793527 + 0.0641835630 0.0664475709 0.0789457336 + 0.0694600120 0.0716837272 0.0845116675 + 0.0749636367 0.0770548731 0.0900767818 + 0.0805091709 0.0824873224 0.0955895111 + 0.0862180665 0.0879941806 0.1010826975 + 0.0919598788 0.0935461521 0.1064976007 + 0.0977663025 0.0991239473 0.1118654013 + 0.1035818979 0.1047077999 0.1171469018 + 0.1094032973 0.1102901995 0.1223551035 + 0.1151698977 0.1158241034 0.1274771988 + 0.1209099963 0.1213333011 0.1325096041 + 0.1265448928 0.1267662942 0.1374547929 + 0.1321122050 0.1321426034 0.1423096061 + 0.1375723034 0.1374354064 0.1470683962 + 0.1429159939 0.1426412016 0.1517543048 + 0.1481667012 0.1477651000 0.1563231945 + 0.1532676965 0.1527830958 0.1608552933 + 0.1582884043 0.1577192992 0.1652355939 + 0.1631516069 0.1625491977 0.1696159989 + 0.1679333001 0.1672876030 0.1738290042 + 0.1725793928 0.1719401926 0.1780259013 + 0.1771221012 0.1764778048 0.1821296066 + 0.1815796942 0.1809709072 0.1861504018 + 0.1858897954 0.1853097975 0.1901641935 + 0.1901896000 0.1896487027 0.1940180957 + 0.1942777932 0.1938105971 0.1978719980 + 0.1983660012 0.1979569942 0.2016555071 + 0.2023289055 0.2020100057 0.2053523958 + 0.2062083930 0.2059722990 0.2090492994 + 0.2100834996 0.2099346966 0.2126373947 + 0.2137690037 0.2137262970 0.2161877006 + 0.2174544036 0.2175149024 0.2197380066 + 0.2210844010 0.2212477028 0.2231622040 + 0.2245907933 0.2248737961 0.2265762985 + 0.2280972004 0.2284999043 0.2299904972 + 0.2315285057 0.2320373952 0.2332790941 + 0.2348707020 0.2355124056 0.2365673035 + 0.2382130027 0.2389874011 0.2398556024 + 0.2414855063 0.2423633039 0.2430329025 + 0.2446777970 0.2456984967 0.2462050021 + 0.2478702068 0.2490337044 0.2493772060 + 0.2510173023 0.2522774041 0.2524636090 + 0.2540734112 0.2554838061 0.2555291057 + 0.2571294904 0.2586902976 0.2585946023 + 0.2601780891 0.2618266940 0.2616071105 + 0.2631106079 0.2649149001 0.2645747066 + 0.2660430968 0.2680031061 0.2675423026 + 0.2689755857 0.2710529864 0.2704944909 + 0.2718352973 0.2740328908 0.2733725905 + 0.2746559978 0.2770127952 0.2762506008 + 0.2774766088 0.2799926102 0.2791286111 + 0.2802866101 0.2828738093 0.2819496095 + 0.2830061018 0.2857545912 0.2847456932 + 0.2857257128 0.2886354923 0.2875418067 + 0.2884452939 0.2914687991 0.2903288901 + 0.2911258042 0.2942593992 0.2930502892 + 0.2937541902 0.2970499098 0.2957716882 + 0.2963826954 0.2998403907 0.2984930873 + 0.2990111113 0.3025532961 0.3011840880 + 0.3015882969 0.3052614927 0.3038372993 + 0.3041346967 0.3079696894 0.3064906001 + 0.3066810966 0.3106591105 0.3091438115 + 0.3092274964 0.3132922947 0.3117550015 + 0.3117223978 0.3159255981 0.3143461943 + 0.3141950965 0.3185588121 0.3169373870 + 0.3166677058 0.3211610913 0.3195286095 + 0.3191402853 0.3237262070 0.3220736086 + 0.3215698004 0.3262912929 0.3246082962 + 0.3239761889 0.3288562894 0.3271430135 + 0.3263826966 0.3313871026 0.3296777904 + 0.3287890851 0.3338901997 0.3321677148 + 0.3311660886 0.3363932967 0.3346511126 + 0.3335132897 0.3388963938 0.3371345103 + 0.3358604908 0.3413681090 0.3396179080 + 0.3382078111 0.3438149989 0.3420617878 + 0.3405424953 0.3462618887 0.3444986045 + 0.3428367972 0.3487088084 0.3469353914 + 0.3451310992 0.3511315882 0.3493720889 + 0.3474254012 0.3535273969 0.3517774940 + 0.3497197032 0.3559232950 0.3541719019 + 0.3519726098 0.3583191037 0.3565663099 + 0.3542197943 0.3607012033 0.3589606881 + 0.3564670086 0.3630507886 0.3613333106 + 0.3587141931 0.3654003143 0.3636893034 + 0.3609434068 0.3677498996 0.3660452068 + 0.3631486893 0.3700976968 0.3684011996 + 0.3653540909 0.3724052906 0.3707458973 + 0.3675594032 0.3747127950 0.3730669022 + 0.3697646856 0.3770203888 0.3753877878 + 0.3719370067 0.3793280125 0.3777087927 + 0.3741051853 0.3816084862 0.3800294101 + 0.3762735128 0.3838779926 0.3823184967 + 0.3784418106 0.3861474097 0.3846076131 + 0.3806008995 0.3884168863 0.3868967891 + 0.3827365041 0.3906759024 0.3891859055 + 0.3848721981 0.3929106891 0.3914563060 + 0.3870078027 0.3951455057 0.3937163949 + 0.3891434073 0.3973802924 0.3959765136 + 0.3912619054 0.3996151090 0.3982365131 + 0.3933688104 0.4018237889 0.4004907012 + 0.3954758048 0.4040271044 0.4027242064 + 0.3975827098 0.4062303007 0.4049575925 + 0.3996897042 0.4084335864 0.4071910083 + 0.4017753005 0.4106284976 0.4094245136 + 0.4038572013 0.4128029048 0.4116396904 + 0.4059390128 0.4149773121 0.4138484895 + 0.4080209136 0.4171518087 0.4160574079 + 0.4101017118 0.4193261862 0.4182662964 + 0.4121617079 0.4214822948 0.4204702079 + 0.4142217934 0.4236302078 0.4226562977 + 0.4162817895 0.4257782102 0.4248422980 + 0.4183419049 0.4279260933 0.4270282984 + 0.4203982055 0.4300732017 0.4292142987 + 0.4224393070 0.4321965873 0.4313865900 + 0.4244804084 0.4343200028 0.4335511923 + 0.4265213907 0.4364433885 0.4357157946 + 0.4285624921 0.4385668933 0.4378803074 + 0.4305987060 0.4406827986 0.4400444925 + 0.4326233864 0.4427833855 0.4421885908 + 0.4346480072 0.4448839128 0.4443328083 + 0.4366726875 0.4469844997 0.4464769065 + 0.4386973083 0.4490849972 0.4486210942 + 0.4407168925 0.4511733949 0.4507581890 + 0.4427272975 0.4532522857 0.4528825879 + 0.4447377026 0.4553312063 0.4550068974 + 0.4467481077 0.4574100971 0.4571312964 + 0.4487585127 0.4594889879 0.4592556953 + 0.4507640898 0.4615522921 0.4613674879 + 0.4527620971 0.4636105001 0.4634723961 + 0.4547601044 0.4656687081 0.4655773938 + 0.4567581117 0.4677268863 0.4676823020 + 0.4587559998 0.4697850943 0.4697872102 + 0.4607498944 0.4718252122 0.4718747139 + 0.4627369046 0.4738632143 0.4739601016 + 0.4647239149 0.4759013057 0.4760456085 + 0.4667108953 0.4779393077 0.4781309962 + 0.4686979055 0.4799773097 0.4802143872 + 0.4706814885 0.4819954932 0.4822798967 + 0.4726586044 0.4840134084 0.4843454957 + 0.4746356905 0.4860314131 0.4864110053 + 0.4766128063 0.4880493879 0.4884765148 + 0.4785900116 0.4900667071 0.4905366004 + 0.4805643857 0.4920643866 0.4925814867 + 0.4825324118 0.4940621853 0.4946263134 + 0.4845002890 0.4960598946 0.4966711104 + 0.4864681959 0.4980576038 0.4987159967 + 0.4884361029 0.5000547767 0.5007526875 + 0.4904021919 0.5020316839 0.5027757287 + 0.4923611879 0.5040085912 0.5047987103 + 0.4943202138 0.5059854984 0.5068216920 + 0.4962792099 0.5079624057 0.5088446140 + 0.4982382059 0.5099393129 0.5108575821 + 0.5001962185 0.5118951201 0.5128573179 + 0.5021461844 0.5138502121 0.5148568749 + 0.5040960908 0.5158053041 0.5168566108 + 0.5060459971 0.5177603960 0.5188562870 + 0.5079959035 0.5197154880 0.5208451152 + 0.5099458098 0.5216509104 0.5228195786 + 0.5118862987 0.5235828757 0.5247941017 + 0.5138264894 0.5255150199 0.5267686248 + 0.5157666802 0.5274469852 0.5287430882 + 0.5177068710 0.5293790102 0.5307077169 + 0.5196471214 0.5312942863 0.5326548815 + 0.5215784907 0.5332015157 0.5346019864 + 0.5235080123 0.5351088047 0.5365492105 + 0.5254374146 0.5370160937 0.5384963751 + 0.5273668766 0.5389233828 0.5404369235 + 0.5292963982 0.5408189893 0.5423542857 + 0.5312179923 0.5426995754 0.5442718267 + 0.5331351161 0.5445801020 0.5461893082 + 0.5350522995 0.5464606881 0.5481067896 + 0.5369694829 0.5483412743 0.5500237942 + 0.5388866067 0.5502184033 0.5519090295 + 0.5407978296 0.5520700216 0.5537940860 + 0.5427005887 0.5539215803 0.5556792021 + 0.5446034074 0.5557731986 0.5575643778 + 0.5465062857 0.5576248169 0.5594494939 + 0.5484091043 0.5594763756 0.5613096952 + 0.5503091812 0.5613054037 0.5631597042 + 0.5521953106 0.5631254911 0.5650097132 + 0.5540813208 0.5649455786 0.5668596029 + 0.5559673905 0.5667657256 0.5687096119 + 0.5578534007 0.5685858130 0.5705479980 + 0.5597394705 0.5703982711 0.5723599195 + 0.5616086125 0.5721842051 0.5741717219 + 0.5634748936 0.5739700794 0.5759835839 + 0.5653412938 0.5757560730 0.5777953863 + 0.5672075748 0.5775420070 0.5796073079 + 0.5690739751 0.5793278813 0.5813869238 + 0.5709286928 0.5810908079 0.5831577182 + 0.5727720857 0.5828397274 0.5849283934 + 0.5746154189 0.5845885873 0.5866991878 + 0.5764586926 0.5863376260 0.5884699821 + 0.5783020854 0.5880864859 0.5902346969 + 0.5801432729 0.5898354053 0.5919613838 + 0.5819600224 0.5915482044 0.5936880708 + 0.5837767124 0.5932571888 0.5954148173 + 0.5855932832 0.5949661732 0.5971413851 + 0.5874099731 0.5966752172 0.5988680720 + 0.5892267227 0.5983842015 0.6005786061 + 0.5910258293 0.6000909209 0.6022583842 + 0.5928118229 0.6017571092 0.6039381027 + 0.5945978761 0.6034232974 0.6056178212 + 0.5963839889 0.6050894856 0.6072975993 + 0.5981701016 0.6067556739 0.6089773178 + 0.5999560952 0.6084219217 0.6106376052 + 0.6017082930 0.6100856066 0.6122676730 + 0.6034597158 0.6117061973 0.6138976812 + 0.6052110195 0.6133267879 0.6155278087 + 0.6069623828 0.6149473190 0.6171578765 + 0.6087138057 0.6165679097 0.6187878847 + 0.6104547977 0.6181885004 0.6204046011 + 0.6121671796 0.6198089719 0.6219825745 + 0.6138796806 0.6213870049 0.6235604882 + 0.6155921221 0.6229591966 0.6251384020 + 0.6173046231 0.6245315075 0.6267163754 + 0.6190170050 0.6261038184 0.6282942891 + 0.6207110882 0.6276760101 0.6298722029 + 0.6223804951 0.6292483211 0.6314002275 + 0.6240499020 0.6307939887 0.6329237819 + 0.6257191896 0.6323155761 0.6344473958 + 0.6273885965 0.6338371038 0.6359710097 + 0.6290580034 0.6353585720 0.6374946237 + 0.6307067871 0.6368800998 0.6390182972 + 0.6323291063 0.6384016275 0.6405218840 + 0.6339514256 0.6399230957 0.6419894099 + 0.6355736852 0.6413943768 0.6434568167 + 0.6371960044 0.6428629756 0.6449242830 + 0.6388183236 0.6443315744 0.6463916898 + 0.6404266953 0.6458001733 0.6478592157 + 0.6419981718 0.6472687721 0.6493266225 + 0.6435695887 0.6487373710 0.6507629156 + 0.6451410055 0.6501982808 0.6521728039 + 0.6467124820 0.6516122222 0.6535826921 + 0.6482838988 0.6530259848 0.6549925208 + 0.6498553753 0.6544399261 0.6564024091 + 0.6513776183 0.6558538079 0.6578121781 + 0.6528947949 0.6572676897 0.6592221260 + 0.6544119716 0.6586815119 0.6606057286 + 0.6559292078 0.6600915790 0.6619569063 + 0.6574463844 0.6614493132 0.6633082032 + 0.6589636207 0.6628069878 0.6646593809 + 0.6604626775 0.6641647220 0.6660106778 + 0.6619228125 0.6655225158 0.6673619151 + 0.6633828282 0.6668801904 0.6687130928 + 0.6648429036 0.6682379246 0.6700615883 + 0.6663029790 0.6695955992 0.6713535786 + 0.6677629948 0.6709131002 0.6726456285 + 0.6692231297 0.6722136736 0.6739376187 + 0.6706553102 0.6735141873 0.6752296090 + 0.6720557809 0.6748147011 0.6765217185 + 0.6734563112 0.6761152148 0.6778137088 + 0.6748567820 0.6774157286 0.6791056991 + 0.6762573719 0.6787163019 0.6803793907 + 0.6776579022 0.6800159812 0.6816120744 + 0.6790583730 0.6812587976 0.6828446984 + 0.6804388165 0.6825014949 0.6840773225 + 0.6817780137 0.6837441921 0.6853098869 + 0.6831172109 0.6849870086 0.6865425110 + 0.6844564080 0.6862297058 0.6877751946 + 0.6857956052 0.6874724030 0.6890078187 + 0.6871348023 0.6887152195 0.6902288795 + 0.6884739995 0.6899579167 0.6914023161 + 0.6898130774 0.6911445856 0.6925758123 + 0.6910985112 0.6923294067 0.6937493086 + 0.6923751831 0.6935142279 0.6949226856 + 0.6936519146 0.6946989894 0.6960961819 + 0.6949285269 0.6958836913 0.6972696185 + 0.6962051988 0.6970685124 0.6984431148 + 0.6974818110 0.6982532740 0.6996166110 + 0.6987584829 0.6994379759 0.7007505894 + 0.7000334263 0.7005925179 0.7018656135 + 0.7012469769 0.7017195225 0.7029805183 + 0.7024605870 0.7028465867 0.7040954232 + 0.7036740780 0.7039735913 0.7052103281 + 0.7048876882 0.7051007152 0.7063252926 + 0.7061012983 0.7062277198 0.7074401975 + 0.7073147893 0.7073547244 0.7085551023 + 0.7085283995 0.7084817886 0.7096700072 + 0.7097420096 0.7096087933 0.7107443810 + 0.7109059095 0.7106986046 0.7118018270 + 0.7120562792 0.7117685080 0.7128592134 + 0.7132068276 0.7128384709 0.7139164805 + 0.7143573165 0.7139083743 0.7149739265 + 0.7155078053 0.7149783969 0.7160311937 + 0.7166582942 0.7160483003 0.7170885801 + 0.7178087831 0.7171183228 0.7181460261 + 0.7189592123 0.7181882262 0.7192032933 + 0.7201038003 0.7192581296 0.7202467918 + 0.7211917043 0.7203109264 0.7212479115 + 0.7222797275 0.7213246822 0.7222489715 + 0.7233676910 0.7223384976 0.7232500911 + 0.7244557142 0.7233523130 0.7242512107 + 0.7255436182 0.7243661284 0.7252522707 + 0.7266315818 0.7253798842 0.7262532711 + 0.7277196050 0.7263938189 0.7272543907 + 0.7288076282 0.7274075747 0.7282555103 + 0.7298954725 0.7284213901 0.7292565703 + 0.7309280038 0.7294352055 0.7302436233 + 0.7319545150 0.7304247022 0.7311900258 + 0.7329810262 0.7313836813 0.7321363091 + 0.7340075970 0.7323426008 0.7330827117 + 0.7350341082 0.7333015800 0.7340291142 + 0.7360606194 0.7342606187 0.7349753976 + 0.7370871902 0.7352195978 0.7359218001 + 0.7381137013 0.7361785173 0.7368682027 + 0.7391402125 0.7371374965 0.7378144860 + 0.7401570082 0.7380964756 0.7387608886 + 0.7411236167 0.7390553951 0.7397072911 + 0.7420902252 0.7400135994 0.7406170964 + 0.7430567741 0.7409192920 0.7415105104 + 0.7440233827 0.7418249249 0.7424039245 + 0.7449899912 0.7427306175 0.7432973981 + 0.7459564805 0.7436363101 0.7441908121 + 0.7469230890 0.7445420027 0.7450842261 + 0.7478896976 0.7454476953 0.7459775805 + 0.7488563061 0.7463533282 0.7468711138 + 0.7498229146 0.7472590208 0.7477645278 + 0.7507420182 0.7481647134 0.7486578822 + 0.7516505122 0.7490704060 0.7495512962 + 0.7525590062 0.7499759793 0.7504193783 + 0.7534675002 0.7508316040 0.7512617707 + 0.7543759942 0.7516856790 0.7521042824 + 0.7552844882 0.7525398731 0.7529466748 + 0.7561929822 0.7533940077 0.7537891269 + 0.7571014762 0.7542482018 0.7546315789 + 0.7580100298 0.7551022768 0.7554739714 + 0.7589185238 0.7559564710 0.7563164234 + 0.7598270178 0.7568106055 0.7571588755 + 0.7606902122 0.7576647997 0.7580013275 + 0.7615427971 0.7585189939 0.7588437796 + 0.7623953223 0.7593731284 0.7596861720 + 0.7632479072 0.7602140903 0.7604979873 + 0.7641004920 0.7610186934 0.7612915039 + 0.7649530172 0.7618231773 0.7620850205 + 0.7658056021 0.7626277804 0.7628785968 + 0.7666581273 0.7634323835 0.7636721134 + 0.7675107121 0.7642369866 0.7644655704 + 0.7683631778 0.7650415897 0.7652592063 + 0.7692158222 0.7658461928 0.7660527229 + 0.7700641155 0.7666506767 0.7668461800 + 0.7708631158 0.7674552798 0.7676398158 + 0.7716619968 0.7682598829 0.7684332728 + 0.7724609971 0.7690644860 0.7692267895 + 0.7732599974 0.7698690891 0.7700191736 + 0.7740589976 0.7706338763 0.7707660198 + 0.7748579979 0.7713909745 0.7715128064 + 0.7756569982 0.7721480131 0.7722595930 + 0.7764559984 0.7729051113 0.7730063796 + 0.7772548795 0.7736622095 0.7737532258 + 0.7780538797 0.7744193077 0.7745000720 + 0.7788528800 0.7751764059 0.7752469182 + 0.7796518803 0.7759335041 0.7759937048 + 0.7804220915 0.7766906023 0.7767404914 + 0.7811700106 0.7774475813 0.7774872780 + 0.7819179296 0.7782046795 0.7782341242 + 0.7826659083 0.7789617777 0.7789809108 + 0.7834138274 0.7797188759 0.7797278166 + 0.7841616869 0.7804474831 0.7804462910 + 0.7849097252 0.7811592221 0.7811486125 + 0.7856575847 0.7818710208 0.7818508744 + 0.7864055037 0.7825827003 0.7825533152 + 0.7871534824 0.7832944989 0.7832555771 + 0.7879014015 0.7840061784 0.7839578986 + 0.7886493206 0.7847179770 0.7846602201 + 0.7893972993 0.7854297161 0.7853626013 + 0.7901358008 0.7861415148 0.7860649228 + 0.7908353209 0.7868531942 0.7867671847 + 0.7915347815 0.7875649929 0.7874695063 + 0.7922343016 0.7882766724 0.7881718874 + 0.7929338217 0.7889884710 0.7888742089 + 0.7936332226 0.7897002101 0.7895764709 + 0.7943326831 0.7903869748 0.7902621031 + 0.7950322032 0.7910556793 0.7909221053 + 0.7957317233 0.7917243242 0.7915822268 + 0.7964311838 0.7923929095 0.7922422886 + 0.7971307039 0.7930616140 0.7929024100 + 0.7978302240 0.7937301993 0.7935624719 + 0.7985296845 0.7943987846 0.7942225933 + 0.7992292047 0.7950674891 0.7948827147 + 0.7999287248 0.7957360744 0.7955427766 + 0.8005871177 0.7964047194 0.7962027788 + 0.8012408018 0.7970734239 0.7968629003 + 0.8018944860 0.7977420092 0.7975230217 + 0.8025482297 0.7984105945 0.7981830835 + 0.8032019138 0.7990792990 0.7988432050 + 0.8038555980 0.7997478843 0.7995033264 + 0.8045094013 0.8003910780 0.8001534939 + 0.8051630855 0.8010187745 0.8007736206 + 0.8058168292 0.8016465902 0.8013936877 + 0.8064705133 0.8022742867 0.8020138144 + 0.8071241975 0.8029021025 0.8026338816 + 0.8077778816 0.8035297990 0.8032540083 + 0.8084316254 0.8041576147 0.8038740754 + 0.8090854287 0.8047853112 0.8044942021 + 0.8097391129 0.8054131269 0.8051143289 + 0.8103669286 0.8060408235 0.8057343960 + 0.8109775186 0.8066685796 0.8063545227 + 0.8115881085 0.8072962761 0.8069745898 + 0.8121985793 0.8079240918 0.8075947165 + 0.8128092289 0.8085517883 0.8082147837 + 0.8134198189 0.8091796041 0.8088349104 + 0.8140304089 0.8098073006 0.8094549775 + 0.8146409988 0.8104082942 0.8100705743 + 0.8152515888 0.8109974265 0.8106529117 + 0.8158621788 0.8115864992 0.8112351894 + 0.8164728284 0.8121755719 0.8118175864 + 0.8170834184 0.8127647042 0.8123999238 + 0.8176940084 0.8133537173 0.8129822016 + 0.8183045983 0.8139427900 0.8135645986 + 0.8189151883 0.8145319223 0.8141468763 + 0.8195257187 0.8151209950 0.8147292733 + 0.8201273084 0.8157101274 0.8153116107 + 0.8206974268 0.8162992001 0.8158938885 + 0.8212674856 0.8168882728 0.8164762855 + 0.8218376040 0.8174774051 0.8170586228 + 0.8224077225 0.8180664778 0.8176409006 + 0.8229777813 0.8186556101 0.8182232976 + 0.8235478997 0.8192446828 0.8188055754 + 0.8241178989 0.8198336959 0.8193879724 + 0.8246880174 0.8203967214 0.8199703097 + 0.8252580762 0.8209493160 0.8205189109 + 0.8258281946 0.8215019107 0.8210656047 + 0.8263983130 0.8220545053 0.8216122985 + 0.8269683719 0.8226072192 0.8221591115 + 0.8275384903 0.8231598139 0.8227058053 + 0.8281086087 0.8237124085 0.8232526183 + 0.8286787271 0.8242650032 0.8237993121 + 0.8292487860 0.8248177171 0.8243461251 + 0.8298189044 0.8253703117 0.8248928189 + 0.8303630948 0.8259229064 0.8254395127 + 0.8308951855 0.8264755011 0.8259863257 + 0.8314273953 0.8270282149 0.8265330195 + 0.8319594860 0.8275808096 0.8270797729 + 0.8324916959 0.8281334043 0.8276265264 + 0.8330239058 0.8286859989 0.8281732798 + 0.8335559964 0.8292385936 0.8287199736 + 0.8340882063 0.8297913074 0.8292667866 + 0.8346202970 0.8303225040 0.8298134804 + 0.8351525068 0.8308408260 0.8303381801 + 0.8356845975 0.8313590884 0.8308513761 + 0.8362168074 0.8318774104 0.8313646913 + 0.8367488980 0.8323956728 0.8318778872 + 0.8372811079 0.8329139948 0.8323912024 + 0.8378131986 0.8334323168 0.8329045177 + 0.8383454084 0.8339505792 0.8334177136 + 0.8388774991 0.8344689012 0.8339310288 + 0.8394097090 0.8349872231 0.8344442248 + 0.8399417996 0.8355054855 0.8349574804 + 0.8404424191 0.8360238075 0.8354706764 + 0.8409391046 0.8365421295 0.8359839916 + 0.8414357901 0.8370603919 0.8364971876 + 0.8419324756 0.8375787139 0.8370105028 + 0.8424291015 0.8380969763 0.8375238180 + 0.8429257870 0.8386152983 0.8380370140 + 0.8434224725 0.8391336203 0.8385503292 + 0.8439192176 0.8396518826 0.8390635252 + 0.8444159031 0.8401595950 0.8395767808 + 0.8449125886 0.8406456113 0.8400844932 + 0.8454092741 0.8411316872 0.8405662775 + 0.8459059000 0.8416177034 0.8410481215 + 0.8464025855 0.8421037793 0.8415299058 + 0.8468992710 0.8425897956 0.8420116901 + 0.8473960161 0.8430758119 0.8424934745 + 0.8478927016 0.8435618877 0.8429753184 + 0.8483893871 0.8440479040 0.8434571028 + 0.8488860130 0.8445339799 0.8439388871 + 0.8493826985 0.8450199962 0.8444206715 + 0.8498793840 0.8455060720 0.8449025154 + 0.8503509760 0.8459920883 0.8453842998 + 0.8508145809 0.8464781046 0.8458660841 + 0.8512781858 0.8469641805 0.8463479280 + 0.8517417908 0.8474501967 0.8468297124 + 0.8522053957 0.8479362726 0.8473114967 + 0.8526690006 0.8484222889 0.8477932811 + 0.8531326056 0.8489084244 0.8482751250 + 0.8535962105 0.8493943810 0.8487569094 + 0.8540596962 0.8498803973 0.8492386937 + 0.8545233011 0.8503437042 0.8497204781 + 0.8549869061 0.8507995009 0.8501899242 + 0.8554505110 0.8512551785 0.8506422043 + 0.8559141159 0.8517109752 0.8510944843 + 0.8563777208 0.8521667719 0.8515468240 + 0.8568413258 0.8526226282 0.8519991040 + 0.8573048711 0.8530784249 0.8524513841 + 0.8577684760 0.8535342216 0.8529037237 + 0.8582320213 0.8539898992 0.8533560038 + 0.8586956263 0.8544456959 0.8538082838 + 0.8591591716 0.8549014926 0.8542606235 + 0.8596227765 0.8553572893 0.8547129035 + 0.8600807190 0.8558130860 0.8551651835 + 0.8605133891 0.8562688828 0.8556174040 + 0.8609461784 0.8567246795 0.8560696840 + 0.8613789082 0.8571804166 0.8565220237 + 0.8618116975 0.8576362133 0.8569743037 + 0.8622444272 0.8580920100 0.8574265838 + 0.8626772165 0.8585478067 0.8578789234 + 0.8631098866 0.8590036035 0.8583312035 + 0.8635426760 0.8594594002 0.8587834835 + 0.8639754057 0.8599150777 0.8592358232 + 0.8644081950 0.8603479266 0.8596881032 + 0.8648409247 0.8607752919 0.8601318002 + 0.8652737141 0.8612027168 0.8605564237 + 0.8657063842 0.8616302013 0.8609811068 + 0.8661391735 0.8620576262 0.8614056706 + 0.8665719032 0.8624849916 0.8618304133 + 0.8670045733 0.8629124761 0.8622549772 + 0.8674374223 0.8633399010 0.8626796007 + 0.8678700924 0.8637673855 0.8631042838 + 0.8683028817 0.8641948104 0.8635289073 + 0.8687356114 0.8646221757 0.8639535904 + 0.8691684008 0.8650497198 0.8643782139 + 0.8696010709 0.8654770851 0.8648027778 + 0.8700317144 0.8659045100 0.8652275205 + 0.8704357147 0.8663319945 0.8656520844 + 0.8708397746 0.8667594194 0.8660768270 + 0.8712437749 0.8671867847 0.8665013909 + 0.8716478944 0.8676143289 0.8669260740 + 0.8720518947 0.8680416942 0.8673506975 + 0.8724560142 0.8684691191 0.8677753210 + 0.8728600144 0.8688966036 0.8682000041 + 0.8732640743 0.8693240285 0.8686246276 + 0.8736680746 0.8697515130 0.8690493107 + 0.8740721941 0.8701677918 0.8694738746 + 0.8744761944 0.8705686927 0.8698986173 + 0.8748803139 0.8709695935 0.8703035116 + 0.8752843142 0.8713704944 0.8707023263 + 0.8756883740 0.8717713952 0.8711010218 + 0.8760923743 0.8721722960 0.8714997768 + 0.8764964938 0.8725731969 0.8718984723 + 0.8769004941 0.8729740977 0.8722972870 + 0.8773046136 0.8733749986 0.8726959825 + 0.8777086139 0.8737758994 0.8730947971 + 0.8781126738 0.8741769195 0.8734936118 + 0.8785166740 0.8745778203 0.8738923073 + 0.8789207935 0.8749787211 0.8742911220 + 0.8793247938 0.8753796220 0.8746898174 + 0.8797289133 0.8757805228 0.8750885725 + 0.8801240921 0.8761814237 0.8754873276 + 0.8805015087 0.8765823245 0.8758860826 + 0.8808789253 0.8769832253 0.8762847781 + 0.8812562227 0.8773841262 0.8766835928 + 0.8816335797 0.8777850270 0.8770824075 + 0.8820109963 0.8781859279 0.8774811029 + 0.8823882937 0.8785868287 0.8778799176 + 0.8827657104 0.8789877295 0.8782786131 + 0.8831431270 0.8793885708 0.8786774278 + 0.8835204244 0.8797894716 0.8790761232 + 0.8838977814 0.8801786900 0.8794748783 + 0.8842751980 0.8805547953 0.8798736930 + 0.8846524954 0.8809309006 0.8802558780 + 0.8850299120 0.8813070059 0.8806303740 + 0.8854073286 0.8816831112 0.8810049891 + 0.8857846260 0.8820592165 0.8813794851 + 0.8861619830 0.8824353218 0.8817539811 + 0.8865392804 0.8828114271 0.8821285963 + 0.8869166970 0.8831874728 0.8825030923 + 0.8872941136 0.8835635781 0.8828777075 + 0.8876714110 0.8839396834 0.8832522035 + 0.8880488276 0.8843157887 0.8836268187 + 0.8884261847 0.8846918941 0.8840013146 + 0.8888034821 0.8850679994 0.8843758106 + 0.8891808987 0.8854441047 0.8847504258 + 0.8895583153 0.8858202100 0.8851249218 + 0.8899356127 0.8861963153 0.8854994774 + 0.8902924061 0.8865724206 0.8858739734 + 0.8906450272 0.8869485259 0.8862485886 + 0.8909975886 0.8873245716 0.8866230845 + 0.8913502097 0.8877006769 0.8869975805 + 0.8917027116 0.8880767822 0.8873721957 + 0.8920552731 0.8884528875 0.8877466917 + 0.8924078941 0.8888289928 0.8881213069 + 0.8927605152 0.8892050982 0.8884958029 + 0.8931130171 0.8895812035 0.8888702989 + 0.8934655786 0.8899573088 0.8892449141 + 0.8938181996 0.8903127909 0.8896194100 + 0.8941708207 0.8906658292 0.8899940252 + 0.8945233226 0.8910186887 0.8903462291 + 0.8948758841 0.8913716078 0.8906980753 + 0.8952285051 0.8917245269 0.8910499811 + 0.8955811262 0.8920775056 0.8914020061 + 0.8959336281 0.8924304247 0.8917539120 + 0.8962861896 0.8927832842 0.8921058178 + 0.8966388106 0.8931362033 0.8924577236 + 0.8969913721 0.8934891820 0.8928096294 + 0.8973438740 0.8938421011 0.8931614757 + 0.8976964951 0.8941950202 0.8935133815 + 0.8980491161 0.8945478797 0.8938652873 + 0.8984016776 0.8949009180 0.8942171931 + 0.8987541795 0.8952537775 0.8945690989 + 0.8991068006 0.8956066966 0.8949210048 + 0.8994594216 0.8959596157 0.8952729106 + 0.8998119831 0.8963125944 0.8956248164 + 0.9001538157 0.8966655135 0.8959767222 + 0.9004834294 0.8970183730 0.8963286281 + 0.9008129239 0.8973712921 0.8966804743 + 0.9011424780 0.8977242708 0.8970323801 + 0.9014719725 0.8980771899 0.8973842859 + 0.9018015862 0.8984301090 0.8977361917 + 0.9021310806 0.8987830281 0.8980880976 + 0.9024606943 0.8991360068 0.8984400034 + 0.9027901888 0.8994889259 0.8987919092 + 0.9031198025 0.8998417854 0.8991438150 + 0.9034494162 0.9001827836 0.8994957209 + 0.9037789106 0.9005141258 0.8998476267 + 0.9041085243 0.9008454084 0.9001874924 + 0.9044380188 0.9011766911 0.9005182981 + 0.9047675729 0.9015079141 0.9008489847 + 0.9050971270 0.9018391967 0.9011797905 + 0.9054266810 0.9021704793 0.9015104771 + 0.9057561755 0.9025018215 0.9018412828 + 0.9060857892 0.9028331041 0.9021720290 + 0.9064154029 0.9031643867 0.9025027752 + 0.9067448974 0.9034956098 0.9028335214 + 0.9070745111 0.9038268924 0.9031643271 + 0.9074040055 0.9041581750 0.9034950137 + 0.9077336192 0.9044895172 0.9038258195 + 0.9080631137 0.9048207998 0.9041565061 + 0.9083927274 0.9051520824 0.9044873118 + 0.9087222219 0.9054833055 0.9048179984 + 0.9090517759 0.9058145881 0.9051488042 + 0.9093812704 0.9061458707 0.9054794908 + 0.9097108841 0.9064772129 0.9058102965 + 0.9100378156 0.9068084955 0.9061409831 + 0.9103459716 0.9071397781 0.9064717889 + 0.9106541872 0.9074711204 0.9068024755 + 0.9109624028 0.9078022838 0.9071332812 + 0.9112706184 0.9081336260 0.9074640274 + 0.9115787745 0.9084649086 0.9077947140 + 0.9118869901 0.9087961912 0.9081255198 + 0.9121950865 0.9091274738 0.9084562063 + 0.9125033021 0.9094588161 0.9087870121 + 0.9128115177 0.9097899795 0.9091176987 + 0.9131196737 0.9101138711 0.9094485044 + 0.9134278893 0.9104250073 0.9097791910 + 0.9137361050 0.9107360840 0.9101033807 + 0.9140443206 0.9110472202 0.9104143977 + 0.9143524766 0.9113582969 0.9107254148 + 0.9146605730 0.9116693735 0.9110363722 + 0.9149687886 0.9119803905 0.9113473892 + 0.9152770042 0.9122915268 0.9116582870 + 0.9155852199 0.9126026034 0.9119693041 + 0.9158933759 0.9129136801 0.9122803211 + 0.9162015915 0.9132248163 0.9125912786 + 0.9165098071 0.9135358930 0.9129022956 + 0.9168180227 0.9138470292 0.9132133126 + 0.9171261191 0.9141579866 0.9135242105 + 0.9174342752 0.9144691229 0.9138352275 + 0.9177424908 0.9147801995 0.9141461849 + 0.9180507064 0.9150912762 0.9144572020 + 0.9183589220 0.9154024124 0.9147682190 + 0.9186670780 0.9157134891 0.9150791764 + 0.9189752936 0.9160246253 0.9153901935 + 0.9192835093 0.9163355827 0.9157010913 + 0.9195916057 0.9166467190 0.9160121083 + 0.9198998213 0.9169577956 0.9163231254 + 0.9201946259 0.9172688723 0.9166340828 + 0.9204829931 0.9175800085 0.9169450998 + 0.9207713008 0.9178910851 0.9172561169 + 0.9210597277 0.9182022214 0.9175670147 + 0.9213480949 0.9185131788 0.9178779721 + 0.9216364026 0.9188243151 0.9181889892 + 0.9219248295 0.9191353917 0.9185000062 + 0.9222130775 0.9194465280 0.9188110232 + 0.9225015044 0.9197576046 0.9191219807 + 0.9227898717 0.9200645089 0.9194329977 + 0.9230781794 0.9203566909 0.9197438955 + 0.9233666062 0.9206489921 0.9200516939 + 0.9236549139 0.9209411740 0.9203441739 + 0.9239432812 0.9212334752 0.9206367135 + 0.9242315888 0.9215257168 0.9209291935 + 0.9245200157 0.9218178988 0.9212217927 + 0.9248083830 0.9221101999 0.9215142727 + 0.9250966907 0.9224023819 0.9218068123 + 0.9253851175 0.9226946235 0.9220994115 + 0.9256734252 0.9229869246 0.9223918915 + 0.9259617925 0.9232791066 0.9226843715 + 0.9262501001 0.9235714078 0.9229769111 + 0.9265385270 0.9238635898 0.9232695103 + 0.9268268943 0.9241557717 0.9235619903 + 0.9271152020 0.9244480729 0.9238544703 + 0.9274036288 0.9247403145 0.9241470098 + 0.9276918769 0.9250324965 0.9244396091 + 0.9279803038 0.9253247976 0.9247320890 + 0.9282686710 0.9256169796 0.9250246286 + 0.9285569787 0.9259092808 0.9253171086 + 0.9288454056 0.9262015224 0.9256097078 + 0.9291337132 0.9264937043 0.9259021878 + 0.9294220805 0.9267860055 0.9261947274 + 0.9297103882 0.9270781875 0.9264872074 + 0.9299988151 0.9273704886 0.9267798066 + 0.9302688241 0.9276626706 0.9270722866 + 0.9305387735 0.9279549122 0.9273648262 + 0.9308087826 0.9282472134 0.9276573062 + 0.9310786724 0.9285393953 0.9279499054 + 0.9313486814 0.9288315773 0.9282423854 + 0.9316185713 0.9291238785 0.9285349250 + 0.9318885803 0.9294161201 0.9288275242 + 0.9321585298 0.9297084212 0.9291200042 + 0.9324284792 0.9300006032 0.9294124842 + 0.9326984882 0.9302752018 0.9297050238 + 0.9329683781 0.9305499196 0.9299976230 + 0.9332383871 0.9308245182 0.9302729964 + 0.9335082769 0.9310991764 0.9305483103 + 0.9337782860 0.9313737750 0.9308236241 + 0.9340481758 0.9316484928 0.9310988784 + 0.9343181849 0.9319230914 0.9313740730 + 0.9345881939 0.9321978092 0.9316493869 + 0.9348580837 0.9324725270 0.9319247007 + 0.9351280928 0.9327471256 0.9322000146 + 0.9353979826 0.9330217838 0.9324753284 + 0.9356679916 0.9332963824 0.9327505827 + 0.9359378815 0.9335711002 0.9330258965 + 0.9362078905 0.9338456988 0.9333012104 + 0.9364778996 0.9341204166 0.9335764050 + 0.9367477894 0.9343950152 0.9338517189 + 0.9370177984 0.9346696734 0.9341269732 + 0.9372876883 0.9349442720 0.9344022870 + 0.9375576973 0.9352189898 0.9346776009 + 0.9378277063 0.9354937077 0.9349529147 + 0.9380975962 0.9357683063 0.9352282286 + 0.9383676052 0.9360430241 0.9355034828 + 0.9386374950 0.9363176227 0.9357786775 + 0.9389075041 0.9365922809 0.9360539913 + 0.9391773939 0.9368668795 0.9363293052 + 0.9394474030 0.9371415973 0.9366046190 + 0.9397174120 0.9374161959 0.9368798733 + 0.9399873018 0.9376909137 0.9371551871 + 0.9402409792 0.9379655719 0.9374305010 + 0.9404938817 0.9382401705 0.9377058148 + 0.9407467842 0.9385148883 0.9379811287 + 0.9409996271 0.9387894869 0.9382563233 + 0.9412525296 0.9390642047 0.9385315776 + 0.9415053725 0.9393388033 0.9388068914 + 0.9417582750 0.9396135211 0.9390822053 + 0.9420111775 0.9398881197 0.9393575191 + 0.9422640800 0.9401531219 0.9396327734 + 0.9425169230 0.9404113293 0.9399080873 + 0.9427698255 0.9406695962 0.9401726127 + 0.9430227280 0.9409278035 0.9404317737 + 0.9432755709 0.9411860704 0.9406909943 + 0.9435284734 0.9414442778 0.9409502149 + 0.9437813759 0.9417026043 0.9412093759 + 0.9440342188 0.9419608116 0.9414685965 + 0.9442871213 0.9422190785 0.9417278171 + 0.9445400238 0.9424772859 0.9419869781 + 0.9447929263 0.9427356124 0.9422461987 + 0.9450458288 0.9429938197 0.9425053000 + 0.9452986717 0.9432520866 0.9427645206 + 0.9455515146 0.9435104132 0.9430236816 + 0.9458044171 0.9437686205 0.9432829022 + 0.9460573196 0.9440268874 0.9435421228 + 0.9463102221 0.9442850947 0.9438012838 + 0.9465631247 0.9445434213 0.9440605044 + 0.9468160272 0.9448016286 0.9443197250 + 0.9470688105 0.9450598955 0.9445788860 + 0.9473217130 0.9453181028 0.9448379874 + 0.9475746155 0.9455764294 0.9450972080 + 0.9478275180 0.9458345771 0.9453564286 + 0.9480804205 0.9460929036 0.9456155896 + 0.9483332038 0.9463511109 0.9458748102 + 0.9485861063 0.9466093779 0.9461339712 + 0.9488390088 0.9468675852 0.9463931918 + 0.9490919113 0.9471259117 0.9466524124 + 0.9493448138 0.9473841190 0.9469115734 + 0.9495977163 0.9476423860 0.9471707940 + 0.9498504996 0.9479007125 0.9474298954 + 0.9500969052 0.9481589198 0.9476891160 + 0.9503340125 0.9484171867 0.9479482770 + 0.9505710006 0.9486753941 0.9482074976 + 0.9508081079 0.9489337206 0.9484667182 + 0.9510450959 0.9491919279 0.9487258792 + 0.9512820840 0.9494501948 0.9489850998 + 0.9515191913 0.9497084022 0.9492443204 + 0.9517561793 0.9499667287 0.9495034814 + 0.9519932270 0.9502115846 0.9497625828 + 0.9522302747 0.9504545927 0.9500206113 + 0.9524673223 0.9506974816 0.9502646923 + 0.9527043104 0.9509404898 0.9505088925 + 0.9529414177 0.9511833787 0.9507529736 + 0.9531784058 0.9514263868 0.9509971738 + 0.9534155130 0.9516692758 0.9512413144 + 0.9536525011 0.9519122839 0.9514855146 + 0.9538894892 0.9521551728 0.9517297149 + 0.9541265965 0.9523981810 0.9519737959 + 0.9543635845 0.9526411295 0.9522179961 + 0.9546005726 0.9528840780 0.9524620771 + 0.9548376799 0.9531270266 0.9527062774 + 0.9550747275 0.9533699751 0.9529504180 + 0.9553117156 0.9536129236 0.9531946182 + 0.9555488229 0.9538558722 0.9534386992 + 0.9557858109 0.9540988207 0.9536828995 + 0.9560227990 0.9543418288 0.9539269805 + 0.9562599063 0.9545847178 0.9541711807 + 0.9564968944 0.9548277259 0.9544153810 + 0.9567340016 0.9550706148 0.9546595216 + 0.9569709897 0.9553136230 0.9549037218 + 0.9572079778 0.9555565119 0.9551478028 + 0.9574450850 0.9557995200 0.9553920031 + 0.9576820731 0.9560424089 0.9556360841 + 0.9579191208 0.9562854171 0.9558802843 + 0.9581562281 0.9565284252 0.9561244249 + 0.9583932161 0.9567713141 0.9563686252 + 0.9586302042 0.9570143223 0.9566128254 + 0.9588673115 0.9572572112 0.9568569064 + 0.9591042995 0.9575002193 0.9571011066 + 0.9593414068 0.9577431083 0.9573451877 + 0.9595783949 0.9579861164 0.9575893879 + 0.9598153830 0.9582290053 0.9578335285 + 0.9600492120 0.9584720135 0.9580777287 + 0.9602714777 0.9587149024 0.9583218098 + 0.9604939222 0.9589579105 0.9585660100 + 0.9607161880 0.9592007995 0.9588100910 + 0.9609385133 0.9594438076 0.9590542912 + 0.9611607790 0.9596866965 0.9592984915 + 0.9613832235 0.9599297047 0.9595425725 + 0.9616054893 0.9601625204 0.9597867727 + 0.9618278146 0.9603912234 0.9600291252 + 0.9620500803 0.9606198072 0.9602593184 + 0.9622725248 0.9608485103 0.9604893923 + 0.9624947906 0.9610772133 0.9607195258 + 0.9627171159 0.9613059163 0.9609495997 + 0.9629393816 0.9615346193 0.9611796737 + 0.9631618261 0.9617632031 0.9614098072 + 0.9633840919 0.9619919062 0.9616398811 + 0.9636064172 0.9622206092 0.9618700147 + 0.9638286829 0.9624493122 0.9621000886 + 0.9640511274 0.9626778960 0.9623302817 + 0.9642733932 0.9629065990 0.9625604153 + 0.9644957185 0.9631353021 0.9627904892 + 0.9647179842 0.9633640051 0.9630206227 + 0.9649404287 0.9635927081 0.9632506967 + 0.9651626945 0.9638212919 0.9634807706 + 0.9653850198 0.9640499949 0.9637109041 + 0.9656072855 0.9642786980 0.9639409781 + 0.9658296704 0.9645074010 0.9641711712 + 0.9660519958 0.9647359848 0.9644013047 + 0.9662743211 0.9649646878 0.9646313787 + 0.9664965868 0.9651933908 0.9648615122 + 0.9667189717 0.9654220939 0.9650915861 + 0.9669412971 0.9656506777 0.9653217196 + 0.9671636224 0.9658793807 0.9655517936 + 0.9673860073 0.9661080837 0.9657819271 + 0.9676082730 0.9663367867 0.9660120010 + 0.9678305984 0.9665654898 0.9662421942 + 0.9680529237 0.9667940736 0.9664723277 + 0.9682753086 0.9670227766 0.9667024016 + 0.9684975743 0.9672514796 0.9669324756 + 0.9687198997 0.9674801826 0.9671626091 + 0.9689422250 0.9677088261 0.9673926830 + 0.9691646099 0.9679375291 0.9676228166 + 0.9693868756 0.9681661725 0.9678528905 + 0.9696092010 0.9683948755 0.9680830836 + 0.9698315263 0.9686235785 0.9683132172 + 0.9700505733 0.9688522220 0.9685432911 + 0.9702591896 0.9690809250 0.9687734246 + 0.9704679251 0.9693096280 0.9690034986 + 0.9706764817 0.9695382714 0.9692335725 + 0.9708852172 0.9697669148 0.9694637060 + 0.9710938931 0.9699956179 0.9696937799 + 0.9713025093 0.9702112079 0.9699239135 + 0.9715111852 0.9704266191 0.9701452851 + 0.9717199206 0.9706419110 0.9703623056 + 0.9719284773 0.9708573222 0.9705793262 + 0.9721372128 0.9710726738 0.9707962871 + 0.9723458886 0.9712880254 0.9710131884 + 0.9725545049 0.9715033770 0.9712302089 + 0.9727631807 0.9717187285 0.9714472294 + 0.9729719162 0.9719340801 0.9716641903 + 0.9731804729 0.9721494913 0.9718812108 + 0.9733892083 0.9723647833 0.9720981717 + 0.9735978842 0.9725801945 0.9723151922 + 0.9738065004 0.9727954865 0.9725322127 + 0.9740151763 0.9730108976 0.9727491736 + 0.9742239118 0.9732261896 0.9729661942 + 0.9744325280 0.9734416008 0.9731832147 + 0.9746412039 0.9736570120 0.9734001756 + 0.9748498797 0.9738723040 0.9736170769 + 0.9750584960 0.9740877151 0.9738340974 + 0.9752671719 0.9743030071 0.9740511179 + 0.9754759073 0.9745184183 0.9742680788 + 0.9756845236 0.9747338295 0.9744850993 + 0.9758931994 0.9749491215 0.9747021198 + 0.9761018753 0.9751644731 0.9749190807 + 0.9763104916 0.9753798246 0.9751361012 + 0.9765192270 0.9755951762 0.9753531218 + 0.9767279029 0.9758105278 0.9755700827 + 0.9769365191 0.9760258794 0.9757871032 + 0.9771451950 0.9762412906 0.9760041237 + 0.9773538709 0.9764565825 0.9762210846 + 0.9775624871 0.9766719937 0.9764379859 + 0.9777712226 0.9768872857 0.9766550064 + 0.9779798985 0.9771026969 0.9768720269 + 0.9781885147 0.9773179889 0.9770889878 + 0.9783971906 0.9775334001 0.9773060083 + 0.9786059260 0.9777488112 0.9775230289 + 0.9788144827 0.9779641032 0.9777399898 + 0.9790232182 0.9781795144 0.9779570103 + 0.9792318940 0.9783948064 0.9781739712 + 0.9794405103 0.9786102176 0.9783909917 + 0.9796491861 0.9788256288 0.9786080122 + 0.9798579216 0.9790409207 0.9788249731 + 0.9800624847 0.9792562723 0.9790418744 + 0.9802585244 0.9794716239 0.9792588949 + 0.9804543853 0.9796869755 0.9794759154 + 0.9806504250 0.9799023271 0.9796928763 + 0.9808464050 0.9801108837 0.9799098969 + 0.9810423851 0.9803137779 0.9801197052 + 0.9812384248 0.9805167913 0.9803245068 + 0.9814342856 0.9807196856 0.9805291891 + 0.9816303253 0.9809225798 0.9807338715 + 0.9818263054 0.9811254740 0.9809386730 + 0.9820222855 0.9813284874 0.9811434150 + 0.9822182059 0.9815313816 0.9813480973 + 0.9824141860 0.9817342758 0.9815528989 + 0.9826102257 0.9819372892 0.9817575812 + 0.9828062057 0.9821401834 0.9819623232 + 0.9830021858 0.9823430777 0.9821671247 + 0.9831981063 0.9825459719 0.9823718071 + 0.9833940864 0.9827489853 0.9825764894 + 0.9835901260 0.9829518795 0.9827812910 + 0.9837861061 0.9831547737 0.9829859734 + 0.9839820266 0.9833577275 0.9831907153 + 0.9841780066 0.9835606813 0.9833955169 + 0.9843739867 0.9837635756 0.9836001992 + 0.9845700264 0.9839665294 0.9838048816 + 0.9847660065 0.9841694832 0.9840096235 + 0.9849619269 0.9843723774 0.9842144251 + 0.9851579070 0.9845752716 0.9844191074 + 0.9853538871 0.9847782254 0.9846237898 + 0.9855499268 0.9849811792 0.9848285913 + 0.9857457876 0.9851840734 0.9850332737 + 0.9859418273 0.9853870273 0.9852380157 + 0.9861378074 0.9855899215 0.9854428172 + 0.9863337874 0.9857928753 0.9856474996 + 0.9865298271 0.9859958291 0.9858521819 + 0.9867256880 0.9861987233 0.9860569835 + 0.9869217277 0.9864016771 0.9862617254 + 0.9871177077 0.9866045713 0.9864664078 + 0.9873136878 0.9868075252 0.9866712093 + 0.9875096083 0.9870104194 0.9868758917 + 0.9877055883 0.9872133732 0.9870805740 + 0.9879016280 0.9874163270 0.9872853756 + 0.9880976081 0.9876192212 0.9874901175 + 0.9882935882 0.9878221154 0.9876947999 + 0.9884895086 0.9880251288 0.9878996015 + 0.9886854887 0.9882280231 0.9881042838 + 0.9888815284 0.9884309173 0.9883090258 + 0.9890775084 0.9886338711 0.9885138273 + 0.9892734289 0.9888368249 0.9887185097 + 0.9894694090 0.9890397191 0.9889231920 + 0.9896653891 0.9892426133 0.9891278744 + 0.9898614287 0.9894456267 0.9893326759 + 0.9900538921 0.9896485209 0.9895374179 + 0.9902380705 0.9898514152 0.9897421002 + 0.9904223084 0.9900512099 0.9899469018 + 0.9906064868 0.9902426004 0.9901431203 + 0.9907907248 0.9904338717 0.9903364182 + 0.9909747839 0.9906252027 0.9905297160 + 0.9911590219 0.9908164740 0.9907228947 + 0.9913432002 0.9910078049 0.9909161925 + 0.9915273786 0.9911991954 0.9911094904 + 0.9917116165 0.9913905263 0.9913027883 + 0.9918957949 0.9915817976 0.9914960265 + 0.9920799732 0.9917731285 0.9916893244 + 0.9922642112 0.9919645190 0.9918826222 + 0.9924482703 0.9921557903 0.9920758009 + 0.9926325083 0.9923471212 0.9922690988 + 0.9928166866 0.9925383925 0.9924623966 + 0.9930009246 0.9927297235 0.9926556945 + 0.9931851029 0.9929211140 0.9928488731 + 0.9933692813 0.9931123853 0.9930421710 + 0.9935535192 0.9933037162 0.9932355285 + 0.9937375784 0.9934949875 0.9934287071 + 0.9939218163 0.9936863780 0.9936220050 + 0.9941059947 0.9938777089 0.9938153028 + 0.9942901731 0.9940689802 0.9940086007 + 0.9944744110 0.9942603111 0.9942017794 + 0.9946585894 0.9944517016 0.9943950772 + 0.9948428273 0.9946429729 0.9945883751 + 0.9950270057 0.9948343039 0.9947816730 + 0.9952111244 0.9950255752 0.9949749112 + 0.9953953028 0.9952169061 0.9951682091 + 0.9955794811 0.9954082966 0.9953615069 + 0.9957637191 0.9955996275 0.9955546856 + 0.9959478974 0.9957908988 0.9957479835 + 0.9961320758 0.9959822297 0.9959412813 + 0.9963163137 0.9961736202 0.9961345792 + 0.9965003729 0.9963648915 0.9963278174 + 0.9966846108 0.9965562224 0.9965211153 + 0.9968687892 0.9967474937 0.9967144132 + 0.9970530272 0.9969388247 0.9969075918 + 0.9972372055 0.9971302152 0.9971008897 + 0.9974213839 0.9973214865 0.9972941875 + 0.9976056218 0.9975128174 0.9974874854 + 0.9977898002 0.9977040887 0.9976807237 + 0.9979739189 0.9978954792 0.9978740215 + 0.9981580973 0.9980868101 0.9980673194 + 0.9983422756 0.9982780814 0.9982606173 + 0.9985265136 0.9984694123 0.9984537959 + 0.9987106919 0.9986606836 0.9986470938 + 0.9988948703 0.9988520741 0.9988403916 + 0.9990791082 0.9990434051 0.9990335703 + 0.9992632866 0.9992346764 0.9992269278 + 0.9994474053 0.9994260073 0.9994202256 + 0.9996315837 0.9996173978 0.9996135235 + 0.9998158216 0.9998087287 0.9998067021 + 1.0000000000 1.0000000000 1.0000000000 +} diff --git a/rpplugins/color_correction/resources/film_luts_raw/kodak_dscs_3153.spi1d b/rpplugins/color_correction/resources/film_luts_raw/kodak_dscs_3153.spi1d new file mode 100644 index 0000000..589da4b --- /dev/null +++ b/rpplugins/color_correction/resources/film_luts_raw/kodak_dscs_3153.spi1d @@ -0,0 +1,1030 @@ +Version 1 +From 0.0 1.0 +Length 1024 +Components 3 +{ + 0.0000000000 0.0000000000 0.0000000000 + 0.0033556900 0.0036243461 0.0021771761 + 0.0067113810 0.0072486931 0.0043543512 + 0.0100719603 0.0109450798 0.0065315268 + 0.0136722000 0.0148685100 0.0087087033 + 0.0172724500 0.0187919401 0.0109967999 + 0.0209288709 0.0229167007 0.0134465704 + 0.0247608796 0.0271310192 0.0158963501 + 0.0285928901 0.0314321816 0.0183461197 + 0.0325581394 0.0359185003 0.0208943095 + 0.0366007015 0.0404266603 0.0236469992 + 0.0406721011 0.0451549515 0.0263996907 + 0.0448958799 0.0498832315 0.0291523803 + 0.0491196699 0.0548080616 0.0321348682 + 0.0534582287 0.0597378612 0.0352196097 + 0.0578269996 0.0648122802 0.0383043587 + 0.0622479804 0.0698948205 0.0415499993 + 0.0667206198 0.0750741214 0.0449920595 + 0.0712093785 0.0802576020 0.0484341197 + 0.0757424608 0.0854823887 0.0520806797 + 0.0802765936 0.0907058865 0.0558979213 + 0.0848271400 0.0959210992 0.0597151592 + 0.0893776789 0.1011238992 0.0638853684 + 0.0939087570 0.1062820032 0.0680840537 + 0.0984367505 0.1114128977 0.0724848807 + 0.1029269993 0.1164738983 0.0770553872 + 0.1073973030 0.1214959025 0.0817479491 + 0.1118313000 0.1264283061 0.0866615325 + 0.1162149012 0.1313190013 0.0916693583 + 0.1205834970 0.1361002028 0.0968769416 + 0.1248577982 0.1408507973 0.1021751985 + 0.1291321069 0.1454659998 0.1076091975 + 0.1333063990 0.1500781029 0.1131248996 + 0.1374552995 0.1545193046 0.1187048033 + 0.1415515989 0.1589604020 0.1243304983 + 0.1455647051 0.1632665992 0.1299701035 + 0.1495777071 0.1675314009 0.1355862021 + 0.1534643024 0.1717227995 0.1411814988 + 0.1573361009 0.1758131981 0.1467006058 + 0.1611633003 0.1799037009 0.1521570981 + 0.1648924053 0.1838286966 0.1575206071 + 0.1686214954 0.1877496988 0.1627777070 + 0.1722615957 0.1916016042 0.1679431945 + 0.1758497059 0.1953604072 0.1729734987 + 0.1794376969 0.1991191953 0.1779143065 + 0.1829102039 0.2027603984 0.1827175021 + 0.1863611937 0.2063656002 0.1874202043 + 0.1898120940 0.2099706978 0.1920142025 + 0.1931387931 0.2134328038 0.1964761019 + 0.1964582950 0.2168937027 0.2008883059 + 0.1997777969 0.2203408033 0.2051143050 + 0.2029809058 0.2236669958 0.2093403041 + 0.2061755955 0.2269932926 0.2133757025 + 0.2093703002 0.2303075939 0.2173759937 + 0.2124706954 0.2335088998 0.2213031054 + 0.2155478001 0.2367102057 0.2250909060 + 0.2186249942 0.2399114966 0.2288787067 + 0.2216414064 0.2430005968 0.2325274944 + 0.2246086001 0.2460864037 0.2361178994 + 0.2275757939 0.2491723001 0.2397083044 + 0.2305241972 0.2521803081 0.2431315929 + 0.2333890945 0.2551597953 0.2465402037 + 0.2362540066 0.2581393123 0.2499487996 + 0.2391189039 0.2610821128 0.2531935871 + 0.2419181019 0.2639639974 0.2564358115 + 0.2446880937 0.2668457925 0.2596780956 + 0.2474582046 0.2697275877 0.2627840936 + 0.2502210140 0.2725282907 0.2658750117 + 0.2529034913 0.2753205895 0.2689658999 + 0.2555859983 0.2781128883 0.2719655037 + 0.2582685053 0.2808786035 0.2749192119 + 0.2609224021 0.2835890055 0.2778730094 + 0.2635244131 0.2862994075 0.2807919979 + 0.2661263049 0.2890098095 0.2836216092 + 0.2687281966 0.2916727960 0.2864513099 + 0.2712922990 0.2943083942 0.2892810106 + 0.2738203108 0.2969441116 0.2920272052 + 0.2763482928 0.2995797098 0.2947449982 + 0.2788763046 0.3021580875 0.2974627912 + 0.2813667059 0.3047255874 0.3001739085 + 0.2838270068 0.3072930872 0.3027910888 + 0.2862873077 0.3098605871 0.3054082096 + 0.2887476087 0.3123694956 0.3080253005 + 0.2911775112 0.3148748875 0.3106203079 + 0.2935760021 0.3173803985 0.3131470084 + 0.2959744036 0.3198859096 0.3156735897 + 0.2983728945 0.3223375976 0.3182002902 + 0.3007532060 0.3247866929 0.3207036853 + 0.3030953109 0.3272357881 0.3231492937 + 0.3054375052 0.3296849132 0.3255949020 + 0.3077796102 0.3320893943 0.3280405104 + 0.3101190925 0.3344874084 0.3304716051 + 0.3124099970 0.3368853033 0.3328445852 + 0.3147009015 0.3392831981 0.3352177143 + 0.3169918060 0.3416486979 0.3375906944 + 0.3192827106 0.3440001905 0.3399637043 + 0.3215416968 0.3463517129 0.3422729075 + 0.3237861097 0.3487032950 0.3445810974 + 0.3260306120 0.3510360122 0.3468891978 + 0.3282749951 0.3533455133 0.3491973877 + 0.3305096924 0.3556550145 0.3514679968 + 0.3327121139 0.3579646051 0.3537184000 + 0.3349145055 0.3602696061 0.3559688032 + 0.3371168971 0.3625411093 0.3582192957 + 0.3393192887 0.3648126125 0.3604589999 + 0.3414955139 0.3670840859 0.3626582026 + 0.3436599970 0.3693554997 0.3648572862 + 0.3458243906 0.3716023862 0.3670564890 + 0.3479889035 0.3738394976 0.3692556024 + 0.3501509130 0.3760766089 0.3714247048 + 0.3522812128 0.3783136904 0.3735783994 + 0.3544115126 0.3805431128 0.3757320940 + 0.3565418124 0.3827491105 0.3778859079 + 0.3586719930 0.3849549890 0.3800387979 + 0.3607907891 0.3871609867 0.3821524978 + 0.3628903031 0.3893668950 0.3842661977 + 0.3649899065 0.3915528059 0.3863798082 + 0.3670895100 0.3937306106 0.3884935081 + 0.3691891134 0.3959082961 0.3905969858 + 0.3712717891 0.3980861008 0.3926754892 + 0.3733437955 0.4002606869 0.3947539926 + 0.3754158914 0.4024128914 0.3968324065 + 0.3774879873 0.4045650959 0.3989109099 + 0.3795599937 0.4067172110 0.4009746909 + 0.3816126883 0.4088693857 0.4030224979 + 0.3836601973 0.4110105038 0.4050701857 + 0.3857075870 0.4131393135 0.4071179032 + 0.3877550960 0.4152680933 0.4091657102 + 0.3898024857 0.4173969030 0.4111976027 + 0.3918300867 0.4195258021 0.4132185876 + 0.3938556015 0.4216380119 0.4152396023 + 0.3958810866 0.4237453938 0.4172605872 + 0.3979066014 0.4258528054 0.4192816019 + 0.3999319971 0.4279601872 0.4212876856 + 0.4019384980 0.4300670028 0.4232856929 + 0.4039444029 0.4321546853 0.4252836108 + 0.4059503078 0.4342423081 0.4272815883 + 0.4079560935 0.4363299906 0.4292795062 + 0.4099619985 0.4384176135 0.4312647879 + 0.4119505882 0.4405007958 0.4332428873 + 0.4139389098 0.4425699115 0.4352209866 + 0.4159272015 0.4446390867 0.4371992052 + 0.4179156125 0.4467082024 0.4391773045 + 0.4199039042 0.4487774074 0.4411455989 + 0.4218772054 0.4508393109 0.4431068003 + 0.4238497913 0.4528909028 0.4450680017 + 0.4258224070 0.4549424946 0.4470292926 + 0.4277949929 0.4569939971 0.4489904940 + 0.4297676086 0.4590455890 0.4509448111 + 0.4317277074 0.4610880911 0.4528915882 + 0.4336861074 0.4631226957 0.4548385143 + 0.4356445074 0.4651573002 0.4567854106 + 0.4376029074 0.4671919048 0.4587321877 + 0.4395613074 0.4692265093 0.4606749117 + 0.4415096939 0.4712507129 0.4626095891 + 0.4434551895 0.4732685983 0.4645442963 + 0.4454007149 0.4752865136 0.4664790034 + 0.4473460913 0.4773043096 0.4684137106 + 0.4492915869 0.4793221951 0.4703465104 + 0.4512295127 0.4813289046 0.4722707868 + 0.4531629980 0.4833298922 0.4741952121 + 0.4550965130 0.4853309095 0.4761194885 + 0.4570299983 0.4873319864 0.4780437946 + 0.4589635134 0.4893330038 0.4799681902 + 0.4608916938 0.4913224876 0.4818837047 + 0.4628139138 0.4933061898 0.4837990999 + 0.4647361040 0.4952898920 0.4857144952 + 0.4666582942 0.4972735941 0.4876298904 + 0.4685805142 0.4992572963 0.4895452857 + 0.4704998136 0.5012295842 0.4914546907 + 0.4724110067 0.5031952262 0.4933620989 + 0.4743221998 0.5051606894 0.4952695966 + 0.4762333930 0.5071262717 0.4971770942 + 0.4781445861 0.5090917945 0.4990845919 + 0.4800555110 0.5110468864 0.5009883046 + 0.4819557965 0.5129930973 0.5028885007 + 0.4838559926 0.5149393082 0.5047886968 + 0.4857563078 0.5168855190 0.5066888928 + 0.4876565039 0.5188316703 0.5085890889 + 0.4895567894 0.5207694769 0.5104873776 + 0.4914484024 0.5226947069 0.5123804808 + 0.4933373034 0.5246199965 0.5142735243 + 0.4952262938 0.5265452862 0.5161666274 + 0.4971151948 0.5284705758 0.5180596113 + 0.4990041852 0.5303910971 0.5199525952 + 0.5008875132 0.5322936177 0.5218384266 + 0.5027645230 0.5341960788 0.5237240195 + 0.5046414733 0.5360984802 0.5256096125 + 0.5065184832 0.5380010009 0.5274953246 + 0.5083954930 0.5399035215 0.5293809175 + 0.5102707148 0.5417822003 0.5312609076 + 0.5121346712 0.5436596274 0.5331382751 + 0.5139986873 0.5455371141 0.5350157022 + 0.5158627033 0.5474146008 0.5368930101 + 0.5177267790 0.5492920280 0.5387703776 + 0.5195907950 0.5511524081 0.5406445265 + 0.5214436054 0.5530024171 0.5425122976 + 0.5232933164 0.5548523068 0.5443801284 + 0.5251430273 0.5567023158 0.5462480187 + 0.5269926786 0.5585523248 0.5481157899 + 0.5288422704 0.5603957176 0.5499836206 + 0.5306860209 0.5622155070 0.5518401861 + 0.5325195789 0.5640351772 0.5536966920 + 0.5343531966 0.5658550262 0.5555531979 + 0.5361868143 0.5676748157 0.5574097037 + 0.5380203724 0.5694946051 0.5592660904 + 0.5398539901 0.5712903738 0.5611143112 + 0.5416709185 0.5730770826 0.5629572272 + 0.5434862971 0.5748637915 0.5648000240 + 0.5453017950 0.5766503811 0.5666428208 + 0.5471172929 0.5784370899 0.5684856176 + 0.5489326715 0.5802192092 0.5703253746 + 0.5507397056 0.5819697976 0.5721517205 + 0.5525346994 0.5837203264 0.5739780068 + 0.5543295741 0.5854709148 0.5758042932 + 0.5561246276 0.5872213840 0.5776305795 + 0.5579195023 0.5889719725 0.5794569254 + 0.5597143769 0.5907062888 0.5812692046 + 0.5614898801 0.5924177170 0.5830757022 + 0.5632616878 0.5941290259 0.5848821998 + 0.5650333762 0.5958402753 0.5866885781 + 0.5668051839 0.5975517035 0.5884950757 + 0.5685769916 0.5992630124 0.5902976990 + 0.5703436136 0.6009503007 0.5920805931 + 0.5720893145 0.6026192904 0.5938634872 + 0.5738348961 0.6042883992 0.5956465006 + 0.5755805969 0.6059575081 0.5974293947 + 0.5773262978 0.6076264977 0.5992122889 + 0.5790719986 0.6092956066 0.6009799242 + 0.5808039904 0.6109384894 0.6027352214 + 0.5825204849 0.6125624180 0.6044905186 + 0.5842369795 0.6141862273 0.6062458158 + 0.5859534740 0.6158099771 0.6080011725 + 0.5876700282 0.6174339056 0.6097565293 + 0.5893865228 0.6190577149 0.6114842892 + 0.5910822153 0.6206613779 0.6132075787 + 0.5927662849 0.6222372055 0.6149309874 + 0.5944504142 0.6238129735 0.6166543961 + 0.5961344838 0.6253888011 0.6183778048 + 0.5978186131 0.6269646287 0.6200990081 + 0.5995026827 0.6285403967 0.6217858791 + 0.6011615992 0.6301125288 0.6234729290 + 0.6028100848 0.6316378117 0.6251598001 + 0.6044585109 0.6331629753 0.6268466711 + 0.6061068773 0.6346881986 0.6285337210 + 0.6077553034 0.6362134814 0.6302152276 + 0.6094037294 0.6377387047 0.6318612099 + 0.6110271811 0.6392639279 0.6335071921 + 0.6126366854 0.6407619119 0.6351531744 + 0.6142461896 0.6422343254 0.6367992163 + 0.6158555746 0.6437066793 0.6384451985 + 0.6174650788 0.6451790929 0.6400886178 + 0.6190745234 0.6466515064 0.6416891813 + 0.6206660867 0.6481239796 0.6432899237 + 0.6222333908 0.6495963931 0.6448904872 + 0.6238006949 0.6510291100 0.6464911103 + 0.6253681183 0.6524468064 0.6480916739 + 0.6269354224 0.6538646221 0.6496922970 + 0.6285027266 0.6552823186 0.6512529254 + 0.6300681233 0.6567000151 0.6528040171 + 0.6315903068 0.6581177115 0.6543551087 + 0.6331124902 0.6595354080 0.6559062004 + 0.6346346736 0.6609153748 0.6574572921 + 0.6361569166 0.6622769237 0.6590083838 + 0.6376791000 0.6636384726 0.6605402231 + 0.6392014027 0.6650000215 0.6620379090 + 0.6407008171 0.6663615108 0.6635357141 + 0.6421751976 0.6677231193 0.6650334001 + 0.6436495185 0.6690846086 0.6665312052 + 0.6451238990 0.6704273820 0.6680288911 + 0.6465982199 0.6717317104 0.6695266962 + 0.6480726004 0.6730359793 0.6709856987 + 0.6495469213 0.6743403077 0.6724267006 + 0.6509864926 0.6756445765 0.6738678217 + 0.6524105072 0.6769489050 0.6753088832 + 0.6538345814 0.6782531738 0.6767500043 + 0.6552587152 0.6795575023 0.6781910062 + 0.6566827297 0.6808236241 0.6796321273 + 0.6581068039 0.6820700169 0.6810289025 + 0.6595308781 0.6833164096 0.6824105978 + 0.6609197855 0.6845629215 0.6837922931 + 0.6622915864 0.6858093143 0.6851739287 + 0.6636633277 0.6870558262 0.6865556240 + 0.6650350094 0.6883022189 0.6879372001 + 0.6664068103 0.6895486116 0.6893188953 + 0.6677784920 0.6907581091 0.6906694174 + 0.6691501737 0.6919463873 0.6919894814 + 0.6705014110 0.6931347847 0.6933096051 + 0.6718192101 0.6943231821 0.6946297288 + 0.6731368899 0.6955115795 0.6959499121 + 0.6744546890 0.6966999769 0.6972699761 + 0.6757724285 0.6978883743 0.6985900998 + 0.6770902276 0.6990767717 0.6999102235 + 0.6784079075 0.7002522945 0.7011716962 + 0.6797257066 0.7013828754 0.7024288177 + 0.6809998155 0.7025135159 0.7036859989 + 0.6822623014 0.7036440969 0.7049431205 + 0.6835249066 0.7047746778 0.7062003016 + 0.6847875118 0.7059053183 0.7074574232 + 0.6860501170 0.7070358992 0.7087146044 + 0.6873127222 0.7081664801 0.7099717259 + 0.6885753274 0.7092970014 0.7111666203 + 0.6898378730 0.7104060054 0.7123600245 + 0.6910517216 0.7114794254 0.7135534286 + 0.6922584176 0.7125527859 0.7147467732 + 0.6934651136 0.7136262059 0.7159401774 + 0.6946716905 0.7146996260 0.7171337008 + 0.6958783865 0.7157731056 0.7183271050 + 0.6970850825 0.7168465257 0.7195205092 + 0.6982917786 0.7179198861 0.7206757069 + 0.6994984150 0.7189933062 0.7218052745 + 0.7006723285 0.7200632095 0.7229349017 + 0.7018228173 0.7210804224 0.7240644097 + 0.7029731870 0.7220975757 0.7251939774 + 0.7041236758 0.7231147885 0.7263236046 + 0.7052742243 0.7241321206 0.7274531722 + 0.7064247131 0.7251492739 0.7285827994 + 0.7075752020 0.7261664867 0.7297123075 + 0.7087255716 0.7271836996 0.7307947278 + 0.7098761201 0.7282009125 0.7318609953 + 0.7109766006 0.7292181253 0.7329272032 + 0.7120710015 0.7302225828 0.7339934707 + 0.7131654024 0.7311848998 0.7350596786 + 0.7142598033 0.7321472168 0.7361260056 + 0.7153543234 0.7331095934 0.7371922731 + 0.7164487243 0.7340719104 0.7382584810 + 0.7175431252 0.7350342274 0.7393248081 + 0.7186375260 0.7359964848 0.7403681874 + 0.7197319865 0.7369588017 0.7413722277 + 0.7207844853 0.7379211187 0.7423762083 + 0.7218233943 0.7388833761 0.7433801889 + 0.7228623033 0.7398456931 0.7443842292 + 0.7239012122 0.7407631874 0.7453882098 + 0.7249401212 0.7416722178 0.7463921905 + 0.7259790897 0.7425811887 0.7473962903 + 0.7270179987 0.7434902191 0.7484002709 + 0.7280569077 0.7443990707 0.7494043112 + 0.7290958166 0.7453081012 0.7503836155 + 0.7301275730 0.7462170720 0.7513269186 + 0.7311120033 0.7471259832 0.7522702217 + 0.7320963144 0.7480350137 0.7532135248 + 0.7330806255 0.7489439845 0.7541568279 + 0.7340649962 0.7498528957 0.7551000714 + 0.7350493073 0.7507187128 0.7560433745 + 0.7360336185 0.7515761256 0.7569866776 + 0.7370179296 0.7524334788 0.7579299808 + 0.7380023003 0.7532908916 0.7588732839 + 0.7389866114 0.7541484237 0.7598165870 + 0.7399709225 0.7550057769 0.7607126236 + 0.7409034967 0.7558631897 0.7615972161 + 0.7418344021 0.7567206025 0.7624816895 + 0.7427654266 0.7575780153 0.7633662820 + 0.7436963916 0.7584354281 0.7642508149 + 0.7446272969 0.7592927814 0.7651354074 + 0.7455583215 0.7601416111 0.7660198808 + 0.7464892864 0.7609493732 0.7669044733 + 0.7474203110 0.7617571950 0.7677890062 + 0.7483512163 0.7625650167 0.7686735988 + 0.7492821813 0.7633727789 0.7695580721 + 0.7502012849 0.7641806006 0.7704144120 + 0.7510803938 0.7649884224 0.7712424994 + 0.7519595027 0.7657961845 0.7720705271 + 0.7528386712 0.7666041255 0.7728986144 + 0.7537177801 0.7674118876 0.7737267017 + 0.7545968890 0.7682197094 0.7745547295 + 0.7554759979 0.7690274715 0.7753828168 + 0.7563552260 0.7698352933 0.7762109041 + 0.7572342753 0.7706053257 0.7770388722 + 0.7581133842 0.7713655829 0.7778670192 + 0.7589924932 0.7721258998 0.7786949873 + 0.7598717213 0.7728862166 0.7795230746 + 0.7607079744 0.7736464739 0.7803282738 + 0.7615370154 0.7744067907 0.7811022997 + 0.7623659968 0.7751671076 0.7818763852 + 0.7631949782 0.7759273052 0.7826504707 + 0.7640240192 0.7766876221 0.7834246159 + 0.7648531199 0.7774478793 0.7841985822 + 0.7656821012 0.7782081962 0.7849727273 + 0.7665110826 0.7789685130 0.7857468128 + 0.7673401237 0.7797287703 0.7865208983 + 0.7681691051 0.7804598808 0.7872949243 + 0.7689980865 0.7811748981 0.7880690098 + 0.7698271275 0.7818897963 0.7888430953 + 0.7706180215 0.7826048136 0.7896171212 + 0.7713987827 0.7833197117 0.7903652787 + 0.7721796036 0.7840347290 0.7910879850 + 0.7729604244 0.7847496271 0.7918108106 + 0.7737411857 0.7854645848 0.7925335169 + 0.7745220065 0.7861794829 0.7932562828 + 0.7753028274 0.7868943810 0.7939789891 + 0.7760835886 0.7876093984 0.7947018147 + 0.7768645287 0.7883242965 0.7954245210 + 0.7776452899 0.7890393138 0.7961472273 + 0.7784261107 0.7897542119 0.7968699932 + 0.7792068720 0.7904409170 0.7975926995 + 0.7799876928 0.7911127210 0.7983155251 + 0.7807230949 0.7917845249 0.7990381718 + 0.7814577222 0.7924563289 0.7997609973 + 0.7821922898 0.7931280732 0.8004512191 + 0.7829269767 0.7937998772 0.8011254072 + 0.7836616039 0.7944718003 0.8017995954 + 0.7843962908 0.7951436043 0.8024737239 + 0.7851309180 0.7958154082 0.8031479120 + 0.7858656049 0.7964872122 0.8038221002 + 0.7866001725 0.7971590161 0.8044962883 + 0.7873347998 0.7978308201 0.8051704168 + 0.7880694866 0.7985026836 0.8058446050 + 0.7888041139 0.7991744876 0.8065187931 + 0.7895388007 0.7998462915 0.8071929812 + 0.7902569771 0.8004866242 0.8078672290 + 0.7909476161 0.8011174798 0.8085412979 + 0.7916381955 0.8017483950 0.8092154860 + 0.7923287749 0.8023793101 0.8098896742 + 0.7930194139 0.8030102253 0.8105255961 + 0.7937099934 0.8036412001 0.8111540079 + 0.7944005728 0.8042721152 0.8117824197 + 0.7950912118 0.8049029708 0.8124107718 + 0.7957817912 0.8055338860 0.8130391836 + 0.7964723706 0.8061649203 0.8136675954 + 0.7971630096 0.8067957759 0.8142960072 + 0.7978535891 0.8074266911 0.8149244189 + 0.7985442281 0.8080576062 0.8155527711 + 0.7992348075 0.8086885214 0.8161811829 + 0.7999253869 0.8093194962 0.8168095946 + 0.8005787134 0.8099504113 0.8174380064 + 0.8012273908 0.8105456829 0.8180664182 + 0.8018761873 0.8111379147 0.8186947703 + 0.8025249243 0.8117302060 0.8193231821 + 0.8031736016 0.8123223782 0.8199515939 + 0.8038223982 0.8129147291 0.8205404282 + 0.8044710755 0.8135069013 0.8211258054 + 0.8051198125 0.8140991926 0.8217111826 + 0.8057686090 0.8146914244 0.8222966194 + 0.8064172864 0.8152837157 0.8228819966 + 0.8070660233 0.8158758879 0.8234674931 + 0.8077148199 0.8164681792 0.8240528703 + 0.8083634973 0.8170604110 0.8246383071 + 0.8090121746 0.8176527023 0.8252236843 + 0.8096609712 0.8182448745 0.8258091211 + 0.8102908134 0.8188372254 0.8263946176 + 0.8108997941 0.8194293976 0.8269799948 + 0.8115088940 0.8200203776 0.8275653720 + 0.8121178746 0.8205760717 0.8281508088 + 0.8127269745 0.8211318851 0.8287361860 + 0.8133360147 0.8216876984 0.8293216825 + 0.8139451146 0.8222435117 0.8299071193 + 0.8145542145 0.8227992058 0.8304585814 + 0.8151631951 0.8233550191 0.8310037851 + 0.8157722950 0.8239107728 0.8315489888 + 0.8163812757 0.8244665265 0.8320941925 + 0.8169903755 0.8250222802 0.8326392770 + 0.8175994158 0.8255780935 0.8331844807 + 0.8182085156 0.8261339068 0.8337296844 + 0.8188176155 0.8266896009 0.8342748880 + 0.8194265962 0.8272454143 0.8348199725 + 0.8200334907 0.8278012276 0.8353651762 + 0.8206049800 0.8283569217 0.8359103799 + 0.8211765885 0.8289126754 0.8364555836 + 0.8217481971 0.8294684887 0.8370007277 + 0.8223196864 0.8300228119 0.8375458717 + 0.8228912950 0.8305441737 0.8380910754 + 0.8234627843 0.8310655951 0.8386362791 + 0.8240343928 0.8315870166 0.8391814232 + 0.8246060014 0.8321084976 0.8397266269 + 0.8251774907 0.8326299191 0.8402529955 + 0.8257490993 0.8331512809 0.8407605886 + 0.8263205886 0.8336728215 0.8412681818 + 0.8268921971 0.8341941833 0.8417757750 + 0.8274638057 0.8347156048 0.8422834277 + 0.8280352950 0.8352370858 0.8427910209 + 0.8286069036 0.8357585073 0.8432986140 + 0.8291783929 0.8362799287 0.8438062072 + 0.8297500014 0.8368014097 0.8443138003 + 0.8303017020 0.8373227715 0.8448213935 + 0.8308379054 0.8378441930 0.8453289866 + 0.8313741088 0.8383656144 0.8458365798 + 0.8319103122 0.8388870955 0.8463441730 + 0.8324465156 0.8394085169 0.8468517065 + 0.8329827189 0.8399298787 0.8473592997 + 0.8335189223 0.8404234052 0.8478668928 + 0.8340551257 0.8409125805 0.8483744860 + 0.8345913291 0.8414016962 0.8488820791 + 0.8351274729 0.8418908715 0.8493896723 + 0.8356636763 0.8423801064 0.8498973250 + 0.8361998796 0.8428692222 0.8503770232 + 0.8367360830 0.8433583975 0.8508495092 + 0.8372722864 0.8438475132 0.8513221145 + 0.8378084898 0.8443366885 0.8517947197 + 0.8383446932 0.8448258042 0.8522673249 + 0.8388810158 0.8453149796 0.8527398109 + 0.8394172192 0.8458042145 0.8532124162 + 0.8399534225 0.8462932706 0.8536850214 + 0.8404592276 0.8467825055 0.8541575074 + 0.8409621119 0.8472716212 0.8546301126 + 0.8414651155 0.8477607965 0.8551027179 + 0.8419679999 0.8482499719 0.8555753231 + 0.8424710035 0.8487390876 0.8560478091 + 0.8429738879 0.8492283225 0.8565204144 + 0.8434768915 0.8497173786 0.8569930196 + 0.8439797759 0.8501937985 0.8574656248 + 0.8444827199 0.8506526947 0.8579381108 + 0.8449857235 0.8511115909 0.8584107161 + 0.8454886079 0.8515704274 0.8588833213 + 0.8459916115 0.8520293236 0.8593558073 + 0.8464944959 0.8524882197 0.8598284125 + 0.8469973803 0.8529471159 0.8602802157 + 0.8475003839 0.8534058928 0.8607202172 + 0.8480033278 0.8538647890 0.8611602187 + 0.8485062718 0.8543236852 0.8616002202 + 0.8490092158 0.8547825813 0.8620402217 + 0.8495122194 0.8552414775 0.8624802232 + 0.8500142097 0.8557003140 0.8629202247 + 0.8504859209 0.8561592102 0.8633602262 + 0.8509575725 0.8566181064 0.8638002276 + 0.8514292836 0.8570770025 0.8642402291 + 0.8519009948 0.8575357795 0.8646801710 + 0.8523727059 0.8579946756 0.8651201725 + 0.8528444171 0.8584535718 0.8655601740 + 0.8533161283 0.8589125276 0.8660001755 + 0.8537877798 0.8593714237 0.8664401770 + 0.8542594910 0.8598302007 0.8668801785 + 0.8547312021 0.8602712154 0.8673201799 + 0.8552029133 0.8607016802 0.8677601814 + 0.8556746244 0.8611322045 0.8682001829 + 0.8561462760 0.8615627289 0.8686401844 + 0.8566179872 0.8619931936 0.8690801859 + 0.8570896983 0.8624237180 0.8695201874 + 0.8575614095 0.8628543019 0.8699601889 + 0.8580331206 0.8632848263 0.8703727126 + 0.8585047722 0.8637152910 0.8707824945 + 0.8589764833 0.8641458154 0.8711922169 + 0.8594481945 0.8645762801 0.8716019988 + 0.8599199057 0.8650068045 0.8720117211 + 0.8603671789 0.8654373288 0.8724213839 + 0.8608096838 0.8658677936 0.8728312254 + 0.8612521291 0.8662983179 0.8732408881 + 0.8616945148 0.8667287827 0.8736507297 + 0.8621369004 0.8671593070 0.8740603924 + 0.8625792861 0.8675897717 0.8744701743 + 0.8630216718 0.8680202961 0.8748798966 + 0.8634641171 0.8684508204 0.8752896786 + 0.8639065027 0.8688812852 0.8756994009 + 0.8643488884 0.8693118095 0.8761091828 + 0.8647912741 0.8697422743 0.8765189052 + 0.8652337193 0.8701621294 0.8769286275 + 0.8656761050 0.8705661297 0.8773384094 + 0.8661184907 0.8709700108 0.8777480721 + 0.8665608764 0.8713740110 0.8781579137 + 0.8670033216 0.8717778921 0.8785675764 + 0.8674457073 0.8721818924 0.8789774179 + 0.8678880930 0.8725857735 0.8793870807 + 0.8683304787 0.8729897141 0.8797969222 + 0.8687729239 0.8733937144 0.8801925182 + 0.8692153096 0.8737975955 0.8805741072 + 0.8696576953 0.8742015958 0.8809558153 + 0.8700938821 0.8746054769 0.8813375235 + 0.8705089092 0.8750094771 0.8817191720 + 0.8709238768 0.8754134178 0.8821008801 + 0.8713387847 0.8758172989 0.8824825287 + 0.8717538118 0.8762212992 0.8828641772 + 0.8721687198 0.8766251802 0.8832458854 + 0.8725836873 0.8770291805 0.8836275935 + 0.8729987144 0.8774331212 0.8840093017 + 0.8734136224 0.8778371215 0.8843908906 + 0.8738285899 0.8782410026 0.8847725987 + 0.8742436171 0.8786448836 0.8851543069 + 0.8746585250 0.8790488839 0.8855360150 + 0.8750734925 0.8794528246 0.8859177232 + 0.8754885197 0.8798568249 0.8862993121 + 0.8759034276 0.8802446723 0.8866810203 + 0.8763183951 0.8806238174 0.8870627284 + 0.8767334223 0.8810029030 0.8874443769 + 0.8771482706 0.8813819885 0.8878260255 + 0.8775632977 0.8817610741 0.8882076740 + 0.8779783249 0.8821402192 0.8885893822 + 0.8783931732 0.8825193048 0.8889710903 + 0.8788082004 0.8828983903 0.8893527985 + 0.8792232275 0.8832774758 0.8897343874 + 0.8796380758 0.8836566210 0.8901082277 + 0.8800498247 0.8840357065 0.8904638886 + 0.8804391026 0.8844147921 0.8908194900 + 0.8808283806 0.8847938776 0.8911752105 + 0.8812177181 0.8851730227 0.8915308714 + 0.8816069961 0.8855521083 0.8918864727 + 0.8819962740 0.8859311938 0.8922421932 + 0.8823856115 0.8863102794 0.8925979137 + 0.8827748895 0.8866894245 0.8929535151 + 0.8831642270 0.8870685101 0.8933091760 + 0.8835535049 0.8874475956 0.8936648965 + 0.8839427233 0.8878266811 0.8940204978 + 0.8843320012 0.8882058263 0.8943762183 + 0.8847212791 0.8885849118 0.8947318792 + 0.8851106167 0.8889639974 0.8950874805 + 0.8854998946 0.8893430829 0.8954432011 + 0.8858891726 0.8897222877 0.8957989216 + 0.8862785101 0.8900951147 0.8961545229 + 0.8866677880 0.8904510140 0.8965101838 + 0.8870571256 0.8908069134 0.8968659043 + 0.8874464035 0.8911628127 0.8972215056 + 0.8878356814 0.8915187120 0.8975772262 + 0.8882250190 0.8918746114 0.8979328871 + 0.8886142969 0.8922305107 0.8982884884 + 0.8890035748 0.8925864100 0.8986442089 + 0.8893929124 0.8929423094 0.8989998102 + 0.8897821903 0.8932980895 0.8993554711 + 0.8901609182 0.8936539888 0.8997111917 + 0.8905261755 0.8940098882 0.9000623226 + 0.8908914924 0.8943657875 0.9003939033 + 0.8912568092 0.8947216868 0.9007254839 + 0.8916221261 0.8950775862 0.9010570049 + 0.8919873834 0.8954334855 0.9013885856 + 0.8923527002 0.8957893848 0.9017202258 + 0.8927180171 0.8961452842 0.9020516872 + 0.8930832744 0.8965011239 0.9023833275 + 0.8934485912 0.8968570232 0.9027149081 + 0.8938139081 0.8972129226 0.9030464888 + 0.8941792250 0.8975688219 0.9033780098 + 0.8945444822 0.8979247212 0.9037095904 + 0.8949097991 0.8982806206 0.9040411711 + 0.8952751160 0.8986365199 0.9043726921 + 0.8956403732 0.8989924192 0.9047042727 + 0.8960056901 0.8993481994 0.9050359130 + 0.8963710070 0.8997040987 0.9053673744 + 0.8967363238 0.9000564218 0.9056990147 + 0.8971015811 0.9003906250 0.9060305953 + 0.8974668980 0.9007248282 0.9063621759 + 0.8978322148 0.9010589719 0.9066936970 + 0.8981974721 0.9013931751 0.9070252776 + 0.8985627890 0.9017273784 0.9073569179 + 0.8989281058 0.9020615816 0.9076883793 + 0.8992933035 0.9023957849 0.9080200195 + 0.8996586204 0.9027299881 0.9083516002 + 0.9000225067 0.9030641913 0.9086831808 + 0.9003654122 0.9033983946 0.9090147018 + 0.9007081985 0.9037325978 0.9093462825 + 0.9010511041 0.9040668011 0.9096779227 + 0.9013940096 0.9044010043 0.9100087881 + 0.9017369151 0.9047352076 0.9103180766 + 0.9020798206 0.9050694108 0.9106273055 + 0.9024227262 0.9054036140 0.9109365940 + 0.9027655125 0.9057378173 0.9112458825 + 0.9031084180 0.9060720801 0.9115551114 + 0.9034513235 0.9064062834 0.9118643999 + 0.9037942290 0.9067404866 0.9121736884 + 0.9041370749 0.9070746899 0.9124829173 + 0.9044799805 0.9074088931 0.9127922058 + 0.9048228264 0.9077430964 0.9131013751 + 0.9051656723 0.9080772996 0.9134107232 + 0.9055085778 0.9084115028 0.9137200117 + 0.9058514833 0.9087457061 0.9140291810 + 0.9061943889 0.9090799093 0.9143385291 + 0.9065371752 0.9094141126 0.9146478176 + 0.9068800807 0.9097483158 0.9149569869 + 0.9072229862 0.9100775123 0.9152662754 + 0.9075658917 0.9103915095 0.9155756235 + 0.9079087973 0.9107053876 0.9158847928 + 0.9082517028 0.9110193849 0.9161940813 + 0.9085944891 0.9113333821 0.9165033102 + 0.9089373946 0.9116473198 0.9168125987 + 0.9092803001 0.9119613171 0.9171218872 + 0.9096232057 0.9122751951 0.9174311161 + 0.9099661112 0.9125891924 0.9177404046 + 0.9102901220 0.9129031897 0.9180496931 + 0.9106121063 0.9132171273 0.9183589220 + 0.9109339714 0.9135311246 0.9186682105 + 0.9112560153 0.9138450027 0.9189774990 + 0.9115778804 0.9141589999 0.9192867279 + 0.9118999243 0.9144729972 0.9195960164 + 0.9122217894 0.9147868752 0.9199051857 + 0.9125437737 0.9151008725 0.9202002287 + 0.9128656983 0.9154148102 0.9204887748 + 0.9131876826 0.9157288074 0.9207773805 + 0.9135096073 0.9160428047 0.9210659862 + 0.9138315916 0.9163566828 0.9213547111 + 0.9141535759 0.9166706800 0.9216433167 + 0.9144755006 0.9169846177 0.9219319224 + 0.9147974849 0.9172986150 0.9222205281 + 0.9151194096 0.9176126122 0.9225090742 + 0.9154413939 0.9179264903 0.9227977991 + 0.9157633185 0.9182404876 0.9230864048 + 0.9160853028 0.9185544252 0.9233750105 + 0.9164072275 0.9188684225 0.9236636162 + 0.9167292118 0.9191824198 0.9239522219 + 0.9170510769 0.9194962978 0.9242408276 + 0.9173731208 0.9198102951 0.9245294929 + 0.9176951051 0.9201167822 0.9248180985 + 0.9180170298 0.9204118252 0.9251067042 + 0.9183390141 0.9207069278 0.9253953099 + 0.9186608791 0.9210019112 0.9256839156 + 0.9189829230 0.9212970138 0.9259725809 + 0.9193047881 0.9215921164 0.9262611866 + 0.9196267724 0.9218870997 0.9265497923 + 0.9199486971 0.9221822023 0.9268383980 + 0.9202542901 0.9224773049 0.9271270037 + 0.9205567241 0.9227722883 0.9274156094 + 0.9208590984 0.9230673909 0.9277042747 + 0.9211614728 0.9233623743 0.9279928803 + 0.9214640260 0.9236574769 0.9282814860 + 0.9217664003 0.9239525795 0.9285700917 + 0.9220687747 0.9242476225 0.9288586974 + 0.9223712087 0.9245427251 0.9291474223 + 0.9226737022 0.9248378277 0.9294360280 + 0.9229760766 0.9251328111 0.9297245741 + 0.9232785106 0.9254279137 0.9300122857 + 0.9235808849 0.9257230163 0.9302818179 + 0.9238833189 0.9260179996 0.9305514097 + 0.9241858125 0.9263131022 0.9308208823 + 0.9244881868 0.9266080856 0.9310904145 + 0.9247906208 0.9269031882 0.9313598871 + 0.9250929952 0.9271982908 0.9316294193 + 0.9253954887 0.9274932742 0.9318988919 + 0.9256979227 0.9277883768 0.9321684241 + 0.9260002971 0.9280834794 0.9324380159 + 0.9263026714 0.9283785224 0.9327074885 + 0.9266052246 0.9286736250 0.9329770207 + 0.9269075990 0.9289686084 0.9332464933 + 0.9272099733 0.9292637110 0.9335160255 + 0.9275124073 0.9295588136 0.9337854981 + 0.9278147817 0.9298537970 0.9340549707 + 0.9281172752 0.9301400185 0.9343245029 + 0.9284197092 0.9304174185 0.9345940948 + 0.9287220836 0.9306948781 0.9348636270 + 0.9290245175 0.9309722781 0.9351330996 + 0.9293270111 0.9312496781 0.9354025722 + 0.9296293855 0.9315270782 0.9356721044 + 0.9299318194 0.9318045974 0.9359415770 + 0.9302201271 0.9320819974 0.9362111092 + 0.9305043221 0.9323593974 0.9364805818 + 0.9307885170 0.9326369166 0.9367501736 + 0.9310727119 0.9329143167 0.9370197058 + 0.9313569069 0.9331917167 0.9372891784 + 0.9316411018 0.9334691167 0.9375587106 + 0.9319252968 0.9337465763 0.9378281832 + 0.9322094917 0.9340239763 0.9380977154 + 0.9324936867 0.9343013763 0.9383671880 + 0.9327778816 0.9345787764 0.9386367202 + 0.9330620766 0.9348562956 0.9389063120 + 0.9333462715 0.9351336956 0.9391757846 + 0.9336305261 0.9354110956 0.9394453168 + 0.9339147210 0.9356886148 0.9397147894 + 0.9341989160 0.9359660149 0.9399843216 + 0.9344831109 0.9362434149 0.9402372241 + 0.9347673059 0.9365208149 0.9404889941 + 0.9350515008 0.9367982745 0.9407408237 + 0.9353356957 0.9370756745 0.9409927130 + 0.9356198907 0.9373530746 0.9412444830 + 0.9359040856 0.9376305938 0.9414963126 + 0.9361882806 0.9379079938 0.9417482018 + 0.9364724755 0.9381853938 0.9419999719 + 0.9367566705 0.9384627938 0.9422518015 + 0.9370409250 0.9387403131 0.9425036907 + 0.9373251200 0.9390177131 0.9427555203 + 0.9376093149 0.9392951131 0.9430072904 + 0.9378935099 0.9395725727 0.9432591796 + 0.9381777048 0.9398499727 0.9435110092 + 0.9384618998 0.9401198030 0.9437627792 + 0.9387460947 0.9403808117 0.9440147281 + 0.9390302896 0.9406418204 0.9442664981 + 0.9393144846 0.9409028292 0.9445183277 + 0.9395986795 0.9411637187 0.9447702169 + 0.9398828745 0.9414247274 0.9450219870 + 0.9401571155 0.9416856766 0.9452738166 + 0.9404243231 0.9419466257 0.9455257058 + 0.9406914711 0.9422075748 0.9457774758 + 0.9409586787 0.9424685836 0.9460293055 + 0.9412258863 0.9427295923 0.9462810755 + 0.9414930940 0.9429904819 0.9465330243 + 0.9417603016 0.9432514906 0.9467847943 + 0.9420275092 0.9435124993 0.9470366240 + 0.9422945976 0.9437733889 0.9472885132 + 0.9425618052 0.9440343976 0.9475402832 + 0.9428290129 0.9442954063 0.9477921128 + 0.9430962205 0.9445564151 0.9480440021 + 0.9433634281 0.9448173046 0.9482957721 + 0.9436305761 0.9450783134 0.9485476017 + 0.9438977838 0.9453393221 0.9487994909 + 0.9441649914 0.9456002116 0.9490513206 + 0.9444321990 0.9458612204 0.9493030906 + 0.9446994066 0.9461222291 0.9495549798 + 0.9449666142 0.9463831782 0.9498068094 + 0.9452338219 0.9466441274 0.9500548244 + 0.9455010295 0.9469050765 0.9502903223 + 0.9457681775 0.9471660852 0.9505258203 + 0.9460353851 0.9474269748 0.9507611990 + 0.9463025928 0.9476879835 0.9509966969 + 0.9465698004 0.9479489923 0.9512321949 + 0.9468370080 0.9482100010 0.9514675736 + 0.9471042156 0.9484708905 0.9517030716 + 0.9473714232 0.9487318993 0.9519386292 + 0.9476385713 0.9489929080 0.9521741271 + 0.9479057789 0.9492537975 0.9524095058 + 0.9481729865 0.9495148063 0.9526450038 + 0.9484401941 0.9497758150 0.9528805017 + 0.9487074018 0.9500346184 0.9531158805 + 0.9489746094 0.9502801895 0.9533513784 + 0.9492418170 0.9505258203 0.9535868764 + 0.9495090246 0.9507713914 0.9538223147 + 0.9497761726 0.9510170221 0.9540578127 + 0.9500408173 0.9512627125 0.9542933106 + 0.9502921104 0.9515082836 0.9545286894 + 0.9505435228 0.9517539144 0.9547641873 + 0.9507948160 0.9519994855 0.9549996853 + 0.9510461092 0.9522451162 0.9552351832 + 0.9512975216 0.9524906874 0.9554706216 + 0.9515488148 0.9527363181 0.9557061195 + 0.9518002272 0.9529820085 0.9559416175 + 0.9520515203 0.9532275796 0.9561769962 + 0.9523028135 0.9534732103 0.9564124942 + 0.9525542259 0.9537187815 0.9566479921 + 0.9528055191 0.9539644122 0.9568833709 + 0.9530568123 0.9542099833 0.9571189284 + 0.9533082247 0.9544556141 0.9573544264 + 0.9535595179 0.9547013044 0.9575898051 + 0.9538108110 0.9549468756 0.9578253031 + 0.9540622234 0.9551925063 0.9580608010 + 0.9543135166 0.9554380774 0.9582962990 + 0.9545649290 0.9556837082 0.9585316777 + 0.9548162222 0.9559292793 0.9587671757 + 0.9550675154 0.9561749101 0.9590026736 + 0.9553189278 0.9564206004 0.9592381120 + 0.9555702209 0.9566661716 0.9594736099 + 0.9558215141 0.9569118023 0.9597091079 + 0.9560729265 0.9571573734 0.9599444866 + 0.9563242197 0.9574030042 0.9601684213 + 0.9565755725 0.9576485753 0.9603887796 + 0.9568269253 0.9578942060 0.9606090784 + 0.9570782185 0.9581398964 0.9608293772 + 0.9573295712 0.9583855271 0.9610496759 + 0.9575809240 0.9586310983 0.9612699747 + 0.9578322172 0.9588767290 0.9614903927 + 0.9580836296 0.9591223001 0.9617106915 + 0.9583349228 0.9593678713 0.9619309902 + 0.9585862160 0.9596135020 0.9621512890 + 0.9588376284 0.9598590732 0.9623715878 + 0.9590889215 0.9600986838 0.9625920057 + 0.9593402743 0.9603298903 0.9628123045 + 0.9595916271 0.9605612159 0.9630326033 + 0.9598429203 0.9607924819 0.9632529020 + 0.9600886703 0.9610238075 0.9634733200 + 0.9603253007 0.9612550735 0.9636936188 + 0.9605618119 0.9614862800 0.9639139175 + 0.9607983232 0.9617176056 0.9641342163 + 0.9610348940 0.9619488716 0.9643545151 + 0.9612714052 0.9621801972 0.9645748734 + 0.9615079761 0.9624115229 0.9647951722 + 0.9617444873 0.9626427293 0.9650154710 + 0.9619809985 0.9628739953 0.9652358294 + 0.9622176290 0.9631053209 0.9654561877 + 0.9624540806 0.9633365870 0.9656764865 + 0.9626907110 0.9635679126 0.9658967853 + 0.9629272223 0.9637991190 0.9661170840 + 0.9631636739 0.9640303850 0.9663373828 + 0.9634003043 0.9642617106 0.9665578008 + 0.9636368155 0.9644929767 0.9667780995 + 0.9638733864 0.9647243023 0.9669983983 + 0.9641098976 0.9649556279 0.9672186971 + 0.9643464088 0.9651867747 0.9674391150 + 0.9645829797 0.9654181004 0.9676594138 + 0.9648194909 0.9656494260 0.9678797126 + 0.9650561213 0.9658806920 0.9681000113 + 0.9652925730 0.9661120176 0.9683203101 + 0.9655292034 0.9663432240 0.9685407281 + 0.9657657146 0.9665744901 0.9687610269 + 0.9660022259 0.9668058157 0.9689813256 + 0.9662387967 0.9670370817 0.9692016244 + 0.9664753079 0.9672684073 0.9694219232 + 0.9667118788 0.9674996138 0.9696422815 + 0.9669483900 0.9677308798 0.9698625803 + 0.9671849012 0.9679622054 0.9700775743 + 0.9674214721 0.9681934714 0.9702839255 + 0.9676579833 0.9684247971 0.9704902172 + 0.9678946137 0.9686561227 0.9706965089 + 0.9681311250 0.9688873291 0.9709028006 + 0.9683675766 0.9691185951 0.9711090922 + 0.9686042070 0.9693499207 0.9713153839 + 0.9688407183 0.9695811868 0.9715216756 + 0.9690772891 0.9698125124 0.9717280269 + 0.9693138003 0.9700412154 0.9719343185 + 0.9695503116 0.9702590704 0.9721406102 + 0.9697868824 0.9704769850 0.9723469019 + 0.9700220823 0.9706948996 0.9725531936 + 0.9702448249 0.9709128141 0.9727594852 + 0.9704675078 0.9711307287 0.9729657769 + 0.9706903100 0.9713485837 0.9731721282 + 0.9709129930 0.9715664983 0.9733784199 + 0.9711356759 0.9717844129 0.9735847116 + 0.9713584781 0.9720023274 0.9737908840 + 0.9715812206 0.9722201824 0.9739971757 + 0.9718039036 0.9724380970 0.9742035270 + 0.9720267057 0.9726560116 0.9744098186 + 0.9722493887 0.9728739262 0.9746161103 + 0.9724720716 0.9730917811 0.9748224020 + 0.9726948738 0.9733096957 0.9750286937 + 0.9729176164 0.9735276103 0.9752349854 + 0.9731402993 0.9737455845 0.9754412770 + 0.9733631015 0.9739634991 0.9756476283 + 0.9735857844 0.9741814137 0.9758539200 + 0.9738085270 0.9743993282 0.9760602117 + 0.9740313292 0.9746171832 0.9762665033 + 0.9742540121 0.9748350978 0.9764727950 + 0.9744768143 0.9750530124 0.9766790867 + 0.9746994972 0.9752709270 0.9768853784 + 0.9749221802 0.9754887819 0.9770917296 + 0.9751449823 0.9757066965 0.9772980213 + 0.9753677249 0.9759246111 0.9775043130 + 0.9755904078 0.9761425257 0.9777106047 + 0.9758132100 0.9763603806 0.9779168963 + 0.9760358930 0.9765782952 0.9781231284 + 0.9762585759 0.9767962098 0.9783294201 + 0.9764813781 0.9770141244 0.9785357118 + 0.9767041206 0.9772319794 0.9787420034 + 0.9769268036 0.9774498940 0.9789482951 + 0.9771496058 0.9776678085 0.9791545868 + 0.9773722887 0.9778857231 0.9793608785 + 0.9775949717 0.9781035781 0.9795672297 + 0.9778177738 0.9783214927 0.9797735214 + 0.9780405164 0.9785394073 0.9799798131 + 0.9782631993 0.9787573218 0.9801744223 + 0.9784860015 0.9789751768 0.9803677201 + 0.9787086844 0.9791930914 0.9805610180 + 0.9789314270 0.9794110060 0.9807543159 + 0.9791542292 0.9796289206 0.9809476137 + 0.9793769121 0.9798467755 0.9811409116 + 0.9795997143 0.9800609946 0.9813342094 + 0.9798223972 0.9802663922 0.9815275073 + 0.9800425172 0.9804717898 0.9817208052 + 0.9802523851 0.9806771874 0.9819141030 + 0.9804621935 0.9808827043 0.9821074009 + 0.9806721210 0.9810881019 0.9823006988 + 0.9808819294 0.9812934995 0.9824939966 + 0.9810917974 0.9814988971 0.9826872945 + 0.9813016057 0.9817042947 0.9828805923 + 0.9815114737 0.9819096923 0.9830738902 + 0.9817212820 0.9821150899 0.9832671881 + 0.9819312096 0.9823204875 0.9834604859 + 0.9821410179 0.9825258851 0.9836537838 + 0.9823508859 0.9827314019 0.9838470817 + 0.9825606942 0.9829367995 0.9840403795 + 0.9827706218 0.9831421971 0.9842336774 + 0.9829803705 0.9833475947 0.9844269753 + 0.9831902981 0.9835529923 0.9846202731 + 0.9834001064 0.9837583899 0.9848135710 + 0.9836099744 0.9839637876 0.9850069284 + 0.9838197827 0.9841691852 0.9852002263 + 0.9840297103 0.9843745828 0.9853935242 + 0.9842395186 0.9845800996 0.9855868220 + 0.9844493866 0.9847854972 0.9857801199 + 0.9846591949 0.9849908948 0.9859734178 + 0.9848691225 0.9851962924 0.9861667156 + 0.9850788713 0.9854016900 0.9863600135 + 0.9852887988 0.9856070876 0.9865533113 + 0.9854986072 0.9858124852 0.9867466092 + 0.9857084751 0.9860178828 0.9869399071 + 0.9859182835 0.9862232804 0.9871332049 + 0.9861282110 0.9864287972 0.9873265028 + 0.9863380194 0.9866341949 0.9875198007 + 0.9865478873 0.9868395925 0.9877130985 + 0.9867578149 0.9870449901 0.9879063964 + 0.9869676232 0.9872503877 0.9880996943 + 0.9871774912 0.9874557853 0.9882929921 + 0.9873872995 0.9876611829 0.9884862900 + 0.9875972271 0.9878665805 0.9886795878 + 0.9878069758 0.9880719781 0.9888730049 + 0.9880169034 0.9882774949 0.9890663028 + 0.9882267118 0.9884828925 0.9892596006 + 0.9884365797 0.9886882901 0.9894528985 + 0.9886463881 0.9888936877 0.9896461964 + 0.9888563156 0.9890990853 0.9898394942 + 0.9890661240 0.9893044829 0.9900307059 + 0.9892759919 0.9895098805 0.9902120233 + 0.9894858003 0.9897152781 0.9903932214 + 0.9896957278 0.9899206758 0.9905744791 + 0.9899054766 0.9901189804 0.9907557964 + 0.9901087880 0.9903126955 0.9909369946 + 0.9903066158 0.9905064702 0.9911183119 + 0.9905043840 0.9907001853 0.9912995100 + 0.9907022119 0.9908940196 0.9914808273 + 0.9909000993 0.9910876751 0.9916620851 + 0.9910979271 0.9912815094 0.9918432832 + 0.9912956953 0.9914752245 0.9920246005 + 0.9914935231 0.9916689992 0.9922057986 + 0.9916914105 0.9918627143 0.9923871160 + 0.9918891788 0.9920564294 0.9925683737 + 0.9920870066 0.9922502041 0.9927495718 + 0.9922847748 0.9924439192 0.9929308891 + 0.9924827218 0.9926376939 0.9931120872 + 0.9926804900 0.9928314090 0.9932934046 + 0.9928783178 0.9930251837 0.9934747219 + 0.9930760860 0.9932188988 0.9936559200 + 0.9932739735 0.9934126735 0.9938371778 + 0.9934718013 0.9936063886 0.9940183759 + 0.9936696291 0.9938002229 0.9941996932 + 0.9938673973 0.9939938784 0.9943810105 + 0.9940652847 0.9941875935 0.9945622087 + 0.9942631125 0.9943814278 0.9947435260 + 0.9944608808 0.9945750833 0.9949247241 + 0.9946587086 0.9947689176 0.9951059818 + 0.9948565960 0.9949625731 0.9952871799 + 0.9950544238 0.9951564074 0.9954684973 + 0.9952521920 0.9953501225 0.9956498146 + 0.9954500198 0.9955438972 0.9958310127 + 0.9956479073 0.9957376122 0.9960122705 + 0.9958456755 0.9959313273 0.9961935282 + 0.9960435033 0.9961251020 0.9963747859 + 0.9962412715 0.9963188171 0.9965561032 + 0.9964392185 0.9965125918 0.9967373013 + 0.9966369867 0.9967063069 0.9969186187 + 0.9968348145 0.9969000816 0.9970998168 + 0.9970325828 0.9970937967 0.9972810745 + 0.9972305298 0.9972875714 0.9974623919 + 0.9974282980 0.9974812865 0.9976435900 + 0.9976261258 0.9976751208 0.9978249073 + 0.9978238940 0.9978687763 0.9980061054 + 0.9980217814 0.9980624914 0.9981874228 + 0.9982196093 0.9982563257 0.9983686805 + 0.9984173775 0.9984499812 0.9985498786 + 0.9986152053 0.9986438155 0.9987311959 + 0.9988130927 0.9988374710 0.9989123940 + 0.9990109205 0.9990313053 0.9990937114 + 0.9992086887 0.9992250204 0.9992750287 + 0.9994065166 0.9994187951 0.9994562268 + 0.9996044040 0.9996125102 0.9996374846 + 0.9998021722 0.9998062849 0.9998186827 + 1.0000000000 1.0000000000 1.0000000000 +} diff --git a/rpplugins/color_correction/resources/film_luts_raw/kodak_dscs_3154.spi1d b/rpplugins/color_correction/resources/film_luts_raw/kodak_dscs_3154.spi1d new file mode 100644 index 0000000..9810d26 --- /dev/null +++ b/rpplugins/color_correction/resources/film_luts_raw/kodak_dscs_3154.spi1d @@ -0,0 +1,1030 @@ +Version 1 +From 0.0 1.0 +Length 1024 +Components 3 +{ + 0.0000000000 0.0000000000 0.0000000000 + 0.0008270687 0.0012806139 0.0007092019 + 0.0016541370 0.0025612270 0.0014184040 + 0.0024812061 0.0038418409 0.0021276060 + 0.0033082750 0.0051224548 0.0028368081 + 0.0041353442 0.0064030681 0.0035460100 + 0.0049624122 0.0076836818 0.0042552119 + 0.0057894811 0.0089642964 0.0049644141 + 0.0066165500 0.0102737201 0.0056736148 + 0.0074436190 0.0117049702 0.0063828169 + 0.0082706874 0.0131362099 0.0070920191 + 0.0090977559 0.0145674599 0.0078012212 + 0.0099248253 0.0159987099 0.0085104229 + 0.0108320098 0.0174299609 0.0092196250 + 0.0117472196 0.0188612100 0.0099288272 + 0.0126624200 0.0203272700 0.0107055604 + 0.0135776196 0.0219289195 0.0114898197 + 0.0144928200 0.0235305596 0.0122740902 + 0.0154080195 0.0251322109 0.0130583504 + 0.0163232200 0.0267338492 0.0138426097 + 0.0172384195 0.0283354893 0.0146268802 + 0.0181536209 0.0299371406 0.0154111404 + 0.0190688204 0.0317234285 0.0161953997 + 0.0199840199 0.0335172787 0.0169796702 + 0.0209966209 0.0353111215 0.0177639294 + 0.0220109392 0.0371049605 0.0185481999 + 0.0230252706 0.0388987996 0.0193324592 + 0.0240395907 0.0407759696 0.0201293100 + 0.0250539202 0.0427856296 0.0209981594 + 0.0260682497 0.0447952896 0.0218669996 + 0.0270825699 0.0468049496 0.0227358509 + 0.0280968994 0.0488146096 0.0236046892 + 0.0291112196 0.0509230010 0.0244735405 + 0.0301393494 0.0531734005 0.0253423806 + 0.0312651210 0.0554237999 0.0262112301 + 0.0323909000 0.0576741993 0.0270800795 + 0.0335166790 0.0599245988 0.0279489197 + 0.0346424617 0.0624321401 0.0288177691 + 0.0357682407 0.0649486035 0.0296866093 + 0.0368940197 0.0674650520 0.0306164194 + 0.0380197987 0.0699815080 0.0315806195 + 0.0391455814 0.0727861822 0.0325448215 + 0.0403015316 0.0755929798 0.0335090198 + 0.0415524915 0.0783997923 0.0344732217 + 0.0428034514 0.0813405216 0.0354374312 + 0.0440544114 0.0844588801 0.0364016294 + 0.0453053713 0.0875772387 0.0373658314 + 0.0465563312 0.0907685384 0.0383300297 + 0.0478072912 0.0942139179 0.0392942317 + 0.0490582511 0.0976593122 0.0402872488 + 0.0503439009 0.1012116969 0.0413589515 + 0.0517351814 0.1049906015 0.0424306504 + 0.0531264618 0.1087696031 0.0435023494 + 0.0545177385 0.1127699018 0.0445740595 + 0.0559090301 0.1168769971 0.0456457585 + 0.0573003106 0.1210578978 0.0467174612 + 0.0586915910 0.1254729033 0.0477891602 + 0.0600922108 0.1298878938 0.0488608703 + 0.0616402999 0.1345676035 0.0499325693 + 0.0631883815 0.1392543018 0.0511177592 + 0.0647364631 0.1441261023 0.0523105711 + 0.0662845522 0.1490330994 0.0535033792 + 0.0678326264 0.1540661007 0.0546961986 + 0.0693807229 0.1591300964 0.0558890104 + 0.0710334405 0.1642663032 0.0570818186 + 0.0727559403 0.1694173962 0.0582746305 + 0.0744784400 0.1745833009 0.0594674386 + 0.0762009397 0.1797512025 0.0607356615 + 0.0779234320 0.1848731041 0.0620646887 + 0.0796459317 0.1899926066 0.0633937269 + 0.0815215707 0.1950089037 0.0647227690 + 0.0834368318 0.2000242025 0.0660518110 + 0.0853521004 0.2048937976 0.0673808381 + 0.0872673616 0.2097633928 0.0687098801 + 0.0891826227 0.2144646943 0.0700433925 + 0.0912189633 0.2191573977 0.0715252534 + 0.0933454409 0.2236897051 0.0730071068 + 0.0954719111 0.2281869054 0.0744889826 + 0.0975983888 0.2325620949 0.0759708434 + 0.0997248664 0.2368548959 0.0774526969 + 0.1020506024 0.2410928011 0.0789345577 + 0.1044057980 0.2451802045 0.0804644004 + 0.1067610979 0.2492675036 0.0821170136 + 0.1091163978 0.2531898916 0.0837696269 + 0.1116243005 0.2570762932 0.0854222402 + 0.1142238006 0.2609150112 0.0870748535 + 0.1168233976 0.2646088004 0.0887274593 + 0.1194228977 0.2683025002 0.0904237032 + 0.1222214997 0.2718980014 0.0922659934 + 0.1250769049 0.2754099071 0.0941082835 + 0.1279322952 0.2789216936 0.0959505737 + 0.1308598965 0.2823159099 0.0977928713 + 0.1339771003 0.2856579125 0.0996351615 + 0.1370943040 0.2889998853 0.1016450971 + 0.1402291059 0.2922315896 0.1036963984 + 0.1436063051 0.2954162955 0.1057477966 + 0.1469835043 0.2986010015 0.1077990979 + 0.1503873020 0.3017044067 0.1098503992 + 0.1540133953 0.3047442138 0.1121131033 + 0.1576395929 0.3077841103 0.1143923029 + 0.1613450944 0.3107880056 0.1166715994 + 0.1651988029 0.3136951029 0.1189509034 + 0.1690524071 0.3166022003 0.1213624030 + 0.1730536968 0.3195092976 0.1238868013 + 0.1771031022 0.3223156929 0.1264111996 + 0.1811967939 0.3251017034 0.1289356053 + 0.1854016036 0.3278875947 0.1316096932 + 0.1896062940 0.3306469023 0.1343929023 + 0.1939094067 0.3333224058 0.1371762007 + 0.1982226968 0.3359979987 0.1399594992 + 0.2025707066 0.3386735022 0.1430062056 + 0.2069430053 0.3412984908 0.1460568011 + 0.2113184035 0.3438735902 0.1491073966 + 0.2157011032 0.3464488089 0.1523478031 + 0.2200832069 0.3490239978 0.1556666940 + 0.2244319022 0.3515425920 0.1589855999 + 0.2287805974 0.3540267050 0.1624847949 + 0.2330776006 0.3565106988 0.1660633981 + 0.2373543978 0.3589948118 0.1696420014 + 0.2415924072 0.3614296019 0.1734369993 + 0.2457672954 0.3638310134 0.1772560030 + 0.2499420941 0.3662323952 0.1811341941 + 0.2539947033 0.3686338067 0.1851633936 + 0.2580456138 0.3710030019 0.1891925931 + 0.2620247900 0.3733294904 0.1933576018 + 0.2659370899 0.3756558895 0.1975566000 + 0.2698495090 0.3779824078 0.2018067986 + 0.2736209035 0.3802998960 0.2061281949 + 0.2773866057 0.3825586140 0.2104569972 + 0.2811067104 0.3848172128 0.2148493975 + 0.2847231030 0.3870758116 0.2192417979 + 0.2883394957 0.3893344998 0.2236506939 + 0.2918758094 0.3915497959 0.2280631959 + 0.2953441143 0.3937469125 0.2324603051 + 0.2988123894 0.3959440887 0.2368455976 + 0.3021861017 0.3981412947 0.2412119061 + 0.3055104911 0.4003298879 0.2455295026 + 0.3088349998 0.4024715126 0.2498470992 + 0.3120698929 0.4046129882 0.2540681958 + 0.3152567148 0.4067544937 0.2582857013 + 0.3184433877 0.4088960886 0.2624298036 + 0.3215635121 0.4110131860 0.2665235102 + 0.3246200085 0.4131042957 0.2705960870 + 0.3276765049 0.4151954055 0.2745501995 + 0.3307037055 0.4172866046 0.2785041928 + 0.3336381018 0.4193777144 0.2823660076 + 0.3365724981 0.4214367867 0.2861714959 + 0.3395070136 0.4234822094 0.2899771035 + 0.3423467875 0.4255276918 0.2936319113 + 0.3451676071 0.4275731146 0.2972859144 + 0.3479883969 0.4296185970 0.3009010851 + 0.3507789969 0.4316303134 0.3044045866 + 0.3534946144 0.4336344004 0.3079079986 + 0.3562101126 0.4356383979 0.3113526106 + 0.3589256108 0.4376423955 0.3147099912 + 0.3615824878 0.4396465123 0.3180673122 + 0.3642010987 0.4416194856 0.3213653862 + 0.3668195903 0.4435859025 0.3245829940 + 0.3694381118 0.4455522895 0.3278006911 + 0.3719865084 0.4475187063 0.3309766054 + 0.3745158017 0.4494850039 0.3340623081 + 0.3770450950 0.4514260888 0.3371481001 + 0.3795743883 0.4533582032 0.3402245045 + 0.3820356131 0.4552902877 0.3431868851 + 0.3844830990 0.4572224021 0.3461492956 + 0.3869304955 0.4591544867 0.3491117060 + 0.3893780112 0.4610689878 0.3519938886 + 0.3917695880 0.4629696906 0.3548417091 + 0.3941422105 0.4648705125 0.3576894999 + 0.3965147138 0.4667713046 0.3605172932 + 0.3988873065 0.4686720073 0.3632592857 + 0.4012235105 0.4705640972 0.3660013080 + 0.4035275877 0.4724361002 0.3687433004 + 0.4058316052 0.4743080139 0.3714326024 + 0.4081357121 0.4761799872 0.3740772903 + 0.4104278982 0.4780519009 0.3767220080 + 0.4126693010 0.4799239039 0.3793666065 + 0.4149107933 0.4817703068 0.3819434941 + 0.4171522856 0.4836156964 0.3844990134 + 0.4193938076 0.4854609966 0.3870545030 + 0.4215936065 0.4873062968 0.3896099925 + 0.4237779975 0.4891516864 0.3920964897 + 0.4259622991 0.4909836054 0.3945704997 + 0.4281466901 0.4928041101 0.3970445096 + 0.4303230941 0.4946246147 0.3995184898 + 0.4324553013 0.4964450002 0.4019325972 + 0.4345873892 0.4982655048 0.4043321908 + 0.4367195070 0.5000848770 0.4067319036 + 0.4388515949 0.5018820167 0.4091314971 + 0.4409618080 0.5036790967 0.4114879966 + 0.4430460930 0.5054761171 0.4138199091 + 0.4451304972 0.5072731972 0.4161519110 + 0.4472149014 0.5090702772 0.4184837937 + 0.4492993057 0.5108565092 0.4207941890 + 0.4513547122 0.5126311779 0.4230645001 + 0.4533953965 0.5144059062 0.4253348112 + 0.4554361105 0.5161805749 0.4276050925 + 0.4574767947 0.5179553032 0.4298754930 + 0.4595173895 0.5197299719 0.4320927858 + 0.4615274966 0.5214862823 0.4343070984 + 0.4635280967 0.5232393146 0.4365214109 + 0.4655286074 0.5249922872 0.4387356937 + 0.4675292075 0.5267453194 0.4409281015 + 0.4695298076 0.5284982920 0.4430915117 + 0.4715020955 0.5302482843 0.4452548027 + 0.4734657109 0.5319799185 0.4474182129 + 0.4754293859 0.5337114930 0.4495815039 + 0.4773930013 0.5354431868 0.4517075121 + 0.4793567061 0.5371748209 0.4538244009 + 0.4812973142 0.5389063954 0.4559414089 + 0.4832268059 0.5406302214 0.4580583870 + 0.4851562977 0.5423403978 0.4601719081 + 0.4870857894 0.5440505743 0.4622465968 + 0.4890153110 0.5457608104 0.4643214047 + 0.4909291863 0.5474711061 0.4663960934 + 0.4928269088 0.5491812825 0.4684709013 + 0.4947246015 0.5508800745 0.4705354869 + 0.4966222942 0.5525686145 0.4725716114 + 0.4985199869 0.5542569757 0.4746077955 + 0.5004112124 0.5559453964 0.4766440094 + 0.5022791028 0.5576338172 0.4786801040 + 0.5041469932 0.5593221784 0.4807038903 + 0.5060148835 0.5609971285 0.4827046990 + 0.5078828931 0.5626630187 0.4847055078 + 0.5097507834 0.5643289089 0.4867062867 + 0.5115942955 0.5659946799 0.4887070954 + 0.5134339929 0.5676606297 0.4906964004 + 0.5152738094 0.5693264008 0.4926646054 + 0.5171135068 0.5709782243 0.4946328104 + 0.5189533234 0.5726205111 0.4966011047 + 0.5207813978 0.5742626786 0.4985693097 + 0.5225942135 0.5759049058 0.5005292892 + 0.5244070292 0.5775471926 0.5024672747 + 0.5262197852 0.5791894197 0.5044053197 + 0.5280326009 0.5808190107 0.5063433051 + 0.5298454762 0.5824362040 0.5082812905 + 0.5316343904 0.5840533972 0.5102161169 + 0.5334210992 0.5856705904 0.5121259093 + 0.5352079272 0.5872877836 0.5140355825 + 0.5369945765 0.5889049768 0.5159453154 + 0.5387812853 0.5905135870 0.5178549886 + 0.5405598879 0.5921041965 0.5197647810 + 0.5423210263 0.5936946869 0.5216510296 + 0.5440822244 0.5952851772 0.5235339999 + 0.5458433032 0.5968757272 0.5254169106 + 0.5476043820 0.5984662175 0.5272998810 + 0.5493655801 0.6000556946 0.5291827917 + 0.5511103868 0.6016175747 0.5310512185 + 0.5528460741 0.6031795144 0.5329084992 + 0.5545817018 0.6047413945 0.5347657800 + 0.5563173890 0.6063032746 0.5366231203 + 0.5580530763 0.6078652143 0.5384802818 + 0.5597887039 0.6094270945 0.5403330922 + 0.5615018010 0.6109694839 0.5421653986 + 0.5632117987 0.6125006080 0.5439975858 + 0.5649217963 0.6140317917 0.5458298922 + 0.5666316748 0.6155629158 0.5476621985 + 0.5683416724 0.6170939803 0.5494945049 + 0.5700508952 0.6186252236 0.5513088703 + 0.5717346072 0.6201528907 0.5531163812 + 0.5734183192 0.6216509938 0.5549240112 + 0.5751019120 0.6231490970 0.5567315221 + 0.5767856240 0.6246472001 0.5585390925 + 0.5784692764 0.6261453032 0.5603417754 + 0.5801506042 0.6276432872 0.5621244907 + 0.5818070769 0.6291413903 0.5639072061 + 0.5834636092 0.6306244135 0.5656898022 + 0.5851200819 0.6320869923 0.5674725175 + 0.5867766142 0.6335496902 0.5692551136 + 0.5884330869 0.6350123286 0.5710229874 + 0.5900881290 0.6364750266 0.5727801919 + 0.5917161703 0.6379376054 0.5745375156 + 0.5933442712 0.6394003034 0.5762947202 + 0.5949723721 0.6408405900 0.5780519247 + 0.5966004729 0.6422653794 0.5798091292 + 0.5982285738 0.6436902285 0.5815427899 + 0.5998566747 0.6451150179 0.5832737088 + 0.6014575958 0.6465398073 0.5850045085 + 0.6030557752 0.6479645967 0.5867353082 + 0.6046540737 0.6493893862 0.5884662271 + 0.6062523127 0.6507912278 0.5901939273 + 0.6078504920 0.6521757841 0.5918970108 + 0.6094486713 0.6535604000 0.5936000943 + 0.6110262275 0.6549450159 0.5953032970 + 0.6125928164 0.6563295126 0.5970063806 + 0.6141594052 0.6577141285 0.5987095237 + 0.6157259941 0.6590986848 0.6004055142 + 0.6172925830 0.6604683995 0.6020792723 + 0.6188592911 0.6618105173 0.6037530899 + 0.6204167008 0.6631525755 0.6054267883 + 0.6219497919 0.6644946933 0.6071006060 + 0.6234828234 0.6658368111 0.6087743044 + 0.6250159144 0.6671789289 0.6104397178 + 0.6265488863 0.6685209274 0.6120821238 + 0.6280819774 0.6698629856 0.6137245297 + 0.6296150088 0.6711651087 0.6153669953 + 0.6311213970 0.6724625826 0.6170094013 + 0.6326187849 0.6737599969 0.6186518073 + 0.6341162920 0.6750574708 0.6202881932 + 0.6356136799 0.6763550043 0.6218971014 + 0.6371111274 0.6776524782 0.6235058904 + 0.6386085153 0.6789500117 0.6251147985 + 0.6401032805 0.6802387238 0.6267235875 + 0.6415628791 0.6814897060 0.6283324957 + 0.6430225968 0.6827408075 0.6299412847 + 0.6444821954 0.6839917898 0.6315155029 + 0.6459417939 0.6852428913 0.6330882907 + 0.6474015117 0.6864938736 0.6346611977 + 0.6488611102 0.6877449751 0.6362339854 + 0.6503120065 0.6889960170 0.6378068924 + 0.6517316103 0.6902375817 0.6393796802 + 0.6531512737 0.6914405823 0.6409292221 + 0.6545709968 0.6926437020 0.6424635053 + 0.6559906006 0.6938467026 0.6439977884 + 0.6574103236 0.6950497031 0.6455320716 + 0.6588299274 0.6962528229 0.6470664144 + 0.6602421999 0.6974558234 0.6486006975 + 0.6616197824 0.6986588836 0.6501314044 + 0.6629973054 0.6998618841 0.6516245008 + 0.6643748879 0.7010213137 0.6531175971 + 0.6657524109 0.7021750808 0.6546106935 + 0.6671299934 0.7033289075 0.6561039090 + 0.6685075164 0.7044826746 0.6575970054 + 0.6698850989 0.7056365013 0.6590901017 + 0.6712222099 0.7067903280 0.6605660915 + 0.6725556254 0.7079440951 0.6620154977 + 0.6738889813 0.7090979218 0.6634649038 + 0.6752223969 0.7102407813 0.6649141908 + 0.6765558124 0.7113444209 0.6663635969 + 0.6778892279 0.7124481201 0.6678130031 + 0.6792225838 0.7135518193 0.6692622900 + 0.6805368066 0.7146555185 0.6706889868 + 0.6818242073 0.7157592177 0.6720920801 + 0.6831117272 0.7168627977 0.6734951735 + 0.6843991280 0.7179664969 0.6748983264 + 0.6856865287 0.7190701962 0.6763014197 + 0.6869739294 0.7201659083 0.6777045727 + 0.6882612705 0.7212188840 0.6791077256 + 0.6895486712 0.7222719789 0.6804931164 + 0.6908051968 0.7233250737 0.6818476915 + 0.6920449734 0.7243781090 0.6832023263 + 0.6932848096 0.7254312038 0.6845569015 + 0.6945245862 0.7264842987 0.6859114766 + 0.6957643032 0.7275372744 0.6872661114 + 0.6970040798 0.7285904288 0.6886206269 + 0.6982439160 0.7296434045 0.6899752021 + 0.6994836926 0.7306630015 0.6912801862 + 0.7006949186 0.7316653132 0.6925842166 + 0.7018857002 0.7326676250 0.6938881874 + 0.7030766010 0.7336698771 0.6951922178 + 0.7042673826 0.7346723080 0.6964963078 + 0.7054582238 0.7356746197 0.6978002787 + 0.7066490054 0.7366768718 0.6991043091 + 0.7078399062 0.7376793027 0.7003920078 + 0.7090306878 0.7386816144 0.7016437054 + 0.7102121711 0.7396839261 0.7028955221 + 0.7113531232 0.7406517267 0.7041472197 + 0.7124938965 0.7416034937 0.7053989768 + 0.7136347294 0.7425553799 0.7066507936 + 0.7147756219 0.7435072064 0.7079024911 + 0.7159163952 0.7444590926 0.7091543078 + 0.7170572281 0.7454109192 0.7103886008 + 0.7181981206 0.7463628054 0.7115867734 + 0.7193388939 0.7473145723 0.7127850056 + 0.7204583883 0.7482665181 0.7139831781 + 0.7215486169 0.7492182851 0.7151812911 + 0.7226387858 0.7501612902 0.7163795233 + 0.7237290144 0.7510632277 0.7175776958 + 0.7248191237 0.7519652247 0.7187758088 + 0.7259092927 0.7528672218 0.7199739814 + 0.7269995213 0.7537690997 0.7211189270 + 0.7280896902 0.7546710968 0.7222625017 + 0.7291797996 0.7555730939 0.7234061956 + 0.7302573919 0.7564749718 0.7245498896 + 0.7312965989 0.7573770285 0.7256935835 + 0.7323358059 0.7582790256 0.7268372178 + 0.7333750129 0.7591809034 0.7279809117 + 0.7344142199 0.7600783706 0.7291246057 + 0.7354534268 0.7609313726 0.7302554250 + 0.7364925742 0.7617843747 0.7313441038 + 0.7375317812 0.7626373768 0.7324327826 + 0.7385709882 0.7634903789 0.7335215211 + 0.7396101952 0.7643433809 0.7346101999 + 0.7406175137 0.7651963830 0.7356988788 + 0.7416058183 0.7660493851 0.7367876172 + 0.7425940037 0.7669023871 0.7378762960 + 0.7435823083 0.7677553892 0.7389649749 + 0.7445706129 0.7686083913 0.7400509715 + 0.7455587983 0.7694613934 0.7410846949 + 0.7465471029 0.7702968121 0.7421182990 + 0.7475354075 0.7711020112 0.7431520224 + 0.7485235929 0.7719072104 0.7441856861 + 0.7495118976 0.7727124095 0.7452194095 + 0.7504745722 0.7735176086 0.7462530732 + 0.7514122725 0.7743229270 0.7472867966 + 0.7523499727 0.7751281261 0.7483205199 + 0.7532876730 0.7759333253 0.7493541837 + 0.7542254925 0.7767385244 0.7503672838 + 0.7551631927 0.7775437236 0.7513464093 + 0.7561008930 0.7783489823 0.7523254156 + 0.7570385933 0.7791541815 0.7533044815 + 0.7579764128 0.7799593806 0.7542834878 + 0.7589141130 0.7807205915 0.7552626133 + 0.7598518133 0.7814794779 0.7562416792 + 0.7607476115 0.7822383046 0.7572206855 + 0.7616354823 0.7829971910 0.7581998110 + 0.7625234127 0.7837560773 0.7591788173 + 0.7634112835 0.7845150232 0.7601491809 + 0.7642992139 0.7852737904 0.7610744238 + 0.7651870847 0.7860326767 0.7619994879 + 0.7660750151 0.7867916226 0.7629246712 + 0.7669628859 0.7875505090 0.7638499141 + 0.7678508162 0.7883092761 0.7647750974 + 0.7687386870 0.7890682220 0.7657002807 + 0.7696266174 0.7898271084 0.7666255236 + 0.7704861760 0.7905514240 0.7675507069 + 0.7713252902 0.7912656069 0.7684757710 + 0.7721645236 0.7919796705 0.7694010139 + 0.7730035782 0.7926939130 0.7703076005 + 0.7738426924 0.7934079766 0.7711800933 + 0.7746818066 0.7941222191 0.7720525265 + 0.7755209208 0.7948362827 0.7729249001 + 0.7763599753 0.7955505252 0.7737973928 + 0.7771990895 0.7962645888 0.7746698260 + 0.7780382037 0.7969787717 0.7755423188 + 0.7788773179 0.7976928949 0.7764146924 + 0.7797163725 0.7984070778 0.7772871852 + 0.7805240154 0.7991213202 0.7781596184 + 0.7813156247 0.7998353839 0.7790321112 + 0.7821071744 0.8005164862 0.7799044847 + 0.7828987241 0.8011876941 0.7807313204 + 0.7836902738 0.8018589020 0.7815523744 + 0.7844818830 0.8025301099 0.7823736072 + 0.7852734923 0.8032013178 0.7831947207 + 0.7860651016 0.8038725853 0.7840157747 + 0.7868565917 0.8045437932 0.7848370075 + 0.7876482010 0.8052150011 0.7856581211 + 0.7884398103 0.8058862090 0.7864792943 + 0.7892314196 0.8065574169 0.7873004079 + 0.7900215983 0.8072286248 0.7881215811 + 0.7907671928 0.8078997731 0.7889426947 + 0.7915127277 0.8085709810 0.7897638083 + 0.7922583222 0.8092421889 0.7905495763 + 0.7930037975 0.8099133968 0.7913212180 + 0.7937493920 0.8105489016 0.7920926809 + 0.7944949269 0.8111789823 0.7928642035 + 0.7952405214 0.8118091822 0.7936357856 + 0.7959859967 0.8124393821 0.7944073081 + 0.7967315912 0.8130695224 0.7951787710 + 0.7974771261 0.8136997223 0.7959504128 + 0.7982227206 0.8143298030 0.7967218757 + 0.7989683151 0.8149600029 0.7974933982 + 0.7997137904 0.8155900836 0.7982649803 + 0.8004320264 0.8162202835 0.7990365028 + 0.8011332154 0.8168504238 0.7998080254 + 0.8018345237 0.8174806237 0.8005437255 + 0.8025357127 0.8181107044 0.8012676239 + 0.8032369018 0.8187409043 0.8019914031 + 0.8039380908 0.8193711042 0.8027151823 + 0.8046392798 0.8200011253 0.8034390807 + 0.8053405285 0.8205922246 0.8041629195 + 0.8060417175 0.8211833239 0.8048866987 + 0.8067429066 0.8217743039 0.8056105971 + 0.8074440956 0.8223654032 0.8063343763 + 0.8081452847 0.8229563832 0.8070582151 + 0.8088464737 0.8235474825 0.8077819943 + 0.8095477223 0.8241385818 0.8085058928 + 0.8102337718 0.8247296214 0.8092296720 + 0.8108925223 0.8253207207 0.8099535108 + 0.8115512133 0.8259118199 0.8106346130 + 0.8122099042 0.8265028000 0.8113127947 + 0.8128685951 0.8270938993 0.8119909763 + 0.8135272264 0.8276848793 0.8126692176 + 0.8141859174 0.8282759786 0.8133473992 + 0.8148446083 0.8288670778 0.8140255809 + 0.8155032992 0.8294581175 0.8147038221 + 0.8161619902 0.8300461173 0.8153820038 + 0.8168206215 0.8306000829 0.8160601258 + 0.8174793124 0.8311539888 0.8167383075 + 0.8181380033 0.8317080140 0.8174164891 + 0.8187966943 0.8322619796 0.8180946708 + 0.8194553852 0.8328160048 0.8187729120 + 0.8201069832 0.8333699107 0.8194510937 + 0.8207250834 0.8339238763 0.8201209903 + 0.8213431239 0.8344779015 0.8207557201 + 0.8219612241 0.8350318074 0.8213903904 + 0.8225793242 0.8355857730 0.8220251203 + 0.8231973052 0.8361397982 0.8226597905 + 0.8238154054 0.8366938233 0.8232945204 + 0.8244335055 0.8372477293 0.8239293098 + 0.8250514865 0.8378016949 0.8245639801 + 0.8256695867 0.8383557200 0.8251987100 + 0.8262876868 0.8389096260 0.8258333802 + 0.8269057274 0.8394635916 0.8264681101 + 0.8275238276 0.8400164843 0.8271027803 + 0.8281419277 0.8405354023 0.8277375102 + 0.8287599087 0.8410543203 0.8283722997 + 0.8293780088 0.8415731192 0.8290070295 + 0.8299961090 0.8420919776 0.8296416998 + 0.8305758238 0.8426108956 0.8302584291 + 0.8311551809 0.8431298137 0.8308519125 + 0.8317345977 0.8436486721 0.8314453959 + 0.8323140740 0.8441675901 0.8320388794 + 0.8328934908 0.8446865082 0.8326324224 + 0.8334729075 0.8452054262 0.8332257867 + 0.8340523839 0.8457242846 0.8338193297 + 0.8346318007 0.8462432027 0.8344128132 + 0.8352112174 0.8467620015 0.8350062966 + 0.8357906938 0.8472809196 0.8355997205 + 0.8363701105 0.8477997780 0.8361932039 + 0.8369495273 0.8483186960 0.8367866874 + 0.8375290036 0.8488376141 0.8373801708 + 0.8381084204 0.8493564725 0.8379737139 + 0.8386877775 0.8498753905 0.8385670781 + 0.8392673135 0.8503690958 0.8391606212 + 0.8398466706 0.8508548737 0.8397541046 + 0.8403992057 0.8513407111 0.8403248191 + 0.8409420252 0.8518266082 0.8408793211 + 0.8414847851 0.8523123860 0.8414338231 + 0.8420276046 0.8527982235 0.8419883251 + 0.8425704837 0.8532840014 0.8425428271 + 0.8431133032 0.8537697792 0.8430973291 + 0.8436561227 0.8542556167 0.8436517715 + 0.8441988826 0.8547413945 0.8442062736 + 0.8447417021 0.8552271724 0.8447607756 + 0.8452845216 0.8557130098 0.8453152776 + 0.8458272815 0.8561987877 0.8458697796 + 0.8463702202 0.8566846251 0.8464242816 + 0.8469129801 0.8571704030 0.8469787836 + 0.8474557996 0.8576561809 0.8475332856 + 0.8479986191 0.8581420183 0.8480879068 + 0.8485413790 0.8586277962 0.8486424088 + 0.8490841985 0.8591135740 0.8491969109 + 0.8496270180 0.8595994115 0.8497514129 + 0.8501589894 0.8600798249 0.8502855897 + 0.8506671786 0.8605344296 0.8508033752 + 0.8511754274 0.8609890938 0.8513212204 + 0.8516836166 0.8614438176 0.8518390059 + 0.8521918058 0.8618984818 0.8523567915 + 0.8526999950 0.8623532057 0.8528745770 + 0.8532081842 0.8628078103 0.8533924222 + 0.8537163734 0.8632624745 0.8539102077 + 0.8542246819 0.8637171984 0.8544279933 + 0.8547328711 0.8641719222 0.8549457788 + 0.8552411199 0.8646265268 0.8554636240 + 0.8557493091 0.8650811911 0.8559814095 + 0.8562574983 0.8655359149 0.8564991951 + 0.8567656875 0.8659905791 0.8570169806 + 0.8572738767 0.8664453030 0.8575347066 + 0.8577821255 0.8668999076 0.8580524921 + 0.8582903147 0.8673545718 0.8585702777 + 0.8587985039 0.8678092957 0.8590881228 + 0.8593066931 0.8682640195 0.8596059084 + 0.8598148823 0.8687186241 0.8601155281 + 0.8603023887 0.8691732883 0.8605988026 + 0.8607779741 0.8696280122 0.8610820770 + 0.8612535000 0.8700773716 0.8615654111 + 0.8617290854 0.8705028296 0.8620486856 + 0.8622046709 0.8709282875 0.8625320196 + 0.8626803160 0.8713536859 0.8630152941 + 0.8631559014 0.8717792034 0.8634986281 + 0.8636314869 0.8722046018 0.8639819026 + 0.8641070724 0.8726301193 0.8644651771 + 0.8645827174 0.8730555177 0.8649485111 + 0.8650581837 0.8734809756 0.8654317856 + 0.8655338287 0.8739064932 0.8659151793 + 0.8660094142 0.8743318915 0.8663985133 + 0.8664849997 0.8747574091 0.8668817878 + 0.8669605851 0.8751828074 0.8673651218 + 0.8674361706 0.8756083250 0.8678483963 + 0.8679118156 0.8760337234 0.8683316708 + 0.8683874011 0.8764591813 0.8688150048 + 0.8688629866 0.8768845797 0.8692982793 + 0.8693385124 0.8773100972 0.8697816133 + 0.8698140979 0.8777354956 0.8702471852 + 0.8702710271 0.8781610131 0.8706982136 + 0.8707159758 0.8785864711 0.8711491823 + 0.8711609244 0.8790119290 0.8716002107 + 0.8716058135 0.8794373870 0.8720511198 + 0.8720507026 0.8798627853 0.8725020885 + 0.8724955916 0.8802697062 0.8729531169 + 0.8729405999 0.8806678057 0.8734040856 + 0.8733854890 0.8810659051 0.8738551140 + 0.8738303781 0.8814638853 0.8743060827 + 0.8742753267 0.8818619847 0.8747571111 + 0.8747202754 0.8822600842 0.8752080798 + 0.8751652241 0.8826581836 0.8756589890 + 0.8756101131 0.8830562234 0.8761100173 + 0.8760550022 0.8834543228 0.8765609860 + 0.8764998913 0.8838524222 0.8770120144 + 0.8769448996 0.8842504025 0.8774629831 + 0.8773897886 0.8846485019 0.8779140115 + 0.8778346777 0.8850466013 0.8783649802 + 0.8782796264 0.8854447007 0.8788160086 + 0.8787245750 0.8858426809 0.8792669773 + 0.8791695237 0.8862407804 0.8797178864 + 0.8796144128 0.8866388798 0.8801575899 + 0.8800554872 0.8870369196 0.8805783987 + 0.8804715872 0.8874350190 0.8809990883 + 0.8808878064 0.8878331184 0.8814198971 + 0.8813039064 0.8882312179 0.8818407059 + 0.8817201257 0.8886291981 0.8822613955 + 0.8821362257 0.8890272975 0.8826822042 + 0.8825523853 0.8894253969 0.8831030130 + 0.8829684854 0.8898233771 0.8835237026 + 0.8833847046 0.8902072906 0.8839445114 + 0.8838008046 0.8905797005 0.8843653202 + 0.8842170238 0.8909522295 0.8847860098 + 0.8846331239 0.8913245797 0.8852068186 + 0.8850492835 0.8916971087 0.8856276274 + 0.8854653835 0.8920695186 0.8860483170 + 0.8858816028 0.8924419880 0.8864691257 + 0.8862977028 0.8928143978 0.8868898749 + 0.8867139220 0.8931869268 0.8873106241 + 0.8871300817 0.8935592771 0.8877313733 + 0.8875461817 0.8939318061 0.8881521821 + 0.8879624009 0.8943042159 0.8885728717 + 0.8883785009 0.8946766853 0.8889936805 + 0.8887947202 0.8950490952 0.8894144893 + 0.8892108202 0.8954216242 0.8898351789 + 0.8896269798 0.8957939744 0.8902388215 + 0.8900402784 0.8961665034 0.8906313777 + 0.8904294968 0.8965389729 0.8910239935 + 0.8908187151 0.8969113827 0.8914164901 + 0.8912078738 0.8972839117 0.8918091059 + 0.8915970922 0.8976563215 0.8922016025 + 0.8919863105 0.8980287910 0.8925942183 + 0.8923755288 0.8984012008 0.8929867148 + 0.8927648067 0.8987737298 0.8933792710 + 0.8931540251 0.8991460800 0.8937718868 + 0.8935431838 0.8995186090 0.8941643834 + 0.8939324021 0.8998910189 0.8945569992 + 0.8943216205 0.9002465010 0.8949494958 + 0.8947107792 0.9005951285 0.8953421116 + 0.8950999975 0.9009435773 0.8957346082 + 0.8954892159 0.9012920856 0.8961272240 + 0.8958783746 0.9016405940 0.8965197802 + 0.8962675929 0.9019891024 0.8969122767 + 0.8966568112 0.9023376107 0.8973048925 + 0.8970460296 0.9026861191 0.8976973891 + 0.8974351883 0.9030346870 0.8980900049 + 0.8978244066 0.9033831954 0.8984825015 + 0.8982136250 0.9037317038 0.8988751173 + 0.8986027837 0.9040802121 0.8992676735 + 0.8989920020 0.9044287205 0.8996602297 + 0.8993812203 0.9047772288 0.9000492096 + 0.8997703791 0.9051256776 0.9004154801 + 0.9001492858 0.9054743052 0.9007818103 + 0.9005132914 0.9058228135 0.9011480212 + 0.9008772969 0.9061713219 0.9015142918 + 0.9012413025 0.9065197706 0.9018806219 + 0.9016053081 0.9068682790 0.9022467732 + 0.9019693732 0.9072167873 0.9026131034 + 0.9023333788 0.9075652957 0.9029793143 + 0.9026973844 0.9079139233 0.9033455849 + 0.9030613899 0.9082623720 0.9037119150 + 0.9034253955 0.9086108804 0.9040781260 + 0.9037894011 0.9089593887 0.9044443965 + 0.9041534066 0.9093078971 0.9048107266 + 0.9045174122 0.9096564054 0.9051768780 + 0.9048814178 0.9100046158 0.9055432081 + 0.9052454233 0.9103307724 0.9059094787 + 0.9056094289 0.9106569886 0.9062756896 + 0.9059733748 0.9109830856 0.9066420197 + 0.9063374996 0.9113093019 0.9070082903 + 0.9067015052 0.9116355181 0.9073745012 + 0.9070655107 0.9119616747 0.9077407718 + 0.9074295163 0.9122877717 0.9081071019 + 0.9077935219 0.9126139879 0.9084733129 + 0.9081575274 0.9129402041 0.9088395834 + 0.9085214734 0.9132663012 0.9092057943 + 0.9088854790 0.9135925174 0.9095721245 + 0.9092494845 0.9139186740 0.9099383950 + 0.9096134901 0.9142448902 0.9102842808 + 0.9099774957 0.9145709872 0.9106261134 + 0.9103195071 0.9148972034 0.9109678864 + 0.9106599092 0.9152234197 0.9113097191 + 0.9110003710 0.9155495763 0.9116513729 + 0.9113408923 0.9158756733 0.9119932055 + 0.9116814137 0.9162018895 0.9123349786 + 0.9120218158 0.9165281057 0.9126768112 + 0.9123622775 0.9168542027 0.9130185843 + 0.9127027988 0.9171804190 0.9133604169 + 0.9130433202 0.9175065756 0.9137021899 + 0.9133837819 0.9178327918 0.9140440226 + 0.9137241840 0.9181588888 0.9143857956 + 0.9140647054 0.9184851050 0.9147276282 + 0.9144052267 0.9188113213 0.9150692821 + 0.9147456884 0.9191374183 0.9154111147 + 0.9150860906 0.9194635749 0.9157528877 + 0.9154266119 0.9197897911 0.9160947204 + 0.9157670736 0.9201086164 0.9164364934 + 0.9161075950 0.9204139113 0.9167783260 + 0.9164479971 0.9207192063 0.9171200991 + 0.9167885184 0.9210246205 0.9174618721 + 0.9171289802 0.9213299155 0.9178037047 + 0.9174695015 0.9216352105 0.9181454778 + 0.9178099036 0.9219406247 0.9184871912 + 0.9181504250 0.9222459197 0.9188290238 + 0.9184908867 0.9225512743 0.9191707969 + 0.9188314080 0.9228566289 0.9195126295 + 0.9191719294 0.9231619239 0.9198544025 + 0.9195122719 0.9234672785 0.9201831222 + 0.9198527932 0.9237725735 0.9205021858 + 0.9201807976 0.9240779281 0.9208211899 + 0.9204993248 0.9243832827 0.9211401939 + 0.9208179116 0.9246885777 0.9214591980 + 0.9211363792 0.9249939919 0.9217783213 + 0.9214549065 0.9252992868 0.9220973253 + 0.9217733741 0.9256045818 0.9224163294 + 0.9220920205 0.9259099960 0.9227353930 + 0.9224104881 0.9262152910 0.9230543971 + 0.9227290154 0.9265205860 0.9233734012 + 0.9230474830 0.9268260002 0.9236925244 + 0.9233661294 0.9271312952 0.9240115285 + 0.9236845970 0.9274367094 0.9243304729 + 0.9240031242 0.9277420044 0.9246494770 + 0.9243215919 0.9280472994 0.9249686003 + 0.9246401787 0.9283527136 0.9252876043 + 0.9249587059 0.9286580086 0.9256066084 + 0.9252771735 0.9289633036 0.9259256721 + 0.9255957007 0.9292687178 0.9262446761 + 0.9259142876 0.9295740128 0.9265636802 + 0.9262328148 0.9298794270 0.9268828034 + 0.9265512824 0.9301729798 0.9272018075 + 0.9268698096 0.9304589033 0.9275208116 + 0.9271882772 0.9307448268 0.9278398752 + 0.9275069237 0.9310306907 0.9281588793 + 0.9278253913 0.9313166142 0.9284778833 + 0.9281439185 0.9316025972 0.9287968874 + 0.9284623861 0.9318885207 0.9291160107 + 0.9287809730 0.9321743846 0.9294350147 + 0.9290995002 0.9324603081 0.9297540188 + 0.9294180274 0.9327462912 0.9300681949 + 0.9297364950 0.9330322146 0.9303660989 + 0.9300515056 0.9333180785 0.9306640029 + 0.9303495884 0.9336040020 0.9309619069 + 0.9306476116 0.9338899851 0.9312596917 + 0.9309456944 0.9341759086 0.9315575957 + 0.9312437773 0.9344617724 0.9318554997 + 0.9315418005 0.9347476959 0.9321534038 + 0.9318398833 0.9350336194 0.9324513078 + 0.9321380258 0.9353196025 0.9327492118 + 0.9324359894 0.9356055260 0.9330469966 + 0.9327340722 0.9358913898 0.9333449006 + 0.9330320954 0.9361773133 0.9336428046 + 0.9333301783 0.9364632964 0.9339407086 + 0.9336283207 0.9367492199 0.9342386127 + 0.9339262843 0.9370350838 0.9345363975 + 0.9342244267 0.9373210073 0.9348343015 + 0.9345223904 0.9376069903 0.9351322055 + 0.9348204732 0.9378929138 0.9354301095 + 0.9351186156 0.9381787777 0.9357280135 + 0.9354165792 0.9384647012 0.9360259175 + 0.9357147217 0.9387506247 0.9363237023 + 0.9360128045 0.9390366077 0.9366216063 + 0.9363108277 0.9393224716 0.9369195104 + 0.9366089106 0.9396083951 0.9372174144 + 0.9369068742 0.9398943186 0.9375153184 + 0.9372050166 0.9401689172 0.9378132224 + 0.9375030994 0.9404367208 0.9381110072 + 0.9378011227 0.9407045245 0.9384089112 + 0.9380992055 0.9409723878 0.9387068152 + 0.9383972287 0.9412401915 0.9390047193 + 0.9386953115 0.9415081143 0.9393026233 + 0.9389933944 0.9417759180 0.9396004081 + 0.9392914176 0.9420437813 0.9398983121 + 0.9395895004 0.9423115849 0.9401832819 + 0.9398875833 0.9425793886 0.9404615164 + 0.9401736856 0.9428473115 0.9407398105 + 0.9404526949 0.9431151152 0.9410179853 + 0.9407318234 0.9433829784 0.9412962198 + 0.9410107732 0.9436507821 0.9415745139 + 0.9412897825 0.9439185858 0.9418526888 + 0.9415687919 0.9441865087 0.9421309829 + 0.9418478012 0.9444543123 0.9424092174 + 0.9421268106 0.9447221756 0.9426875114 + 0.9424058199 0.9449899793 0.9429656863 + 0.9426848292 0.9452577829 0.9432439804 + 0.9429637790 0.9455257058 0.9435222149 + 0.9432427883 0.9457935095 0.9438003898 + 0.9435217977 0.9460613728 0.9440786839 + 0.9438008070 0.9463291764 0.9443569183 + 0.9440798163 0.9465970993 0.9446352124 + 0.9443588257 0.9468649030 0.9449133873 + 0.9446377754 0.9471327066 0.9451916814 + 0.9449167848 0.9474006295 0.9454699159 + 0.9451957941 0.9476683736 0.9457480907 + 0.9454748034 0.9479362965 0.9460263848 + 0.9457538128 0.9482041001 0.9463046193 + 0.9460328221 0.9484719038 0.9465829134 + 0.9463117719 0.9487398267 0.9468610883 + 0.9465907812 0.9490075707 0.9471393824 + 0.9468697906 0.9492754936 0.9474176168 + 0.9471487999 0.9495432973 0.9476959109 + 0.9474278092 0.9498111010 0.9479740858 + 0.9477068186 0.9500740170 0.9482523203 + 0.9479858279 0.9503250122 0.9485306144 + 0.9482647777 0.9505760074 0.9488087893 + 0.9485437870 0.9508270025 0.9490870833 + 0.9488227963 0.9510779977 0.9493653178 + 0.9491018057 0.9513291121 0.9496436119 + 0.9493808150 0.9515801072 0.9499217868 + 0.9496598244 0.9518311024 0.9501869082 + 0.9499387741 0.9520820975 0.9504470229 + 0.9502040148 0.9523330927 0.9507070184 + 0.9504652023 0.9525840878 0.9509670138 + 0.9507265091 0.9528350830 0.9512270093 + 0.9509876966 0.9530860782 0.9514870048 + 0.9512490034 0.9533370733 0.9517470002 + 0.9515101910 0.9535881281 0.9520069957 + 0.9517714977 0.9538391232 0.9522671103 + 0.9520328045 0.9540901184 0.9525271058 + 0.9522939920 0.9543411136 0.9527871013 + 0.9525552988 0.9545921087 0.9530470967 + 0.9528164864 0.9548432231 0.9533070922 + 0.9530777931 0.9550942183 0.9535670877 + 0.9533389807 0.9553452134 0.9538270831 + 0.9536002874 0.9555962086 0.9540871978 + 0.9538615942 0.9558472037 0.9543471932 + 0.9541227818 0.9560981989 0.9546071887 + 0.9543840885 0.9563491940 0.9548671842 + 0.9546452761 0.9566001892 0.9551271796 + 0.9549065828 0.9568511844 0.9553871751 + 0.9551677704 0.9571021795 0.9556471705 + 0.9554290771 0.9573531747 0.9559072852 + 0.9556903839 0.9576042295 0.9561672807 + 0.9559515715 0.9578552246 0.9564272761 + 0.9562128782 0.9581062198 0.9566872716 + 0.9564741254 0.9583572149 0.9569473267 + 0.9567353725 0.9586083293 0.9572073221 + 0.9569966197 0.9588593245 0.9574673176 + 0.9572579265 0.9591103196 0.9577273726 + 0.9575191736 0.9593613148 0.9579874277 + 0.9577804208 0.9596123099 0.9582474232 + 0.9580417275 0.9598633051 0.9585074186 + 0.9583029151 0.9601072073 0.9587674141 + 0.9585642219 0.9603425264 0.9590274096 + 0.9588255286 0.9605777860 0.9592875242 + 0.9590867162 0.9608132243 0.9595475197 + 0.9593480229 0.9610484838 0.9598075151 + 0.9596092105 0.9612839222 0.9600630999 + 0.9598705173 0.9615191817 0.9603062272 + 0.9601234198 0.9617545009 0.9605492949 + 0.9603682160 0.9619898796 0.9607924223 + 0.9606128931 0.9622251987 0.9610354900 + 0.9608576298 0.9624605179 0.9612786174 + 0.9611024261 0.9626958966 0.9615216851 + 0.9613471031 0.9629312158 0.9617648125 + 0.9615918994 0.9631665945 0.9620078802 + 0.9618365765 0.9634019136 0.9622510076 + 0.9620813727 0.9636371732 0.9624940753 + 0.9623261094 0.9638726115 0.9627372026 + 0.9625709057 0.9641078711 0.9629802704 + 0.9628155828 0.9643431902 0.9632233977 + 0.9630603194 0.9645786285 0.9634665251 + 0.9633051157 0.9648138881 0.9637095928 + 0.9635497928 0.9650493264 0.9639527202 + 0.9637945890 0.9652845860 0.9641957879 + 0.9640393257 0.9655199051 0.9644389153 + 0.9642841220 0.9657552838 0.9646819830 + 0.9645287991 0.9659906030 0.9649251103 + 0.9647734761 0.9662259817 0.9651681781 + 0.9650182724 0.9664613008 0.9654113054 + 0.9652630091 0.9666966200 0.9656543732 + 0.9655078053 0.9669319987 0.9658975005 + 0.9657524824 0.9671673179 0.9661406279 + 0.9659972787 0.9674025774 0.9663836956 + 0.9662420154 0.9676380157 0.9666268229 + 0.9664868116 0.9678732753 0.9668698907 + 0.9667314887 0.9681087136 0.9671130180 + 0.9669762254 0.9683439732 0.9673560858 + 0.9672210217 0.9685792923 0.9675992131 + 0.9674656987 0.9688146710 0.9678422809 + 0.9677104950 0.9690499902 0.9680854082 + 0.9679551721 0.9692854285 0.9683284760 + 0.9682000279 0.9695206881 0.9685716033 + 0.9684447050 0.9697560072 0.9688146710 + 0.9686893821 0.9699913859 0.9690577984 + 0.9689341784 0.9702126980 0.9693009257 + 0.9691789150 0.9704334140 0.9695439935 + 0.9694237113 0.9706541896 0.9697871208 + 0.9696683884 0.9708749056 0.9700282216 + 0.9699131846 0.9710956812 0.9702556133 + 0.9701480269 0.9713163972 0.9704830050 + 0.9703773856 0.9715371728 0.9707103968 + 0.9706068039 0.9717580080 0.9709377885 + 0.9708361030 0.9719787240 0.9711652994 + 0.9710655212 0.9721994996 0.9713926911 + 0.9712948799 0.9724202156 0.9716200829 + 0.9715242982 0.9726409912 0.9718474746 + 0.9717537165 0.9728617072 0.9720749259 + 0.9719830155 0.9730824828 0.9723023176 + 0.9722123742 0.9733031988 0.9725297093 + 0.9724417925 0.9735239744 0.9727571011 + 0.9726712108 0.9737448096 0.9729844928 + 0.9729006290 0.9739655256 0.9732118845 + 0.9731299281 0.9741863012 0.9734392762 + 0.9733592868 0.9744070172 0.9736667275 + 0.9735887051 0.9746277928 0.9738941193 + 0.9738181233 0.9748485088 0.9741215110 + 0.9740474820 0.9750692844 0.9743489027 + 0.9742767811 0.9752901196 0.9745762944 + 0.9745061994 0.9755107760 0.9748036861 + 0.9747356176 0.9757316113 0.9750310779 + 0.9749649763 0.9759523273 0.9752585292 + 0.9751943946 0.9761731029 0.9754859209 + 0.9754236937 0.9763938189 0.9757133722 + 0.9756531119 0.9766145945 0.9759408236 + 0.9758824706 0.9768353105 0.9761682153 + 0.9761118889 0.9770560861 0.9763956070 + 0.9763413072 0.9772769213 0.9766229987 + 0.9765706062 0.9774975777 0.9768503904 + 0.9768000245 0.9777184129 0.9770777822 + 0.9770293832 0.9779391289 0.9773051739 + 0.9772588015 0.9781599045 0.9775326252 + 0.9774881005 0.9783806205 0.9777600169 + 0.9777175188 0.9786013961 0.9779874086 + 0.9779468775 0.9788221717 0.9782148004 + 0.9781762958 0.9790428877 0.9784421921 + 0.9784057140 0.9792637229 0.9786695838 + 0.9786350131 0.9794843793 0.9788969755 + 0.9788643718 0.9797052145 0.9791244268 + 0.9790937901 0.9799258709 0.9793518186 + 0.9793232083 0.9801377058 0.9795792103 + 0.9795526266 0.9803448915 0.9798066020 + 0.9797819257 0.9805520177 0.9800319076 + 0.9800106287 0.9807592034 0.9802446961 + 0.9802256823 0.9809663892 0.9804576039 + 0.9804407954 0.9811735749 0.9806703925 + 0.9806559086 0.9813808203 0.9808831811 + 0.9808710217 0.9815880060 0.9810960889 + 0.9810860753 0.9817951918 0.9813088775 + 0.9813011289 0.9820023775 0.9815217853 + 0.9815161824 0.9822095037 0.9817345738 + 0.9817312956 0.9824166894 0.9819474816 + 0.9819464087 0.9826238751 0.9821602702 + 0.9821615219 0.9828311205 0.9823731780 + 0.9823765755 0.9830383062 0.9825860262 + 0.9825916886 0.9832454920 0.9827988148 + 0.9828066826 0.9834526777 0.9830117226 + 0.9830217957 0.9836598039 0.9832245111 + 0.9832369089 0.9838669896 0.9834374189 + 0.9834520221 0.9840741754 0.9836502075 + 0.9836670756 0.9842814207 0.9838631153 + 0.9838821888 0.9844886065 0.9840759039 + 0.9840973020 0.9846957922 0.9842888117 + 0.9843124151 0.9849029779 0.9845016003 + 0.9845274091 0.9851101041 0.9847143888 + 0.9847425222 0.9853172898 0.9849272966 + 0.9849575758 0.9855244756 0.9851400852 + 0.9851726890 0.9857317209 0.9853529930 + 0.9853878021 0.9859389067 0.9855657816 + 0.9856029153 0.9861460924 0.9857786894 + 0.9858180285 0.9863532782 0.9859914780 + 0.9860330224 0.9865604043 0.9862043262 + 0.9862480760 0.9867675900 0.9864171743 + 0.9864631891 0.9869747758 0.9866300225 + 0.9866783023 0.9871820211 0.9868428707 + 0.9868934155 0.9873892069 0.9870557189 + 0.9871085286 0.9875963926 0.9872686267 + 0.9873235822 0.9878035784 0.9874814153 + 0.9875385761 0.9880108237 0.9876943231 + 0.9877536893 0.9882178903 0.9879071116 + 0.9879688025 0.9884250760 0.9881199002 + 0.9881839156 0.9886323214 0.9883328080 + 0.9883990288 0.9888395071 0.9885455966 + 0.9886140823 0.9890466928 0.9887585044 + 0.9888291955 0.9892538786 0.9889712930 + 0.9890443087 0.9894611239 0.9891842008 + 0.9892593026 0.9896681905 0.9893969893 + 0.9894744158 0.9898753762 0.9896098971 + 0.9896895289 0.9900776148 0.9898226857 + 0.9899045825 0.9902721047 0.9900333285 + 0.9901123047 0.9904667139 0.9902325869 + 0.9903141260 0.9906613231 0.9904320240 + 0.9905158877 0.9908558130 0.9906312823 + 0.9907177091 0.9910504222 0.9908306003 + 0.9909194112 0.9912449121 0.9910299778 + 0.9911211729 0.9914395213 0.9912292957 + 0.9913229942 0.9916340113 0.9914286137 + 0.9915248156 0.9918286204 0.9916279912 + 0.9917265773 0.9920232296 0.9918273091 + 0.9919283986 0.9922177196 0.9920266271 + 0.9921302199 0.9924123287 0.9922260046 + 0.9923319817 0.9926068187 0.9924253225 + 0.9925338030 0.9928014278 0.9926245809 + 0.9927356243 0.9929959178 0.9928240180 + 0.9929373264 0.9931905270 0.9930232763 + 0.9931390882 0.9933850765 0.9932225943 + 0.9933409095 0.9935796261 0.9934219718 + 0.9935426712 0.9937741756 0.9936212897 + 0.9937444925 0.9939687252 0.9938206077 + 0.9939463139 0.9941632748 0.9940199852 + 0.9941480756 0.9943578243 0.9942193031 + 0.9943498969 0.9945523739 0.9944186211 + 0.9945517182 0.9947469831 0.9946179986 + 0.9947534800 0.9949414730 0.9948173165 + 0.9949551821 0.9951360822 0.9950165749 + 0.9951570034 0.9953305721 0.9952160120 + 0.9953588247 0.9955251813 0.9954152703 + 0.9955605865 0.9957196712 0.9956145883 + 0.9957624078 0.9959142804 0.9958140254 + 0.9959642291 0.9961088896 0.9960132837 + 0.9961659908 0.9963033795 0.9962127209 + 0.9963678122 0.9964979887 0.9964119792 + 0.9965695739 0.9966924787 0.9966112971 + 0.9967713952 0.9968870878 0.9968106747 + 0.9969730973 0.9970815778 0.9970099926 + 0.9971749187 0.9972761869 0.9972093105 + 0.9973766804 0.9974707961 0.9974086881 + 0.9975785017 0.9976652861 0.9976080060 + 0.9977803230 0.9978598952 0.9978073239 + 0.9979820848 0.9980543852 0.9980067015 + 0.9981839061 0.9982489944 0.9982060194 + 0.9983857274 0.9984434843 0.9984052777 + 0.9985874891 0.9986380935 0.9986047149 + 0.9987893105 0.9988327026 0.9988039732 + 0.9989910126 0.9990271926 0.9990032911 + 0.9991927743 0.9992218018 0.9992027283 + 0.9993945956 0.9994162917 0.9994019866 + 0.9995964170 0.9996109009 0.9996013045 + 0.9997981787 0.9998053908 0.9998006821 + 1.0000000000 1.0000000000 1.0000000000 +} diff --git a/rpplugins/color_correction/resources/film_luts_raw/kodak_dscs_3155.spi1d b/rpplugins/color_correction/resources/film_luts_raw/kodak_dscs_3155.spi1d new file mode 100644 index 0000000..8fe8fd6 --- /dev/null +++ b/rpplugins/color_correction/resources/film_luts_raw/kodak_dscs_3155.spi1d @@ -0,0 +1,1030 @@ +Version 1 +From 0.0 1.0 +Length 1024 +Components 3 +{ + 0.0000000000 0.0000000000 0.0000000000 + 0.0048120469 0.0048120469 0.0048120469 + 0.0096240947 0.0096240947 0.0096240947 + 0.0145009197 0.0145009197 0.0145009197 + 0.0193832405 0.0193832405 0.0193832405 + 0.0242968407 0.0242968407 0.0242968407 + 0.0292149596 0.0292149596 0.0292149596 + 0.0341353305 0.0341353305 0.0341353305 + 0.0390561298 0.0390561298 0.0390561298 + 0.0439544208 0.0439544208 0.0439544208 + 0.0488473810 0.0488473810 0.0488473810 + 0.0536984690 0.0536984690 0.0536984690 + 0.0585366711 0.0585366711 0.0585366711 + 0.0633208230 0.0633208230 0.0633208230 + 0.0680815428 0.0680815428 0.0680815428 + 0.0727850720 0.0727850720 0.0727850720 + 0.0774499997 0.0774499997 0.0774499997 + 0.0820651725 0.0820651725 0.0820651725 + 0.0866203383 0.0866203383 0.0866203383 + 0.0911446288 0.0911446288 0.0911446288 + 0.0955801234 0.0955801234 0.0955801234 + 0.1000152007 0.1000152007 0.1000152007 + 0.1043246016 0.1043246016 0.1043246016 + 0.1086340994 0.1086340994 0.1086340994 + 0.1128552034 0.1128552034 0.1128552034 + 0.1170352995 0.1170352995 0.1170352995 + 0.1211775988 0.1211775988 0.1211775988 + 0.1252277046 0.1252277046 0.1252277046 + 0.1292777061 0.1292777061 0.1292777061 + 0.1332218945 0.1332218945 0.1332218945 + 0.1371431053 0.1371431053 0.1371431053 + 0.1410301030 0.1410301030 0.1410301030 + 0.1448252946 0.1448252946 0.1448252946 + 0.1486205012 0.1486205012 0.1486205012 + 0.1523379982 0.1523379982 0.1523379982 + 0.1560111046 0.1560111046 0.1560111046 + 0.1596841961 0.1596841961 0.1596841961 + 0.1632499993 0.1632499993 0.1632499993 + 0.1668058038 0.1668058038 0.1668058038 + 0.1703501940 0.1703501940 0.1703501940 + 0.1737938970 0.1737938970 0.1737938970 + 0.1772377044 0.1772377044 0.1772377044 + 0.1806603968 0.1806603968 0.1806603968 + 0.1839977056 0.1839977056 0.1839977056 + 0.1873349994 0.1873349994 0.1873349994 + 0.1906519979 0.1906519979 0.1906519979 + 0.1938886046 0.1938886046 0.1938886046 + 0.1971253008 0.1971253008 0.1971253008 + 0.2003512979 0.2003512979 0.2003512979 + 0.2034929991 0.2034929991 0.2034929991 + 0.2066347003 0.2066347003 0.2066347003 + 0.2097764015 0.2097764015 0.2097764015 + 0.2128352970 0.2128352970 0.2128352970 + 0.2158876956 0.2158876956 0.2158876956 + 0.2189401984 0.2189401984 0.2189401984 + 0.2219379991 0.2219379991 0.2219379991 + 0.2249068022 0.2249068022 0.2249068022 + 0.2278755009 0.2278755009 0.2278755009 + 0.2308219969 0.2308219969 0.2308219969 + 0.2337123007 0.2337123007 0.2337123007 + 0.2366026938 0.2366026938 0.2366026938 + 0.2394929975 0.2394929975 0.2394929975 + 0.2423229069 0.2423229069 0.2423229069 + 0.2451398969 0.2451398969 0.2451398969 + 0.2479569018 0.2479569018 0.2479569018 + 0.2507550120 0.2507550120 0.2507550120 + 0.2535035014 0.2535035014 0.2535035014 + 0.2562519908 0.2562519908 0.2562519908 + 0.2590003908 0.2590003908 0.2590003908 + 0.2617082000 0.2617082000 0.2617082000 + 0.2643926144 0.2643926144 0.2643926144 + 0.2670770884 0.2670770884 0.2670770884 + 0.2697615027 0.2697615027 0.2697615027 + 0.2723914981 0.2723914981 0.2723914981 + 0.2750161886 0.2750161886 0.2750161886 + 0.2776409090 0.2776409090 0.2776409090 + 0.2802599967 0.2802599967 0.2802599967 + 0.2828288972 0.2828288972 0.2828288972 + 0.2853977978 0.2853977978 0.2853977978 + 0.2879666984 0.2879666984 0.2879666984 + 0.2905246913 0.2905246913 0.2905246913 + 0.2930414975 0.2930414975 0.2930414975 + 0.2955583036 0.2955583036 0.2955583036 + 0.2980751097 0.2980751097 0.2980751097 + 0.3005805016 0.3005805016 0.3005805016 + 0.3030486107 0.3030486107 0.3030486107 + 0.3055166900 0.3055166900 0.3055166900 + 0.3079847991 0.3079847991 0.3079847991 + 0.3104445040 0.3104445040 0.3104445040 + 0.3128669858 0.3128669858 0.3128669858 + 0.3152895868 0.3152895868 0.3152895868 + 0.3177120984 0.3177120984 0.3177120984 + 0.3201321959 0.3201321959 0.3201321959 + 0.3225120902 0.3225120902 0.3225120902 + 0.3248918951 0.3248918951 0.3248918951 + 0.3272717893 0.3272717893 0.3272717893 + 0.3296515942 0.3296515942 0.3296515942 + 0.3319971859 0.3319971859 0.3319971859 + 0.3343369961 0.3343369961 0.3343369961 + 0.3366766870 0.3366766870 0.3366766870 + 0.3390164971 0.3390164971 0.3390164971 + 0.3413344026 0.3413344026 0.3413344026 + 0.3436363935 0.3436363935 0.3436363935 + 0.3459384143 0.3459384143 0.3459384143 + 0.3482404947 0.3482404947 0.3482404947 + 0.3505341113 0.3505341113 0.3505341113 + 0.3528004885 0.3528004885 0.3528004885 + 0.3550668955 0.3550668955 0.3550668955 + 0.3573333025 0.3573333025 0.3573333025 + 0.3595997095 0.3595997095 0.3595997095 + 0.3618383110 0.3618383110 0.3618383110 + 0.3640710115 0.3640710115 0.3640710115 + 0.3663035929 0.3663035929 0.3663035929 + 0.3685362935 0.3685362935 0.3685362935 + 0.3707579076 0.3707579076 0.3707579076 + 0.3729583919 0.3729583919 0.3729583919 + 0.3751589060 0.3751589060 0.3751589060 + 0.3773593903 0.3773593903 0.3773593903 + 0.3795599043 0.3795599043 0.3795599043 + 0.3817358911 0.3817358911 0.3817358911 + 0.3839055896 0.3839055896 0.3839055896 + 0.3860754073 0.3860754073 0.3860754073 + 0.3882451952 0.3882451952 0.3882451952 + 0.3904092908 0.3904092908 0.3904092908 + 0.3925495148 0.3925495148 0.3925495148 + 0.3946897089 0.3946897089 0.3946897089 + 0.3968299031 0.3968299031 0.3968299031 + 0.3989700973 0.3989700973 0.3989700973 + 0.4010953903 0.4010953903 0.4010953903 + 0.4032069147 0.4032069147 0.4032069147 + 0.4053184092 0.4053184092 0.4053184092 + 0.4074299037 0.4074299037 0.4074299037 + 0.4095414877 0.4095414877 0.4095414877 + 0.4116311073 0.4116311073 0.4116311073 + 0.4137147069 0.4137147069 0.4137147069 + 0.4157981873 0.4157981873 0.4157981873 + 0.4178817868 0.4178817868 0.4178817868 + 0.4199653864 0.4199653864 0.4199653864 + 0.4220218956 0.4220218956 0.4220218956 + 0.4240779877 0.4240779877 0.4240779877 + 0.4261341095 0.4261341095 0.4261341095 + 0.4281901121 0.4281901121 0.4281901121 + 0.4302429855 0.4302429855 0.4302429855 + 0.4322718084 0.4322718084 0.4322718084 + 0.4343006909 0.4343006909 0.4343006909 + 0.4363296032 0.4363296032 0.4363296032 + 0.4383583963 0.4383583963 0.4383583963 + 0.4403820932 0.4403820932 0.4403820932 + 0.4423837960 0.4423837960 0.4423837960 + 0.4443854988 0.4443854988 0.4443854988 + 0.4463872015 0.4463872015 0.4463872015 + 0.4483889043 0.4483889043 0.4483889043 + 0.4503852129 0.4503852129 0.4503852129 + 0.4523595870 0.4523595870 0.4523595870 + 0.4543339908 0.4543339908 0.4543339908 + 0.4563083053 0.4563083053 0.4563083053 + 0.4582827091 0.4582827091 0.4582827091 + 0.4602535069 0.4602535069 0.4602535069 + 0.4622001946 0.4622001946 0.4622001946 + 0.4641467929 0.4641467929 0.4641467929 + 0.4660935104 0.4660935104 0.4660935104 + 0.4680401981 0.4680401981 0.4680401981 + 0.4699868858 0.4699868858 0.4699868858 + 0.4719055891 0.4719055891 0.4719055891 + 0.4738239944 0.4738239944 0.4738239944 + 0.4757424891 0.4757424891 0.4757424891 + 0.4776608944 0.4776608944 0.4776608944 + 0.4795793891 0.4795793891 0.4795793891 + 0.4814752936 0.4814752936 0.4814752936 + 0.4833647907 0.4833647907 0.4833647907 + 0.4852542877 0.4852542877 0.4852542877 + 0.4871438146 0.4871438146 0.4871438146 + 0.4890333116 0.4890333116 0.4890333116 + 0.4909082949 0.4909082949 0.4909082949 + 0.4927679002 0.4927679002 0.4927679002 + 0.4946275949 0.4946275949 0.4946275949 + 0.4964872897 0.4964872897 0.4964872897 + 0.4983470142 0.4983470142 0.4983470142 + 0.5002033114 0.5002033114 0.5002033114 + 0.5020321012 0.5020321012 0.5020321012 + 0.5038608909 0.5038608909 0.5038608909 + 0.5056896806 0.5056896806 0.5056896806 + 0.5075185895 0.5075185895 0.5075185895 + 0.5093473792 0.5093473792 0.5093473792 + 0.5111556053 0.5111556053 0.5111556053 + 0.5129525065 0.5129525065 0.5129525065 + 0.5147492886 0.5147492886 0.5147492886 + 0.5165460706 0.5165460706 0.5165460706 + 0.5183429122 0.5183429122 0.5183429122 + 0.5201370716 0.5201370716 0.5201370716 + 0.5219007134 0.5219007134 0.5219007134 + 0.5236642957 0.5236642957 0.5236642957 + 0.5254278183 0.5254278183 0.5254278183 + 0.5271914005 0.5271914005 0.5271914005 + 0.5289549232 0.5289549232 0.5289549232 + 0.5307043791 0.5307043791 0.5307043791 + 0.5324332714 0.5324332714 0.5324332714 + 0.5341622829 0.5341622829 0.5341622829 + 0.5358911753 0.5358911753 0.5358911753 + 0.5376201868 0.5376201868 0.5376201868 + 0.5393490791 0.5393490791 0.5393490791 + 0.5410556197 0.5410556197 0.5410556197 + 0.5427485704 0.5427485704 0.5427485704 + 0.5444415212 0.5444415212 0.5444415212 + 0.5461344719 0.5461344719 0.5461344719 + 0.5478274226 0.5478274226 0.5478274226 + 0.5495203733 0.5495203733 0.5495203733 + 0.5511866212 0.5511866212 0.5511866212 + 0.5528420806 0.5528420806 0.5528420806 + 0.5544977188 0.5544977188 0.5544977188 + 0.5561531782 0.5561531782 0.5561531782 + 0.5578088164 0.5578088164 0.5578088164 + 0.5594642758 0.5594642758 0.5594642758 + 0.5610936284 0.5610936284 0.5610936284 + 0.5627104044 0.5627104044 0.5627104044 + 0.5643271208 0.5643271208 0.5643271208 + 0.5659437776 0.5659437776 0.5659437776 + 0.5675606132 0.5675606132 0.5675606132 + 0.5691773295 0.5691773295 0.5691773295 + 0.5707743168 0.5707743168 0.5707743168 + 0.5723509192 0.5723509192 0.5723509192 + 0.5739275217 0.5739275217 0.5739275217 + 0.5755040050 0.5755040050 0.5755040050 + 0.5770806074 0.5770806074 0.5770806074 + 0.5786570907 0.5786570907 0.5786570907 + 0.5802274942 0.5802274942 0.5802274942 + 0.5817626119 0.5817626119 0.5817626119 + 0.5832977295 0.5832977295 0.5832977295 + 0.5848327279 0.5848327279 0.5848327279 + 0.5863677859 0.5863677859 0.5863677859 + 0.5879029036 0.5879029036 0.5879029036 + 0.5894379020 0.5894379020 0.5894379020 + 0.5909458995 0.5909458995 0.5909458995 + 0.5924382806 0.5924382806 0.5924382806 + 0.5939307213 0.5939307213 0.5939307213 + 0.5954229832 0.5954229832 0.5954229832 + 0.5969154239 0.5969154239 0.5969154239 + 0.5984076858 0.5984076858 0.5984076858 + 0.5999001265 0.5999001265 0.5999001265 + 0.6013516188 0.6013516188 0.6013516188 + 0.6028001904 0.6028001904 0.6028001904 + 0.6042487025 0.6042487025 0.6042487025 + 0.6056972742 0.6056972742 0.6056972742 + 0.6071457863 0.6071457863 0.6071457863 + 0.6085944176 0.6085944176 0.6085944176 + 0.6100416183 0.6100416183 0.6100416183 + 0.6114454269 0.6114454269 0.6114454269 + 0.6128491759 0.6128491759 0.6128491759 + 0.6142529845 0.6142529845 0.6142529845 + 0.6156567931 0.6156567931 0.6156567931 + 0.6170606017 0.6170606017 0.6170606017 + 0.6184644103 0.6184644103 0.6184644103 + 0.6198682785 0.6198682785 0.6198682785 + 0.6212307811 0.6212307811 0.6212307811 + 0.6225889921 0.6225889921 0.6225889921 + 0.6239473224 0.6239473224 0.6239473224 + 0.6253055930 0.6253055930 0.6253055930 + 0.6266638041 0.6266638041 0.6266638041 + 0.6280220747 0.6280220747 0.6280220747 + 0.6293802857 0.6293802857 0.6293802857 + 0.6307135224 0.6307135224 0.6307135224 + 0.6320255995 0.6320255995 0.6320255995 + 0.6333376765 0.6333376765 0.6333376765 + 0.6346498132 0.6346498132 0.6346498132 + 0.6359618902 0.6359618902 0.6359618902 + 0.6372740269 0.6372740269 0.6372740269 + 0.6385861039 0.6385861039 0.6385861039 + 0.6398981810 0.6398981810 0.6398981810 + 0.6411672831 0.6411672831 0.6411672831 + 0.6424328089 0.6424328089 0.6424328089 + 0.6436982751 0.6436982751 0.6436982751 + 0.6449638009 0.6449638009 0.6449638009 + 0.6462293863 0.6462293863 0.6462293863 + 0.6474949121 0.6474949121 0.6474949121 + 0.6487603784 0.6487603784 0.6487603784 + 0.6500248909 0.6500248909 0.6500248909 + 0.6512436271 0.6512436271 0.6512436271 + 0.6524624228 0.6524624228 0.6524624228 + 0.6536810994 0.6536810994 0.6536810994 + 0.6548997760 0.6548997760 0.6548997760 + 0.6561185122 0.6561185122 0.6561185122 + 0.6573371887 0.6573371887 0.6573371887 + 0.6585559249 0.6585559249 0.6585559249 + 0.6597746015 0.6597746015 0.6597746015 + 0.6609550714 0.6609550714 0.6609550714 + 0.6621270180 0.6621270180 0.6621270180 + 0.6632987857 0.6632987857 0.6632987857 + 0.6644706726 0.6644706726 0.6644706726 + 0.6656426191 0.6656426191 0.6656426191 + 0.6668143868 0.6668143868 0.6668143868 + 0.6679862738 0.6679862738 0.6679862738 + 0.6691582203 0.6691582203 0.6691582203 + 0.6703168750 0.6703168750 0.6703168750 + 0.6714420915 0.6714420915 0.6714420915 + 0.6725673079 0.6725673079 0.6725673079 + 0.6736925244 0.6736925244 0.6736925244 + 0.6748176813 0.6748176813 0.6748176813 + 0.6759428978 0.6759428978 0.6759428978 + 0.6770681143 0.6770681143 0.6770681143 + 0.6781932712 0.6781932712 0.6781932712 + 0.6793184876 0.6793184876 0.6793184876 + 0.6804254055 0.6804254055 0.6804254055 + 0.6815043092 0.6815043092 0.6815043092 + 0.6825832129 0.6825832129 0.6825832129 + 0.6836621165 0.6836621165 0.6836621165 + 0.6847409010 0.6847409010 0.6847409010 + 0.6858198047 0.6858198047 0.6858198047 + 0.6868987083 0.6868987083 0.6868987083 + 0.6879776120 0.6879776120 0.6879776120 + 0.6890565157 0.6890565157 0.6890565157 + 0.6901295781 0.6901295781 0.6901295781 + 0.6911628246 0.6911628246 0.6911628246 + 0.6921958923 0.6921958923 0.6921958923 + 0.6932290196 0.6932290196 0.6932290196 + 0.6942620873 0.6942620873 0.6942620873 + 0.6952952147 0.6952952147 0.6952952147 + 0.6963282824 0.6963282824 0.6963282824 + 0.6973615289 0.6973615289 0.6973615289 + 0.6983945966 0.6983945966 0.6983945966 + 0.6994277239 0.6994277239 0.6994277239 + 0.7004407048 0.7004407048 0.7004407048 + 0.7014287710 0.7014287710 0.7014287710 + 0.7024167776 0.7024167776 0.7024167776 + 0.7034049034 0.7034049034 0.7034049034 + 0.7043930292 0.7043930292 0.7043930292 + 0.7053809762 0.7053809762 0.7053809762 + 0.7063691020 0.7063691020 0.7063691020 + 0.7073571086 0.7073571086 0.7073571086 + 0.7083451748 0.7083451748 0.7083451748 + 0.7093333006 0.7093333006 0.7093333006 + 0.7103068829 0.7103068829 0.7103068829 + 0.7112507820 0.7112507820 0.7112507820 + 0.7121946812 0.7121946812 0.7121946812 + 0.7131385207 0.7131385207 0.7131385207 + 0.7140824199 0.7140824199 0.7140824199 + 0.7150263190 0.7150263190 0.7150263190 + 0.7159700990 0.7159700990 0.7159700990 + 0.7169139981 0.7169139981 0.7169139981 + 0.7178577781 0.7178577781 0.7178577781 + 0.7188016772 0.7188016772 0.7188016772 + 0.7197455764 0.7197455764 0.7197455764 + 0.7206578851 0.7206578851 0.7206578851 + 0.7215585113 0.7215585113 0.7215585113 + 0.7224591970 0.7224591970 0.7224591970 + 0.7233598828 0.7233598828 0.7233598828 + 0.7242605090 0.7242605090 0.7242605090 + 0.7251611948 0.7251611948 0.7251611948 + 0.7260618806 0.7260618806 0.7260618806 + 0.7269625068 0.7269625068 0.7269625068 + 0.7278631926 0.7278631926 0.7278631926 + 0.7287638783 0.7287638783 0.7287638783 + 0.7296645045 0.7296645045 0.7296645045 + 0.7305387855 0.7305387855 0.7305387855 + 0.7313973904 0.7313973904 0.7313973904 + 0.7322559953 0.7322559953 0.7322559953 + 0.7331146002 0.7331146002 0.7331146002 + 0.7339732051 0.7339732051 0.7339732051 + 0.7348316908 0.7348316908 0.7348316908 + 0.7356902957 0.7356902957 0.7356902957 + 0.7365489006 0.7365489006 0.7365489006 + 0.7374075055 0.7374075055 0.7374075055 + 0.7382661104 0.7382661104 0.7382661104 + 0.7391247153 0.7391247153 0.7391247153 + 0.7399833202 0.7399833202 0.7399833202 + 0.7408018112 0.7408018112 0.7408018112 + 0.7416195273 0.7416195273 0.7416195273 + 0.7424373031 0.7424373031 0.7424373031 + 0.7432550192 0.7432550192 0.7432550192 + 0.7440726757 0.7440726757 0.7440726757 + 0.7448903918 0.7448903918 0.7448903918 + 0.7457082272 0.7457082272 0.7457082272 + 0.7465258837 0.7465258837 0.7465258837 + 0.7473435998 0.7473435998 0.7473435998 + 0.7481613755 0.7481613755 0.7481613755 + 0.7489790916 0.7489790916 0.7489790916 + 0.7497968078 0.7497968078 0.7497968078 + 0.7505847812 0.7505847812 0.7505847812 + 0.7513629794 0.7513629794 0.7513629794 + 0.7521411777 0.7521411777 0.7521411777 + 0.7529193759 0.7529193759 0.7529193759 + 0.7536975145 0.7536975145 0.7536975145 + 0.7544757128 0.7544757128 0.7544757128 + 0.7552539110 0.7552539110 0.7552539110 + 0.7560319901 0.7560319901 0.7560319901 + 0.7568101883 0.7568101883 0.7568101883 + 0.7575883865 0.7575883865 0.7575883865 + 0.7583665848 0.7583665848 0.7583665848 + 0.7591447234 0.7591447234 0.7591447234 + 0.7599229217 0.7599229217 0.7599229217 + 0.7606667280 0.7606667280 0.7606667280 + 0.7614067197 0.7614067197 0.7614067197 + 0.7621465921 0.7621465921 0.7621465921 + 0.7628865838 0.7628865838 0.7628865838 + 0.7636265755 0.7636265755 0.7636265755 + 0.7643666267 0.7643666267 0.7643666267 + 0.7651066184 0.7651066184 0.7651066184 + 0.7658466101 0.7658466101 0.7658466101 + 0.7665864825 0.7665864825 0.7665864825 + 0.7673264742 0.7673264742 0.7673264742 + 0.7680665255 0.7680665255 0.7680665255 + 0.7688065171 0.7688065171 0.7688065171 + 0.7695465088 0.7695465088 0.7695465088 + 0.7702721953 0.7702721953 0.7702721953 + 0.7709754109 0.7709754109 0.7709754109 + 0.7716786265 0.7716786265 0.7716786265 + 0.7723817825 0.7723817825 0.7723817825 + 0.7730849981 0.7730849981 0.7730849981 + 0.7737882733 0.7737882733 0.7737882733 + 0.7744914889 0.7744914889 0.7744914889 + 0.7751947045 0.7751947045 0.7751947045 + 0.7758979201 0.7758979201 0.7758979201 + 0.7766010761 0.7766010761 0.7766010761 + 0.7773042917 0.7773042917 0.7773042917 + 0.7780075073 0.7780075073 0.7780075073 + 0.7787107229 0.7787107229 0.7787107229 + 0.7794138789 0.7794138789 0.7794138789 + 0.7801111937 0.7801111937 0.7801111937 + 0.7807791233 0.7807791233 0.7807791233 + 0.7814469934 0.7814469934 0.7814469934 + 0.7821149230 0.7821149230 0.7821149230 + 0.7827826738 0.7827826738 0.7827826738 + 0.7834506035 0.7834506035 0.7834506035 + 0.7841184735 0.7841184735 0.7841184735 + 0.7847864032 0.7847864032 0.7847864032 + 0.7854542136 0.7854542136 0.7854542136 + 0.7861220837 0.7861220837 0.7861220837 + 0.7867900133 0.7867900133 0.7867900133 + 0.7874578834 0.7874578834 0.7874578834 + 0.7881256938 0.7881256938 0.7881256938 + 0.7887936234 0.7887936234 0.7887936234 + 0.7894614935 0.7894614935 0.7894614935 + 0.7901228070 0.7901228070 0.7901228070 + 0.7907568216 0.7907568216 0.7907568216 + 0.7913907766 0.7913907766 0.7913907766 + 0.7920247912 0.7920247912 0.7920247912 + 0.7926588058 0.7926588058 0.7926588058 + 0.7932928801 0.7932928801 0.7932928801 + 0.7939268947 0.7939268947 0.7939268947 + 0.7945609093 0.7945609093 0.7945609093 + 0.7951949239 0.7951949239 0.7951949239 + 0.7958288789 0.7958288789 0.7958288789 + 0.7964628935 0.7964628935 0.7964628935 + 0.7970969081 0.7970969081 0.7970969081 + 0.7977309227 0.7977309227 0.7977309227 + 0.7983648777 0.7983648777 0.7983648777 + 0.7989988923 0.7989988923 0.7989988923 + 0.7996329069 0.7996329069 0.7996329069 + 0.8002532721 0.8002532721 0.8002532721 + 0.8008549213 0.8008549213 0.8008549213 + 0.8014565110 0.8014565110 0.8014565110 + 0.8020581007 0.8020581007 0.8020581007 + 0.8026596904 0.8026596904 0.8026596904 + 0.8032613993 0.8032613993 0.8032613993 + 0.8038629889 0.8038629889 0.8038629889 + 0.8044645786 0.8044645786 0.8044645786 + 0.8050662279 0.8050662279 0.8050662279 + 0.8056678176 0.8056678176 0.8056678176 + 0.8062694073 0.8062694073 0.8062694073 + 0.8068709970 0.8068709970 0.8068709970 + 0.8074725866 0.8074725866 0.8074725866 + 0.8080741763 0.8080741763 0.8080741763 + 0.8086758256 0.8086758256 0.8086758256 + 0.8092774153 0.8092774153 0.8092774153 + 0.8098791242 0.8098791242 0.8098791242 + 0.8104559183 0.8104559183 0.8104559183 + 0.8110265732 0.8110265732 0.8110265732 + 0.8115972877 0.8115972877 0.8115972877 + 0.8121680021 0.8121680021 0.8121680021 + 0.8127385974 0.8127385974 0.8127385974 + 0.8133093119 0.8133093119 0.8133093119 + 0.8138800263 0.8138800263 0.8138800263 + 0.8144506216 0.8144506216 0.8144506216 + 0.8150212765 0.8150212765 0.8150212765 + 0.8155919909 0.8155919909 0.8155919909 + 0.8161625862 0.8161625862 0.8161625862 + 0.8167333007 0.8167333007 0.8167333007 + 0.8173040152 0.8173040152 0.8173040152 + 0.8178747296 0.8178747296 0.8178747296 + 0.8184453249 0.8184453249 0.8184453249 + 0.8190159798 0.8190159798 0.8190159798 + 0.8195866942 0.8195866942 0.8195866942 + 0.8201491833 0.8201491833 0.8201491833 + 0.8206903934 0.8206903934 0.8206903934 + 0.8212316036 0.8212316036 0.8212316036 + 0.8217726946 0.8217726946 0.8217726946 + 0.8223139048 0.8223139048 0.8223139048 + 0.8228551149 0.8228551149 0.8228551149 + 0.8233962059 0.8233962059 0.8233962059 + 0.8239374161 0.8239374161 0.8239374161 + 0.8244786263 0.8244786263 0.8244786263 + 0.8250197768 0.8250197768 0.8250197768 + 0.8255609274 0.8255609274 0.8255609274 + 0.8261020780 0.8261020780 0.8261020780 + 0.8266432881 0.8266432881 0.8266432881 + 0.8271844983 0.8271844983 0.8271844983 + 0.8277255893 0.8277255893 0.8277255893 + 0.8282667994 0.8282667994 0.8282667994 + 0.8288080096 0.8288080096 0.8288080096 + 0.8293492198 0.8293492198 0.8293492198 + 0.8298903108 0.8298903108 0.8298903108 + 0.8304091096 0.8304091096 0.8304091096 + 0.8309221864 0.8309221864 0.8309221864 + 0.8314353228 0.8314353228 0.8314353228 + 0.8319483995 0.8319483995 0.8319483995 + 0.8324614763 0.8324614763 0.8324614763 + 0.8329746127 0.8329746127 0.8329746127 + 0.8334876895 0.8334876895 0.8334876895 + 0.8340008259 0.8340008259 0.8340008259 + 0.8345139027 0.8345139027 0.8345139027 + 0.8350269794 0.8350269794 0.8350269794 + 0.8355401158 0.8355401158 0.8355401158 + 0.8360531926 0.8360531926 0.8360531926 + 0.8365663290 0.8365663290 0.8365663290 + 0.8370794058 0.8370794058 0.8370794058 + 0.8375924826 0.8375924826 0.8375924826 + 0.8381056190 0.8381056190 0.8381056190 + 0.8386186957 0.8386186957 0.8386186957 + 0.8391317725 0.8391317725 0.8391317725 + 0.8396449089 0.8396449089 0.8396449089 + 0.8401497006 0.8401497006 0.8401497006 + 0.8406361938 0.8406361938 0.8406361938 + 0.8411226273 0.8411226273 0.8411226273 + 0.8416090012 0.8416090012 0.8416090012 + 0.8420953751 0.8420953751 0.8420953751 + 0.8425818086 0.8425818086 0.8425818086 + 0.8430681825 0.8430681825 0.8430681825 + 0.8435546160 0.8435546160 0.8435546160 + 0.8440409899 0.8440409899 0.8440409899 + 0.8445274234 0.8445274234 0.8445274234 + 0.8450137973 0.8450137973 0.8450137973 + 0.8455001712 0.8455001712 0.8455001712 + 0.8459866047 0.8459866047 0.8459866047 + 0.8464729786 0.8464729786 0.8464729786 + 0.8469594121 0.8469594121 0.8469594121 + 0.8474457860 0.8474457860 0.8474457860 + 0.8479322195 0.8479322195 0.8479322195 + 0.8484185934 0.8484185934 0.8484185934 + 0.8489050269 0.8489050269 0.8489050269 + 0.8493914008 0.8493914008 0.8493914008 + 0.8498777747 0.8498777747 0.8498777747 + 0.8503453135 0.8503453135 0.8503453135 + 0.8508062959 0.8508062959 0.8508062959 + 0.8512673974 0.8512673974 0.8512673974 + 0.8517283797 0.8517283797 0.8517283797 + 0.8521894813 0.8521894813 0.8521894813 + 0.8526505828 0.8526505828 0.8526505828 + 0.8531116247 0.8531116247 0.8531116247 + 0.8535727262 0.8535727262 0.8535727262 + 0.8540337086 0.8540337086 0.8540337086 + 0.8544948101 0.8544948101 0.8544948101 + 0.8549559116 0.8549559116 0.8549559116 + 0.8554168940 0.8554168940 0.8554168940 + 0.8558779955 0.8558779955 0.8558779955 + 0.8563390970 0.8563390970 0.8563390970 + 0.8568000793 0.8568000793 0.8568000793 + 0.8572611809 0.8572611809 0.8572611809 + 0.8577222228 0.8577222228 0.8577222228 + 0.8581833243 0.8581833243 0.8581833243 + 0.8586444259 0.8586444259 0.8586444259 + 0.8591054082 0.8591054082 0.8591054082 + 0.8595665097 0.8595665097 0.8595665097 + 0.8600261211 0.8600261211 0.8600261211 + 0.8604630828 0.8604630828 0.8604630828 + 0.8609001040 0.8609001040 0.8609001040 + 0.8613371849 0.8613371849 0.8613371849 + 0.8617742062 0.8617742062 0.8617742062 + 0.8622112274 0.8622112274 0.8622112274 + 0.8626481891 0.8626481891 0.8626481891 + 0.8630852103 0.8630852103 0.8630852103 + 0.8635222912 0.8635222912 0.8635222912 + 0.8639593124 0.8639593124 0.8639593124 + 0.8643962741 0.8643962741 0.8643962741 + 0.8648332953 0.8648332953 0.8648332953 + 0.8652703166 0.8652703166 0.8652703166 + 0.8657073975 0.8657073975 0.8657073975 + 0.8661444187 0.8661444187 0.8661444187 + 0.8665813804 0.8665813804 0.8665813804 + 0.8670184016 0.8670184016 0.8670184016 + 0.8674554229 0.8674554229 0.8674554229 + 0.8678925037 0.8678925037 0.8678925037 + 0.8683295250 0.8683295250 0.8683295250 + 0.8687664866 0.8687664866 0.8687664866 + 0.8692035079 0.8692035079 0.8692035079 + 0.8696405888 0.8696405888 0.8696405888 + 0.8700734973 0.8700734973 0.8700734973 + 0.8704878092 0.8704878092 0.8704878092 + 0.8709020019 0.8709020019 0.8709020019 + 0.8713161945 0.8713161945 0.8713161945 + 0.8717305064 0.8717305064 0.8717305064 + 0.8721446991 0.8721446991 0.8721446991 + 0.8725590110 0.8725590110 0.8725590110 + 0.8729732037 0.8729732037 0.8729732037 + 0.8733873963 0.8733873963 0.8733873963 + 0.8738017082 0.8738017082 0.8738017082 + 0.8742159009 0.8742159009 0.8742159009 + 0.8746302128 0.8746302128 0.8746302128 + 0.8750444055 0.8750444055 0.8750444055 + 0.8754585981 0.8754585981 0.8754585981 + 0.8758729100 0.8758729100 0.8758729100 + 0.8762871027 0.8762871027 0.8762871027 + 0.8767014146 0.8767014146 0.8767014146 + 0.8771156073 0.8771156073 0.8771156073 + 0.8775297999 0.8775297999 0.8775297999 + 0.8779441118 0.8779441118 0.8779441118 + 0.8783583045 0.8783583045 0.8783583045 + 0.8787726164 0.8787726164 0.8787726164 + 0.8791868091 0.8791868091 0.8791868091 + 0.8796010017 0.8796010017 0.8796010017 + 0.8800144792 0.8800144792 0.8800144792 + 0.8804072142 0.8804072142 0.8804072142 + 0.8807997704 0.8807997704 0.8807997704 + 0.8811925054 0.8811925054 0.8811925054 + 0.8815851808 0.8815851808 0.8815851808 + 0.8819777966 0.8819777966 0.8819777966 + 0.8823704720 0.8823704720 0.8823704720 + 0.8827632070 0.8827632070 0.8827632070 + 0.8831558228 0.8831558228 0.8831558228 + 0.8835484982 0.8835484982 0.8835484982 + 0.8839411736 0.8839411736 0.8839411736 + 0.8843337893 0.8843337893 0.8843337893 + 0.8847265244 0.8847265244 0.8847265244 + 0.8851191998 0.8851191998 0.8851191998 + 0.8855118752 0.8855118752 0.8855118752 + 0.8859044909 0.8859044909 0.8859044909 + 0.8862972260 0.8862972260 0.8862972260 + 0.8866899014 0.8866899014 0.8866899014 + 0.8870825171 0.8870825171 0.8870825171 + 0.8874751925 0.8874751925 0.8874751925 + 0.8878679276 0.8878679276 0.8878679276 + 0.8882604837 0.8882604837 0.8882604837 + 0.8886532187 0.8886532187 0.8886532187 + 0.8890458941 0.8890458941 0.8890458941 + 0.8894385099 0.8894385099 0.8894385099 + 0.8898311853 0.8898311853 0.8898311853 + 0.8902121782 0.8902121782 0.8902121782 + 0.8905845284 0.8905845284 0.8905845284 + 0.8909568191 0.8909568191 0.8909568191 + 0.8913289905 0.8913289905 0.8913289905 + 0.8917012811 0.8917012811 0.8917012811 + 0.8920735121 0.8920735121 0.8920735121 + 0.8924458027 0.8924458027 0.8924458027 + 0.8928180933 0.8928180933 0.8928180933 + 0.8931903243 0.8931903243 0.8931903243 + 0.8935626149 0.8935626149 0.8935626149 + 0.8939347863 0.8939347863 0.8939347863 + 0.8943070769 0.8943070769 0.8943070769 + 0.8946794271 0.8946794271 0.8946794271 + 0.8950515985 0.8950515985 0.8950515985 + 0.8954238892 0.8954238892 0.8954238892 + 0.8957961202 0.8957961202 0.8957961202 + 0.8961684108 0.8961684108 0.8961684108 + 0.8965405822 0.8965405822 0.8965405822 + 0.8969128728 0.8969128728 0.8969128728 + 0.8972852230 0.8972852230 0.8972852230 + 0.8976573944 0.8976573944 0.8976573944 + 0.8980296850 0.8980296850 0.8980296850 + 0.8984019160 0.8984019160 0.8984019160 + 0.8987742066 0.8987742066 0.8987742066 + 0.8991464972 0.8991464972 0.8991464972 + 0.8995187283 0.8995187283 0.8995187283 + 0.8998910189 0.8998910189 0.8998910189 + 0.9002496004 0.9002496004 0.9002496004 + 0.9006025195 0.9006025195 0.9006025195 + 0.9009554982 0.9009554982 0.9009554982 + 0.9013084769 0.9013084769 0.9013084769 + 0.9016613960 0.9016613960 0.9016613960 + 0.9020143747 0.9020143747 0.9020143747 + 0.9023672938 0.9023672938 0.9023672938 + 0.9027202725 0.9027202725 0.9027202725 + 0.9030731916 0.9030731916 0.9030731916 + 0.9034261703 0.9034261703 0.9034261703 + 0.9037792087 0.9037792087 0.9037792087 + 0.9041321278 0.9041321278 0.9041321278 + 0.9044851065 0.9044851065 0.9044851065 + 0.9048380256 0.9048380256 0.9048380256 + 0.9051910043 0.9051910043 0.9051910043 + 0.9055439234 0.9055439234 0.9055439234 + 0.9058969021 0.9058969021 0.9058969021 + 0.9062498808 0.9062498808 0.9062498808 + 0.9066027999 0.9066027999 0.9066027999 + 0.9069557786 0.9069557786 0.9069557786 + 0.9073086977 0.9073086977 0.9073086977 + 0.9076616764 0.9076616764 0.9076616764 + 0.9080145955 0.9080145955 0.9080145955 + 0.9083675742 0.9083675742 0.9083675742 + 0.9087206125 0.9087206125 0.9087206125 + 0.9090734720 0.9090734720 0.9090734720 + 0.9094265103 0.9094265103 0.9094265103 + 0.9097794294 0.9097794294 0.9097794294 + 0.9101254940 0.9101254940 0.9101254940 + 0.9104602933 0.9104602933 0.9104602933 + 0.9107949734 0.9107949734 0.9107949734 + 0.9111297131 0.9111297131 0.9111297131 + 0.9114643931 0.9114643931 0.9114643931 + 0.9117990732 0.9117990732 0.9117990732 + 0.9121338129 0.9121338129 0.9121338129 + 0.9124684930 0.9124684930 0.9124684930 + 0.9128032923 0.9128032923 0.9128032923 + 0.9131379724 0.9131379724 0.9131379724 + 0.9134727120 0.9134727120 0.9134727120 + 0.9138073921 0.9138073921 0.9138073921 + 0.9141420722 0.9141420722 0.9141420722 + 0.9144768119 0.9144768119 0.9144768119 + 0.9148114920 0.9148114920 0.9148114920 + 0.9151462913 0.9151462913 0.9151462913 + 0.9154809713 0.9154809713 0.9154809713 + 0.9158157110 0.9158157110 0.9158157110 + 0.9161503911 0.9161503911 0.9161503911 + 0.9164850712 0.9164850712 0.9164850712 + 0.9168198109 0.9168198109 0.9168198109 + 0.9171544909 0.9171544909 0.9171544909 + 0.9174892902 0.9174892902 0.9174892902 + 0.9178239703 0.9178239703 0.9178239703 + 0.9181587100 0.9181587100 0.9181587100 + 0.9184933901 0.9184933901 0.9184933901 + 0.9188281298 0.9188281298 0.9188281298 + 0.9191628098 0.9191628098 0.9191628098 + 0.9194974899 0.9194974899 0.9194974899 + 0.9198322892 0.9198322892 0.9198322892 + 0.9201583862 0.9201583862 0.9201583862 + 0.9204757810 0.9204757810 0.9204757810 + 0.9207932949 0.9207932949 0.9207932949 + 0.9211108088 0.9211108088 0.9211108088 + 0.9214283228 0.9214283228 0.9214283228 + 0.9217457771 0.9217457771 0.9217457771 + 0.9220631719 0.9220631719 0.9220631719 + 0.9223806858 0.9223806858 0.9223806858 + 0.9226981997 0.9226981997 0.9226981997 + 0.9230157137 0.9230157137 0.9230157137 + 0.9233332276 0.9233332276 0.9233332276 + 0.9236506224 0.9236506224 0.9236506224 + 0.9239680767 0.9239680767 0.9239680767 + 0.9242855906 0.9242855906 0.9242855906 + 0.9246031046 0.9246031046 0.9246031046 + 0.9249204993 0.9249204993 0.9249204993 + 0.9252380133 0.9252380133 0.9252380133 + 0.9255555272 0.9255555272 0.9255555272 + 0.9258729815 0.9258729815 0.9258729815 + 0.9261904955 0.9261904955 0.9261904955 + 0.9265078902 0.9265078902 0.9265078902 + 0.9268254042 0.9268254042 0.9268254042 + 0.9271429181 0.9271429181 0.9271429181 + 0.9274603724 0.9274603724 0.9274603724 + 0.9277778268 0.9277778268 0.9277778268 + 0.9280952811 0.9280952811 0.9280952811 + 0.9284127951 0.9284127951 0.9284127951 + 0.9287303090 0.9287303090 0.9287303090 + 0.9290478230 0.9290478230 0.9290478230 + 0.9293652177 0.9293652177 0.9293652177 + 0.9296826720 0.9296826720 0.9296826720 + 0.9300001860 0.9300001860 0.9300001860 + 0.9303014278 0.9303014278 0.9303014278 + 0.9306026101 0.9306026101 0.9306026101 + 0.9309037924 0.9309037924 0.9309037924 + 0.9312049747 0.9312049747 0.9312049747 + 0.9315062165 0.9315062165 0.9315062165 + 0.9318073988 0.9318073988 0.9318073988 + 0.9321085811 0.9321085811 0.9321085811 + 0.9324098229 0.9324098229 0.9324098229 + 0.9327110052 0.9327110052 0.9327110052 + 0.9330121875 0.9330121875 0.9330121875 + 0.9333134294 0.9333134294 0.9333134294 + 0.9336146116 0.9336146116 0.9336146116 + 0.9339157939 0.9339157939 0.9339157939 + 0.9342169762 0.9342169762 0.9342169762 + 0.9345182180 0.9345182180 0.9345182180 + 0.9348194003 0.9348194003 0.9348194003 + 0.9351205826 0.9351205826 0.9351205826 + 0.9354218245 0.9354218245 0.9354218245 + 0.9357230067 0.9357230067 0.9357230067 + 0.9360241890 0.9360241890 0.9360241890 + 0.9363253713 0.9363253713 0.9363253713 + 0.9366264939 0.9366264939 0.9366264939 + 0.9369276762 0.9369276762 0.9369276762 + 0.9372289181 0.9372289181 0.9372289181 + 0.9375301003 0.9375301003 0.9375301003 + 0.9378312826 0.9378312826 0.9378312826 + 0.9381325245 0.9381325245 0.9381325245 + 0.9384337068 0.9384337068 0.9384337068 + 0.9387348890 0.9387348890 0.9387348890 + 0.9390360713 0.9390360713 0.9390360713 + 0.9393373132 0.9393373132 0.9393373132 + 0.9396384954 0.9396384954 0.9396384954 + 0.9399396777 0.9399396777 0.9399396777 + 0.9402285814 0.9402285814 0.9402285814 + 0.9405145049 0.9405145049 0.9405145049 + 0.9408003092 0.9408003092 0.9408003092 + 0.9410861135 0.9410861135 0.9410861135 + 0.9413719177 0.9413719177 0.9413719177 + 0.9416577816 0.9416577816 0.9416577816 + 0.9419435859 0.9419435859 0.9419435859 + 0.9422293901 0.9422293901 0.9422293901 + 0.9425153136 0.9425153136 0.9425153136 + 0.9428011179 0.9428011179 0.9428011179 + 0.9430869222 0.9430869222 0.9430869222 + 0.9433727264 0.9433727264 0.9433727264 + 0.9436585903 0.9436585903 0.9436585903 + 0.9439443946 0.9439443946 0.9439443946 + 0.9442301989 0.9442301989 0.9442301989 + 0.9445160031 0.9445160031 0.9445160031 + 0.9448019266 0.9448019266 0.9448019266 + 0.9450876713 0.9450876713 0.9450876713 + 0.9453734756 0.9453734756 0.9453734756 + 0.9456593990 0.9456593990 0.9456593990 + 0.9459452033 0.9459452033 0.9459452033 + 0.9462310076 0.9462310076 0.9462310076 + 0.9465168118 0.9465168118 0.9465168118 + 0.9468026757 0.9468026757 0.9468026757 + 0.9470884800 0.9470884800 0.9470884800 + 0.9473742843 0.9473742843 0.9473742843 + 0.9476600885 0.9476600885 0.9476600885 + 0.9479460120 0.9479460120 0.9479460120 + 0.9482318163 0.9482318163 0.9482318163 + 0.9485176206 0.9485176206 0.9485176206 + 0.9488034248 0.9488034248 0.9488034248 + 0.9490892887 0.9490892887 0.9490892887 + 0.9493750930 0.9493750930 0.9493750930 + 0.9496608973 0.9496608973 0.9496608973 + 0.9499468207 0.9499468207 0.9499468207 + 0.9502208233 0.9502208233 0.9502208233 + 0.9504920840 0.9504920840 0.9504920840 + 0.9507634044 0.9507634044 0.9507634044 + 0.9510347247 0.9510347247 0.9510347247 + 0.9513059855 0.9513059855 0.9513059855 + 0.9515774250 0.9515774250 0.9515774250 + 0.9518486857 0.9518486857 0.9518486857 + 0.9521200061 0.9521200061 0.9521200061 + 0.9523913264 0.9523913264 0.9523913264 + 0.9526625872 0.9526625872 0.9526625872 + 0.9529339075 0.9529339075 0.9529339075 + 0.9532052279 0.9532052279 0.9532052279 + 0.9534766078 0.9534766078 0.9534766078 + 0.9537479281 0.9537479281 0.9537479281 + 0.9540191889 0.9540191889 0.9540191889 + 0.9542905092 0.9542905092 0.9542905092 + 0.9545618296 0.9545618296 0.9545618296 + 0.9548330903 0.9548330903 0.9548330903 + 0.9551044106 0.9551044106 0.9551044106 + 0.9553757906 0.9553757906 0.9553757906 + 0.9556471109 0.9556471109 0.9556471109 + 0.9559183717 0.9559183717 0.9559183717 + 0.9561896920 0.9561896920 0.9561896920 + 0.9564610124 0.9564610124 0.9564610124 + 0.9567322731 0.9567322731 0.9567322731 + 0.9570037127 0.9570037127 0.9570037127 + 0.9572749734 0.9572749734 0.9572749734 + 0.9575462937 0.9575462937 0.9575462937 + 0.9578176141 0.9578176141 0.9578176141 + 0.9580888748 0.9580888748 0.9580888748 + 0.9583601952 0.9583601952 0.9583601952 + 0.9586315155 0.9586315155 0.9586315155 + 0.9589028955 0.9589028955 0.9589028955 + 0.9591742158 0.9591742158 0.9591742158 + 0.9594454765 0.9594454765 0.9594454765 + 0.9597167969 0.9597167969 0.9597167969 + 0.9599881172 0.9599881172 0.9599881172 + 0.9602463245 0.9602463245 0.9602463245 + 0.9605039954 0.9605039954 0.9605039954 + 0.9607616067 0.9607616067 0.9607616067 + 0.9610192180 0.9610192180 0.9610192180 + 0.9612768292 0.9612768292 0.9612768292 + 0.9615343809 0.9615343809 0.9615343809 + 0.9617919922 0.9617919922 0.9617919922 + 0.9620497227 0.9620497227 0.9620497227 + 0.9623072743 0.9623072743 0.9623072743 + 0.9625648856 0.9625648856 0.9625648856 + 0.9628224969 0.9628224969 0.9628224969 + 0.9630801082 0.9630801082 0.9630801082 + 0.9633377194 0.9633377194 0.9633377194 + 0.9635953903 0.9635953903 0.9635953903 + 0.9638530016 0.9638530016 0.9638530016 + 0.9641106129 0.9641106129 0.9641106129 + 0.9643682241 0.9643682241 0.9643682241 + 0.9646257758 0.9646257758 0.9646257758 + 0.9648833871 0.9648833871 0.9648833871 + 0.9651411176 0.9651411176 0.9651411176 + 0.9653987288 0.9653987288 0.9653987288 + 0.9656562805 0.9656562805 0.9656562805 + 0.9659138918 0.9659138918 0.9659138918 + 0.9661715031 0.9661715031 0.9661715031 + 0.9664291143 0.9664291143 0.9664291143 + 0.9666867852 0.9666867852 0.9666867852 + 0.9669443965 0.9669443965 0.9669443965 + 0.9672020078 0.9672020078 0.9672020078 + 0.9674596190 0.9674596190 0.9674596190 + 0.9677171707 0.9677171707 0.9677171707 + 0.9679747820 0.9679747820 0.9679747820 + 0.9682325125 0.9682325125 0.9682325125 + 0.9684901237 0.9684901237 0.9684901237 + 0.9687476754 0.9687476754 0.9687476754 + 0.9690052867 0.9690052867 0.9690052867 + 0.9692628980 0.9692628980 0.9692628980 + 0.9695205092 0.9695205092 0.9695205092 + 0.9697781801 0.9697781801 0.9697781801 + 0.9700340033 0.9700340033 0.9700340033 + 0.9702786803 0.9702786803 0.9702786803 + 0.9705232978 0.9705232978 0.9705232978 + 0.9707679749 0.9707679749 0.9707679749 + 0.9710127115 0.9710127115 0.9710127115 + 0.9712573886 0.9712573886 0.9712573886 + 0.9715021253 0.9715021253 0.9715021253 + 0.9717468023 0.9717468023 0.9717468023 + 0.9719914794 0.9719914794 0.9719914794 + 0.9722362161 0.9722362161 0.9722362161 + 0.9724807739 0.9724807739 0.9724807739 + 0.9727255106 0.9727255106 0.9727255106 + 0.9729701877 0.9729701877 0.9729701877 + 0.9732149243 0.9732149243 0.9732149243 + 0.9734596014 0.9734596014 0.9734596014 + 0.9737042785 0.9737042785 0.9737042785 + 0.9739490151 0.9739490151 0.9739490151 + 0.9741935730 0.9741935730 0.9741935730 + 0.9744383097 0.9744383097 0.9744383097 + 0.9746829867 0.9746829867 0.9746829867 + 0.9749277234 0.9749277234 0.9749277234 + 0.9751724005 0.9751724005 0.9751724005 + 0.9754170775 0.9754170775 0.9754170775 + 0.9756618142 0.9756618142 0.9756618142 + 0.9759064913 0.9759064913 0.9759064913 + 0.9761511087 0.9761511087 0.9761511087 + 0.9763957858 0.9763957858 0.9763957858 + 0.9766405225 0.9766405225 0.9766405225 + 0.9768851995 0.9768851995 0.9768851995 + 0.9771298766 0.9771298766 0.9771298766 + 0.9773746133 0.9773746133 0.9773746133 + 0.9776192904 0.9776192904 0.9776192904 + 0.9778640270 0.9778640270 0.9778640270 + 0.9781085849 0.9781085849 0.9781085849 + 0.9783533216 0.9783533216 0.9783533216 + 0.9785979986 0.9785979986 0.9785979986 + 0.9788426757 0.9788426757 0.9788426757 + 0.9790874124 0.9790874124 0.9790874124 + 0.9793320894 0.9793320894 0.9793320894 + 0.9795768261 0.9795768261 0.9795768261 + 0.9798213840 0.9798213840 0.9798213840 + 0.9800627828 0.9800627828 0.9800627828 + 0.9802953005 0.9802953005 0.9802953005 + 0.9805278182 0.9805278182 0.9805278182 + 0.9807602763 0.9807602763 0.9807602763 + 0.9809927940 0.9809927940 0.9809927940 + 0.9812251925 0.9812251925 0.9812251925 + 0.9814577103 0.9814577103 0.9814577103 + 0.9816902280 0.9816902280 0.9816902280 + 0.9819226861 0.9819226861 0.9819226861 + 0.9821552038 0.9821552038 0.9821552038 + 0.9823877215 0.9823877215 0.9823877215 + 0.9826201200 0.9826201200 0.9826201200 + 0.9828525782 0.9828525782 0.9828525782 + 0.9830850959 0.9830850959 0.9830850959 + 0.9833176136 0.9833176136 0.9833176136 + 0.9835500717 0.9835500717 0.9835500717 + 0.9837825894 0.9837825894 0.9837825894 + 0.9840149879 0.9840149879 0.9840149879 + 0.9842475057 0.9842475057 0.9842475057 + 0.9844800234 0.9844800234 0.9844800234 + 0.9847124815 0.9847124815 0.9847124815 + 0.9849449992 0.9849449992 0.9849449992 + 0.9851775169 0.9851775169 0.9851775169 + 0.9854099154 0.9854099154 0.9854099154 + 0.9856423736 0.9856423736 0.9856423736 + 0.9858748913 0.9858748913 0.9858748913 + 0.9861074090 0.9861074090 0.9861074090 + 0.9863399267 0.9863399267 0.9863399267 + 0.9865723848 0.9865723848 0.9865723848 + 0.9868047833 0.9868047833 0.9868047833 + 0.9870373011 0.9870373011 0.9870373011 + 0.9872698188 0.9872698188 0.9872698188 + 0.9875022769 0.9875022769 0.9875022769 + 0.9877347946 0.9877347946 0.9877347946 + 0.9879673123 0.9879673123 0.9879673123 + 0.9881997108 0.9881997108 0.9881997108 + 0.9884322286 0.9884322286 0.9884322286 + 0.9886646867 0.9886646867 0.9886646867 + 0.9888972044 0.9888972044 0.9888972044 + 0.9891297221 0.9891297221 0.9891297221 + 0.9893621206 0.9893621206 0.9893621206 + 0.9895945787 0.9895945787 0.9895945787 + 0.9898270965 0.9898270965 0.9898270965 + 0.9900565743 0.9900565743 0.9900565743 + 0.9902775884 0.9902775884 0.9902775884 + 0.9904986024 0.9904986024 0.9904986024 + 0.9907194972 0.9907194972 0.9907194972 + 0.9909405112 0.9909405112 0.9909405112 + 0.9911615252 0.9911615252 0.9911615252 + 0.9913824201 0.9913824201 0.9913824201 + 0.9916033745 0.9916033745 0.9916033745 + 0.9918243885 0.9918243885 0.9918243885 + 0.9920452833 0.9920452833 0.9920452833 + 0.9922662973 0.9922662973 0.9922662973 + 0.9924871922 0.9924871922 0.9924871922 + 0.9927082062 0.9927082062 0.9927082062 + 0.9929292202 0.9929292202 0.9929292202 + 0.9931501150 0.9931501150 0.9931501150 + 0.9933711290 0.9933711290 0.9933711290 + 0.9935920835 0.9935920835 0.9935920835 + 0.9938129783 0.9938129783 0.9938129783 + 0.9940339923 0.9940339923 0.9940339923 + 0.9942548871 0.9942548871 0.9942548871 + 0.9944759011 0.9944759011 0.9944759011 + 0.9946969151 0.9946969151 0.9946969151 + 0.9949178100 0.9949178100 0.9949178100 + 0.9951388240 0.9951388240 0.9951388240 + 0.9953597784 0.9953597784 0.9953597784 + 0.9955806732 0.9955806732 0.9955806732 + 0.9958016872 0.9958016872 0.9958016872 + 0.9960227013 0.9960227013 0.9960227013 + 0.9962435961 0.9962435961 0.9962435961 + 0.9964646101 0.9964646101 0.9964646101 + 0.9966855049 0.9966855049 0.9966855049 + 0.9969065189 0.9969065189 0.9969065189 + 0.9971274734 0.9971274734 0.9971274734 + 0.9973484278 0.9973484278 0.9973484278 + 0.9975693822 0.9975693822 0.9975693822 + 0.9977903962 0.9977903962 0.9977903962 + 0.9980112910 0.9980112910 0.9980112910 + 0.9982323050 0.9982323050 0.9982323050 + 0.9984533191 0.9984533191 0.9984533191 + 0.9986742139 0.9986742139 0.9986742139 + 0.9988952279 0.9988952279 0.9988952279 + 0.9991161227 0.9991161227 0.9991161227 + 0.9993370771 0.9993370771 0.9993370771 + 0.9995580912 0.9995580912 0.9995580912 + 0.9997789860 0.9997789860 0.9997789860 + 1.0000000000 1.0000000000 1.0000000000 +} diff --git a/rpplugins/color_correction/resources/film_luts_raw/kodak_dscs_3156.spi1d b/rpplugins/color_correction/resources/film_luts_raw/kodak_dscs_3156.spi1d new file mode 100644 index 0000000..5f4ce9f --- /dev/null +++ b/rpplugins/color_correction/resources/film_luts_raw/kodak_dscs_3156.spi1d @@ -0,0 +1,1030 @@ +Version 1 +From 0.0 1.0 +Length 1024 +Components 3 +{ + 0.0000000000 0.0000000000 0.0000000000 + 0.0012913510 0.0008980598 0.0004710060 + 0.0025827030 0.0017961200 0.0009420120 + 0.0038740539 0.0026941791 0.0014130180 + 0.0051654060 0.0035922390 0.0018840240 + 0.0064567570 0.0044902992 0.0023550300 + 0.0077481088 0.0053883591 0.0028260360 + 0.0090394598 0.0062864190 0.0032970421 + 0.0103690401 0.0071844789 0.0037680480 + 0.0118096303 0.0080825379 0.0042390539 + 0.0132502196 0.0089805983 0.0047100601 + 0.0146908201 0.0098786578 0.0051810662 + 0.0161314104 0.0108593097 0.0056520719 + 0.0175720006 0.0118528605 0.0061230781 + 0.0190125909 0.0128464103 0.0065940842 + 0.0205063205 0.0138399703 0.0070650899 + 0.0221158192 0.0148335202 0.0075360960 + 0.0237253308 0.0158270709 0.0080071017 + 0.0253348406 0.0168206207 0.0084781079 + 0.0269443505 0.0178141799 0.0089491140 + 0.0285538603 0.0188077297 0.0094201202 + 0.0301827304 0.0198012795 0.0098911263 + 0.0319830701 0.0208809301 0.0103980303 + 0.0337834209 0.0219821204 0.0109157199 + 0.0355837606 0.0230832994 0.0114334105 + 0.0373841003 0.0241844803 0.0119511103 + 0.0391844399 0.0252856594 0.0124687999 + 0.0411023311 0.0263868403 0.0129864896 + 0.0431175716 0.0274880193 0.0135041801 + 0.0451328084 0.0285892002 0.0140218800 + 0.0471480489 0.0296903793 0.0145395696 + 0.0491632894 0.0308787897 0.0150572602 + 0.0513193496 0.0321012996 0.0155749600 + 0.0535753891 0.0333238207 0.0160926506 + 0.0558314398 0.0345463417 0.0166103393 + 0.0580874793 0.0357688516 0.0171280298 + 0.0603842996 0.0369913690 0.0176457297 + 0.0629082322 0.0382138900 0.0181634203 + 0.0654321536 0.0394364111 0.0186811108 + 0.0679560676 0.0407326184 0.0191988107 + 0.0705360919 0.0420918800 0.0197164994 + 0.0733550414 0.0434511304 0.0202579591 + 0.0761739910 0.0448103808 0.0208282005 + 0.0789929330 0.0461696312 0.0213984400 + 0.0820178986 0.0475288890 0.0219686702 + 0.0851573721 0.0488881394 0.0225389097 + 0.0882968530 0.0502754003 0.0231091492 + 0.0915927812 0.0517885610 0.0236793794 + 0.0950742513 0.0533017218 0.0242496207 + 0.0985557213 0.0548148789 0.0248198602 + 0.1022457033 0.0563280284 0.0253900904 + 0.1060836017 0.0578411892 0.0259603299 + 0.1099215001 0.0593543500 0.0265305694 + 0.1141121984 0.0609665997 0.0271007996 + 0.1183103025 0.0626525879 0.0276710391 + 0.1227174997 0.0643385872 0.0282412805 + 0.1272657067 0.0660245866 0.0288115107 + 0.1319428980 0.0677105933 0.0293817502 + 0.1368145049 0.0693965778 0.0299519897 + 0.1417827010 0.0712067708 0.0305764992 + 0.1469336003 0.0730861723 0.0312060006 + 0.1521732956 0.0749655813 0.0318355002 + 0.1575435996 0.0768449828 0.0324649997 + 0.1629938930 0.0787243918 0.0330944993 + 0.1685118973 0.0806729570 0.0337239988 + 0.1740811020 0.0827676505 0.0343534984 + 0.1796693951 0.0848623365 0.0349830016 + 0.1852522939 0.0869570300 0.0356125012 + 0.1908237040 0.0890517235 0.0362420008 + 0.1963316947 0.0912766010 0.0368715003 + 0.2017958015 0.0936091468 0.0375009999 + 0.2071722001 0.0959417075 0.0381304994 + 0.2124657035 0.0982742608 0.0387599990 + 0.2176671028 0.1006745026 0.0393894985 + 0.2227557003 0.1032672003 0.0400210209 + 0.2277524024 0.1058600023 0.0407175012 + 0.2326270938 0.1084527001 0.0414139815 + 0.2374019027 0.1111586019 0.0421104617 + 0.2420724034 0.1140320972 0.0428069495 + 0.2466181964 0.1169055998 0.0435034297 + 0.2511056960 0.1197791025 0.0441999100 + 0.2554233968 0.1229275018 0.0448963903 + 0.2597410083 0.1260987967 0.0455928706 + 0.2638502121 0.1292701066 0.0462893508 + 0.2679460049 0.1326791048 0.0469858386 + 0.2719362974 0.1361591071 0.0476823188 + 0.2758204043 0.1396390945 0.0483787991 + 0.2797045112 0.1433980018 0.0490752794 + 0.2834044099 0.1471890956 0.0497717597 + 0.2870891094 0.1510583013 0.0505192392 + 0.2907347083 0.1551516056 0.0512915812 + 0.2942334116 0.1592448950 0.0520639084 + 0.2977321148 0.1635666043 0.0528362505 + 0.3011702895 0.1679400951 0.0536085814 + 0.3044967949 0.1724427938 0.0543809198 + 0.3078233004 0.1770606041 0.0551532507 + 0.3110949993 0.1817495972 0.0559255891 + 0.3142628968 0.1865632981 0.0566979311 + 0.3174307942 0.1914165020 0.0574702583 + 0.3205712140 0.1963680983 0.0582426004 + 0.3235935867 0.2013394982 0.0590149313 + 0.3266159892 0.2063657045 0.0597872697 + 0.3296383023 0.2113949060 0.0606219508 + 0.3325434029 0.2164323032 0.0614803396 + 0.3354324996 0.2214559019 0.0623387285 + 0.3383215964 0.2264461070 0.0631971210 + 0.3411597013 0.2314081937 0.0640555099 + 0.3439269960 0.2363009006 0.0649138913 + 0.3466942906 0.2411601990 0.0657722801 + 0.3494617045 0.2459158003 0.0666306689 + 0.3521394134 0.2506479919 0.0674890578 + 0.3547956049 0.2552376986 0.0683474466 + 0.3574517071 0.2598274946 0.0692058429 + 0.3601036966 0.2642399073 0.0700715408 + 0.3626584113 0.2686452866 0.0710277036 + 0.3652130067 0.2729164064 0.0719838589 + 0.3677676022 0.2771278918 0.0729400069 + 0.3703106046 0.2812767923 0.0738961697 + 0.3727726042 0.2852917016 0.0748523325 + 0.3752346039 0.2893066108 0.0758084878 + 0.3776965141 0.2931610048 0.0767646432 + 0.3801530898 0.2969819903 0.0777207986 + 0.3825305104 0.3007636070 0.0786769614 + 0.3849078119 0.3043971956 0.0796331167 + 0.3872852027 0.3080308139 0.0806578100 + 0.3896625936 0.3115825951 0.0817251801 + 0.3919736147 0.3150376081 0.0827925429 + 0.3942736089 0.3184925914 0.0838598981 + 0.3965736926 0.3218528032 0.0849272683 + 0.3988736868 0.3251396120 0.0859946311 + 0.4011375904 0.3284263909 0.0870619863 + 0.4033668935 0.3316313028 0.0881293565 + 0.4055961072 0.3347609043 0.0891967192 + 0.4078254104 0.3378903866 0.0902953967 + 0.4100531042 0.3409723938 0.0914893299 + 0.4122174084 0.3439559937 0.0926832631 + 0.4143818021 0.3469395041 0.0938771889 + 0.4165461957 0.3499230146 0.0950711221 + 0.4187105894 0.3527748883 0.0962650478 + 0.4208509922 0.3556233943 0.0974589810 + 0.4229558110 0.3584718108 0.0986529067 + 0.4250606000 0.3612624109 0.0998468399 + 0.4271655083 0.3639861941 0.1011663005 + 0.4292702973 0.3667100072 0.1025042981 + 0.4313394129 0.3694337904 0.1038423032 + 0.4333893955 0.3720667064 0.1051801965 + 0.4354394078 0.3746758103 0.1065182015 + 0.4374893904 0.3772849143 0.1078561991 + 0.4395394921 0.3798938990 0.1091940999 + 0.4415503144 0.3824017942 0.1105972007 + 0.4435496926 0.3849053979 0.1120989993 + 0.4455491900 0.3874089122 0.1136007011 + 0.4475485981 0.3899124861 0.1151024029 + 0.4495480955 0.3923225105 0.1166040972 + 0.4515112042 0.3947291076 0.1181057990 + 0.4534637928 0.3971355855 0.1196075976 + 0.4554164112 0.3995422125 0.1212465018 + 0.4573689997 0.4018765986 0.1229339987 + 0.4593215883 0.4041940868 0.1246215031 + 0.4612458050 0.4065114856 0.1263090074 + 0.4631549120 0.4088290036 0.1279965043 + 0.4650638998 0.4111058116 0.1296840012 + 0.4669730067 0.4133413136 0.1315421015 + 0.4688819945 0.4155766964 0.1334394962 + 0.4707742035 0.4178121984 0.1353369951 + 0.4726425111 0.4200460017 0.1372344047 + 0.4745109081 0.4222060144 0.1391319036 + 0.4763793051 0.4243659079 0.1411572993 + 0.4782476127 0.4265258014 0.1432905942 + 0.4801135957 0.4286858141 0.1454239935 + 0.4819437861 0.4308184981 0.1475573033 + 0.4837738872 0.4329088032 0.1496907026 + 0.4856041074 0.4349991083 0.1520487964 + 0.4874342084 0.4370894134 0.1544450074 + 0.4892643988 0.4391798079 0.1568412036 + 0.4910728931 0.4412310123 0.1592375040 + 0.4928669035 0.4432570040 0.1618310958 + 0.4946610034 0.4452829957 0.1645168066 + 0.4964550138 0.4473089874 0.1672026068 + 0.4982489944 0.4493350089 0.1698883027 + 0.5000422001 0.4513210058 0.1728748977 + 0.5018019080 0.4532875121 0.1758745015 + 0.5035614967 0.4552539885 0.1788741052 + 0.5053212047 0.4572204053 0.1820818037 + 0.5070807934 0.4591869116 0.1854145974 + 0.5088403821 0.4611209929 0.1887473017 + 0.5105888247 0.4630320966 0.1922948956 + 0.5123155117 0.4649432898 0.1959716976 + 0.5140420794 0.4668545127 0.1996484995 + 0.5157688260 0.4687657058 0.2036353946 + 0.5174953938 0.4706586897 0.2076551020 + 0.5192220807 0.4725184143 0.2118106931 + 0.5209311843 0.4743781090 0.2161566019 + 0.5226259232 0.4762378037 0.2205363065 + 0.5243206024 0.4780975878 0.2251745015 + 0.5260154009 0.4799573123 0.2298126072 + 0.5277100801 0.4817700088 0.2346820980 + 0.5294048190 0.4835816026 0.2395613045 + 0.5310792923 0.4853931963 0.2446004003 + 0.5327429175 0.4872049093 0.2496553957 + 0.5344064832 0.4890165031 0.2548052073 + 0.5360699892 0.4908075035 0.2599619925 + 0.5377336144 0.4925738871 0.2651447952 + 0.5393971205 0.4943403900 0.2703250945 + 0.5410410762 0.4961068928 0.2754637897 + 0.5426740050 0.4978733957 0.2805902958 + 0.5443068743 0.4996398985 0.2856245041 + 0.5459396839 0.5013725162 0.2906390131 + 0.5475726128 0.5030964017 0.2955218852 + 0.5492054224 0.5048202872 0.3003894985 + 0.5508226156 0.5065442920 0.3050881028 + 0.5524250269 0.5082681775 0.3097867072 + 0.5540273190 0.5099921227 0.3142902851 + 0.5556296706 0.5116760135 0.3187845051 + 0.5572320223 0.5133596063 0.3231228888 + 0.5588343740 0.5150431991 0.3274034858 + 0.5604283810 0.5167267919 0.3315997124 + 0.5620002151 0.5184103847 0.3356657028 + 0.5635718703 0.5200918913 0.3397318125 + 0.5651437044 0.5217370987 0.3436022103 + 0.5667154193 0.5233823061 0.3474588096 + 0.5682871938 0.5250275135 0.3512471020 + 0.5698590279 0.5266727209 0.3549034894 + 0.5714026093 0.5283179283 0.3585597873 + 0.5729435086 0.5299631953 0.3621017039 + 0.5744842887 0.5315724015 0.3655692935 + 0.5760251880 0.5331807733 0.3690369129 + 0.5775660276 0.5347892046 0.3723773956 + 0.5791069269 0.5363975167 0.3756690919 + 0.5806344748 0.5380058885 0.3789606988 + 0.5821440220 0.5396143198 0.3821411133 + 0.5836533904 0.5411956906 0.3852699995 + 0.5851628184 0.5427685976 0.3883990049 + 0.5866721869 0.5443415046 0.3914547861 + 0.5881816745 0.5459142923 0.3944340944 + 0.5896911025 0.5474871993 0.3974134028 + 0.5911749005 0.5490601063 0.4003747106 + 0.5926522017 0.5506191254 0.4032168984 + 0.5941295028 0.5521575212 0.4060590863 + 0.5956066847 0.5536959171 0.4089013040 + 0.5970839858 0.5552341938 0.4116666019 + 0.5985612869 0.5567725897 0.4143835008 + 0.6000376940 0.5583109856 0.4171003997 + 0.6014819145 0.5598493814 0.4198172987 + 0.6029260755 0.5613573790 0.4224275053 + 0.6043702960 0.5628619790 0.4250301123 + 0.6058145761 0.5643666983 0.4276326001 + 0.6072587967 0.5658714175 0.4302257001 + 0.6087030172 0.5673760772 0.4327239990 + 0.6101437807 0.5688806772 0.4352222979 + 0.6115540266 0.5703768730 0.4377205968 + 0.6129640937 0.5718483925 0.4402106106 + 0.6143742800 0.5733199120 0.4426138103 + 0.6157845259 0.5747913718 0.4450170994 + 0.6171945930 0.5762628913 0.4474202991 + 0.6186047792 0.5777344108 0.4498234987 + 0.6200146079 0.5792058706 0.4521464109 + 0.6213896275 0.5806623101 0.4544628859 + 0.6227645874 0.5821009278 0.4567793906 + 0.6241396070 0.5835396051 0.4590958953 + 0.6255146265 0.5849782228 0.4613640904 + 0.6268895864 0.5864169002 0.4636014104 + 0.6282646060 0.5878555179 0.4658387005 + 0.6296396255 0.5892940760 0.4680759907 + 0.6309878230 0.5907161236 0.4703032076 + 0.6323264837 0.5921220183 0.4724679887 + 0.6336652040 0.5935279727 0.4746327996 + 0.6350039244 0.5949339271 0.4767976999 + 0.6363425255 0.5963398218 0.4789625108 + 0.6376811862 0.5977457166 0.4810926914 + 0.6390199065 0.5991516113 0.4831911922 + 0.6403484941 0.6005445123 0.4852896035 + 0.6416497231 0.6019176841 0.4873880148 + 0.6429507732 0.6032907963 0.4894863963 + 0.6442520022 0.6046640277 0.4915387034 + 0.6455531716 0.6060370803 0.4935761094 + 0.6468542814 0.6074103117 0.4956134856 + 0.6481555104 0.6087834239 0.4976508021 + 0.6494566202 0.6101527810 0.4996882081 + 0.6507353187 0.6114928722 0.5016778708 + 0.6519978046 0.6128330827 0.5036588907 + 0.6532601714 0.6141732931 0.5056399703 + 0.6545227170 0.6155133843 0.5076211095 + 0.6557852030 0.6168535948 0.5096021295 + 0.6570476890 0.6181936860 0.5115414858 + 0.6583101749 0.6195338964 0.5134704709 + 0.6595727205 0.6208522916 0.5153993964 + 0.6608088017 0.6221591830 0.5173283815 + 0.6620315909 0.6234660149 0.5192573071 + 0.6632543206 0.6247729063 0.5211564898 + 0.6644769907 0.6260796785 0.5230368972 + 0.6656997204 0.6273866296 0.5249174237 + 0.6669223905 0.6286934018 0.5267977715 + 0.6681451201 0.6300002933 0.5286782980 + 0.6693677902 0.6312733889 0.5305452943 + 0.6705707908 0.6325464845 0.5323804021 + 0.6717528105 0.6338195801 0.5342155099 + 0.6729347110 0.6350926757 0.5360506177 + 0.6741166115 0.6363657713 0.5378857255 + 0.6752985716 0.6376389265 0.5397207737 + 0.6764804721 0.6389120221 0.5415198207 + 0.6776624918 0.6401801705 0.5433121920 + 0.6788443923 0.6414189935 0.5451046228 + 0.6800253987 0.6426578760 0.5468971133 + 0.6811656952 0.6438966990 0.5486894846 + 0.6823059916 0.6451355815 0.5504710078 + 0.6834462881 0.6463744044 0.5522230268 + 0.6845865846 0.6476132870 0.5539749861 + 0.6857268810 0.6488522291 0.5557268858 + 0.6868671179 0.6500884891 0.5574789047 + 0.6880074143 0.6512925029 0.5592309237 + 0.6891477108 0.6524965167 0.5609611869 + 0.6902772784 0.6537005901 0.5626745224 + 0.6913753152 0.6549046040 0.5643877983 + 0.6924731731 0.6561086774 0.5661010742 + 0.6935710907 0.6573126912 0.5678144097 + 0.6946691275 0.6585168242 0.5695276856 + 0.6957669854 0.6597207785 0.5712140203 + 0.6968650222 0.6608976722 0.5728901029 + 0.6979628801 0.6620662808 0.5745661259 + 0.6990607977 0.6632350087 0.5762422085 + 0.7001525760 0.6644036174 0.5779181719 + 0.7012076974 0.6655722857 0.5795943141 + 0.7022626996 0.6667408943 0.5812429190 + 0.7033178210 0.6679096222 0.5828827024 + 0.7043728828 0.6690781713 0.5845226049 + 0.7054278851 0.6702393293 0.5861623883 + 0.7064830065 0.6713719964 0.5878022909 + 0.7075381279 0.6725047231 0.5894420743 + 0.7085930705 0.6736373901 0.5910584927 + 0.7096481919 0.6747701168 0.5926628113 + 0.7106745243 0.6759027839 0.5942670703 + 0.7116863132 0.6770355105 0.5958713889 + 0.7126982212 0.6781681776 0.5974757075 + 0.7137101293 0.6793009043 0.5990800261 + 0.7147219777 0.6804196239 0.6006693244 + 0.7157338262 0.6815158129 0.6022384763 + 0.7167456746 0.6826120019 0.6038076282 + 0.7177575827 0.6837081909 0.6053767204 + 0.7187694907 0.6848043799 0.6069458723 + 0.7197813988 0.6859006286 0.6085150242 + 0.7207592726 0.6869968176 0.6100823283 + 0.7217279077 0.6880930066 0.6116163135 + 0.7226964235 0.6891891956 0.6131502986 + 0.7236649990 0.6902757883 0.6146842837 + 0.7246335745 0.6913350224 0.6162183881 + 0.7256022096 0.6923943162 0.6177523732 + 0.7265707850 0.6934534907 0.6192864180 + 0.7275393009 0.6945127249 0.6208015084 + 0.7285078764 0.6955720186 0.6223003268 + 0.7294765115 0.6966311932 0.6237990260 + 0.7304251790 0.6976904273 0.6252977252 + 0.7313506007 0.6987497211 0.6267964244 + 0.7322760224 0.6998088956 0.6282951236 + 0.7332013845 0.7008374929 0.6297938228 + 0.7341268063 0.7018594146 0.6312615871 + 0.7350522280 0.7028812170 0.6327245831 + 0.7359775901 0.7039030790 0.6341875196 + 0.7369030118 0.7049250007 0.6356505156 + 0.7378283739 0.7059468031 0.6371133924 + 0.7387537956 0.7069687247 0.6385763288 + 0.7396792173 0.7079905868 0.6400383115 + 0.7405766249 0.7090123892 0.6414648294 + 0.7414591908 0.7100329995 0.6428912878 + 0.7423416972 0.7110173106 0.6443178058 + 0.7432242036 0.7120015025 0.6457443833 + 0.7441068292 0.7129856944 0.6471709013 + 0.7449892759 0.7139698863 0.6485974193 + 0.7458719015 0.7149540782 0.6500232816 + 0.7467544079 0.7159383297 0.6514126062 + 0.7476369739 0.7169225216 0.6528018117 + 0.7485194802 0.7179067731 0.6541910768 + 0.7494021058 0.7188910246 0.6555804014 + 0.7502709031 0.7198752165 0.6569697261 + 0.7511112094 0.7208263874 0.6583588719 + 0.7519513965 0.7217727900 0.6597481966 + 0.7527915835 0.7227191925 0.6611062288 + 0.7536318898 0.7236654758 0.6624572873 + 0.7544720769 0.7246118784 0.6638084054 + 0.7553123236 0.7255582809 0.6651595235 + 0.7561525106 0.7265046835 0.6665105820 + 0.7569928169 0.7274510860 0.6678617001 + 0.7578330040 0.7283974886 0.6692128181 + 0.7586731911 0.7293438911 0.6705474854 + 0.7595134974 0.7302786708 0.6718593836 + 0.7603362203 0.7311872244 0.6731712818 + 0.7611348033 0.7320957184 0.6744831800 + 0.7619335055 0.7330042124 0.6757950187 + 0.7627320886 0.7339128256 0.6771069169 + 0.7635306716 0.7348213196 0.6784188151 + 0.7643293738 0.7357298136 0.6797307134 + 0.7651280165 0.7366383076 0.6810106039 + 0.7659267187 0.7375468016 0.6822822094 + 0.7667253017 0.7384554148 0.6835538149 + 0.7675240040 0.7393639088 0.6848254800 + 0.7683225870 0.7402610779 0.6860970855 + 0.7691212296 0.7411319017 0.6873686910 + 0.7699198723 0.7420026064 0.6886402965 + 0.7706819177 0.7428733706 0.6899120212 + 0.7714399099 0.7437440753 0.6911451221 + 0.7721979022 0.7446148992 0.6923754811 + 0.7729557753 0.7454857230 0.6936057806 + 0.7737138271 0.7463564277 0.6948360801 + 0.7744718194 0.7472271919 0.6960663795 + 0.7752296925 0.7480978966 0.6972966790 + 0.7759876847 0.7489687204 0.6985270977 + 0.7767456770 0.7498394847 0.6997573972 + 0.7775036097 0.7506796122 0.7009537816 + 0.7782616019 0.7515128255 0.7021418214 + 0.7790195942 0.7523460984 0.7033298016 + 0.7797775269 0.7531793118 0.7045179009 + 0.7805075049 0.7540125847 0.7057058811 + 0.7812259197 0.7548457980 0.7068939209 + 0.7819442153 0.7556790113 0.7080820203 + 0.7826625705 0.7565122843 0.7092700005 + 0.7833809257 0.7573454976 0.7104414105 + 0.7840992808 0.7581787705 0.7115862966 + 0.7848175764 0.7590119839 0.7127311826 + 0.7855359912 0.7598451972 0.7138760090 + 0.7862542868 0.7606481910 0.7150208950 + 0.7869727015 0.7614442706 0.7161657810 + 0.7876909971 0.7622404099 0.7173107266 + 0.7884094119 0.7630366087 0.7184554935 + 0.7891278267 0.7638326883 0.7196003795 + 0.7898461223 0.7646288276 0.7207167149 + 0.7905343175 0.7654249072 0.7218176723 + 0.7912142277 0.7662209868 0.7229186893 + 0.7918941975 0.7670171261 0.7240195870 + 0.7925741076 0.7678132057 0.7251206040 + 0.7932540178 0.7686092854 0.7262216210 + 0.7939339876 0.7694054246 0.7273225784 + 0.7946138978 0.7701922059 0.7284234762 + 0.7952939272 0.7709516883 0.7295244932 + 0.7959737778 0.7717111707 0.7306001782 + 0.7966536880 0.7724707127 0.7316566706 + 0.7973337173 0.7732301950 0.7327132821 + 0.7980136275 0.7739896774 0.7337697744 + 0.7986935973 0.7747492194 0.7348263264 + 0.7993735075 0.7755087018 0.7358828187 + 0.8000504971 0.7762681842 0.7369393110 + 0.8006933928 0.7770277262 0.7379958034 + 0.8013362288 0.7777872086 0.7390522957 + 0.8019790053 0.7785466909 0.7401041985 + 0.8026219010 0.7793061733 0.7411159277 + 0.8032646775 0.7800626159 0.7421275973 + 0.8039075732 0.7807862163 0.7431393266 + 0.8045504093 0.7815096974 0.7441509962 + 0.8051931858 0.7822332978 0.7451627254 + 0.8058360815 0.7829567790 0.7461743951 + 0.8064789176 0.7836803794 0.7471861243 + 0.8071216941 0.7844039202 0.7481977940 + 0.8077645898 0.7851275206 0.7492095232 + 0.8084074259 0.7858511209 0.7502114177 + 0.8090502024 0.7865746021 0.7511780858 + 0.8096930981 0.7872982025 0.7521448731 + 0.8103172779 0.7880216837 0.7531116009 + 0.8109244108 0.7887452841 0.7540783286 + 0.8115314841 0.7894688249 0.7550451159 + 0.8121386766 0.7901830077 0.7560117841 + 0.8127458096 0.7908713818 0.7569785714 + 0.8133528829 0.7915598154 0.7579452991 + 0.8139600754 0.7922481894 0.7589120269 + 0.8145672083 0.7929366231 0.7598788142 + 0.8151742816 0.7936249971 0.7608063221 + 0.8157814145 0.7943133712 0.7617281079 + 0.8163886070 0.7950018048 0.7626500130 + 0.8169956803 0.7956901193 0.7635719180 + 0.8176028132 0.7963784933 0.7644938231 + 0.8182100058 0.7970669270 0.7654156089 + 0.8188170791 0.7977553010 0.7663375139 + 0.8194242120 0.7984436750 0.7672594190 + 0.8200296164 0.7991321087 0.7681813240 + 0.8206024766 0.7998204827 0.7691031098 + 0.8211753964 0.8004835248 0.7700238228 + 0.8217483163 0.8011376858 0.7709010839 + 0.8223211169 0.8017917871 0.7717785239 + 0.8228939772 0.8024458885 0.7726557851 + 0.8234668970 0.8030999899 0.7735331059 + 0.8240398169 0.8037540913 0.7744104862 + 0.8246126771 0.8044083118 0.7752878070 + 0.8251855969 0.8050624132 0.7761651278 + 0.8257585168 0.8057165146 0.7770425081 + 0.8263313770 0.8063706160 0.7779198289 + 0.8269041777 0.8070247173 0.7787970901 + 0.8274770975 0.8076788187 0.7796744704 + 0.8280500174 0.8083329797 0.7805240750 + 0.8286228776 0.8089870811 0.7813575268 + 0.8291957974 0.8096411824 0.7821907997 + 0.8297687173 0.8102803230 0.7830241919 + 0.8303220272 0.8109011054 0.7838575244 + 0.8308622241 0.8115220070 0.7846909165 + 0.8314023018 0.8121427894 0.7855241895 + 0.8319424987 0.8127635717 0.7863575816 + 0.8324825764 0.8133844733 0.7871909142 + 0.8330227733 0.8140053153 0.7880243063 + 0.8335629106 0.8146260977 0.7888575792 + 0.8341031075 0.8152469993 0.7896909714 + 0.8346431851 0.8158677816 0.7904971242 + 0.8351833820 0.8164886236 0.7912873030 + 0.8357235193 0.8171095252 0.7920774221 + 0.8362637162 0.8177303076 0.7928674817 + 0.8368037939 0.8183512092 0.7936577201 + 0.8373439908 0.8189719915 0.7944477797 + 0.8378841281 0.8195927739 0.7952378988 + 0.8384243250 0.8202025890 0.7960280776 + 0.8389644027 0.8207911849 0.7968181968 + 0.8395045996 0.8213797808 0.7976083159 + 0.8400421143 0.8219683766 0.7983984947 + 0.8405510783 0.8225570917 0.7991886139 + 0.8410599828 0.8231456876 0.7999786735 + 0.8415690064 0.8237342834 0.8007277846 + 0.8420779109 0.8243228793 0.8014757037 + 0.8425868154 0.8249114752 0.8022235036 + 0.8430957794 0.8255001903 0.8029714227 + 0.8436046839 0.8260887861 0.8037192822 + 0.8441137075 0.8266773820 0.8044672012 + 0.8446226120 0.8272659779 0.8052151203 + 0.8451315165 0.8278546929 0.8059629798 + 0.8456404805 0.8284432888 0.8067108989 + 0.8461493850 0.8290318847 0.8074588180 + 0.8466584086 0.8296204805 0.8082066774 + 0.8471673131 0.8301981091 0.8089544773 + 0.8476762176 0.8307555914 0.8097023964 + 0.8481851816 0.8313131928 0.8104255795 + 0.8486940861 0.8318706751 0.8111323714 + 0.8492031097 0.8324282765 0.8118392229 + 0.8497120142 0.8329858184 0.8125458956 + 0.8502081037 0.8335434198 0.8132526875 + 0.8506873250 0.8341009021 0.8139594793 + 0.8511666059 0.8346583843 0.8146662712 + 0.8516458869 0.8352159858 0.8153731227 + 0.8521251082 0.8357735276 0.8160799146 + 0.8526043892 0.8363311291 0.8167867064 + 0.8530836105 0.8368886113 0.8174934983 + 0.8535628915 0.8374462128 0.8182002902 + 0.8540421724 0.8380036950 0.8189070821 + 0.8545213938 0.8385611773 0.8196138144 + 0.8550006747 0.8391187787 0.8203026056 + 0.8554800153 0.8396763206 0.8209695816 + 0.8559591770 0.8402212858 0.8216364980 + 0.8564385176 0.8407490253 0.8223034739 + 0.8569177985 0.8412765861 0.8229705095 + 0.8573970199 0.8418043256 0.8236374855 + 0.8578763008 0.8423318863 0.8243045211 + 0.8583555818 0.8428596258 0.8249714971 + 0.8588348031 0.8433871865 0.8256384730 + 0.8593140841 0.8439149261 0.8263055086 + 0.8597934246 0.8444424868 0.8269724846 + 0.8602566123 0.8449702263 0.8276394010 + 0.8607078195 0.8454977870 0.8283063769 + 0.8611589074 0.8460255265 0.8289734125 + 0.8616099954 0.8465530872 0.8296403885 + 0.8620610833 0.8470808268 0.8302897215 + 0.8625121713 0.8476083875 0.8309183121 + 0.8629633784 0.8481361270 0.8315469027 + 0.8634145260 0.8486636877 0.8321754932 + 0.8638656139 0.8491914272 0.8328040838 + 0.8643167019 0.8497189879 0.8334327936 + 0.8647677898 0.8502333164 0.8340613842 + 0.8652189970 0.8507323265 0.8346899748 + 0.8656700850 0.8512312174 0.8353186250 + 0.8661211729 0.8517302275 0.8359472156 + 0.8665723205 0.8522291780 0.8365758061 + 0.8670234084 0.8527281880 0.8372043967 + 0.8674746156 0.8532270789 0.8378329873 + 0.8679257035 0.8537260890 0.8384615779 + 0.8683767915 0.8542250991 0.8390902281 + 0.8688278794 0.8547241092 0.8397188783 + 0.8692790270 0.8552231193 0.8403270841 + 0.8697301745 0.8557220101 0.8409187794 + 0.8701705933 0.8562210202 0.8415105939 + 0.8705950975 0.8567199707 0.8421024084 + 0.8710194826 0.8572189808 0.8426941037 + 0.8714439869 0.8577179909 0.8432859182 + 0.8718684912 0.8582168818 0.8438776135 + 0.8722929955 0.8587158918 0.8444694281 + 0.8727173805 0.8592149019 0.8450611234 + 0.8731418848 0.8597139120 0.8456528783 + 0.8735663891 0.8602011204 0.8462445736 + 0.8739908934 0.8606727123 0.8468363881 + 0.8744153976 0.8611443043 0.8474280834 + 0.8748397827 0.8616157770 0.8480198979 + 0.8752642870 0.8620874286 0.8486115932 + 0.8756887913 0.8625589013 0.8492034078 + 0.8761132956 0.8630304933 0.8497951031 + 0.8765377998 0.8635020256 0.8503637910 + 0.8769621849 0.8639736176 0.8509203196 + 0.8773866892 0.8644450903 0.8514767885 + 0.8778111935 0.8649166822 0.8520333171 + 0.8782356977 0.8653882146 0.8525897861 + 0.8786600828 0.8658598065 0.8531463146 + 0.8790845871 0.8663312793 0.8537027836 + 0.8795090914 0.8668028712 0.8542593122 + 0.8799335957 0.8672744036 0.8548157811 + 0.8803368211 0.8677459955 0.8553723097 + 0.8807361126 0.8682175279 0.8559287786 + 0.8811354041 0.8686891198 0.8564853072 + 0.8815348148 0.8691605926 0.8570417166 + 0.8819341063 0.8696321845 0.8575981855 + 0.8823333979 0.8700979948 0.8581547141 + 0.8827326894 0.8705433011 0.8587111831 + 0.8831319809 0.8709887266 0.8592677116 + 0.8835312724 0.8714340925 0.8598241806 + 0.8839306235 0.8718795180 0.8603577018 + 0.8843299150 0.8723248839 0.8608806133 + 0.8847292066 0.8727701902 0.8614034057 + 0.8851284981 0.8732156157 0.8619263172 + 0.8855277896 0.8736609817 0.8624492288 + 0.8859272003 0.8741064072 0.8629720211 + 0.8863264918 0.8745517135 0.8634948730 + 0.8867257833 0.8749970794 0.8640177846 + 0.8871250749 0.8754425049 0.8645406961 + 0.8875244260 0.8758878708 0.8650634885 + 0.8879237175 0.8763331771 0.8655864000 + 0.8883230090 0.8767786026 0.8661093116 + 0.8887223005 0.8772240281 0.8666321039 + 0.8891215920 0.8776693940 0.8671550155 + 0.8895208836 0.8781148195 0.8676779270 + 0.8899201751 0.8785601258 0.8682007790 + 0.8903005719 0.8790054917 0.8687235713 + 0.8906760812 0.8794509172 0.8692464828 + 0.8910517097 0.8798962831 0.8697693944 + 0.8914272785 0.8803225160 0.8702744246 + 0.8918027878 0.8807430267 0.8707653284 + 0.8921784163 0.8811634183 0.8712561727 + 0.8925539851 0.8815839291 0.8717470765 + 0.8929294944 0.8820043206 0.8722379804 + 0.8933051229 0.8824247718 0.8727290034 + 0.8936806917 0.8828452229 0.8732199073 + 0.8940562010 0.8832656741 0.8737108111 + 0.8944318295 0.8836861849 0.8742017150 + 0.8948073983 0.8841065764 0.8746926188 + 0.8951830268 0.8845270872 0.8751835227 + 0.8955584764 0.8849474788 0.8756744862 + 0.8959341049 0.8853679895 0.8761653900 + 0.8963096738 0.8857883811 0.8766562939 + 0.8966851830 0.8862088919 0.8771471977 + 0.8970608115 0.8866292834 0.8776381016 + 0.8974363804 0.8870497942 0.8781290054 + 0.8978118896 0.8874701858 0.8786200285 + 0.8981875181 0.8878906965 0.8791108727 + 0.8985630870 0.8883110881 0.8796017766 + 0.8989385962 0.8887315989 0.8800870180 + 0.8993142247 0.8891521096 0.8805475831 + 0.8996897936 0.8895725012 0.8810082078 + 0.9000614882 0.8899930120 0.8814688921 + 0.9004147053 0.8903900981 0.8819295168 + 0.9007679224 0.8907868862 0.8823900819 + 0.9011210799 0.8911836743 0.8828508258 + 0.9014742970 0.8915804029 0.8833113909 + 0.9018275142 0.8919771910 0.8837720156 + 0.9021806717 0.8923739791 0.8842326999 + 0.9025338888 0.8927707076 0.8846933246 + 0.9028872252 0.8931674957 0.8851538897 + 0.9032403827 0.8935642838 0.8856145740 + 0.9035935998 0.8939610720 0.8860751987 + 0.9039468169 0.8943578005 0.8865358233 + 0.9042999744 0.8947545886 0.8869965076 + 0.9046531916 0.8951513767 0.8874570727 + 0.9050064087 0.8955481052 0.8879176974 + 0.9053596258 0.8959448934 0.8883783221 + 0.9057129025 0.8963416815 0.8888390064 + 0.9060661197 0.8967384100 0.8892995715 + 0.9064192772 0.8971351981 0.8897601962 + 0.9067724943 0.8975319862 0.8902071118 + 0.9071257114 0.8979287744 0.8906391263 + 0.9074789286 0.8983255029 0.8910710812 + 0.9078320861 0.8987222910 0.8915032148 + 0.9081853032 0.8991190791 0.8919352293 + 0.9085385203 0.8995158076 0.8923671842 + 0.9088917971 0.8999125957 0.8927991986 + 0.9092450142 0.9002919197 0.8932312131 + 0.9095981717 0.9006661773 0.8936632276 + 0.9099513888 0.9010404944 0.8940951824 + 0.9102864861 0.9014148116 0.8945271969 + 0.9106187224 0.9017891288 0.8949592113 + 0.9109507799 0.9021633863 0.8953912258 + 0.9112830162 0.9025377035 0.8958231807 + 0.9116151929 0.9029120207 0.8962551951 + 0.9119474292 0.9032862782 0.8966872096 + 0.9122796059 0.9036605954 0.8971192241 + 0.9126117229 0.9040349126 0.8975511789 + 0.9129438996 0.9044092298 0.8979831934 + 0.9132760763 0.9047834873 0.8984152079 + 0.9136083126 0.9051578045 0.8988472223 + 0.9139404893 0.9055321217 0.8992791772 + 0.9142726064 0.9059063792 0.8997111917 + 0.9146047831 0.9062806964 0.9001343250 + 0.9149370193 0.9066550732 0.9005392790 + 0.9152691960 0.9070293903 0.9009442925 + 0.9156013727 0.9074037075 0.9013493061 + 0.9159336090 0.9077780247 0.9017543197 + 0.9162657261 0.9081522822 0.9021592736 + 0.9165979028 0.9085265994 0.9025642872 + 0.9169300795 0.9089009166 0.9029693007 + 0.9172623158 0.9092751741 0.9033743143 + 0.9175944924 0.9096494913 0.9037793279 + 0.9179266095 0.9100223780 0.9041842818 + 0.9182587862 0.9103754759 0.9045892954 + 0.9185910225 0.9107285142 0.9049943089 + 0.9189231992 0.9110814929 0.9053993225 + 0.9192553759 0.9114345908 0.9058042765 + 0.9195876122 0.9117876291 0.9062092900 + 0.9199197292 0.9121406078 0.9066143036 + 0.9202368855 0.9124937057 0.9070193172 + 0.9205493927 0.9128466845 0.9074242711 + 0.9208617806 0.9131997228 0.9078292847 + 0.9211742282 0.9135528207 0.9082342982 + 0.9214866161 0.9139057994 0.9086393118 + 0.9217990041 0.9142587781 0.9090443254 + 0.9221115112 0.9146118760 0.9094492793 + 0.9224238992 0.9149649143 0.9098542929 + 0.9227362871 0.9153178930 0.9102429748 + 0.9230486751 0.9156708717 0.9106225967 + 0.9233611822 0.9160240293 0.9110022187 + 0.9236736298 0.9163770080 0.9113817811 + 0.9239860177 0.9167299867 0.9117614031 + 0.9242984056 0.9170830846 0.9121410251 + 0.9246109128 0.9174361229 0.9125205874 + 0.9249233007 0.9177891016 0.9129002094 + 0.9252356887 0.9181421995 0.9132797122 + 0.9255480766 0.9184951782 0.9136592746 + 0.9258605242 0.9188482165 0.9140388966 + 0.9261729717 0.9192013144 0.9144185185 + 0.9264854193 0.9195542932 0.9147980809 + 0.9267978072 0.9199072719 0.9151777029 + 0.9271101952 0.9202455282 0.9155573249 + 0.9274227023 0.9205784202 0.9159368873 + 0.9277350903 0.9209113121 0.9163165092 + 0.9280474782 0.9212443233 0.9166960120 + 0.9283599257 0.9215772152 0.9170755744 + 0.9286723137 0.9219101071 0.9174551964 + 0.9289848208 0.9222429991 0.9178348184 + 0.9292972088 0.9225758910 0.9182143807 + 0.9296095967 0.9229087830 0.9185940027 + 0.9299219847 0.9232416749 0.9189736247 + 0.9302204847 0.9235746861 0.9193531871 + 0.9305143952 0.9239075780 0.9197328091 + 0.9308083057 0.9242405295 0.9201052785 + 0.9311022162 0.9245734215 0.9204609990 + 0.9313960075 0.9249063134 0.9208167195 + 0.9316899180 0.9252392054 0.9211723804 + 0.9319838285 0.9255720973 0.9215281010 + 0.9322776794 0.9259051085 0.9218838215 + 0.9325714707 0.9262380004 0.9222394824 + 0.9328653812 0.9265708923 0.9225953221 + 0.9331592917 0.9269037843 0.9229509830 + 0.9334532022 0.9272366762 0.9233067036 + 0.9337469935 0.9275696278 0.9236624241 + 0.9340409040 0.9279025197 0.9240180850 + 0.9343348145 0.9282354712 0.9243738055 + 0.9346287251 0.9285684228 0.9247295260 + 0.9349225163 0.9289013147 0.9250851870 + 0.9352164268 0.9292342067 0.9254410267 + 0.9355102777 0.9295670986 0.9257966876 + 0.9358041286 0.9298999906 0.9261524081 + 0.9360979795 0.9302197099 0.9265081286 + 0.9363918900 0.9305335879 0.9268637896 + 0.9366858006 0.9308475256 0.9272195101 + 0.9369795918 0.9311614037 0.9275751710 + 0.9372735023 0.9314752817 0.9279308915 + 0.9375674129 0.9317892194 0.9282866120 + 0.9378613234 0.9321032166 0.9286423922 + 0.9381551147 0.9324170947 0.9289981127 + 0.9384490252 0.9327309728 0.9293537736 + 0.9387428761 0.9330449104 0.9297094941 + 0.9390367866 0.9333587885 0.9300611019 + 0.9393305779 0.9336727262 0.9303944111 + 0.9396244884 0.9339867234 0.9307277203 + 0.9399183989 0.9343006015 0.9310610294 + 0.9401996732 0.9346144795 0.9313942790 + 0.9404761791 0.9349284172 0.9317277074 + 0.9407526851 0.9352422953 0.9320610166 + 0.9410290718 0.9355561733 0.9323943257 + 0.9413055778 0.9358701706 0.9327275753 + 0.9415820837 0.9361841083 0.9330608845 + 0.9418585896 0.9364979863 0.9333941936 + 0.9421349764 0.9368119240 0.9337275028 + 0.9424114823 0.9371258020 0.9340608120 + 0.9426879883 0.9374397993 0.9343941808 + 0.9429644942 0.9377536774 0.9347274899 + 0.9432408810 0.9380676150 0.9350607991 + 0.9435173869 0.9383814931 0.9353941083 + 0.9437938929 0.9386953712 0.9357274175 + 0.9440703988 0.9390093088 0.9360607266 + 0.9443467855 0.9393233061 0.9363939762 + 0.9446232915 0.9396371841 0.9367272854 + 0.9448997974 0.9399511218 0.9370607138 + 0.9451763034 0.9402499199 0.9373940229 + 0.9454526901 0.9405459166 0.9377272725 + 0.9457291961 0.9408419132 0.9380605817 + 0.9460057020 0.9411379099 0.9383938909 + 0.9462822080 0.9414339066 0.9387272000 + 0.9465587139 0.9417299032 0.9390605092 + 0.9468351007 0.9420258999 0.9393938780 + 0.9471116066 0.9423218966 0.9397271872 + 0.9473881125 0.9426178932 0.9400566816 + 0.9476646185 0.9429138899 0.9403690100 + 0.9479410052 0.9432098269 0.9406812787 + 0.9482175112 0.9435058236 0.9409937263 + 0.9484940171 0.9438018203 0.9413059950 + 0.9487705231 0.9440978169 0.9416183233 + 0.9490469098 0.9443938136 0.9419305921 + 0.9493234158 0.9446898103 0.9422429800 + 0.9495999217 0.9449858069 0.9425553083 + 0.9498764277 0.9452818036 0.9428675771 + 0.9501438141 0.9455778003 0.9431800246 + 0.9504039884 0.9458737969 0.9434922934 + 0.9506642222 0.9461697936 0.9438046217 + 0.9509242773 0.9464657903 0.9441168904 + 0.9511845112 0.9467617869 0.9444292784 + 0.9514446855 0.9470577836 0.9447416067 + 0.9517048001 0.9473537803 0.9450538754 + 0.9519649744 0.9476497769 0.9453663230 + 0.9522252083 0.9479457736 0.9456785917 + 0.9524853230 0.9482417703 0.9459909201 + 0.9527454972 0.9485378265 0.9463031888 + 0.9530056715 0.9488338232 0.9466155767 + 0.9532657862 0.9491298199 0.9469279051 + 0.9535260201 0.9494258165 0.9472401738 + 0.9537861943 0.9497218132 0.9475526214 + 0.9540463090 0.9500167966 0.9478648901 + 0.9543064833 0.9502959251 0.9481772184 + 0.9545667171 0.9505749941 0.9484894872 + 0.9548268914 0.9508541226 0.9488018751 + 0.9550870061 0.9511331916 0.9491142035 + 0.9553471804 0.9514123201 0.9494264722 + 0.9556074142 0.9516913891 0.9497389197 + 0.9558675289 0.9519705176 0.9500480294 + 0.9561277032 0.9522495866 0.9503406882 + 0.9563878775 0.9525287747 0.9506334066 + 0.9566479921 0.9528079033 0.9509260058 + 0.9569082260 0.9530869722 0.9512187243 + 0.9571684003 0.9533661008 0.9515113831 + 0.9574285150 0.9536452293 0.9518041015 + 0.9576886892 0.9539242983 0.9520968199 + 0.9579489231 0.9542034268 0.9523894787 + 0.9582089782 0.9544824958 0.9526821971 + 0.9584692121 0.9547616243 0.9529749155 + 0.9587293863 0.9550406933 0.9532675743 + 0.9589895010 0.9553198814 0.9535602927 + 0.9592496753 0.9555990100 0.9538530111 + 0.9595099092 0.9558780789 0.9541457295 + 0.9597700238 0.9561572075 0.9544383883 + 0.9600284100 0.9564362764 0.9547309875 + 0.9602733254 0.9567154050 0.9550237060 + 0.9605181813 0.9569944739 0.9553164244 + 0.9607630968 0.9572736025 0.9556090832 + 0.9610080123 0.9575526714 0.9559018016 + 0.9612529278 0.9578318000 0.9561945200 + 0.9614977837 0.9581109881 0.9564871788 + 0.9617425799 0.9583901167 0.9567798972 + 0.9619874954 0.9586691856 0.9570726156 + 0.9622324109 0.9589483142 0.9573652744 + 0.9624773264 0.9592273831 0.9576579928 + 0.9627221823 0.9595065117 0.9579507113 + 0.9629670978 0.9597855806 0.9582434297 + 0.9632120132 0.9600610137 0.9585360885 + 0.9634569287 0.9603242278 0.9588286877 + 0.9637017846 0.9605875015 0.9591214061 + 0.9639465809 0.9608507156 0.9594141245 + 0.9641914964 0.9611139297 0.9597067833 + 0.9644364119 0.9613770843 0.9599995017 + 0.9646813273 0.9616402984 0.9602739215 + 0.9649261832 0.9619035125 0.9605482221 + 0.9651710987 0.9621667266 0.9608225226 + 0.9654160142 0.9624298811 0.9610968828 + 0.9656609297 0.9626930952 0.9613711834 + 0.9659057260 0.9629563093 0.9616456032 + 0.9661505818 0.9632195830 0.9619199038 + 0.9663954973 0.9634827971 0.9621942043 + 0.9666404128 0.9637460113 0.9624686241 + 0.9668853283 0.9640092254 0.9627429247 + 0.9671301842 0.9642723799 0.9630172253 + 0.9673750997 0.9645355940 0.9632915854 + 0.9676200151 0.9647988081 0.9635658860 + 0.9678648114 0.9650620222 0.9638401866 + 0.9681097269 0.9653251767 0.9641146064 + 0.9683545828 0.9655883908 0.9643889070 + 0.9685994983 0.9658517241 0.9646632075 + 0.9688444138 0.9661148787 0.9649376273 + 0.9690893292 0.9663780928 0.9652119279 + 0.9693341851 0.9666413069 0.9654862285 + 0.9695791006 0.9669045210 0.9657605886 + 0.9698240161 0.9671676755 0.9660348892 + 0.9700648189 0.9674308896 0.9663093090 + 0.9702954292 0.9676941037 0.9665836096 + 0.9705259800 0.9679573178 0.9668579102 + 0.9707565904 0.9682204723 0.9671322703 + 0.9709870815 0.9684838057 0.9674065709 + 0.9712176919 0.9687470198 0.9676808715 + 0.9714483023 0.9690101743 0.9679552913 + 0.9716789126 0.9692733884 0.9682295918 + 0.9719094038 0.9695366025 0.9685038924 + 0.9721400142 0.9697998166 0.9687783122 + 0.9723706245 0.9700593948 0.9690526128 + 0.9726011753 0.9703077078 0.9693269134 + 0.9728317857 0.9705559015 0.9696012735 + 0.9730622768 0.9708042145 0.9698755741 + 0.9732928872 0.9710524082 0.9701405764 + 0.9735234976 0.9713007212 0.9703977704 + 0.9737541080 0.9715489149 0.9706549048 + 0.9739845991 0.9717972279 0.9709120989 + 0.9742152095 0.9720454216 0.9711692929 + 0.9744458199 0.9722936749 0.9714264870 + 0.9746763706 0.9725419283 0.9716836810 + 0.9749069810 0.9727901816 0.9719408751 + 0.9751374722 0.9730383754 0.9721981287 + 0.9753680825 0.9732866883 0.9724552035 + 0.9755986929 0.9735348821 0.9727123976 + 0.9758293033 0.9737831950 0.9729695916 + 0.9760597944 0.9740313888 0.9732267857 + 0.9762904048 0.9742797017 0.9734839797 + 0.9765210152 0.9745278955 0.9737411737 + 0.9767516255 0.9747762084 0.9739984274 + 0.9769821763 0.9750244021 0.9742556214 + 0.9772127271 0.9752727151 0.9745126963 + 0.9774432778 0.9755209088 0.9747698903 + 0.9776738882 0.9757692218 0.9750270844 + 0.9779044986 0.9760174155 0.9752842784 + 0.9781349897 0.9762657285 0.9755414724 + 0.9783656001 0.9765139222 0.9757987261 + 0.9785962105 0.9767621756 0.9760559201 + 0.9788268209 0.9770104885 0.9763129950 + 0.9790573716 0.9772586823 0.9765701890 + 0.9792879224 0.9775069952 0.9768273830 + 0.9795184731 0.9777551889 0.9770845771 + 0.9797490835 0.9780035019 0.9773417711 + 0.9799796939 0.9782516956 0.9775990248 + 0.9801980257 0.9785000086 0.9778562188 + 0.9804152250 0.9787482023 0.9781134129 + 0.9806324244 0.9789965153 0.9783704877 + 0.9808496237 0.9792447090 0.9786276817 + 0.9810667038 0.9794930220 0.9788848758 + 0.9812839031 0.9797412157 0.9791421294 + 0.9815011024 0.9799895287 0.9793993235 + 0.9817183018 0.9802241921 0.9796565175 + 0.9819355011 0.9804583788 0.9799137115 + 0.9821525812 0.9806926250 0.9801601768 + 0.9823697805 0.9809268117 0.9804013968 + 0.9825869799 0.9811609983 0.9806426167 + 0.9828041792 0.9813951850 0.9808837175 + 0.9830213785 0.9816293120 0.9811248779 + 0.9832385182 0.9818634987 0.9813660979 + 0.9834557176 0.9820976853 0.9816073179 + 0.9836729169 0.9823318720 0.9818484783 + 0.9838901162 0.9825661182 0.9820895791 + 0.9841073155 0.9828003049 0.9823307991 + 0.9843243957 0.9830343723 0.9825720191 + 0.9845415950 0.9832686186 0.9828131795 + 0.9847587943 0.9835028052 0.9830542803 + 0.9849759936 0.9837369919 0.9832955003 + 0.9851931930 0.9839711785 0.9835367203 + 0.9854102731 0.9842054248 0.9837778807 + 0.9856274724 0.9844396114 0.9840189815 + 0.9858446717 0.9846736789 0.9842602015 + 0.9860618711 0.9849079251 0.9845014215 + 0.9862790108 0.9851421118 0.9847425818 + 0.9864962101 0.9853762984 0.9849838018 + 0.9867134094 0.9856104851 0.9852249026 + 0.9869306087 0.9858446717 0.9854661226 + 0.9871478081 0.9860787988 0.9857072830 + 0.9873648882 0.9863129854 0.9859485030 + 0.9875820875 0.9865471721 0.9861896038 + 0.9877992868 0.9867814183 0.9864308238 + 0.9880164862 0.9870156050 0.9866719842 + 0.9882336855 0.9872497916 0.9869132042 + 0.9884508252 0.9874839783 0.9871544242 + 0.9886680245 0.9877181053 0.9873955250 + 0.9888852239 0.9879522920 0.9876366854 + 0.9891024232 0.9881864786 0.9878779054 + 0.9893196225 0.9884207249 0.9881191254 + 0.9895367026 0.9886549115 0.9883602262 + 0.9897539020 0.9888890982 0.9886013865 + 0.9899711013 0.9891232252 0.9888426065 + 0.9901773930 0.9893574119 0.9890838265 + 0.9903820157 0.9895915985 0.9893249273 + 0.9905866981 0.9898257852 0.9895660877 + 0.9907913208 0.9900565743 0.9898073077 + 0.9909960032 0.9902775884 0.9900454879 + 0.9912006259 0.9904984832 0.9902716875 + 0.9914051890 0.9907194972 0.9904980063 + 0.9916098714 0.9909405112 0.9907242060 + 0.9918144941 0.9911614060 0.9909504056 + 0.9920191169 0.9913824201 0.9911767244 + 0.9922237992 0.9916033149 0.9914029241 + 0.9924284220 0.9918243289 0.9916291833 + 0.9926331043 0.9920452833 0.9918553829 + 0.9928377271 0.9922661781 0.9920815825 + 0.9930422902 0.9924871922 0.9923079014 + 0.9932469726 0.9927082062 0.9925341010 + 0.9934515953 0.9929291010 0.9927603006 + 0.9936562181 0.9931501150 0.9929866195 + 0.9938609004 0.9933711290 0.9932128191 + 0.9940655231 0.9935920238 0.9934390783 + 0.9942702055 0.9938129783 0.9936652780 + 0.9944748282 0.9940339923 0.9938914776 + 0.9946793914 0.9942548871 0.9941177964 + 0.9948840737 0.9944759011 0.9943439960 + 0.9950886965 0.9946967959 0.9945703149 + 0.9952933192 0.9949178100 0.9947965145 + 0.9954980016 0.9951388240 0.9950227141 + 0.9957026243 0.9953597188 0.9952489734 + 0.9959073067 0.9955806732 0.9954751730 + 0.9961119294 0.9958016872 0.9957014918 + 0.9963164926 0.9960225821 0.9959276915 + 0.9965211749 0.9962435961 0.9961538911 + 0.9967257977 0.9964646101 0.9963802099 + 0.9969304204 0.9966855049 0.9966064095 + 0.9971351027 0.9969065189 0.9968327284 + 0.9973397255 0.9971274734 0.9970589280 + 0.9975444078 0.9973484278 0.9972851276 + 0.9977489710 0.9975693822 0.9975113869 + 0.9979535937 0.9977903962 0.9977375865 + 0.9981582761 0.9980112910 0.9979637861 + 0.9983628988 0.9982323050 0.9981901050 + 0.9985675216 0.9984531999 0.9984163046 + 0.9987722039 0.9986742139 0.9986426234 + 0.9989768267 0.9988952279 0.9988688231 + 0.9991815090 0.9991161227 0.9990950227 + 0.9993860722 0.9993370771 0.9993212819 + 0.9995906949 0.9995580912 0.9995474815 + 0.9997953773 0.9997789860 0.9997738004 + 1.0000000000 1.0000000000 1.0000000000 +} diff --git a/rpplugins/color_correction/resources/film_luts_raw/kodak_ektachrome_100.spi1d b/rpplugins/color_correction/resources/film_luts_raw/kodak_ektachrome_100.spi1d new file mode 100644 index 0000000..f78872f --- /dev/null +++ b/rpplugins/color_correction/resources/film_luts_raw/kodak_ektachrome_100.spi1d @@ -0,0 +1,1030 @@ +Version 1 +From 0.0 1.0 +Length 1024 +Components 3 +{ + 0.0000000000 0.0000000000 0.0000000000 + 0.0004029108 0.0002821621 0.0001828344 + 0.0008352380 0.0005855577 0.0003765924 + 0.0012884660 0.0009102127 0.0005832637 + 0.0017661640 0.0012608080 0.0008021335 + 0.0022727679 0.0016344450 0.0010323920 + 0.0028016400 0.0020279640 0.0012744220 + 0.0033602209 0.0024469071 0.0015256481 + 0.0039473702 0.0028940800 0.0017888939 + 0.0045624170 0.0033709989 0.0020655000 + 0.0052064499 0.0038755860 0.0023565269 + 0.0058913450 0.0044098911 0.0026614380 + 0.0066106170 0.0049738358 0.0029808299 + 0.0073703690 0.0055717099 0.0033126650 + 0.0081646843 0.0062076761 0.0036578199 + 0.0090046516 0.0068754591 0.0040169759 + 0.0098797111 0.0075756288 0.0043923021 + 0.0108015500 0.0083136391 0.0047826152 + 0.0117765898 0.0090896897 0.0051890090 + 0.0128089404 0.0099051362 0.0056110788 + 0.0138962502 0.0107623404 0.0060491539 + 0.0150366900 0.0116626900 0.0065042591 + 0.0162367094 0.0126068601 0.0069758608 + 0.0174948201 0.0135949403 0.0074637011 + 0.0188118201 0.0146293398 0.0079666628 + 0.0201881006 0.0157077797 0.0084832394 + 0.0216275994 0.0168280900 0.0090179667 + 0.0231346209 0.0179986991 0.0095704449 + 0.0247129407 0.0192209203 0.0101442495 + 0.0263695195 0.0204982292 0.0107389204 + 0.0280960202 0.0218272507 0.0113510201 + 0.0298976302 0.0232012607 0.0119804395 + 0.0317782089 0.0246255603 0.0126269804 + 0.0337512381 0.0260962192 0.0132909399 + 0.0358026214 0.0276108794 0.0139709497 + 0.0379312597 0.0291825198 0.0146665303 + 0.0401499309 0.0308093708 0.0153818596 + 0.0424532183 0.0324951895 0.0161184706 + 0.0448440388 0.0342448987 0.0168759096 + 0.0473214611 0.0360610783 0.0176607408 + 0.0498819388 0.0379341505 0.0184673797 + 0.0525423586 0.0398601405 0.0192978401 + 0.0553006493 0.0418499894 0.0201489609 + 0.0581430085 0.0438929684 0.0210218206 + 0.0610603690 0.0459916182 0.0219117906 + 0.0640591532 0.0481535792 0.0228250604 + 0.0671426877 0.0503738187 0.0237576701 + 0.0703096837 0.0526381992 0.0247094091 + 0.0735653490 0.0549571402 0.0256804898 + 0.0769181773 0.0573286191 0.0266711209 + 0.0803592205 0.0597677194 0.0276827496 + 0.0838969871 0.0622712001 0.0287114196 + 0.0875223130 0.0648275465 0.0297578406 + 0.0912306681 0.0674386173 0.0308247507 + 0.0950332806 0.0701159835 0.0319116488 + 0.0989207476 0.0728433207 0.0330191404 + 0.1029006988 0.0756310001 0.0341475010 + 0.1069691032 0.0784748793 0.0352968313 + 0.1111252010 0.0813758895 0.0364708304 + 0.1153606027 0.0843334123 0.0376655087 + 0.1196606010 0.0873407498 0.0388817117 + 0.1240456998 0.0903989002 0.0401183404 + 0.1285089999 0.0934979469 0.0413741618 + 0.1330395043 0.0966412276 0.0426500700 + 0.1376578957 0.0998382494 0.0439491197 + 0.1423473954 0.1030810028 0.0452704318 + 0.1471080929 0.1063693017 0.0466123708 + 0.1519421935 0.1097078994 0.0479735583 + 0.1568460017 0.1131009012 0.0493564717 + 0.1618086994 0.1165459007 0.0507622100 + 0.1668350995 0.1200487018 0.0521893688 + 0.1719325930 0.1235952005 0.0536371209 + 0.1770922989 0.1271920949 0.0551049188 + 0.1823212057 0.1308318973 0.0565952100 + 0.1875973940 0.1345200986 0.0581106283 + 0.1929260045 0.1382502019 0.0596516207 + 0.1983052045 0.1420248002 0.0612149313 + 0.2037338018 0.1458451003 0.0627992302 + 0.2092058957 0.1496911049 0.0644068494 + 0.2147053927 0.1535611004 0.0660389215 + 0.2202475965 0.1574510038 0.0676914304 + 0.2258259058 0.1613723040 0.0693570822 + 0.2314376980 0.1653227061 0.0710399523 + 0.2370904982 0.1692909002 0.0727412999 + 0.2427740991 0.1732849032 0.0744594336 + 0.2484734952 0.1773027033 0.0761927664 + 0.2541978061 0.1813420951 0.0779421404 + 0.2599338889 0.1854172051 0.0797097385 + 0.2656922042 0.1895329952 0.0814976320 + 0.2714639008 0.1936807036 0.0833064169 + 0.2772484124 0.1978671998 0.0851336494 + 0.2830584943 0.2020945996 0.0869752765 + 0.2888925076 0.2063394040 0.0888287425 + 0.2947472036 0.2105993927 0.0906959027 + 0.3006064892 0.2148775011 0.0925794691 + 0.3064776063 0.2191728055 0.0944826677 + 0.3123730123 0.2234859020 0.0964089409 + 0.3182818890 0.2278206050 0.0983487070 + 0.3241820931 0.2321731001 0.1003040969 + 0.3300934136 0.2365338057 0.1022775024 + 0.3360261023 0.2409182042 0.1042753011 + 0.3419634998 0.2453251928 0.1062982008 + 0.3478932977 0.2497422993 0.1083303019 + 0.3538097143 0.2541579902 0.1103701964 + 0.3597145975 0.2585824132 0.1124206036 + 0.3656162918 0.2630195916 0.1144891009 + 0.3715220988 0.2674663961 0.1165636033 + 0.3774074912 0.2719157040 0.1186439022 + 0.3832853138 0.2763611078 0.1207353026 + 0.3891583085 0.2808066010 0.1228388026 + 0.3950240016 0.2852618098 0.1249521971 + 0.4008567035 0.2897278070 0.1270755976 + 0.4066801071 0.2942065001 0.1292198002 + 0.4124872983 0.2987079918 0.1313749999 + 0.4182811975 0.3031933904 0.1335413009 + 0.4240790904 0.3076609075 0.1357281953 + 0.4298571944 0.3121108115 0.1379179060 + 0.4356110096 0.3165585101 0.1401115060 + 0.4413394928 0.3209869862 0.1423158050 + 0.4470395148 0.3254047930 0.1445332021 + 0.4527026117 0.3298167884 0.1467590034 + 0.4583334923 0.3342174888 0.1489966065 + 0.4639326930 0.3386009932 0.1512416005 + 0.4695220888 0.3429653049 0.1534925997 + 0.4750846922 0.3473365903 0.1557577997 + 0.4806160927 0.3517040908 0.1580404937 + 0.4860872924 0.3560670912 0.1603357941 + 0.4915176928 0.3604130149 0.1626514047 + 0.4969187081 0.3647586107 0.1649708003 + 0.5022816062 0.3691031039 0.1672956944 + 0.5076225996 0.3734341860 0.1696293950 + 0.5129231811 0.3777643144 0.1719669998 + 0.5181546807 0.3820936084 0.1743122041 + 0.5233271718 0.3864077926 0.1766573936 + 0.5284634233 0.3907110095 0.1790025979 + 0.5335465074 0.3950001001 0.1813486069 + 0.5385751724 0.3992711008 0.1836972982 + 0.5435780883 0.4035327137 0.1860560030 + 0.5485448241 0.4077767134 0.1884246022 + 0.5534678102 0.4120056033 0.1908023953 + 0.5583646297 0.4162251055 0.1931803972 + 0.5632166862 0.4203993082 0.1955589950 + 0.5680477023 0.4245612025 0.1979466975 + 0.5728545189 0.4287038147 0.2003419995 + 0.5775995255 0.4328233004 0.2027534992 + 0.5823162794 0.4369328022 0.2051690072 + 0.5869674087 0.4410141110 0.2075875998 + 0.5915768743 0.4450846910 0.2100103050 + 0.5961518884 0.4491345882 0.2124343067 + 0.6006463170 0.4531683922 0.2148666978 + 0.6051229239 0.4571923018 0.2172998041 + 0.6095721126 0.4611825943 0.2197346985 + 0.6139861941 0.4651634991 0.2221716940 + 0.6183604002 0.4691112041 0.2246143073 + 0.6226823926 0.4730412066 0.2270615995 + 0.6269859076 0.4769391119 0.2295158058 + 0.6312270761 0.4808132946 0.2319785058 + 0.6354541779 0.4846689999 0.2344491929 + 0.6396340728 0.4885058105 0.2369215935 + 0.6438084245 0.4923363924 0.2393949032 + 0.6479752064 0.4961437881 0.2418684959 + 0.6520851254 0.4999468923 0.2443421036 + 0.6561610103 0.5037171841 0.2468205988 + 0.6601614952 0.5074794292 0.2493008971 + 0.6641432047 0.5112071037 0.2517744899 + 0.6680347919 0.5149219036 0.2542459071 + 0.6719154716 0.5186061263 0.2567091882 + 0.6757277846 0.5222734809 0.2591697872 + 0.6795322895 0.5259137750 0.2616206110 + 0.6833059192 0.5295230746 0.2640681863 + 0.6870679259 0.5330942273 0.2665097117 + 0.6908019781 0.5366339087 0.2689489126 + 0.6945022941 0.5401414037 0.2713932097 + 0.6981444955 0.5436180830 0.2738403976 + 0.7017527223 0.5470659733 0.2762868106 + 0.7053136826 0.5504943728 0.2787325978 + 0.7088435292 0.5539047718 0.2811723053 + 0.7123348117 0.5572900772 0.2836047113 + 0.7157995105 0.5606504083 0.2860364020 + 0.7192326784 0.5639901757 0.2884666920 + 0.7226405144 0.5673059225 0.2908954918 + 0.7260167003 0.5705996752 0.2933177948 + 0.7293487191 0.5738595724 0.2957400084 + 0.7326173782 0.5771085024 0.2981606126 + 0.7358595133 0.5803325772 0.3005810976 + 0.7390533090 0.5835512877 0.3029994965 + 0.7422223091 0.5867486000 0.3054173887 + 0.7453266978 0.5899420977 0.3078261018 + 0.7484182715 0.5930835009 0.3102284968 + 0.7514507174 0.5962249041 0.3126305044 + 0.7544791102 0.5993114114 0.3150317967 + 0.7574347258 0.6023926139 0.3174335063 + 0.7603902817 0.6054285169 0.3198406994 + 0.7632429004 0.6084480286 0.3222478032 + 0.7660846710 0.6114342213 0.3246580958 + 0.7688931227 0.6143910885 0.3270691931 + 0.7716894150 0.6173362732 0.3294793069 + 0.7744498253 0.6202554703 0.3318881989 + 0.7771797776 0.6231728196 0.3342961073 + 0.7798776031 0.6260603070 0.3366977870 + 0.7825078964 0.6289477944 0.3390995860 + 0.7851305008 0.6318117976 0.3414917886 + 0.7876675725 0.6346691847 0.3438811004 + 0.7902047038 0.6375092864 0.3462617099 + 0.7926716805 0.6403307915 0.3486273885 + 0.7951231003 0.6431398988 0.3509930074 + 0.7975525260 0.6458842754 0.3533450067 + 0.7999621034 0.6486287117 0.3556961119 + 0.8023657799 0.6513149738 0.3580406904 + 0.8047469854 0.6539878845 0.3603785932 + 0.8071283102 0.6566321254 0.3627164066 + 0.8094397187 0.6592395902 0.3650526106 + 0.8117408156 0.6618456841 0.3673886955 + 0.8139895797 0.6644176841 0.3697170913 + 0.8161870241 0.6669896841 0.3720383942 + 0.8183761239 0.6695259213 0.3743596971 + 0.8205000162 0.6720392704 0.3766688108 + 0.8226239085 0.6745491028 0.3789778948 + 0.8247258067 0.6770399213 0.3812792897 + 0.8268182278 0.6795307994 0.3835709095 + 0.8289020061 0.6819990277 0.3858624995 + 0.8309609294 0.6844567060 0.3881478012 + 0.8330196738 0.6869028211 0.3904320002 + 0.8350235224 0.6892951131 0.3927091956 + 0.8370118737 0.6916874051 0.3949654102 + 0.8389791846 0.6940457821 0.3972215950 + 0.8408939242 0.6963855028 0.3994632065 + 0.8428086042 0.6987230182 0.4016954005 + 0.8446682096 0.7010375261 0.4039277136 + 0.8465105295 0.7033519149 0.4061439037 + 0.8483420014 0.7056419253 0.4083589911 + 0.8501332998 0.7079067230 0.4105660021 + 0.8519244790 0.7101715803 0.4127483070 + 0.8536859751 0.7123854160 0.4149304926 + 0.8554301858 0.7145920992 0.4171046913 + 0.8571730852 0.7167863250 0.4192717075 + 0.8588685989 0.7189391255 0.4214386046 + 0.8605639935 0.7210919857 0.4236004949 + 0.8622372150 0.7232128978 0.4257610142 + 0.8638756275 0.7253087163 0.4279214144 + 0.8655139804 0.7274044156 0.4300718904 + 0.8671008945 0.7294499874 0.4322223067 + 0.8686684966 0.7314872742 0.4343703091 + 0.8702337742 0.7335180044 0.4365068972 + 0.8717327714 0.7355036736 0.4386434853 + 0.8732318878 0.7374892831 0.4407753050 + 0.8747140765 0.7394585013 0.4428966939 + 0.8761591911 0.7413989902 0.4450182021 + 0.8776043057 0.7433394194 0.4471280873 + 0.8790065050 0.7452735901 0.4492236078 + 0.8803750873 0.7472031116 0.4513190985 + 0.8817436099 0.7491325736 0.4533992112 + 0.8830839992 0.7510256767 0.4554660916 + 0.8844164014 0.7529067993 0.4575330019 + 0.8857486844 0.7547879815 0.4595870972 + 0.8870559931 0.7566236854 0.4616327882 + 0.8883624077 0.7584543824 0.4636783898 + 0.8896635771 0.7602844834 0.4657067060 + 0.8909289837 0.7620761991 0.4677248001 + 0.8921945095 0.7638679147 0.4697428942 + 0.8934394121 0.7656568289 0.4717616141 + 0.8946236968 0.7674204707 0.4737805128 + 0.8958079815 0.7691841722 0.4757995009 + 0.8969696164 0.7709385753 0.4778141081 + 0.8980888724 0.7726433873 0.4798257947 + 0.8992081881 0.7743480802 0.4818373919 + 0.9003195167 0.7760472894 0.4838384986 + 0.9014195800 0.7777205706 0.4858298898 + 0.9025197029 0.7793939114 0.4878214002 + 0.9035978913 0.7810617089 0.4898056984 + 0.9046490788 0.7827023864 0.4917800128 + 0.9057002068 0.7843430042 0.4937543869 + 0.9067236185 0.7859767079 0.4957253933 + 0.9077128172 0.7875623107 0.4976881146 + 0.9087020159 0.7891479731 0.4996508062 + 0.9096745849 0.7907313108 0.5016111732 + 0.9106239080 0.7922711968 0.5035545826 + 0.9115731716 0.7938110232 0.5054979920 + 0.9124993086 0.7953509092 0.5074414015 + 0.9133828282 0.7968598008 0.5093576908 + 0.9142662287 0.7983667254 0.5112711787 + 0.9151422977 0.7998737097 0.5131847262 + 0.9159966707 0.8013570905 0.5150825977 + 0.9168511033 0.8028343916 0.5169728994 + 0.9176996946 0.8043118119 0.5188632011 + 0.9185072780 0.8057656884 0.5207424760 + 0.9193148017 0.8072052002 0.5226051807 + 0.9201223254 0.8086445928 0.5244678855 + 0.9209262133 0.8100745082 0.5263286233 + 0.9217298031 0.8114904165 0.5281689167 + 0.9225333929 0.8129063249 0.5300090909 + 0.9233224988 0.8143162727 0.5318493843 + 0.9241070151 0.8156955242 0.5336812139 + 0.9248914719 0.8170747161 0.5355101228 + 0.9256622195 0.8184539080 0.5373389721 + 0.9264205098 0.8198124170 0.5391626954 + 0.9271788001 0.8211680055 0.5409774184 + 0.9279240966 0.8225237131 0.5427920222 + 0.9286308885 0.8238555193 0.5446066260 + 0.9293376803 0.8251689076 0.5463947058 + 0.9300444722 0.8264822960 0.5481811166 + 0.9307246208 0.8277850151 0.5499675870 + 0.9314032793 0.8290479183 0.5517386198 + 0.9320818782 0.8303108215 0.5534932017 + 0.9327319860 0.8315737247 0.5552479029 + 0.9333636761 0.8327975273 0.5570024848 + 0.9339953065 0.8340129256 0.5587229133 + 0.9346169233 0.8352283239 0.5604429841 + 0.9352049828 0.8364298940 0.5621631742 + 0.9357931018 0.8376104832 0.5638735890 + 0.9363812208 0.8387910128 0.5655727983 + 0.9369478822 0.8399716020 0.5672720075 + 0.9375097752 0.8411086798 0.5689712167 + 0.9380717874 0.8422427773 0.5706508160 + 0.9386349916 0.8433768749 0.5723282099 + 0.9392004013 0.8445004821 0.5740054846 + 0.9397658110 0.8456103802 0.5756754279 + 0.9403312206 0.8467202783 0.5773270726 + 0.9408558011 0.8478301764 0.5789787173 + 0.9413745999 0.8489074111 0.5806304216 + 0.9418935180 0.8499805927 0.5822653174 + 0.9423980713 0.8510538936 0.5838909149 + 0.9428763986 0.8521230221 0.5855165124 + 0.9433547258 0.8531830907 0.5871421099 + 0.9438331127 0.8542432189 0.5887404084 + 0.9443081021 0.8553032875 0.5903375149 + 0.9447823763 0.8563414812 0.5919346213 + 0.9452565908 0.8573703170 0.5935288072 + 0.9457269907 0.8583989739 0.5951129794 + 0.9461808801 0.8594260216 0.5966972113 + 0.9466348290 0.8604149818 0.5982813835 + 0.9470885992 0.8614040017 0.5998545289 + 0.9475203156 0.8623930812 0.6014149189 + 0.9479331970 0.8633654118 0.6029751897 + 0.9483461976 0.8643069267 0.6045355797 + 0.9487591982 0.8652483821 0.6060755253 + 0.9491466284 0.8661898971 0.6076046824 + 0.9495298862 0.8671160936 0.6091338992 + 0.9499133229 0.8680329919 0.6106631756 + 0.9502913952 0.8689497709 0.6121817827 + 0.9506375790 0.8698666096 0.6136978269 + 0.9509837031 0.8707538843 0.6152138710 + 0.9513298869 0.8716354966 0.6167299747 + 0.9516645074 0.8725172281 0.6182156801 + 0.9519801736 0.8733978868 0.6196988225 + 0.9522958994 0.8742434978 0.6211817861 + 0.9526115060 0.8750889897 0.6226648092 + 0.9529042244 0.8759344816 0.6241227984 + 0.9531800151 0.8767787218 0.6255803704 + 0.9534558058 0.8776161075 0.6270378828 + 0.9537314773 0.8784536123 0.6284952760 + 0.9539870024 0.8792909980 0.6299347878 + 0.9542350173 0.8801239729 0.6313741803 + 0.9544829726 0.8809452057 0.6328135729 + 0.9547309875 0.8817663789 0.6342530847 + 0.9549531937 0.8825874925 0.6356778741 + 0.9551706910 0.8833963275 0.6371027231 + 0.9553881884 0.8841794729 0.6385273933 + 0.9556056857 0.8849627972 0.6399521232 + 0.9558088183 0.8857461214 0.6413484812 + 0.9560105801 0.8865262866 0.6427426934 + 0.9562124014 0.8873007894 0.6441369057 + 0.9564142227 0.8880752921 0.6455309987 + 0.9566016793 0.8888496757 0.6469084024 + 0.9567884803 0.8896216154 0.6482821703 + 0.9569752812 0.8903880119 0.6496559978 + 0.9571620822 0.8911542892 0.6510298252 + 0.9573429823 0.8919206858 0.6523879170 + 0.9575235844 0.8926829100 0.6537382007 + 0.9577041864 0.8934323192 0.6550884843 + 0.9578847289 0.8941817284 0.6564388871 + 0.9580754042 0.8949311972 0.6577758193 + 0.9582675099 0.8956754208 0.6590979099 + 0.9584596157 0.8963845968 0.6604200006 + 0.9586517215 0.8970937729 0.6617420912 + 0.9588462114 0.8978030086 0.6630570889 + 0.9590412974 0.8985121846 0.6643490791 + 0.9592363834 0.8991947770 0.6656410098 + 0.9594315290 0.8998764753 0.6669330001 + 0.9596217275 0.9005582929 0.6682248712 + 0.9598088861 0.9012399912 0.6695014238 + 0.9599962234 0.9018872976 0.6707772017 + 0.9601835012 0.9025238752 0.6720529199 + 0.9603782296 0.9031605124 0.6733285785 + 0.9605820775 0.9037970901 0.6746001244 + 0.9607859850 0.9044255018 0.6758689880 + 0.9609898925 0.9050459862 0.6771379709 + 0.9611927271 0.9056665897 0.6784068942 + 0.9613916874 0.9062871933 0.6796714067 + 0.9615907073 0.9069045186 0.6809216142 + 0.9617896080 0.9075098038 0.6821717024 + 0.9619886279 0.9081152081 0.6834219098 + 0.9621633887 0.9087206125 0.6846719980 + 0.9623364210 0.9093260169 0.6859096885 + 0.9625093937 0.9099286199 0.6871445179 + 0.9626824260 0.9105308056 0.6883792281 + 0.9628574252 0.9111331105 0.6896139979 + 0.9630337954 0.9117352962 0.6908426285 + 0.9632101059 0.9123305082 0.6920586824 + 0.9633864760 0.9129180908 0.6932747960 + 0.9635632038 0.9135056138 0.6944910288 + 0.9637411237 0.9140931964 0.6957070827 + 0.9639191031 0.9146800041 0.6969081163 + 0.9640970230 0.9152501225 0.6981055140 + 0.9642748833 0.9158201814 0.6993029118 + 0.9644508958 0.9163902998 0.7005001903 + 0.9646263719 0.9169602990 0.7016944289 + 0.9648019075 0.9175173044 0.7028782964 + 0.9649773836 0.9180638790 0.7040622234 + 0.9651508927 0.9186105132 0.7052459717 + 0.9653204083 0.9191570878 0.7064298987 + 0.9654898047 0.9197033048 0.7075976133 + 0.9656593204 0.9202299118 0.7087550759 + 0.9658287168 0.9207565784 0.7099125981 + 0.9659901857 0.9212831855 0.7110701203 + 0.9661499262 0.9218099117 0.7122275233 + 0.9663096070 0.9223287106 0.7133823037 + 0.9664692283 0.9228376746 0.7145369053 + 0.9666253924 0.9233465791 0.7156915069 + 0.9667711854 0.9238554835 0.7168461084 + 0.9669169188 0.9243643880 0.7179933786 + 0.9670627117 0.9248356819 0.7191138864 + 0.9672083855 0.9252979159 0.7202343941 + 0.9673423171 0.9257600904 0.7213549018 + 0.9674692750 0.9262223244 0.7224754095 + 0.9675962925 0.9266850948 0.7235804796 + 0.9677233100 0.9271525741 0.7246658802 + 0.9678503275 0.9276201725 0.7257512808 + 0.9679561853 0.9280877113 0.7268366814 + 0.9680612087 0.9285551906 0.7279220819 + 0.9681661725 0.9290199280 0.7289987803 + 0.9682713151 0.9294800162 0.7300698757 + 0.9683721066 0.9299402237 0.7311409712 + 0.9684600830 0.9304003716 0.7322121263 + 0.9685481191 0.9308605194 0.7332832217 + 0.9686360955 0.9313055873 0.7343558073 + 0.9687241912 0.9317405820 0.7354289889 + 0.9687963128 0.9321755767 0.7365021110 + 0.9688509703 0.9326105714 0.7375752926 + 0.9689058065 0.9330456257 0.7386484146 + 0.9689605236 0.9334610105 0.7396969199 + 0.9690153003 0.9338703752 0.7407392263 + 0.9690718055 0.9342797995 0.7417815924 + 0.9691293836 0.9346892238 0.7428238988 + 0.9691869020 0.9350985885 0.7438662052 + 0.9692444205 0.9354946017 0.7448874712 + 0.9693019986 0.9358887076 0.7459040284 + 0.9693595767 0.9362828135 0.7469205260 + 0.9694172740 0.9366768003 0.7479370236 + 0.9694749713 0.9370709062 0.7489535213 + 0.9695327282 0.9374542832 0.7499631047 + 0.9695904255 0.9378368855 0.7509707212 + 0.9696562290 0.9382194877 0.7519782782 + 0.9697234035 0.9386020899 0.7529858947 + 0.9697905779 0.9389846921 0.7539935112 + 0.9698578119 0.9393534064 0.7549921870 + 0.9699249864 0.9397209883 0.7559866905 + 0.9700003266 0.9400886297 0.7569811940 + 0.9700766802 0.9404562116 0.7579756975 + 0.9701529741 0.9408237934 0.7589702010 + 0.9702293873 0.9411832094 0.7599533200 + 0.9703058004 0.9415413737 0.7609264255 + 0.9703885913 0.9418995976 0.7618994713 + 0.9704725742 0.9422578216 0.7628725767 + 0.9705566168 0.9426159859 0.7638456225 + 0.9706404805 0.9429603815 0.7648131251 + 0.9707245231 0.9433007836 0.7657690048 + 0.9708133936 0.9436411858 0.7667248249 + 0.9709036946 0.9439815879 0.7676807046 + 0.9709941149 0.9443218708 0.7686365843 + 0.9710844755 0.9446520805 0.7695921063 + 0.9711748958 0.9449757934 0.7705423832 + 0.9712682962 0.9452995062 0.7714927793 + 0.9713637233 0.9456232190 0.7724431753 + 0.9714590907 0.9459468722 0.7733935118 + 0.9715543985 0.9462659955 0.7743439078 + 0.9716498256 0.9465780258 0.7752857804 + 0.9717406034 0.9468899965 0.7762247920 + 0.9718248844 0.9472020268 0.7771639228 + 0.9719092846 0.9475139976 0.7781028748 + 0.9719936848 0.9478241205 0.7790420055 + 0.9720780849 0.9481198788 0.7799775004 + 0.9721639752 0.9484158158 0.7809069157 + 0.9722574949 0.9487115741 0.7818363905 + 0.9723510146 0.9490075111 0.7827658057 + 0.9724445939 0.9493033886 0.7836952806 + 0.9725381136 0.9495918155 0.7846246958 + 0.9726316929 0.9498783946 0.7855424881 + 0.9727249742 0.9501649141 0.7864595056 + 0.9728183150 0.9504513741 0.7873764038 + 0.9729115963 0.9507378936 0.7882934213 + 0.9730048776 0.9510220885 0.7892103791 + 0.9730982184 0.9513028860 0.7901170850 + 0.9731950164 0.9515836239 0.7910107970 + 0.9732956290 0.9518643022 0.7919045091 + 0.9733961225 0.9521449804 0.7927982211 + 0.9734966755 0.9524257779 0.7936918736 + 0.9735972285 0.9526972175 0.7945855856 + 0.9736980200 0.9529681802 0.7954729199 + 0.9738026261 0.9532393217 0.7963594198 + 0.9739071131 0.9535102844 0.7972459197 + 0.9740117192 0.9537813067 0.7981324196 + 0.9741162062 0.9540500045 0.7990188003 + 0.9742208123 0.9543160200 0.7999022007 + 0.9743257165 0.9545819759 0.8007770777 + 0.9744309187 0.9548478723 0.8016518950 + 0.9745361209 0.9551138878 0.8025267720 + 0.9746413231 0.9553797841 0.8034017086 + 0.9747465253 0.9556449056 0.8042765856 + 0.9748516083 0.9559097886 0.8051419854 + 0.9749541283 0.9561746716 0.8060011268 + 0.9750565290 0.9564396739 0.8068600893 + 0.9751588702 0.9567046165 0.8077191710 + 0.9752613902 0.9569633007 0.8085781932 + 0.9753637910 0.9572036862 0.8094372749 + 0.9754638076 0.9574440718 0.8102779984 + 0.9755604267 0.9576845765 0.8111159205 + 0.9756569266 0.9579250216 0.8119537234 + 0.9757534266 0.9581654072 0.8127915263 + 0.9758499861 0.9584035873 0.8136293888 + 0.9759464860 0.9586400986 0.8144659996 + 0.9760364890 0.9588767290 0.8152853847 + 0.9761242867 0.9591131806 0.8161048293 + 0.9762120247 0.9593496919 0.8169242144 + 0.9762998223 0.9595862031 0.8177435994 + 0.9763875008 0.9598243833 0.8185629845 + 0.9764752984 0.9600629807 0.8193802834 + 0.9765614867 0.9603015184 0.8201889992 + 0.9766476154 0.9605401158 0.8209977150 + 0.9767338037 0.9607787132 0.8218063712 + 0.9768199921 0.9610170722 0.8226152062 + 0.9769061804 0.9612380862 0.8234239221 + 0.9769896269 0.9614589810 0.8242325187 + 0.9770637155 0.9616798759 0.8250408173 + 0.9771376848 0.9619007707 0.8258491158 + 0.9772117138 0.9621217847 0.8266574144 + 0.9772858024 0.9623394012 0.8274655938 + 0.9773597717 0.9625350237 0.8282738924 + 0.9774324298 0.9627305865 0.8290752172 + 0.9775022864 0.9629262090 0.8298593760 + 0.9775723219 0.9631217718 0.8306434751 + 0.9776422977 0.9633173943 0.8314276934 + 0.9777122736 0.9635074139 0.8322117925 + 0.9777823091 0.9636734724 0.8329960108 + 0.9778506756 0.9638395905 0.8337736726 + 0.9779173136 0.9640057087 0.8345307708 + 0.9779838920 0.9641718268 0.8352878094 + 0.9780504704 0.9643378854 0.8360449076 + 0.9781171083 0.9645028710 0.8368018866 + 0.9781836867 0.9646632075 0.8375589848 + 0.9782491922 0.9648234844 0.8383142948 + 0.9783133864 0.9649837017 0.8390561938 + 0.9783775806 0.9651439786 0.8397982121 + 0.9784417748 0.9653041959 0.8405401111 + 0.9785060287 0.9654663801 0.8412820101 + 0.9785702229 0.9656417966 0.8420239091 + 0.9786368012 0.9658172727 0.8427659273 + 0.9787064791 0.9659928083 0.8434938788 + 0.9787762761 0.9661682844 0.8442208171 + 0.9788460135 0.9663438201 0.8449476957 + 0.9789156914 0.9665191770 0.8456746936 + 0.9789854288 0.9667049050 0.8464015722 + 0.9790521264 0.9668906927 0.8471285105 + 0.9791120887 0.9670764804 0.8478465080 + 0.9791721106 0.9672623277 0.8485602736 + 0.9792320728 0.9674479961 0.8492740989 + 0.9792920947 0.9676337838 0.8499878049 + 0.9793521166 0.9678208232 0.8507015705 + 0.9794105291 0.9680082202 0.8514152765 + 0.9794589877 0.9681956172 0.8521232009 + 0.9795076251 0.9683828950 0.8528202772 + 0.9795562029 0.9685702920 0.8535174131 + 0.9796047807 0.9687576890 0.8542146087 + 0.9796532989 0.9689376950 0.8549116850 + 0.9797018766 0.9691110253 0.8556088805 + 0.9797381759 0.9692844152 0.8563060164 + 0.9797729850 0.9694576859 0.8569779992 + 0.9798077941 0.9696310163 0.8576492071 + 0.9798427224 0.9698044062 0.8583204150 + 0.9798774719 0.9699763060 0.8589916229 + 0.9799122810 0.9701421857 0.8596627712 + 0.9799376130 0.9703081250 0.8603339791 + 0.9799560905 0.9704741240 0.8609988093 + 0.9799745083 0.9706400037 0.8616573811 + 0.9799929857 0.9708058834 0.8623160124 + 0.9800114036 0.9709718227 0.8629745841 + 0.9800298810 0.9711270928 0.8636332154 + 0.9800478220 0.9712795019 0.8642917871 + 0.9800634980 0.9714319110 0.8649504185 + 0.9800791740 0.9715842009 0.8655930758 + 0.9800949097 0.9717366099 0.8662353754 + 0.9801105857 0.9718890190 0.8668777943 + 0.9801263213 0.9720391035 0.8675202131 + 0.9801419973 0.9721841812 0.8681625724 + 0.9801493883 0.9723293185 0.8688049912 + 0.9801540971 0.9724743962 0.8694401979 + 0.9801586866 0.9726194739 0.8700637817 + 0.9801633954 0.9727646112 0.8706874251 + 0.9801681042 0.9729096293 0.8713108897 + 0.9801728129 0.9730468988 0.8719344735 + 0.9801768064 0.9731817245 0.8725581169 + 0.9801785946 0.9733164907 0.8731817007 + 0.9801803827 0.9734513164 0.8737874031 + 0.9801821709 0.9735862017 0.8743858933 + 0.9801840186 0.9737210274 0.8749843836 + 0.9801859260 0.9738534093 0.8755828738 + 0.9801877141 0.9739726186 0.8761814237 + 0.9801887274 0.9740918279 0.8767799139 + 0.9801893234 0.9742109776 0.8773784041 + 0.9801899195 0.9743301272 0.8779736757 + 0.9801905155 0.9744492769 0.8785690069 + 0.9801911116 0.9745684862 0.8791642189 + 0.9801917076 0.9746857285 0.8797594905 + 0.9801923037 0.9748008251 0.8803547025 + 0.9801943898 0.9749158025 0.8809499741 + 0.9801964760 0.9750308990 0.8815435767 + 0.9801986814 0.9751458764 0.8821282983 + 0.9802008271 0.9752609134 0.8827130198 + 0.9802029729 0.9753760099 0.8832976222 + 0.9802051187 0.9754949212 0.8838822842 + 0.9802073240 0.9756155014 0.8844670057 + 0.9802094102 0.9757360220 0.8850517273 + 0.9802116156 0.9758566022 0.8856287003 + 0.9802137017 0.9759771824 0.8861843944 + 0.9802159071 0.9760977030 0.8867400289 + 0.9802179933 0.9762182832 0.8872956038 + 0.9802200794 0.9763411283 0.8878511786 + 0.9802222848 0.9764642119 0.8884068131 + 0.9802243710 0.9765874147 0.8889623880 + 0.9802265763 0.9767104983 0.8895106912 + 0.9802287221 0.9768335819 0.8900415897 + 0.9802309275 0.9769567847 0.8905724883 + 0.9802330136 0.9770799279 0.8911035061 + 0.9802352190 0.9772124887 0.8916344047 + 0.9802373052 0.9773454070 0.8921653032 + 0.9802395105 0.9774783254 0.8926963210 + 0.9802415967 0.9776111841 0.8932245970 + 0.9802438021 0.9777441025 0.8937453032 + 0.9802458882 0.9778770208 0.8942660093 + 0.9802479744 0.9780098796 0.8947867155 + 0.9802501798 0.9781574011 0.8953074217 + 0.9802523255 0.9783051014 0.8958281875 + 0.9802544713 0.9784528017 0.8963488936 + 0.9802566171 0.9786006212 0.8968678117 + 0.9802588224 0.9787483215 0.8973752856 + 0.9802609086 0.9788960218 0.8978827000 + 0.9802631140 0.9790437222 0.8983901739 + 0.9802652001 0.9791916013 0.8988977075 + 0.9802674055 0.9793394804 0.8994051814 + 0.9802694917 0.9794874191 0.8999127150 + 0.9802716970 0.9796352983 0.9004201889 + 0.9802737832 0.9797831774 0.9009217024 + 0.9802759290 0.9799311161 0.9014229178 + 0.9802780747 0.9800789952 0.9019240737 + 0.9802802205 0.9802207947 0.9024252892 + 0.9802927971 0.9803609848 0.9029263854 + 0.9803174734 0.9805011749 0.9034276009 + 0.9803423285 0.9806414247 0.9039288163 + 0.9803670049 0.9807816148 0.9044218063 + 0.9803916812 0.9809218049 0.9049109221 + 0.9804164171 0.9810619950 0.9053999782 + 0.9804412127 0.9811941981 0.9058890939 + 0.9804722071 0.9813209176 0.9063782096 + 0.9805197120 0.9814475179 0.9068673253 + 0.9805672169 0.9815741777 0.9073563814 + 0.9806147814 0.9817007780 0.9078388810 + 0.9806622863 0.9818274975 0.9083073139 + 0.9807097912 0.9819540977 0.9087758064 + 0.9807572961 0.9820784926 0.9092441797 + 0.9808050990 0.9821977019 0.9097126126 + 0.9808717966 0.9823167920 0.9101811051 + 0.9809383750 0.9824360013 0.9106494784 + 0.9810050726 0.9825550914 0.9111179709 + 0.9810717106 0.9826743007 0.9115676880 + 0.9811384082 0.9827933908 0.9120151997 + 0.9812049866 0.9829124808 0.9124627113 + 0.9812716842 0.9830338955 0.9129102230 + 0.9813528061 0.9831554294 0.9133576751 + 0.9814409018 0.9832769036 0.9138051867 + 0.9815291166 0.9833983779 0.9142525792 + 0.9816172123 0.9835199118 0.9146981835 + 0.9817053080 0.9836413860 0.9151405096 + 0.9817934036 0.9837629199 0.9155828953 + 0.9818816185 0.9838852882 0.9160252213 + 0.9819723964 0.9840087891 0.9164674878 + 0.9820711017 0.9841321707 0.9169098735 + 0.9821699262 0.9842556715 0.9173521996 + 0.9822685719 0.9843791127 0.9177945852 + 0.9823673964 0.9845024943 0.9182294011 + 0.9824661016 0.9846259952 0.9186623096 + 0.9825648069 0.9847493768 0.9190952182 + 0.9826635718 0.9848722816 0.9195280075 + 0.9827668071 0.9849951267 0.9199609160 + 0.9828714132 0.9851179123 0.9203937054 + 0.9829760194 0.9852408171 0.9208266139 + 0.9830806255 0.9853636026 0.9212580919 + 0.9831852913 0.9854863882 0.9216784835 + 0.9832898974 0.9856092930 0.9220989943 + 0.9833945036 0.9857273102 0.9225193858 + 0.9834997058 0.9858360887 0.9229398966 + 0.9836072922 0.9859449267 0.9233602881 + 0.9837149978 0.9860537052 0.9237807989 + 0.9838227034 0.9861624837 0.9242011905 + 0.9839304090 0.9862713218 0.9246129990 + 0.9840379953 0.9863801003 0.9250090122 + 0.9841457009 0.9864888787 0.9254049063 + 0.9842534065 0.9865922928 0.9258008003 + 0.9843615294 0.9866927266 0.9261968136 + 0.9844700098 0.9867932200 0.9265927076 + 0.9845784903 0.9868935943 0.9269887209 + 0.9846869707 0.9869940281 0.9273846149 + 0.9847955108 0.9870945215 0.9277727008 + 0.9849039912 0.9871948957 0.9281532168 + 0.9850124121 0.9872953296 0.9285337925 + 0.9851208925 0.9873874187 0.9289144278 + 0.9852285981 0.9874783158 0.9292948842 + 0.9853361249 0.9875692129 0.9296755195 + 0.9854434729 0.9876601100 0.9300559759 + 0.9855508804 0.9877510071 0.9304366112 + 0.9856582880 0.9878419042 0.9308059812 + 0.9857658148 0.9879328012 0.9311676025 + 0.9858732224 0.9880235195 0.9315292239 + 0.9859805703 0.9881017208 0.9318907261 + 0.9860852957 0.9881799817 0.9322522879 + 0.9861897826 0.9882581830 0.9326137900 + 0.9862943888 0.9883363843 0.9329754114 + 0.9863988757 0.9884145856 0.9333369136 + 0.9865034223 0.9884927869 0.9336916804 + 0.9866079092 0.9885709882 0.9340415001 + 0.9867123961 0.9886481762 0.9343912005 + 0.9868168831 0.9887102842 0.9347409010 + 0.9869164228 0.9887723923 0.9350907207 + 0.9870160222 0.9888346195 0.9354404211 + 0.9871155024 0.9888967276 0.9357901216 + 0.9872151017 0.9889587760 0.9361398816 + 0.9873145819 0.9890210032 0.9364842176 + 0.9874141812 0.9890831113 0.9368222952 + 0.9875137210 0.9891446233 0.9371604919 + 0.9876132011 0.9891886115 0.9374986887 + 0.9877052903 0.9892325997 0.9378368855 + 0.9877973795 0.9892765880 0.9381750226 + 0.9878895283 0.9893206954 0.9385132194 + 0.9879816175 0.9893646836 0.9388514161 + 0.9880737066 0.9894086719 0.9391885996 + 0.9881657958 0.9894527197 0.9395235181 + 0.9882578850 0.9894968271 0.9398584962 + 0.9883499742 0.9895275831 0.9401934147 + 0.9884337187 0.9895573258 0.9405282736 + 0.9885166287 0.9895870090 0.9408631921 + 0.9885994792 0.9896166921 0.9411981106 + 0.9886823893 0.9896463752 0.9415330291 + 0.9887652993 0.9896761179 0.9418678880 + 0.9888483286 0.9897058010 0.9422001839 + 0.9889311790 0.9897354841 0.9425324798 + 0.9890140891 0.9897568822 0.9428647161 + 0.9890915155 0.9897748828 0.9431970119 + 0.9891669154 0.9897928834 0.9435293078 + 0.9892423153 0.9898108840 0.9438614845 + 0.9893177152 0.9898290038 0.9441937804 + 0.9893931150 0.9898470044 0.9445260167 + 0.9894685149 0.9898650050 0.9448490143 + 0.9895439148 0.9898830056 0.9451668262 + 0.9896193147 0.9898968935 0.9454845786 + 0.9896823168 0.9899048805 0.9458023906 + 0.9897314906 0.9899129272 0.9461202025 + 0.9897806048 0.9899209142 0.9464380145 + 0.9898297191 0.9899289012 0.9467557073 + 0.9898788929 0.9899368882 0.9470735192 + 0.9899280071 0.9899448752 0.9473884106 + 0.9899771214 0.9899529815 0.9476900101 + 0.9900262952 0.9899609089 0.9479916096 + 0.9900729060 0.9899665117 0.9482933283 + 0.9901000857 0.9899721146 0.9485949278 + 0.9901273847 0.9899777174 0.9488965869 + 0.9901546836 0.9899833202 0.9491981864 + 0.9901819229 0.9899889231 0.9494997859 + 0.9902092218 0.9899945259 0.9498015046 + 0.9902365208 0.9900001287 0.9501004815 + 0.9902637005 0.9900057912 0.9503980279 + 0.9902909994 0.9900106788 0.9506955147 + 0.9903110862 0.9900152087 0.9509931207 + 0.9903277755 0.9900196195 0.9512906075 + 0.9903444052 0.9900240898 0.9515880942 + 0.9903609753 0.9900286198 0.9518855810 + 0.9903776050 0.9900329709 0.9521831274 + 0.9903942943 0.9900375009 0.9524806142 + 0.9904109240 0.9900419116 0.9527738094 + 0.9904274940 0.9900463820 0.9530668855 + 0.9904429913 0.9900497794 0.9533600211 + 0.9904512763 0.9900531173 0.9536530972 + 0.9904596210 0.9900565147 0.9539461732 + 0.9904679060 0.9900599122 0.9542394280 + 0.9904761910 0.9900631905 0.9545325041 + 0.9904844761 0.9900665879 0.9548255801 + 0.9904927015 0.9900699854 0.9551169872 + 0.9905009866 0.9900733232 0.9554036856 + 0.9905092716 0.9900764227 0.9556903243 + 0.9905135036 0.9900786877 0.9559770226 + 0.9905136228 0.9900810122 0.9562636018 + 0.9905136824 0.9900833964 0.9565503001 + 0.9905138016 0.9900857210 0.9568368793 + 0.9905139208 0.9900879860 0.9571235776 + 0.9905139804 0.9900904298 0.9574102163 + 0.9905140996 0.9900926948 0.9576948285 + 0.9905142188 0.9900950193 0.9579765797 + 0.9905142188 0.9900968075 0.9582585096 + 0.9905145168 0.9900981784 0.9585403204 + 0.9905148149 0.9900994897 0.9588220716 + 0.9905151725 0.9901009202 0.9591038823 + 0.9905154705 0.9901022911 0.9593858123 + 0.9905158281 0.9901036024 0.9596676230 + 0.9905161262 0.9901049733 0.9599493742 + 0.9905164838 0.9901064038 0.9602293968 + 0.9905167818 0.9901077151 0.9605073929 + 0.9905170798 0.9901083708 0.9607855082 + 0.9905173779 0.9901089072 0.9610636234 + 0.9905176759 0.9901093245 0.9613416791 + 0.9905180931 0.9901098013 0.9616196752 + 0.9905183911 0.9901102185 0.9618977904 + 0.9905186892 0.9901106954 0.9621759057 + 0.9905189872 0.9901111126 0.9624540210 + 0.9905194044 0.9901115894 0.9627259970 + 0.9905197024 0.9901120067 0.9629914761 + 0.9905200005 0.9901124835 0.9632570148 + 0.9905202985 0.9901130199 0.9635224938 + 0.9905205965 0.9901136160 0.9637879729 + 0.9905210137 0.9901140928 0.9640535116 + 0.9905213118 0.9901146293 0.9643189907 + 0.9905216098 0.9901151061 0.9645845294 + 0.9905219078 0.9901155829 0.9648500085 + 0.9905223250 0.9901161194 0.9651170969 + 0.9905226231 0.9901167154 0.9653869867 + 0.9905229211 0.9901171923 0.9656568170 + 0.9905232191 0.9901177287 0.9659267068 + 0.9905235171 0.9901182055 0.9661965966 + 0.9905238748 0.9901186824 0.9664664268 + 0.9905241728 0.9901192188 0.9667363167 + 0.9905244708 0.9901198149 0.9670060873 + 0.9905248284 0.9901202917 0.9672759771 + 0.9905251861 0.9901208282 0.9675456285 + 0.9905254841 0.9901213050 0.9678133130 + 0.9905257821 0.9901217818 0.9680811167 + 0.9905260801 0.9901223183 0.9683488011 + 0.9905264974 0.9901229143 0.9686166048 + 0.9905267954 0.9901233912 0.9688842893 + 0.9905270934 0.9901239276 0.9691520929 + 0.9905273914 0.9901244044 0.9694197774 + 0.9905276895 0.9901248813 0.9696875811 + 0.9905281067 0.9901254177 0.9699553251 + 0.9905284047 0.9901258945 0.9702137709 + 0.9905287027 0.9901264906 0.9704701900 + 0.9905290008 0.9901270270 0.9707266092 + 0.9905294180 0.9901275039 0.9709830284 + 0.9905297160 0.9901279807 0.9712393880 + 0.9905300140 0.9901285172 0.9714958072 + 0.9905303121 0.9901289940 0.9717522264 + 0.9905306101 0.9901295900 0.9720085859 + 0.9905310273 0.9901301265 0.9722651243 + 0.9905313253 0.9901306033 0.9725131989 + 0.9905316234 0.9901310802 0.9727489948 + 0.9905319214 0.9901316166 0.9729847908 + 0.9905322790 0.9901320934 0.9732205868 + 0.9905325770 0.9901326895 0.9734563828 + 0.9905328751 0.9901332259 0.9736921787 + 0.9905331731 0.9901337028 0.9739279747 + 0.9905334711 0.9901341796 0.9741637707 + 0.9905338883 0.9901347160 0.9743996263 + 0.9905341864 0.9901351929 0.9746354222 + 0.9905344844 0.9901357889 0.9748558998 + 0.9905347824 0.9901363254 0.9750742912 + 0.9905351996 0.9901368022 0.9752926230 + 0.9905354977 0.9901372790 0.9755108953 + 0.9905357957 0.9901378155 0.9757292867 + 0.9905360937 0.9901382923 0.9759476185 + 0.9905363917 0.9901388884 0.9761658907 + 0.9905368090 0.9901394248 0.9763842821 + 0.9905371070 0.9901399016 0.9766026139 + 0.9905374050 0.9901403785 0.9768189192 + 0.9905377030 0.9901409149 0.9770290852 + 0.9905450940 0.9901413918 0.9772393107 + 0.9905598164 0.9901419282 0.9774494767 + 0.9905744791 0.9901425242 0.9776597023 + 0.9905890822 0.9901430011 0.9778699279 + 0.9906038046 0.9901434779 0.9780800939 + 0.9906185269 0.9901440144 0.9782903194 + 0.9906330705 0.9901444912 0.9785004854 + 0.9906477928 0.9901450276 0.9787107110 + 0.9906623960 0.9901456237 0.9789108038 + 0.9906771183 0.9901518822 0.9791017771 + 0.9906994104 0.9901679754 0.9792928100 + 0.9907227159 0.9901841879 0.9794839025 + 0.9907460213 0.9902004004 0.9796748757 + 0.9907693267 0.9902166128 0.9798659086 + 0.9907925725 0.9902328253 0.9800568819 + 0.9908158779 0.9902489781 0.9802479148 + 0.9908391833 0.9902651906 0.9804388881 + 0.9908624887 0.9902812839 0.9806299210 + 0.9908857942 0.9902974963 0.9808201790 + 0.9909120202 0.9903177023 0.9810101986 + 0.9909530282 0.9903402925 0.9812002182 + 0.9909939766 0.9903628826 0.9813901782 + 0.9910349250 0.9903854728 0.9815803170 + 0.9910758734 0.9904081225 0.9817702770 + 0.9911168814 0.9904307127 0.9819602966 + 0.9911578298 0.9904533029 0.9821503162 + 0.9911987782 0.9904758930 0.9823402762 + 0.9912397861 0.9904984832 0.9825302958 + 0.9912806749 0.9905210733 0.9827157855 + 0.9913269281 0.9905534983 0.9828997254 + 0.9913831949 0.9905890822 0.9830836058 + 0.9914394021 0.9906246066 0.9832674265 + 0.9914957285 0.9906600714 0.9834513068 + 0.9915518761 0.9906957150 0.9836351871 + 0.9916082025 0.9907311797 0.9838191271 + 0.9916644096 0.9907668233 0.9840028882 + 0.9917206764 0.9908022881 0.9841868281 + 0.9917770028 0.9908378124 0.9843707085 + 0.9918332100 0.9908733964 0.9845507741 + 0.9918966293 0.9909213781 0.9847291708 + 0.9919701815 0.9909728169 0.9849076271 + 0.9920437932 0.9910240769 0.9850859046 + 0.9921175241 0.9910753965 0.9852643013 + 0.9921910763 0.9911267757 0.9854426980 + 0.9922646880 0.9911780953 0.9856210947 + 0.9923382998 0.9912294149 0.9857994914 + 0.9924119115 0.9912807941 0.9859778881 + 0.9924855232 0.9913321137 0.9861562848 + 0.9925590754 0.9913833737 0.9863287807 + 0.9926332831 0.9914423823 0.9864963889 + 0.9927082062 0.9915043712 0.9866638780 + 0.9927831888 0.9915664196 0.9868314266 + 0.9928581119 0.9916284084 0.9869989157 + 0.9929330945 0.9916903973 0.9871664047 + 0.9930080175 0.9917523861 0.9873338938 + 0.9930830002 0.9918143153 0.9875013828 + 0.9931579828 0.9918763041 0.9876688719 + 0.9932329059 0.9919382930 0.9878364801 + 0.9933078885 0.9920002818 0.9879997969 + 0.9933835864 0.9920656085 0.9881514907 + 0.9934617877 0.9921336174 0.9883031845 + 0.9935399890 0.9922016859 0.9884548783 + 0.9936181903 0.9922698140 0.9886065722 + 0.9936962724 0.9923378825 0.9887583256 + 0.9937744737 0.9924060106 0.9889100194 + 0.9938526750 0.9924740791 0.9890617132 + 0.9939308763 0.9925422072 0.9892134070 + 0.9940090775 0.9926102757 0.9893651009 + 0.9940872788 0.9926782846 0.9895167947 + 0.9941654801 0.9927479029 0.9896612763 + 0.9942458868 0.9928218722 0.9898049235 + 0.9943264127 0.9928959012 0.9899485111 + 0.9944068789 0.9929698706 0.9900920987 + 0.9944872856 0.9930438995 0.9902356863 + 0.9945678115 0.9931179881 0.9903792739 + 0.9946482778 0.9931920171 0.9905229211 + 0.9947286844 0.9932659864 0.9906665087 + 0.9948092103 0.9933400154 0.9908100963 + 0.9948896766 0.9934139848 0.9909536839 + 0.9949702024 0.9934880137 0.9910960197 + 0.9950510263 0.9935687184 0.9912365079 + 0.9951320887 0.9936506152 0.9913768768 + 0.9952132106 0.9937325120 0.9915173054 + 0.9952942729 0.9938144088 0.9916576743 + 0.9953753948 0.9938963056 0.9917981029 + 0.9954563975 0.9939782023 0.9919384718 + 0.9955375195 0.9940600991 0.9920789003 + 0.9956185818 0.9941418767 0.9922193885 + 0.9956997037 0.9942237735 0.9923598170 + 0.9957808256 0.9943056703 0.9925001860 + 0.9958618283 0.9943904281 0.9926363230 + 0.9959421158 0.9944810271 0.9927713275 + 0.9960222840 0.9945715070 0.9929062724 + 0.9961025715 0.9946621060 0.9930412173 + 0.9961829185 0.9947527051 0.9931762218 + 0.9962632060 0.9948431849 0.9933112264 + 0.9963434935 0.9949337840 0.9934461117 + 0.9964237809 0.9950243235 0.9935811162 + 0.9965040088 0.9951149225 0.9937161207 + 0.9965842962 0.9952055216 0.9938511252 + 0.9966645837 0.9952960014 0.9939857125 + 0.9967439771 0.9953925014 0.9941160083 + 0.9968224764 0.9954916239 0.9942464232 + 0.9969010949 0.9955906868 0.9943767190 + 0.9969795942 0.9956899285 0.9945070148 + 0.9970582128 0.9957889915 0.9946373105 + 0.9971367121 0.9958881140 0.9947676063 + 0.9972152710 0.9959872961 0.9948979020 + 0.9972937703 0.9960864186 0.9950283170 + 0.9973723888 0.9961854815 0.9951586127 + 0.9974510074 0.9962846041 0.9952889085 + 0.9975295067 0.9963837862 0.9954196215 + 0.9976075292 0.9964898825 0.9955514073 + 0.9976853132 0.9965963960 0.9956831932 + 0.9977632165 0.9967029095 0.9958150983 + 0.9978411198 0.9968094230 0.9959468842 + 0.9979189038 0.9969159961 0.9960787296 + 0.9979968071 0.9970225096 0.9962105751 + 0.9980745912 0.9971290231 0.9963424206 + 0.9981524944 0.9972354770 0.9964742064 + 0.9982303977 0.9973421097 0.9966061115 + 0.9983081818 0.9974486232 0.9967378974 + 0.9983860850 0.9975554943 0.9968718290 + 0.9984629154 0.9976667166 0.9970114231 + 0.9985396862 0.9977778792 0.9971510768 + 0.9986165166 0.9978891015 0.9972906709 + 0.9986932874 0.9980002046 0.9974303246 + 0.9987701178 0.9981114268 0.9975699186 + 0.9988468885 0.9982225895 0.9977095723 + 0.9989237189 0.9983338118 0.9978492260 + 0.9990004897 0.9984449744 0.9979888201 + 0.9990773201 0.9985561967 0.9981284142 + 0.9991542101 0.9986674190 0.9982680082 + 0.9992305040 0.9987785816 0.9984086156 + 0.9993004799 0.9988896251 0.9985532761 + 0.9993703961 0.9990006089 0.9986979961 + 0.9994403720 0.9991117120 0.9988425970 + 0.9995102882 0.9992226958 0.9989873171 + 0.9995803237 0.9993337989 0.9991319776 + 0.9996501803 0.9994447827 0.9992766976 + 0.9997202158 0.9995558262 0.9994212985 + 0.9997900724 0.9996669292 0.9995660186 + 0.9998601079 0.9997779131 0.9997106791 + 0.9999300241 0.9998890162 0.9998552799 + 1.0000000000 1.0000000000 1.0000000000 +} diff --git a/rpplugins/color_correction/resources/film_luts_raw/kodak_ektachrome_100_plus.spi1d b/rpplugins/color_correction/resources/film_luts_raw/kodak_ektachrome_100_plus.spi1d new file mode 100644 index 0000000..9b7575b --- /dev/null +++ b/rpplugins/color_correction/resources/film_luts_raw/kodak_ektachrome_100_plus.spi1d @@ -0,0 +1,1030 @@ +Version 1 +From 0.0 1.0 +Length 1024 +Components 3 +{ + 0.0000000000 0.0000000000 0.0000000000 + 0.0004568259 0.0001897309 0.0001937342 + 0.0009166480 0.0003902519 0.0003960232 + 0.0013811550 0.0006009749 0.0006110691 + 0.0018588870 0.0008188499 0.0008411508 + 0.0023563609 0.0010459250 0.0010869150 + 0.0028804501 0.0012829941 0.0013466120 + 0.0034379531 0.0015326150 0.0016192500 + 0.0040225340 0.0017928330 0.0019048119 + 0.0046354202 0.0020639880 0.0022035320 + 0.0052711908 0.0023474649 0.0025181000 + 0.0059363251 0.0026404259 0.0028487111 + 0.0066329152 0.0029452001 0.0031957659 + 0.0073490841 0.0032632940 0.0035582529 + 0.0080807637 0.0035944299 0.0039348011 + 0.0088355178 0.0039396151 0.0043245698 + 0.0096289609 0.0043014390 0.0047304570 + 0.0104655102 0.0046766838 0.0051527582 + 0.0113350702 0.0050640670 0.0055932738 + 0.0122496197 0.0054649492 0.0060512018 + 0.0131988404 0.0058779810 0.0065282308 + 0.0141810300 0.0063044452 0.0070242109 + 0.0151987597 0.0067441980 0.0075386940 + 0.0162404794 0.0072005908 0.0080726901 + 0.0173083302 0.0076743681 0.0086258948 + 0.0184124205 0.0081653623 0.0091975229 + 0.0195518192 0.0086749326 0.0097900750 + 0.0207353197 0.0092027588 0.0103992401 + 0.0219628699 0.0097467797 0.0110272104 + 0.0232388396 0.0103067802 0.0116758104 + 0.0245534405 0.0108824596 0.0123488903 + 0.0259076506 0.0114777200 0.0130474502 + 0.0273041893 0.0120923202 0.0137724997 + 0.0287391301 0.0127261700 0.0145242196 + 0.0302102603 0.0133811496 0.0153033203 + 0.0317212492 0.0140584502 0.0161061808 + 0.0332731493 0.0147604104 0.0169263799 + 0.0348760188 0.0154822599 0.0177620295 + 0.0365183204 0.0162258204 0.0186164491 + 0.0382087417 0.0169929601 0.0194896292 + 0.0399495289 0.0177801996 0.0203795508 + 0.0417297594 0.0185851697 0.0212911796 + 0.0435510091 0.0194129106 0.0222245902 + 0.0454129390 0.0202547908 0.0231861304 + 0.0473076887 0.0211168006 0.0241758395 + 0.0492347218 0.0219969898 0.0251984708 + 0.0512037501 0.0229012799 0.0262466706 + 0.0532191209 0.0238268599 0.0273228493 + 0.0552755818 0.0247761197 0.0284204800 + 0.0573842004 0.0257481597 0.0295423996 + 0.0595382415 0.0267426297 0.0306846593 + 0.0617300794 0.0277668294 0.0318456888 + 0.0639634207 0.0288175102 0.0330268405 + 0.0662460178 0.0298932791 0.0342224501 + 0.0685783774 0.0309970807 0.0354311503 + 0.0709521696 0.0321253613 0.0366570689 + 0.0733637214 0.0332747698 0.0379007794 + 0.0758268237 0.0344457105 0.0391649790 + 0.0783338398 0.0356396101 0.0404515490 + 0.0808990374 0.0368562713 0.0417614505 + 0.0835125297 0.0380946510 0.0430966802 + 0.0861754268 0.0393532701 0.0444576107 + 0.0888888985 0.0406360887 0.0458458997 + 0.0916479379 0.0419454388 0.0472616889 + 0.0944517180 0.0432827994 0.0486994199 + 0.0972917899 0.0446463488 0.0501526110 + 0.1001828983 0.0460356399 0.0516319200 + 0.1031202003 0.0474530496 0.0531338789 + 0.1061026007 0.0488977507 0.0546585694 + 0.1091277003 0.0503737107 0.0562016517 + 0.1121969000 0.0518880300 0.0577665791 + 0.1153125986 0.0534419082 0.0593559109 + 0.1184772998 0.0550320297 0.0609692894 + 0.1216840968 0.0566530786 0.0626069382 + 0.1249388009 0.0583061315 0.0642700866 + 0.1282431036 0.0599966310 0.0659606308 + 0.1315928996 0.0617280900 0.0676777512 + 0.1349757016 0.0634948835 0.0694218278 + 0.1383993030 0.0652914569 0.0711889118 + 0.1418682933 0.0671163797 0.0729750469 + 0.1453785002 0.0689697564 0.0747864991 + 0.1489267945 0.0708598867 0.0766221583 + 0.1525138021 0.0727824494 0.0784773678 + 0.1561374068 0.0747363791 0.0803539827 + 0.1597927064 0.0767190233 0.0822619572 + 0.1634854972 0.0787282810 0.0842007920 + 0.1672230065 0.0807615295 0.0861660689 + 0.1710027009 0.0828175321 0.0881549865 + 0.1748190969 0.0849011689 0.0901617482 + 0.1786739975 0.0870237797 0.0921890587 + 0.1825643927 0.0891877636 0.0942407027 + 0.1864794940 0.0913877636 0.0963157490 + 0.1904242039 0.0936163589 0.0984156132 + 0.1944115013 0.0958681777 0.1005403996 + 0.1984315068 0.0981432199 0.1026867032 + 0.2024817020 0.1004460007 0.1048531979 + 0.2065692991 0.1027875021 0.1070401967 + 0.2106909007 0.1051672027 0.1092483029 + 0.2148406059 0.1075756028 0.1114758030 + 0.2190158069 0.1100080982 0.1137152985 + 0.2232162058 0.1124617979 0.1159678996 + 0.2274380028 0.1149377003 0.1182356998 + 0.2316682935 0.1174454018 0.1205220968 + 0.2359098047 0.1199733987 0.1228303015 + 0.2401736975 0.1225221008 0.1251548976 + 0.2444601953 0.1250932068 0.1274984032 + 0.2487654984 0.1276911050 0.1298629940 + 0.2530876994 0.1303067952 0.1322595030 + 0.2574402988 0.1329407990 0.1346741021 + 0.2618153989 0.1355946958 0.1371085942 + 0.2662160099 0.1382690966 0.1395681947 + 0.2706286907 0.1409652978 0.1420474052 + 0.2750388086 0.1436827034 0.1445465982 + 0.2794604897 0.1464273036 0.1470647007 + 0.2838951945 0.1492000073 0.1496022046 + 0.2883372903 0.1519946009 0.1521558017 + 0.2927843034 0.1548147053 0.1547247022 + 0.2972404063 0.1576558053 0.1573172063 + 0.3016996980 0.1605056971 0.1599285007 + 0.3061661124 0.1633636951 0.1625496000 + 0.3106426001 0.1662496030 0.1651808023 + 0.3151304126 0.1691479981 0.1678352952 + 0.3196105063 0.1720582992 0.1704951972 + 0.3240850866 0.1749927998 0.1731574982 + 0.3285588920 0.1779374033 0.1758297980 + 0.3330225945 0.1808930039 0.1785068065 + 0.3374676108 0.1838704050 0.1811906993 + 0.3418787122 0.1868537068 0.1838902980 + 0.3462742865 0.1898439974 0.1865974069 + 0.3506546915 0.1928507984 0.1893136948 + 0.3550148010 0.1958658993 0.1920381039 + 0.3593491912 0.1988967061 0.1947682947 + 0.3636716902 0.2019404024 0.1975080073 + 0.3679802120 0.2049918026 0.2002497017 + 0.3722729981 0.2080595046 0.2029945999 + 0.3765603900 0.2111341059 0.2057335973 + 0.3808422089 0.2142200023 0.2084708959 + 0.3850818872 0.2173251063 0.2112185955 + 0.3893063068 0.2204380035 0.2139669061 + 0.3935188055 0.2235597968 0.2167157978 + 0.3977065980 0.2266864032 0.2194723934 + 0.4018787146 0.2298216969 0.2222321928 + 0.4060066938 0.2329684943 0.2249837965 + 0.4101200104 0.2361215949 0.2277349979 + 0.4142099917 0.2392960936 0.2304856032 + 0.4182651937 0.2424751967 0.2332389951 + 0.4223062098 0.2456675023 0.2359952033 + 0.4263221025 0.2488580942 0.2387603074 + 0.4303199053 0.2520464957 0.2415284067 + 0.4342919886 0.2552388906 0.2442979962 + 0.4382177889 0.2584339082 0.2470681965 + 0.4421251118 0.2616392970 0.2498411983 + 0.4459949136 0.2648470998 0.2526099086 + 0.4498532116 0.2680524886 0.2553699017 + 0.4536815882 0.2712588012 0.2581270933 + 0.4574846029 0.2744691968 0.2608813047 + 0.4612646103 0.2776809931 0.2636286914 + 0.4650110900 0.2808963060 0.2663717866 + 0.4687466919 0.2841087878 0.2691045105 + 0.4724290967 0.2873168886 0.2718333900 + 0.4761005938 0.2905252874 0.2745406926 + 0.4797236025 0.2937338948 0.2772436142 + 0.4833352864 0.2969321907 0.2799426019 + 0.4869242013 0.3001225889 0.2826412022 + 0.4905020893 0.3033182919 0.2853288949 + 0.4940682054 0.3065170944 0.2880161107 + 0.4975984991 0.3097181022 0.2906906009 + 0.5011065006 0.3129202127 0.2933647931 + 0.5045886040 0.3161264956 0.2960147858 + 0.5080611110 0.3193351030 0.2986648083 + 0.5115216970 0.3225524127 0.3013044894 + 0.5149798989 0.3257744014 0.3039439917 + 0.5184119940 0.3289855123 0.3065662980 + 0.5218411088 0.3321900964 0.3091877103 + 0.5252186060 0.3353936970 0.3117879033 + 0.5285930037 0.3385963142 0.3143858016 + 0.5319072008 0.3417963088 0.3169586957 + 0.5352197886 0.3449935913 0.3195259869 + 0.5384925008 0.3481869996 0.3220764101 + 0.5417643785 0.3513746858 0.3246203065 + 0.5449957848 0.3545599878 0.3271425962 + 0.5482258201 0.3577390015 0.3296504021 + 0.5514274836 0.3609147966 0.3321473897 + 0.5546270013 0.3640691936 0.3346312940 + 0.5577927828 0.3672235906 0.3371109962 + 0.5609536767 0.3703644872 0.3395805061 + 0.5640918016 0.3735049069 0.3420476019 + 0.5672239065 0.3766363859 0.3444921076 + 0.5703287125 0.3797653019 0.3469367027 + 0.5734214783 0.3828806877 0.3493632078 + 0.5764908195 0.3859854937 0.3517870903 + 0.5795422792 0.3890849948 0.3541991115 + 0.5825762749 0.3921729028 0.3566043973 + 0.5855858922 0.3952594101 0.3590024114 + 0.5885831118 0.3983199000 0.3613883853 + 0.5915424228 0.4013803899 0.3637714088 + 0.5944979191 0.4044235051 0.3661235869 + 0.5973832011 0.4074612856 0.3684759140 + 0.6002684832 0.4104872942 0.3708046079 + 0.6031265855 0.4134992957 0.3731263876 + 0.6059790850 0.4165073037 0.3754419982 + 0.6088135242 0.4194850922 0.3777495921 + 0.6116350889 0.4224627912 0.3800561130 + 0.6144289970 0.4254232049 0.3823485970 + 0.6171646714 0.4283778071 0.3846412003 + 0.6198990941 0.4313283861 0.3869284093 + 0.6225900054 0.4342721999 0.3892132044 + 0.6252809763 0.4372158945 0.3914948106 + 0.6279500127 0.4401437044 0.3937678039 + 0.6306102276 0.4430705905 0.3960408866 + 0.6332606077 0.4459845126 0.3983030021 + 0.6358942986 0.4488858879 0.4005627036 + 0.6385279298 0.4517867863 0.4028213918 + 0.6411197186 0.4546740949 0.4050782025 + 0.6437116265 0.4575614929 0.4073350132 + 0.6462585926 0.4604415894 0.4095784128 + 0.6487771869 0.4633156955 0.4118196964 + 0.6512870789 0.4661892056 0.4140588045 + 0.6537609100 0.4690420032 0.4162935913 + 0.6562346816 0.4718948007 0.4185284078 + 0.6586757898 0.4747399092 0.4207589924 + 0.6611058712 0.4775764942 0.4229885936 + 0.6635295749 0.4804131091 0.4252167940 + 0.6659365296 0.4832342863 0.4274396896 + 0.6683434248 0.4860537946 0.4296625853 + 0.6707113981 0.4888609052 0.4318814874 + 0.6730682254 0.4916389883 0.4340975881 + 0.6754177213 0.4944170117 0.4363138080 + 0.6777454019 0.4971829057 0.4385361969 + 0.6800730824 0.4999426007 0.4407587945 + 0.6823896766 0.5027021766 0.4429790080 + 0.6847013831 0.5054432154 0.4451938868 + 0.6870059967 0.5081841946 0.4474087059 + 0.6892570853 0.5109151006 0.4496183991 + 0.6915082932 0.5136244893 0.4518249035 + 0.6937376857 0.5163338184 0.4540314078 + 0.6959462762 0.5190213919 0.4562326968 + 0.6981548071 0.5216943026 0.4584333897 + 0.7003312111 0.5243672132 0.4606317878 + 0.7025029063 0.5270034075 0.4628174901 + 0.7046647072 0.5296329856 0.4650033116 + 0.7067890167 0.5322594047 0.4671837091 + 0.7089133263 0.5348445177 0.4693551958 + 0.7110230923 0.5374295712 0.4715267122 + 0.7131193280 0.5399996042 0.4736973047 + 0.7152153850 0.5425274968 0.4758673906 + 0.7172769904 0.5450553894 0.4780373871 + 0.7193294168 0.5475718975 0.4801994860 + 0.7213792801 0.5500730276 0.4823586047 + 0.7233660817 0.5525740981 0.4845176935 + 0.7253528237 0.5550534725 0.4866720140 + 0.7273290753 0.5575155020 0.4888255000 + 0.7292746902 0.5599774718 0.4909788966 + 0.7312203050 0.5624241233 0.4931291044 + 0.7331498861 0.5648627281 0.4952791035 + 0.7350592017 0.5673012733 0.4974288940 + 0.7369683981 0.5697147846 0.4995673001 + 0.7388588190 0.5721186996 0.5017058253 + 0.7407366037 0.5745226145 0.5038431287 + 0.7426143289 0.5768790841 0.5059599280 + 0.7444639802 0.5792204738 0.5080766082 + 0.7463030815 0.5815619826 0.5101922750 + 0.7481421232 0.5838884115 0.5122897029 + 0.7499330044 0.5862100720 0.5143870711 + 0.7517132163 0.5885317922 0.5164837837 + 0.7534933090 0.5908361077 0.5185531974 + 0.7552289963 0.5931339860 0.5206226110 + 0.7569586039 0.5954319835 0.5226920247 + 0.7586882710 0.5977076292 0.5247408152 + 0.7603802085 0.5999724269 0.5267890096 + 0.7620685101 0.6022372842 0.5288370848 + 0.7637568116 0.6044870019 0.5308629870 + 0.7654249072 0.6067258120 0.5328854918 + 0.7670909762 0.6089646220 0.5349079967 + 0.7687572241 0.6111888885 0.5369161963 + 0.7703763843 0.6133955717 0.5389193892 + 0.7719892263 0.6156023145 0.5409225225 + 0.7736020088 0.6177954078 0.5429117084 + 0.7751833797 0.6199551821 0.5448905230 + 0.7767575979 0.6221150160 0.5468692780 + 0.7783316970 0.6242699027 0.5488427281 + 0.7799007893 0.6263784170 0.5508071780 + 0.7814676762 0.6284868121 0.5527716875 + 0.7830346823 0.6305952072 0.5547339916 + 0.7845696211 0.6326767802 0.5566831827 + 0.7860810757 0.6347541213 0.5586323738 + 0.7875925899 0.6368314028 0.5605816245 + 0.7890849113 0.6388925910 0.5625146031 + 0.7905498147 0.6409428716 0.5644453764 + 0.7920145988 0.6429932117 0.5663762093 + 0.7934713960 0.6450356841 0.5682945848 + 0.7948976159 0.6470593810 0.5702040195 + 0.7963238955 0.6490830779 0.5721132755 + 0.7977501154 0.6511068940 0.5740166903 + 0.7991691232 0.6531022191 0.5759012103 + 0.8005877733 0.6550961733 0.5777856112 + 0.8020066023 0.6570903063 0.5796700716 + 0.8034045100 0.6590561271 0.5815389156 + 0.8047934771 0.6610018015 0.5834053159 + 0.8061826229 0.6629474759 0.5852717757 + 0.8075594902 0.6648828983 0.5871319771 + 0.8089175820 0.6667698026 0.5889847875 + 0.8102757931 0.6686565876 0.5908375978 + 0.8116320968 0.6705434918 0.5926902294 + 0.8129532933 0.6724057198 0.5945152044 + 0.8142744899 0.6742588282 0.5963401794 + 0.8155958056 0.6761118174 0.5981652141 + 0.8168948889 0.6779593229 0.5999823809 + 0.8181831241 0.6797894835 0.6017925739 + 0.8194714189 0.6816197038 0.6036027074 + 0.8207564950 0.6834499836 0.6054127812 + 0.8220325708 0.6852660775 0.6072114706 + 0.8233085871 0.6870769262 0.6090102196 + 0.8245846033 0.6888877153 0.6108089089 + 0.8258383870 0.6906918287 0.6126012802 + 0.8270868063 0.6924620271 0.6143857241 + 0.8283351064 0.6942321062 0.6161699891 + 0.8295804858 0.6960023046 0.6179543734 + 0.8308194280 0.6977444887 0.6197059155 + 0.8320583105 0.6994649768 0.6214510202 + 0.8332971931 0.7011855245 0.6231961846 + 0.8345112801 0.7029060125 0.6249343753 + 0.8357185721 0.7046008110 0.6266446710 + 0.8369258046 0.7062937021 0.6283550262 + 0.8381229043 0.7079864740 0.6300653219 + 0.8392837048 0.7096688151 0.6317604184 + 0.8404445052 0.7113192081 0.6334416270 + 0.8416053057 0.7129697204 0.6351227164 + 0.8427382708 0.7146201134 0.6368038058 + 0.8438537121 0.7162567973 0.6384651065 + 0.8449690938 0.7178813815 0.6401215792 + 0.8460845947 0.7195060253 0.6417779922 + 0.8471649885 0.7211306095 0.6434329748 + 0.8482443094 0.7227483988 0.6450561881 + 0.8493235707 0.7243642807 0.6466792822 + 0.8503887057 0.7259801030 0.6483023763 + 0.8514184952 0.7275959253 0.6499150991 + 0.8524482250 0.7291961908 0.6514953971 + 0.8534778953 0.7307960987 0.6530758142 + 0.8544930816 0.7323961258 0.6546561122 + 0.8554970026 0.7339910865 0.6562228203 + 0.8565009236 0.7355558872 0.6577693820 + 0.8575047851 0.7371206880 0.6593158841 + 0.8584917784 0.7386854887 0.6608623862 + 0.8594745994 0.7402415276 0.6623889208 + 0.8604573011 0.7417721748 0.6638967991 + 0.8614401221 0.7433028817 0.6654046774 + 0.8623782992 0.7448335886 0.6669126153 + 0.8633162975 0.7463521957 0.6683937907 + 0.8642541766 0.7478467226 0.6698569059 + 0.8651856780 0.7493410707 0.6713200212 + 0.8660802841 0.7508355975 0.6727830768 + 0.8669748902 0.7523164153 0.6742259264 + 0.8678696156 0.7537738085 0.6756564975 + 0.8687558770 0.7552313209 0.6770871878 + 0.8696188927 0.7566887140 0.6785178185 + 0.8704819083 0.7581344843 0.6799271703 + 0.8713449240 0.7595599294 0.6813234091 + 0.8722006083 0.7609851956 0.6827195883 + 0.8730415106 0.7624105215 0.6841157079 + 0.8738824725 0.7638270259 0.6854910851 + 0.8747234941 0.7652239203 0.6868504286 + 0.8755509257 0.7666208744 0.6882097721 + 0.8763540983 0.7680178285 0.6895691156 + 0.8771572709 0.7694097161 0.6909182072 + 0.8779605031 0.7707833052 0.6922556162 + 0.8787578940 0.7721568942 0.6935930252 + 0.8795443177 0.7735304832 0.6949303746 + 0.8803306818 0.7749016285 0.6962568164 + 0.8811172247 0.7762401104 0.6975601912 + 0.8818970919 0.7775787115 0.6988636851 + 0.8826605082 0.7789173126 0.7001671195 + 0.8834239841 0.7802559137 0.7014654875 + 0.8841875196 0.7815645933 0.7027323842 + 0.8849436045 0.7828695774 0.7039992213 + 0.8856664896 0.7841745019 0.7052659988 + 0.8863893151 0.7854794860 0.7065327764 + 0.8871122003 0.7867677808 0.7077702880 + 0.8878350854 0.7880474925 0.7090048194 + 0.8885604143 0.7893270850 0.7102392912 + 0.8892856836 0.7906067967 0.7114737034 + 0.8900108933 0.7918794155 0.7126892805 + 0.8907362223 0.7931404114 0.7138935924 + 0.8914461732 0.7944014072 0.7150977850 + 0.8921533227 0.7956624031 0.7163020968 + 0.8928604126 0.7969211936 0.7174999714 + 0.8935676217 0.7981446981 0.7186828256 + 0.8942708969 0.7993682027 0.7198656797 + 0.8949717283 0.8005917072 0.7210485935 + 0.8956726193 0.8018152118 0.7222315073 + 0.8963733912 0.8030143976 0.7233734727 + 0.8970720768 0.8042024970 0.7245125771 + 0.8977661729 0.8053905964 0.7256516814 + 0.8984603286 0.8065786958 0.7267907262 + 0.8991544247 0.8077601790 0.7279145122 + 0.8998485208 0.8089237809 0.7290235758 + 0.9005149007 0.8100873828 0.7301326990 + 0.9011809230 0.8112509847 0.7312418222 + 0.9018470049 0.8124147058 0.7323492169 + 0.9025130272 0.8135333061 0.7334213853 + 0.9031683207 0.8146411777 0.7344936728 + 0.9038167000 0.8157489896 0.7355659008 + 0.9044650793 0.8168568015 0.7366381288 + 0.9051135182 0.8179541826 0.7376983166 + 0.9057582021 0.8190261722 0.7387477160 + 0.9063869119 0.8200982213 0.7397971153 + 0.9070156217 0.8211702108 0.7408465743 + 0.9076442122 0.8222423196 0.7418959737 + 0.9082729220 0.8232967854 0.7429301143 + 0.9088765979 0.8243448734 0.7439635992 + 0.9094702005 0.8253930211 0.7449972034 + 0.9100638032 0.8264411092 0.7460306883 + 0.9106575251 0.8274878860 0.7470514178 + 0.9112505913 0.8285259008 0.7480484843 + 0.9118415713 0.8295637965 0.7490454912 + 0.9124326706 0.8306018114 0.7500426173 + 0.9130237103 0.8316397071 0.7510396242 + 0.9136146903 0.8326591849 0.7520161271 + 0.9142035246 0.8336567283 0.7529833913 + 0.9147909284 0.8346542120 0.7539507151 + 0.9153783917 0.8356516957 0.7549179792 + 0.9159657955 0.8366491795 0.7558851838 + 0.9165533185 0.8376235962 0.7568265200 + 0.9171171784 0.8385900259 0.7577672005 + 0.9176810980 0.8395562768 0.7587078214 + 0.9182450771 0.8405227065 0.7596483827 + 0.9188089967 0.8414890766 0.7605820894 + 0.9193634987 0.8424319029 0.7614898086 + 0.9198989272 0.8433743119 0.7623975277 + 0.9204342961 0.8443166018 0.7633051276 + 0.9209697843 0.8452588916 0.7642127872 + 0.9215052128 0.8461968899 0.7651119828 + 0.9220255017 0.8471127748 0.7659983039 + 0.9225360751 0.8480286002 0.7668846250 + 0.9230468273 0.8489444852 0.7677708864 + 0.9235574007 0.8498603106 0.7686572075 + 0.9240680933 0.8507688046 0.7695332766 + 0.9245592952 0.8516598940 0.7703999877 + 0.9250469208 0.8525511026 0.7712668180 + 0.9255344272 0.8534421921 0.7721335888 + 0.9260219932 0.8543332815 0.7730002999 + 0.9265089035 0.8552088737 0.7738537788 + 0.9269595146 0.8560588956 0.7746983767 + 0.9274101257 0.8569089174 0.7755429745 + 0.9278606176 0.8577588797 0.7763875723 + 0.9283112288 0.8586089015 0.7772322297 + 0.9287610054 0.8594486117 0.7780702710 + 0.9292058945 0.8602731228 0.7789046168 + 0.9296509027 0.8610975742 0.7797389030 + 0.9300957918 0.8619220853 0.7805731893 + 0.9305406809 0.8627465963 0.7814074755 + 0.9309821129 0.8635640740 0.7822362781 + 0.9314101934 0.8643702269 0.7830613256 + 0.9318383932 0.8651763201 0.7838863730 + 0.9322664738 0.8659824133 0.7847114205 + 0.9326946139 0.8667885065 0.7855364084 + 0.9331154227 0.8675866127 0.7863515019 + 0.9335113764 0.8683658838 0.7871572971 + 0.9339073896 0.8691452146 0.7879629731 + 0.9343034029 0.8699244857 0.7887688279 + 0.9346994758 0.8707038164 0.7895745039 + 0.9350925088 0.8714814186 0.7903773189 + 0.9354733229 0.8722500205 0.7911751866 + 0.9358540773 0.8730186224 0.7919729948 + 0.9362348914 0.8737872243 0.7927709222 + 0.9366155863 0.8745558262 0.7935687900 + 0.9369941950 0.8753244281 0.7943630815 + 0.9373536110 0.8760707974 0.7951408029 + 0.9377130270 0.8768165112 0.7959185839 + 0.9380723834 0.8775621057 0.7966964245 + 0.9384316802 0.8783078194 0.7974742055 + 0.9387910962 0.8790534139 0.7982519865 + 0.9391242266 0.8797795773 0.7990127802 + 0.9394561052 0.8804981112 0.7997723222 + 0.9397879839 0.8812165260 0.8005318046 + 0.9401199222 0.8819350004 0.8012912869 + 0.9404518008 0.8826534748 0.8020508289 + 0.9407855868 0.8833674192 0.8027989864 + 0.9411200881 0.8840746284 0.8035404086 + 0.9414545298 0.8847818971 0.8042817116 + 0.9417889714 0.8854891062 0.8050230145 + 0.9421234727 0.8861963749 0.8057643771 + 0.9424526095 0.8869026899 0.8065025806 + 0.9427763224 0.8875902891 0.8072319031 + 0.9430999160 0.8882780075 0.8079612255 + 0.9434236288 0.8889656067 0.8086904883 + 0.9437472224 0.8896532059 0.8094198108 + 0.9440696836 0.8903409243 0.8101490736 + 0.9443870783 0.8910048008 0.8108692765 + 0.9447045922 0.8916543722 0.8115875721 + 0.9450219870 0.8923041224 0.8123059273 + 0.9453393817 0.8929538131 0.8130242229 + 0.9456567764 0.8936033845 0.8137425184 + 0.9459626079 0.8942502141 0.8144533038 + 0.9462655187 0.8948795795 0.8151500821 + 0.9465684891 0.8955091238 0.8158469200 + 0.9468713999 0.8961384892 0.8165438175 + 0.9471743703 0.8967679739 0.8172405958 + 0.9474688172 0.8973973989 0.8179373741 + 0.9477491975 0.8980208039 0.8186287880 + 0.9480295777 0.8986400962 0.8193188906 + 0.9483100176 0.8992593884 0.8200089931 + 0.9485903978 0.8998786807 0.8206989765 + 0.9488707781 0.9004979730 0.8213890791 + 0.9491494298 0.9011172056 0.8220766783 + 0.9494279027 0.9017202854 0.8227545023 + 0.9497063160 0.9023234844 0.8234323859 + 0.9499847889 0.9029266238 0.8241102099 + 0.9502632022 0.9035297036 0.8247880936 + 0.9505476952 0.9041329026 0.8254659176 + 0.9508438706 0.9047262073 0.8261309862 + 0.9511401057 0.9053006768 0.8267852068 + 0.9514362812 0.9058750868 0.8274394274 + 0.9517325163 0.9064496160 0.8280935884 + 0.9520286918 0.9070240855 0.8287478089 + 0.9523310065 0.9075986147 0.8294020295 + 0.9526355267 0.9081652761 0.8300411105 + 0.9529399872 0.9087274075 0.8306767941 + 0.9532445073 0.9092894197 0.8313124776 + 0.9535490274 0.9098513722 0.8319482803 + 0.9538534284 0.9104133844 0.8325840235 + 0.9541549087 0.9109753966 0.8332191706 + 0.9544565082 0.9115229845 0.8338392973 + 0.9547581077 0.9120678902 0.8344593048 + 0.9550595880 0.9126127958 0.8350793123 + 0.9553611875 0.9131575823 0.8356993794 + 0.9556581974 0.9137024879 0.8363193870 + 0.9559459090 0.9142473936 0.8369358778 + 0.9562335014 0.9147704840 0.8375366926 + 0.9565210938 0.9152935147 0.8381375074 + 0.9568086863 0.9158164859 0.8387383223 + 0.9570962787 0.9163393974 0.8393390775 + 0.9573791027 0.9168624282 0.8399398923 + 0.9576573968 0.9173836112 0.8405390978 + 0.9579358101 0.9178845882 0.8411338925 + 0.9582142234 0.9183856249 0.8417286873 + 0.9584925771 0.9188866019 0.8423236012 + 0.9587709904 0.9193875790 0.8429183960 + 0.9590389132 0.9198886156 0.8435133100 + 0.9593018293 0.9203869104 0.8441042900 + 0.9595646262 0.9208633900 0.8446862102 + 0.9598274827 0.9213399291 0.8452680111 + 0.9600902796 0.9218164086 0.8458498716 + 0.9603531957 0.9222928882 0.8464317918 + 0.9606087208 0.9227694273 0.8470137119 + 0.9608618021 0.9232439995 0.8475909233 + 0.9611148834 0.9236922264 0.8481546044 + 0.9613680243 0.9241403937 0.8487182856 + 0.9616211057 0.9245886207 0.8492819071 + 0.9618741870 0.9250367880 0.8498455882 + 0.9621182084 0.9254850149 0.8504093289 + 0.9623593092 0.9259333014 0.8509712815 + 0.9626005292 0.9263677001 0.8515232801 + 0.9628416896 0.9268016815 0.8520752788 + 0.9630827904 0.9272356033 0.8526272774 + 0.9633240104 0.9276695848 0.8531792760 + 0.9635608792 0.9281035066 0.8537312746 + 0.9637960792 0.9285374880 0.8542832732 + 0.9640312791 0.9289491773 0.8548194766 + 0.9642664790 0.9293550849 0.8553553224 + 0.9645017982 0.9297609925 0.8558911085 + 0.9647369981 0.9301669002 0.8564267755 + 0.9649640918 0.9305728078 0.8569626212 + 0.9651858807 0.9309787154 0.8574984074 + 0.9654077888 0.9313749075 0.8580273986 + 0.9656295776 0.9317634106 0.8585538864 + 0.9658514261 0.9321519136 0.8590804935 + 0.9660732150 0.9325404763 0.8596069813 + 0.9662867188 0.9329289794 0.8601335287 + 0.9664887190 0.9333174825 0.8606600761 + 0.9666907787 0.9337003827 0.8611857295 + 0.9668927789 0.9340664744 0.8617103100 + 0.9670948982 0.9344326258 0.8622347713 + 0.9672968984 0.9347985983 0.8627592921 + 0.9674957991 0.9351646900 0.8632838130 + 0.9676799178 0.9355307817 0.8638082743 + 0.9678639174 0.9358968735 0.8643323183 + 0.9680479169 0.9362515807 0.8648458719 + 0.9682319164 0.9366047978 0.8653594851 + 0.9684159756 0.9369578958 0.8658730984 + 0.9685999751 0.9373109937 0.8663867116 + 0.9687842727 0.9376642108 0.8669003248 + 0.9689685702 0.9380173087 0.8674138784 + 0.9691529274 0.9383693933 0.8679202795 + 0.9693372250 0.9387202263 0.8684219718 + 0.9695215225 0.9390708804 0.8689237833 + 0.9697058201 0.9394217134 0.8694254756 + 0.9698892236 0.9397724271 0.8699272275 + 0.9700716734 0.9401232004 0.8704289794 + 0.9702541232 0.9404739141 0.8709301949 + 0.9704365134 0.9408150911 0.8714262247 + 0.9706190228 0.9411553741 0.8719220757 + 0.9708014131 0.9414957166 0.8724181056 + 0.9709836841 0.9418359995 0.8729140759 + 0.9711577892 0.9421764016 0.8734099865 + 0.9713318944 0.9425166845 0.8739060163 + 0.9715059996 0.9428496957 0.8744006157 + 0.9716801047 0.9431682229 0.8748937249 + 0.9718542099 0.9434866905 0.8753868937 + 0.9720283747 0.9438052177 0.8758801222 + 0.9721953273 0.9441236854 0.8763732910 + 0.9723548889 0.9444422722 0.8768664002 + 0.9725145102 0.9447607994 0.8773596287 + 0.9726741910 0.9450662732 0.8778408170 + 0.9728338122 0.9453657866 0.8783197999 + 0.9729933739 0.9456652999 0.8787987828 + 0.9731529951 0.9459646940 0.8792778254 + 0.9732946754 0.9462642074 0.8797568083 + 0.9734343886 0.9465637207 0.8802356720 + 0.9735741019 0.9468631744 0.8807138205 + 0.9737136960 0.9471693039 0.8811848164 + 0.9738534093 0.9474757910 0.8816556931 + 0.9739931226 0.9477822781 0.8821266890 + 0.9741299152 0.9480888247 0.8825976849 + 0.9742575288 0.9483953118 0.8830686212 + 0.9743850827 0.9487017989 0.8835396171 + 0.9745125771 0.9490079880 0.8840103149 + 0.9746401906 0.9493122101 0.8844805956 + 0.9747678041 0.9496163726 0.8849508166 + 0.9748952985 0.9499207139 0.8854210973 + 0.9750214219 0.9502248764 0.8858913183 + 0.9751458764 0.9505292177 0.8863615990 + 0.9752703905 0.9508333802 0.8868318200 + 0.9753949046 0.9511339068 0.8872954845 + 0.9755194783 0.9514247775 0.8877508044 + 0.9756439924 0.9517157078 0.8882061243 + 0.9757685065 0.9520065784 0.8886613846 + 0.9758896232 0.9522975087 0.8891167045 + 0.9760090113 0.9525884986 0.8895720243 + 0.9761283994 0.9528794289 0.8900272846 + 0.9762479067 0.9531695247 0.8904743195 + 0.9763672948 0.9534580112 0.8909124732 + 0.9764866829 0.9537466168 0.8913506866 + 0.9766061902 0.9540351033 0.8917888999 + 0.9767202735 0.9543237090 0.8922271132 + 0.9768331051 0.9546121955 0.8926653266 + 0.9769458771 0.9549006820 0.8931034803 + 0.9770585895 0.9551869035 0.8935418129 + 0.9771714211 0.9554678202 0.8939803243 + 0.9772841930 0.9557486773 0.8944187760 + 0.9773970246 0.9560295939 0.8948572874 + 0.9775123000 0.9563105106 0.8952959180 + 0.9776281118 0.9565914273 0.8957344294 + 0.9777439237 0.9568722844 0.8961728811 + 0.9778596759 0.9571502805 0.8966065049 + 0.9779754877 0.9574174285 0.8970314264 + 0.9780912995 0.9576845169 0.8974562883 + 0.9782071114 0.9579516053 0.8978813291 + 0.9783318043 0.9582186937 0.8983061910 + 0.9784587026 0.9584857821 0.8987311125 + 0.9785856009 0.9587529898 0.8991559744 + 0.9787124991 0.9590197206 0.8995798230 + 0.9788395166 0.9592756033 0.8999984860 + 0.9789664149 0.9595314860 0.9004172087 + 0.9790933132 0.9597874284 0.9008359909 + 0.9792243838 0.9600433111 0.9012547135 + 0.9793574214 0.9602991939 0.9016733766 + 0.9794905186 0.9605550766 0.9020922184 + 0.9796234965 0.9608110189 0.9025108814 + 0.9797564745 0.9610598087 0.9029234052 + 0.9798895717 0.9613065720 0.9033355117 + 0.9800226092 0.9615533948 0.9037474990 + 0.9801558256 0.9618002176 0.9041596055 + 0.9802892208 0.9620471001 0.9045715928 + 0.9804226160 0.9622939229 0.9049835801 + 0.9805560112 0.9625406861 0.9053956866 + 0.9806892872 0.9627807736 0.9057967067 + 0.9808226824 0.9630126953 0.9061899185 + 0.9809560776 0.9632446766 0.9065830708 + 0.9810881019 0.9634765983 0.9069762826 + 0.9812154174 0.9637085199 0.9073694944 + 0.9813426733 0.9639403820 0.9077627063 + 0.9814701080 0.9641724229 0.9081559181 + 0.9815974236 0.9644042850 0.9085468054 + 0.9817246795 0.9646360278 0.9089267254 + 0.9818521142 0.9648677111 0.9093065262 + 0.9819794297 0.9650995135 0.9096863866 + 0.9821053743 0.9653311968 0.9100661874 + 0.9822311997 0.9655628800 0.9104459882 + 0.9823570251 0.9657946825 0.9108259082 + 0.9824826717 0.9660264254 0.9112057090 + 0.9826084971 0.9662542939 0.9115757942 + 0.9827343225 0.9664790034 0.9119412899 + 0.9828600883 0.9667037129 0.9123067856 + 0.9829840064 0.9669284225 0.9126722217 + 0.9831055999 0.9671530724 0.9130377173 + 0.9832271934 0.9673777819 0.9134030938 + 0.9833487868 0.9676026106 0.9137685895 + 0.9834703803 0.9678273201 0.9141318202 + 0.9835919738 0.9680370092 0.9144750237 + 0.9837136269 0.9682462811 0.9148182273 + 0.9838352203 0.9684554935 0.9151614904 + 0.9839490056 0.9686648250 0.9155046940 + 0.9840624928 0.9688740969 0.9158478975 + 0.9841759801 0.9690833092 0.9161911011 + 0.9842895269 0.9692925811 0.9165343046 + 0.9844030142 0.9694945812 0.9168791175 + 0.9845163822 0.9696804285 0.9172258973 + 0.9846299291 0.9698662758 0.9175727963 + 0.9847432971 0.9700521231 0.9179195762 + 0.9848564267 0.9702379704 0.9182664156 + 0.9849694967 0.9704238176 0.9186133146 + 0.9850826859 0.9706097245 0.9189600945 + 0.9851958156 0.9707955718 0.9193068743 + 0.9853088856 0.9709764719 0.9196500182 + 0.9854220748 0.9711537957 0.9199913740 + 0.9855352044 0.9713311195 0.9203327894 + 0.9856474996 0.9715083838 0.9206743240 + 0.9857596159 0.9716858268 0.9210156798 + 0.9858716130 0.9718630910 0.9213570952 + 0.9859836102 0.9720404148 0.9216985703 + 0.9860956073 0.9722176790 0.9220399857 + 0.9862076044 0.9723867774 0.9223676920 + 0.9863196015 0.9725531936 0.9226933122 + 0.9864315987 0.9727196097 0.9230188727 + 0.9865403175 0.9728860259 0.9233446121 + 0.9866489172 0.9730523825 0.9236701727 + 0.9867573977 0.9732187986 0.9239959121 + 0.9868658781 0.9733852148 0.9243214726 + 0.9869744182 0.9735515714 0.9246470928 + 0.9870830178 0.9737042189 0.9249747992 + 0.9871914983 0.9738543034 0.9253026247 + 0.9872993231 0.9740043283 0.9256303906 + 0.9874020219 0.9741542935 0.9259580970 + 0.9875046015 0.9743043184 0.9262859225 + 0.9876071811 0.9744542837 0.9266136885 + 0.9877098203 0.9746043086 0.9269413948 + 0.9878123999 0.9747542739 0.9272692204 + 0.9879150987 0.9748876095 0.9276003242 + 0.9880176783 0.9750179052 0.9279316068 + 0.9881187081 0.9751480818 0.9282628298 + 0.9882128835 0.9752783775 0.9285941124 + 0.9883071184 0.9754086733 0.9289252758 + 0.9884012938 0.9755390286 0.9292566180 + 0.9884955287 0.9756692052 0.9295879006 + 0.9885897040 0.9757995009 0.9299191236 + 0.9886838794 0.9759184122 0.9302431941 + 0.9887781143 0.9760339260 0.9305663109 + 0.9888703227 0.9761493802 0.9308894873 + 0.9889534116 0.9762648940 0.9312126040 + 0.9890366197 0.9763804078 0.9315357208 + 0.9891197085 0.9764959216 0.9318587780 + 0.9892027974 0.9766113758 0.9321818948 + 0.9892858863 0.9767268896 0.9325050116 + 0.9893689752 0.9768431187 0.9328215718 + 0.9894521236 0.9769597054 0.9331353903 + 0.9895340800 0.9770764112 0.9334493279 + 0.9896032810 0.9771929979 0.9337630868 + 0.9896724820 0.9773095846 0.9340769053 + 0.9897418022 0.9774262905 0.9343907833 + 0.9898110032 0.9775428772 0.9347046018 + 0.9898802042 0.9776595235 0.9350184798 + 0.9899495244 0.9777796865 0.9353330135 + 0.9900187254 0.9779065847 0.9356483817 + 0.9900879264 0.9780334830 0.9359638095 + 0.9901421070 0.9781603813 0.9362791181 + 0.9901946187 0.9782872796 0.9365944862 + 0.9902470708 0.9784141779 0.9369099140 + 0.9902997017 0.9785410762 0.9372252822 + 0.9903522134 0.9786679745 0.9375407100 + 0.9904047847 0.9787948132 0.9378561974 + 0.9904572964 0.9789273143 0.9381728768 + 0.9905098081 0.9790598154 0.9384894967 + 0.9905501008 0.9791921973 0.9388061762 + 0.9905833006 0.9793246984 0.9391229153 + 0.9906166196 0.9794571996 0.9394394755 + 0.9906498194 0.9795895815 0.9397562146 + 0.9906830192 0.9797220826 0.9400727749 + 0.9907162189 0.9798545837 0.9403895140 + 0.9907494187 0.9799873829 0.9406992793 + 0.9907826185 0.9801204205 0.9410055280 + 0.9908105135 0.9802533984 0.9413117170 + 0.9908241034 0.9803863764 0.9416180253 + 0.9908378124 0.9805194139 0.9419242144 + 0.9908514023 0.9806525111 0.9422304034 + 0.9908649921 0.9807854891 0.9425367117 + 0.9908785820 0.9809185266 0.9428429008 + 0.9908922911 0.9810513854 0.9431486726 + 0.9909058809 0.9811798930 0.9434512854 + 0.9909194708 0.9813084006 0.9437538981 + 0.9909344912 0.9814370275 0.9440565705 + 0.9909498096 0.9815654755 0.9443591833 + 0.9909651279 0.9816941023 0.9446619153 + 0.9909805059 0.9818226099 0.9449645281 + 0.9909958243 0.9819511771 0.9452670813 + 0.9910110831 0.9820796847 0.9455698133 + 0.9910264015 0.9822043180 0.9458690882 + 0.9910417199 0.9823232293 0.9461650848 + 0.9910593033 0.9824422002 0.9464610219 + 0.9910830855 0.9825611711 0.9467570186 + 0.9911068082 0.9826800823 0.9470530152 + 0.9911304712 0.9827991128 0.9473490119 + 0.9911543131 0.9829180241 0.9476450086 + 0.9911779761 0.9830369949 0.9479410052 + 0.9912016988 0.9831560254 0.9482370019 + 0.9912254214 0.9832714796 0.9485340714 + 0.9912492037 0.9833855033 0.9488316178 + 0.9912775159 0.9834995270 0.9491291046 + 0.9913085103 0.9836134911 0.9494264722 + 0.9913393855 0.9837275147 0.9497240186 + 0.9913703799 0.9838414788 0.9500213861 + 0.9914013147 0.9839556217 0.9503188729 + 0.9914323092 0.9840695858 0.9506164193 + 0.9914631844 0.9841836095 0.9509137869 + 0.9914941788 0.9842914939 0.9512110949 + 0.9915251136 0.9843987226 0.9515084028 + 0.9915609956 0.9845058918 0.9518057108 + 0.9915972948 0.9846131206 0.9521030188 + 0.9916337132 0.9847202897 0.9524002075 + 0.9916700125 0.9848275185 0.9526975155 + 0.9917063117 0.9849346876 0.9529948235 + 0.9917426705 0.9850419164 0.9532920718 + 0.9917790294 0.9851490855 0.9535887241 + 0.9918153286 0.9852461815 0.9538760185 + 0.9918519855 0.9853430986 0.9541633129 + 0.9918923974 0.9854400158 0.9544506073 + 0.9919328094 0.9855368733 0.9547379017 + 0.9919732213 0.9856337905 0.9550251961 + 0.9920135736 0.9857307076 0.9553123713 + 0.9920539856 0.9858275056 0.9555997252 + 0.9920943975 0.9859244227 0.9558870196 + 0.9921348095 0.9860212803 0.9561737180 + 0.9921752214 0.9861149192 0.9564520121 + 0.9922161102 0.9862084985 0.9567303061 + 0.9922596216 0.9863020778 0.9570086002 + 0.9923030138 0.9863955975 0.9572867751 + 0.9923465252 0.9864891768 0.9575651288 + 0.9923899770 0.9865828156 0.9578434229 + 0.9924334884 0.9866762757 0.9581217170 + 0.9924769998 0.9867699146 0.9583998919 + 0.9925205112 0.9868633747 0.9586781859 + 0.9925640225 0.9869536757 0.9589493871 + 0.9926077724 0.9870436192 0.9592202902 + 0.9926536083 0.9871335030 0.9594913125 + 0.9926993251 0.9872233868 0.9597622156 + 0.9927451015 0.9873132706 0.9600331187 + 0.9927908778 0.9874032140 0.9603040218 + 0.9928365946 0.9874930978 0.9605749249 + 0.9928823709 0.9875829816 0.9608458877 + 0.9929282069 0.9876729250 0.9611167908 + 0.9929739237 0.9877598286 0.9613807201 + 0.9930197001 0.9878454208 0.9616423249 + 0.9930669069 0.9879310131 0.9619039893 + 0.9931141138 0.9880164862 0.9621657133 + 0.9931613207 0.9881020784 0.9624273777 + 0.9932085276 0.9881876707 0.9626889825 + 0.9932556748 0.9882733226 0.9629507065 + 0.9933028221 0.9883589149 0.9632123709 + 0.9933500290 0.9884445071 0.9634739757 + 0.9933971763 0.9885308146 0.9637349844 + 0.9934443831 0.9886181951 0.9639952183 + 0.9934918880 0.9887055755 0.9642552733 + 0.9935395122 0.9887928963 0.9645155072 + 0.9935870767 0.9888802767 0.9647756219 + 0.9936347008 0.9889677167 0.9650356770 + 0.9936823249 0.9890550971 0.9652959108 + 0.9937298894 0.9891424775 0.9655560255 + 0.9937775135 0.9892299175 0.9658161998 + 0.9938250780 0.9893172979 0.9660758972 + 0.9938727021 0.9894027710 0.9663285017 + 0.9939200282 0.9894883037 0.9665812254 + 0.9939668179 0.9895737767 0.9668337703 + 0.9940136075 0.9896594286 0.9670864940 + 0.9940603971 0.9897449017 0.9673390985 + 0.9941071868 0.9898303747 0.9675918221 + 0.9941540956 0.9899159074 0.9678444266 + 0.9942008853 0.9900014997 0.9680969715 + 0.9942476749 0.9900869727 0.9683496952 + 0.9942945242 0.9901695848 0.9685934186 + 0.9943410754 0.9902492166 0.9688298702 + 0.9943857789 0.9903287888 0.9690665007 + 0.9944304228 0.9904084206 0.9693030119 + 0.9944751263 0.9904879928 0.9695395827 + 0.9945198298 0.9905676246 0.9697762132 + 0.9945644140 0.9906471968 0.9700127244 + 0.9946091175 0.9907268286 0.9702492952 + 0.9946537018 0.9908064008 0.9704858065 + 0.9946984053 0.9908859730 0.9707223773 + 0.9947431087 0.9909566045 0.9709470272 + 0.9947856069 0.9910261035 0.9711709023 + 0.9948266745 0.9910956025 0.9713948965 + 0.9948678017 0.9911652207 0.9716188908 + 0.9949088097 0.9912347198 0.9718428254 + 0.9949498773 0.9913042188 0.9720668197 + 0.9949908853 0.9913737774 0.9722908139 + 0.9950320125 0.9914432764 0.9725146890 + 0.9950730801 0.9915127754 0.9727386832 + 0.9951140881 0.9915797710 0.9729639292 + 0.9951552153 0.9916355014 0.9731928706 + 0.9951915145 0.9916911721 0.9734219909 + 0.9952275753 0.9917469025 0.9736511111 + 0.9952636957 0.9918025732 0.9738801122 + 0.9952998161 0.9918583035 0.9741091728 + 0.9953358769 0.9919139743 0.9743381739 + 0.9953719974 0.9919697046 0.9745672941 + 0.9954081178 0.9920253754 0.9747962952 + 0.9954441786 0.9920811057 0.9750254154 + 0.9954802990 0.9921348095 0.9752535820 + 0.9955152273 0.9921852946 0.9754807949 + 0.9955464005 0.9922357798 0.9757078886 + 0.9955775142 0.9922863245 0.9759351015 + 0.9956086874 0.9923368096 0.9761621952 + 0.9956398010 0.9923872948 0.9763892889 + 0.9956709743 0.9924377799 0.9766165018 + 0.9957020879 0.9924883246 0.9768435955 + 0.9957333207 0.9925388098 0.9770708084 + 0.9957643747 0.9925892949 0.9772979021 + 0.9957956076 0.9926403165 0.9775205851 + 0.9958270788 0.9926918149 0.9777389169 + 0.9958592057 0.9927433729 0.9779571891 + 0.9958912134 0.9927948713 0.9781755209 + 0.9959232807 0.9928464293 0.9783937931 + 0.9959554076 0.9928979874 0.9786121249 + 0.9959874749 0.9929494858 0.9788303971 + 0.9960194826 0.9930011034 0.9790487289 + 0.9960516095 0.9930526018 0.9792670012 + 0.9960836768 0.9931041002 0.9794852138 + 0.9961156845 0.9931588173 0.9797025919 + 0.9961478114 0.9932174087 0.9799190164 + 0.9961798787 0.9932761192 0.9801353216 + 0.9962120056 0.9933347702 0.9803516269 + 0.9962440133 0.9933934808 0.9805679917 + 0.9962760806 0.9934520721 0.9807842970 + 0.9963082075 0.9935107827 0.9810007215 + 0.9963402152 0.9935694933 0.9812170267 + 0.9963722825 0.9936280847 0.9814332724 + 0.9964044094 0.9936867952 0.9816496968 + 0.9964364767 0.9937475920 0.9818658829 + 0.9964681864 0.9938132763 0.9820817709 + 0.9964997172 0.9938790202 0.9822977781 + 0.9965311289 0.9939447045 0.9825137258 + 0.9965624809 0.9940103889 0.9827296734 + 0.9965938926 0.9940760732 0.9829456210 + 0.9966253042 0.9941418171 0.9831615090 + 0.9966567159 0.9942075014 0.9833775163 + 0.9966881275 0.9942731857 0.9835934043 + 0.9967194796 0.9943389297 0.9838094115 + 0.9967508912 0.9944049120 0.9840244055 + 0.9967818856 0.9944759011 0.9842302203 + 0.9968118072 0.9945470095 0.9844359159 + 0.9968416095 0.9946179986 0.9846416712 + 0.9968714714 0.9946889877 0.9848474860 + 0.9969013929 0.9947599769 0.9850531816 + 0.9969311953 0.9948310256 0.9852589965 + 0.9969611168 0.9949020743 0.9854648113 + 0.9969909787 0.9949731231 0.9856705070 + 0.9970209002 0.9950441122 0.9858763218 + 0.9970507026 0.9951151013 0.9860820174 + 0.9970806837 0.9951882958 0.9862825871 + 0.9971145988 0.9952625036 0.9864811897 + 0.9971485138 0.9953365922 0.9866797924 + 0.9971824288 0.9954108000 0.9868783951 + 0.9972162843 0.9954848886 0.9870769978 + 0.9972501993 0.9955590963 0.9872756004 + 0.9972841144 0.9956331849 0.9874743223 + 0.9973180294 0.9957073927 0.9876729250 + 0.9973520041 0.9957814813 0.9878715277 + 0.9973859191 0.9958556890 0.9880700707 + 0.9974197745 0.9959298968 0.9882662892 + 0.9974561930 0.9960047007 0.9884554744 + 0.9974939227 0.9960793853 0.9886447787 + 0.9975317121 0.9961541295 0.9888340235 + 0.9975695014 0.9962288737 0.9890233278 + 0.9976071715 0.9963036180 0.9892125130 + 0.9976450205 0.9963783026 0.9894018173 + 0.9976828098 0.9964529872 0.9895910025 + 0.9977204800 0.9965277910 0.9897803068 + 0.9977583289 0.9966024756 0.9899694920 + 0.9977961183 0.9966772199 0.9901587963 + 0.9978342056 0.9967505932 0.9903476834 + 0.9978744984 0.9968233109 0.9905365109 + 0.9979146719 0.9968960285 0.9907252789 + 0.9979549050 0.9969686866 0.9909141064 + 0.9979951978 0.9970412850 0.9911028147 + 0.9980353713 0.9971140027 0.9912915826 + 0.9980756044 0.9971867204 0.9914804101 + 0.9981158972 0.9972593784 0.9916691780 + 0.9981560707 0.9973320961 0.9918578863 + 0.9981964231 0.9974046946 0.9920467138 + 0.9982365966 0.9974774122 0.9922354817 + 0.9982774258 0.9975458980 0.9924197197 + 0.9983186722 0.9976140857 0.9926037192 + 0.9983600974 0.9976822734 0.9927877188 + 0.9984014034 0.9977505207 0.9929717779 + 0.9984427094 0.9978188276 0.9931557775 + 0.9984840155 0.9978870153 0.9933397770 + 0.9985253215 0.9979552031 0.9935238957 + 0.9985666275 0.9980235100 0.9937078953 + 0.9986079931 0.9980916977 0.9938918948 + 0.9986492991 0.9981598854 0.9940760136 + 0.9986906052 0.9982272983 0.9942585826 + 0.9987317920 0.9982891083 0.9944334030 + 0.9987729192 0.9983509779 0.9946082234 + 0.9988141060 0.9984129071 0.9947831035 + 0.9988551736 0.9984747171 0.9949579239 + 0.9988964200 0.9985365868 0.9951328039 + 0.9989374876 0.9985983968 0.9953076243 + 0.9989786148 0.9986603260 0.9954825044 + 0.9990198016 0.9987221956 0.9956573248 + 0.9990609288 0.9987840056 0.9958320856 + 0.9991021156 0.9988458753 0.9960070252 + 0.9991431832 0.9989060760 0.9961810708 + 0.9991831779 0.9989601970 0.9963524938 + 0.9992231131 0.9990143776 0.9965239167 + 0.9992631078 0.9990684986 0.9966952801 + 0.9993029833 0.9991226196 0.9968667030 + 0.9993429780 0.9991768003 0.9970381856 + 0.9993829131 0.9992309213 0.9972096086 + 0.9994229078 0.9992849827 0.9973809719 + 0.9994627833 0.9993392229 0.9975523949 + 0.9995027781 0.9993932843 0.9977238178 + 0.9995427132 0.9994474053 0.9978951812 + 0.9995825291 0.9995000958 0.9980673790 + 0.9996204972 0.9995455146 0.9982430935 + 0.9996584058 0.9995909929 0.9984188080 + 0.9996963739 0.9996364117 0.9985945225 + 0.9997342825 0.9996818900 0.9987701774 + 0.9997723103 0.9997273088 0.9989458919 + 0.9998102188 0.9997727871 0.9991214871 + 0.9998481870 0.9998182058 0.9992972016 + 0.9998860955 0.9998636842 0.9994729161 + 0.9999241233 0.9999091029 0.9996485710 + 0.9999619722 0.9999545813 0.9998242855 + 1.0000000000 1.0000000000 1.0000000000 +} diff --git a/rpplugins/color_correction/resources/film_luts_raw/kodak_ektachrome_320t.spi1d b/rpplugins/color_correction/resources/film_luts_raw/kodak_ektachrome_320t.spi1d new file mode 100644 index 0000000..64ffe96 --- /dev/null +++ b/rpplugins/color_correction/resources/film_luts_raw/kodak_ektachrome_320t.spi1d @@ -0,0 +1,1030 @@ +Version 1 +From 0.0 1.0 +Length 1024 +Components 3 +{ + 0.0000000000 0.0000000000 0.0000000000 + 0.0002252978 0.0001790309 0.0001295420 + 0.0004642465 0.0003632053 0.0002623819 + 0.0007179323 0.0005541568 0.0004006781 + 0.0009859804 0.0007514893 0.0005452139 + 0.0012678721 0.0009573574 0.0006973416 + 0.0015588400 0.0011699020 0.0008563135 + 0.0018630330 0.0013911340 0.0010223610 + 0.0021819880 0.0016211460 0.0011926870 + 0.0025155889 0.0018565780 0.0013685439 + 0.0028599249 0.0021005161 0.0015487690 + 0.0032150650 0.0023508291 0.0017341210 + 0.0035848729 0.0026105260 0.0019261140 + 0.0039705001 0.0028831610 0.0021247759 + 0.0043733879 0.0031664821 0.0023306201 + 0.0047887620 0.0034602690 0.0025444049 + 0.0052145422 0.0037645160 0.0027661640 + 0.0056500668 0.0040802141 0.0029950261 + 0.0061007268 0.0044055800 0.0032312879 + 0.0065691760 0.0047432170 0.0034755419 + 0.0070610601 0.0050931652 0.0037271639 + 0.0075698970 0.0054551372 0.0039859852 + 0.0080941729 0.0058285771 0.0042510540 + 0.0086274194 0.0062132268 0.0045252559 + 0.0091798287 0.0066124098 0.0048091090 + 0.0097458120 0.0070239422 0.0051020859 + 0.0103271501 0.0074481708 0.0054048309 + 0.0109248599 0.0078837927 0.0057164561 + 0.0115405796 0.0083313556 0.0060368772 + 0.0121761197 0.0087913852 0.0063676350 + 0.0128270397 0.0092629055 0.0067081312 + 0.0134987198 0.0097476542 0.0070575029 + 0.0141942296 0.0102479504 0.0074174819 + 0.0149099398 0.0107645998 0.0077879899 + 0.0156464409 0.0112993503 0.0081683872 + 0.0164025500 0.0118529601 0.0085596293 + 0.0171775799 0.0124243395 0.0089649754 + 0.0179736298 0.0130097996 0.0093868207 + 0.0187904108 0.0136122899 0.0098197656 + 0.0196329206 0.0142326104 0.0102641098 + 0.0205026697 0.0148694804 0.0107198805 + 0.0213967599 0.0155238304 0.0111865401 + 0.0223194696 0.0161926802 0.0116670104 + 0.0232650694 0.0168744400 0.0121609699 + 0.0242343191 0.0175730493 0.0126681803 + 0.0252331793 0.0182904303 0.0131873302 + 0.0262477491 0.0190270096 0.0137195401 + 0.0272829495 0.0197816994 0.0142644998 + 0.0283390097 0.0205556992 0.0148215797 + 0.0294161700 0.0213519502 0.0153918499 + 0.0305210594 0.0221705697 0.0159767196 + 0.0316550806 0.0230139699 0.0165775400 + 0.0328192115 0.0238830894 0.0171922501 + 0.0340085700 0.0247773398 0.0178213306 + 0.0352222398 0.0256955195 0.0184620898 + 0.0364655294 0.0266327392 0.0191150103 + 0.0377436206 0.0275894795 0.0197834391 + 0.0390567891 0.0285663195 0.0204676799 + 0.0404002182 0.0295625906 0.0211681798 + 0.0417738296 0.0305766594 0.0218840092 + 0.0431732200 0.0316094011 0.0226133801 + 0.0445903614 0.0326650515 0.0233574491 + 0.0460246801 0.0337462984 0.0241182297 + 0.0474831313 0.0348512717 0.0248960592 + 0.0489709415 0.0359775797 0.0256870594 + 0.0504862815 0.0371238813 0.0264920406 + 0.0520257801 0.0382876694 0.0273139309 + 0.0535882413 0.0394724905 0.0281523801 + 0.0551759303 0.0406848602 0.0290120896 + 0.0567948110 0.0419235602 0.0298898704 + 0.0584423989 0.0431861505 0.0307816397 + 0.0601175204 0.0444719717 0.0316898413 + 0.0618218705 0.0457797199 0.0326160900 + 0.0635616332 0.0471059717 0.0335598104 + 0.0653382763 0.0484526493 0.0345212892 + 0.0671429336 0.0498179607 0.0355015099 + 0.0689680427 0.0512084812 0.0364993811 + 0.0708093792 0.0526283309 0.0375161916 + 0.0726710036 0.0540754311 0.0385530815 + 0.0745575577 0.0555453300 0.0396075509 + 0.0764711723 0.0570352189 0.0406817608 + 0.0784109309 0.0585439503 0.0417732410 + 0.0803771317 0.0600703284 0.0428790301 + 0.0823737681 0.0616120808 0.0439984985 + 0.0844059363 0.0631667823 0.0451391600 + 0.0864771232 0.0647454932 0.0462969095 + 0.0885818601 0.0663540736 0.0474717803 + 0.0907145590 0.0679863468 0.0486642793 + 0.0928772986 0.0696446896 0.0498744808 + 0.0950741023 0.0713270679 0.0511019900 + 0.0973075032 0.0730293319 0.0523469895 + 0.0995769203 0.0747480765 0.0536088012 + 0.1018780991 0.0764901415 0.0548868291 + 0.1042044014 0.0782487020 0.0561818182 + 0.1065538973 0.0800288767 0.0574982315 + 0.1089283004 0.0818311423 0.0588314198 + 0.1113215014 0.0836538672 0.0601810999 + 0.1137316003 0.0854980275 0.0615520887 + 0.1161573976 0.0873684287 0.0629485399 + 0.1185979992 0.0892611369 0.0643650293 + 0.1210614964 0.0911754370 0.0658011809 + 0.1235487014 0.0931112692 0.0672666430 + 0.1260568053 0.0950720683 0.0687462613 + 0.1285867989 0.0970498696 0.0702391118 + 0.1311426014 0.0990442634 0.0717507899 + 0.1337202042 0.1010560021 0.0732835308 + 0.1363096982 0.1031069979 0.0748315826 + 0.1389120072 0.1051762030 0.0763994083 + 0.1415282041 0.1072625965 0.0779832006 + 0.1441825926 0.1093714982 0.0795782432 + 0.1468576044 0.1115005016 0.0811884925 + 0.1495531946 0.1136446968 0.0828164518 + 0.1522718966 0.1158049032 0.0844542831 + 0.1550171971 0.1179929972 0.0861058980 + 0.1577734947 0.1201986000 0.0877750516 + 0.1605415046 0.1224215031 0.0894542485 + 0.1633353978 0.1246768013 0.0911507979 + 0.1661441028 0.1269477010 0.0928589627 + 0.1689610034 0.1292310059 0.0945746303 + 0.1717838943 0.1315293014 0.0963099599 + 0.1746120006 0.1338451058 0.0980574191 + 0.1774456948 0.1361752003 0.0998183563 + 0.1802875996 0.1385367960 0.1016084999 + 0.1831531972 0.1409143060 0.1034116000 + 0.1860264987 0.1433060020 0.1052436978 + 0.1889072955 0.1457217932 0.1070917994 + 0.1918103993 0.1481487006 0.1089527979 + 0.1947200000 0.1505914032 0.1108305007 + 0.1976352930 0.1530454010 0.1127144024 + 0.2005549073 0.1555085927 0.1146150976 + 0.2034773976 0.1579966992 0.1165283024 + 0.2064062953 0.1605020016 0.1184550002 + 0.2093463987 0.1630198956 0.1204015985 + 0.2122935951 0.1655519009 0.1223547012 + 0.2152556032 0.1680873036 0.1243321002 + 0.2182167023 0.1706292033 0.1263145953 + 0.2211762965 0.1731802970 0.1283138990 + 0.2241538018 0.1757373065 0.1303219944 + 0.2271365970 0.1783048064 0.1323408037 + 0.2301204056 0.1808757931 0.1343753040 + 0.2331143022 0.1834571958 0.1364185959 + 0.2361201942 0.1860488951 0.1384806037 + 0.2391359061 0.1886530071 0.1405466050 + 0.2421551943 0.1912735999 0.1426350027 + 0.2451844066 0.1939011961 0.1447259039 + 0.2482129037 0.1965422034 0.1468326002 + 0.2512401044 0.1991859972 0.1489423960 + 0.2542673051 0.2018409967 0.1510629058 + 0.2572943866 0.2045024037 0.1531887054 + 0.2603251040 0.2071764022 0.1553260982 + 0.2633563876 0.2098606974 0.1574766040 + 0.2663846016 0.2125551999 0.1596474946 + 0.2694126070 0.2152567953 0.1618286073 + 0.2724404037 0.2179622054 0.1640225053 + 0.2754598856 0.2206754982 0.1662251055 + 0.2784681916 0.2233911008 0.1684374958 + 0.2814692855 0.2261153013 0.1706584990 + 0.2844651043 0.2288406044 0.1728888005 + 0.2874703109 0.2315697968 0.1751244962 + 0.2904790938 0.2343001068 0.1773661971 + 0.2934839129 0.2370491028 0.1796108931 + 0.2964878976 0.2397976965 0.1818595976 + 0.2994953096 0.2425439954 0.1841097027 + 0.3025026917 0.2452909946 0.1863622963 + 0.3054913878 0.2480435967 0.1886177063 + 0.3084802032 0.2507981956 0.1908794940 + 0.3114694059 0.2535662055 0.1931429952 + 0.3144572079 0.2563355863 0.1954129934 + 0.3174341023 0.2591148913 0.1976844966 + 0.3204114139 0.2618939877 0.1999710053 + 0.3233911097 0.2646703124 0.2022576034 + 0.3263702095 0.2674466074 0.2045578957 + 0.3293448985 0.2702299058 0.2068590969 + 0.3323191106 0.2730130851 0.2091719061 + 0.3352886140 0.2757953107 0.2114882022 + 0.3382574916 0.2785772979 0.2138084024 + 0.3412111998 0.2813608050 0.2161314934 + 0.3441649079 0.2841446996 0.2184565067 + 0.3471063972 0.2869217098 0.2207846045 + 0.3500475883 0.2896957994 0.2231137007 + 0.3529730141 0.2924658060 0.2254499942 + 0.3558960855 0.2952325046 0.2277863026 + 0.3588060141 0.2979984879 0.2301243991 + 0.3617117107 0.3007633984 0.2324627936 + 0.3645960987 0.3035242856 0.2348098010 + 0.3674674034 0.3062672913 0.2371633947 + 0.3703210056 0.3090102971 0.2395182997 + 0.3731533885 0.3117265999 0.2418767959 + 0.3759778142 0.3144418001 0.2442353964 + 0.3787800074 0.3171553910 0.2465995997 + 0.3815816045 0.3198683858 0.2489643991 + 0.3843731880 0.3225778937 0.2513361871 + 0.3871648014 0.3252829909 0.2537139058 + 0.3899506927 0.3279863000 0.2560917139 + 0.3927353919 0.3306789994 0.2584705949 + 0.3955127001 0.3333716094 0.2608495951 + 0.3982842863 0.3360339999 0.2632276118 + 0.4010469019 0.3386904001 0.2656053007 + 0.4037859142 0.3413349092 0.2679820061 + 0.4065249860 0.3439669013 0.2703562975 + 0.4092408121 0.3465988040 0.2727305889 + 0.4119558036 0.3492295146 0.2751063108 + 0.4146685004 0.3518601954 0.2774823904 + 0.4173798859 0.3544926047 0.2798556983 + 0.4200862050 0.3571256995 0.2822236121 + 0.4227792919 0.3597556055 0.2845914066 + 0.4254722893 0.3623783886 0.2869648039 + 0.4281426072 0.3650011122 0.2893395126 + 0.4308102131 0.3676072955 0.2917163968 + 0.4334703088 0.3702105880 0.2940998971 + 0.4361222088 0.3728044033 0.2964833975 + 0.4387736022 0.3753828108 0.2988683879 + 0.4414154887 0.3779611886 0.3012540936 + 0.4440574050 0.3805244863 0.3036401868 + 0.4466896951 0.3830857873 0.3060306907 + 0.4493151903 0.3856397867 0.3084211946 + 0.4519402087 0.3881801963 0.3108114004 + 0.4545603991 0.3907206953 0.3132013977 + 0.4571805894 0.3932437003 0.3155913949 + 0.4597933888 0.3957622051 0.3179830909 + 0.4624007940 0.3982788026 0.3203752935 + 0.4650070071 0.4007883966 0.3227669895 + 0.4675796926 0.4032979906 0.3251537979 + 0.4701522887 0.4057931900 0.3275406957 + 0.4727115929 0.4082787931 0.3299230933 + 0.4752551019 0.4107643068 0.3322981000 + 0.4777986109 0.4132384062 0.3346731067 + 0.4803014100 0.4157119989 0.3370327055 + 0.4827977121 0.4181810915 0.3393830955 + 0.4852870107 0.4206390083 0.3417334855 + 0.4877533019 0.4230970144 0.3440715075 + 0.4902195036 0.4255495965 0.3464072049 + 0.4926728904 0.4279986918 0.3487423956 + 0.4951168895 0.4304477870 0.3510628939 + 0.4975608885 0.4328849018 0.3533833921 + 0.4999994040 0.4353202879 0.3556984961 + 0.5024372935 0.4377534091 0.3579910994 + 0.5048713088 0.4401684999 0.3602836132 + 0.5072880983 0.4425837100 0.3625684083 + 0.5097048879 0.4449890852 0.3648371100 + 0.5121037960 0.4473744929 0.3671058118 + 0.5144798160 0.4497599006 0.3693706095 + 0.5168557167 0.4521426857 0.3716300130 + 0.5192152858 0.4545232058 0.3738893867 + 0.5215666294 0.4569036067 0.3761452138 + 0.5239177942 0.4592863917 0.3783971071 + 0.5262326002 0.4616703987 0.3806490004 + 0.5285415053 0.4640542865 0.3828856945 + 0.5308492184 0.4664343894 0.3851085007 + 0.5331150889 0.4688135087 0.3873313069 + 0.5353810191 0.4711925089 0.3895424902 + 0.5376406908 0.4735459089 0.3917432129 + 0.5398690104 0.4758956134 0.3939439058 + 0.5420972705 0.4782454073 0.3961327970 + 0.5443140864 0.4805634022 0.3983095884 + 0.5464997292 0.4828793108 0.4004862905 + 0.5486851931 0.4851951003 0.4026562870 + 0.5508528948 0.4874885082 0.4048171043 + 0.5529860854 0.4897811115 0.4069780111 + 0.5551192164 0.4920735955 0.4091326892 + 0.5572410822 0.4943391979 0.4112750888 + 0.5593448877 0.4966034889 0.4134174883 + 0.5614485741 0.4988678992 0.4155569077 + 0.5635406971 0.5010880828 0.4176844060 + 0.5656147003 0.5033046007 0.4198119938 + 0.5676888227 0.5055211186 0.4219393134 + 0.5697504878 0.5077061057 0.4240606129 + 0.5717914104 0.5098856091 0.4261820018 + 0.5738322139 0.5120651722 0.4283033907 + 0.5758668780 0.5142083168 0.4304130077 + 0.5778881907 0.5163393021 0.4325203001 + 0.5799093843 0.5184702277 0.4346275926 + 0.5819228292 0.5205832124 0.4367291033 + 0.5839092731 0.5226848125 0.4388267994 + 0.5858957171 0.5247864127 0.4409244955 + 0.5878791809 0.5268790722 0.4430136979 + 0.5898365974 0.5289608240 0.4450865090 + 0.5917940140 0.5310423970 0.4471594095 + 0.5937513709 0.5331161022 0.4492312074 + 0.5956690907 0.5351639986 0.4512765110 + 0.5975846052 0.5372117758 0.4533218145 + 0.5995001197 0.5392596722 0.4553669989 + 0.6013880968 0.5412784815 0.4573917985 + 0.6032671928 0.5432971716 0.4594076872 + 0.6051464081 0.5453159213 0.4614236057 + 0.6070122123 0.5473181009 0.4634315073 + 0.6088663936 0.5493139029 0.4654226899 + 0.6107205153 0.5513098240 0.4674139023 + 0.6125701070 0.5532947779 0.4694051147 + 0.6144073009 0.5552641749 0.4713697135 + 0.6162444949 0.5572335720 0.4733316898 + 0.6180818081 0.5592026711 0.4752937853 + 0.6199104190 0.5611671209 0.4772514999 + 0.6217387915 0.5631313920 0.4792042077 + 0.6235671043 0.5650957823 0.4811568856 + 0.6253790855 0.5670524836 0.4831095934 + 0.6271820068 0.5690057278 0.4850563109 + 0.6289849281 0.5709587932 0.4870027900 + 0.6307768226 0.5729085207 0.4889493883 + 0.6325399876 0.5748482943 0.4908913076 + 0.6343032122 0.5767881870 0.4928275049 + 0.6360663772 0.5787280798 0.4947637022 + 0.6378102899 0.5806527734 0.4966998994 + 0.6395515203 0.5825737715 0.4986213148 + 0.6412925720 0.5844948292 0.5005409122 + 0.6430225968 0.5864080787 0.5024604797 + 0.6447380185 0.5883042812 0.5043705106 + 0.6464533806 0.5902004242 0.5062571168 + 0.6481688023 0.5920965075 0.5081436038 + 0.6498512030 0.5939829946 0.5100302100 + 0.6515321136 0.5958667994 0.5119035840 + 0.6532130241 0.5977506042 0.5137699842 + 0.6548699141 0.5996311903 0.5156363249 + 0.6564965248 0.6014996767 0.5175027251 + 0.6581230760 0.6033681035 0.5193520188 + 0.6597496867 0.6052364707 0.5212007165 + 0.6613441706 0.6070837975 0.5230494738 + 0.6629346013 0.6089169979 0.5248932838 + 0.6645249724 0.6107501984 0.5267223120 + 0.6661086082 0.6125832796 0.5285513997 + 0.6676759124 0.6143841743 0.5303804278 + 0.6692432761 0.6161835194 0.5322028995 + 0.6708106995 0.6179828048 0.5340183973 + 0.6723604202 0.6197698712 0.5358340144 + 0.6739010811 0.6215232015 0.5376495123 + 0.6754419208 0.6232764721 0.5394585729 + 0.6769825816 0.6250298023 0.5412647724 + 0.6784970164 0.6267579794 0.5430709720 + 0.6800110936 0.6284642816 0.5448771119 + 0.6815252900 0.6301707029 0.5466737747 + 0.6830374002 0.6318771243 0.5484687090 + 0.6845443249 0.6335585117 0.5502635837 + 0.6860511899 0.6352325082 0.5520585775 + 0.6875581145 0.6369063854 0.5538393855 + 0.6890510917 0.6385803223 0.5556197762 + 0.6905319095 0.6402255893 0.5574001074 + 0.6920126081 0.6418696046 0.5591800213 + 0.6934934258 0.6435136199 0.5609490871 + 0.6949405074 0.6451522708 0.5627182126 + 0.6963760257 0.6467463970 0.5644872189 + 0.6978114843 0.6483405232 0.5662546158 + 0.6992468834 0.6499347091 0.5680006146 + 0.7006595135 0.6515222788 0.5697466135 + 0.7020696998 0.6530866027 0.5714926720 + 0.7034800053 0.6546509266 0.5732375979 + 0.7048898935 0.6562151909 0.5749657750 + 0.7062891126 0.6577690244 0.5766940713 + 0.7076883912 0.6592959762 0.5784224272 + 0.7090877295 0.6608229876 0.5801504254 + 0.7104840875 0.6623499990 0.5818541050 + 0.7118595243 0.6638725996 0.5835577846 + 0.7132350206 0.6653854251 0.5852615237 + 0.7146103978 0.6668980718 0.5869652033 + 0.7159860134 0.6684108973 0.5886417031 + 0.7173621058 0.6699141264 0.5903154016 + 0.7187381983 0.6713935733 0.5919892192 + 0.7201142907 0.6728730798 0.5936629772 + 0.7214856148 0.6743525863 0.5953096747 + 0.7228314281 0.6758230925 0.5969482064 + 0.7241771221 0.6772614717 0.5985866785 + 0.7255228758 0.6786999702 0.6002252102 + 0.7268646955 0.6801384091 0.6018486023 + 0.7281752825 0.6815736294 0.6034609079 + 0.7294859290 0.6829831004 0.6050732136 + 0.7307965159 0.6843926907 0.6066855192 + 0.7321065068 0.6858022213 0.6082887053 + 0.7333903909 0.6872118115 0.6098747253 + 0.7346742749 0.6885958910 0.6114608049 + 0.7359582782 0.6899790168 0.6130468249 + 0.7372422218 0.6913622022 0.6146309972 + 0.7385115027 0.6927453279 0.6161890030 + 0.7397789955 0.6941304803 0.6177470088 + 0.7410464883 0.6955162883 0.6193048954 + 0.7423139811 0.6969019771 0.6208629012 + 0.7435634732 0.6982877851 0.6223968267 + 0.7448058128 0.6996648908 0.6239222288 + 0.7460480928 0.7010340095 0.6254476905 + 0.7472903728 0.7024030089 0.6269730926 + 0.7485197783 0.7037721276 0.6284868121 + 0.7497360110 0.7051346898 0.6299803257 + 0.7509521842 0.7064757943 0.6314738989 + 0.7521684170 0.7078167796 0.6329674721 + 0.7533807158 0.7091578841 0.6344609857 + 0.7545793056 0.7104989886 0.6359264851 + 0.7557778955 0.7118229270 0.6373904943 + 0.7569764256 0.7131447792 0.6388545036 + 0.7581750154 0.7144666910 0.6403185129 + 0.7593536973 0.7157886028 0.6417623162 + 0.7605302930 0.7170932889 0.6431841850 + 0.7617068887 0.7183820009 0.6446061730 + 0.7628834844 0.7196707129 0.6460281014 + 0.7640433908 0.7209593058 0.6474500895 + 0.7651894093 0.7222459912 0.6488506198 + 0.7663354278 0.7235112786 0.6502503753 + 0.7674813867 0.7247765064 0.6516500711 + 0.7686260939 0.7260417938 0.6530498266 + 0.7697625160 0.7273070812 0.6544442773 + 0.7708989978 0.7285519838 0.6558309197 + 0.7720354795 0.7297835946 0.6572173834 + 0.7731719017 0.7310153246 0.6586040258 + 0.7742877007 0.7322468758 0.6599906087 + 0.7753937244 0.7334775925 0.6613616943 + 0.7764996886 0.7346972227 0.6627286077 + 0.7776057124 0.7359166741 0.6640955210 + 0.7787057161 0.7371363044 0.6654623747 + 0.7797777057 0.7383558154 0.6668282747 + 0.7808495760 0.7395550013 0.6681864858 + 0.7819216251 0.7407342792 0.6695446968 + 0.7829934955 0.7419134974 0.6709029078 + 0.7840589285 0.7430927753 0.6722611785 + 0.7851203084 0.7442719936 0.6736127734 + 0.7861816883 0.7454271913 0.6749550104 + 0.7872430086 0.7465791702 0.6762971282 + 0.7883045077 0.7477310896 0.6776393056 + 0.7893705964 0.7488831282 0.6789814234 + 0.7904366851 0.7500287294 0.6803113818 + 0.7915027738 0.7511497736 0.6816344857 + 0.7925689220 0.7522708774 0.6829575896 + 0.7936292291 0.7533919811 0.6842806935 + 0.7946795225 0.7545130849 0.6856039166 + 0.7957298160 0.7556204796 0.6869193912 + 0.7967801094 0.7567132115 0.6882331967 + 0.7978304029 0.7578058243 0.6895471215 + 0.7988722920 0.7588983774 0.6908609867 + 0.7999097109 0.7599909902 0.6921749115 + 0.8009471893 0.7610651851 0.6934753060 + 0.8019847274 0.7621316910 0.6947749853 + 0.8030220866 0.7631980777 0.6960747838 + 0.8040328026 0.7642645240 0.6973745227 + 0.8050405979 0.7653309107 0.6986737847 + 0.8060483932 0.7663741708 0.6999592781 + 0.8070561886 0.7674140930 0.7012447715 + 0.8080614805 0.7684540153 0.7025303245 + 0.8090434074 0.7694938779 0.7038156986 + 0.8100252748 0.7705338001 0.7050995827 + 0.8110070825 0.7715379000 0.7063539028 + 0.8119890094 0.7725417018 0.7076082230 + 0.8129674792 0.7735455036 0.7088624835 + 0.8139352798 0.7745493054 0.7101168036 + 0.8149030805 0.7755506039 0.7113707066 + 0.8158710003 0.7765091062 0.7126060128 + 0.8168388009 0.7774677277 0.7138411999 + 0.8177986741 0.7784262896 0.7150765061 + 0.8187428117 0.7793847919 0.7163118124 + 0.8196867704 0.7803425789 0.7175469995 + 0.8206307888 0.7812892795 0.7187737226 + 0.8215748072 0.7822360992 0.7199997902 + 0.8225091100 0.7831827998 0.7212259173 + 0.8234264851 0.7841296196 0.7224519849 + 0.8243438005 0.7850759029 0.7236781120 + 0.8252611756 0.7860084176 0.7248950005 + 0.8261786103 0.7869408727 0.7261095047 + 0.8270888925 0.7878733873 0.7273240089 + 0.8279858232 0.7888059020 0.7285385728 + 0.8288828135 0.7897384167 0.7297530770 + 0.8297798038 0.7906383872 0.7309511900 + 0.8306767941 0.7915360928 0.7321383953 + 0.8315675855 0.7924336791 0.7333257198 + 0.8324421048 0.7933313847 0.7345129251 + 0.8333166242 0.7942289710 0.7357000709 + 0.8341910839 0.7951080203 0.7368817925 + 0.8350657225 0.7959815860 0.7380530834 + 0.8359373212 0.7968552709 0.7392244935 + 0.8367924094 0.7977288961 0.7403959036 + 0.8376473784 0.7986025810 0.7415671945 + 0.8385024071 0.7994632721 0.7427378297 + 0.8393573761 0.8003144264 0.7438889742 + 0.8402125239 0.8011655211 0.7450402975 + 0.8410465717 0.8020166159 0.7461915016 + 0.8418799043 0.8028677106 0.7473427057 + 0.8427131772 0.8037161231 0.7484940290 + 0.8435465097 0.8045580983 0.7496194839 + 0.8443799019 0.8054001927 0.7507324815 + 0.8452067971 0.8062422276 0.7518454194 + 0.8460311890 0.8070843220 0.7529584169 + 0.8468557000 0.8079264164 0.7540712953 + 0.8476800919 0.8087493777 0.7551763058 + 0.8485044837 0.8095721006 0.7562569976 + 0.8493136764 0.8103948832 0.7573378086 + 0.8501023054 0.8112176061 0.7584185004 + 0.8508908749 0.8120403886 0.7594993114 + 0.8516795039 0.8128635883 0.7605800033 + 0.8524680734 0.8136872053 0.7616460919 + 0.8532543182 0.8145108223 0.7627075911 + 0.8540086150 0.8153343797 0.7637690902 + 0.8547629714 0.8161579967 0.7648305893 + 0.8555173278 0.8169798255 0.7658920884 + 0.8562716842 0.8177930117 0.7669504285 + 0.8570259809 0.8186061978 0.7679973245 + 0.8577690721 0.8194193840 0.7690442204 + 0.8585063815 0.8202325106 0.7700911164 + 0.8592435718 0.8210456967 0.7711378932 + 0.8599808812 0.8218513727 0.7721847892 + 0.8607181907 0.8226534724 0.7732229233 + 0.8614515066 0.8234555125 0.7742553949 + 0.8621680737 0.8242576122 0.7752879858 + 0.8628845811 0.8250595927 0.7763205171 + 0.8636012077 0.8258600831 0.7773531079 + 0.8643177748 0.8266490102 0.7783856988 + 0.8650344014 0.8274379969 0.7793797255 + 0.8657494187 0.8282269239 0.7803717256 + 0.8664636016 0.8290157914 0.7813637853 + 0.8671777844 0.8298047185 0.7823559046 + 0.8678920269 0.8305819035 0.7833480239 + 0.8686062098 0.8313472867 0.7843325734 + 0.8693193793 0.8321127295 0.7852917910 + 0.8700184822 0.8328779936 0.7862508893 + 0.8707175851 0.8336433768 0.7872101068 + 0.8714166880 0.8344088197 0.7881693244 + 0.8721157908 0.8351647258 0.7891284227 + 0.8728148937 0.8359184861 0.7900806069 + 0.8734970093 0.8366723061 0.7910240293 + 0.8741555810 0.8374261856 0.7919672728 + 0.8748142123 0.8381800056 0.7929106951 + 0.8754727840 0.8389329910 0.7938539982 + 0.8761314750 0.8396766782 0.7947974205 + 0.8767901063 0.8404204249 0.7957333922 + 0.8774240017 0.8411641121 0.7966641784 + 0.8780478835 0.8419076800 0.7975950241 + 0.8786717057 0.8426514268 0.7985258102 + 0.8792955279 0.8433899879 0.7994565964 + 0.8799194098 0.8441156745 0.8003873825 + 0.8805431724 0.8448413014 0.8012884855 + 0.8811553121 0.8455669880 0.8021752238 + 0.8817664981 0.8462926149 0.8030619025 + 0.8823778033 0.8470183015 0.8039487004 + 0.8829889894 0.8477351069 0.8048353791 + 0.8836002946 0.8484396935 0.8057221174 + 0.8842098713 0.8491442800 0.8065841794 + 0.8848046064 0.8498489261 0.8074355125 + 0.8853992820 0.8505535126 0.8082867861 + 0.8859940171 0.8512580991 0.8091381192 + 0.8865886927 0.8519487977 0.8099893928 + 0.8871833086 0.8526254892 0.8108407259 + 0.8877705932 0.8533021212 0.8116824031 + 0.8883280158 0.8539788127 0.8125190139 + 0.8888853788 0.8546553850 0.8133556247 + 0.8894428015 0.8553320169 0.8141922951 + 0.8900002241 0.8560088277 0.8150289059 + 0.8905575871 0.8566855788 0.8158655167 + 0.8911083937 0.8573625088 0.8166936040 + 0.8916376829 0.8580393195 0.8175144792 + 0.8921670914 0.8587161899 0.8183354735 + 0.8926963806 0.8593930006 0.8191564083 + 0.8932257295 0.8600615859 0.8199774027 + 0.8937550783 0.8607198000 0.8207982779 + 0.8942791820 0.8613780141 0.8216099739 + 0.8947834969 0.8620361090 0.8224058747 + 0.8952878118 0.8626943231 0.8232018948 + 0.8957921863 0.8633524776 0.8239977956 + 0.8962965012 0.8640044928 0.8247938156 + 0.8968008161 0.8646433949 0.8255897760 + 0.8973022103 0.8652822971 0.8263819218 + 0.8977811933 0.8659210801 0.8271486163 + 0.8982601166 0.8665599823 0.8279151917 + 0.8987389803 0.8671988845 0.8286818862 + 0.8992179036 0.8678355217 0.8294485211 + 0.8996968865 0.8684571981 0.8302152157 + 0.9001758099 0.8690788746 0.8309819102 + 0.9006456137 0.8697006106 0.8317354918 + 0.9011150002 0.8703222871 0.8324862123 + 0.9015843272 0.8709440827 0.8332368731 + 0.9020537138 0.8715658188 0.8339877129 + 0.9025231004 0.8721610904 0.8347383738 + 0.9029924273 0.8727529049 0.8354892135 + 0.9034619927 0.8733446002 0.8362295032 + 0.9039316773 0.8739364147 0.8369569182 + 0.9044014812 0.8745281100 0.8376842737 + 0.9048712254 0.8751199245 0.8384116888 + 0.9053409100 0.8756937981 0.8391389847 + 0.9058105946 0.8762534857 0.8398663998 + 0.9062727094 0.8768131137 0.8405938148 + 0.9067248106 0.8773728013 0.8413041234 + 0.9071769118 0.8779324889 0.8420143127 + 0.9076290131 0.8784921169 0.8427246213 + 0.9080811143 0.8790519238 0.8434348702 + 0.9085332751 0.8796120286 0.8441451192 + 0.9089835286 0.8801720738 0.8448554277 + 0.9094098210 0.8807322979 0.8455566764 + 0.9098359942 0.8812924027 0.8462482095 + 0.9102622867 0.8818526268 0.8469398022 + 0.9106885791 0.8824126720 0.8476313949 + 0.9111148119 0.8829627037 0.8483229876 + 0.9115411043 0.8835083246 0.8490145206 + 0.9119545221 0.8840540051 0.8497061133 + 0.9123607874 0.8845996857 0.8503819108 + 0.9127669930 0.8851453066 0.8510559201 + 0.9131733179 0.8856909871 0.8517298102 + 0.9135795236 0.8862351179 0.8524037004 + 0.9139857888 0.8867712021 0.8530777097 + 0.9143912196 0.8873074055 0.8537515998 + 0.9147915244 0.8878436089 0.8544242978 + 0.9151918292 0.8883798122 0.8550928831 + 0.9155920744 0.8889160156 0.8557615280 + 0.9159923792 0.8894522190 0.8564301133 + 0.9163928032 0.8899856806 0.8570985794 + 0.9167931080 0.8905174136 0.8577672243 + 0.9171940088 0.8910490274 0.8584358096 + 0.9175955057 0.8915805817 0.8590922952 + 0.9179968834 0.8921123147 0.8597366810 + 0.9183983207 0.8926439285 0.8603811860 + 0.9187998176 0.8931754827 0.8610256910 + 0.9192011952 0.8936873078 0.8616700768 + 0.9196026921 0.8941966891 0.8623145819 + 0.9199982882 0.8947061896 0.8629590869 + 0.9203935862 0.8952155709 0.8635929823 + 0.9207888246 0.8957250714 0.8642224073 + 0.9211840034 0.8962345123 0.8648517728 + 0.9215791821 0.8967435956 0.8654811978 + 0.9219744205 0.8972501755 0.8661106229 + 0.9223681092 0.8977568150 0.8667399883 + 0.9227561951 0.8982635140 0.8673694134 + 0.9231444001 0.8987700939 0.8679875731 + 0.9235324860 0.8992767930 0.8686034083 + 0.9239205718 0.8997833729 0.8692191839 + 0.9243087769 0.9002879262 0.8698350191 + 0.9246969223 0.9007881284 0.8704507947 + 0.9250844717 0.9012882710 0.8710665703 + 0.9254714251 0.9017884135 0.8716825247 + 0.9258583188 0.9022886157 0.8722918034 + 0.9262452126 0.9027888179 0.8729001880 + 0.9266321063 0.9032890201 0.8735085726 + 0.9270188808 0.9037815928 0.8741170168 + 0.9274057746 0.9042645097 0.8747254014 + 0.9277873039 0.9047474265 0.8753337860 + 0.9281644821 0.9052304029 0.8759421706 + 0.9285417199 0.9057133198 0.8765338063 + 0.9289188981 0.9061961770 0.8771222234 + 0.9292961955 0.9066790938 0.8777105212 + 0.9296733737 0.9071536064 0.8782988787 + 0.9300506115 0.9076185226 0.8788872957 + 0.9304202199 0.9080834985 0.8794757128 + 0.9307851791 0.9085484147 0.8800640106 + 0.9311501980 0.9090133905 0.8806303740 + 0.9315152764 0.9094783068 0.8811889887 + 0.9318802953 0.9099432826 0.8817476034 + 0.9322453141 0.9103996754 0.8823062181 + 0.9326102734 0.9108446240 0.8828647733 + 0.9329578280 0.9112895131 0.8834233880 + 0.9332942963 0.9117342830 0.8839820027 + 0.9336308241 0.9121791720 0.8845335245 + 0.9339672923 0.9126241207 0.8850793839 + 0.9343038201 0.9130688906 0.8856253028 + 0.9346402884 0.9135128260 0.8861711025 + 0.9349768162 0.9139543176 0.8867170215 + 0.9352998137 0.9143959284 0.8872628808 + 0.9356107712 0.9148374200 0.8878087997 + 0.9359217882 0.9152789116 0.8883525729 + 0.9362328053 0.9157204032 0.8888916969 + 0.9365438819 0.9161620140 0.8894308209 + 0.9368548989 0.9166017175 0.8899700046 + 0.9371659160 0.9170259833 0.8905091286 + 0.9374731183 0.9174504280 0.8910481930 + 0.9377737045 0.9178748131 0.8915873170 + 0.9380741715 0.9182991982 0.8921263814 + 0.9383748174 0.9187235832 0.8926637769 + 0.9386752844 0.9191479087 0.8932011127 + 0.9389758706 0.9195722938 0.8937383294 + 0.9392765164 0.9199801087 0.8942756057 + 0.9395747185 0.9203845263 0.8948128819 + 0.9398567080 0.9207890034 0.8953502178 + 0.9401388168 0.9211934209 0.8958874941 + 0.9404208064 0.9215978980 0.8964194059 + 0.9407027960 0.9220023751 0.8969466090 + 0.9409849048 0.9224067926 0.8974738717 + 0.9412668943 0.9228081107 0.8980011940 + 0.9415488839 0.9232060909 0.8985285163 + 0.9418272972 0.9236040115 0.8990557194 + 0.9421048760 0.9240018725 0.8995829821 + 0.9423825145 0.9243999124 0.9001092911 + 0.9426599741 0.9247977734 0.9006150961 + 0.9429376125 0.9251956940 0.9011210203 + 0.9432151914 0.9255933166 0.9016268253 + 0.9434927106 0.9259833097 0.9021326900 + 0.9437695742 0.9263733029 0.9026384950 + 0.9440454841 0.9267632961 0.9031443000 + 0.9443213940 0.9271534085 0.9036502242 + 0.9445973039 0.9275434017 0.9041491747 + 0.9448732138 0.9279333949 0.9046404958 + 0.9451491237 0.9283233881 0.9051318169 + 0.9454249740 0.9286991954 0.9056230783 + 0.9457010031 0.9290624261 0.9061143994 + 0.9459671974 0.9294254780 0.9066057205 + 0.9462327957 0.9297887087 0.9070969224 + 0.9464982748 0.9301518798 0.9075881839 + 0.9467638135 0.9305151105 0.9080798030 + 0.9470294118 0.9308782816 0.9085714817 + 0.9472948909 0.9312413931 0.9090631008 + 0.9475604296 0.9315894246 0.9095547199 + 0.9478178024 0.9319362044 0.9100463986 + 0.9480611086 0.9322831035 0.9105380177 + 0.9483044744 0.9326300025 0.9110296965 + 0.9485477805 0.9329767823 0.9115203023 + 0.9487910867 0.9333236814 0.9119966030 + 0.9490345120 0.9336705804 0.9124727845 + 0.9492778182 0.9340136051 0.9129490852 + 0.9495211244 0.9343457222 0.9134253860 + 0.9497414231 0.9346777797 0.9139016271 + 0.9499527812 0.9350097775 0.9143779278 + 0.9501643181 0.9353418946 0.9148542285 + 0.9503756762 0.9356740117 0.9153259993 + 0.9505872130 0.9360061288 0.9157835841 + 0.9507985711 0.9363381267 0.9162412286 + 0.9510101080 0.9366635084 0.9166988134 + 0.9512215257 0.9369819164 0.9171562791 + 0.9514275789 0.9373003840 0.9176139235 + 0.9516335726 0.9376189113 0.9180715084 + 0.9518396258 0.9379373193 0.9185290933 + 0.9520456791 0.9382557869 0.9189860821 + 0.9522516727 0.9385743141 0.9194421172 + 0.9524577856 0.9388927221 0.9198979735 + 0.9526637793 0.9392104745 0.9203540087 + 0.9528685808 0.9395279288 0.9208099246 + 0.9530680180 0.9398452044 0.9212657809 + 0.9532672763 0.9401625991 0.9217218161 + 0.9534667134 0.9404799938 0.9221776724 + 0.9536660910 0.9407973289 0.9226272106 + 0.9538655281 0.9411147237 0.9230633974 + 0.9540649056 0.9414321184 0.9234995246 + 0.9542642832 0.9417477250 0.9239355922 + 0.9544624090 0.9420624971 0.9243717194 + 0.9546576738 0.9423773289 0.9248077869 + 0.9548529983 0.9426922202 0.9252439737 + 0.9550482035 0.9430069923 0.9256801009 + 0.9552435279 0.9433218837 0.9261130095 + 0.9554387927 0.9436367154 0.9265359044 + 0.9556339979 0.9439516068 0.9269587994 + 0.9558293223 0.9442648888 0.9273816943 + 0.9560242295 0.9445775747 0.9278045297 + 0.9562184215 0.9448903799 0.9282274246 + 0.9564124942 0.9452031255 0.9286503196 + 0.9566066861 0.9455158114 0.9290730953 + 0.9568008780 0.9458284974 0.9294950962 + 0.9569950104 0.9461413026 0.9299049973 + 0.9571892023 0.9464539886 0.9303148985 + 0.9573832750 0.9467725158 0.9307246804 + 0.9575788975 0.9470949173 0.9311345816 + 0.9577786922 0.9474173188 0.9315444827 + 0.9579784274 0.9477397799 0.9319543242 + 0.9581782222 0.9480621815 0.9323642254 + 0.9583780169 0.9483845830 0.9327741265 + 0.9585776925 0.9487069845 0.9331759810 + 0.9587774873 0.9490293860 0.9335759282 + 0.9589772820 0.9493505955 0.9339758158 + 0.9591774940 0.9496698976 0.9343758225 + 0.9593815804 0.9499891996 0.9347757101 + 0.9595857263 0.9503086209 0.9351757169 + 0.9597898126 0.9506279230 0.9355756044 + 0.9599938989 0.9509472251 0.9359754920 + 0.9601979852 0.9512665272 0.9363701940 + 0.9604020715 0.9515858889 0.9367583990 + 0.9606062174 0.9519029856 0.9371466041 + 0.9608103037 0.9522051215 0.9375349283 + 0.9610272050 0.9525070786 0.9379230738 + 0.9612463713 0.9528092146 0.9383112788 + 0.9614655972 0.9531112909 0.9386994839 + 0.9616847038 0.9534133077 0.9390878081 + 0.9619039297 0.9537153840 0.9394757748 + 0.9621229768 0.9540174007 0.9398490787 + 0.9623422027 0.9543194771 0.9402223229 + 0.9625613093 0.9546111822 0.9405955076 + 0.9627830982 0.9548994899 0.9409686923 + 0.9630070925 0.9551877975 0.9413419962 + 0.9632312059 0.9554761052 0.9417151809 + 0.9634553194 0.9557644129 0.9420884252 + 0.9636793733 0.9560527802 0.9424616098 + 0.9639034271 0.9563410878 0.9428309202 + 0.9641274810 0.9566293955 0.9431958199 + 0.9643515944 0.9569211006 0.9435607791 + 0.9645748734 0.9572210908 0.9439256787 + 0.9647920132 0.9575210214 0.9442906976 + 0.9650089741 0.9578210115 0.9446555972 + 0.9652261138 0.9581208825 0.9450206161 + 0.9654431939 0.9584208131 0.9453855157 + 0.9656602144 0.9587208033 0.9457504749 + 0.9658772945 0.9590206742 0.9461066127 + 0.9660943747 0.9593207240 0.9464613199 + 0.9663113952 0.9596204162 0.9468160272 + 0.9665256739 0.9599201083 0.9471706152 + 0.9667379260 0.9602196813 0.9475253224 + 0.9669501185 0.9605193734 0.9478799105 + 0.9671623111 0.9608191252 0.9482346177 + 0.9673745036 0.9611188173 0.9485892057 + 0.9675868154 0.9614183903 0.9489434958 + 0.9677990079 0.9617180824 0.9492951035 + 0.9680112004 0.9620164037 0.9496467113 + 0.9682233930 0.9623020887 0.9499983191 + 0.9684261084 0.9625877142 0.9503499866 + 0.9686285853 0.9628733993 0.9507015944 + 0.9688311219 0.9631590843 0.9510532022 + 0.9690335989 0.9634447098 0.9514048100 + 0.9692360759 0.9637303948 0.9517564178 + 0.9694386125 0.9640160203 0.9521070719 + 0.9696410894 0.9643017054 0.9524558187 + 0.9698436260 0.9645820260 0.9528045058 + 0.9700453281 0.9648528099 0.9531531930 + 0.9702448845 0.9651235938 0.9535018802 + 0.9704446197 0.9653943777 0.9538506269 + 0.9706441760 0.9656652212 0.9541993737 + 0.9708439112 0.9659358859 0.9545481205 + 0.9710435271 0.9662067294 0.9548968077 + 0.9712432027 0.9664775133 0.9552431107 + 0.9714428782 0.9667482972 0.9555861950 + 0.9716424942 0.9670147896 0.9559292197 + 0.9718437195 0.9672774076 0.9562721848 + 0.9720464945 0.9675399065 0.9566152096 + 0.9722493291 0.9678025246 0.9569581747 + 0.9724521041 0.9680650830 0.9573013186 + 0.9726549983 0.9683277011 0.9576442838 + 0.9728577733 0.9685903192 0.9579873085 + 0.9730606079 0.9688528776 0.9583258033 + 0.9732633829 0.9691154957 0.9586578012 + 0.9734662175 0.9693738818 0.9589897990 + 0.9736676216 0.9696295261 0.9593217969 + 0.9738680124 0.9698851109 0.9596537948 + 0.9740685225 0.9701406956 0.9599856734 + 0.9742689133 0.9703962803 0.9603176713 + 0.9744693041 0.9706519246 0.9606497288 + 0.9746698141 0.9709075093 0.9609817266 + 0.9748702049 0.9711630940 0.9613105059 + 0.9750707150 0.9714187980 0.9616318941 + 0.9752711058 0.9716637135 0.9619532824 + 0.9754704237 0.9719005227 0.9622746706 + 0.9756690860 0.9721373916 0.9625961185 + 0.9758678079 0.9723742008 0.9629175067 + 0.9760664105 0.9726111293 0.9632390141 + 0.9762650728 0.9728478789 0.9635604024 + 0.9764636755 0.9730846882 0.9638817906 + 0.9766623974 0.9733216166 0.9642019868 + 0.9768610001 0.9735584259 0.9645112753 + 0.9770597219 0.9737908244 0.9648205042 + 0.9772512913 0.9740175009 0.9651297927 + 0.9774367809 0.9742441773 0.9654390812 + 0.9776223898 0.9744709134 0.9657483101 + 0.9778078794 0.9746975899 0.9660575986 + 0.9779934287 0.9749243259 0.9663668871 + 0.9781789780 0.9751510024 0.9666761160 + 0.9783645272 0.9753776789 0.9669854045 + 0.9785500765 0.9756044149 0.9672716260 + 0.9787356257 0.9758260846 0.9675518870 + 0.9789177179 0.9760301113 0.9678322077 + 0.9790937901 0.9762340784 0.9681125283 + 0.9792699218 0.9764381051 0.9683927894 + 0.9794459939 0.9766421914 0.9686729908 + 0.9796221256 0.9768462181 0.9689533114 + 0.9797981977 0.9770501852 0.9692335725 + 0.9799743295 0.9772542119 0.9695138931 + 0.9801504016 0.9774581790 0.9697943926 + 0.9803264737 0.9776623249 0.9700750709 + 0.9805015922 0.9778532982 0.9703558087 + 0.9806643128 0.9780429006 0.9706364870 + 0.9808269739 0.9782323837 0.9709172249 + 0.9809898138 0.9784219861 0.9711979032 + 0.9811524749 0.9786115289 0.9714785814 + 0.9813151956 0.9788010716 0.9717593193 + 0.9814779162 0.9789906144 0.9720399976 + 0.9816406965 0.9791802168 0.9723206758 + 0.9818034172 0.9793697000 0.9725946784 + 0.9819660783 0.9795542955 0.9728677869 + 0.9821212888 0.9797332883 0.9731410146 + 0.9822732210 0.9799122810 0.9734141231 + 0.9824250937 0.9800912738 0.9736872911 + 0.9825769067 0.9802703261 0.9739603996 + 0.9827287793 0.9804493189 0.9742336273 + 0.9828807116 0.9806283116 0.9745066762 + 0.9830325842 0.9808073044 0.9747799039 + 0.9831845164 0.9809862971 0.9750474095 + 0.9833363891 0.9811652899 0.9753007293 + 0.9834849238 0.9813308120 0.9755538702 + 0.9836212993 0.9814954996 0.9758071899 + 0.9837576747 0.9816601872 0.9760603905 + 0.9838941097 0.9818249941 0.9763137102 + 0.9840304852 0.9819896817 0.9765669107 + 0.9841669798 0.9821544290 0.9768201709 + 0.9843034148 0.9823191762 0.9770733714 + 0.9844397902 0.9824839234 0.9773266912 + 0.9845762253 0.9826486111 0.9775664210 + 0.9847126007 0.9828112721 0.9777957797 + 0.9848353863 0.9829697013 0.9780251980 + 0.9849503040 0.9831280708 0.9782546163 + 0.9850652814 0.9832863808 0.9784839749 + 0.9851801991 0.9834448099 0.9787133932 + 0.9852951169 0.9836031199 0.9789428115 + 0.9854100943 0.9837614894 0.9791722894 + 0.9855250120 0.9839199185 0.9794017076 + 0.9856399298 0.9840782285 0.9796311259 + 0.9857547879 0.9842365980 0.9798449278 + 0.9858698249 0.9843990207 0.9800536036 + 0.9859718084 0.9845643044 0.9802622199 + 0.9860730767 0.9847295880 0.9804708958 + 0.9861744046 0.9848948717 0.9806795716 + 0.9862756729 0.9850602746 0.9808881879 + 0.9863771200 0.9852256179 0.9810969234 + 0.9864783883 0.9853909016 0.9813054800 + 0.9865797162 0.9855561852 0.9815142155 + 0.9866809845 0.9857215285 0.9817228913 + 0.9867823124 0.9858868122 0.9819098115 + 0.9868842959 0.9860410094 0.9820920825 + 0.9869905710 0.9861913919 0.9822744727 + 0.9870967865 0.9863417149 0.9824568033 + 0.9872030020 0.9864919782 0.9826391935 + 0.9873092771 0.9866423011 0.9828215241 + 0.9874154925 0.9867926240 0.9830037951 + 0.9875218272 0.9869430065 0.9831861854 + 0.9876279831 0.9870933294 0.9833685160 + 0.9877343178 0.9872435927 0.9835509062 + 0.9878404737 0.9873939157 0.9837235212 + 0.9879497886 0.9875226021 0.9838936925 + 0.9880681038 0.9876458049 0.9840639234 + 0.9881862998 0.9877688885 0.9842339754 + 0.9883046150 0.9878919721 0.9844042063 + 0.9884228706 0.9880151749 0.9845743775 + 0.9885411859 0.9881383181 0.9847446084 + 0.9886595011 0.9882614017 0.9849147201 + 0.9887778163 0.9883846045 0.9850848913 + 0.9888960123 0.9885076880 0.9852551222 + 0.9890143275 0.9886307716 0.9854249954 + 0.9891341925 0.9887586832 0.9855948091 + 0.9892588854 0.9888883233 0.9857646227 + 0.9893836975 0.9890179038 0.9859343767 + 0.9895085096 0.9891474247 0.9861043096 + 0.9896333218 0.9892770052 0.9862741232 + 0.9897580743 0.9894065857 0.9864438772 + 0.9898828268 0.9895361066 0.9866136909 + 0.9900075793 0.9896656871 0.9867835045 + 0.9901323915 0.9897953272 0.9869533181 + 0.9902572036 0.9899247885 0.9871199131 + 0.9903820157 0.9900571704 0.9872816801 + 0.9905074835 0.9901915789 0.9874433875 + 0.9906330109 0.9903261065 0.9876052141 + 0.9907584190 0.9904605150 0.9877669215 + 0.9908838868 0.9905949831 0.9879286885 + 0.9910094142 0.9907293916 0.9880905151 + 0.9911348224 0.9908639193 0.9882522225 + 0.9912602901 0.9909983277 0.9884139895 + 0.9913856983 0.9911326766 0.9885756969 + 0.9915112257 0.9912672043 0.9887369871 + 0.9916366935 0.9914013147 0.9888862967 + 0.9917575717 0.9915347099 0.9890357256 + 0.9918779731 0.9916681051 0.9891850948 + 0.9919983149 0.9918015003 0.9893345237 + 0.9921187162 0.9919348955 0.9894838929 + 0.9922391176 0.9920682907 0.9896332026 + 0.9923595190 0.9922016263 0.9897825718 + 0.9924799204 0.9923350215 0.9899320006 + 0.9926003218 0.9924684167 0.9900814295 + 0.9927207232 0.9926018119 0.9902307987 + 0.9928411245 0.9927352071 0.9903745055 + 0.9929553270 0.9928619862 0.9905139208 + 0.9930647016 0.9929882884 0.9906532764 + 0.9931741953 0.9931144714 0.9907926917 + 0.9932836294 0.9932407737 0.9909321070 + 0.9933931231 0.9933670759 0.9910715222 + 0.9935024977 0.9934933186 0.9912108779 + 0.9936119914 0.9936196208 0.9913502932 + 0.9937214851 0.9937458038 0.9914897084 + 0.9938309193 0.9938721061 0.9916291237 + 0.9939404130 0.9939982891 0.9917684793 + 0.9940490127 0.9941191077 0.9919059277 + 0.9941514730 0.9942321777 0.9920433164 + 0.9942539930 0.9943454266 0.9921807051 + 0.9943563938 0.9944584966 0.9923179746 + 0.9944589138 0.9945716858 0.9924554229 + 0.9945613742 0.9946848154 0.9925928116 + 0.9946638942 0.9947978854 0.9927302003 + 0.9947664142 0.9949110746 0.9928675294 + 0.9948688149 0.9950242043 0.9930049181 + 0.9949712753 0.9951373935 0.9931423068 + 0.9950737953 0.9952505231 0.9932782054 + 0.9951713085 0.9953569770 0.9934102893 + 0.9952647090 0.9954618812 0.9935423732 + 0.9953581095 0.9955667853 0.9936743975 + 0.9954516292 0.9956716895 0.9938064814 + 0.9955450296 0.9957765937 0.9939386249 + 0.9956383705 0.9958814979 0.9940707088 + 0.9957317710 0.9959864020 0.9942027926 + 0.9958252907 0.9960911870 0.9943348765 + 0.9959186912 0.9961960912 0.9944670200 + 0.9960120916 0.9963009953 0.9945989847 + 0.9961054921 0.9964051247 0.9947274923 + 0.9961966872 0.9965000153 0.9948515892 + 0.9962875843 0.9965949059 0.9949758053 + 0.9963784814 0.9966897964 0.9951000214 + 0.9964693785 0.9967846870 0.9952241182 + 0.9965602756 0.9968795776 0.9953482747 + 0.9966511726 0.9969745278 0.9954724908 + 0.9967421293 0.9970694184 0.9955965877 + 0.9968330264 0.9971643090 0.9957208037 + 0.9969239235 0.9972591996 0.9958449006 + 0.9970148206 0.9973540902 0.9959691167 + 0.9971055984 0.9974477887 0.9960889220 + 0.9971954226 0.9975377917 0.9962046742 + 0.9972853065 0.9976279140 0.9963206053 + 0.9973750710 0.9977179170 0.9964364171 + 0.9974650145 0.9978079200 0.9965522289 + 0.9975547791 0.9978979230 0.9966681004 + 0.9976447225 0.9979879260 0.9967839122 + 0.9977344871 0.9980779290 0.9968997240 + 0.9978243709 0.9981678724 0.9970155954 + 0.9979141951 0.9982579947 0.9971314073 + 0.9980040789 0.9983479977 0.9972472191 + 0.9980940223 0.9984341860 0.9973635077 + 0.9981843829 0.9985107780 0.9974802732 + 0.9982746840 0.9985873103 0.9975970984 + 0.9983651042 0.9986637831 0.9977139235 + 0.9984555244 0.9987403750 0.9978306890 + 0.9985458851 0.9988169074 0.9979475141 + 0.9986361861 0.9988934994 0.9980642796 + 0.9987266064 0.9989699721 0.9981811047 + 0.9988170266 0.9990465045 0.9982979298 + 0.9989073873 0.9991230965 0.9984146953 + 0.9989976883 0.9991996288 0.9985315204 + 0.9990869761 0.9992740154 0.9986500740 + 0.9991700053 0.9993399978 0.9987728000 + 0.9992529750 0.9994059801 0.9988955259 + 0.9993360043 0.9994720221 0.9990181923 + 0.9994189739 0.9995380044 0.9991409779 + 0.9995020032 0.9996039867 0.9992637038 + 0.9995849729 0.9996700287 0.9993864298 + 0.9996680021 0.9997360110 0.9995090961 + 0.9997509718 0.9998019934 0.9996318221 + 0.9998340011 0.9998679757 0.9997546077 + 0.9999169707 0.9999340177 0.9998772740 + 1.0000000000 1.0000000000 1.0000000000 +} diff --git a/rpplugins/color_correction/resources/film_luts_raw/kodak_ektachrome_400x.spi1d b/rpplugins/color_correction/resources/film_luts_raw/kodak_ektachrome_400x.spi1d new file mode 100644 index 0000000..3216d6e --- /dev/null +++ b/rpplugins/color_correction/resources/film_luts_raw/kodak_ektachrome_400x.spi1d @@ -0,0 +1,1030 @@ +Version 1 +From 0.0 1.0 +Length 1024 +Components 3 +{ + 0.0000000000 0.0000000000 0.0000000000 + 0.0003428414 0.0002644671 0.0001401811 + 0.0007192744 0.0005423503 0.0002875368 + 0.0011335440 0.0008326409 0.0004389792 + 0.0015786689 0.0011433410 0.0005958441 + 0.0020476291 0.0014799440 0.0007588092 + 0.0025404820 0.0018298780 0.0009286210 + 0.0030616501 0.0021946840 0.0011060070 + 0.0036125139 0.0025735211 0.0012919310 + 0.0041929889 0.0029686880 0.0014847160 + 0.0048043700 0.0033767780 0.0016857330 + 0.0054497430 0.0038043610 0.0018942290 + 0.0061183511 0.0042493441 0.0021089639 + 0.0068146689 0.0047143549 0.0023315491 + 0.0075340671 0.0051967530 0.0025640430 + 0.0082950303 0.0057056639 0.0028035671 + 0.0090911062 0.0062496541 0.0030509511 + 0.0099175517 0.0068204752 0.0033067439 + 0.0107904803 0.0074211471 0.0035727150 + 0.0117002502 0.0080482997 0.0038465990 + 0.0126570398 0.0087003373 0.0041274340 + 0.0136648295 0.0093829166 0.0044194721 + 0.0147075197 0.0101065598 0.0047251140 + 0.0157950595 0.0108555797 0.0050429730 + 0.0169297699 0.0116311004 0.0053711529 + 0.0181103703 0.0124387797 0.0057113222 + 0.0193332806 0.0132759996 0.0060676620 + 0.0206129998 0.0141413296 0.0064390958 + 0.0219328105 0.0150437802 0.0068241018 + 0.0233088601 0.0159855708 0.0072196471 + 0.0247331504 0.0169505794 0.0076266280 + 0.0262072906 0.0179369505 0.0080475174 + 0.0277359709 0.0189558994 0.0084815770 + 0.0293284301 0.0200254805 0.0089281071 + 0.0309679396 0.0211107805 0.0093870452 + 0.0326597206 0.0222219098 0.0098592760 + 0.0343937390 0.0233689900 0.0103457300 + 0.0361940786 0.0245578606 0.0108465999 + 0.0380464606 0.0257728007 0.0113617396 + 0.0399493314 0.0270075500 0.0118910903 + 0.0419140086 0.0282745995 0.0124359597 + 0.0439488515 0.0296080001 0.0129955998 + 0.0460439511 0.0309876800 0.0135690300 + 0.0481984690 0.0323878303 0.0141631197 + 0.0504118018 0.0338152684 0.0147708496 + 0.0526927300 0.0352800488 0.0153927896 + 0.0550270416 0.0367900804 0.0160309207 + 0.0574264787 0.0383353084 0.0166857298 + 0.0598822795 0.0398985818 0.0173553694 + 0.0623928793 0.0414841883 0.0180462394 + 0.0649654418 0.0431171395 0.0187484995 + 0.0676013976 0.0448169708 0.0194632709 + 0.0702958703 0.0465711690 0.0201920494 + 0.0730418488 0.0483480282 0.0209390707 + 0.0758519098 0.0501504205 0.0217033103 + 0.0787305906 0.0519958399 0.0224795192 + 0.0816697702 0.0538894385 0.0232669692 + 0.0846705586 0.0558331497 0.0240675099 + 0.0877186880 0.0578123406 0.0248920992 + 0.0908257365 0.0598101094 0.0257320199 + 0.0940086022 0.0618289597 0.0265861396 + 0.0972353294 0.0639070272 0.0274642892 + 0.1005206034 0.0660314709 0.0283592492 + 0.1038618013 0.0682074204 0.0292693600 + 0.1072567031 0.0704347715 0.0302035604 + 0.1107103974 0.0726976171 0.0311573707 + 0.1142259985 0.0749783218 0.0321260095 + 0.1177944019 0.0772918463 0.0331200808 + 0.1214151010 0.0796481296 0.0341317691 + 0.1250821054 0.0820898935 0.0351568311 + 0.1287855953 0.0845760182 0.0362133905 + 0.1325509995 0.0870889798 0.0372799113 + 0.1363651007 0.0896213502 0.0383602083 + 0.1402193010 0.0921822414 0.0394625701 + 0.1441060007 0.0947721824 0.0405752398 + 0.1480046958 0.0973958895 0.0417135507 + 0.1519186944 0.1000884995 0.0428665988 + 0.1558499932 0.1028292999 0.0440348983 + 0.1598220021 0.1056241989 0.0452243313 + 0.1638336033 0.1084792018 0.0464208983 + 0.1678801030 0.1113488972 0.0476398095 + 0.1719820052 0.1142351031 0.0488679707 + 0.1761175990 0.1171704978 0.0501159504 + 0.1802733988 0.1201329008 0.0513837487 + 0.1844418943 0.1231521964 0.0526686385 + 0.1886288971 0.1262086034 0.0539824814 + 0.1928298026 0.1292911023 0.0553071685 + 0.1970759928 0.1324020028 0.0566712618 + 0.2013373971 0.1355181038 0.0580410585 + 0.2056180984 0.1386440992 0.0594506897 + 0.2099272013 0.1417901963 0.0608652011 + 0.2142390013 0.1449521929 0.0623159185 + 0.2185354978 0.1481644064 0.0637758672 + 0.2228298932 0.1513926983 0.0652757511 + 0.2271223068 0.1547017992 0.0667859018 + 0.2314382046 0.1580224037 0.0683313832 + 0.2357621044 0.1613737047 0.0698857680 + 0.2401127070 0.1647437066 0.0714698881 + 0.2444832027 0.1681362987 0.0730611980 + 0.2488923073 0.1715582013 0.0746805519 + 0.2533152103 0.1749991030 0.0763059929 + 0.2577489913 0.1784823984 0.0779676214 + 0.2621993124 0.1819818020 0.0796313584 + 0.2666550875 0.1855379939 0.0813349113 + 0.2711015940 0.1891071051 0.0830384567 + 0.2755472958 0.1927215010 0.0847683027 + 0.2799974084 0.1963423938 0.0865003392 + 0.2844476104 0.2000225931 0.0882561207 + 0.2888987958 0.2037090063 0.0900193900 + 0.2933452129 0.2073960006 0.0917988792 + 0.2977733016 0.2110829949 0.0935909674 + 0.3021937013 0.2147787064 0.0953960270 + 0.3065907061 0.2184758037 0.0972275063 + 0.3109777868 0.2221865058 0.0990616009 + 0.3153359890 0.2259006053 0.1009372994 + 0.3196929097 0.2296067029 0.1028129980 + 0.3240458071 0.2333091944 0.1047334969 + 0.3283928931 0.2370095998 0.1066685989 + 0.3327110112 0.2407082021 0.1086295024 + 0.3370262086 0.2444002032 0.1106277034 + 0.3413048983 0.2480811030 0.1126269996 + 0.3455835879 0.2517619133 0.1146645993 + 0.3498139083 0.2554424107 0.1167021990 + 0.3540413976 0.2591229081 0.1187660992 + 0.3582440019 0.2627831101 0.1208472997 + 0.3624396026 0.2664416134 0.1229355037 + 0.3666112125 0.2701123059 0.1250668019 + 0.3707655966 0.2737897933 0.1271981001 + 0.3749122918 0.2774769068 0.1293662041 + 0.3790445030 0.2811841965 0.1315550953 + 0.3831717968 0.2848913968 0.1337489933 + 0.3872435987 0.2885521054 0.1359899044 + 0.3913154006 0.2922112942 0.1382308006 + 0.3953064978 0.2958714068 0.1404815018 + 0.3992744088 0.2995322049 0.1427416056 + 0.4032138884 0.3031899035 0.1450016946 + 0.4071162045 0.3068281114 0.1472705007 + 0.4110161960 0.3104662001 0.1495404989 + 0.4148718119 0.3140855134 0.1518152952 + 0.4187273979 0.3176954091 0.1541071981 + 0.4225727022 0.3213038146 0.1563991010 + 0.4264118969 0.3249039054 0.1586962938 + 0.4302516878 0.3285039961 0.1609987020 + 0.4340943098 0.3320690989 0.1633010954 + 0.4379369915 0.3356105089 0.1656249017 + 0.4417563081 0.3391517997 0.1679558009 + 0.4455639124 0.3426533043 0.1702867001 + 0.4493665993 0.3461548090 0.1726520061 + 0.4531346858 0.3496446013 0.1750191003 + 0.4569028914 0.3531137109 0.1773868054 + 0.4606313109 0.3565827906 0.1797600985 + 0.4643262029 0.3600330055 0.1821334064 + 0.4680210054 0.3634741902 0.1845103949 + 0.4716567993 0.3669154048 0.1869013011 + 0.4752872884 0.3703399003 0.1892922968 + 0.4789054096 0.3737635016 0.1916884929 + 0.4824860990 0.3771829009 0.1940988004 + 0.4860669076 0.3805834055 0.1965090930 + 0.4896276891 0.3839837909 0.1989264935 + 0.4931711853 0.3873957992 0.2013619989 + 0.4967147112 0.3908275962 0.2037975937 + 0.5001958013 0.3942595124 0.2062384039 + 0.5036591887 0.3976672888 0.2086957991 + 0.5071225762 0.4010519087 0.2111531943 + 0.5105044842 0.4044364095 0.2136141956 + 0.5138846040 0.4077871144 0.2160944939 + 0.5172544718 0.4111149907 0.2185747027 + 0.5205571055 0.4144429862 0.2210548967 + 0.5238596201 0.4177626073 0.2235321999 + 0.5271421075 0.4210774004 0.2260096073 + 0.5303608179 0.4243923128 0.2284868956 + 0.5335794091 0.4276579022 0.2309691012 + 0.5367782116 0.4308958948 0.2334523946 + 0.5399305224 0.4341338873 0.2359357029 + 0.5430827141 0.4373329878 0.2384334058 + 0.5462197065 0.4405049086 0.2409410030 + 0.5493230820 0.4436767995 0.2434486002 + 0.5524265170 0.4468128979 0.2459536940 + 0.5555045009 0.4499109983 0.2484524995 + 0.5585151911 0.4530090988 0.2509512901 + 0.5615258813 0.4560930133 0.2534500957 + 0.5645241141 0.4591484070 0.2559669018 + 0.5674679279 0.4622037113 0.2584846020 + 0.5704116821 0.4652596116 0.2610023916 + 0.5733518004 0.4683186114 0.2635214031 + 0.5762202740 0.4713774920 0.2660414875 + 0.5790888071 0.4744364917 0.2685616016 + 0.5819572806 0.4774442017 0.2710804045 + 0.5847468972 0.4804444015 0.2735868096 + 0.5875238180 0.4834446013 0.2760930955 + 0.5903006792 0.4864538014 0.2785995007 + 0.5930446982 0.4894700050 0.2811084092 + 0.5957688093 0.4924862981 0.2836191952 + 0.5984929204 0.4954943061 0.2861298919 + 0.6011797786 0.4984689057 0.2886404097 + 0.6037912965 0.5014435053 0.2911294997 + 0.6064026952 0.5044180751 0.2936185896 + 0.6090142131 0.5073412061 0.2961077094 + 0.6115440130 0.5102497935 0.2985940874 + 0.6140723825 0.5131583810 0.3010762036 + 0.6166006923 0.5160554051 0.3035584092 + 0.6191328168 0.5189260840 0.3060404956 + 0.6216673851 0.5217968822 0.3085111082 + 0.6242020726 0.5246676803 0.3109765947 + 0.6267291903 0.5274786949 0.3134421110 + 0.6292034984 0.5302724242 0.3159075975 + 0.6316779256 0.5330660939 0.3183633983 + 0.6341521740 0.5358421206 0.3208185136 + 0.6366034746 0.5385411978 0.3232735991 + 0.6390401721 0.5412402749 0.3257263005 + 0.6414769292 0.5439392924 0.3281632960 + 0.6439121962 0.5465759039 0.3306002915 + 0.6463143826 0.5491589904 0.3330372870 + 0.6487165093 0.5517421961 0.3354707062 + 0.6511186957 0.5543252826 0.3378941119 + 0.6535044909 0.5568907857 0.3403174877 + 0.6558670998 0.5594527125 0.3427408934 + 0.6582297087 0.5620146990 0.3451600075 + 0.6605921984 0.5645741224 0.3475705981 + 0.6629050970 0.5670986772 0.3499810994 + 0.6651992202 0.5696232915 0.3523916006 + 0.6674932837 0.5721479058 0.3547942042 + 0.6697874069 0.5746628046 0.3571807146 + 0.6720268130 0.5771465898 0.3595671952 + 0.6742650867 0.5796303749 0.3619537950 + 0.6765033007 0.5821142197 0.3643409908 + 0.6787335277 0.5846080780 0.3667303920 + 0.6809238791 0.5871208906 0.3691197932 + 0.6831144094 0.5896338224 0.3715091050 + 0.6853048205 0.5921465755 0.3738974929 + 0.6874766946 0.5946516991 0.3762792051 + 0.6896049976 0.5971447825 0.3786608875 + 0.6917333007 0.5996379256 0.3810425997 + 0.6938616037 0.6021310091 0.3834243119 + 0.6959702969 0.6046125293 0.3858002126 + 0.6980445981 0.6070746183 0.3881756961 + 0.7001190186 0.6095365882 0.3905512989 + 0.7021933198 0.6119986773 0.3929268122 + 0.7042300105 0.6144391894 0.3952862024 + 0.7062014937 0.6168267131 0.3976376057 + 0.7081729770 0.6192142963 0.3999890983 + 0.7101445198 0.6216018200 0.4023405910 + 0.7120977044 0.6239740252 0.4046814144 + 0.7140085101 0.6262511015 0.4070011973 + 0.7159193754 0.6285281777 0.4093208909 + 0.7178301811 0.6308053732 0.4116407037 + 0.7197390199 0.6330825090 0.4139603972 + 0.7216380239 0.6352655292 0.4162608087 + 0.7235370874 0.6374403238 0.4185597897 + 0.7254360914 0.6396151185 0.4208588004 + 0.7273350954 0.6417899728 0.4231578112 + 0.7291654944 0.6438943744 0.4254482090 + 0.7309942245 0.6459581256 0.4277282059 + 0.7328227758 0.6480216980 0.4300082028 + 0.7346515059 0.6500852704 0.4322882891 + 0.7364507914 0.6521360278 0.4345682859 + 0.7382380962 0.6541525126 0.4368130863 + 0.7400254011 0.6561689973 0.4390538931 + 0.7418125868 0.6581856012 0.4412946999 + 0.7435858846 0.6602020860 0.4435355067 + 0.7453356981 0.6621177197 0.4457657039 + 0.7470855117 0.6640151739 0.4479677975 + 0.7488353252 0.6659126282 0.4501698911 + 0.7505850792 0.6678100824 0.4523718953 + 0.7522721887 0.6696808934 0.4545739889 + 0.7539572716 0.6715016961 0.4567523003 + 0.7556424141 0.6733224988 0.4589129984 + 0.7573276162 0.6751433015 0.4610736966 + 0.7590008974 0.6769641042 0.4632343948 + 0.7606620789 0.6787366271 0.4653950036 + 0.7623233199 0.6804947853 0.4675134122 + 0.7639845014 0.6822531223 0.4696210027 + 0.7656456828 0.6840112805 0.4717285931 + 0.7672730088 0.6857655048 0.4738362134 + 0.7688981295 0.6874911189 0.4759437144 + 0.7705233097 0.6892166138 0.4780164063 + 0.7721484900 0.6909422278 0.4800868034 + 0.7737551928 0.6926677227 0.4821572006 + 0.7753220201 0.6943894029 0.4842276871 + 0.7768889070 0.6961051822 0.4862979054 + 0.7784556746 0.6978209019 0.4883329868 + 0.7800226212 0.6995366812 0.4903681874 + 0.7815604806 0.7012524009 0.4924033880 + 0.7830802798 0.7029501796 0.4944385886 + 0.7846000791 0.7046359777 0.4964737892 + 0.7861198783 0.7063217163 0.4984565973 + 0.7876396775 0.7080073953 0.5004389286 + 0.7891361713 0.7096931934 0.5024212003 + 0.7906283140 0.7113500237 0.5044035912 + 0.7921203971 0.7129955292 0.5063859224 + 0.7936124802 0.7146410942 0.5083438754 + 0.7951045036 0.7162865996 0.5102990866 + 0.7965341210 0.7179322243 0.5122541785 + 0.7979624867 0.7195677161 0.5142092705 + 0.7993909717 0.7212001085 0.5161644220 + 0.8008195162 0.7228323817 0.5181018710 + 0.8022456169 0.7244647741 0.5200322866 + 0.8036258817 0.7260971069 0.5219627023 + 0.8050063252 0.7276834846 0.5238931179 + 0.8063865900 0.7292519212 0.5258234739 + 0.8077669144 0.7308204174 0.5277478099 + 0.8091464043 0.7323887944 0.5296645164 + 0.8105019927 0.7339571714 0.5315812826 + 0.8118575215 0.7355170846 0.5334979892 + 0.8132131100 0.7370710969 0.5354146957 + 0.8145685792 0.7386251092 0.5373278856 + 0.8159241080 0.7401791215 0.5392090082 + 0.8172050714 0.7417330742 0.5410900712 + 0.8184810877 0.7432689071 0.5429710746 + 0.8197571039 0.7447763085 0.5448521972 + 0.8210331798 0.7462838292 0.5467333198 + 0.8223091960 0.7477911711 0.5485991836 + 0.8235437870 0.7492985725 0.5504574180 + 0.8247652054 0.7507972121 0.5523154736 + 0.8259866834 0.7522162199 0.5541737080 + 0.8272081017 0.7536352873 0.5560318232 + 0.8284295797 0.7550544143 0.5578854084 + 0.8296269178 0.7564734817 0.5597094297 + 0.8307995200 0.7578924894 0.5615333915 + 0.8319721818 0.7592418194 0.5633574128 + 0.8331449032 0.7605643868 0.5651813745 + 0.8343175054 0.7618870139 0.5670053959 + 0.8354796767 0.7632095814 0.5688126087 + 0.8365802765 0.7645322084 0.5706043243 + 0.8376808167 0.7658463717 0.5723959208 + 0.8387814164 0.7671360970 0.5741875768 + 0.8398818970 0.7684258819 0.5759791732 + 0.8409824967 0.7697157264 0.5777708888 + 0.8420794010 0.7710055113 0.5795426965 + 0.8431748152 0.7722951770 0.5813097954 + 0.8442702293 0.7735279799 0.5830768943 + 0.8453655839 0.7747368217 0.5848439932 + 0.8464609981 0.7759457231 0.5866110921 + 0.8475471139 0.7771545053 0.5883777738 + 0.8485909104 0.7783632874 0.5900940895 + 0.8496348262 0.7795684934 0.5918104053 + 0.8506786823 0.7807170153 0.5935267210 + 0.8517224789 0.7818654180 0.5952430964 + 0.8527663946 0.7830138803 0.5969594121 + 0.8537737131 0.7841622829 0.5986704230 + 0.8547530770 0.7853106856 0.6003401279 + 0.8557325006 0.7864531875 0.6020097733 + 0.8567119241 0.7875832915 0.6036794186 + 0.8576912880 0.7887133956 0.6053491235 + 0.8586707115 0.7898433805 0.6070188284 + 0.8596333861 0.7909734845 0.6086828709 + 0.8605933189 0.7921035886 0.6103072166 + 0.8615533113 0.7932407856 0.6119315028 + 0.8625131845 0.7943854928 0.6135557890 + 0.8634731770 0.7955302000 0.6151800752 + 0.8644313216 0.7966749072 0.6168044209 + 0.8653596044 0.7978194952 0.6184266806 + 0.8662878871 0.7989642024 0.6199904084 + 0.8672162294 0.8000708222 0.6215540767 + 0.8681445122 0.8011484742 0.6231178045 + 0.8690729141 0.8022263050 0.6246814728 + 0.8699941039 0.8033040166 0.6262450814 + 0.8708788157 0.8043817282 0.6278088093 + 0.8717635870 0.8054593801 0.6293694973 + 0.8726484179 0.8065189123 0.6309295893 + 0.8735331297 0.8075633049 0.6324898005 + 0.8744179010 0.8086076975 0.6340498924 + 0.8752959967 0.8096520901 0.6356101036 + 0.8761417270 0.8106964827 0.6371701956 + 0.8769873977 0.8117408752 0.6387233734 + 0.8778331280 0.8127887249 0.6402710080 + 0.8786787987 0.8138411045 0.6418185830 + 0.8795245290 0.8148934841 0.6433662176 + 0.8803673983 0.8159459233 0.6449137926 + 0.8811801076 0.8169983029 0.6464614868 + 0.8819928765 0.8180506825 0.6480066180 + 0.8828055859 0.8190910220 0.6495386958 + 0.8836184144 0.8200846910 0.6510708928 + 0.8844311237 0.8210783005 0.6526029706 + 0.8852438927 0.8220720291 0.6541351080 + 0.8860117793 0.8230656981 0.6556673050 + 0.8867745996 0.8240593076 0.6571993828 + 0.8875373006 0.8250529766 0.6587041020 + 0.8883000016 0.8260309100 0.6601948738 + 0.8890628219 0.8270068169 0.6616855860 + 0.8898255229 0.8279826045 0.6631764174 + 0.8905583024 0.8289585114 0.6646671891 + 0.8912715912 0.8299342990 0.6661580205 + 0.8919848800 0.8309102058 0.6676467061 + 0.8926982284 0.8318812847 0.6691030264 + 0.8934115767 0.8328469992 0.6705592871 + 0.8941249251 0.8338125944 0.6720156074 + 0.8948332071 0.8347781897 0.6734719276 + 0.8955228925 0.8357439041 0.6749281883 + 0.8962126970 0.8367094994 0.6763845086 + 0.8969023824 0.8376750946 0.6778261065 + 0.8975921869 0.8385697007 0.6792402864 + 0.8982818723 0.8394591808 0.6806545854 + 0.8989716768 0.8403486013 0.6820688248 + 0.8996360898 0.8412380219 0.6834830046 + 0.9002904892 0.8421275020 0.6848973036 + 0.9009450078 0.8430169225 0.6863114834 + 0.9015994072 0.8438990116 0.6877009869 + 0.9022538066 0.8447635770 0.6890684962 + 0.9029083252 0.8456280828 0.6904361248 + 0.9035584927 0.8464927077 0.6918036938 + 0.9041764140 0.8473572731 0.6931712031 + 0.9047942758 0.8482218981 0.6945387721 + 0.9054121971 0.8490865231 0.6959062815 + 0.9060301781 0.8499292731 0.6972550750 + 0.9066480994 0.8507544994 0.6985912919 + 0.9072660208 0.8515797257 0.6999275088 + 0.9078578949 0.8524048924 0.7012637258 + 0.9084116817 0.8532301188 0.7025998831 + 0.9089655280 0.8540552855 0.7039362192 + 0.9095193148 0.8548805118 0.7052723765 + 0.9100729823 0.8557091951 0.7065873146 + 0.9106268287 0.8565393090 0.7078853250 + 0.9111806154 0.8573694825 0.7091832161 + 0.9117125273 0.8581997156 0.7104812264 + 0.9122291207 0.8590298891 0.7117791176 + 0.9127455950 0.8598600030 0.7130771279 + 0.9132621288 0.8606901765 0.7143750191 + 0.9137787223 0.8614907861 0.7156553864 + 0.9142951965 0.8622807264 0.7169089913 + 0.9148116708 0.8630706072 0.7181627154 + 0.9153102040 0.8638604879 0.7194163203 + 0.9157993793 0.8646503091 0.7206699252 + 0.9162884951 0.8654401898 0.7219234705 + 0.9167776108 0.8662300706 0.7231771946 + 0.9172667861 0.8670079708 0.7244259715 + 0.9177559018 0.8677796721 0.7256401777 + 0.9182450175 0.8685513735 0.7268543243 + 0.9187002778 0.8693230152 0.7280684114 + 0.9191343188 0.8700947165 0.7292826176 + 0.9195683002 0.8708662987 0.7304967046 + 0.9200022817 0.8716380000 0.7317107916 + 0.9204363227 0.8723940253 0.7329249978 + 0.9208703041 0.8731313944 0.7341042161 + 0.9213042855 0.8738688231 0.7352702022 + 0.9217389822 0.8746061921 0.7364361882 + 0.9221745729 0.8753436804 0.7376021743 + 0.9226102233 0.8760811090 0.7387682796 + 0.9230456948 0.8768184781 0.7399343252 + 0.9234812856 0.8775455952 0.7411003113 + 0.9239168763 0.8782122135 0.7422618270 + 0.9243525267 0.8788788915 0.7434059978 + 0.9247846007 0.8795455098 0.7445502877 + 0.9252011776 0.8802121878 0.7456945777 + 0.9256178141 0.8808789253 0.7468389273 + 0.9260342717 0.8815454841 0.7479830980 + 0.9264509082 0.8822122216 0.7491273880 + 0.9268674850 0.8828688264 0.7502716780 + 0.9272841215 0.8835214972 0.7514011860 + 0.9277005792 0.8841741085 0.7525197268 + 0.9280946255 0.8848267794 0.7536382079 + 0.9284824133 0.8854793906 0.7547566891 + 0.9288702011 0.8861320019 0.7558751702 + 0.9292579889 0.8867846727 0.7569937110 + 0.9296457767 0.8874309063 0.7581123114 + 0.9300336242 0.8880439997 0.7592307925 + 0.9304214716 0.8886572123 0.7603214979 + 0.9308112860 0.8892703056 0.7614058256 + 0.9312064052 0.8898835182 0.7624900937 + 0.9316015244 0.8904966116 0.7635744214 + 0.9319965839 0.8911098242 0.7646586895 + 0.9323917031 0.8917229176 0.7657430172 + 0.9327868223 0.8923314214 0.7668272853 + 0.9331818819 0.8929349184 0.7679116130 + 0.9335770011 0.8935384154 0.7689800262 + 0.9339686036 0.8941419125 0.7700471282 + 0.9343581796 0.8947455287 0.7711141109 + 0.9347478151 0.8953490257 0.7721812129 + 0.9351373911 0.8959525228 0.7732483149 + 0.9355270267 0.8965560198 0.7743152976 + 0.9359166026 0.8971521854 0.7753823996 + 0.9363061786 0.8977450132 0.7764495015 + 0.9366958141 0.8983377814 0.7774727941 + 0.9370884895 0.8989306092 0.7784914970 + 0.9374815822 0.8995233774 0.7795102000 + 0.9378746748 0.9001162052 0.7805289030 + 0.9382678270 0.9007089734 0.7815477252 + 0.9386609197 0.9013018012 0.7825664282 + 0.9390540123 0.9018632174 0.7835850716 + 0.9394471049 0.9024146795 0.7846037745 + 0.9398401976 0.9029660821 0.7855820060 + 0.9402080178 0.9035176039 0.7865473032 + 0.9405754209 0.9040690064 0.7875126004 + 0.9409428835 0.9046205282 0.7884777784 + 0.9413102865 0.9051718712 0.7894430757 + 0.9416776896 0.9057233930 0.7904083729 + 0.9420450926 0.9062736034 0.7913736105 + 0.9424126148 0.9068232179 0.7923389077 + 0.9427800179 0.9073727727 0.7932832241 + 0.9431211948 0.9079225063 0.7942044735 + 0.9434615970 0.9084721208 0.7951257825 + 0.9438019991 0.9090217948 0.7960470915 + 0.9441424012 0.9095714092 0.7969682813 + 0.9444829226 0.9101210237 0.7978895903 + 0.9448233247 0.9106593132 0.7988108993 + 0.9451637268 0.9111868739 0.7997322083 + 0.9455041289 0.9117143750 0.8006522059 + 0.9458433986 0.9122418761 0.8015512228 + 0.9461824298 0.9127693772 0.8024501204 + 0.9465214014 0.9132968783 0.8033490777 + 0.9468603730 0.9138243794 0.8042480946 + 0.9471994042 0.9143518806 0.8051471114 + 0.9475384951 0.9148817062 0.8060461283 + 0.9478775263 0.9154210091 0.8069450855 + 0.9482164979 0.9159603715 0.8078441024 + 0.9485536218 0.9164997935 0.8087291718 + 0.9488890767 0.9170392156 0.8096008897 + 0.9492245913 0.9175785184 0.8104726076 + 0.9495601058 0.9181178808 0.8113443255 + 0.9498956203 0.9186573029 0.8122159839 + 0.9502310157 0.9191967249 0.8130877018 + 0.9505664706 0.9197019935 0.8139594197 + 0.9509019852 0.9201949835 0.8148310781 + 0.9512333870 0.9206879139 0.8157027960 + 0.9515367150 0.9211807847 0.8165382743 + 0.9518401027 0.9216737747 0.8173654079 + 0.9521434903 0.9221667051 0.8181924820 + 0.9524468184 0.9226595759 0.8190196753 + 0.9527502060 0.9231525064 0.8198468089 + 0.9530535936 0.9236370921 0.8206740022 + 0.9533569813 0.9240685105 0.8215010762 + 0.9536603093 0.9244999290 0.8223283291 + 0.9539365172 0.9249312282 0.8231554031 + 0.9541925788 0.9253625870 0.8239536285 + 0.9544487000 0.9257940054 0.8247510791 + 0.9547048807 0.9262254238 0.8255487084 + 0.9549610019 0.9266567230 0.8263462782 + 0.9552171230 0.9270880818 0.8271439075 + 0.9554733038 0.9275091887 0.8279414773 + 0.9557294250 0.9279149771 0.8287389874 + 0.9559856057 0.9283208251 0.8295366168 + 0.9562343955 0.9287264943 0.8303341866 + 0.9564822912 0.9291322827 0.8311038017 + 0.9567301273 0.9295380116 0.8318734765 + 0.9569780231 0.9299438000 0.8326432109 + 0.9572259188 0.9303495884 0.8334128261 + 0.9574738145 0.9307553172 0.8341825008 + 0.9577217102 0.9311472178 0.8349521756 + 0.9579694867 0.9315264225 0.8357219100 + 0.9582170844 0.9319056273 0.8364915252 + 0.9584596753 0.9322847724 0.8372612000 + 0.9587022066 0.9326639771 0.8380025029 + 0.9589446783 0.9330431223 0.8387396932 + 0.9591872096 0.9334223270 0.8394770026 + 0.9594296813 0.9338014722 0.8402141929 + 0.9596722126 0.9341806769 0.8409515023 + 0.9599146843 0.9345543981 0.8416886926 + 0.9601572156 0.9349225760 0.8424260020 + 0.9603989124 0.9352908134 0.8431631923 + 0.9606298208 0.9356588721 0.8439005017 + 0.9608606100 0.9360271096 0.8446270823 + 0.9610915184 0.9363952875 0.8453466296 + 0.9613224268 0.9367635250 0.8460661769 + 0.9615532756 0.9371317029 0.8467857838 + 0.9617841840 0.9374998808 0.8475053906 + 0.9620149732 0.9378612041 0.8482248783 + 0.9622458816 0.9382085204 0.8489444852 + 0.9624767900 0.9385557771 0.8496640921 + 0.9627113938 0.9389030933 0.8503836989 + 0.9629462957 0.9392504096 0.8510984778 + 0.9631810784 0.9395977259 0.8517916203 + 0.9634159207 0.9399449825 0.8524847031 + 0.9636507034 0.9402922988 0.8531777263 + 0.9638856053 0.9406396151 0.8538708091 + 0.9641203880 0.9409868717 0.8545638919 + 0.9643551707 0.9413303137 0.8552569151 + 0.9645900726 0.9416738153 0.8559499979 + 0.9648157954 0.9420171976 0.8566430211 + 0.9650372267 0.9423606992 0.8573361039 + 0.9652585983 0.9427040815 0.8580203056 + 0.9654800892 0.9430475831 0.8586984873 + 0.9657015204 0.9433910251 0.8593767285 + 0.9659228921 0.9437345266 0.8600549102 + 0.9661443233 0.9440779090 0.8607330918 + 0.9663656950 0.9444156289 0.8614112735 + 0.9665871263 0.9447482824 0.8620895147 + 0.9668061733 0.9450809956 0.8627676964 + 0.9670186043 0.9454137087 0.8634458780 + 0.9672309160 0.9457464218 0.8641241193 + 0.9674432278 0.9460790157 0.8647658229 + 0.9676554799 0.9464117289 0.8654016256 + 0.9678679109 0.9467443824 0.8660374284 + 0.9680802226 0.9470770955 0.8666731715 + 0.9682924747 0.9474098086 0.8673089743 + 0.9685047865 0.9477065802 0.8679447770 + 0.9687172174 0.9479998946 0.8685806990 + 0.9689158201 0.9482930899 0.8692165017 + 0.9691076875 0.9485862851 0.8698523045 + 0.9692996740 0.9488794804 0.8704881072 + 0.9694917202 0.9491726756 0.8711016178 + 0.9696837068 0.9494658709 0.8717142940 + 0.9698755741 0.9497591257 0.8723270893 + 0.9700676203 0.9500523210 0.8729398847 + 0.9702596068 0.9503493905 0.8735526204 + 0.9704515934 0.9506735206 0.8741654158 + 0.9706435204 0.9509977102 0.8747782111 + 0.9708371758 0.9513218999 0.8753908873 + 0.9710310102 0.9516459703 0.8760036826 + 0.9712247849 0.9519702196 0.8766164780 + 0.9714186192 0.9522942901 0.8772181273 + 0.9716123939 0.9526184797 0.8778185844 + 0.9718062282 0.9529427290 0.8784192204 + 0.9720000029 0.9532667994 0.8790197968 + 0.9721937776 0.9535914063 0.8796203136 + 0.9723876119 0.9539176226 0.8802208900 + 0.9725819230 0.9542437792 0.8808215261 + 0.9727863073 0.9545699954 0.8814219832 + 0.9729905725 0.9548962116 0.8820226192 + 0.9731948972 0.9552224278 0.8826230764 + 0.9733992815 0.9555485845 0.8832188249 + 0.9736036062 0.9558748007 0.8838123083 + 0.9738078713 0.9562010169 0.8844056726 + 0.9740121961 0.9565271735 0.8849992156 + 0.9742165804 0.9568511248 0.8855926991 + 0.9744209051 0.9571459889 0.8861861825 + 0.9746251702 0.9574409127 0.8867797256 + 0.9748240113 0.9577358961 0.8873730898 + 0.9750226736 0.9580308199 0.8879665732 + 0.9752213955 0.9583256841 0.8885601163 + 0.9754201770 0.9586207271 0.8891478777 + 0.9756188989 0.9589155912 0.8897228837 + 0.9758176208 0.9592105150 0.8902978897 + 0.9760162830 0.9595054984 0.8908728957 + 0.9762151241 0.9598004222 0.8914479017 + 0.9764137864 0.9600865245 0.8920229077 + 0.9766125083 0.9603704214 0.8925979137 + 0.9767935276 0.9606543183 0.8931729198 + 0.9769693017 0.9609382749 0.8937479258 + 0.9771450758 0.9612221718 0.8943228722 + 0.9773209095 0.9615061283 0.8948978782 + 0.9774966836 0.9617900848 0.8954554200 + 0.9776725173 0.9620739818 0.8960071206 + 0.9778482914 0.9623578787 0.8965588808 + 0.9780241251 0.9626418948 0.8971105814 + 0.9781998992 0.9629204869 0.8976622820 + 0.9783756733 0.9631900191 0.8982141018 + 0.9785385132 0.9634596109 0.8987658024 + 0.9786810875 0.9637290835 0.8993175030 + 0.9788236022 0.9639986157 0.8998693228 + 0.9789661765 0.9642680883 0.9004210234 + 0.9791086912 0.9645376801 0.9009723067 + 0.9792513251 0.9648072124 0.9015076160 + 0.9793937802 0.9650766850 0.9020429850 + 0.9795364141 0.9653462172 0.9025782943 + 0.9796789289 0.9656158090 0.9031136036 + 0.9798215032 0.9658737183 0.9036489725 + 0.9799640179 0.9661279917 0.9041842818 + 0.9800881743 0.9663822055 0.9047195911 + 0.9802088141 0.9666364789 0.9052549005 + 0.9803295135 0.9668908119 0.9057903290 + 0.9804500937 0.9671450853 0.9063255787 + 0.9805706739 0.9673992991 0.9068583846 + 0.9806913733 0.9676535726 0.9073730111 + 0.9808120131 0.9679079056 0.9078876972 + 0.9809325933 0.9681621790 0.9084023237 + 0.9810532928 0.9684163928 0.9089170098 + 0.9811738729 0.9686573148 0.9094316959 + 0.9812927842 0.9688978791 0.9099463224 + 0.9813982248 0.9691385031 0.9104610085 + 0.9815034866 0.9693791270 0.9109755754 + 0.9816088080 0.9696196914 0.9114903212 + 0.9817141294 0.9698603153 0.9120050073 + 0.9818193913 0.9701009989 0.9125185013 + 0.9819247127 0.9703416228 0.9130074978 + 0.9820299745 0.9705821872 0.9134966135 + 0.9821352959 0.9708228111 0.9139856100 + 0.9822406173 0.9710630178 0.9144747257 + 0.9823458791 0.9712886810 0.9149637222 + 0.9824467897 0.9715144038 0.9154527783 + 0.9825308919 0.9717401266 0.9159417748 + 0.9826151133 0.9719656706 0.9164308906 + 0.9826992154 0.9721913934 0.9169198871 + 0.9827833176 0.9724171162 0.9174090028 + 0.9828674793 0.9726427794 0.9178979993 + 0.9829515815 0.9728683829 0.9183769822 + 0.9830356836 0.9730941057 0.9188531041 + 0.9831197858 0.9733198285 0.9193292260 + 0.9832040071 0.9735454917 0.9198052883 + 0.9832881093 0.9737340212 0.9202814102 + 0.9833707809 0.9739177823 0.9207574725 + 0.9834439754 0.9741016030 0.9212337136 + 0.9835172892 0.9742854238 0.9217097759 + 0.9835904837 0.9744691253 0.9221858978 + 0.9836636782 0.9746528864 0.9226620197 + 0.9837368727 0.9748367071 0.9231380820 + 0.9838101864 0.9750205278 0.9236043096 + 0.9838833809 0.9752042890 0.9240511060 + 0.9839565754 0.9753881097 0.9244979024 + 0.9840298891 0.9755718708 0.9249446988 + 0.9841030836 0.9757249951 0.9253914952 + 0.9841762781 0.9758548141 0.9258382916 + 0.9842556119 0.9759846926 0.9262850881 + 0.9843357205 0.9761145711 0.9267318249 + 0.9844158292 0.9762445092 0.9271786213 + 0.9844958782 0.9763743877 0.9276254177 + 0.9845761061 0.9765042067 0.9280722141 + 0.9846562147 0.9766340852 0.9285190105 + 0.9847363234 0.9767640233 0.9289492965 + 0.9848164916 0.9768939018 0.9293727875 + 0.9848966002 0.9770237803 0.9297962785 + 0.9849767089 0.9771535993 0.9302198291 + 0.9850568175 0.9772822857 0.9306433201 + 0.9851419926 0.9774109721 0.9310668111 + 0.9852340221 0.9775397778 0.9314903021 + 0.9853258729 0.9776685238 0.9319137931 + 0.9854179025 0.9777972102 0.9323372841 + 0.9855098724 0.9779258966 0.9327607751 + 0.9856017828 0.9780547023 0.9331843257 + 0.9856938124 0.9781833887 0.9336078167 + 0.9857857227 0.9783120751 0.9340065718 + 0.9858776927 0.9784408808 0.9344022870 + 0.9859697223 0.9785696268 0.9347980022 + 0.9860615730 0.9787036777 0.9351937175 + 0.9861536026 0.9788467884 0.9355893731 + 0.9862487912 0.9789898992 0.9359850883 + 0.9863448143 0.9791330099 0.9363806844 + 0.9864408970 0.9792761207 0.9367763996 + 0.9865369201 0.9794191718 0.9371721148 + 0.9866328835 0.9795622230 0.9375677705 + 0.9867290258 0.9797052741 0.9379634857 + 0.9868249893 0.9798483849 0.9383592010 + 0.9869210124 0.9799914956 0.9387403131 + 0.9870170951 0.9801346064 0.9391192794 + 0.9871131182 0.9802777171 0.9394981861 + 0.9872090816 0.9804211855 0.9398772120 + 0.9873052239 0.9805650711 0.9402561784 + 0.9874122143 0.9807090163 0.9406352043 + 0.9875195026 0.9808530211 0.9410141706 + 0.9876267910 0.9809969068 0.9413931966 + 0.9877340198 0.9811409116 0.9417721033 + 0.9878413081 0.9812847972 0.9421511292 + 0.9879485965 0.9814286828 0.9425300956 + 0.9880558848 0.9815726876 0.9429091215 + 0.9881631136 0.9817165732 0.9432799816 + 0.9882704020 0.9818605781 0.9436467290 + 0.9883776903 0.9820045233 0.9440134168 + 0.9884849787 0.9821479917 0.9443802238 + 0.9885923266 0.9822906852 0.9447469115 + 0.9887036085 0.9824334979 0.9451135993 + 0.9888151288 0.9825763106 0.9454804063 + 0.9889264703 0.9827191234 0.9458470941 + 0.9890379906 0.9828618765 0.9462139010 + 0.9891495109 0.9830046892 0.9465805888 + 0.9892609715 0.9831475019 0.9469472766 + 0.9893724918 0.9832903147 0.9473140836 + 0.9894838929 0.9834331274 0.9476754069 + 0.9895954132 0.9835758805 0.9480211139 + 0.9897068739 0.9837186933 0.9483667016 + 0.9898183942 0.9838594198 0.9487122893 + 0.9899299145 0.9839885831 0.9490579963 + 0.9900401235 0.9841178060 0.9494035840 + 0.9901499152 0.9842470884 0.9497491717 + 0.9902598262 0.9843763113 0.9500948787 + 0.9903696179 0.9845055938 0.9504405260 + 0.9904795289 0.9846348166 0.9507861137 + 0.9905893207 0.9847640991 0.9511318207 + 0.9906991124 0.9848933220 0.9514774084 + 0.9908090234 0.9850226045 0.9518229961 + 0.9909188151 0.9851518273 0.9521476030 + 0.9910287261 0.9852811098 0.9524605274 + 0.9911385179 0.9854102731 0.9527733922 + 0.9912483096 0.9855383039 0.9530863166 + 0.9913557172 0.9856656790 0.9533991814 + 0.9914582968 0.9857931137 0.9537121058 + 0.9915608764 0.9859204888 0.9540249705 + 0.9916635156 0.9860478044 0.9543378949 + 0.9917660952 0.9861751795 0.9546508193 + 0.9918686748 0.9863026142 0.9549636841 + 0.9919713140 0.9864299893 0.9552766085 + 0.9920738935 0.9865574241 0.9555894732 + 0.9921764731 0.9866846800 0.9559023976 + 0.9922791123 0.9868121147 0.9562044144 + 0.9923816919 0.9869394898 0.9565039873 + 0.9924842715 0.9870668054 0.9568036795 + 0.9925869107 0.9871830940 0.9571033120 + 0.9926795959 0.9872993827 0.9574030042 + 0.9927687049 0.9874156713 0.9577025771 + 0.9928578734 0.9875320196 0.9580023289 + 0.9929469824 0.9876484275 0.9583019018 + 0.9930362105 0.9877647161 0.9586015940 + 0.9931253195 0.9878810048 0.9589012265 + 0.9932144880 0.9879972935 0.9592009187 + 0.9933035970 0.9881135821 0.9595004916 + 0.9933928251 0.9882298708 0.9598001838 + 0.9934818745 0.9883462787 0.9600859880 + 0.9935711026 0.9884626269 0.9603683949 + 0.9936602116 0.9885759950 0.9606508017 + 0.9937493801 0.9886701107 0.9609330893 + 0.9938194156 0.9887642264 0.9612154961 + 0.9938877821 0.9888582230 0.9614979029 + 0.9939562082 0.9889522791 0.9617803097 + 0.9940245748 0.9890463948 0.9620627165 + 0.9940930009 0.9891405106 0.9623451233 + 0.9941614866 0.9892346263 0.9626274109 + 0.9942299128 0.9893286228 0.9629098177 + 0.9942982793 0.9894226789 0.9631922245 + 0.9943667054 0.9895167947 0.9634745717 + 0.9944350719 0.9896109104 0.9637439251 + 0.9945034981 0.9897050261 0.9640030265 + 0.9945719838 0.9897977114 0.9642621875 + 0.9946404099 0.9898560047 0.9645212889 + 0.9946832061 0.9899142981 0.9647803903 + 0.9947232008 0.9899725914 0.9650396109 + 0.9947631955 0.9900308847 0.9652987123 + 0.9948033094 0.9900891781 0.9655578732 + 0.9948433042 0.9901474714 0.9658169746 + 0.9948832989 0.9902058244 0.9660760760 + 0.9949232936 0.9902641177 0.9663352966 + 0.9949632883 0.9903224111 0.9665943980 + 0.9950032830 0.9903807044 0.9668534994 + 0.9950432777 0.9904391170 0.9671121836 + 0.9950833917 0.9904974103 0.9673674703 + 0.9951233864 0.9905557036 0.9676228166 + 0.9951633811 0.9905830026 0.9678779840 + 0.9951838851 0.9905992150 0.9681332707 + 0.9951946735 0.9906154275 0.9683884978 + 0.9952054024 0.9906315804 0.9686437845 + 0.9952160716 0.9906477928 0.9688990116 + 0.9952269197 0.9906640053 0.9691542983 + 0.9952375889 0.9906800985 0.9694095254 + 0.9952483177 0.9906963110 0.9696648121 + 0.9952589869 0.9907125235 0.9699200988 + 0.9952697754 0.9907286763 0.9701753259 + 0.9952805042 0.9907448888 0.9704306126 + 0.9952911735 0.9907611012 0.9706832170 + 0.9953020215 0.9907773137 0.9709324241 + 0.9953126907 0.9907947183 0.9711815715 + 0.9953212142 0.9908165932 0.9714307785 + 0.9953212142 0.9908384085 0.9716799855 + 0.9953212142 0.9908602834 0.9719290733 + 0.9953212142 0.9908822179 0.9721782804 + 0.9953212142 0.9909040928 0.9724274874 + 0.9953212142 0.9909260273 0.9726766944 + 0.9953212142 0.9909479022 0.9729259014 + 0.9953212142 0.9909697771 0.9731751084 + 0.9953212142 0.9909917116 0.9734243155 + 0.9953212142 0.9910135865 0.9736735225 + 0.9953212142 0.9910355210 0.9739227295 + 0.9953212142 0.9910573959 0.9741604924 + 0.9953212142 0.9910792708 0.9743885994 + 0.9953212142 0.9911091924 0.9746165872 + 0.9953212142 0.9911481738 0.9748446941 + 0.9953212142 0.9911870956 0.9750726819 + 0.9953212142 0.9912260771 0.9753007889 + 0.9953212142 0.9912649989 0.9755288959 + 0.9953212142 0.9913039804 0.9757568836 + 0.9953212142 0.9913429022 0.9759849906 + 0.9953212142 0.9913818836 0.9762129784 + 0.9953212142 0.9914208055 0.9764410853 + 0.9953212142 0.9914597869 0.9766690731 + 0.9953212142 0.9914987087 0.9768971801 + 0.9953212142 0.9915376902 0.9771252871 + 0.9953212142 0.9915766120 0.9773470759 + 0.9953212142 0.9916155934 0.9775602818 + 0.9953212142 0.9916595817 0.9777734280 + 0.9953212142 0.9917085767 0.9779865742 + 0.9953212142 0.9917575717 0.9781997800 + 0.9953212142 0.9918066263 0.9784129262 + 0.9953212142 0.9918555021 0.9786260724 + 0.9953212142 0.9919044971 0.9788392186 + 0.9953212142 0.9919534922 0.9790524244 + 0.9953212142 0.9920024872 0.9792655706 + 0.9953212142 0.9920514822 0.9794787169 + 0.9953212142 0.9921004176 0.9796919227 + 0.9953212142 0.9921494126 0.9799050093 + 0.9953212142 0.9921984076 0.9801182151 + 0.9953212142 0.9922474027 0.9803304076 + 0.9953212142 0.9922963977 0.9805278778 + 0.9953212142 0.9923471808 0.9807254076 + 0.9953224063 0.9924020767 0.9809228182 + 0.9953249097 0.9924570918 0.9811202884 + 0.9953272939 0.9925119877 0.9813178182 + 0.9953297973 0.9925670028 0.9815152884 + 0.9953323007 0.9926218987 0.9817128181 + 0.9953346848 0.9926769137 0.9819102883 + 0.9953371882 0.9927318096 0.9821078181 + 0.9953395724 0.9927868247 0.9823052883 + 0.9953420758 0.9928417206 0.9825028181 + 0.9953445196 0.9928966761 0.9827002287 + 0.9953470230 0.9929515719 0.9828976989 + 0.9953494072 0.9930065870 0.9830952287 + 0.9953519106 0.9930614829 0.9832865000 + 0.9953542948 0.9931164980 0.9834707975 + 0.9953567982 0.9931734204 0.9836549759 + 0.9953591824 0.9932305217 0.9838392735 + 0.9953616858 0.9932876825 0.9840235710 + 0.9953641891 0.9933447838 0.9842079282 + 0.9953665733 0.9934020042 0.9843922257 + 0.9953690767 0.9934591055 0.9845765233 + 0.9953715205 0.9935163260 0.9847608209 + 0.9953740239 0.9935734272 0.9849451184 + 0.9953764081 0.9936305881 0.9851294160 + 0.9953789115 0.9936876893 0.9853137136 + 0.9953812957 0.9937449098 0.9854980111 + 0.9953837991 0.9938020110 0.9856823087 + 0.9953861833 0.9938591719 0.9858666062 + 0.9953886867 0.9939162731 0.9860420227 + 0.9953911901 0.9939727783 0.9862126112 + 0.9953935742 0.9940270185 0.9863831997 + 0.9953960776 0.9940811992 0.9865537882 + 0.9953985214 0.9941353798 0.9867243767 + 0.9954010248 0.9941896200 0.9868950248 + 0.9954034090 0.9942439198 0.9870656133 + 0.9954059124 0.9942981005 0.9872363210 + 0.9954082966 0.9943522811 0.9874069095 + 0.9954108000 0.9944065213 0.9875774980 + 0.9954131842 0.9944607019 0.9877480865 + 0.9954156876 0.9945148826 0.9879186749 + 0.9954180717 0.9945691228 0.9880893230 + 0.9954205751 0.9946233034 0.9882599115 + 0.9954230785 0.9946774840 0.9884305000 + 0.9954255223 0.9947317243 0.9885919094 + 0.9954280257 0.9947829843 0.9887465835 + 0.9954304099 0.9948282242 0.9889013767 + 0.9954329133 0.9948732853 0.9890561104 + 0.9954352975 0.9949185252 0.9892109036 + 0.9954378009 0.9949635863 0.9893655777 + 0.9954401851 0.9950088263 0.9895203114 + 0.9954426885 0.9950540066 0.9896751046 + 0.9954450727 0.9950991273 0.9898297787 + 0.9954475760 0.9951443076 0.9899845719 + 0.9954500198 0.9951894283 0.9901393056 + 0.9954525232 0.9952346087 0.9902940989 + 0.9954550266 0.9952797890 0.9904487729 + 0.9954574108 0.9953249097 0.9906036258 + 0.9954599142 0.9953700900 0.9907582998 + 0.9954622984 0.9954152107 0.9909070134 + 0.9954648018 0.9954605103 0.9910390973 + 0.9954801202 0.9955064058 0.9911711812 + 0.9955012202 0.9955521822 0.9913033247 + 0.9955222011 0.9955980778 0.9914354086 + 0.9955431819 0.9956439137 0.9915674925 + 0.9955642223 0.9956898093 0.9916995764 + 0.9955853224 0.9957355857 0.9918317199 + 0.9956063032 0.9957814813 0.9919638038 + 0.9956272840 0.9958273172 0.9920958877 + 0.9956483245 0.9958732128 0.9922279716 + 0.9956693053 0.9959189892 0.9923601151 + 0.9956904054 0.9959648848 0.9924923182 + 0.9957113862 0.9960107207 0.9926244020 + 0.9957324266 0.9960566163 0.9927564859 + 0.9957534075 0.9961023927 0.9928886294 + 0.9957743883 0.9961482882 0.9930137992 + 0.9957994223 0.9961935878 0.9931361079 + 0.9958305955 0.9962387085 0.9932584167 + 0.9958618283 0.9962838292 0.9933807254 + 0.9958930016 0.9963290095 0.9935030937 + 0.9959241748 0.9963740706 0.9936254025 + 0.9959552884 0.9964193106 0.9937477112 + 0.9959865212 0.9964643717 0.9938700199 + 0.9960176945 0.9965096116 0.9939923882 + 0.9960489273 0.9965546727 0.9941146970 + 0.9960801005 0.9965999126 0.9942370057 + 0.9961112738 0.9966449738 0.9943593144 + 0.9961425066 0.9966902137 0.9944816828 + 0.9961736798 0.9967352748 0.9946039915 + 0.9962049127 0.9967803955 0.9947263002 + 0.9962360859 0.9968255758 0.9948486090 + 0.9962673187 0.9968703985 0.9949529171 + 0.9963043928 0.9969134927 0.9950549006 + 0.9963427782 0.9969565868 0.9951568842 + 0.9963811040 0.9969998002 0.9952589273 + 0.9964194894 0.9970428944 0.9953609109 + 0.9964578152 0.9970859885 0.9954628944 + 0.9964962006 0.9971290827 0.9955649972 + 0.9965345263 0.9971721768 0.9956669807 + 0.9965729117 0.9972152710 0.9957690239 + 0.9966111779 0.9972584248 0.9958710074 + 0.9966496229 0.9973015189 0.9959729910 + 0.9966878891 0.9973446131 0.9960749745 + 0.9967262745 0.9973878264 0.9961770177 + 0.9967646003 0.9974309206 0.9962790012 + 0.9968029857 0.9974740148 0.9963809848 + 0.9968413115 0.9975171089 0.9964830279 + 0.9968796968 0.9975619912 0.9965667129 + 0.9969285727 0.9976121783 0.9966462255 + 0.9969775081 0.9976624250 0.9967256784 + 0.9970263839 0.9977126122 0.9968051910 + 0.9970752001 0.9977626801 0.9968847036 + 0.9971240759 0.9978129268 0.9969642162 + 0.9971730113 0.9978631139 0.9970437884 + 0.9972218871 0.9979133010 0.9971233010 + 0.9972707033 0.9979634285 0.9972028136 + 0.9973195791 0.9980136156 0.9972823262 + 0.9973685145 0.9980638027 0.9973617792 + 0.9974173903 0.9981139898 0.9974412918 + 0.9974662066 0.9981641769 0.9975208044 + 0.9975150824 0.9982143044 0.9976003170 + 0.9975640178 0.9982644916 0.9976798296 + 0.9976128936 0.9983146787 0.9977592826 + 0.9976617098 0.9983649850 0.9978352189 + 0.9977235794 0.9984163046 0.9979071021 + 0.9977864027 0.9984676242 0.9979789257 + 0.9978492260 0.9985188842 0.9980508089 + 0.9979119897 0.9985702038 0.9981226921 + 0.9979748130 0.9986215234 0.9981945157 + 0.9980375767 0.9986727834 0.9982663989 + 0.9981004000 0.9987241030 0.9983382821 + 0.9981632233 0.9987754226 0.9984102249 + 0.9982259870 0.9988266826 0.9984819889 + 0.9982886910 0.9988780022 0.9985538721 + 0.9983515143 0.9989293218 0.9986258149 + 0.9984142780 0.9989805818 0.9986975789 + 0.9984771013 0.9990319014 0.9987695217 + 0.9985399246 0.9990832210 0.9988414049 + 0.9986026883 0.9991344810 0.9989132881 + 0.9986655116 0.9991858006 0.9989851117 + 0.9987378716 0.9992346764 0.9990463257 + 0.9988167882 0.9992824793 0.9991058707 + 0.9988957047 0.9993302822 0.9991654754 + 0.9989746213 0.9993782043 0.9992250800 + 0.9990534782 0.9994260073 0.9992846847 + 0.9991322756 0.9994738102 0.9993442893 + 0.9992111921 0.9995216727 0.9994038939 + 0.9992901087 0.9995694757 0.9994634986 + 0.9993690252 0.9996172786 0.9995231032 + 0.9994478226 0.9996652007 0.9995828271 + 0.9995266795 0.9997130036 0.9996423721 + 0.9996055961 0.9997608066 0.9997019768 + 0.9996845126 0.9998087287 0.9997615814 + 0.9997634292 0.9998564720 0.9998211861 + 0.9998422265 0.9999042749 0.9998807907 + 0.9999210835 0.9999521971 0.9999403954 + 1.0000000000 1.0000000000 1.0000000000 +} diff --git a/rpplugins/color_correction/resources/film_luts_raw/kodak_ektachrome_64.spi1d b/rpplugins/color_correction/resources/film_luts_raw/kodak_ektachrome_64.spi1d new file mode 100644 index 0000000..31d4b94 --- /dev/null +++ b/rpplugins/color_correction/resources/film_luts_raw/kodak_ektachrome_64.spi1d @@ -0,0 +1,1030 @@ +Version 1 +From 0.0 1.0 +Length 1024 +Components 3 +{ + 0.0000000000 0.0000000000 0.0000000000 + 0.0003177276 0.0001941380 0.0001446141 + 0.0006504654 0.0003951061 0.0002949580 + 0.0010024470 0.0006061521 0.0004526987 + 0.0013694729 0.0008284810 0.0006180415 + 0.0017452050 0.0010607000 0.0007899137 + 0.0021349210 0.0013002760 0.0009697909 + 0.0025417069 0.0015479270 0.0011566620 + 0.0029633259 0.0018080650 0.0013511210 + 0.0033958510 0.0020795320 0.0015535100 + 0.0038457969 0.0023645640 0.0017640300 + 0.0043162489 0.0026637421 0.0019820260 + 0.0048077060 0.0029760071 0.0022097649 + 0.0053204661 0.0033004310 0.0024460619 + 0.0058609000 0.0036376549 0.0026919940 + 0.0064359619 0.0039854120 0.0029474010 + 0.0070374971 0.0043447139 0.0032128871 + 0.0076601300 0.0047178762 0.0034874950 + 0.0083078844 0.0051065790 0.0037723500 + 0.0089809727 0.0055108499 0.0040672510 + 0.0096816579 0.0059318668 0.0043718130 + 0.0104107000 0.0063705379 0.0046862401 + 0.0111686802 0.0068254122 0.0050117052 + 0.0119535998 0.0072979759 0.0053493860 + 0.0127734104 0.0077873981 0.0056989561 + 0.0136253396 0.0082948767 0.0060607451 + 0.0145092504 0.0088192495 0.0064340578 + 0.0154185202 0.0093626482 0.0068193851 + 0.0163518004 0.0099276053 0.0072161448 + 0.0173176397 0.0105159301 0.0076254872 + 0.0183163304 0.0111296400 0.0080476142 + 0.0193513595 0.0117682600 0.0084802704 + 0.0204212200 0.0124294702 0.0089247832 + 0.0215315297 0.0131156798 0.0093830954 + 0.0226835497 0.0138275698 0.0098542161 + 0.0238747206 0.0145641901 0.0103377597 + 0.0251002200 0.0153265698 0.0108324597 + 0.0263673309 0.0161136203 0.0113382703 + 0.0276758503 0.0169268306 0.0118559897 + 0.0290231593 0.0177657008 0.0123869004 + 0.0304085892 0.0186326504 0.0129301697 + 0.0318260118 0.0195293408 0.0134853199 + 0.0332819484 0.0204478092 0.0140506905 + 0.0347733498 0.0213932004 0.0146252401 + 0.0363029502 0.0223640501 0.0152128004 + 0.0378724001 0.0233600903 0.0158141498 + 0.0394730903 0.0243795607 0.0164301693 + 0.0411083102 0.0254261997 0.0170600507 + 0.0427853093 0.0264967792 0.0177041702 + 0.0444947183 0.0275935791 0.0183603093 + 0.0462447405 0.0287111904 0.0190260392 + 0.0480214991 0.0298579894 0.0197018404 + 0.0498294383 0.0310345795 0.0203909706 + 0.0516717583 0.0322387293 0.0210961197 + 0.0535553694 0.0334732905 0.0218155701 + 0.0554724000 0.0347375497 0.0225481000 + 0.0574280284 0.0360305011 0.0232938007 + 0.0594230108 0.0373505987 0.0240523200 + 0.0614495687 0.0386989899 0.0248243101 + 0.0635085627 0.0400783718 0.0256102104 + 0.0656058565 0.0414873511 0.0264102798 + 0.0677408203 0.0429296084 0.0272227693 + 0.0699115321 0.0444077104 0.0280466098 + 0.0721197501 0.0459156111 0.0288844202 + 0.0743607506 0.0474466383 0.0297372099 + 0.0766320974 0.0490012988 0.0306023601 + 0.0789411888 0.0505829789 0.0314776190 + 0.0812913403 0.0521959811 0.0323632210 + 0.0836748034 0.0538401082 0.0332610384 + 0.0860934034 0.0555139296 0.0341722593 + 0.0885434672 0.0572180599 0.0350961611 + 0.0910215825 0.0589511804 0.0360324383 + 0.0935282633 0.0607071407 0.0369832404 + 0.0960653424 0.0624810904 0.0379483290 + 0.0986272693 0.0642725229 0.0389264598 + 0.1012184024 0.0660862923 0.0399172194 + 0.1038417965 0.0679221675 0.0409205295 + 0.1064930037 0.0697782189 0.0419377983 + 0.1091663986 0.0716602802 0.0429698490 + 0.1118554026 0.0735708624 0.0440155715 + 0.1145604029 0.0755072236 0.0450732484 + 0.1172852963 0.0774691924 0.0461424887 + 0.1200316027 0.0794569179 0.0472251885 + 0.1228056028 0.0814680681 0.0483251885 + 0.1256061941 0.0835034922 0.0494407713 + 0.1284314990 0.0855652988 0.0505689494 + 0.1312845945 0.0876543671 0.0517092496 + 0.1341657043 0.0897689089 0.0528627299 + 0.1370669007 0.0919097364 0.0540304407 + 0.1399842948 0.0940792933 0.0552122705 + 0.1429264992 0.0962784812 0.0564116687 + 0.1458958983 0.0985052586 0.0576241314 + 0.1488838047 0.1007623002 0.0588485189 + 0.1518885940 0.1030460969 0.0600855909 + 0.1549195051 0.1053560004 0.0613366812 + 0.1579769999 0.1076906994 0.0626053810 + 0.1610527933 0.1100478992 0.0638882369 + 0.1641492993 0.1124247015 0.0651839301 + 0.1672637016 0.1148206964 0.0664921403 + 0.1703891009 0.1172372997 0.0678140298 + 0.1735228002 0.1196703017 0.0691531822 + 0.1766714007 0.1221214011 0.0705029890 + 0.1798343062 0.1245933995 0.0718628988 + 0.1830091029 0.1270965040 0.0732344314 + 0.1861923933 0.1296184957 0.0746224895 + 0.1893824935 0.1321596056 0.0760240182 + 0.1925912052 0.1347205937 0.0774392113 + 0.1958242953 0.1373080015 0.0788744465 + 0.1990808994 0.1399126947 0.0803256184 + 0.2023572028 0.1425279975 0.0817875490 + 0.2056479007 0.1451531053 0.0832600370 + 0.2089466006 0.1477964967 0.0847453102 + 0.2122559994 0.1504597068 0.0862387866 + 0.2155746967 0.1531386971 0.0877406523 + 0.2189022005 0.1558340043 0.0892590731 + 0.2222436965 0.1585476995 0.0907859504 + 0.2255931050 0.1612742990 0.0923209935 + 0.2289551944 0.1640138030 0.0938680470 + 0.2323365957 0.1667792052 0.0954221934 + 0.2357338965 0.1695535034 0.0969835818 + 0.2391352057 0.1723369062 0.0985596627 + 0.2425421029 0.1751406044 0.1001449004 + 0.2459709942 0.1779552996 0.1017419994 + 0.2494048029 0.1807786971 0.1033572033 + 0.2528398931 0.1836172044 0.1049804986 + 0.2562730014 0.1864625067 0.1066166982 + 0.2597048879 0.1893129051 0.1082694978 + 0.2631390095 0.1921741962 0.1099312007 + 0.2665784955 0.1950452030 0.1116095036 + 0.2700111866 0.1979237944 0.1132924035 + 0.2734400928 0.2008170038 0.1149808988 + 0.2768634856 0.2037173063 0.1166793033 + 0.2802909017 0.2066275030 0.1183826998 + 0.2837207019 0.2095531970 0.1201020032 + 0.2871545851 0.2124857008 0.1218283027 + 0.2905927896 0.2154320031 0.1235624999 + 0.2940321863 0.2183827013 0.1253096014 + 0.2974657118 0.2213367969 0.1270615011 + 0.3008908927 0.2242961973 0.1288305074 + 0.3043087125 0.2272599936 0.1306017935 + 0.3077211082 0.2302363962 0.1323782951 + 0.3111295104 0.2332222015 0.1341592073 + 0.3145295084 0.2362163067 0.1359436959 + 0.3179244995 0.2392161936 0.1377421021 + 0.3213168085 0.2422180027 0.1395442933 + 0.3247092962 0.2452265024 0.1413614005 + 0.3281050920 0.2482353002 0.1431804001 + 0.3315083981 0.2512444854 0.1450074017 + 0.3348960876 0.2542502880 0.1468372047 + 0.3382737041 0.2572538853 0.1486722976 + 0.3416486979 0.2602624893 0.1505120993 + 0.3450245857 0.2632722855 0.1523568034 + 0.3484072983 0.2662931085 0.1542067975 + 0.3517858982 0.2693150043 0.1560602039 + 0.3551585078 0.2723414004 0.1579221934 + 0.3585281074 0.2753702104 0.1597875059 + 0.3618960977 0.2784039080 0.1616556942 + 0.3652538955 0.2814370096 0.1635244936 + 0.3686091900 0.2844694853 0.1653988063 + 0.3719412088 0.2874999940 0.1672738940 + 0.3752706051 0.2905291021 0.1691565067 + 0.3785892129 0.2935574949 0.1710398048 + 0.3819032013 0.2965855002 0.1729318947 + 0.3852080107 0.2996020913 0.1748245955 + 0.3885084093 0.3026154935 0.1767162979 + 0.3918038011 0.3056125045 0.1786078960 + 0.3950856030 0.3086062074 0.1804991066 + 0.3983576894 0.3115797043 0.1823901981 + 0.4016107023 0.3145501018 0.1842828989 + 0.4048540890 0.3175120950 0.1861757934 + 0.4080660939 0.3204728961 0.1880692989 + 0.4112665951 0.3234159946 0.1899631023 + 0.4144412875 0.3263562918 0.1918607950 + 0.4176087081 0.3292810023 0.1937602013 + 0.4207499921 0.3322027028 0.1956637949 + 0.4238848984 0.3351123035 0.1975702047 + 0.4270057082 0.3380188048 0.1994725019 + 0.4301230907 0.3409165144 0.2013705969 + 0.4332121015 0.3438107073 0.2032697052 + 0.4362936020 0.3467020988 0.2051707059 + 0.4393599927 0.3495917916 0.2070730031 + 0.4424214065 0.3524695039 0.2089823037 + 0.4454444051 0.3553349078 0.2108915001 + 0.4484499991 0.3581919074 0.2128047943 + 0.4514287114 0.3610335886 0.2147184014 + 0.4543898106 0.3638724089 0.2166287005 + 0.4573354125 0.3666979969 0.2185377926 + 0.4602653980 0.3695237041 0.2204501927 + 0.4631789029 0.3723416924 0.2223664969 + 0.4660640955 0.3751595914 0.2242840976 + 0.4689424038 0.3779619932 0.2262071967 + 0.4717960060 0.3807600141 0.2281304002 + 0.4746480882 0.3835526109 0.2300624996 + 0.4774642885 0.3863407075 0.2319957018 + 0.4802804887 0.3891260922 0.2339314967 + 0.4830631018 0.3919047117 0.2358691990 + 0.4858393073 0.3946832120 0.2378090024 + 0.4886021912 0.3974429071 0.2397564054 + 0.4913567901 0.4002025127 0.2417037040 + 0.4941014051 0.4029656053 0.2436508983 + 0.4968290031 0.4057300985 0.2455980927 + 0.4995543063 0.4084877074 0.2475478053 + 0.5022572875 0.4112327099 0.2495003939 + 0.5049604177 0.4139777124 0.2514531016 + 0.5076419115 0.4167033136 0.2534070015 + 0.5103181005 0.4194287956 0.2553609014 + 0.5129829049 0.4221394062 0.2573103011 + 0.5156350732 0.4248403907 0.2592563927 + 0.5182831287 0.4275377989 0.2612015903 + 0.5209032893 0.4302201867 0.2631373107 + 0.5235236287 0.4329026937 0.2650730908 + 0.5261074901 0.4355578125 0.2670041025 + 0.5286799073 0.4382039905 0.2689318061 + 0.5312321782 0.4408400953 0.2708589137 + 0.5337486863 0.4434512854 0.2727747858 + 0.5362653136 0.4460625947 0.2746906877 + 0.5387454033 0.4486452043 0.2766082883 + 0.5412231088 0.4512208104 0.2785277963 + 0.5436828136 0.4537886977 0.2804473042 + 0.5461235046 0.4563367963 0.2823554873 + 0.5485640168 0.4588850141 0.2842623889 + 0.5509892702 0.4614095986 0.2861675918 + 0.5534147024 0.4639258087 0.2880688012 + 0.5558288097 0.4664359093 0.2899698913 + 0.5582318902 0.4689145088 0.2918665111 + 0.5606350899 0.4713929892 0.2937605083 + 0.5629963875 0.4738500118 0.2956545055 + 0.5653566718 0.4762899876 0.2975474000 + 0.5677015781 0.4787299931 0.2994402945 + 0.5700250864 0.4811362922 0.3013291955 + 0.5723484755 0.4835399985 0.3032068908 + 0.5746430159 0.4859381914 0.3050845861 + 0.5769314766 0.4883219898 0.3069567978 + 0.5792130232 0.4907056987 0.3088240921 + 0.5814688802 0.4930708110 0.3106913865 + 0.5837246776 0.4954228103 0.3125565946 + 0.5859628916 0.4977746904 0.3144212067 + 0.5881881118 0.5000953078 0.3162856996 + 0.5904132128 0.5024111271 0.3181492090 + 0.5926191807 0.5047224760 0.3200125992 + 0.5948230028 0.5070027113 0.3218753934 + 0.5970178246 0.5092828870 0.3237349093 + 0.5991765857 0.5115441084 0.3255943954 + 0.6013354063 0.5137696862 0.3274545968 + 0.6034780741 0.5159952044 0.3293164074 + 0.6056026816 0.5182105899 0.3311783075 + 0.6077274084 0.5204172730 0.3330385983 + 0.6098302007 0.5226240754 0.3348967135 + 0.6119242907 0.5248165131 0.3367548883 + 0.6140184999 0.5270028710 0.3386108875 + 0.6160811782 0.5291892886 0.3404648006 + 0.6181414723 0.5313519239 0.3423185945 + 0.6201986074 0.5335099101 0.3441708982 + 0.6222298145 0.5356678963 0.3460218906 + 0.6242610812 0.5378025174 0.3478729129 + 0.6262831092 0.5399355888 0.3497231901 + 0.6282786727 0.5420684218 0.3515729904 + 0.6302741766 0.5441771150 0.3534227014 + 0.6322615147 0.5462856889 0.3552713096 + 0.6342349052 0.5483934283 0.3571187854 + 0.6362084150 0.5504837036 0.3589664102 + 0.6381633878 0.5525740981 0.3608083129 + 0.6400970817 0.5546634793 0.3626450896 + 0.6420307159 0.5567383170 0.3644818962 + 0.6439446807 0.5588130951 0.3663117886 + 0.6458404064 0.5608872771 0.3681330979 + 0.6477361917 0.5629431009 0.3699544966 + 0.6496070027 0.5649988055 0.3717769086 + 0.6514570713 0.5670546293 0.3736014068 + 0.6533071995 0.5690968037 0.3754259944 + 0.6551311016 0.5711386800 0.3772482872 + 0.6569324732 0.5731804967 0.3790614903 + 0.6587339044 0.5751888156 0.3808746040 + 0.6605200768 0.5771927238 0.3826875985 + 0.6622908711 0.5791965723 0.3844920993 + 0.6640617251 0.5811750889 0.3862965107 + 0.6658166051 0.5831453800 0.3881008923 + 0.6675499082 0.5851157904 0.3898971975 + 0.6692832112 0.5870721936 0.3916915953 + 0.6710019112 0.5890191197 0.3934859037 + 0.6726891994 0.5909659863 0.3952794969 + 0.6743766069 0.5928977728 0.3970726132 + 0.6760562062 0.5948076248 0.3988656104 + 0.6776999831 0.5967172980 0.4006549120 + 0.6793438196 0.5986235142 0.4024339914 + 0.6809874177 0.6005135775 0.4042131007 + 0.6826078892 0.6024037004 0.4059922099 + 0.6842284203 0.6042937040 0.4077546000 + 0.6858488917 0.6061664820 0.4095160961 + 0.6874536872 0.6080377102 0.4112777114 + 0.6890544891 0.6099088788 0.4130330980 + 0.6906551719 0.6117550135 0.4147844911 + 0.6922481060 0.6135854721 0.4165357947 + 0.6938346028 0.6154159904 0.4182860851 + 0.6954210997 0.6172372103 0.4200322032 + 0.6969972849 0.6190348268 0.4217784107 + 0.6985461712 0.6208323240 0.4235245883 + 0.7000951767 0.6226298809 0.4252654016 + 0.7016441226 0.6243864298 0.4270048141 + 0.7031658292 0.6261391044 0.4287441969 + 0.7046864033 0.6278917193 0.4304836094 + 0.7062069774 0.6296277046 0.4322234094 + 0.7077113986 0.6313474774 0.4339630902 + 0.7092053294 0.6330673099 0.4357028008 + 0.7106992006 0.6347842813 0.4374335110 + 0.7121831179 0.6364610791 0.4391623139 + 0.7136318088 0.6381378770 0.4408909976 + 0.7150804996 0.6398146749 0.4426156878 + 0.7165293097 0.6414784789 0.4443300068 + 0.7179604173 0.6431329846 0.4460442066 + 0.7193871140 0.6447873712 0.4477584064 + 0.7208138108 0.6464402080 0.4494678080 + 0.7222303152 0.6480689049 0.4511752129 + 0.7236266732 0.6496976018 0.4528824985 + 0.7250230908 0.6513261795 0.4545893967 + 0.7264196277 0.6529368162 0.4562911987 + 0.7277973294 0.6545298100 0.4579930007 + 0.7291715741 0.6561228037 0.4596947134 + 0.7305458188 0.6577157974 0.4613985121 + 0.7319157720 0.6592859030 0.4631048143 + 0.7332760096 0.6608538032 0.4648110867 + 0.7346363068 0.6624217033 0.4665173888 + 0.7359964848 0.6639863253 0.4682199955 + 0.7373399734 0.6655421257 0.4699214101 + 0.7386773825 0.6670979857 0.4716227055 + 0.7400146723 0.6686539054 0.4733240902 + 0.7413491011 0.6702005863 0.4750083089 + 0.7426620722 0.6717411876 0.4766924977 + 0.7439751029 0.6732819080 0.4783768058 + 0.7452880740 0.6748226285 0.4800589979 + 0.7465865016 0.6763488054 0.4817341864 + 0.7478682995 0.6778733134 0.4834094048 + 0.7491500974 0.6793978214 0.4850845933 + 0.7504318953 0.6809164882 0.4867551029 + 0.7516843081 0.6823992729 0.4884186983 + 0.7529281974 0.6838821173 0.4900822937 + 0.7541720867 0.6853649020 0.4917457998 + 0.7554147243 0.6868361831 0.4934011996 + 0.7566283941 0.6882851720 0.4950498044 + 0.7578421831 0.6897342205 0.4966984093 + 0.7590559721 0.6911832094 0.4983471036 + 0.7602614760 0.6926218867 0.4999813139 + 0.7614449263 0.6940507293 0.5016077161 + 0.7626283765 0.6954795122 0.5032340884 + 0.7638118267 0.6969082952 0.5048604012 + 0.7649738789 0.6983196139 0.5064805746 + 0.7661107183 0.6997205019 0.5080981851 + 0.7672476172 0.7011213899 0.5097157955 + 0.7683845162 0.7025222778 0.5113334060 + 0.7695062757 0.7039136291 0.5129374266 + 0.7706182003 0.7053009868 0.5145360827 + 0.7717301250 0.7066884041 0.5161347985 + 0.7728418708 0.7080758810 0.5177333951 + 0.7739313245 0.7094560266 0.5193111897 + 0.7750114799 0.7108336091 0.5208796263 + 0.7760915756 0.7122113109 0.5224481225 + 0.7771716714 0.7135888934 0.5240164995 + 0.7782340050 0.7149400711 0.5255811214 + 0.7792907953 0.7162821293 0.5271432996 + 0.7803477049 0.7176241279 0.5287054777 + 0.7814046144 0.7189661264 0.5302677155 + 0.7824332118 0.7202813029 0.5318275094 + 0.7834541202 0.7215846181 0.5333846807 + 0.7844750285 0.7228879929 0.5349419713 + 0.7854959965 0.7241913080 0.5364993215 + 0.7865008712 0.7254747152 0.5380507708 + 0.7875007987 0.7267451286 0.5395910144 + 0.7885007858 0.7280154228 0.5411313176 + 0.7895007730 0.7292857170 0.5426715016 + 0.7904886007 0.7305502295 0.5442109704 + 0.7914711237 0.7318078876 0.5457459092 + 0.7924535871 0.7330656052 0.5472807288 + 0.7934361100 0.7343233228 0.5488154888 + 0.7943943143 0.7355695963 0.5503503084 + 0.7953352928 0.7367874980 0.5518705845 + 0.7962762713 0.7380053997 0.5533890128 + 0.7972173095 0.7392233014 0.5549073815 + 0.7981507182 0.7404392958 0.5564258099 + 0.7990738750 0.7416235209 0.5579320788 + 0.7999970913 0.7428076863 0.5594297051 + 0.8009203076 0.7439919710 0.5609273911 + 0.8018379807 0.7451761961 0.5624250174 + 0.8027368188 0.7463406920 0.5639188886 + 0.8036355972 0.7474998236 0.5654007196 + 0.8045343757 0.7486588955 0.5668826103 + 0.8054332137 0.7498180866 0.5683643818 + 0.8063105941 0.7509673834 0.5698462725 + 0.8071876168 0.7521057129 0.5713130832 + 0.8080645800 0.7532439232 0.5727772713 + 0.8089416027 0.7543821931 0.5742415190 + 0.8098158240 0.7555181980 0.5757057071 + 0.8106887937 0.7566338778 0.5771644711 + 0.8115618229 0.7577496767 0.5786156058 + 0.8124346733 0.7588654757 0.5800666213 + 0.8132982850 0.7599812150 0.5815176964 + 0.8141440153 0.7610852718 0.5829687715 + 0.8149898052 0.7621840835 0.5843982100 + 0.8158354759 0.7632827759 0.5858259201 + 0.8166813254 0.7643815875 0.5872535706 + 0.8174951077 0.7654762268 0.5886812210 + 0.8183075190 0.7665566802 0.5901004076 + 0.8191198707 0.7676370740 0.5915061831 + 0.8199322820 0.7687175870 0.5929120183 + 0.8207353950 0.7697979808 0.5943177938 + 0.8215301037 0.7708619833 0.5957236290 + 0.8223248124 0.7719196081 0.5971149802 + 0.8231195211 0.7729771137 0.5985029936 + 0.8239132166 0.7740346193 0.5998910069 + 0.8246840835 0.7750877142 0.6012789011 + 0.8254551291 0.7761170268 0.6026648283 + 0.8262259960 0.7771462798 0.6040399075 + 0.8269969821 0.7781755924 0.6054151058 + 0.8277590871 0.7792049050 0.6067903042 + 0.8285127878 0.7802203894 0.6081655025 + 0.8292664289 0.7812247872 0.6095303893 + 0.8300201297 0.7822293043 0.6108843088 + 0.8307737112 0.7832337022 0.6122382283 + 0.8315144181 0.7842381001 0.6135920882 + 0.8322539926 0.7852112055 0.6149461269 + 0.8329936862 0.7861806750 0.6162794232 + 0.8337333202 0.7871502042 0.6176058054 + 0.8344634175 0.7881196737 0.6189321876 + 0.8351711035 0.7890831828 0.6202585101 + 0.8358789086 0.7900207043 0.6215848923 + 0.8365865946 0.7909581065 0.6228948832 + 0.8372943997 0.7918956280 0.6242042184 + 0.8379939198 0.7928329706 0.6255134940 + 0.8386886120 0.7937645912 0.6268228292 + 0.8393831849 0.7946882248 0.6281303167 + 0.8400778174 0.7956116796 0.6294245124 + 0.8407723904 0.7965353131 0.6307187080 + 0.8414523005 0.7974588871 0.6320130229 + 0.8421304226 0.7983703017 0.6333072186 + 0.8428084850 0.7992740870 0.6345958710 + 0.8434864879 0.8001778126 0.6358658075 + 0.8441630006 0.8010815978 0.6371356845 + 0.8448262811 0.8019853830 0.6384056211 + 0.8454895020 0.8028789163 0.6396754980 + 0.8461527824 0.8037689924 0.6409432292 + 0.8468161225 0.8046591878 0.6422051191 + 0.8474723101 0.8055493236 0.6434670091 + 0.8481097817 0.8064395189 0.6447290182 + 0.8487473130 0.8073065877 0.6459909081 + 0.8493847847 0.8081693053 0.6472480297 + 0.8500223160 0.8090320826 0.6484932899 + 0.8506528139 0.8098948002 0.6497384906 + 0.8512719870 0.8107575178 0.6509838104 + 0.8518912196 0.8115878105 0.6522290111 + 0.8525105119 0.8124132156 0.6534695029 + 0.8531296849 0.8132386804 0.6546944976 + 0.8537434936 0.8140640855 0.6559193730 + 0.8543506861 0.8148896098 0.6571443081 + 0.8549579978 0.8157023191 0.6583693027 + 0.8555651903 0.8165128231 0.6595931053 + 0.8561723828 0.8173233271 0.6608086228 + 0.8567661047 0.8181337714 0.6620242000 + 0.8573439121 0.8189442754 0.6632397771 + 0.8579216003 0.8197408915 0.6644554138 + 0.8584992886 0.8205333948 0.6656709909 + 0.8590769768 0.8213258982 0.6668658853 + 0.8596463799 0.8221184015 0.6680600047 + 0.8602035046 0.8229109049 0.6692541838 + 0.8607606888 0.8236929774 0.6704483032 + 0.8613178134 0.8244690895 0.6716424227 + 0.8618749976 0.8252452016 0.6728152037 + 0.8624271750 0.8260213137 0.6739807129 + 0.8629680276 0.8267974854 0.6751462221 + 0.8635088801 0.8275653720 0.6763116717 + 0.8640497923 0.8283231854 0.6774771810 + 0.8645905852 0.8290811181 0.6786333919 + 0.8651301265 0.8298389912 0.6797791719 + 0.8656617999 0.8305969238 0.6809248924 + 0.8661935925 0.8313513994 0.6820706725 + 0.8667253256 0.8320925832 0.6832165122 + 0.8672569990 0.8328338265 0.6843608022 + 0.8677886724 0.8335750103 0.6854962111 + 0.8683093786 0.8343161941 0.6866315007 + 0.8688293099 0.8350573778 0.6877667904 + 0.8693491817 0.8357766271 0.6889020801 + 0.8698691130 0.8364936113 0.6900374889 + 0.8703891039 0.8372104764 0.6911699772 + 0.8708937764 0.8379275203 0.6923016906 + 0.8713908792 0.8386443853 0.6934332848 + 0.8718879819 0.8393507004 0.6945648789 + 0.8723850846 0.8400480151 0.6956964731 + 0.8728821874 0.8407453895 0.6968225241 + 0.8733705282 0.8414428234 0.6979349852 + 0.8738415837 0.8421400785 0.6990476251 + 0.8743125796 0.8428345919 0.7001600862 + 0.8747836947 0.8435099125 0.7012727261 + 0.8752548099 0.8441851735 0.7023853064 + 0.8757258058 0.8448604941 0.7034785748 + 0.8761900067 0.8455356956 0.7045670152 + 0.8766540289 0.8462110162 0.7056552768 + 0.8771178722 0.8468806148 0.7067435980 + 0.8775817752 0.8475472927 0.7078319192 + 0.8780456781 0.8482139111 0.7089164257 + 0.8785020113 0.8488805294 0.7099874020 + 0.8789511919 0.8495470881 0.7110584974 + 0.8794003725 0.8502116799 0.7121295929 + 0.8798494935 0.8508617282 0.7132006288 + 0.8802986741 0.8515115976 0.7142717242 + 0.8807477951 0.8521615267 0.7153381109 + 0.8811936975 0.8528113961 0.7164012194 + 0.8816397190 0.8534613252 0.7174643278 + 0.8820856214 0.8541015983 0.7185273767 + 0.8825315237 0.8547332287 0.7195906043 + 0.8829774261 0.8553647995 0.7206537127 + 0.8834267855 0.8559963703 0.7216954231 + 0.8838804960 0.8566280007 0.7227349877 + 0.8843340874 0.8572596908 0.7237744927 + 0.8847877979 0.8578745127 0.7248139977 + 0.8852415085 0.8584867120 0.7258535028 + 0.8856950998 0.8590989709 0.7268896103 + 0.8861432076 0.8597112894 0.7279071808 + 0.8865901828 0.8603236079 0.7289246917 + 0.8870372176 0.8609315753 0.7299422026 + 0.8874841928 0.8615155816 0.7309597731 + 0.8879311085 0.8620995879 0.7319772840 + 0.8883765936 0.8626837134 0.7329847217 + 0.8888130188 0.8632677197 0.7339726090 + 0.8892495036 0.8638517857 0.7349603772 + 0.8896859288 0.8644294739 0.7359483242 + 0.8901224136 0.8649967909 0.7369360924 + 0.8905587792 0.8655641079 0.7379239798 + 0.8909912109 0.8661314249 0.7389044762 + 0.8914173841 0.8666986227 0.7398765087 + 0.8918436170 0.8672658801 0.7408484817 + 0.8922697902 0.8678284287 0.7418205738 + 0.8926960230 0.8683868051 0.7427926064 + 0.8931223154 0.8689451218 0.7437645793 + 0.8935400248 0.8695034981 0.7447342873 + 0.8939518929 0.8700618148 0.7457019091 + 0.8943638206 0.8706201911 0.7466694713 + 0.8947756886 0.8711758852 0.7476369739 + 0.8951874971 0.8717300892 0.7486045957 + 0.8955994248 0.8722842932 0.7495722175 + 0.8960080743 0.8728384972 0.7505385876 + 0.8964155912 0.8733927011 0.7515040040 + 0.8968231082 0.8739469051 0.7524694800 + 0.8972306252 0.8744983077 0.7534348965 + 0.8976380229 0.8750482798 0.7544003129 + 0.8980454803 0.8755983114 0.7553657293 + 0.8984466195 0.8761482835 0.7563228011 + 0.8988459110 0.8766983151 0.7572699785 + 0.8992452025 0.8772484064 0.7582172155 + 0.8996444941 0.8777912259 0.7591643929 + 0.9000439048 0.8783296943 0.7601115108 + 0.9004431963 0.8788682222 0.7610586882 + 0.9008390903 0.8794066906 0.7620021105 + 0.9012339711 0.8799452186 0.7629373074 + 0.9016289711 0.8804838061 0.7638723850 + 0.9020239711 0.8810167909 0.7648075819 + 0.9024189711 0.8815448284 0.7657427788 + 0.9028139114 0.8820728064 0.7666779757 + 0.9032065868 0.8826007843 0.7676120996 + 0.9035984278 0.8831288218 0.7685371041 + 0.9039902091 0.8836567998 0.7694622278 + 0.9043819904 0.8841773272 0.7703871727 + 0.9047737718 0.8846845031 0.7713122964 + 0.9051656127 0.8851916790 0.7722373009 + 0.9055474997 0.8856989145 0.7731624246 + 0.9059227109 0.8862062097 0.7740741968 + 0.9062979221 0.8867133856 0.7749837041 + 0.9066730738 0.8872200251 0.7758932710 + 0.9070482850 0.8877230883 0.7768027782 + 0.9074234962 0.8882262111 0.7777122855 + 0.9077919126 0.8887292147 0.7786217928 + 0.9081501961 0.8892322779 0.7795184851 + 0.9085084796 0.8897352815 0.7804030776 + 0.9088668227 0.8902384043 0.7812876105 + 0.9092251062 0.8907387853 0.7821720839 + 0.9095833898 0.8912386894 0.7830566168 + 0.9099410176 0.8917385936 0.7839412093 + 0.9102939963 0.8922384977 0.7848230004 + 0.9106469750 0.8927385211 0.7856823802 + 0.9110000134 0.8932384253 0.7865417004 + 0.9113529921 0.8937345147 0.7874010801 + 0.9117060900 0.8942261934 0.7882605195 + 0.9120591283 0.8947178721 0.7891197801 + 0.9124001861 0.8952096105 0.7899792194 + 0.9127386212 0.8957012892 0.7908260822 + 0.9130769968 0.8961930871 0.7916657925 + 0.9134153724 0.8966842890 0.7925053835 + 0.9137538075 0.8971561790 0.7933450937 + 0.9140921831 0.8976281881 0.7941846848 + 0.9144207835 0.8981001973 0.7950243950 + 0.9147356153 0.8985722065 0.7958624959 + 0.9150503874 0.8990442157 0.7966837883 + 0.9153652191 0.8995161057 0.7975050807 + 0.9156799912 0.8999810219 0.7983263731 + 0.9159948230 0.9004393816 0.7991477847 + 0.9163095951 0.9008978009 0.7999690771 + 0.9166138768 0.9013561010 0.8007904291 + 0.9169176221 0.9018145204 0.8015990257 + 0.9172213078 0.9022728205 0.8023931980 + 0.9175249934 0.9027311802 0.8031873107 + 0.9178286791 0.9031661749 0.8039814830 + 0.9181324244 0.9035997987 0.8047757149 + 0.9184330106 0.9040333033 0.8055698872 + 0.9187291861 0.9044669271 0.8063641191 + 0.9190254211 0.9049004912 0.8071421981 + 0.9193214774 0.9053339958 0.8079159856 + 0.9196177125 0.9057644010 0.8086897135 + 0.9199138284 0.9061868787 0.8094635010 + 0.9202100039 0.9066092968 0.8102372289 + 0.9205018878 0.9070317745 0.8110108972 + 0.9207926989 0.9074543118 0.8117843866 + 0.9210835099 0.9078767896 0.8125452995 + 0.9213743210 0.9082993269 0.8133062124 + 0.9216650724 0.9087104201 0.8140671253 + 0.9219558835 0.9091129899 0.8148279786 + 0.9222459793 0.9095156193 0.8155888915 + 0.9225308895 0.9099181890 0.8163498044 + 0.9228156805 0.9103208184 0.8171091080 + 0.9231005907 0.9107235074 0.8178617954 + 0.9233853817 0.9111260772 0.8186144233 + 0.9236702919 0.9115067720 0.8193669915 + 0.9239550829 0.9118813276 0.8201196790 + 0.9242395163 0.9122558832 0.8208723068 + 0.9245231748 0.9126303792 0.8216248751 + 0.9248068929 0.9130049944 0.8223708868 + 0.9250906110 0.9133794904 0.8230999112 + 0.9253743291 0.9137541056 0.8238288164 + 0.9256579280 0.9141280055 0.8245577812 + 0.9259415865 0.9145019054 0.8252866864 + 0.9262230992 0.9148758054 0.8260157108 + 0.9265028238 0.9152497053 0.8267446160 + 0.9267824888 0.9156236053 0.8274663091 + 0.9270622134 0.9159975052 0.8281710148 + 0.9273418784 0.9163714051 0.8288756013 + 0.9276214838 0.9167358279 0.8295801878 + 0.9279012084 0.9171000123 0.8302847743 + 0.9281796813 0.9174641967 0.8309894204 + 0.9284574986 0.9178283811 0.8316941261 + 0.9287353158 0.9181925058 0.8323919773 + 0.9290130734 0.9185566902 0.8330684900 + 0.9292908907 0.9189208746 0.8337450027 + 0.9295685887 0.9192627072 0.8344215155 + 0.9298464060 0.9196035266 0.8350980878 + 0.9301217794 0.9199442863 0.8357746005 + 0.9303957820 0.9202849865 0.8364511132 + 0.9306699038 0.9206258059 0.8371245265 + 0.9309440255 0.9209665060 0.8377707005 + 0.9312180877 0.9213073254 0.8384168744 + 0.9314922094 0.9216343164 0.8390631080 + 0.9317662716 0.9219589829 0.8397092819 + 0.9320312738 0.9222837090 0.8403555155 + 0.9322906733 0.9226084948 0.8410016894 + 0.9325500727 0.9229332209 0.8416479230 + 0.9328094721 0.9232580066 0.8422836065 + 0.9330688119 0.9235826731 0.8429179788 + 0.9333282113 0.9238941073 0.8435524106 + 0.9335876107 0.9241997004 0.8441867828 + 0.9338458180 0.9245051742 0.8448212147 + 0.9341027141 0.9248107076 0.8454555869 + 0.9343596101 0.9251161814 0.8460900187 + 0.9346163869 0.9254217148 0.8467177749 + 0.9348732829 0.9257271886 0.8473411202 + 0.9351301789 0.9260296226 0.8479645252 + 0.9353870749 0.9263281822 0.8485878706 + 0.9356436729 0.9266266823 0.8492112160 + 0.9358993769 0.9269253016 0.8498346210 + 0.9361552000 0.9272238016 0.8504580259 + 0.9364109039 0.9275224209 0.8510761857 + 0.9366667271 0.9278209209 0.8516775966 + 0.9369223714 0.9281198978 0.8522790074 + 0.9371781945 0.9284216762 0.8528804183 + 0.9374338984 0.9287235737 0.8534818292 + 0.9376984239 0.9290254116 0.8540831804 + 0.9379627705 0.9293273091 0.8546845913 + 0.9382272959 0.9296290874 0.8552860022 + 0.9384917021 0.9299309850 0.8558799028 + 0.9387561083 0.9302328229 0.8564717770 + 0.9390205741 0.9305325747 0.8570637703 + 0.9392849803 0.9308316112 0.8576557040 + 0.9395543933 0.9311305285 0.8582475781 + 0.9398267269 0.9314295053 0.8588395119 + 0.9400988817 0.9317284822 0.8594313860 + 0.9403710961 0.9320273995 0.8600232005 + 0.9406434298 0.9323263764 0.8606147766 + 0.9409155846 0.9326242208 0.8612062931 + 0.9411879182 0.9329177737 0.8617979288 + 0.9414601922 0.9332113862 0.8623893857 + 0.9417330027 0.9335049987 0.8629810214 + 0.9420056939 0.9337986112 0.8635724783 + 0.9422785044 0.9340922236 0.8641641140 + 0.9425511956 0.9343857765 0.8647502065 + 0.9428240061 0.9346793890 0.8653333783 + 0.9430966973 0.9349703789 0.8659164906 + 0.9433695078 0.9352599978 0.8664996028 + 0.9436365962 0.9355496168 0.8670827150 + 0.9439011216 0.9358391762 0.8676658273 + 0.9441655278 0.9361287951 0.8682489991 + 0.9444299936 0.9364184141 0.8688321114 + 0.9446943998 0.9367079735 0.8694059253 + 0.9449589252 0.9369975924 0.8699793220 + 0.9452232718 0.9372946024 0.8705525994 + 0.9454872012 0.9375914931 0.8711258769 + 0.9457437992 0.9378883839 0.8716992736 + 0.9460003972 0.9381853938 0.8722726107 + 0.9462569952 0.9384822845 0.8728458881 + 0.9465134740 0.9387792945 0.8734164834 + 0.9467700720 0.9390761852 0.8739734888 + 0.9470267296 0.9393727779 0.8745303750 + 0.9472833276 0.9396685958 0.8750873804 + 0.9475367069 0.9399644136 0.8756443858 + 0.9477851987 0.9402601719 0.8762012720 + 0.9480336905 0.9405561090 0.8767582774 + 0.9482821822 0.9408519268 0.8773152828 + 0.9485306740 0.9411476851 0.8778693080 + 0.9487792253 0.9414435029 0.8784165978 + 0.9490277171 0.9417338967 0.8789640069 + 0.9492762089 0.9420179129 0.8795112967 + 0.9495244026 0.9423019886 0.8800587058 + 0.9497724175 0.9425861239 0.8806061149 + 0.9500203729 0.9428701997 0.8811534047 + 0.9502683878 0.9431542754 0.8817008138 + 0.9505164027 0.9434382915 0.8822470903 + 0.9507644176 0.9437224269 0.8827915788 + 0.9510124922 0.9440007806 0.8833361864 + 0.9512605071 0.9442747831 0.8838806748 + 0.9515028000 0.9445487857 0.8844252229 + 0.9517431855 0.9448227882 0.8849697113 + 0.9519836903 0.9450967908 0.8855141997 + 0.9522241950 0.9453707933 0.8860588074 + 0.9524646997 0.9456447959 0.8865966797 + 0.9527052045 0.9459187984 0.8871210217 + 0.9529457092 0.9461904168 0.8876453042 + 0.9531862140 0.9464601874 0.8881695867 + 0.9534236193 0.9467300177 0.8886939883 + 0.9536604285 0.9469999075 0.8892182708 + 0.9538971782 0.9472696781 0.8897426128 + 0.9541339278 0.9475396276 0.8902668953 + 0.9543706775 0.9478093982 0.8907887936 + 0.9546074867 0.9480792284 0.8913012743 + 0.9548442960 0.9483507872 0.8918138146 + 0.9550809860 0.9486241937 0.8923262954 + 0.9553158283 0.9488974810 0.8928387761 + 0.9555500746 0.9491708279 0.8933513761 + 0.9557843804 0.9494441152 0.8938639164 + 0.9560186863 0.9497175217 0.8943763971 + 0.9562528729 0.9499908090 0.8948888779 + 0.9564871788 0.9502640963 0.8953927159 + 0.9567214847 0.9505357742 0.8958964944 + 0.9569557905 0.9508042932 0.8964002132 + 0.9571847916 0.9510728717 0.8969039917 + 0.9574114084 0.9513413906 0.8974078298 + 0.9576380253 0.9516100287 0.8979116082 + 0.9578645825 0.9518784881 0.8984153271 + 0.9580911994 0.9521470070 0.8989191055 + 0.9583178759 0.9524155855 0.8994185925 + 0.9585444927 0.9526826739 0.8999162912 + 0.9587711096 0.9529364109 0.9004138708 + 0.9589902163 0.9531900287 0.9009116292 + 0.9592015147 0.9534437060 0.9014092088 + 0.9594126940 0.9536973238 0.9019069076 + 0.9596238732 0.9539508820 0.9024044871 + 0.9598351121 0.9542046189 0.9029021859 + 0.9600464106 0.9544581771 0.9033970833 + 0.9602575898 0.9547119141 0.9038860798 + 0.9604688287 0.9549633861 0.9043750167 + 0.9606760144 0.9552143216 0.9048638940 + 0.9608663917 0.9554650784 0.9053527713 + 0.9610567093 0.9557158947 0.9058417082 + 0.9612470865 0.9559667706 0.9063305855 + 0.9614375234 0.9562175870 0.9068195224 + 0.9616279006 0.9564685225 0.9073083997 + 0.9618182778 0.9567192793 0.9077844024 + 0.9620087147 0.9569705129 0.9082577825 + 0.9621990919 0.9572222233 0.9087312222 + 0.9623833895 0.9574738741 0.9092046022 + 0.9625663757 0.9577257037 0.9096779823 + 0.9627494216 0.9579774141 0.9101514220 + 0.9629324079 0.9582291245 0.9106246829 + 0.9631155133 0.9584808946 0.9110981226 + 0.9632984996 0.9587326050 0.9115682244 + 0.9634814858 0.9589843154 0.9120290875 + 0.9636644721 0.9592264891 0.9124898911 + 0.9638484120 0.9594662786 0.9129506946 + 0.9640339017 0.9597061872 0.9134116173 + 0.9642195106 0.9599459767 0.9138724208 + 0.9644050002 0.9601858258 0.9143332243 + 0.9645904899 0.9604256749 0.9147940278 + 0.9647760987 0.9606655240 0.9152548909 + 0.9649615884 0.9609053731 0.9157108068 + 0.9651471972 0.9611442089 0.9161633849 + 0.9653326869 0.9613788724 0.9166160226 + 0.9655120969 0.9616137147 0.9170686007 + 0.9656897783 0.9618483782 0.9175212979 + 0.9658675194 0.9620831013 0.9179738760 + 0.9660452008 0.9623178840 0.9184265137 + 0.9662228227 0.9625526071 0.9188790917 + 0.9664005041 0.9627872705 0.9193317294 + 0.9665781856 0.9630219936 0.9197779894 + 0.9667559266 0.9632468820 0.9202229977 + 0.9669327736 0.9634612799 0.9206681252 + 0.9671043158 0.9636756778 0.9211130738 + 0.9672759175 0.9638900757 0.9215580821 + 0.9674474001 0.9641044736 0.9220032096 + 0.9676188827 0.9643189907 0.9224482179 + 0.9677904844 0.9645333886 0.9228932858 + 0.9679620266 0.9647477865 0.9233382940 + 0.9681335092 0.9649621844 0.9237800241 + 0.9683051109 0.9651690125 0.9242216945 + 0.9684718251 0.9653723240 0.9246633053 + 0.9686310291 0.9655755758 0.9251049757 + 0.9687901139 0.9657788873 0.9255465865 + 0.9689491987 0.9659821987 0.9259883165 + 0.9691084027 0.9661855102 0.9264299273 + 0.9692674875 0.9663888216 0.9268715978 + 0.9694265723 0.9665920138 0.9273126125 + 0.9695857763 0.9667953253 0.9277383089 + 0.9697449207 0.9669919014 0.9281641245 + 0.9699026942 0.9671866894 0.9285898209 + 0.9700592756 0.9673815966 0.9290155172 + 0.9702159166 0.9675763845 0.9294412136 + 0.9703724980 0.9677711725 0.9298669100 + 0.9705290794 0.9679660201 0.9302927256 + 0.9706857204 0.9681608081 0.9307184219 + 0.9708423018 0.9683555961 0.9311441183 + 0.9709988832 0.9685503840 0.9315564036 + 0.9711555243 0.9687359929 0.9319686294 + 0.9713115096 0.9689192772 0.9323807955 + 0.9714668989 0.9691025019 0.9327929020 + 0.9716224074 0.9692857862 0.9332051277 + 0.9717779160 0.9694690108 0.9336172938 + 0.9719334245 0.9696522951 0.9340295196 + 0.9720888138 0.9698355198 0.9344416857 + 0.9722443223 0.9700188041 0.9348539114 + 0.9723997712 0.9702020288 0.9352610111 + 0.9725552797 0.9703844786 0.9356672168 + 0.9727123976 0.9705666900 0.9360734224 + 0.9728708863 0.9707489014 0.9364796281 + 0.9730293751 0.9709311128 0.9368857741 + 0.9731879234 0.9711133242 0.9372920990 + 0.9733464122 0.9712954164 0.9376983047 + 0.9735049009 0.9714776278 0.9381045103 + 0.9736633897 0.9716597795 0.9385107160 + 0.9738218784 0.9718419909 0.9389162064 + 0.9739804268 0.9720212221 0.9393213987 + 0.9741386175 0.9721977711 0.9397264719 + 0.9742962122 0.9723743796 0.9401317239 + 0.9744538069 0.9725509882 0.9405367970 + 0.9746114016 0.9727275968 0.9409419894 + 0.9747691154 0.9729040861 0.9413471222 + 0.9749267101 0.9730806947 0.9417521954 + 0.9750843048 0.9732573032 0.9421573877 + 0.9752420187 0.9734339118 0.9425604939 + 0.9753996134 0.9736099839 0.9429581165 + 0.9755573869 0.9737846851 0.9433556795 + 0.9757156968 0.9739593267 0.9437533021 + 0.9758740067 0.9741340280 0.9441508055 + 0.9760323763 0.9743086100 0.9445484281 + 0.9761906862 0.9744831920 0.9449459910 + 0.9763489962 0.9746578932 0.9453436136 + 0.9765074253 0.9748324752 0.9457411766 + 0.9766656756 0.9750071764 0.9461387992 + 0.9768239856 0.9751818180 0.9465218186 + 0.9769824147 0.9753580093 0.9469017982 + 0.9771348834 0.9755343795 0.9472817183 + 0.9772865176 0.9757108092 0.9476615787 + 0.9774382114 0.9758871794 0.9480414987 + 0.9775897861 0.9760636091 0.9484214187 + 0.9777414203 0.9762399793 0.9488013983 + 0.9778929949 0.9764164090 0.9491813183 + 0.9780446887 0.9765927792 0.9495611787 + 0.9781963229 0.9767692089 0.9499387145 + 0.9783478975 0.9769436717 0.9503098726 + 0.9785013795 0.9771149158 0.9506810904 + 0.9786573052 0.9772862196 0.9510523081 + 0.9788131118 0.9774574041 0.9514235258 + 0.9789689779 0.9776285887 0.9517948031 + 0.9791249037 0.9777997732 0.9521660209 + 0.9792807102 0.9779710174 0.9525371790 + 0.9794365764 0.9781423211 0.9529083967 + 0.9795925021 0.9783135056 0.9532796144 + 0.9797484279 0.9784846902 0.9536480904 + 0.9799041748 0.9786469936 0.9540150762 + 0.9800559878 0.9788064957 0.9543820024 + 0.9802073240 0.9789659977 0.9547489882 + 0.9803586006 0.9791253805 0.9551159143 + 0.9805098772 0.9792848825 0.9554827809 + 0.9806612730 0.9794443846 0.9558498263 + 0.9808126092 0.9796038866 0.9562166929 + 0.9809638858 0.9797633886 0.9565836787 + 0.9811152220 0.9799227715 0.9569506049 + 0.9812664986 0.9800817966 0.9573094845 + 0.9814171195 0.9802325964 0.9576671720 + 0.9815658927 0.9803833961 0.9580247998 + 0.9817147255 0.9805341959 0.9583824873 + 0.9818633795 0.9806848764 0.9587401748 + 0.9820122123 0.9808356762 0.9590978026 + 0.9821609259 0.9809864759 0.9594554901 + 0.9823096991 0.9811372757 0.9598131776 + 0.9824584126 0.9812880754 0.9601708055 + 0.9826071858 0.9814388752 0.9605284929 + 0.9827558994 0.9815893173 0.9608864188 + 0.9829031229 0.9817385077 0.9612444043 + 0.9830487967 0.9818876982 0.9616022706 + 0.9831944108 0.9820368886 0.9619601965 + 0.9833400846 0.9821860790 0.9623181820 + 0.9834856987 0.9823353291 0.9626761079 + 0.9836313725 0.9824845195 0.9630339742 + 0.9837771058 0.9826337099 0.9633920193 + 0.9839227200 0.9827829003 0.9637498856 + 0.9840683937 0.9829320908 0.9641076922 + 0.9842140079 0.9830825925 0.9644622207 + 0.9843599200 0.9832354188 0.9648168087 + 0.9845057726 0.9833881855 0.9651712775 + 0.9846516848 0.9835410118 0.9655258060 + 0.9847975969 0.9836937785 0.9658802748 + 0.9849435091 0.9838467240 0.9662348032 + 0.9850894213 0.9839994907 0.9665892720 + 0.9852352738 0.9841523170 0.9669439197 + 0.9853813052 0.9843050838 0.9672983885 + 0.9855272174 0.9844579101 0.9676529169 + 0.9856731296 0.9846124053 0.9679955244 + 0.9858202934 0.9847701192 0.9683375955 + 0.9859679937 0.9849278927 0.9686797857 + 0.9861156940 0.9850856066 0.9690219164 + 0.9862633944 0.9852433801 0.9693641067 + 0.9864110947 0.9854010940 0.9697061777 + 0.9865589142 0.9855589271 0.9700484276 + 0.9867066145 0.9857165813 0.9703904986 + 0.9868543148 0.9858744144 0.9707326889 + 0.9870020151 0.9860321283 0.9710748196 + 0.9871497154 0.9861894846 0.9714078903 + 0.9872943163 0.9863452911 0.9717383981 + 0.9874371886 0.9865010977 0.9720689058 + 0.9875801206 0.9866569042 0.9723994136 + 0.9877228737 0.9868127704 0.9727299213 + 0.9878658056 0.9869685769 0.9730604291 + 0.9880086780 0.9871243834 0.9733908772 + 0.9881514907 0.9872803092 0.9737213850 + 0.9882944226 0.9874361157 0.9740518928 + 0.9884372950 0.9875919223 0.9743824005 + 0.9885801077 0.9877477288 0.9747108221 + 0.9887198210 0.9878988266 0.9750369191 + 0.9888557196 0.9880496860 0.9753628969 + 0.9889916182 0.9882006049 0.9756889939 + 0.9891275167 0.9883515239 0.9760150909 + 0.9892634749 0.9885023832 0.9763411880 + 0.9893993735 0.9886533022 0.9766672254 + 0.9895352721 0.9888042212 0.9769933224 + 0.9896711707 0.9889550805 0.9773194194 + 0.9898071885 0.9891059995 0.9776453972 + 0.9899430871 0.9892569184 0.9779708982 + 0.9900798202 0.9894033074 0.9782887101 + 0.9902198911 0.9895470738 0.9786065817 + 0.9903600216 0.9896908998 0.9789245129 + 0.9905000925 0.9898347259 0.9792423248 + 0.9906402826 0.9899784923 0.9795601964 + 0.9907804132 0.9901223183 0.9798781276 + 0.9909204841 0.9902660847 0.9801958799 + 0.9910606146 0.9904099107 0.9805138111 + 0.9912006855 0.9905536771 0.9808316827 + 0.9913408756 0.9906975031 0.9811494946 + 0.9914810061 0.9908416271 0.9814661145 + 0.9916189909 0.9909868836 0.9817817807 + 0.9917564988 0.9911323190 0.9820973873 + 0.9918940067 0.9912775755 0.9824131131 + 0.9920315146 0.9914230108 0.9827287197 + 0.9921690226 0.9915683270 0.9830443263 + 0.9923064709 0.9917137027 0.9833599925 + 0.9924440980 0.9918590188 0.9836755991 + 0.9925816059 0.9920043945 0.9839913249 + 0.9927191138 0.9921497107 0.9843068719 + 0.9928566217 0.9922950268 0.9846224785 + 0.9929937124 0.9924386144 0.9849327803 + 0.9931297898 0.9925811291 0.9852427244 + 0.9932658076 0.9927235842 0.9855526090 + 0.9934018850 0.9928659797 0.9858624935 + 0.9935380220 0.9930084944 0.9861723781 + 0.9936740994 0.9931508899 0.9864822030 + 0.9938101768 0.9932934046 0.9867920876 + 0.9939463139 0.9934358001 0.9871019721 + 0.9940823913 0.9935783148 0.9874119163 + 0.9942185283 0.9937207103 0.9877216816 + 0.9943544865 0.9938632250 0.9880297184 + 0.9944881201 0.9940040112 0.9883286953 + 0.9946203232 0.9941446781 0.9886276722 + 0.9947524071 0.9942854047 0.9889267087 + 0.9948846102 0.9944260716 0.9892256856 + 0.9950168133 0.9945669174 0.9895246029 + 0.9951490164 0.9947075844 0.9898235798 + 0.9952812195 0.9948483109 0.9901226163 + 0.9954133034 0.9949889779 0.9904215932 + 0.9955455065 0.9951297045 0.9907206297 + 0.9956777096 0.9952703714 0.9910196066 + 0.9958099127 0.9954108000 0.9913132787 + 0.9959365129 0.9955487251 0.9915956259 + 0.9960625768 0.9956865907 0.9918777943 + 0.9961885810 0.9958245158 0.9921600223 + 0.9963147044 0.9959623814 0.9924421906 + 0.9964408278 0.9961003065 0.9927244186 + 0.9965668917 0.9962381721 0.9930065870 + 0.9966928959 0.9963760972 0.9932888150 + 0.9968190193 0.9965140224 0.9935709834 + 0.9969450831 0.9966518879 0.9938532114 + 0.9970712066 0.9967898130 0.9941353798 + 0.9971972108 0.9969279766 0.9944099784 + 0.9973220825 0.9970669746 0.9946690202 + 0.9974470139 0.9972059131 0.9949278831 + 0.9975720048 0.9973449111 0.9951869249 + 0.9976968765 0.9974839091 0.9954459071 + 0.9978219271 0.9976229072 0.9957048297 + 0.9979467988 0.9977619052 0.9959638119 + 0.9980716705 0.9979009032 0.9962226748 + 0.9981967211 0.9980399013 0.9964817166 + 0.9983215928 0.9981788993 0.9967406988 + 0.9984465241 0.9983178973 0.9969996214 + 0.9985718727 0.9984570742 0.9972563982 + 0.9987018108 0.9985973835 0.9975059032 + 0.9988316298 0.9987375736 0.9977552891 + 0.9989613891 0.9988778830 0.9980046749 + 0.9990912080 0.9990180731 0.9982541203 + 0.9992210865 0.9991583824 0.9985035062 + 0.9993509054 0.9992986917 0.9987528920 + 0.9994807243 0.9994388819 0.9990022779 + 0.9996104836 0.9995791912 0.9992517829 + 0.9997404218 0.9997195005 0.9995012283 + 0.9998701811 0.9998596907 0.9997506142 + 1.0000000000 1.0000000000 1.0000000000 +} diff --git a/rpplugins/color_correction/resources/film_luts_raw/kodak_ektachrome_64t.spi1d b/rpplugins/color_correction/resources/film_luts_raw/kodak_ektachrome_64t.spi1d new file mode 100644 index 0000000..e0066fa --- /dev/null +++ b/rpplugins/color_correction/resources/film_luts_raw/kodak_ektachrome_64t.spi1d @@ -0,0 +1,1030 @@ +Version 1 +From 0.0 1.0 +Length 1024 +Components 3 +{ + 0.0000000000 0.0000000000 0.0000000000 + 0.0007026231 0.0005291322 0.0003438386 + 0.0014857050 0.0011212280 0.0007142003 + 0.0023536440 0.0017713160 0.0011152170 + 0.0033091281 0.0024790310 0.0015472880 + 0.0043581589 0.0032436289 0.0020068779 + 0.0055047469 0.0040647909 0.0024986709 + 0.0067437058 0.0049467869 0.0030213159 + 0.0080656186 0.0058862939 0.0035776510 + 0.0094755674 0.0068916250 0.0041668881 + 0.0109947799 0.0079634041 0.0047885012 + 0.0125997197 0.0091056926 0.0054450892 + 0.0142905395 0.0103072003 0.0061361468 + 0.0160812791 0.0115757296 0.0068590711 + 0.0179866701 0.0129182898 0.0076176482 + 0.0199946500 0.0143368002 0.0084124254 + 0.0220939498 0.0158436093 0.0092439801 + 0.0242956392 0.0174334496 0.0101133203 + 0.0266019199 0.0191023294 0.0110254698 + 0.0290070400 0.0208547898 0.0119773299 + 0.0315142386 0.0226893406 0.0129693104 + 0.0341268592 0.0246077292 0.0140018696 + 0.0368515886 0.0266096294 0.0150737204 + 0.0396952704 0.0286963899 0.0161837209 + 0.0426549911 0.0308631808 0.0173352305 + 0.0457203016 0.0331055112 0.0185222793 + 0.0488859490 0.0354270898 0.0197516698 + 0.0521433800 0.0378220901 0.0210211892 + 0.0554969683 0.0402937494 0.0223336108 + 0.0589461401 0.0428398289 0.0236905906 + 0.0624969490 0.0454611294 0.0250933897 + 0.0661549270 0.0481612310 0.0265355706 + 0.0699189603 0.0509477705 0.0280245394 + 0.0737859830 0.0538181216 0.0295602791 + 0.0777632222 0.0567707308 0.0311385598 + 0.0818370879 0.0598130785 0.0327619798 + 0.0860176310 0.0629488677 0.0344315693 + 0.0903011784 0.0661693737 0.0361473896 + 0.0946921036 0.0694710910 0.0379051082 + 0.0991754308 0.0728540421 0.0397059508 + 0.1037482023 0.0763145164 0.0415495113 + 0.1084047034 0.0798475519 0.0434369706 + 0.1131415963 0.0834460035 0.0453708693 + 0.1179561019 0.0871294513 0.0473461710 + 0.1228469983 0.0908933803 0.0493673384 + 0.1278257072 0.0947273821 0.0514261499 + 0.1328838021 0.0986372530 0.0535301305 + 0.1380223036 0.1026311964 0.0556773506 + 0.1432214975 0.1067062020 0.0578665212 + 0.1484941989 0.1108566970 0.0601071604 + 0.1538525969 0.1150842011 0.0623893999 + 0.1592795998 0.1193784997 0.0647117496 + 0.1647690982 0.1237355024 0.0670745894 + 0.1703308970 0.1281584054 0.0694851503 + 0.1759331971 0.1326268017 0.0719340369 + 0.1815855950 0.1371477991 0.0744230300 + 0.1872842014 0.1417109966 0.0769482180 + 0.1930216998 0.1463264972 0.0795174912 + 0.1988134980 0.1509988010 0.0821337178 + 0.2046463042 0.1557403058 0.0847895518 + 0.2105436027 0.1605253071 0.0874943137 + 0.2164897025 0.1653804928 0.0902354270 + 0.2224933952 0.1702827066 0.0930147171 + 0.2285283953 0.1752299964 0.0958402529 + 0.2345996946 0.1802355051 0.0987048224 + 0.2407190949 0.1852916926 0.1016040966 + 0.2468644977 0.1903931051 0.1045442000 + 0.2530235052 0.1955378056 0.1075213999 + 0.2591835856 0.2007202953 0.1105407029 + 0.2653717995 0.2059361935 0.1135976985 + 0.2715786099 0.2111911029 0.1166936010 + 0.2777847946 0.2164549977 0.1198228002 + 0.2839922011 0.2217417061 0.1229953989 + 0.2902092040 0.2270426005 0.1262023002 + 0.2964079082 0.2323473990 0.1294420958 + 0.3025959134 0.2376510054 0.1327183992 + 0.3087722957 0.2429573983 0.1360210031 + 0.3149321079 0.2482704073 0.1393564939 + 0.3210678101 0.2535850108 0.1427318007 + 0.3272047043 0.2589012980 0.1461382955 + 0.3333187997 0.2642197907 0.1495731026 + 0.3394154012 0.2695527971 0.1530420035 + 0.3454918861 0.2748903036 0.1565402001 + 0.3515484929 0.2802191973 0.1600638032 + 0.3576078117 0.2855531871 0.1636112034 + 0.3636479080 0.2909021080 0.1671815962 + 0.3696722090 0.2962611914 0.1707742065 + 0.3756689131 0.3016174138 0.1743832976 + 0.3816395998 0.3069770932 0.1780118048 + 0.3875685036 0.3123393059 0.1816574037 + 0.3934744000 0.3176954985 0.1853218973 + 0.3993682861 0.3230510056 0.1890095025 + 0.4052383006 0.3284165859 0.1927215010 + 0.4110727012 0.3337813914 0.1964581013 + 0.4168589115 0.3391354084 0.2002173960 + 0.4226124883 0.3444840014 0.2039882988 + 0.4283437133 0.3498201966 0.2077811956 + 0.4340476990 0.3551411927 0.2115973979 + 0.4397180080 0.3604322970 0.2154300958 + 0.4453499019 0.3657175899 0.2192791998 + 0.4509378076 0.3709863126 0.2231477052 + 0.4564813077 0.3762353063 0.2270365059 + 0.4619686007 0.3814581037 0.2309399992 + 0.4674080908 0.3866479099 0.2348691970 + 0.4728043079 0.3918175101 0.2388215065 + 0.4781545103 0.3969655931 0.2427939028 + 0.4834581017 0.4020648003 0.2467841059 + 0.4887135029 0.4071336091 0.2507896125 + 0.4939058125 0.4121663868 0.2548081875 + 0.4990504086 0.4171527028 0.2588363886 + 0.5041617155 0.4221054912 0.2628706992 + 0.5092216134 0.4270165861 0.2669112086 + 0.5142281055 0.4319120049 0.2709617913 + 0.5191956758 0.4367876947 0.2750129104 + 0.5241003036 0.4416337907 0.2790606022 + 0.5289487243 0.4464288056 0.2831023932 + 0.5337404013 0.4511983097 0.2871333063 + 0.5384750962 0.4559360147 0.2911599874 + 0.5431362987 0.4606370032 0.2951760888 + 0.5477464795 0.4652822018 0.2991817892 + 0.5523136854 0.4699006975 0.3031803966 + 0.5568382740 0.4744859934 0.3071657121 + 0.5613049269 0.4790317118 0.3111445010 + 0.5657191277 0.4835188091 0.3151197135 + 0.5700793862 0.4879747033 0.3190810978 + 0.5743808150 0.4923951924 0.3230370879 + 0.5786144733 0.4967536032 0.3269884884 + 0.5828108191 0.5010759830 0.3309372962 + 0.5869714022 0.5053607821 0.3348788023 + 0.5910838246 0.5095916986 0.3388131857 + 0.5951429009 0.5137745738 0.3427393138 + 0.5991551280 0.5179340243 0.3466500044 + 0.6030982733 0.5220689774 0.3505468071 + 0.6069651246 0.5261592269 0.3544330001 + 0.6107723713 0.5302231908 0.3583126962 + 0.6144962907 0.5342565775 0.3621850014 + 0.6181483865 0.5382382274 0.3660446107 + 0.6217647195 0.5421987772 0.3698979020 + 0.6253350973 0.5461328030 0.3737412989 + 0.6288506985 0.5500105023 0.3775792122 + 0.6323326230 0.5538635254 0.3814140856 + 0.6357542872 0.5576797724 0.3852416873 + 0.6391350031 0.5614629984 0.3890604079 + 0.6424909234 0.5652248263 0.3928706050 + 0.6457951069 0.5689184070 0.3966498971 + 0.6490675807 0.5725790858 0.4004212022 + 0.6523084044 0.5761985779 0.4041798115 + 0.6554991007 0.5797787905 0.4079318047 + 0.6586679220 0.5833429098 0.4116778970 + 0.6617909074 0.5868695974 0.4154145122 + 0.6648769975 0.5903773904 0.4191451073 + 0.6679384708 0.5938647985 0.4228456020 + 0.6709473133 0.5972957015 0.4265331924 + 0.6739342213 0.6007062197 0.4302001894 + 0.6768646836 0.6040558815 0.4338527918 + 0.6797602177 0.6073855162 0.4374971986 + 0.6826251745 0.6106783748 0.4411129951 + 0.6854385138 0.6139551997 0.4447222054 + 0.6882362962 0.6172215939 0.4483056068 + 0.6909871101 0.6204239726 0.4518764913 + 0.6937232018 0.6236106753 0.4554122090 + 0.6964259148 0.6267350912 0.4589309096 + 0.6990894079 0.6298514009 0.4624271989 + 0.7017171979 0.6329439878 0.4658999145 + 0.7042943835 0.6360031962 0.4693557024 + 0.7068523169 0.6390181780 0.4727905095 + 0.7093623877 0.6420083046 0.4762170017 + 0.7118644714 0.6449810863 0.4796274900 + 0.7143244743 0.6479082704 0.4830344915 + 0.7167754769 0.6508182287 0.4864130020 + 0.7191916108 0.6536681056 0.4897888005 + 0.7215893865 0.6565065980 0.4931452870 + 0.7239490151 0.6593149900 0.4965006113 + 0.7262917757 0.6621205807 0.4998255074 + 0.7286117077 0.6648774147 0.5031486154 + 0.7308964729 0.6676303744 0.5064402819 + 0.7331464291 0.6703311205 0.5097302794 + 0.7353671193 0.6730266809 0.5129926205 + 0.7375649214 0.6756759286 0.5162526965 + 0.7397302985 0.6783176064 0.5194661021 + 0.7418738008 0.6808996201 0.5226792097 + 0.7439814806 0.6834768057 0.5258497000 + 0.7460665703 0.6860129833 0.5290201902 + 0.7481163740 0.6885464191 0.5321524143 + 0.7501432896 0.6910448074 0.5352824926 + 0.7521458268 0.6935424209 0.5383893847 + 0.7541307211 0.6960023046 0.5414927006 + 0.7560967207 0.6984623075 0.5445662737 + 0.7580459714 0.7008609176 0.5476304889 + 0.7599691153 0.7032560110 0.5506601930 + 0.7618615031 0.7055974007 0.5536696911 + 0.7637408972 0.7079290748 0.5566582084 + 0.7655979991 0.7102227807 0.5596238971 + 0.7674412727 0.7125021815 0.5625798106 + 0.7692431808 0.7147536278 0.5655139089 + 0.7710394859 0.7169851065 0.5684432983 + 0.7727897167 0.7192016244 0.5713353753 + 0.7745398879 0.7213971019 0.5742275119 + 0.7762631774 0.7235780954 0.5770719051 + 0.7779850960 0.7257089019 0.5799102783 + 0.7796735764 0.7278391123 0.5827142000 + 0.7813516259 0.7299191952 0.5854988098 + 0.7830191255 0.7319993973 0.5882691145 + 0.7846779227 0.7340465784 0.5910149813 + 0.7863258123 0.7360842228 0.5937579870 + 0.7879499197 0.7381075025 0.5964655280 + 0.7895722985 0.7401170731 0.5991730094 + 0.7911682725 0.7421147823 0.6018517017 + 0.7927643061 0.7440714836 0.6045210958 + 0.7943251133 0.7460281849 0.6071749926 + 0.7958757281 0.7479510903 0.6098067760 + 0.7974109054 0.7498708963 0.6124358773 + 0.7989286184 0.7517752051 0.6150038242 + 0.8004400134 0.7536681890 0.6175717711 + 0.8019111753 0.7555513978 0.6200997233 + 0.8033823967 0.7573989034 0.6226056814 + 0.8048381209 0.7592465281 0.6251029968 + 0.8062893748 0.7610545754 0.6275702119 + 0.8077279925 0.7628545165 0.6300374269 + 0.8091471791 0.7646414042 0.6324740052 + 0.8105664849 0.7664098144 0.6349017024 + 0.8119462729 0.7681781054 0.6373167038 + 0.8133255243 0.7698963284 0.6397023201 + 0.8146849871 0.7716131806 0.6420879960 + 0.8160281777 0.7733101845 0.6444455981 + 0.8173695207 0.7749879956 0.6467962861 + 0.8186913133 0.7766653895 0.6491395235 + 0.8200129867 0.7783104777 0.6514626145 + 0.8213170171 0.7799556255 0.6537855864 + 0.8226091266 0.7815762162 0.6560755968 + 0.8238981962 0.7831717730 0.6583523750 + 0.8251538873 0.7847673893 0.6606240273 + 0.8264095783 0.7863461971 0.6628612876 + 0.8276506066 0.7879241705 0.6650987267 + 0.8288792968 0.7894842029 0.6673101187 + 0.8301079869 0.7910140753 0.6694974899 + 0.8313009739 0.7925441265 0.6716848016 + 0.8324930072 0.7940390110 0.6738216877 + 0.8336700201 0.7955235243 0.6759517193 + 0.8348218799 0.7970044017 0.6780722141 + 0.8359737992 0.7984637022 0.6801573038 + 0.8371133804 0.7999228835 0.6822422743 + 0.8382487893 0.8013638258 0.6843022108 + 0.8393824100 0.8027846813 0.6863384247 + 0.8404983878 0.8042055964 0.6883745193 + 0.8416143060 0.8055989742 0.6903743148 + 0.8427138925 0.8069851995 0.6923640966 + 0.8437898159 0.8083692193 0.6943526864 + 0.8448657990 0.8097262979 0.6963012815 + 0.8459321260 0.8110834956 0.6982498765 + 0.8469941020 0.8124284744 0.7001879215 + 0.8480560780 0.8137484789 0.7020930052 + 0.8491019011 0.8150684834 0.7039980888 + 0.8501470089 0.8163607121 0.7058871984 + 0.8511853814 0.8176304102 0.7077549100 + 0.8521944284 0.8189001083 0.7096226215 + 0.8532034159 0.8201503158 0.7114666104 + 0.8542025089 0.8213939071 0.7132933736 + 0.8551856279 0.8226374984 0.7151201963 + 0.8561686873 0.8238468766 0.7169187069 + 0.8571283221 0.8250527978 0.7187049985 + 0.8580685258 0.8262571096 0.7204912901 + 0.8590087295 0.8274198174 0.7222427130 + 0.8599494100 0.8285825253 0.7239848971 + 0.8608903289 0.8297395110 0.7257270217 + 0.8618311882 0.8308607936 0.7274336815 + 0.8627600074 0.8319821954 0.7291340828 + 0.8636854887 0.8330979943 0.7308344841 + 0.8646110892 0.8341925740 0.7325049043 + 0.8655208945 0.8352872729 0.7341710925 + 0.8664281964 0.8363729715 0.7358372808 + 0.8673354983 0.8374316096 0.7374768853 + 0.8682217002 0.8384901285 0.7391127944 + 0.8691056967 0.8395386934 0.7407485843 + 0.8699898124 0.8405579925 0.7423660159 + 0.8708515763 0.8415772915 0.7439796925 + 0.8717116117 0.8425924182 0.7455934882 + 0.8725715280 0.8435931206 0.7471752763 + 0.8734114170 0.8445938230 0.7487472296 + 0.8742489219 0.8455908895 0.7503191829 + 0.8750864267 0.8465701938 0.7518702149 + 0.8759170175 0.8475493789 0.7534102798 + 0.8767464161 0.8485258222 0.7549505234 + 0.8775756955 0.8494656086 0.7564716935 + 0.8783869743 0.8504052758 0.7579756975 + 0.8791924715 0.8513450027 0.7594797015 + 0.8799980283 0.8522825241 0.7609726191 + 0.8807792068 0.8532198071 0.7624449730 + 0.8815463185 0.8541572094 0.7639175057 + 0.8823133707 0.8550791144 0.7653834224 + 0.8830744028 0.8559969068 0.7668110132 + 0.8838288188 0.8569146991 0.7682386041 + 0.8845831156 0.8578169942 0.7696663141 + 0.8853343725 0.8587086201 0.7710726857 + 0.8860781193 0.8596001863 0.7724769711 + 0.8868216872 0.8604816794 0.7738813162 + 0.8875637054 0.8613451123 0.7752763033 + 0.8882815242 0.8622086048 0.7766659856 + 0.8889992833 0.8630689979 0.7780556083 + 0.8897172213 0.8639014959 0.7794315815 + 0.8904141784 0.8647338748 0.7807787061 + 0.8911063075 0.8655663729 0.7821257710 + 0.8917983770 0.8663951159 0.7834728956 + 0.8924919963 0.8672229052 0.7847924829 + 0.8931869864 0.8680506945 0.7861111760 + 0.8938819766 0.8688691258 0.7874299884 + 0.8945751190 0.8696764112 0.7887393832 + 0.8952596188 0.8704836965 0.7900424004 + 0.8959441185 0.8712878227 0.7913452983 + 0.8966286182 0.8720598817 0.7926430702 + 0.8972942233 0.8728318810 0.7939155102 + 0.8979557157 0.8736039996 0.7951877713 + 0.8986173272 0.8743599057 0.7964602113 + 0.8992745876 0.8751083016 0.7977172136 + 0.8999263048 0.8758566976 0.7989680767 + 0.9005779028 0.8766024709 0.8002188802 + 0.9012296200 0.8773398995 0.8014593720 + 0.9018729925 0.8780772090 0.8026626706 + 0.9025161862 0.8788145781 0.8038660288 + 0.9031593800 0.8795428872 0.8050693274 + 0.9037922025 0.8802682757 0.8062509894 + 0.9044145942 0.8809937239 0.8074226975 + 0.9050371051 0.8817160130 0.8085945249 + 0.9056594968 0.8824285269 0.8097618222 + 0.9062777162 0.8831409812 0.8108941913 + 0.9068958759 0.8838534951 0.8120266199 + 0.9075139761 0.8845480084 0.8131589890 + 0.9081308842 0.8852338791 0.8142759204 + 0.9087464213 0.8859198093 0.8153775930 + 0.9093617797 0.8866025805 0.8164793253 + 0.9099771976 0.8872501254 0.8175811172 + 0.9105805159 0.8878976703 0.8186519146 + 0.9111816287 0.8885452151 0.8197175860 + 0.9117826819 0.8891865015 0.8207833171 + 0.9123781919 0.8898199797 0.8218469024 + 0.9129536748 0.8904533982 0.8229005933 + 0.9135290980 0.8910868764 0.8239542246 + 0.9141045809 0.8917121887 0.8250077963 + 0.9146608114 0.8923351169 0.8260518909 + 0.9152011871 0.8929579854 0.8270838261 + 0.9157415032 0.8935797215 0.8281157017 + 0.9162818789 0.8941801190 0.8291476965 + 0.9168179035 0.8947805762 0.8301671743 + 0.9173532128 0.8953809738 0.8311806917 + 0.9178884029 0.8959742785 0.8321940899 + 0.9184231758 0.8965504169 0.8332076073 + 0.9189543128 0.8971264958 0.8341963291 + 0.9194852710 0.8977025747 0.8351811171 + 0.9200162888 0.8982679844 0.8361659050 + 0.9205431938 0.8988227844 0.8371505141 + 0.9210606217 0.8993775249 0.8381142020 + 0.9215779901 0.8999322057 0.8390778899 + 0.9220954180 0.9004656076 0.8400415778 + 0.9226071239 0.9009882212 0.8410019279 + 0.9231125712 0.9015107751 0.8419361115 + 0.9236180782 0.9020333290 0.8428702950 + 0.9241235256 0.9025334716 0.8438045979 + 0.9246153235 0.9030274749 0.8447362781 + 0.9250978231 0.9035214782 0.8456568718 + 0.9255803227 0.9040154815 0.8465775847 + 0.9260628223 0.9045063853 0.8474981785 + 0.9265328050 0.9049968123 0.8484144211 + 0.9269970059 0.9054871798 0.8493136764 + 0.9274612069 0.9059776068 0.8502129912 + 0.9279254079 0.9064562917 0.8511123061 + 0.9283785820 0.9069336057 0.8520066738 + 0.9288275838 0.9074109793 0.8528792262 + 0.9292767048 0.9078882933 0.8537517190 + 0.9297257066 0.9083464146 0.8546240926 + 0.9301574826 0.9088020921 0.8554927111 + 0.9305828214 0.9092578888 0.8563321233 + 0.9310081005 0.9097136259 0.8571714759 + 0.9314333797 0.9101629257 0.8580110073 + 0.9318456054 0.9106109142 0.8588501811 + 0.9322518110 0.9110590219 0.8596740961 + 0.9326580763 0.9115070105 0.8604980111 + 0.9330642819 0.9119517207 0.8613219261 + 0.9334682822 0.9123954177 0.8621457815 + 0.9338707924 0.9128389955 0.8629440069 + 0.9342733026 0.9132825732 0.8637380004 + 0.9346758127 0.9137256145 0.8645321131 + 0.9350727201 0.9141682982 0.8653261065 + 0.9354630113 0.9146109819 0.8661041856 + 0.9358533025 0.9150536060 0.8668742180 + 0.9362437129 0.9154921770 0.8676440716 + 0.9366282821 0.9159253836 0.8684141040 + 0.9369992018 0.9163584709 0.8691806197 + 0.9373700023 0.9167916179 0.8699421883 + 0.9377409220 0.9172230959 0.8707038164 + 0.9381108284 0.9176480174 0.8714653850 + 0.9384678006 0.9180728793 0.8722239733 + 0.9388247728 0.9184976816 0.8729615808 + 0.9391818047 0.9189226031 0.8736993074 + 0.9395387769 0.9193425775 0.8744369149 + 0.9398884177 0.9197623134 0.8751745820 + 0.9402360916 0.9201819897 0.8758922219 + 0.9405838847 0.9206016064 0.8766046166 + 0.9409316182 0.9210132957 0.8773170114 + 0.9412720203 0.9214196801 0.8780294061 + 0.9416047931 0.9218261838 0.8787423968 + 0.9419375062 0.9222326279 0.8794564009 + 0.9422702193 0.9226341248 0.8801705241 + 0.9426016808 0.9230197072 0.8808845282 + 0.9429249763 0.9234051704 0.8815984726 + 0.9432482719 0.9237906933 0.8823022246 + 0.9435716271 0.9241762161 0.8830056190 + 0.9438948035 0.9245483875 0.8837090731 + 0.9442144036 0.9249175191 0.8844125271 + 0.9445325136 0.9252867103 0.8851082921 + 0.9448506236 0.9256557822 0.8857964277 + 0.9451687932 0.9260243177 0.8864845037 + 0.9454866052 0.9263916016 0.8871726990 + 0.9458038807 0.9267588258 0.8878607750 + 0.9461210966 0.9271261096 0.8885198236 + 0.9464383721 0.9274932742 0.8891779184 + 0.9467555881 0.9278637767 0.8898360729 + 0.9470669031 0.9282348752 0.8904942274 + 0.9473763108 0.9286059737 0.8911436796 + 0.9476857185 0.9289770126 0.8917800188 + 0.9479951262 0.9293472171 0.8924162984 + 0.9483039975 0.9297147989 0.8930525780 + 0.9486111999 0.9300825000 0.8936889172 + 0.9489184022 0.9304502010 0.8942996860 + 0.9492256045 0.9308179021 0.8949031234 + 0.9495326877 0.9311780930 0.8955063820 + 0.9498348832 0.9315345883 0.8961097002 + 0.9501338005 0.9318912029 0.8967118263 + 0.9504327774 0.9322476983 0.8973019719 + 0.9507316947 0.9326038957 0.8978921175 + 0.9510306716 0.9329422712 0.8984823227 + 0.9513161778 0.9332805872 0.8990725279 + 0.9516012073 0.9336189032 0.8996539712 + 0.9518861771 0.9339572787 0.9002208710 + 0.9521712065 0.9342914224 0.9007877707 + 0.9524512291 0.9346157908 0.9013546109 + 0.9527168274 0.9349402189 0.9019215107 + 0.9529824257 0.9352647066 0.9024795890 + 0.9532480240 0.9355890751 0.9030315876 + 0.9535136223 0.9359090924 0.9035837054 + 0.9537726045 0.9362252951 0.9041357040 + 0.9540249705 0.9365414977 0.9046877027 + 0.9542772770 0.9368577003 0.9052293897 + 0.9545297027 0.9371739030 0.9057677984 + 0.9547821283 0.9374797940 0.9063060880 + 0.9550374746 0.9377818108 0.9068444967 + 0.9552941918 0.9380838871 0.9073829055 + 0.9555509090 0.9383859038 0.9079146981 + 0.9558076262 0.9386879206 0.9084457159 + 0.9560642838 0.9389883280 0.9089766145 + 0.9563276768 0.9392884970 0.9095075727 + 0.9565923810 0.9395886064 0.9100385904 + 0.9568570852 0.9398887157 0.9105516076 + 0.9571216702 0.9401888251 0.9110634923 + 0.9573863745 0.9404814839 0.9115753770 + 0.9576531053 0.9407737255 0.9120873809 + 0.9579198956 0.9410659075 0.9125993252 + 0.9581868052 0.9413580894 0.9130939245 + 0.9584535956 0.9416502714 0.9135876894 + 0.9587203860 0.9419289231 0.9140815139 + 0.9589838982 0.9422072768 0.9145752788 + 0.9592472911 0.9424856901 0.9150691032 + 0.9595106244 0.9427641034 0.9155386090 + 0.9597740173 0.9430423975 0.9160056710 + 0.9600374103 0.9433137178 0.9164727926 + 0.9602922201 0.9435846806 0.9169399142 + 0.9605466127 0.9438555837 0.9174069762 + 0.9608010054 0.9441264868 0.9178671837 + 0.9610555172 0.9443975091 0.9183259010 + 0.9613099098 0.9446647167 0.9187846184 + 0.9615522027 0.9449313283 0.9192432165 + 0.9617928863 0.9451979995 0.9197018743 + 0.9620336294 0.9454646707 0.9201496840 + 0.9622743130 0.9457312822 0.9205917716 + 0.9625151157 0.9459909201 0.9210339785 + 0.9627497196 0.9462481141 0.9214761853 + 0.9629824162 0.9465051889 0.9219183922 + 0.9632151127 0.9467623830 0.9223541021 + 0.9634478092 0.9470195174 0.9227821827 + 0.9636805058 0.9472687244 0.9232103229 + 0.9639062881 0.9475113153 0.9236382842 + 0.9641271234 0.9477539062 0.9240664244 + 0.9643478990 0.9479964972 0.9244915843 + 0.9645686746 0.9482392073 0.9249045253 + 0.9647895098 0.9484791160 0.9253175259 + 0.9650083780 0.9487127066 0.9257304072 + 0.9652239084 0.9489462972 0.9261432886 + 0.9654393196 0.9491798878 0.9265562296 + 0.9656546712 0.9494134784 0.9269577861 + 0.9658702016 0.9496471286 0.9273576736 + 0.9660856128 0.9498767257 0.9277576208 + 0.9663015008 0.9501063228 0.9281575084 + 0.9665173888 0.9503358006 0.9285573959 + 0.9667332768 0.9505653977 0.9289472103 + 0.9669492245 0.9507949948 0.9293261766 + 0.9671651125 0.9510244727 0.9297050834 + 0.9673789144 0.9512541294 0.9300841093 + 0.9675917029 0.9514836073 0.9304630756 + 0.9678044915 0.9517130852 0.9308412075 + 0.9680173993 0.9519426823 0.9312015176 + 0.9682301879 0.9521713257 0.9315618277 + 0.9684410095 0.9523969293 0.9319220185 + 0.9686465859 0.9526224732 0.9322823286 + 0.9688522816 0.9528480172 0.9326425791 + 0.9690579176 0.9530736208 0.9330028892 + 0.9692634940 0.9532991052 0.9333631992 + 0.9694690704 0.9535260201 0.9337235093 + 0.9696654081 0.9537532926 0.9340837002 + 0.9698594809 0.9539806843 0.9344440103 + 0.9700536728 0.9542080164 0.9348043203 + 0.9702479243 0.9544352889 0.9351575971 + 0.9704419971 0.9546620846 0.9355108738 + 0.9706341028 0.9548869133 0.9358642101 + 0.9708212018 0.9551116228 0.9362174273 + 0.9710081816 0.9553362727 0.9365707040 + 0.9711952806 0.9555611014 0.9369189143 + 0.9713823795 0.9557858109 0.9372587800 + 0.9715694189 0.9560061097 0.9375988245 + 0.9717484713 0.9562234282 0.9379386902 + 0.9719241261 0.9564408064 0.9382786155 + 0.9720997214 0.9566581845 0.9386184812 + 0.9722753167 0.9568755031 0.9389562011 + 0.9724509120 0.9570928812 0.9392927885 + 0.9726263285 0.9572992921 0.9396293759 + 0.9727976918 0.9575052261 0.9399660826 + 0.9729689956 0.9577109814 0.9403027296 + 0.9731404185 0.9579169154 0.9406393766 + 0.9733117223 0.9581226707 0.9409670830 + 0.9734830856 0.9583271146 0.9412943721 + 0.9736548066 0.9585263133 0.9416217208 + 0.9738274217 0.9587255120 0.9419491291 + 0.9739999175 0.9589247108 0.9422764182 + 0.9741724133 0.9591240287 0.9426026940 + 0.9743450284 0.9593232274 0.9429237247 + 0.9745175242 0.9595177770 0.9432445765 + 0.9746888876 0.9597066045 0.9435654879 + 0.9748594165 0.9598953724 0.9438865185 + 0.9750298858 0.9600841999 0.9442073703 + 0.9752004147 0.9602730274 0.9445272088 + 0.9753708839 0.9604617953 0.9448443055 + 0.9755414724 0.9606478810 0.9451612830 + 0.9757080078 0.9608321786 0.9454783201 + 0.9758731723 0.9610164762 0.9457954168 + 0.9760383964 0.9612007737 0.9461123943 + 0.9762036204 0.9613850713 0.9464284778 + 0.9763687849 0.9615694284 0.9467430115 + 0.9765340090 0.9617481232 0.9470574856 + 0.9766919017 0.9619243741 0.9473719001 + 0.9768484235 0.9621006846 0.9476863742 + 0.9770050049 0.9622771144 0.9480009079 + 0.9771615267 0.9624534249 0.9483118057 + 0.9773181081 0.9626296759 0.9486168027 + 0.9774745703 0.9628033042 0.9489219189 + 0.9776207805 0.9629759192 0.9492269158 + 0.9777655005 0.9631485939 0.9495319128 + 0.9779102802 0.9633212090 0.9498370290 + 0.9780550003 0.9634938240 0.9501398802 + 0.9781997800 0.9636663795 0.9504382014 + 0.9783445001 0.9638398290 0.9507365227 + 0.9784767032 0.9640133977 0.9510347843 + 0.9786067009 0.9641870856 0.9513331056 + 0.9787368178 0.9643607736 0.9516314268 + 0.9788668752 0.9645345211 0.9519273043 + 0.9789968729 0.9647082090 0.9522131085 + 0.9791269898 0.9648808241 0.9524989128 + 0.9792442918 0.9650526047 0.9527845979 + 0.9793577790 0.9652245045 0.9530704021 + 0.9794713259 0.9653962851 0.9533562064 + 0.9795848131 0.9655681849 0.9536418915 + 0.9796983004 0.9657400250 0.9539101720 + 0.9798117280 0.9659097195 0.9541785121 + 0.9799193740 0.9660761952 0.9544466734 + 0.9800233841 0.9662427902 0.9547150135 + 0.9801273942 0.9664093852 0.9549832940 + 0.9802314043 0.9665759802 0.9552515745 + 0.9803354144 0.9667425752 0.9555094838 + 0.9804394245 0.9669076800 0.9557638168 + 0.9805418849 0.9670665264 0.9560182095 + 0.9806420207 0.9672253132 0.9562726021 + 0.9807420969 0.9673839808 0.9565269947 + 0.9808421731 0.9675428271 0.9567813873 + 0.9809423089 0.9677016139 0.9570345283 + 0.9810423851 0.9678602815 0.9572860003 + 0.9811419249 0.9680219889 0.9575374126 + 0.9812365174 0.9681841135 0.9577888250 + 0.9813309908 0.9683461785 0.9580402970 + 0.9814255834 0.9685081840 0.9582917094 + 0.9815201163 0.9686703086 0.9585428834 + 0.9816147089 0.9688323736 0.9587876201 + 0.9817091823 0.9689944983 0.9590322971 + 0.9817987084 0.9691566229 0.9592769146 + 0.9818863273 0.9693186879 0.9595215917 + 0.9819738865 0.9694808125 0.9597663283 + 0.9820615053 0.9696428776 0.9600110054 + 0.9821491241 0.9698050022 0.9602541924 + 0.9822366834 0.9699668884 0.9604964256 + 0.9823241830 0.9701260924 0.9607385993 + 0.9824113846 0.9702852964 0.9609807730 + 0.9824985862 0.9704445004 0.9612230062 + 0.9825857878 0.9706035852 0.9614651203 + 0.9826729298 0.9707627892 0.9617071152 + 0.9827600718 0.9709219933 0.9619415998 + 0.9828472733 0.9710779786 0.9621762037 + 0.9829329252 0.9712315798 0.9624108076 + 0.9830182195 0.9713851213 0.9626452923 + 0.9831033945 0.9715387225 0.9628798962 + 0.9831886888 0.9716922045 0.9631145000 + 0.9832739234 0.9718458056 0.9633466005 + 0.9833592176 0.9719992876 0.9635754228 + 0.9834436178 0.9721450210 0.9638043046 + 0.9835252166 0.9722905159 0.9640331864 + 0.9836068749 0.9724360704 0.9642621279 + 0.9836885929 0.9725816250 0.9644908905 + 0.9837701917 0.9727271199 0.9647197723 + 0.9838519096 0.9728726149 0.9649403095 + 0.9839335084 0.9730172753 0.9651581049 + 0.9840176105 0.9731602073 0.9653759003 + 0.9841032028 0.9733030796 0.9655936956 + 0.9841887951 0.9734460711 0.9658116102 + 0.9842743874 0.9735890031 0.9660294056 + 0.9843600988 0.9737318754 0.9662470818 + 0.9844456911 0.9738749266 0.9664586186 + 0.9845312834 0.9740148783 0.9666702151 + 0.9846189022 0.9741529226 0.9668816924 + 0.9847068191 0.9742910266 0.9670932293 + 0.9847946167 0.9744290709 0.9673047066 + 0.9848824739 0.9745671749 0.9675163031 + 0.9849703908 0.9747052193 0.9677258134 + 0.9850581884 0.9748433232 0.9679268003 + 0.9851459861 0.9749873877 0.9681277871 + 0.9852334261 0.9751328230 0.9683287740 + 0.9853208065 0.9752783179 0.9685298204 + 0.9854081869 0.9754236937 0.9687308073 + 0.9854956269 0.9755691886 0.9689317942 + 0.9855828881 0.9757146835 0.9691283703 + 0.9856703281 0.9758601189 0.9693145752 + 0.9857584238 0.9760093093 0.9695008993 + 0.9858487844 0.9761587977 0.9696871042 + 0.9859390855 0.9763082862 0.9698734283 + 0.9860295057 0.9764577746 0.9700595737 + 0.9861198068 0.9766073227 0.9702458978 + 0.9862102270 0.9767568111 0.9704262018 + 0.9863005280 0.9769061804 0.9705942273 + 0.9863908887 0.9770559072 0.9707623124 + 0.9864816070 0.9772055745 0.9709302783 + 0.9865723252 0.9773551822 0.9710983038 + 0.9866629839 0.9775049090 0.9712663889 + 0.9867537022 0.9776545763 0.9714344144 + 0.9868444204 0.9778043032 0.9715989828 + 0.9869350195 0.9779539108 0.9717546105 + 0.9870250821 0.9781007171 0.9719101787 + 0.9871137738 0.9782474041 0.9720658064 + 0.9872025251 0.9783940911 0.9722213745 + 0.9872910976 0.9785407782 0.9723770022 + 0.9873797894 0.9786874056 0.9725325704 + 0.9874684811 0.9788340926 0.9726879001 + 0.9875571132 0.9789807796 0.9728415012 + 0.9876449704 0.9791290164 0.9729952216 + 0.9877302051 0.9792773128 0.9731488824 + 0.9878153205 0.9794257283 0.9733024836 + 0.9879004955 0.9795740843 0.9734562039 + 0.9879856110 0.9797223806 0.9736099243 + 0.9880707860 0.9798707962 0.9737635255 + 0.9881559014 0.9800190926 0.9739124179 + 0.9882411957 0.9801667929 0.9740610719 + 0.9883286953 0.9803141952 0.9742097855 + 0.9884161949 0.9804617167 0.9743584991 + 0.9885035753 0.9806091189 0.9745070934 + 0.9885910749 0.9807565212 0.9746558070 + 0.9886785746 0.9809039235 0.9748045206 + 0.9887660146 0.9810513258 0.9749522209 + 0.9888535142 0.9811971784 0.9750993252 + 0.9889419079 0.9813411236 0.9752464890 + 0.9890304208 0.9814851284 0.9753937125 + 0.9891189933 0.9816290736 0.9755408764 + 0.9892076254 0.9817730784 0.9756880999 + 0.9892961979 0.9819170237 0.9758353233 + 0.9893847108 0.9820610285 0.9759811163 + 0.9894732833 0.9822043180 0.9761242867 + 0.9895619154 0.9823424220 0.9762675166 + 0.9896506071 0.9824805260 0.9764106870 + 0.9897391796 0.9826186895 0.9765539169 + 0.9898278117 0.9827567935 0.9766970873 + 0.9899165034 0.9828948975 0.9768403172 + 0.9900050759 0.9830330014 0.9769834280 + 0.9900938272 0.9831712246 0.9771208167 + 0.9901822805 0.9833034277 0.9772574902 + 0.9902700186 0.9834333062 0.9773942232 + 0.9903578162 0.9835631847 0.9775308967 + 0.9904454947 0.9836931229 0.9776676297 + 0.9905332923 0.9838230014 0.9778043032 + 0.9906209707 0.9839528799 0.9779409766 + 0.9907088280 0.9840828180 0.9780768752 + 0.9907965064 0.9842103124 0.9782114029 + 0.9908831120 0.9843295217 0.9783458114 + 0.9909690022 0.9844487906 0.9784802794 + 0.9910550117 0.9845681190 0.9786148071 + 0.9911409020 0.9846873283 0.9787492752 + 0.9912267923 0.9848065972 0.9788838029 + 0.9913126826 0.9849258065 0.9790182114 + 0.9913986921 0.9850450754 0.9791532755 + 0.9914844036 0.9851558208 0.9792885184 + 0.9915674925 0.9852620959 0.9794237018 + 0.9916505814 0.9853683114 0.9795590043 + 0.9917337894 0.9854745269 0.9796941876 + 0.9918168783 0.9855806828 0.9798293710 + 0.9919000864 0.9856870174 0.9799646139 + 0.9919831753 0.9857931733 0.9800996780 + 0.9920663834 0.9858993888 0.9802330732 + 0.9921478033 0.9859907031 0.9803665876 + 0.9922270775 0.9860820174 0.9805001020 + 0.9923064709 0.9861732721 0.9806334972 + 0.9923858047 0.9862647057 0.9807670116 + 0.9924650788 0.9863560200 0.9809004068 + 0.9925444126 0.9864472747 0.9810339212 + 0.9926236868 0.9865385890 0.9811660051 + 0.9927030802 0.9866275787 0.9812954068 + 0.9927787781 0.9867103100 0.9814248085 + 0.9928531051 0.9867929220 0.9815542102 + 0.9929273725 0.9868754745 0.9816836119 + 0.9930018187 0.9869580865 0.9818130732 + 0.9930760860 0.9870408177 0.9819424748 + 0.9931504130 0.9871234298 0.9820718765 + 0.9932246804 0.9872059822 0.9821982980 + 0.9932990074 0.9872871041 0.9823215008 + 0.9933676124 0.9873663783 0.9824448228 + 0.9934356213 0.9874455929 0.9825680852 + 0.9935035706 0.9875249267 0.9826912880 + 0.9935715795 0.9876040816 0.9828146100 + 0.9936395884 0.9876832962 0.9829378724 + 0.9937075973 0.9877625704 0.9830611944 + 0.9937756062 0.9878417850 0.9831799269 + 0.9938433766 0.9879186749 0.9832950234 + 0.9939035773 0.9879934192 0.9834101796 + 0.9939638972 0.9880682230 0.9835252762 + 0.9940240979 0.9881430268 0.9836404920 + 0.9940842986 0.9882177711 0.9837555885 + 0.9941444993 0.9882925749 0.9838708043 + 0.9942047000 0.9883673191 0.9839859009 + 0.9942649007 0.9884421229 0.9840955734 + 0.9943246841 0.9885138273 0.9842007160 + 0.9943755865 0.9885829091 0.9843057990 + 0.9944264293 0.9886521101 0.9844108224 + 0.9944772720 0.9887213111 0.9845159054 + 0.9945281148 0.9887903929 0.9846209884 + 0.9945790172 0.9888595939 0.9847260714 + 0.9946299195 0.9889286757 0.9848312140 + 0.9946807027 0.9889978766 0.9849311113 + 0.9947316051 0.9890637994 0.9850243926 + 0.9947717190 0.9891260266 0.9851177931 + 0.9948117137 0.9891883135 0.9852110744 + 0.9948517084 0.9892506003 0.9853044748 + 0.9948915839 0.9893128872 0.9853978157 + 0.9949315786 0.9893751740 0.9854912162 + 0.9949715734 0.9894374013 0.9855846167 + 0.9950115085 0.9894996881 0.9856761098 + 0.9950515032 0.9895594120 0.9857621193 + 0.9950813055 0.9896134734 0.9858481288 + 0.9951090217 0.9896675944 0.9859341979 + 0.9951366782 0.9897217155 0.9860202074 + 0.9951645136 0.9897757769 0.9861062169 + 0.9951922297 0.9898298979 0.9861922860 + 0.9952198863 0.9898840189 0.9862782955 + 0.9952477217 0.9899380207 0.9863643050 + 0.9952753782 0.9899916053 0.9864417911 + 0.9952955842 0.9900360703 0.9865189195 + 0.9953106046 0.9900807142 0.9865959883 + 0.9953256845 0.9901251793 0.9866731763 + 0.9953408241 0.9901698232 0.9867503047 + 0.9953557849 0.9902142882 0.9868274927 + 0.9953709245 0.9902588725 0.9869046211 + 0.9953858852 0.9903033972 0.9869816899 + 0.9954010248 0.9903479815 0.9870569706 + 0.9954146743 0.9903848171 0.9871309996 + 0.9954246283 0.9904186130 0.9872050285 + 0.9954345822 0.9904522896 0.9872788787 + 0.9954444766 0.9904860854 0.9873529077 + 0.9954544902 0.9905198216 0.9874268770 + 0.9954643846 0.9905534983 0.9875009060 + 0.9954743981 0.9905872941 0.9875748754 + 0.9954842925 0.9906209707 0.9876483083 + 0.9954943061 0.9906514287 0.9877181053 + 0.9954999089 0.9906733036 0.9877879024 + 0.9955047965 0.9906951189 0.9878576994 + 0.9955096245 0.9907169938 0.9879274964 + 0.9955145121 0.9907388091 0.9879974127 + 0.9955192804 0.9907606840 0.9880672097 + 0.9955242276 0.9907824993 0.9881370068 + 0.9955291152 0.9908043742 0.9882068038 + 0.9955338836 0.9908261895 0.9882770777 + 0.9955371022 0.9908388257 0.9883475900 + 0.9955371022 0.9908484817 0.9884182215 + 0.9955371022 0.9908581972 0.9884887934 + 0.9955371022 0.9908677936 0.9885594249 + 0.9955371022 0.9908775091 0.9886299968 + 0.9955371022 0.9908872247 0.9887005091 + 0.9955371022 0.9908968806 0.9887710810 + 0.9955371022 0.9909064770 0.9888417125 + 0.9955371022 0.9909154773 0.9889119267 + 0.9955376983 0.9909201860 0.9889820218 + 0.9955384135 0.9909248948 0.9890521765 + 0.9955391884 0.9909297228 0.9891223907 + 0.9955399036 0.9909343719 0.9891924858 + 0.9955406189 0.9909390807 0.9892627001 + 0.9955413938 0.9909437895 0.9893327951 + 0.9955421090 0.9909486175 0.9894030094 + 0.9955428839 0.9909533262 0.9894726872 + 0.9955435991 0.9909560084 0.9895405769 + 0.9955443740 0.9909560084 0.9896085262 + 0.9955450892 0.9909560084 0.9896764159 + 0.9955459237 0.9909560084 0.9897443056 + 0.9955465794 0.9909560084 0.9898123145 + 0.9955472946 0.9909560084 0.9898802042 + 0.9955481291 0.9909560084 0.9899480939 + 0.9955487847 0.9909560084 0.9900159836 + 0.9955496192 0.9909560084 0.9900823832 + 0.9955502748 0.9909573793 0.9901462197 + 0.9955511093 0.9909597039 0.9902099967 + 0.9955518246 0.9909620285 0.9902737141 + 0.9955524802 0.9909642935 0.9903374910 + 0.9955533147 0.9909666181 0.9904012084 + 0.9955539703 0.9909688830 0.9904649854 + 0.9955548048 0.9909712076 0.9905287027 + 0.9955555201 0.9909734726 0.9905924797 + 0.9955562949 0.9909757972 0.9906535745 + 0.9955570102 0.9909781218 0.9907112718 + 0.9955577850 0.9909803867 0.9907689095 + 0.9955585003 0.9909827113 0.9908266068 + 0.9955592155 0.9909849763 0.9908841848 + 0.9955599904 0.9909873009 0.9909418821 + 0.9955607057 0.9909896255 0.9909995198 + 0.9955614805 0.9909918904 0.9910572171 + 0.9955621958 0.9909942150 0.9911147952 + 0.9955629706 0.9909964800 0.9911692739 + 0.9955636859 0.9910038114 0.9912189841 + 0.9955644011 0.9910129905 0.9912686944 + 0.9955651760 0.9910221100 0.9913184047 + 0.9955658913 0.9910312891 0.9913681149 + 0.9955667257 0.9910405278 0.9914177060 + 0.9955673814 0.9910495877 0.9914674163 + 0.9955682158 0.9910588264 0.9915171266 + 0.9955688715 0.9910680056 0.9915667772 + 0.9955697060 0.9910771251 0.9916139841 + 0.9955704212 0.9910891056 0.9916545749 + 0.9955710769 0.9911026955 0.9916951060 + 0.9955719113 0.9911162853 0.9917356968 + 0.9955726266 0.9911298752 0.9917762280 + 0.9955734015 0.9911434054 0.9918168187 + 0.9955741167 0.9911569953 0.9918574095 + 0.9955748916 0.9911705852 0.9918978810 + 0.9955756068 0.9911841750 0.9919384718 + 0.9955763221 0.9911978245 0.9919788837 + 0.9955770969 0.9912132025 0.9920160770 + 0.9955778122 0.9912310243 0.9920532703 + 0.9955785871 0.9912489057 0.9920905232 + 0.9955793023 0.9912667274 0.9921277165 + 0.9955800772 0.9912844896 0.9921649098 + 0.9955807924 0.9913023114 0.9922021031 + 0.9955816269 0.9913200736 0.9922392964 + 0.9955822825 0.9913378954 0.9922764897 + 0.9955829978 0.9913557172 0.9923136830 + 0.9955837727 0.9913741946 0.9923480153 + 0.9955844879 0.9913958907 0.9923812747 + 0.9955853224 0.9914177060 0.9924144745 + 0.9955859780 0.9914395213 0.9924477935 + 0.9955868125 0.9914612770 0.9924809933 + 0.9955875278 0.9914830923 0.9925143123 + 0.9955881834 0.9915049076 0.9925475121 + 0.9955890179 0.9915266037 0.9925807118 + 0.9955896735 0.9915484190 0.9926139712 + 0.9955905080 0.9915701747 0.9926487803 + 0.9955912232 0.9915946722 0.9926875234 + 0.9955919981 0.9916201234 0.9927260876 + 0.9955927134 0.9916453958 0.9927647710 + 0.9955934882 0.9916707873 0.9928033948 + 0.9955942035 0.9916961193 0.9928420782 + 0.9955949187 0.9917215109 0.9928807020 + 0.9955956936 0.9917467833 0.9929193854 + 0.9955964088 0.9917721748 0.9929580092 + 0.9955971837 0.9917975068 0.9929966927 + 0.9955980182 0.9918254018 0.9930391908 + 0.9956101775 0.9918603897 0.9930828214 + 0.9956223965 0.9918953180 0.9931263924 + 0.9956346154 0.9919303060 0.9931700826 + 0.9956468940 0.9919652939 0.9932137132 + 0.9956591129 0.9920002222 0.9932574034 + 0.9956712723 0.9920352101 0.9933009744 + 0.9956834912 0.9920700788 0.9933447242 + 0.9956957102 0.9921051264 0.9933882952 + 0.9957079291 0.9921399951 0.9934325218 + 0.9957221746 0.9921805263 0.9934805036 + 0.9957391024 0.9922237992 0.9935284853 + 0.9957559705 0.9922670722 0.9935765266 + 0.9957728982 0.9923102856 0.9936243892 + 0.9957898259 0.9923536181 0.9936723709 + 0.9958066940 0.9923968911 0.9937204123 + 0.9958236814 0.9924401045 0.9937682748 + 0.9958406091 0.9924833775 0.9938163161 + 0.9958574772 0.9925267100 0.9938642979 + 0.9958744049 0.9925699234 0.9939137101 + 0.9958940744 0.9926193953 0.9939653277 + 0.9959146976 0.9926689863 0.9940168262 + 0.9959353805 0.9927186966 0.9940683842 + 0.9959560037 0.9927682877 0.9941200018 + 0.9959766865 0.9928179979 0.9941715002 + 0.9959973097 0.9928675890 0.9942231178 + 0.9960179925 0.9929172993 0.9942746162 + 0.9960386157 0.9929668903 0.9943261743 + 0.9960592985 0.9930166006 0.9943777919 + 0.9960799217 0.9930669069 0.9944308996 + 0.9961034060 0.9931212068 0.9944851995 + 0.9961270094 0.9931753874 0.9945394993 + 0.9961506128 0.9932296276 0.9945937991 + 0.9961740971 0.9932839274 0.9946479797 + 0.9961977005 0.9933381081 0.9947022796 + 0.9962213039 0.9933922887 0.9947565794 + 0.9962449074 0.9934465885 0.9948108792 + 0.9962685108 0.9935008287 0.9948651791 + 0.9962921143 0.9935550094 0.9949194789 + 0.9963157773 0.9936100245 0.9949749112 + 0.9963418245 0.9936673045 0.9950308800 + 0.9963676929 0.9937245846 0.9950869083 + 0.9963936210 0.9937819242 0.9951428771 + 0.9964196086 0.9938392043 0.9951989055 + 0.9964454770 0.9938964844 0.9952549934 + 0.9964715242 0.9939538240 0.9953110218 + 0.9964973927 0.9940111041 0.9953669906 + 0.9965233207 0.9940683842 0.9954230189 + 0.9965493083 0.9941257238 0.9954789877 + 0.9965752959 0.9941834211 0.9955353737 + 0.9966030717 0.9942424893 0.9955919981 + 0.9966309071 0.9943016768 0.9956486225 + 0.9966586828 0.9943608046 0.9957051873 + 0.9966865182 0.9944199920 0.9957618713 + 0.9967144132 0.9944791794 0.9958184958 + 0.9967421889 0.9945383072 0.9958751202 + 0.9967700243 0.9945974946 0.9959316850 + 0.9967978001 0.9946566224 0.9959883094 + 0.9968255758 0.9947158098 0.9960448742 + 0.9968534112 0.9947745800 0.9961013198 + 0.9968826771 0.9948306084 0.9961574078 + 0.9969120026 0.9948865175 0.9962133765 + 0.9969413280 0.9949424267 0.9962695241 + 0.9969705939 0.9949982762 0.9963254929 + 0.9969999194 0.9950541854 0.9963815212 + 0.9970293045 0.9951100945 0.9964376092 + 0.9970585704 0.9951661229 0.9964935780 + 0.9970878959 0.9952219725 0.9965497255 + 0.9971172214 0.9952778816 0.9966056943 + 0.9971464872 0.9953337908 0.9966616035 + 0.9971768856 0.9953922033 0.9967159033 + 0.9972077012 0.9954509735 0.9967702031 + 0.9972383976 0.9955098033 0.9968245029 + 0.9972692132 0.9955686927 0.9968789220 + 0.9973000288 0.9956275225 0.9969332218 + 0.9973307848 0.9956862926 0.9969875216 + 0.9973614812 0.9957451224 0.9970418811 + 0.9973922968 0.9958038926 0.9970961809 + 0.9974231124 0.9958627224 0.9971504807 + 0.9974539280 0.9959216118 0.9972047806 + 0.9974855185 0.9959818721 0.9972571731 + 0.9975185990 0.9960436821 0.9973087907 + 0.9975516796 0.9961054921 0.9973604083 + 0.9975848198 0.9961673021 0.9974119067 + 0.9976179004 0.9962291121 0.9974635243 + 0.9976509809 0.9962909222 0.9975150824 + 0.9976841211 0.9963526726 0.9975667000 + 0.9977172017 0.9964144826 0.9976183176 + 0.9977502823 0.9964762926 0.9976698756 + 0.9977834225 0.9965381026 0.9977214932 + 0.9978165030 0.9965999722 0.9977722764 + 0.9978520870 0.9966641068 0.9978203177 + 0.9978877902 0.9967283010 0.9978682995 + 0.9979234934 0.9967923760 0.9979162812 + 0.9979591966 0.9968565702 0.9979643226 + 0.9979950190 0.9969207048 0.9980123043 + 0.9980307221 0.9969848990 0.9980602860 + 0.9980664253 0.9970489740 0.9981083274 + 0.9981021881 0.9971132278 0.9981563091 + 0.9981378913 0.9971773028 0.9982042909 + 0.9981735945 0.9972414970 0.9982522726 + 0.9982103705 0.9973062277 0.9982975721 + 0.9982488155 0.9973716736 0.9983413815 + 0.9982872009 0.9974371791 0.9983850718 + 0.9983255863 0.9975026846 0.9984288812 + 0.9983639717 0.9975680709 0.9984725714 + 0.9984024167 0.9976335764 0.9985163808 + 0.9984408021 0.9976990819 0.9985600710 + 0.9984791875 0.9977645874 0.9986038804 + 0.9985176921 0.9978300929 0.9986475706 + 0.9985560775 0.9978954792 0.9986913800 + 0.9985945225 0.9979609847 0.9987350702 + 0.9986345768 0.9980263114 0.9987767935 + 0.9986755252 0.9980915785 0.9988182187 + 0.9987164140 0.9981567860 0.9988597035 + 0.9987573028 0.9982221127 0.9989011288 + 0.9987981915 0.9982873797 0.9989426136 + 0.9988390803 0.9983525872 0.9989839792 + 0.9988800287 0.9984179139 0.9990255237 + 0.9989209175 0.9984831214 0.9990668893 + 0.9989618063 0.9985483885 0.9991083741 + 0.9990026951 0.9986137152 0.9991497993 + 0.9990435839 0.9986789227 0.9991911054 + 0.9990863204 0.9987418056 0.9992294908 + 0.9991291761 0.9988046288 0.9992678165 + 0.9991720915 0.9988675117 0.9993060827 + 0.9992150068 0.9989302754 0.9993445277 + 0.9992579222 0.9989930987 0.9993827939 + 0.9993007779 0.9990559220 0.9994211793 + 0.9993436933 0.9991186857 0.9994595051 + 0.9993866086 0.9991815090 0.9994978905 + 0.9994295239 0.9992442727 0.9995362163 + 0.9994723797 0.9993070960 0.9995746017 + 0.9995154142 0.9993696809 0.9996126294 + 0.9995594025 0.9994270205 0.9996479154 + 0.9996035099 0.9994843006 0.9996830821 + 0.9996474981 0.9995415807 0.9997183084 + 0.9996916056 0.9995989203 0.9997534752 + 0.9997357130 0.9996562004 0.9997887015 + 0.9997797012 0.9997134805 0.9998239279 + 0.9998238087 0.9997708201 0.9998590946 + 0.9998677969 0.9998281002 0.9998943806 + 0.9999119043 0.9998853803 0.9999296069 + 0.9999558926 0.9999427199 0.9999647737 + 1.0000000000 1.0000000000 1.0000000000 +} diff --git a/rpplugins/color_correction/resources/film_luts_raw/kodak_ektachrome_e100s.spi1d b/rpplugins/color_correction/resources/film_luts_raw/kodak_ektachrome_e100s.spi1d new file mode 100644 index 0000000..cad63e6 --- /dev/null +++ b/rpplugins/color_correction/resources/film_luts_raw/kodak_ektachrome_e100s.spi1d @@ -0,0 +1,1030 @@ +Version 1 +From 0.0 1.0 +Length 1024 +Components 3 +{ + 0.0000000000 0.0000000000 0.0000000000 + 0.0003622885 0.0002231146 0.0002231146 + 0.0007382494 0.0004596260 0.0004596260 + 0.0011324980 0.0007107497 0.0007107497 + 0.0015447290 0.0009748340 0.0009748340 + 0.0019822840 0.0012541140 0.0012541140 + 0.0024496829 0.0015510730 0.0015510730 + 0.0029426741 0.0018673710 0.0018673710 + 0.0034610520 0.0022024000 0.0022024000 + 0.0040061148 0.0025572821 0.0025572821 + 0.0045792251 0.0029304300 0.0029304300 + 0.0051838872 0.0033235741 0.0033235741 + 0.0058237561 0.0037373570 0.0037373570 + 0.0064960350 0.0041693011 0.0041693011 + 0.0072039221 0.0046230098 0.0046230098 + 0.0079505397 0.0050979760 0.0050979760 + 0.0087367687 0.0055915830 0.0055915830 + 0.0095584840 0.0061070491 0.0061070491 + 0.0104124900 0.0066442229 0.0066442229 + 0.0112989703 0.0071999640 0.0071999640 + 0.0122200102 0.0077770371 0.0077770371 + 0.0131755099 0.0083772372 0.0083772372 + 0.0141713005 0.0089993617 0.0089993617 + 0.0152068604 0.0096444618 0.0096444618 + 0.0162801705 0.0103151305 0.0103151305 + 0.0173835605 0.0110131698 0.0110131698 + 0.0185210407 0.0117386896 0.0117386896 + 0.0196854398 0.0124893300 0.0124893300 + 0.0208813995 0.0132624302 0.0132624302 + 0.0221185796 0.0140622798 0.0140622798 + 0.0234044399 0.0148894899 0.0148894899 + 0.0247398503 0.0157391094 0.0157391094 + 0.0261158608 0.0166204907 0.0166204907 + 0.0275394097 0.0175324902 0.0175324902 + 0.0290060304 0.0184764005 0.0184764005 + 0.0305129606 0.0194491595 0.0194491595 + 0.0320634693 0.0204504505 0.0204504505 + 0.0336536989 0.0214823205 0.0214823205 + 0.0352861397 0.0225437600 0.0225437600 + 0.0369675495 0.0236390196 0.0236390196 + 0.0386981517 0.0247705802 0.0247705802 + 0.0404745191 0.0259348303 0.0259348303 + 0.0422977097 0.0271375105 0.0271375105 + 0.0441726409 0.0283817798 0.0283817798 + 0.0460996106 0.0296590906 0.0296590906 + 0.0480887406 0.0309759099 0.0309759099 + 0.0501275212 0.0323227607 0.0323227607 + 0.0522207692 0.0337067991 0.0337067991 + 0.0543671884 0.0351255499 0.0351255499 + 0.0565663688 0.0365805998 0.0365805998 + 0.0588187315 0.0380711295 0.0380711295 + 0.0611272007 0.0396083593 0.0396083593 + 0.0634748489 0.0411784090 0.0411784090 + 0.0658760667 0.0427908003 0.0427908003 + 0.0683400705 0.0444480814 0.0444480814 + 0.0708511695 0.0461456515 0.0461456515 + 0.0734233931 0.0478809699 0.0478809699 + 0.0760477036 0.0496524908 0.0496524908 + 0.0787281767 0.0514654815 0.0514654815 + 0.0814533383 0.0533178188 0.0533178188 + 0.0842291415 0.0552090518 0.0552090518 + 0.0870640278 0.0571336001 0.0571336001 + 0.0899450928 0.0590961091 0.0590961091 + 0.0928783119 0.0610942282 0.0610942282 + 0.0958742201 0.0631353706 0.0631353706 + 0.0989081487 0.0652145892 0.0652145892 + 0.1019897982 0.0673257634 0.0673257634 + 0.1051272005 0.0694703013 0.0694703013 + 0.1083052009 0.0716492608 0.0716492608 + 0.1115389019 0.0738634914 0.0738634914 + 0.1148212031 0.0761086568 0.0761086568 + 0.1181529984 0.0783852488 0.0783852488 + 0.1215258017 0.0806891099 0.0806891099 + 0.1249411032 0.0830274820 0.0830274820 + 0.1283981055 0.0854015574 0.0854015574 + 0.1318998039 0.0878068879 0.0878068879 + 0.1354435980 0.0902427882 0.0902427882 + 0.1390310973 0.0927055702 0.0927055702 + 0.1426659971 0.0952004492 0.0952004492 + 0.1463364065 0.0977323800 0.0977323800 + 0.1500398070 0.1002930999 0.1002930999 + 0.1537826061 0.1028838009 0.1028838009 + 0.1575697958 0.1055003032 0.1055003032 + 0.1613817066 0.1081380993 0.1081380993 + 0.1652164012 0.1108009964 0.1108009964 + 0.1690932959 0.1134867966 0.1134867966 + 0.1729968935 0.1161940992 0.1161940992 + 0.1769410968 0.1189275980 0.1189275980 + 0.1809352040 0.1216920018 0.1216920018 + 0.1849523038 0.1244781017 0.1244781017 + 0.1889985055 0.1272816956 0.1272816956 + 0.1930781007 0.1301010996 0.1301010996 + 0.1971940994 0.1329389066 0.1329389066 + 0.2013469040 0.1358011961 0.1358011961 + 0.2055312991 0.1386940926 0.1386940926 + 0.2097439021 0.1416130960 0.1416130960 + 0.2139831036 0.1445533037 0.1445533037 + 0.2182556987 0.1475161016 0.1475161016 + 0.2225302011 0.1505060941 0.1505060941 + 0.2268306017 0.1535229981 0.1535229981 + 0.2311580926 0.1565562934 0.1565562934 + 0.2355093956 0.1596101969 0.1596101969 + 0.2398717999 0.1626808047 0.1626808047 + 0.2442272007 0.1657689065 0.1657689065 + 0.2485899031 0.1688731015 0.1688731015 + 0.2529604137 0.1719909012 0.1719909012 + 0.2573277056 0.1751365066 0.1751365066 + 0.2616989017 0.1782941073 0.1782941073 + 0.2660799026 0.1814624071 0.1814624071 + 0.2704606056 0.1846423000 0.1846423000 + 0.2748312056 0.1878450066 0.1878450066 + 0.2791987956 0.1910510063 0.1910510063 + 0.2835668027 0.1942614019 0.1942614019 + 0.2879388928 0.1974803954 0.1974803954 + 0.2923108041 0.2007077038 0.2007077038 + 0.2966752946 0.2039379030 0.2039379030 + 0.3010303974 0.2071726024 0.2071726024 + 0.3053742945 0.2104312927 0.2104312927 + 0.3097003102 0.2136991024 0.2136991024 + 0.3140352070 0.2169768065 0.2169768065 + 0.3183707893 0.2202724963 0.2202724963 + 0.3226906061 0.2235676050 0.2235676050 + 0.3270021975 0.2268693000 0.2268693000 + 0.3313120902 0.2301850021 0.2301850021 + 0.3356218934 0.2334984988 0.2334984988 + 0.3399325907 0.2368156016 0.2368156016 + 0.3442339897 0.2401401997 0.2401401997 + 0.3485251963 0.2434774041 0.2434774041 + 0.3527927101 0.2468263060 0.2468263060 + 0.3570409119 0.2501969039 0.2501969039 + 0.3612729013 0.2535721958 0.2535721958 + 0.3654753864 0.2569538951 0.2569538951 + 0.3696604967 0.2603574097 0.2603574097 + 0.3738316894 0.2637628019 0.2637628019 + 0.3779726923 0.2671697140 0.2671697140 + 0.3820927143 0.2705962062 0.2705962062 + 0.3861967027 0.2740235031 0.2740235031 + 0.3902786970 0.2774519026 0.2774519026 + 0.3943498135 0.2808937132 0.2808937132 + 0.3984076083 0.2843413949 0.2843413949 + 0.4024240077 0.2878027856 0.2878027856 + 0.4064257145 0.2912661135 0.2912661135 + 0.4104036987 0.2947317958 0.2947317958 + 0.4143416882 0.2981860042 0.2981860042 + 0.4182564914 0.3016363978 0.3016363978 + 0.4221282005 0.3050855994 0.3050855994 + 0.4259957075 0.3085319102 0.3085319102 + 0.4298554957 0.3119722009 0.3119722009 + 0.4336968064 0.3154138923 0.3154138923 + 0.4375284910 0.3188566864 0.3188566864 + 0.4413171113 0.3222773075 0.3222773075 + 0.4450969100 0.3256925941 0.3256925941 + 0.4488551915 0.3290956020 0.3290956020 + 0.4526067972 0.3324885964 0.3324885964 + 0.4563522935 0.3358506858 0.3358506858 + 0.4600827098 0.3392089009 0.3392089009 + 0.4638085067 0.3425619900 0.3425619900 + 0.4674848914 0.3459056914 0.3459056914 + 0.4711487889 0.3492426872 0.3492426872 + 0.4747653008 0.3525683880 0.3525683880 + 0.4783576131 0.3558900058 0.3558900058 + 0.4819136858 0.3591865897 0.3591865897 + 0.4854589999 0.3624787927 0.3624787927 + 0.4889962077 0.3657391071 0.3657391071 + 0.4925225973 0.3689970076 0.3689970076 + 0.4960449040 0.3722279966 0.3722279966 + 0.4995129108 0.3754577041 0.3754577041 + 0.5029718280 0.3786748946 0.3786748946 + 0.5064191222 0.3818857074 0.3818857074 + 0.5098642111 0.3850541115 0.3850541115 + 0.5132802725 0.3882220984 0.3882220984 + 0.5166903138 0.3913877010 0.3913877010 + 0.5200588107 0.3945508003 0.3945508003 + 0.5234236717 0.3976989985 0.3976989985 + 0.5267717838 0.4008451104 0.4008451104 + 0.5301045775 0.4039750993 0.4039750993 + 0.5333794951 0.4071030021 0.4071030021 + 0.5366390944 0.4102006853 0.4102006853 + 0.5398436189 0.4132984877 0.4132984877 + 0.5430372953 0.4163655937 0.4163655937 + 0.5461881757 0.4194326997 0.4194326997 + 0.5493322015 0.4224604964 0.4224604964 + 0.5524412990 0.4254842997 0.4254842997 + 0.5555446744 0.4284946918 0.4284946918 + 0.5586010814 0.4315015972 0.4315015972 + 0.5616549253 0.4344901145 0.4344901145 + 0.5646228194 0.4374687970 0.4374687970 + 0.5675905943 0.4404281080 0.4404281080 + 0.5705261230 0.4433673024 0.4433673024 + 0.5734590292 0.4462912083 0.4462912083 + 0.5763446093 0.4491803050 0.4491803050 + 0.5792183876 0.4520643055 0.4520643055 + 0.5820407867 0.4549018145 0.4549018145 + 0.5848355889 0.4577394128 0.4577394128 + 0.5875927210 0.4605427086 0.4605427086 + 0.5903086066 0.4633406997 0.4633406997 + 0.5930045843 0.4661261141 0.4661261141 + 0.5956503153 0.4689033926 0.4689033926 + 0.5982949138 0.4716737866 0.4716737866 + 0.6009235978 0.4744301140 0.4744301140 + 0.6035524011 0.4771854877 0.4771854877 + 0.6061716080 0.4799031019 0.4799031019 + 0.6087887883 0.4826206863 0.4826206863 + 0.6113740206 0.4853239954 0.4853239954 + 0.6139330864 0.4880208969 0.4880208969 + 0.6164814830 0.4907048047 0.4907048047 + 0.6189994812 0.4933629036 0.4933629036 + 0.6215174794 0.4960210919 0.4960210919 + 0.6240079999 0.4986290932 0.4986290932 + 0.6264969110 0.5012347102 0.5012347102 + 0.6289771795 0.5038244128 0.5038244128 + 0.6314516068 0.5064008236 0.5064008236 + 0.6339148283 0.5089727044 0.5089727044 + 0.6363407969 0.5115088224 0.5115088224 + 0.6387668252 0.5140448213 0.5140448213 + 0.6411426067 0.5165610909 0.5165610909 + 0.6435087919 0.5190668106 0.5190668106 + 0.6458575130 0.5215663910 0.5215663910 + 0.6481820941 0.5240356922 0.5240356922 + 0.6505066752 0.5265049934 0.5265049934 + 0.6528093815 0.5289555192 0.5289555192 + 0.6551114917 0.5313962102 0.5313962102 + 0.6573888063 0.5338327885 0.5338327885 + 0.6596413255 0.5362383723 0.5362383723 + 0.6618937254 0.5386438966 0.5386438966 + 0.6641113162 0.5410385132 0.5410385132 + 0.6663289070 0.5434240103 0.5434240103 + 0.6685289741 0.5458095074 0.5458095074 + 0.6707097888 0.5481578112 0.5481578112 + 0.6728904843 0.5505042076 0.5505042076 + 0.6750382781 0.5528417826 0.5528417826 + 0.6771832705 0.5551611185 0.5551611185 + 0.6793134809 0.5574803948 0.5574803948 + 0.6814150810 0.5597792864 0.5597792864 + 0.6835166812 0.5620682836 0.5620682836 + 0.6855754852 0.5643572211 0.5643572211 + 0.6876184940 0.5665962100 0.5665962100 + 0.6896557808 0.5688347220 0.5688347220 + 0.6916378736 0.5710633993 0.5710633993 + 0.6936199069 0.5732669830 0.5732669830 + 0.6955876946 0.5754706860 0.5754706860 + 0.6975364089 0.5776560903 0.5776560903 + 0.6994851232 0.5798259974 0.5798259974 + 0.7013980150 0.5819959044 0.5819959044 + 0.7032977939 0.5841305852 0.5841305852 + 0.7051973939 0.5862547755 0.5862547755 + 0.7070760727 0.5883789062 0.5883789062 + 0.7089548111 0.5904625058 0.5904625058 + 0.7108243704 0.5925447941 0.5925447941 + 0.7126672864 0.5946221948 0.5946221948 + 0.7145102024 0.5966691971 0.5966691971 + 0.7163286209 0.5987161994 0.5987161994 + 0.7181193829 0.6007555127 0.6007555127 + 0.7199102044 0.6027747989 0.6027747989 + 0.7216753960 0.6047940254 0.6047940254 + 0.7234271765 0.6068055034 0.6068055034 + 0.7251790166 0.6088048220 0.6088048220 + 0.7269017100 0.6108040214 0.6108040214 + 0.7286177278 0.6127884984 0.6127884984 + 0.7303336263 0.6147556901 0.6147556901 + 0.7319886088 0.6167228818 0.6167228818 + 0.7336395979 0.6186692119 0.6186692119 + 0.7352887988 0.6205952168 0.6205952168 + 0.7368847132 0.6225212216 0.6225212216 + 0.7384806275 0.6244304776 0.6244304776 + 0.7400730848 0.6263242960 0.6263242960 + 0.7416328788 0.6282181740 0.6282181740 + 0.7431927919 0.6301015019 0.6301015019 + 0.7447494268 0.6319742799 0.6319742799 + 0.7462829947 0.6338471174 0.6338471174 + 0.7478165030 0.6356995106 0.6356995106 + 0.7493439913 0.6375269890 0.6375269890 + 0.7508273125 0.6393544078 0.6393544078 + 0.7523106933 0.6411694288 0.6411694288 + 0.7537910938 0.6429628134 0.6429628134 + 0.7552406788 0.6447560787 0.6447560787 + 0.7566903234 0.6465445161 0.6465445161 + 0.7581396103 0.6483175755 0.6483175755 + 0.7595729828 0.6500906944 0.6500906944 + 0.7610062957 0.6518586874 0.6518586874 + 0.7624397278 0.6535770297 0.6535770297 + 0.7638341784 0.6552951932 0.6552951932 + 0.7652254105 0.6570134759 0.6570134759 + 0.7666165233 0.6587092280 0.6587092280 + 0.7679901719 0.6604024768 0.6604024768 + 0.7693589926 0.6620957851 0.6620957851 + 0.7707278728 0.6637632847 0.6637632847 + 0.7720705867 0.6654189229 0.6654189229 + 0.7733970284 0.6670743823 0.6670743823 + 0.7747234702 0.6687203050 0.6687203050 + 0.7760393023 0.6703534126 0.6703534126 + 0.7773399949 0.6719865203 0.6719865203 + 0.7786408067 0.6736162901 0.6736162901 + 0.7799372077 0.6752253771 0.6752253771 + 0.7812135220 0.6768345833 0.6768345833 + 0.7824897170 0.6784437895 0.6784437895 + 0.7837659717 0.6800181270 0.6800181270 + 0.7850177884 0.6815842986 0.6815842986 + 0.7862669826 0.6831504703 0.6831504703 + 0.7875161767 0.6846908927 0.6846908927 + 0.7887520194 0.6861993074 0.6861993074 + 0.7899786830 0.6877077222 0.6877077222 + 0.7912054062 0.6892145872 0.6892145872 + 0.7924262285 0.6906890869 0.6906890869 + 0.7936294079 0.6921635866 0.6921635866 + 0.7948325872 0.6936382055 0.6936382055 + 0.7960357070 0.6950960159 0.6950960159 + 0.7972220778 0.6965432167 0.6965432167 + 0.7984061241 0.6979902983 0.6979902983 + 0.7995899916 0.6994342804 0.6994342804 + 0.8007580042 0.7008578181 0.7008578181 + 0.8019068241 0.7022812963 0.7022812963 + 0.8030557036 0.7037047744 0.7037047744 + 0.8042045236 0.7051180005 0.7051180005 + 0.8053393960 0.7065249085 0.7065249085 + 0.8064743876 0.7079318166 0.7079318166 + 0.8076093793 0.7093364000 0.7093364000 + 0.8087307215 0.7107117772 0.7107117772 + 0.8098388910 0.7120870948 0.7120870948 + 0.8109471798 0.7134624124 0.7134624124 + 0.8120555282 0.7148199081 0.7148199081 + 0.8131191134 0.7161585093 0.7161585093 + 0.8141819239 0.7174972296 0.7174972296 + 0.8152446747 0.7188357711 0.7188357711 + 0.8162903190 0.7201492190 0.7201492190 + 0.8173117042 0.7214584947 0.7214584947 + 0.8183330894 0.7227677703 0.7227677703 + 0.8193544149 0.7240737081 0.7240737081 + 0.8203511238 0.7253654003 0.7253654003 + 0.8213419914 0.7266569734 0.7266569734 + 0.8223329186 0.7279486060 0.7279486060 + 0.8233172894 0.7292181849 0.7292181849 + 0.8242688179 0.7304645777 0.7304645777 + 0.8252202272 0.7317109704 0.7317109704 + 0.8261716962 0.7329574227 0.7329574227 + 0.8271054029 0.7341820002 0.7341820002 + 0.8280197978 0.7353988290 0.7353988290 + 0.8289341927 0.7366157174 0.7366157174 + 0.8298485875 0.7378326058 0.7378326058 + 0.8307464719 0.7390285134 0.7390285134 + 0.8316389918 0.7402232885 0.7402232885 + 0.8325315118 0.7414181828 0.7414181828 + 0.8334239721 0.7426074743 0.7426074743 + 0.8342829943 0.7437586784 0.7437586784 + 0.8351417184 0.7449098229 0.7449098229 + 0.8360003829 0.7460609078 0.7460609078 + 0.8368576169 0.7472000122 0.7472000122 + 0.8377087116 0.7483038902 0.7483038902 + 0.8385598063 0.7494078875 0.7494078875 + 0.8394109011 0.7505118251 0.7505118251 + 0.8402518034 0.7516049743 0.7516049743 + 0.8410723209 0.7526779175 0.7526779175 + 0.8418927789 0.7537506819 0.7537506819 + 0.8427134156 0.7548235059 0.7548235059 + 0.8435238004 0.7558841705 0.7558841705 + 0.8443217278 0.7569258809 0.7569258809 + 0.8451194763 0.7579675913 0.7579675913 + 0.8459174037 0.7590093017 0.7590093017 + 0.8467006087 0.7600433230 0.7600433230 + 0.8474699259 0.7610656023 0.7610656023 + 0.8482393026 0.7620878220 0.7620878220 + 0.8490086198 0.7631099820 0.7631099820 + 0.8497787714 0.7641208768 0.7641208768 + 0.8505498171 0.7651112080 0.7651112080 + 0.8513206840 0.7661014795 0.7661014795 + 0.8520916104 0.7670918107 0.7670918107 + 0.8528512120 0.7680724263 0.7680724263 + 0.8536006212 0.7690268159 0.7690268159 + 0.8543499708 0.7699812055 0.7699812055 + 0.8550993800 0.7709355950 0.7709355950 + 0.8558359146 0.7718878984 0.7718878984 + 0.8565574884 0.7728270292 0.7728270292 + 0.8572790027 0.7737662196 0.7737662196 + 0.8580005765 0.7747054100 0.7747054100 + 0.8587099910 0.7756444812 0.7756444812 + 0.8593978286 0.7765566707 0.7765566707 + 0.8600856066 0.7774680257 0.7774680257 + 0.8607733846 0.7783793211 0.7783793211 + 0.8614575863 0.7792906165 0.7792906165 + 0.8621283770 0.7801936865 0.7801936865 + 0.8627992272 0.7810940146 0.7810940146 + 0.8634700179 0.7819942832 0.7819942832 + 0.8641406894 0.7828946114 0.7828946114 + 0.8648099899 0.7837845087 0.7837845087 + 0.8654794097 0.7846636772 0.7846636772 + 0.8661487103 0.7855427861 0.7855427861 + 0.8668180108 0.7864218950 0.7864218950 + 0.8674687743 0.7872971892 0.7872971892 + 0.8681142926 0.7881550193 0.7881550193 + 0.8687598109 0.7890126705 0.7890126705 + 0.8694053292 0.7898705006 0.7898705006 + 0.8700295091 0.7907282114 0.7907282114 + 0.8706318736 0.7915742993 0.7915742993 + 0.8712342978 0.7924178839 0.7924178839 + 0.8718366027 0.7932615280 0.7932615280 + 0.8724340200 0.7941049933 0.7941049933 + 0.8730055094 0.7949374914 0.7949374914 + 0.8735769987 0.7957543135 0.7957543135 + 0.8741484880 0.7965711951 0.7965711951 + 0.8747199774 0.7973880172 0.7973880172 + 0.8752837777 0.7982048988 0.7982048988 + 0.8758454919 0.7989869118 0.7989869118 + 0.8764070868 0.7997676134 0.7997676134 + 0.8769688010 0.8005483150 0.8005483150 + 0.8775206208 0.8013290167 0.8013290167 + 0.8780546188 0.8021016717 0.8021016717 + 0.8785886765 0.8028652072 0.8028652072 + 0.8791226745 0.8036286831 0.8036286831 + 0.8796567917 0.8043922186 0.8043922186 + 0.8801620007 0.8051556945 0.8051556945 + 0.8806633949 0.8058984876 0.8058984876 + 0.8811649084 0.8066393733 0.8066393733 + 0.8816663027 0.8073803186 0.8073803186 + 0.8821567297 0.8081210852 0.8081210852 + 0.8826276064 0.8088607192 0.8088607192 + 0.8830984831 0.8095976114 0.8095976114 + 0.8835694194 0.8103343844 0.8103343844 + 0.8840402961 0.8110712171 0.8110712171 + 0.8845028877 0.8118081093 0.8118081093 + 0.8849632740 0.8125373125 0.8125373125 + 0.8854237199 0.8132628202 0.8132628202 + 0.8858841062 0.8139883280 0.8139883280 + 0.8863461018 0.8147137761 0.8147137761 + 0.8868156075 0.8154392838 0.8154392838 + 0.8872851133 0.8161317110 0.8161317110 + 0.8877546191 0.8168231845 0.8168231845 + 0.8882240057 0.8175147176 0.8175147176 + 0.8886895180 0.8182061911 0.8182061911 + 0.8891507983 0.8188943863 0.8188943863 + 0.8896121979 0.8195710182 0.8195710182 + 0.8900735974 0.8202475905 0.8202475905 + 0.8905348778 0.8209241033 0.8209241033 + 0.8909785748 0.8216006756 0.8216006756 + 0.8914170861 0.8222699761 0.8222699761 + 0.8918557167 0.8229292035 0.8229292035 + 0.8922942281 0.8235884905 0.8235884905 + 0.8927327991 0.8242477179 0.8242477179 + 0.8931676149 0.8249068856 0.8249068856 + 0.8936023712 0.8255603909 0.8255603909 + 0.8940371871 0.8262094259 0.8262094259 + 0.8944720030 0.8268585205 0.8268585205 + 0.8949096203 0.8275076151 0.8275076151 + 0.8953595161 0.8281567097 0.8281567097 + 0.8958094716 0.8287855983 0.8287855983 + 0.8962594271 0.8294041753 0.8294041753 + 0.8967093825 0.8300228119 0.8300228119 + 0.8971595168 0.8306415081 0.8306415081 + 0.8976098895 0.8312600851 0.8312600851 + 0.8980603218 0.8318728209 0.8318728209 + 0.8985106945 0.8324831128 0.8324831128 + 0.8989611268 0.8330934048 0.8330934048 + 0.8994054198 0.8337035775 0.8337035775 + 0.8998395801 0.8343139291 0.8343139291 + 0.9002736807 0.8349158764 0.8349158764 + 0.9007077813 0.8355141878 0.8355141878 + 0.9011420012 0.8361124992 0.8361124992 + 0.9015651941 0.8367106915 0.8367106915 + 0.9019711018 0.8373090029 0.8373090029 + 0.9023771286 0.8378884792 0.8378884792 + 0.9027829766 0.8384566903 0.8384566903 + 0.9031888843 0.8390247822 0.8390247822 + 0.9035964012 0.8395929933 0.8395929933 + 0.9040068984 0.8401612043 0.8401612043 + 0.9044172764 0.8407253027 0.8407253027 + 0.9048277140 0.8412854075 0.8412854075 + 0.9052380919 0.8418455124 0.8418455124 + 0.9056466222 0.8424056768 0.8424056768 + 0.9060494900 0.8429657817 0.8429657817 + 0.9064524770 0.8435230255 0.8435230255 + 0.9068554044 0.8440740705 0.8440740705 + 0.9072582722 0.8446251750 0.8446251750 + 0.9076607823 0.8451762795 0.8451762795 + 0.9080597162 0.8457275033 0.8457275033 + 0.9084585905 0.8462774158 0.8462774158 + 0.9088575244 0.8468161225 0.8468161225 + 0.9092563987 0.8473547101 0.8473547101 + 0.9096552730 0.8478932977 0.8478932977 + 0.9100391865 0.8484320045 0.8484320045 + 0.9104216099 0.8489705920 0.8489705920 + 0.9108039141 0.8494958878 0.8494958878 + 0.9111862779 0.8500180244 0.8500180244 + 0.9115687013 0.8505399823 0.8505399823 + 0.9119420052 0.8510619998 0.8510619998 + 0.9123104215 0.8515840173 0.8515840173 + 0.9126788974 0.8521022201 0.8521022201 + 0.9130473137 0.8526157737 0.8526157737 + 0.9134156704 0.8531293273 0.8531293273 + 0.9137811065 0.8536428809 0.8536428809 + 0.9141399860 0.8541564941 0.8541564941 + 0.9144989848 0.8546689749 0.8546689749 + 0.9148579240 0.8551610112 0.8551610112 + 0.9152169228 0.8556529880 0.8556529880 + 0.9155759215 0.8561450243 0.8561450243 + 0.9159141779 0.8566370010 0.8566370010 + 0.9162515998 0.8571289182 0.8571289182 + 0.9165889025 0.8576136231 0.8576136231 + 0.9169263244 0.8580930233 0.8580930233 + 0.9172636867 0.8585724235 0.8585724235 + 0.9175904989 0.8590518832 0.8590518832 + 0.9179077148 0.8595312834 0.8595312834 + 0.9182248116 0.8600099087 0.8600099087 + 0.9185420275 0.8604763150 0.8604763150 + 0.9188591242 0.8609427810 0.8609427810 + 0.9191758037 0.8614091873 0.8614091873 + 0.9194787145 0.8618755937 0.8618755937 + 0.9197816253 0.8623420000 0.8623420000 + 0.9200844169 0.8628141284 0.8628141284 + 0.9203873277 0.8632925153 0.8632925153 + 0.9206901789 0.8637707829 0.8637707829 + 0.9209961295 0.8642491102 0.8642491102 + 0.9213051796 0.8647273779 0.8647273779 + 0.9216142893 0.8652058244 0.8652058244 + 0.9219235182 0.8656808734 0.8656808734 + 0.9222326279 0.8661553860 0.8661553860 + 0.9225417972 0.8666298985 0.8666298985 + 0.9228463769 0.8671044111 0.8671044111 + 0.9231504202 0.8675789237 0.8675789237 + 0.9234544039 0.8680508733 0.8680508733 + 0.9237583876 0.8685060740 0.8685060740 + 0.9240623713 0.8689612746 0.8689612746 + 0.9243630767 0.8694164753 0.8694164753 + 0.9246509075 0.8698716164 0.8698716164 + 0.9249386787 0.8703268170 0.8703268170 + 0.9252265096 0.8707792163 0.8707792163 + 0.9255142212 0.8712267280 0.8712267280 + 0.9258019924 0.8716741204 0.8716741204 + 0.9260783792 0.8721215725 0.8721215725 + 0.9263415933 0.8725690246 0.8725690246 + 0.9266049266 0.8730164766 0.8730164766 + 0.9268680811 0.8734666109 0.8734666109 + 0.9271314144 0.8739191890 0.8739191890 + 0.9273946285 0.8743718266 0.8743718266 + 0.9276558757 0.8748244047 0.8748244047 + 0.9279161096 0.8752769232 0.8752769232 + 0.9281764030 0.8757295012 0.8757295012 + 0.9284366965 0.8761757016 0.8761757016 + 0.9286969900 0.8766183257 0.8766183257 + 0.9289572835 0.8770608902 0.8770608902 + 0.9292187095 0.8775033951 0.8775033951 + 0.9294803143 0.8779460192 0.8779460192 + 0.9297419190 0.8783885837 0.8783885837 + 0.9300035238 0.8788154125 0.8788154125 + 0.9302651286 0.8792347908 0.8792347908 + 0.9305267930 0.8796542287 0.8796542287 + 0.9307944179 0.8800736070 0.8800736070 + 0.9310628176 0.8804931045 0.8804931045 + 0.9313312173 0.8809124827 0.8809124827 + 0.9315996170 0.8813328147 0.8813328147 + 0.9318680167 0.8817536831 0.8817536831 + 0.9321364164 0.8821746111 0.8821746111 + 0.9324026108 0.8825954199 0.8825954199 + 0.9326686263 0.8830162883 0.8830162883 + 0.9329345822 0.8834370971 0.8834370971 + 0.9332005978 0.8838580251 0.8838580251 + 0.9334664941 0.8842790127 0.8842790127 + 0.9337325096 0.8846998811 0.8846998811 + 0.9339888096 0.8851209283 0.8851209283 + 0.9342433810 0.8855419159 0.8855419159 + 0.9344980121 0.8859627843 0.8859627843 + 0.9347525835 0.8863782883 0.8863782883 + 0.9350072145 0.8867862821 0.8867862821 + 0.9352617860 0.8871942759 0.8871942759 + 0.9355120063 0.8876023293 0.8876023293 + 0.9357606769 0.8880103230 0.8880103230 + 0.9360094070 0.8884181976 0.8884181976 + 0.9362581968 0.8888232708 0.8888232708 + 0.9365069270 0.8892168999 0.8892168999 + 0.9367555976 0.8896105289 0.8896105289 + 0.9369971156 0.8900040984 0.8900040984 + 0.9372326732 0.8903976083 0.8903976083 + 0.9374684095 0.8907911777 0.8907911777 + 0.9377040267 0.8911848068 0.8911848068 + 0.9379395843 0.8915761113 0.8915761113 + 0.9381753206 0.8919671178 0.8919671178 + 0.9384089708 0.8923581839 0.8923581839 + 0.9386385083 0.8927491903 0.8927491903 + 0.9388679266 0.8931403160 0.8931403160 + 0.9390972853 0.8935313225 0.8935313225 + 0.9393268228 0.8939135075 0.8939135075 + 0.9395561814 0.8942884803 0.8942884803 + 0.9397855997 0.8946635723 0.8946635723 + 0.9400131106 0.8950387239 0.8950387239 + 0.9402405024 0.8954138160 0.8954138160 + 0.9404678941 0.8957887888 0.8957887888 + 0.9406952858 0.8961619735 0.8961619735 + 0.9409226775 0.8965228200 0.8965228200 + 0.9411501288 0.8968836069 0.8968836069 + 0.9413790703 0.8972443938 0.8972443938 + 0.9416092038 0.8976051211 0.8976051211 + 0.9418392777 0.8979659081 0.8979659081 + 0.9420694113 0.8983266950 0.8983266950 + 0.9422994852 0.8986871243 0.8986871243 + 0.9425296187 0.8990470767 0.8990470767 + 0.9427592158 0.8994072080 0.8994072080 + 0.9429851174 0.8997672796 0.8997672796 + 0.9432110190 0.9001272917 0.9001272917 + 0.9434369206 0.9004874229 0.9004874229 + 0.9436628222 0.9008464217 0.9008464217 + 0.9438887239 0.9011930227 0.9011930227 + 0.9441146255 0.9015396237 0.9015396237 + 0.9443339109 0.9018862247 0.9018862247 + 0.9445490241 0.9022328258 0.9022328258 + 0.9447640777 0.9025794268 0.9025794268 + 0.9449791908 0.9029260278 0.9029260278 + 0.9451943040 0.9032617211 0.9032617211 + 0.9454094172 0.9035840034 0.9035840034 + 0.9456244111 0.9039062262 0.9039062262 + 0.9458345175 0.9042283893 0.9042283893 + 0.9460445046 0.9045506120 0.9045506120 + 0.9462546110 0.9048727751 0.9048727751 + 0.9464645982 0.9051949978 0.9051949978 + 0.9466745853 0.9055181146 0.9055181146 + 0.9468846917 0.9058414102 0.9058414102 + 0.9470942020 0.9061647058 0.9061647058 + 0.9473028183 0.9064880013 0.9064880013 + 0.9475114942 0.9068112969 0.9068112969 + 0.9477201104 0.9071347117 0.9071347117 + 0.9479287267 0.9074580073 0.9074580073 + 0.9481372833 0.9077845216 0.9077845216 + 0.9483458996 0.9081110954 0.9081110954 + 0.9485498071 0.9084377289 0.9084377289 + 0.9487506747 0.9087643027 0.9087643027 + 0.9489514828 0.9090908766 0.9090908766 + 0.9491522908 0.9094176292 0.9094176292 + 0.9493530989 0.9097433090 0.9097433090 + 0.9495540261 0.9100611806 0.9100611806 + 0.9497547746 0.9103791714 0.9103791714 + 0.9499650002 0.9106972218 0.9106972218 + 0.9501776099 0.9110150933 0.9110150933 + 0.9503902197 0.9113330841 0.9113330841 + 0.9506028295 0.9116510749 0.9116510749 + 0.9508153796 0.9119694829 0.9119694829 + 0.9510279894 0.9122899771 0.9122899771 + 0.9512405992 0.9126105905 0.9126105905 + 0.9514577985 0.9129310846 0.9129310846 + 0.9516754150 0.9132516980 0.9132516980 + 0.9518930912 0.9135721922 0.9135721922 + 0.9521107078 0.9138928056 0.9138928056 + 0.9523283839 0.9142141938 0.9142141938 + 0.9525460005 0.9145398736 0.9145398736 + 0.9527636766 0.9148656130 0.9148656130 + 0.9529777169 0.9151912928 0.9151912928 + 0.9531913996 0.9155169725 0.9155169725 + 0.9534052014 0.9158427119 0.9158427119 + 0.9536188841 0.9161683917 0.9161683917 + 0.9538326859 0.9164946079 0.9164946079 + 0.9540464878 0.9168255925 0.9168255925 + 0.9542601705 0.9171565771 0.9171565771 + 0.9544739723 0.9174876213 0.9174876213 + 0.9546877146 0.9178186059 0.9178186059 + 0.9549015164 0.9181495905 0.9181495905 + 0.9551151991 0.9184805155 0.9184805155 + 0.9553288817 0.9188115001 0.9188115001 + 0.9555426836 0.9191362858 0.9191362858 + 0.9557564259 0.9194607139 0.9194607139 + 0.9559655190 0.9197850823 0.9197850823 + 0.9561733007 0.9201093912 0.9201093912 + 0.9563812017 0.9204338193 0.9204338193 + 0.9565889835 0.9207581878 0.9207581878 + 0.9567968845 0.9210826159 0.9210826159 + 0.9570047259 0.9214031100 0.9214031100 + 0.9572126269 0.9217219949 0.9217219949 + 0.9574205279 0.9220409989 0.9220409989 + 0.9576283097 0.9223598838 0.9223598838 + 0.9578362107 0.9226788878 0.9226788878 + 0.9580441117 0.9229977727 0.9229977727 + 0.9582520127 0.9233167768 0.9233167768 + 0.9584599137 0.9236333966 0.9236333966 + 0.9586678147 0.9239464998 0.9239464998 + 0.9588736892 0.9242596030 0.9242596030 + 0.9590756893 0.9245728254 0.9245728254 + 0.9592776895 0.9248859286 0.9248859286 + 0.9594796896 0.9251989722 0.9251989722 + 0.9596816897 0.9255120754 0.9255120754 + 0.9598835707 0.9258251786 0.9258251786 + 0.9600855708 0.9261450171 0.9261450171 + 0.9602875710 0.9264646769 0.9264646769 + 0.9604778290 0.9267843962 0.9267843962 + 0.9606677890 0.9271041751 0.9271041751 + 0.9608578086 0.9274238944 0.9274238944 + 0.9610478282 0.9277436137 0.9277436137 + 0.9612377882 0.9280633926 0.9280633926 + 0.9614278078 0.9283816814 0.9283816814 + 0.9616177082 0.9286987782 0.9286987782 + 0.9617974758 0.9290158749 0.9290158749 + 0.9619693160 0.9293330908 0.9293330908 + 0.9621409774 0.9296501875 0.9296501875 + 0.9623126984 0.9299672842 0.9299672842 + 0.9624844193 0.9302843809 0.9302843809 + 0.9626560807 0.9306014776 0.9306014776 + 0.9628278017 0.9309071898 0.9309071898 + 0.9629982710 0.9312127233 0.9312127233 + 0.9631454945 0.9315180779 0.9315180779 + 0.9632925987 0.9318236113 0.9318236113 + 0.9634398222 0.9321290851 0.9321290851 + 0.9635869861 0.9324346185 0.9324346185 + 0.9637340903 0.9327399731 0.9327399731 + 0.9638813138 0.9330422282 0.9330422282 + 0.9640284777 0.9333382249 0.9333382249 + 0.9641625285 0.9336342812 0.9336342812 + 0.9642810822 0.9339302778 0.9339302778 + 0.9643996954 0.9342262745 0.9342262745 + 0.9645183086 0.9345223904 0.9345223904 + 0.9646369219 0.9348183870 0.9348183870 + 0.9647554755 0.9351143837 0.9351143837 + 0.9648740888 0.9354104996 0.9354104996 + 0.9649927020 0.9357064962 0.9357064962 + 0.9651054740 0.9360026121 0.9360026121 + 0.9652165771 0.9362986088 0.9362986088 + 0.9653276801 0.9365946054 0.9365946054 + 0.9654389024 0.9368907213 0.9368907213 + 0.9655500054 0.9371867180 0.9371867180 + 0.9656612277 0.9374827743 0.9374827743 + 0.9657722712 0.9377809167 0.9377809167 + 0.9658837914 0.9380794764 0.9380794764 + 0.9660049081 0.9383779764 0.9383779764 + 0.9661260247 0.9386765957 0.9386765957 + 0.9662470818 0.9389750957 0.9389750957 + 0.9663681984 0.9392737150 0.9392737150 + 0.9664893150 0.9395722151 0.9395722151 + 0.9666103721 0.9398707747 0.9398707747 + 0.9667314887 0.9401614070 0.9401614070 + 0.9668537974 0.9404516220 0.9404516220 + 0.9669811130 0.9407417774 0.9407417774 + 0.9671084285 0.9410318732 0.9410318732 + 0.9672356844 0.9413220882 0.9413220882 + 0.9673628807 0.9416123033 0.9416123033 + 0.9674901962 0.9419023991 0.9419023991 + 0.9676175117 0.9421926141 0.9421926141 + 0.9677448273 0.9424642920 0.9424642920 + 0.9678722024 0.9427356124 0.9427356124 + 0.9680001140 0.9430068731 0.9430068731 + 0.9681280255 0.9432781935 0.9432781935 + 0.9682558775 0.9435495138 0.9435495138 + 0.9683837891 0.9438207150 0.9438207150 + 0.9685117006 0.9440919757 0.9440919757 + 0.9686396122 0.9443632960 0.9443632960 + 0.9687675238 0.9446105957 0.9446105957 + 0.9688940048 0.9448559284 0.9448559284 + 0.9690169096 0.9451010823 0.9451010823 + 0.9691396952 0.9453462958 0.9453462958 + 0.9692625999 0.9455916286 0.9455916286 + 0.9693853855 0.9458367825 0.9458367825 + 0.9695081711 0.9460821152 0.9460821152 + 0.9696310759 0.9463273287 0.9463273287 + 0.9697539210 0.9465690255 0.9465690255 + 0.9698749781 0.9468097091 0.9468097091 + 0.9699872136 0.9470502734 0.9470502734 + 0.9700993896 0.9472910166 0.9472910166 + 0.9702115059 0.9475315809 0.9475315809 + 0.9703236818 0.9477723241 0.9477723241 + 0.9704359174 0.9480128884 0.9480128884 + 0.9705479741 0.9482535124 0.9482535124 + 0.9706602097 0.9484931827 0.9484931827 + 0.9707723260 0.9487320185 0.9487320185 + 0.9708713889 0.9489706755 0.9489706755 + 0.9709702730 0.9492095113 0.9492095113 + 0.9710690975 0.9494482875 0.9494482875 + 0.9711679220 0.9496871233 0.9496871233 + 0.9712666869 0.9499258995 0.9499258995 + 0.9713655114 0.9501646757 0.9501646757 + 0.9714642763 0.9504017234 0.9504017234 + 0.9715631008 0.9506325722 0.9506325722 + 0.9716647267 0.9508634806 0.9508634806 + 0.9717674255 0.9510943890 0.9510943890 + 0.9718701243 0.9513254166 0.9513254166 + 0.9719728231 0.9515563250 0.9515563250 + 0.9720755219 0.9517871737 0.9517871737 + 0.9721782207 0.9520180821 0.9520180821 + 0.9722809792 0.9522489905 0.9522489905 + 0.9723836780 0.9524822235 0.9524822235 + 0.9724901915 0.9527158737 0.9527158737 + 0.9726037979 0.9529495835 0.9529495835 + 0.9727175236 0.9531832933 0.9531832933 + 0.9728311896 0.9534170032 0.9534170032 + 0.9729447961 0.9536505938 0.9536505938 + 0.9730585217 0.9538843036 0.9538843036 + 0.9731721878 0.9541180134 0.9541180134 + 0.9732859135 0.9543501735 0.9543501735 + 0.9733995199 0.9545791745 0.9545791745 + 0.9735301733 0.9548081160 0.9548081160 + 0.9736629128 0.9550369978 0.9550369978 + 0.9737957120 0.9552658796 0.9552658796 + 0.9739285111 0.9554948211 0.9554948211 + 0.9740611911 0.9557238221 0.9557238221 + 0.9741939902 0.9559527040 0.9559527040 + 0.9743267894 0.9561815858 0.9561815858 + 0.9744595289 0.9564020038 0.9564020038 + 0.9745973945 0.9566190243 0.9566190243 + 0.9747449160 0.9568361044 0.9568361044 + 0.9748924971 0.9570531249 0.9570531249 + 0.9750400186 0.9572700858 0.9572700858 + 0.9751874804 0.9574871063 0.9574871063 + 0.9753351212 0.9577041268 0.9577041268 + 0.9754825830 0.9579210877 0.9579210877 + 0.9756301045 0.9581381083 0.9581381083 + 0.9757776856 0.9583560228 0.9583560228 + 0.9759315848 0.9585739970 0.9585739970 + 0.9760882258 0.9587919116 0.9587919116 + 0.9762448072 0.9590098262 0.9590098262 + 0.9764013886 0.9592276812 0.9592276812 + 0.9765580297 0.9594457150 0.9594457150 + 0.9767146111 0.9596636295 0.9596636295 + 0.9768711925 0.9598814845 0.9598814845 + 0.9770277739 0.9601004124 0.9601004124 + 0.9771844149 0.9603220224 0.9603220224 + 0.9773445129 0.9605436921 0.9605436921 + 0.9775046706 0.9607654214 0.9607654214 + 0.9776650071 0.9609870911 0.9609870911 + 0.9778252244 0.9612088203 0.9612088203 + 0.9779855013 0.9614304900 0.9614304900 + 0.9781457186 0.9616522193 0.9616522193 + 0.9783058763 0.9618738890 0.9618738890 + 0.9784662127 0.9620940089 0.9620940089 + 0.9786261916 0.9623115063 0.9623115063 + 0.9787849188 0.9625288844 0.9625288844 + 0.9789437056 0.9627463818 0.9627463818 + 0.9791023731 0.9629638195 0.9629638195 + 0.9792612195 0.9631813169 0.9631813169 + 0.9794198871 0.9633988142 0.9633988142 + 0.9795786738 0.9636161923 0.9636161923 + 0.9797374010 0.9638336897 0.9638336897 + 0.9798961878 0.9640504122 0.9640504122 + 0.9800534844 0.9642658830 0.9642658830 + 0.9802057147 0.9644814730 0.9644814730 + 0.9803580046 0.9646970034 0.9646970034 + 0.9805101752 0.9649125934 0.9649125934 + 0.9806625247 0.9651281834 0.9651281834 + 0.9808148146 0.9653437138 0.9653437138 + 0.9809669852 0.9655593038 0.9655593038 + 0.9811192751 0.9657747746 0.9657747746 + 0.9812715054 0.9659873843 0.9659873843 + 0.9814214110 0.9661936760 0.9661936760 + 0.9815621972 0.9664000273 0.9664000273 + 0.9817029834 0.9666063190 0.9666063190 + 0.9818438292 0.9668126106 0.9668126106 + 0.9819844961 0.9670189023 0.9670189023 + 0.9821252823 0.9672251940 0.9672251940 + 0.9822661281 0.9674314260 0.9674314260 + 0.9824067950 0.9676377177 0.9676377177 + 0.9825475812 0.9678443074 0.9678443074 + 0.9826868773 0.9680523872 0.9680523872 + 0.9828112125 0.9682605267 0.9682605267 + 0.9829354882 0.9684684873 0.9684684873 + 0.9830598235 0.9686766267 0.9686766267 + 0.9831839800 0.9688847065 0.9688847065 + 0.9833083153 0.9690927863 0.9690927863 + 0.9834325910 0.9693009257 0.9693009257 + 0.9835569263 0.9695090055 0.9695090055 + 0.9836812019 0.9697170854 0.9697170854 + 0.9838054180 0.9699230194 0.9699230194 + 0.9839122891 0.9701287746 0.9701287746 + 0.9840167165 0.9703344703 0.9703344703 + 0.9841210246 0.9705402255 0.9705402255 + 0.9842253923 0.9707459211 0.9707459211 + 0.9843298197 0.9709516168 0.9709516168 + 0.9844341278 0.9711573124 0.9711573124 + 0.9845384955 0.9713630080 0.9713630080 + 0.9846428037 0.9715687037 0.9715687037 + 0.9847471714 0.9717782140 0.9717782140 + 0.9848499894 0.9719914198 0.9719914198 + 0.9849516153 0.9722046256 0.9722046256 + 0.9850531816 0.9724177718 0.9724177718 + 0.9851548076 0.9726309180 0.9726309180 + 0.9852563143 0.9728441238 0.9728441238 + 0.9853578806 0.9730573297 0.9730573297 + 0.9854595065 0.9732704759 0.9732704759 + 0.9855610728 0.9734836817 0.9734836817 + 0.9856626987 0.9736968279 0.9736968279 + 0.9857648015 0.9739102125 0.9739102125 + 0.9858701229 0.9741235971 0.9741235971 + 0.9859753847 0.9743369222 0.9743369222 + 0.9860807061 0.9745503068 0.9745503068 + 0.9861860275 0.9747636914 0.9747636914 + 0.9862912893 0.9749770164 0.9749770164 + 0.9863966107 0.9751904011 0.9751904011 + 0.9865018725 0.9754037857 0.9754037857 + 0.9866071939 0.9756171703 0.9756171703 + 0.9867125154 0.9758273959 0.9758273959 + 0.9868178964 0.9760339856 0.9760339856 + 0.9869232774 0.9762405753 0.9762405753 + 0.9870287776 0.9764472842 0.9764472842 + 0.9871342778 0.9766538739 0.9766538739 + 0.9872397184 0.9768605232 0.9768605232 + 0.9873452187 0.9770671129 0.9770671129 + 0.9874507189 0.9772738218 0.9772738218 + 0.9875562191 0.9774804115 0.9774804115 + 0.9876616001 0.9776870012 0.9776870012 + 0.9877671003 0.9778900146 0.9778900146 + 0.9878692031 0.9780920148 0.9780920148 + 0.9879713058 0.9782938957 0.9782938957 + 0.9880735278 0.9784958959 0.9784958959 + 0.9881755710 0.9786978960 0.9786978960 + 0.9882776737 0.9788998961 0.9788998961 + 0.9883798957 0.9791017771 0.9791017771 + 0.9884819984 0.9793037772 0.9793037772 + 0.9885841012 0.9795057774 0.9795057774 + 0.9886862040 0.9797077179 0.9797077179 + 0.9887884855 0.9798991084 0.9798991084 + 0.9888911843 0.9800903797 0.9800903797 + 0.9889938831 0.9802817702 0.9802817702 + 0.9890967011 0.9804731011 0.9804731011 + 0.9891993999 0.9806643724 0.9806643724 + 0.9893020988 0.9808558226 0.9808558226 + 0.9894047976 0.9810470939 0.9810470939 + 0.9895074964 0.9812384844 0.9812384844 + 0.9896101952 0.9814298153 0.9814298153 + 0.9897128940 0.9816213250 0.9816213250 + 0.9898141026 0.9818137884 0.9818137884 + 0.9899132252 0.9820061922 0.9820061922 + 0.9900122881 0.9821987152 0.9821987152 + 0.9901114106 0.9823911190 0.9823911190 + 0.9902104735 0.9825835824 0.9825835824 + 0.9903095961 0.9827759862 0.9827759862 + 0.9904087186 0.9829685092 0.9829685092 + 0.9905077815 0.9831609130 0.9831609130 + 0.9906069040 0.9833533764 0.9833533764 + 0.9907060266 0.9835463166 0.9835463166 + 0.9908010960 0.9837430716 0.9837430716 + 0.9908921719 0.9839398265 0.9839398265 + 0.9909833074 0.9841365218 0.9841365218 + 0.9910743833 0.9843332767 0.9843332767 + 0.9911653996 0.9845299721 0.9845299721 + 0.9912564754 0.9847267270 0.9847267270 + 0.9913476110 0.9849234819 0.9849234819 + 0.9914386868 0.9851201773 0.9851201773 + 0.9915298223 0.9853168726 0.9853168726 + 0.9916208982 0.9855136275 0.9855136275 + 0.9917073250 0.9857079983 0.9857079983 + 0.9917883277 0.9859024286 0.9859024286 + 0.9918693900 0.9860966802 0.9860966802 + 0.9919503927 0.9862911105 0.9862911105 + 0.9920313954 0.9864854217 0.9864854217 + 0.9921123981 0.9866797924 0.9866797924 + 0.9921934009 0.9868742228 0.9868742228 + 0.9922744036 0.9870684743 0.9870684743 + 0.9923554063 0.9872629046 0.9872629046 + 0.9924364090 0.9874572754 0.9874572754 + 0.9925166965 0.9876400828 0.9876400828 + 0.9925954938 0.9878200889 0.9878200889 + 0.9926741719 0.9880000949 0.9880000949 + 0.9927530289 0.9881801009 0.9881801009 + 0.9928318262 0.9883599877 0.9883599877 + 0.9929105043 0.9885399938 0.9885399938 + 0.9929893017 0.9887199998 0.9887199998 + 0.9930680990 0.9889000058 0.9889000058 + 0.9931467772 0.9890800118 0.9890800118 + 0.9932255745 0.9892598987 0.9892598987 + 0.9933044910 0.9894347787 0.9894347787 + 0.9933881760 0.9896039963 0.9896039963 + 0.9934718013 0.9897732735 0.9897732735 + 0.9935554266 0.9899424911 0.9899424911 + 0.9936391115 0.9901117086 0.9901117086 + 0.9937226772 0.9902809858 0.9902809858 + 0.9938063025 0.9904502034 0.9904502034 + 0.9938899875 0.9906194210 0.9906194210 + 0.9939736128 0.9907886982 0.9907886982 + 0.9940572977 0.9909579158 0.9909579158 + 0.9941409230 0.9911267161 0.9911267161 + 0.9942286015 0.9912837148 0.9912837148 + 0.9943184853 0.9914405942 0.9914405942 + 0.9944083095 0.9915975928 0.9915975928 + 0.9944980741 0.9917545915 0.9917545915 + 0.9945880175 0.9919115901 0.9919115901 + 0.9946777821 0.9920685887 0.9920685887 + 0.9947676063 0.9922255874 0.9922255874 + 0.9948573709 0.9923825860 0.9923825860 + 0.9949473143 0.9925395846 0.9925395846 + 0.9950370789 0.9926965833 0.9926965833 + 0.9951277971 0.9928529263 0.9928529263 + 0.9952226877 0.9930083752 0.9930083752 + 0.9953176975 0.9931638837 0.9931638837 + 0.9954125881 0.9933193922 0.9933193922 + 0.9955074787 0.9934750199 0.9934750199 + 0.9956024289 0.9936305285 0.9936305285 + 0.9956973791 0.9937859774 0.9937859774 + 0.9957923293 0.9939414859 0.9939414859 + 0.9958872199 0.9940969944 0.9940969944 + 0.9959821105 0.9942525029 0.9942525029 + 0.9960770011 0.9944080710 0.9944080710 + 0.9961733222 0.9945561886 0.9945561886 + 0.9962705970 0.9947028756 0.9947028756 + 0.9963678718 0.9948495030 0.9948495030 + 0.9964652061 0.9949960709 0.9949960709 + 0.9965624809 0.9951426983 0.9951426983 + 0.9966596961 0.9952893853 0.9952893853 + 0.9967569709 0.9954360127 0.9954360127 + 0.9968543053 0.9955825806 0.9955825806 + 0.9969515800 0.9957293272 0.9957293272 + 0.9970489144 0.9958758950 0.9958758950 + 0.9971461892 0.9960218072 0.9960218072 + 0.9972419143 0.9961522818 0.9961522818 + 0.9973374009 0.9962828159 0.9962828159 + 0.9974328876 0.9964132905 0.9964132905 + 0.9975283742 0.9965438247 0.9965438247 + 0.9976239204 0.9966742992 0.9966742992 + 0.9977192879 0.9968047738 0.9968047738 + 0.9978147745 0.9969353080 0.9969353080 + 0.9979103208 0.9970657825 0.9970657825 + 0.9980058074 0.9971963167 0.9971963167 + 0.9981012940 0.9973267913 0.9973267913 + 0.9981966019 0.9974548221 0.9974548221 + 0.9982848763 0.9975687265 0.9975687265 + 0.9983732104 0.9976826906 0.9976826906 + 0.9984614849 0.9977965951 0.9977965951 + 0.9985498190 0.9979106188 0.9979106188 + 0.9986380935 0.9980245233 0.9980245233 + 0.9987264276 0.9981384277 0.9981384277 + 0.9988147020 0.9982523918 0.9982523918 + 0.9989029765 0.9983662963 0.9983662963 + 0.9989913106 0.9984803200 0.9984803200 + 0.9990795851 0.9985942245 0.9985942245 + 0.9991670847 0.9987086058 0.9987086058 + 0.9992427826 0.9988260269 0.9988260269 + 0.9993184805 0.9989433885 0.9989433885 + 0.9993941784 0.9990608096 0.9990608096 + 0.9994698763 0.9991781712 0.9991781712 + 0.9995456934 0.9992955923 0.9992955923 + 0.9996213913 0.9994130135 0.9994130135 + 0.9996970892 0.9995303750 0.9995303750 + 0.9997727871 0.9996477962 0.9996477962 + 0.9998486042 0.9997652173 0.9997652173 + 0.9999243021 0.9998825788 0.9998825788 + 1.0000000000 1.0000000000 1.0000000000 +} diff --git a/rpplugins/color_correction/resources/film_luts_raw/kodak_gold_100.spi1d b/rpplugins/color_correction/resources/film_luts_raw/kodak_gold_100.spi1d new file mode 100644 index 0000000..fe5e218 --- /dev/null +++ b/rpplugins/color_correction/resources/film_luts_raw/kodak_gold_100.spi1d @@ -0,0 +1,1030 @@ +Version 1 +From 0.0 1.0 +Length 1024 +Components 3 +{ + 0.0000000000 0.0000000000 0.0000000000 + 0.0085512707 0.0085512707 0.0040388089 + 0.0166211706 0.0166211706 0.0078869723 + 0.0239217207 0.0239217207 0.0115889302 + 0.0305970907 0.0305970907 0.0151835401 + 0.0367598310 0.0367598310 0.0186785609 + 0.0425867885 0.0425867885 0.0220463201 + 0.0481229611 0.0481229611 0.0253170207 + 0.0533615910 0.0533615910 0.0285046306 + 0.0583925582 0.0583925582 0.0316370614 + 0.0632038563 0.0632038563 0.0346923992 + 0.0678458065 0.0678458065 0.0376951098 + 0.0723663494 0.0723663494 0.0406254604 + 0.0767436773 0.0767436773 0.0434999615 + 0.0809408724 0.0809408724 0.0463499017 + 0.0850247815 0.0850247815 0.0491519198 + 0.0890202522 0.0890202522 0.0518954284 + 0.0929083526 0.0929083526 0.0545983687 + 0.0967549235 0.0967549235 0.0572627783 + 0.1004967019 0.1004967019 0.0598945618 + 0.1041401029 0.1041401029 0.0624886788 + 0.1076878980 0.1076878980 0.0650598332 + 0.1111321002 0.1111321002 0.0676003397 + 0.1145434007 0.1145434007 0.0700881407 + 0.1179336980 0.1179336980 0.0725532621 + 0.1213003024 0.1213003024 0.0749963596 + 0.1246234998 0.1246234998 0.0774110928 + 0.1278907061 0.1278907061 0.0798068568 + 0.1311019957 0.1311019957 0.0821953192 + 0.1342176050 0.1342176050 0.0845582336 + 0.1372642964 0.1372642964 0.0868936703 + 0.1402868927 0.1402868927 0.0891988575 + 0.1433071941 0.1433071941 0.0914948583 + 0.1463229060 0.1463229060 0.0937692001 + 0.1493196040 0.1493196040 0.0960261002 + 0.1522929072 0.1522929072 0.0982703716 + 0.1552488059 0.1552488059 0.1005069017 + 0.1581514031 0.1581514031 0.1027444005 + 0.1609746069 0.1609746069 0.1049712971 + 0.1637527943 0.1637527943 0.1071826965 + 0.1664921939 0.1664921939 0.1093685031 + 0.1691893935 0.1691893935 0.1115406975 + 0.1718754023 0.1718754023 0.1136908978 + 0.1745572984 0.1745572984 0.1158114970 + 0.1772463024 0.1772463024 0.1179215983 + 0.1799204051 0.1799204051 0.1200228035 + 0.1825827062 0.1825827062 0.1221131980 + 0.1852307022 0.1852307022 0.1241903976 + 0.1878415048 0.1878415048 0.1262644976 + 0.1904177964 0.1904177964 0.1283268929 + 0.1929835975 0.1929835975 0.1303768009 + 0.1955551058 0.1955551058 0.1324191988 + 0.1980939955 0.1980939955 0.1344535947 + 0.2005960941 0.2005960941 0.1364852041 + 0.2030780017 0.2030780017 0.1385065019 + 0.2055498958 0.2055498958 0.1404985934 + 0.2080249041 0.2080249041 0.1424852014 + 0.2104936987 0.2104936987 0.1444734931 + 0.2129532993 0.2129532993 0.1464570016 + 0.2153917998 0.2153917998 0.1484331042 + 0.2178138942 0.2178138942 0.1504009962 + 0.2202032059 0.2202032059 0.1523738950 + 0.2225545049 0.2225545049 0.1543436050 + 0.2248750031 0.2248750031 0.1563021988 + 0.2271793038 0.2271793038 0.1582521945 + 0.2294784039 0.2294784039 0.1601931006 + 0.2317692935 0.2317692935 0.1621181965 + 0.2340328991 0.2340328991 0.1640346050 + 0.2362951934 0.2362951934 0.1659477949 + 0.2385396957 0.2385396957 0.1678593010 + 0.2407682985 0.2407682985 0.1697596014 + 0.2429841012 0.2429841012 0.1716434956 + 0.2451926023 0.2451926023 0.1735229045 + 0.2473980039 0.2473980039 0.1754001975 + 0.2495967001 0.2495967001 0.1772678047 + 0.2518011928 0.2518011928 0.1791307926 + 0.2540042996 0.2540042996 0.1809882969 + 0.2561990917 0.2561990917 0.1828391999 + 0.2583766878 0.2583766878 0.1846980006 + 0.2605302930 0.2605302930 0.1865592003 + 0.2626619041 0.2626619041 0.1884168983 + 0.2647795081 0.2647795081 0.1902665943 + 0.2668896914 0.2668896914 0.1921050996 + 0.2689956129 0.2689956129 0.1939377934 + 0.2710914016 0.2710914016 0.1957681030 + 0.2731707096 0.2731707096 0.1975923926 + 0.2752295136 0.2752295136 0.1994120032 + 0.2772876024 0.2772876024 0.2012308985 + 0.2793470919 0.2793470919 0.2030453980 + 0.2813898921 0.2813898921 0.2048553973 + 0.2834160924 0.2834160924 0.2066580951 + 0.2854352891 0.2854352891 0.2084507048 + 0.2874428928 0.2874428928 0.2102348953 + 0.2894397080 0.2894397080 0.2120144963 + 0.2914342880 0.2914342880 0.2137901038 + 0.2934266925 0.2934266925 0.2155577987 + 0.2954250872 0.2954250872 0.2173161060 + 0.2974228859 0.2974228859 0.2190670073 + 0.2994059920 0.2994059920 0.2208126932 + 0.3013804853 0.3013804853 0.2225555927 + 0.3033458889 0.3033458889 0.2242987007 + 0.3052974939 0.3052974939 0.2260434926 + 0.3072321117 0.3072321117 0.2277884930 + 0.3091601133 0.3091601133 0.2295302004 + 0.3110798895 0.3110798895 0.2312685996 + 0.3129976094 0.3129976094 0.2329937071 + 0.3149156868 0.3149156868 0.2347085029 + 0.3168309927 0.3168309927 0.2364155948 + 0.3187418878 0.3187418878 0.2381125987 + 0.3206557930 0.3206557930 0.2397992015 + 0.3225586116 0.3225586116 0.2414820939 + 0.3244569898 0.3244569898 0.2431667000 + 0.3263500929 0.3263500929 0.2448462993 + 0.3282350898 0.3282350898 0.2465201020 + 0.3301092982 0.3301092982 0.2481863946 + 0.3319670856 0.3319670856 0.2498456985 + 0.3338209093 0.3338209093 0.2515039146 + 0.3356688023 0.3356688023 0.2531544864 + 0.3375090063 0.3375090063 0.2548001111 + 0.3393396139 0.3393396139 0.2564423978 + 0.3411692083 0.3411692083 0.2580820024 + 0.3429956138 0.3429956138 0.2597126067 + 0.3448179960 0.3448179960 0.2613438070 + 0.3466367126 0.3466367126 0.2629727125 + 0.3484556079 0.3484556079 0.2645977139 + 0.3502711058 0.3502711058 0.2662194967 + 0.3520781100 0.3520781100 0.2678410113 + 0.3538728952 0.3538728952 0.2694599032 + 0.3556573093 0.3556573093 0.2710745037 + 0.3574326932 0.3574326932 0.2726924121 + 0.3591986001 0.3591986001 0.2743096948 + 0.3609502912 0.3609502912 0.2759279013 + 0.3626965880 0.3626965880 0.2775534987 + 0.3644376099 0.3644376099 0.2791810930 + 0.3661716878 0.3661716878 0.2808074951 + 0.3679068089 0.3679068089 0.2824282944 + 0.3696404099 0.3696404099 0.2840456963 + 0.3713721931 0.3713721931 0.2856619060 + 0.3730970919 0.3730970919 0.2872773111 + 0.3748179972 0.3748179972 0.2888830006 + 0.3765349090 0.3765349090 0.2904838920 + 0.3782503903 0.3782503903 0.2920790017 + 0.3799589872 0.3799589872 0.2936722934 + 0.3816598058 0.3816598058 0.2952640057 + 0.3833526969 0.3833526969 0.2968522906 + 0.3850415051 0.3850415051 0.2984321117 + 0.3867242932 0.3867242932 0.3000073135 + 0.3883965015 0.3883965015 0.3015750051 + 0.3900654912 0.3900654912 0.3031345010 + 0.3917332888 0.3917332888 0.3046869040 + 0.3933978081 0.3933978081 0.3062342107 + 0.3950597942 0.3950597942 0.3077783883 + 0.3967128098 0.3967128098 0.3093160987 + 0.3983623087 0.3983623087 0.3108538985 + 0.4000048041 0.4000048041 0.3123919070 + 0.4016445875 0.4016445875 0.3139241934 + 0.4032827914 0.4032827914 0.3154524863 + 0.4049166143 0.4049166143 0.3169719875 + 0.4065478146 0.4065478146 0.3184897006 + 0.4081723094 0.4081723094 0.3200064003 + 0.4097915888 0.4097915888 0.3215180039 + 0.4114066064 0.4114066064 0.3230280876 + 0.4130186141 0.4130186141 0.3245337009 + 0.4146288931 0.4146288931 0.3260375857 + 0.4162240028 0.4162240028 0.3275386989 + 0.4178164005 0.4178164005 0.3290353119 + 0.4194015861 0.4194015861 0.3305288851 + 0.4209814072 0.4209814072 0.3320241868 + 0.4225557148 0.4225557148 0.3335199058 + 0.4241304100 0.4241304100 0.3350135982 + 0.4257053137 0.4257053137 0.3365071118 + 0.4272772074 0.4272772074 0.3379994035 + 0.4288483858 0.4288483858 0.3394888043 + 0.4304055870 0.4304055870 0.3409718871 + 0.4319624007 0.4319624007 0.3424525857 + 0.4335188866 0.4335188866 0.3439300954 + 0.4350732863 0.4350732863 0.3454062939 + 0.4366205037 0.4366205037 0.3468815088 + 0.4381664991 0.4381664991 0.3483560085 + 0.4397099912 0.4397099912 0.3498300910 + 0.4412516952 0.4412516952 0.3513006866 + 0.4427905977 0.4427905977 0.3527697921 + 0.4443261921 0.4443261921 0.3542422950 + 0.4458572865 0.4458572865 0.3557159901 + 0.4473834038 0.4473834038 0.3571884036 + 0.4489029944 0.4489029944 0.3586604893 + 0.4504176080 0.4504176080 0.3601266146 + 0.4519256949 0.4519256949 0.3615907133 + 0.4534310102 0.4534310102 0.3630562127 + 0.4549323916 0.4549323916 0.3645220101 + 0.4564324915 0.4564324915 0.3659847081 + 0.4579305947 0.4579305947 0.3674460053 + 0.4594289064 0.4594289064 0.3689005077 + 0.4609279037 0.4609279037 0.3703509867 + 0.4624246955 0.4624246955 0.3718009889 + 0.4639141858 0.4639141858 0.3732503951 + 0.4654031098 0.4654031098 0.3746976852 + 0.4668875039 0.4668875039 0.3761422932 + 0.4683718085 0.4683718085 0.3775857091 + 0.4698401988 0.4698401988 0.3790262043 + 0.4713082910 0.4713082910 0.3804647923 + 0.4727697968 0.4727697968 0.3818928897 + 0.4742299914 0.4742299914 0.3833209872 + 0.4756909013 0.4756909013 0.3847407997 + 0.4771521986 0.4771521986 0.3861603141 + 0.4786089063 0.4786089063 0.3875763118 + 0.4800598919 0.4800598919 0.3889910877 + 0.4815098047 0.4815098047 0.3904035985 + 0.4829556048 0.4829556048 0.3918142915 + 0.4844014049 0.4844014049 0.3932228088 + 0.4858314991 0.4858314991 0.3946261108 + 0.4872612059 0.4872612059 0.3960292935 + 0.4886828065 0.4886828065 0.3974260986 + 0.4901008904 0.4901008904 0.3988228142 + 0.4915114045 0.4915114045 0.4002167881 + 0.4929108918 0.4929108918 0.4016098976 + 0.4943102002 0.4943102002 0.4030028880 + 0.4957073927 0.4957073927 0.4043959975 + 0.4971045852 0.4971045852 0.4057886899 + 0.4984934032 0.4984934032 0.4071742892 + 0.4998792112 0.4998792112 0.4085598886 + 0.5012617707 0.5012617707 0.4099406004 + 0.5026388168 0.5026388168 0.4113186896 + 0.5040158033 0.5040158033 0.4126941860 + 0.5053874850 0.5053874850 0.4140625894 + 0.5067589283 0.5067589283 0.4154309928 + 0.5081269145 0.5081269145 0.4167915881 + 0.5094919205 0.5094919205 0.4181506932 + 0.5108559132 0.5108559132 0.4195038080 + 0.5122082829 0.5122082829 0.4208473861 + 0.5135607719 0.5135607719 0.4221909940 + 0.5149065852 0.5149065852 0.4235303998 + 0.5162479877 0.5162479877 0.4248695076 + 0.5175889134 0.5175889134 0.4262058139 + 0.5189247727 0.5189247727 0.4275380969 + 0.5202606916 0.5202606916 0.4288704097 + 0.5215886235 0.5215886235 0.4302046895 + 0.5229104161 0.5229104161 0.4315393865 + 0.5242322087 0.5242322087 0.4328733981 + 0.5255554914 0.5255554914 0.4342060983 + 0.5268787742 0.5268787742 0.4355388880 + 0.5281956792 0.5281956792 0.4368667901 + 0.5295035243 0.5295035243 0.4381929040 + 0.5308111906 0.5308111906 0.4395191073 + 0.5321189761 0.5321189761 0.4408474863 + 0.5334268212 0.5334268212 0.4421758950 + 0.5347332954 0.5347332954 0.4435034096 + 0.5360326171 0.5360326171 0.4448300004 + 0.5373319983 0.5373319983 0.4461565018 + 0.5386298895 0.5386298895 0.4474779069 + 0.5399259925 0.5399259925 0.4487977922 + 0.5412220955 0.5412220955 0.4501172900 + 0.5425089002 0.5425089002 0.4514313042 + 0.5437930822 0.5437930822 0.4527452886 + 0.5450770259 0.5450770259 0.4540582001 + 0.5463545918 0.5463545918 0.4553689063 + 0.5476322174 0.5476322174 0.4566796124 + 0.5489053726 0.5489053726 0.4579856992 + 0.5501675010 0.5501675010 0.4592883885 + 0.5514295101 0.5514295101 0.4605911970 + 0.5526881218 0.5526881218 0.4618827999 + 0.5539432168 0.5539432168 0.4631715119 + 0.5551983714 0.5551983714 0.4644601941 + 0.5564481020 0.5564481020 0.4657382965 + 0.5576952100 0.5576952100 0.4670161009 + 0.5589423180 0.5589423180 0.4682930112 + 0.5601819158 0.5601819158 0.4695635140 + 0.5614199042 0.5614199042 0.4708338976 + 0.5626578927 0.5626578927 0.4721035063 + 0.5638862252 0.5638862252 0.4733701050 + 0.5651137829 0.5651137829 0.4746366143 + 0.5663412213 0.5663412213 0.4759002030 + 0.5675578117 0.5675578117 0.4771572948 + 0.5687745214 0.5687745214 0.4784145057 + 0.5699902177 0.5699902177 0.4796695113 + 0.5711944103 0.5711944103 0.4809209108 + 0.5723987222 0.5723987222 0.4821723998 + 0.5736017227 0.5736017227 0.4834229946 + 0.5747933984 0.5747933984 0.4846724868 + 0.5759850144 0.5759850144 0.4859218895 + 0.5771753788 0.5771753788 0.4871684015 + 0.5783529878 0.5783529878 0.4884099960 + 0.5795305967 0.5795305967 0.4896515906 + 0.5807074904 0.5807074904 0.4908894002 + 0.5818707943 0.5818707943 0.4921191931 + 0.5830342174 0.5830342174 0.4933489859 + 0.5841975808 0.5841975808 0.4945765138 + 0.5853506923 0.5853506923 0.4957973957 + 0.5865036249 0.5865036249 0.4970183074 + 0.5876564980 0.5876564980 0.4982382059 + 0.5888124108 0.5888124108 0.4994524121 + 0.5899686813 0.5899686813 0.5006666183 + 0.5911250710 0.5911250710 0.5018808246 + 0.5922722220 0.5922722220 0.5030846000 + 0.5934156775 0.5934156775 0.5042884946 + 0.5945591927 0.5945591927 0.5054923296 + 0.5956988931 0.5956988931 0.5066840053 + 0.5968354940 0.5968354940 0.5078731179 + 0.5979719758 0.5979719758 0.5090621710 + 0.5991039276 0.5991039276 0.5102484822 + 0.6002264023 0.6002264023 0.5114330053 + 0.6013488770 0.6013488770 0.5126175284 + 0.6024705768 0.6024705768 0.5138002038 + 0.6035845876 0.6035845876 0.5149796009 + 0.6046985984 0.6046985984 0.5161591172 + 0.6058124900 0.6058124900 0.5173382759 + 0.6069167256 0.6069167256 0.5185145736 + 0.6080183983 0.6080183983 0.5196908116 + 0.6091201901 0.6091201901 0.5208671093 + 0.6102225184 0.6102225184 0.5220367908 + 0.6113256216 0.6113256216 0.5232045054 + 0.6124286056 0.6124286056 0.5243722200 + 0.6135300994 0.6135300994 0.5255355239 + 0.6146209836 0.6146209836 0.5266925097 + 0.6157119274 0.6157119274 0.5278496146 + 0.6168028712 0.6168028712 0.5290066004 + 0.6178948283 0.6178948283 0.5301629901 + 0.6189870238 0.6189870238 0.5313194990 + 0.6200792193 0.6200792193 0.5324760079 + 0.6211677194 0.6211677194 0.5336307287 + 0.6222478747 0.6222478747 0.5347841978 + 0.6233282089 0.6233282089 0.5359376073 + 0.6244084239 0.6244084239 0.5370901227 + 0.6254897118 0.6254897118 0.5382356048 + 0.6265712976 0.6265712976 0.5393812060 + 0.6276528239 0.6276528239 0.5405266881 + 0.6287301183 0.6287301183 0.5416650176 + 0.6297997832 0.6297997832 0.5427989960 + 0.6308693886 0.6308693886 0.5439329147 + 0.6319391131 0.6319391131 0.5450661778 + 0.6330032945 0.6330032945 0.5461930037 + 0.6340664029 0.6340664029 0.5473198295 + 0.6351293921 0.6351293921 0.5484464765 + 0.6361892819 0.6361892819 0.5495709777 + 0.6372389197 0.6372389197 0.5506932139 + 0.6382886171 0.6382886171 0.5518153906 + 0.6393381953 0.6393381953 0.5529376864 + 0.6403782964 0.6403782964 0.5540469885 + 0.6414123774 0.6414123774 0.5551546812 + 0.6424465179 0.6424465179 0.5562624931 + 0.6434807181 0.6434807181 0.5573676229 + 0.6445010900 0.6445010900 0.5584642291 + 0.6455209851 0.6455209851 0.5595607758 + 0.6465408802 0.6465408802 0.5606573820 + 0.6475573182 0.6475573182 0.5617504716 + 0.6485638022 0.6485638022 0.5628405809 + 0.6495704055 0.6495704055 0.5639305711 + 0.6505770087 0.6505770087 0.5650206804 + 0.6515771747 0.6515771747 0.5661026239 + 0.6525719166 0.6525719166 0.5671824217 + 0.6535665989 0.6535665989 0.5682622194 + 0.6545614004 0.6545614004 0.5693418980 + 0.6555476785 0.6555476785 0.5704169869 + 0.6565313935 0.6565313935 0.5714920163 + 0.6575151086 0.6575151086 0.5725671053 + 0.6584988236 0.6584988236 0.5736408830 + 0.6594734192 0.6594734192 0.5747092962 + 0.6604474783 0.6604474783 0.5757777095 + 0.6614215970 0.6614215970 0.5768461227 + 0.6623948812 0.6623948812 0.5779128075 + 0.6633601785 0.6633601785 0.5789762139 + 0.6643254757 0.6643254757 0.5800395012 + 0.6652907133 0.6652907133 0.5811027884 + 0.6662545800 0.6662545800 0.5821601152 + 0.6672123075 0.6672123075 0.5832095742 + 0.6681699157 0.6681699157 0.5842590928 + 0.6691275835 0.6691275835 0.5853086114 + 0.6700835824 0.6700835824 0.5863516927 + 0.6710343957 0.6710343957 0.5873885155 + 0.6719852090 0.6719852090 0.5884252787 + 0.6729360223 0.6729360223 0.5894619823 + 0.6738809943 0.6738809943 0.5904929042 + 0.6748093963 0.6748093963 0.5915179849 + 0.6757377982 0.6757377982 0.5925431252 + 0.6766662002 0.6766662002 0.5935683250 + 0.6775926948 0.6775926948 0.5945895910 + 0.6785131097 0.6785131097 0.5956068039 + 0.6794335842 0.6794335842 0.5966240168 + 0.6803539991 0.6803539991 0.5976412296 + 0.6812713742 0.6812713742 0.5986567140 + 0.6821733713 0.6821733713 0.5996695757 + 0.6830754280 0.6830754280 0.6006824970 + 0.6839774251 0.6839774251 0.6016954780 + 0.6848791242 0.6848791242 0.6027052999 + 0.6857768893 0.6857768893 0.6037077904 + 0.6866745949 0.6866745949 0.6047102213 + 0.6875724196 0.6875724196 0.6057127118 + 0.6884701252 0.6884701252 0.6067149043 + 0.6893548965 0.6893548965 0.6077160239 + 0.6902378798 0.6902378798 0.6087170243 + 0.6911209822 0.6911209822 0.6097180247 + 0.6920040250 0.6920040250 0.6107190251 + 0.6928865910 0.6928865910 0.6117115021 + 0.6937689781 0.6937689781 0.6127033234 + 0.6946514249 0.6946514249 0.6136950850 + 0.6955338120 0.6955338120 0.6146869063 + 0.6964113712 0.6964113712 0.6156741977 + 0.6972827911 0.6972827911 0.6166592240 + 0.6981540918 0.6981540918 0.6176441908 + 0.6990255117 0.6990255117 0.6186292171 + 0.6998962164 0.6998962164 0.6196087003 + 0.7007628083 0.7007628083 0.6205787063 + 0.7016295195 0.7016295195 0.6215487123 + 0.7024961114 0.7024961114 0.6225187182 + 0.7033627033 0.7033627033 0.6234884858 + 0.7042225003 0.7042225003 0.6244485974 + 0.7050803900 0.7050803900 0.6254087090 + 0.7059382796 0.7059382796 0.6263688207 + 0.7067962885 0.7067962885 0.6273288727 + 0.7076508999 0.7076508999 0.6282864809 + 0.7085005045 0.7085005045 0.6292427778 + 0.7093501091 0.7093501091 0.6301990747 + 0.7101997137 0.7101997137 0.6311553717 + 0.7110493183 0.7110493183 0.6321104765 + 0.7118933797 0.7118933797 0.6330611706 + 0.7127372026 0.7127372026 0.6340118051 + 0.7135810852 0.7135810852 0.6349623799 + 0.7144250274 0.7144250274 0.6359130740 + 0.7152673006 0.7152673006 0.6368628144 + 0.7161080241 0.7161080241 0.6378120780 + 0.7169486880 0.7169486880 0.6387614012 + 0.7177892923 0.7177892923 0.6397107244 + 0.7186300159 0.7186300159 0.6406584978 + 0.7194681168 0.7194681168 0.6415982842 + 0.7203060985 0.7203060985 0.6425381899 + 0.7211440802 0.7211440802 0.6434779763 + 0.7219821215 0.7219821215 0.6444178820 + 0.7228178978 0.7228178978 0.6453549862 + 0.7236496806 0.7236496806 0.6462903023 + 0.7244815826 0.7244815826 0.6472254992 + 0.7253134847 0.7253134847 0.6481606960 + 0.7261453271 0.7261453271 0.6490960121 + 0.7269656062 0.7269656062 0.6500247121 + 0.7277814746 0.7277814746 0.6509529948 + 0.7285972834 0.7285972834 0.6518813968 + 0.7294130921 0.7294130921 0.6528097987 + 0.7302284837 0.7302284837 0.6537358165 + 0.7310312986 0.7310312986 0.6546552181 + 0.7318341136 0.7318341136 0.6555745006 + 0.7326369286 0.7326369286 0.6564939022 + 0.7334398031 0.7334398031 0.6574133039 + 0.7342393994 0.7342393994 0.6583278179 + 0.7350317240 0.7350317240 0.6592379212 + 0.7358239889 0.7358239889 0.6601479053 + 0.7366163135 0.7366163135 0.6610580087 + 0.7374085188 0.7374085188 0.6619681120 + 0.7381967902 0.7381967902 0.6628733873 + 0.7389813066 0.7389813066 0.6637769938 + 0.7397658229 0.7397658229 0.6646806002 + 0.7405503988 0.7405503988 0.6655843258 + 0.7413349152 0.7413349152 0.6664878726 + 0.7421157956 0.7421157956 0.6673874855 + 0.7428950071 0.7428950071 0.6682866216 + 0.7436742187 0.7436742187 0.6691858172 + 0.7444533706 0.7444533706 0.6700848937 + 0.7452325821 0.7452325821 0.6709840894 + 0.7460039258 0.7460039258 0.6718817949 + 0.7467731833 0.7467731833 0.6727795005 + 0.7475423813 0.7475423813 0.6736772060 + 0.7483115792 0.7483115792 0.6745749712 + 0.7490807772 0.7490807772 0.6754717827 + 0.7498486042 0.7498486042 0.6763551831 + 0.7506161928 0.7506161928 0.6772385240 + 0.7513837814 0.7513837814 0.6781218052 + 0.7521514297 0.7521514297 0.6790052056 + 0.7529190183 0.7529190183 0.6798881292 + 0.7536765933 0.7536765933 0.6807652712 + 0.7544323802 0.7544323802 0.6816424131 + 0.7551882863 0.7551882863 0.6825196147 + 0.7559440732 0.7559440732 0.6833966970 + 0.7566999793 0.7566999793 0.6842737198 + 0.7574527860 0.7574527860 0.6851336956 + 0.7582048178 0.7582048178 0.6859937906 + 0.7589567900 0.7589567900 0.6868538260 + 0.7597088218 0.7597088218 0.6877138019 + 0.7604607940 0.7604607940 0.6885737777 + 0.7612053156 0.7612053156 0.6894273758 + 0.7619463801 0.7619463801 0.6902801991 + 0.7626876235 0.7626876235 0.6911330819 + 0.7634288073 0.7634288073 0.6919859052 + 0.7641698718 0.7641698718 0.6928387284 + 0.7649000883 0.7649000883 0.6936817169 + 0.7656204104 0.7656204104 0.6945211887 + 0.7663406134 0.7663406134 0.6953607202 + 0.7670608759 0.7670608759 0.6962001920 + 0.7677811980 0.7677811980 0.6970396042 + 0.7684996128 0.7684996128 0.6978752017 + 0.7692136168 0.7692136168 0.6987071037 + 0.7699276209 0.7699276209 0.6995388865 + 0.7706416249 0.7706416249 0.7003707886 + 0.7713556290 0.7713556290 0.7012026906 + 0.7720690966 0.7720690966 0.7020341158 + 0.7727692723 0.7727692723 0.7028638721 + 0.7734695077 0.7734695077 0.7036936879 + 0.7741696835 0.7741696835 0.7045235038 + 0.7748699188 0.7748699188 0.7053533792 + 0.7755700946 0.7755700946 0.7061831951 + 0.7762656212 0.7762656212 0.7070057988 + 0.7769591808 0.7769591808 0.7078278065 + 0.7776529193 0.7776529193 0.7086496949 + 0.7783464789 0.7783464789 0.7094715834 + 0.7790400982 0.7790400982 0.7102934718 + 0.7797309756 0.7797309756 0.7111132741 + 0.7804160714 0.7804160714 0.7119309902 + 0.7811012268 0.7811012268 0.7127488256 + 0.7817863226 0.7817863226 0.7135666013 + 0.7824714184 0.7824714184 0.7143843174 + 0.7831565142 0.7831565142 0.7152014971 + 0.7838354707 0.7838354707 0.7160099149 + 0.7845135927 0.7845135927 0.7168182135 + 0.7851915956 0.7851915956 0.7176265717 + 0.7858697176 0.7858697176 0.7184348702 + 0.7865477800 0.7865477800 0.7192432880 + 0.7872189879 0.7872189879 0.7200449109 + 0.7878777981 0.7878777981 0.7208411098 + 0.7885367274 0.7885367274 0.7216373086 + 0.7891955972 0.7891955972 0.7224333882 + 0.7898544073 0.7898544073 0.7232295871 + 0.7905132771 0.7905132771 0.7240257859 + 0.7911655903 0.7911655903 0.7248097062 + 0.7918161750 0.7918161750 0.7255933881 + 0.7924668193 0.7924668193 0.7263771296 + 0.7931174040 0.7931174040 0.7271608114 + 0.7937679887 0.7937679887 0.7279444933 + 0.7944167256 0.7944167256 0.7287240028 + 0.7950556278 0.7950556278 0.7294961214 + 0.7956945896 0.7956945896 0.7302681208 + 0.7963336110 0.7963336110 0.7310401797 + 0.7969725728 0.7969725728 0.7318121791 + 0.7976115942 0.7976115942 0.7325842977 + 0.7982401848 0.7982401848 0.7333511114 + 0.7988576889 0.7988576889 0.7341153026 + 0.7994753122 0.7994753122 0.7348794937 + 0.8000928164 0.8000928164 0.7356436849 + 0.8007103205 0.8007103205 0.7364078760 + 0.8013278246 0.8013278246 0.7371721268 + 0.8019409180 0.8019409180 0.7379267216 + 0.8025524020 0.8025524020 0.7386804819 + 0.8031638861 0.8031638861 0.7394343019 + 0.8037754297 0.8037754297 0.7401881218 + 0.8043869138 0.8043869138 0.7409418225 + 0.8049983978 0.8049983978 0.7416955233 + 0.8055992126 0.8055992126 0.7424479723 + 0.8061988950 0.8061988950 0.7432004809 + 0.8067986965 0.8067986965 0.7439529896 + 0.8073984981 0.8073984981 0.7447054982 + 0.8079982996 0.8079982996 0.7454580069 + 0.8085979223 0.8085979223 0.7462081909 + 0.8091943860 0.8091943860 0.7469503880 + 0.8097909093 0.8097909093 0.7476925850 + 0.8103873134 0.8103873134 0.7484347820 + 0.8109837770 0.8109837770 0.7491769791 + 0.8115803003 0.8115803003 0.7499191761 + 0.8121759295 0.8121759295 0.7506610751 + 0.8127642274 0.8127642274 0.7514020801 + 0.8133525252 0.8133525252 0.7521430850 + 0.8139408231 0.8139408231 0.7528840899 + 0.8145290017 0.8145290017 0.7536250949 + 0.8151172996 0.8151172996 0.7543660998 + 0.8157039881 0.8157039881 0.7551041842 + 0.8162763119 0.8162763119 0.7558351159 + 0.8168486953 0.8168486953 0.7565659285 + 0.8174210787 0.8174210787 0.7572966814 + 0.8179934025 0.8179934025 0.7580274940 + 0.8185657859 0.8185657859 0.7587584257 + 0.8191381097 0.8191381097 0.7594878078 + 0.8197093010 0.8197093010 0.7602121234 + 0.8202804923 0.8202804923 0.7609363794 + 0.8208516836 0.8208516836 0.7616605759 + 0.8214228749 0.8214228749 0.7623848915 + 0.8219941258 0.8219941258 0.7631092072 + 0.8225653172 0.8225653172 0.7638326287 + 0.8231304884 0.8231304884 0.7645456791 + 0.8236950040 0.8236950040 0.7652587891 + 0.8242594004 0.8242594004 0.7659717798 + 0.8248239160 0.8248239160 0.7666848898 + 0.8253883719 0.8253883719 0.7673979998 + 0.8259528875 0.8259528875 0.7681111097 + 0.8265138268 0.8265138268 0.7688196898 + 0.8270732164 0.8270732164 0.7695276737 + 0.8276326060 0.8276326060 0.7702357173 + 0.8281919956 0.8281919956 0.7709437013 + 0.8287513852 0.8287513852 0.7716516852 + 0.8293107748 0.8293107748 0.7723596096 + 0.8298665881 0.8298665881 0.7730653286 + 0.8304176927 0.8304176927 0.7737694979 + 0.8309687972 0.8309687972 0.7744737267 + 0.8315199018 0.8315199018 0.7751778960 + 0.8320710063 0.8320710063 0.7758821249 + 0.8326221108 0.8326221108 0.7765862942 + 0.8331729174 0.8331729174 0.7772877216 + 0.8337209225 0.8337209225 0.7779809833 + 0.8342689276 0.8342689276 0.7786744237 + 0.8348168135 0.8348168135 0.7793678045 + 0.8353648186 0.8353648186 0.7800611854 + 0.8359127045 0.8359127045 0.7807545066 + 0.8364607096 0.8364607096 0.7814478874 + 0.8370041251 0.8370041251 0.7821326256 + 0.8375453949 0.8375453949 0.7828158140 + 0.8380867243 0.8380867243 0.7834990025 + 0.8386281133 0.8386281133 0.7841823101 + 0.8391693830 0.8391693830 0.7848654985 + 0.8397107124 0.8397107124 0.7855486870 + 0.8402513862 0.8402513862 0.7862282991 + 0.8407893777 0.8407893777 0.7869021297 + 0.8413274288 0.8413274288 0.7875759006 + 0.8418654799 0.8418654799 0.7882496119 + 0.8424034715 0.8424034715 0.7889233828 + 0.8429415226 0.8429415226 0.7895972133 + 0.8434795737 0.8434795737 0.7902709246 + 0.8440154791 0.8440154791 0.7909373045 + 0.8445503712 0.8445503712 0.7916023135 + 0.8450853229 0.8450853229 0.7922673225 + 0.8456202149 0.8456202149 0.7929322124 + 0.8461551070 0.8461551070 0.7935972214 + 0.8466899991 0.8466899991 0.7942621112 + 0.8472244143 0.8472244143 0.7949252725 + 0.8477507234 0.8477507234 0.7955821753 + 0.8482769728 0.8482769728 0.7962390184 + 0.8488032818 0.8488032818 0.7968958020 + 0.8493295908 0.8493295908 0.7975527048 + 0.8498557806 0.8498557806 0.7982094884 + 0.8503820896 0.8503820896 0.7988663912 + 0.8509023786 0.8509023786 0.7995193005 + 0.8514125943 0.8514125943 0.8001686931 + 0.8519228101 0.8519228101 0.8008180857 + 0.8524330258 0.8524330258 0.8014674783 + 0.8529431224 0.8529431224 0.8021169901 + 0.8534532785 0.8534532785 0.8027663827 + 0.8539634943 0.8539634943 0.8034157753 + 0.8544731736 0.8544731736 0.8040614128 + 0.8549826145 0.8549826145 0.8047059178 + 0.8554919958 0.8554919958 0.8053503036 + 0.8560013175 0.8560013175 0.8059946895 + 0.8565106988 0.8565106988 0.8066391945 + 0.8570200801 0.8570200801 0.8072835803 + 0.8575295210 0.8575295210 0.8079280257 + 0.8580337167 0.8580337167 0.8085677028 + 0.8585366011 0.8585366011 0.8092070818 + 0.8590394258 0.8590394258 0.8098465204 + 0.8595423102 0.8595423102 0.8104857802 + 0.8600450754 0.8600450754 0.8111252189 + 0.8605480194 0.8605480194 0.8117644787 + 0.8610509038 0.8610509038 0.8124037981 + 0.8615514040 0.8615514040 0.8130391240 + 0.8620514870 0.8620514870 0.8136743903 + 0.8625516891 0.8625516891 0.8143097162 + 0.8630518913 0.8630518913 0.8149451017 + 0.8635520935 0.8635520935 0.8155804276 + 0.8640522957 0.8640522957 0.8162156940 + 0.8645523787 0.8645523787 0.8168507218 + 0.8650534749 0.8650534749 0.8174775243 + 0.8655548096 0.8655548096 0.8181043863 + 0.8660560250 0.8660560250 0.8187311888 + 0.8665571809 0.8665571809 0.8193581104 + 0.8670583963 0.8670583963 0.8199849129 + 0.8675596714 0.8675596714 0.8206117749 + 0.8680608869 0.8680608869 0.8212385774 + 0.8685551882 0.8685551882 0.8218612075 + 0.8690482974 0.8690482974 0.8224837184 + 0.8695412874 0.8695412874 0.8231062293 + 0.8700343966 0.8700343966 0.8237286210 + 0.8705273867 0.8705273867 0.8243510723 + 0.8710203767 0.8710203767 0.8249735832 + 0.8715134859 0.8715134859 0.8255960941 + 0.8719956875 0.8719956875 0.8262088895 + 0.8724732995 0.8724732995 0.8268200159 + 0.8729509711 0.8729509711 0.8274310827 + 0.8734285831 0.8734285831 0.8280420899 + 0.8739063144 0.8739063144 0.8286532164 + 0.8743839264 0.8743839264 0.8292642832 + 0.8748615980 0.8748615980 0.8298754096 + 0.8753389120 0.8753389120 0.8304854035 + 0.8758158088 0.8758158088 0.8310946822 + 0.8762927055 0.8762927055 0.8317040801 + 0.8767696023 0.8767696023 0.8323134780 + 0.8772464991 0.8772464991 0.8329228163 + 0.8777233958 0.8777233958 0.8335322142 + 0.8782002926 0.8782002926 0.8341416121 + 0.8786755800 0.8786755800 0.8347480297 + 0.8791444898 0.8791444898 0.8353486061 + 0.8796133995 0.8796133995 0.8359493017 + 0.8800823092 0.8800823092 0.8365498781 + 0.8805512190 0.8805512190 0.8371505737 + 0.8810201287 0.8810201287 0.8377512097 + 0.8814889789 0.8814889789 0.8383519053 + 0.8819578886 0.8819578886 0.8389524817 + 0.8824142218 0.8824142218 0.8395484090 + 0.8828679919 0.8828679919 0.8401440978 + 0.8833217025 0.8833217025 0.8407397866 + 0.8837754726 0.8837754726 0.8413354158 + 0.8842293024 0.8842293024 0.8419311047 + 0.8846830726 0.8846830726 0.8425267935 + 0.8851369023 0.8851369023 0.8431224823 + 0.8855882287 0.8855882287 0.8437144756 + 0.8860356212 0.8860356212 0.8443030119 + 0.8864830136 0.8864830136 0.8448914886 + 0.8869304061 0.8869304061 0.8454800844 + 0.8873776793 0.8873776793 0.8460686207 + 0.8878250718 0.8878250718 0.8466570973 + 0.8882725239 0.8882725239 0.8472455740 + 0.8887199163 0.8887199163 0.8478341103 + 0.8891612291 0.8891612291 0.8484159112 + 0.8896014094 0.8896014094 0.8489974737 + 0.8900417089 0.8900417089 0.8495792150 + 0.8904820085 0.8904820085 0.8501607776 + 0.8909221888 0.8909221888 0.8507425189 + 0.8913624883 0.8913624883 0.8513240814 + 0.8918027282 0.8918027282 0.8519057035 + 0.8922411799 0.8922411799 0.8524854779 + 0.8926743269 0.8926743269 0.8530620933 + 0.8931074142 0.8931074142 0.8536388278 + 0.8935403824 0.8935403824 0.8542153835 + 0.8939735293 0.8939735293 0.8547919989 + 0.8944066167 0.8944066167 0.8553686142 + 0.8948397040 0.8948397040 0.8559452891 + 0.8952727914 0.8952727914 0.8565219045 + 0.8957030177 0.8957030177 0.8570963740 + 0.8961309195 0.8961309195 0.8576697707 + 0.8965588212 0.8965588212 0.8582432866 + 0.8969867229 0.8969867229 0.8588168025 + 0.8974146843 0.8974146843 0.8593901992 + 0.8978425860 0.8978425860 0.8599637151 + 0.8982704878 0.8982704878 0.8605371714 + 0.8986983895 0.8986983895 0.8611106873 + 0.8991193175 0.8991193175 0.8616771102 + 0.8995382190 0.8995382190 0.8622428179 + 0.8999571204 0.8999571204 0.8628084064 + 0.9003760219 0.9003760219 0.8633741140 + 0.9007949233 0.9007949233 0.8639398217 + 0.9012138247 0.9012138247 0.8645054102 + 0.9016327262 0.9016327262 0.8650711179 + 0.9020516276 0.9020516276 0.8656365275 + 0.9024695158 0.9024695158 0.8661962152 + 0.9028872848 0.9028872848 0.8667557836 + 0.9033051729 0.9033051729 0.8673154116 + 0.9037230015 0.9037230015 0.8678750992 + 0.9041407704 0.9041407704 0.8684347272 + 0.9045585990 0.9045585990 0.8689942956 + 0.9049764872 0.9049764872 0.8695539236 + 0.9053943157 0.9053943157 0.8701127172 + 0.9058037996 0.9058037996 0.8706625104 + 0.9062129855 0.9062129855 0.8712123036 + 0.9066222906 0.9066222906 0.8717620969 + 0.9070315957 0.9070315957 0.8723118901 + 0.9074407816 0.9074407816 0.8728616834 + 0.9078500867 0.9078500867 0.8734114170 + 0.9082593918 0.9082593918 0.8739612103 + 0.9086686969 0.9086686969 0.8745108247 + 0.9090744257 0.9090744257 0.8750563860 + 0.9094799757 0.9094799757 0.8756021261 + 0.9098855853 0.9098855853 0.8761476874 + 0.9102911949 0.9102911949 0.8766933084 + 0.9106968045 0.9106968045 0.8772389293 + 0.9111024141 0.9111024141 0.8777846098 + 0.9115080237 0.9115080237 0.8783301711 + 0.9119135737 0.9119135737 0.8788757920 + 0.9123172760 0.9123172760 0.8794146180 + 0.9127206802 0.9127206802 0.8799529076 + 0.9131240845 0.9131240845 0.8804911971 + 0.9135274291 0.9135274291 0.8810294867 + 0.9139307737 0.9139307737 0.8815677762 + 0.9143341780 0.9143341780 0.8821061254 + 0.9147375822 0.9147375822 0.8826442957 + 0.9151409268 0.9151409268 0.8831825852 + 0.9155405164 0.9155405164 0.8837168813 + 0.9159377217 0.9159377217 0.8842496276 + 0.9163349271 0.9163349271 0.8847821951 + 0.9167321920 0.9167321920 0.8853148818 + 0.9171293974 0.9171293974 0.8858476281 + 0.9175266027 0.9175266027 0.8863803148 + 0.9179238081 0.9179238081 0.8869130015 + 0.9183210135 0.9183210135 0.8874456882 + 0.9187163711 0.9187163711 0.8879768252 + 0.9191077948 0.9191077948 0.8885056973 + 0.9194992185 0.9194992185 0.8890346885 + 0.9198907018 0.9198907018 0.8895636201 + 0.9202821255 0.9202821255 0.8900926113 + 0.9206734896 0.9206734896 0.8906214833 + 0.9210649133 0.9210649133 0.8911504745 + 0.9214563966 0.9214563966 0.8916794062 + 0.9218478203 0.9218478203 0.8922079802 + 0.9222431183 0.9222431183 0.8927248120 + 0.9226387143 0.9226387143 0.8932415843 + 0.9230343103 0.9230343103 0.8937584162 + 0.9234299064 0.9234299064 0.8942751288 + 0.9238255024 0.9238255024 0.8947919011 + 0.9242212176 0.9242212176 0.8953086734 + 0.9246168137 0.9246168137 0.8958255053 + 0.9250124097 0.9250124097 0.8963422179 + 0.9254066944 0.9254066944 0.8968577981 + 0.9257994294 0.9257994294 0.8973724246 + 0.9261922240 0.9261922240 0.8978869915 + 0.9265850186 0.9265850186 0.8984016776 + 0.9269778132 0.9269778132 0.8989163041 + 0.9273704886 0.9273704886 0.8994308710 + 0.9277632833 0.9277632833 0.8999454975 + 0.9281560779 0.9281560779 0.9004601240 + 0.9285488129 0.9285488129 0.9009746909 + 0.9289314151 0.9289314151 0.9014821053 + 0.9293128252 0.9293128252 0.9019892216 + 0.9296941161 0.9296941161 0.9024963975 + 0.9300754070 0.9300754070 0.9030035138 + 0.9304568172 0.9304568172 0.9035106897 + 0.9308381081 0.9308381081 0.9040178061 + 0.9312195182 0.9312195182 0.9045249820 + 0.9316008091 0.9316008091 0.9050320983 + 0.9319807887 0.9319807887 0.9055399895 + 0.9323564172 0.9323564172 0.9060496092 + 0.9327319860 0.9327319860 0.9065591097 + 0.9331076145 0.9331076145 0.9070687294 + 0.9334831834 0.9334831834 0.9075781703 + 0.9338588119 0.9338588119 0.9080877900 + 0.9342343807 0.9342343807 0.9085972905 + 0.9346100092 0.9346100092 0.9091069102 + 0.9349855781 0.9349855781 0.9096164107 + 0.9353610277 0.9353610277 0.9101235867 + 0.9357361794 0.9357361794 0.9106287956 + 0.9361115098 0.9361115098 0.9111341238 + 0.9364867210 0.9364867210 0.9116392732 + 0.9368619919 0.9368619919 0.9121444821 + 0.9372372031 0.9372372031 0.9126498103 + 0.9376124740 0.9376124740 0.9131550193 + 0.9379876852 0.9379876852 0.9136602879 + 0.9383630157 0.9383630157 0.9141654968 + 0.9387336969 0.9387336969 0.9146683216 + 0.9391016960 0.9391016960 0.9151700735 + 0.9394698143 0.9394698143 0.9156718850 + 0.9398378134 0.9398378134 0.9161736965 + 0.9402058125 0.9402058125 0.9166755080 + 0.9405738115 0.9405738115 0.9171772003 + 0.9409418106 0.9409418106 0.9176790118 + 0.9413098097 0.9413098097 0.9181808233 + 0.9416779280 0.9416779280 0.9186825752 + 0.9420405030 0.9420405030 0.9191823006 + 0.9424005747 0.9424005747 0.9196813107 + 0.9427607059 0.9427607059 0.9201803803 + 0.9431207180 0.9431207180 0.9206793904 + 0.9434807897 0.9434807897 0.9211784005 + 0.9438409209 0.9438409209 0.9216774106 + 0.9442009926 0.9442009926 0.9221764803 + 0.9445611238 0.9445611238 0.9226754904 + 0.9449210763 0.9449210763 0.9231745005 + 0.9452818036 0.9452818036 0.9236670136 + 0.9456428289 0.9456428289 0.9241566062 + 0.9460036755 0.9460036755 0.9246463180 + 0.9463647008 0.9463647008 0.9251359105 + 0.9467257261 0.9467257261 0.9256255031 + 0.9470866919 0.9470866919 0.9261152148 + 0.9474475980 0.9474475980 0.9266048074 + 0.9478086233 0.9478086233 0.9270945191 + 0.9481695890 0.9481695890 0.9275841117 + 0.9485284090 0.9485284090 0.9280738831 + 0.9488850236 0.9488850236 0.9285637140 + 0.9492415786 0.9492415786 0.9290536046 + 0.9495981932 0.9495981932 0.9295433760 + 0.9499548078 0.9499548078 0.9300333261 + 0.9503114223 0.9503114223 0.9305232167 + 0.9506679773 0.9506679773 0.9310129881 + 0.9510245919 0.9510245919 0.9315028787 + 0.9513812065 0.9513812065 0.9319928288 + 0.9517353773 0.9517353773 0.9324811101 + 0.9520826936 0.9520826936 0.9329659939 + 0.9524298906 0.9524298906 0.9334508777 + 0.9527770877 0.9527770877 0.9339358211 + 0.9531244040 0.9531244040 0.9344208241 + 0.9534716010 0.9534716010 0.9349057078 + 0.9538187981 0.9538187981 0.9353905916 + 0.9541659951 0.9541659951 0.9358754754 + 0.9545133114 0.9545133114 0.9363604784 + 0.9548605084 0.9548605084 0.9368454218 + 0.9552074075 0.9552074075 0.9373251796 + 0.9555541873 0.9555541873 0.9378048778 + 0.9559010267 0.9559010267 0.9382845759 + 0.9562478065 0.9562478065 0.9387642145 + 0.9565945864 0.9565945864 0.9392439127 + 0.9569414258 0.9569414258 0.9397236109 + 0.9572882056 0.9572882056 0.9402033091 + 0.9576349854 0.9576349854 0.9406828880 + 0.9579818249 0.9579818249 0.9411625862 + 0.9583277106 0.9583277106 0.9416403770 + 0.9586725235 0.9586725235 0.9421163201 + 0.9590172172 0.9590172172 0.9425923228 + 0.9593619704 0.9593619704 0.9430683255 + 0.9597067237 0.9597067237 0.9435443282 + 0.9600514770 0.9600514770 0.9440202713 + 0.9603962898 0.9603962898 0.9444962144 + 0.9607409835 0.9607409835 0.9449722171 + 0.9610857964 0.9610857964 0.9454482198 + 0.9614306092 0.9614306092 0.9459242225 + 0.9617655277 0.9617655277 0.9463955164 + 0.9620996714 0.9620996714 0.9468665719 + 0.9624338150 0.9624338150 0.9473378062 + 0.9627678990 0.9627678990 0.9478089213 + 0.9631021023 0.9631021023 0.9482800961 + 0.9634361863 0.9634361863 0.9487512112 + 0.9637703896 0.9637703896 0.9492223859 + 0.9641044736 0.9641044736 0.9496935010 + 0.9644386172 0.9644386172 0.9501646757 + 0.9647706747 0.9647706747 0.9506316185 + 0.9650973082 0.9650973082 0.9510896206 + 0.9654238820 0.9654238820 0.9515476823 + 0.9657505155 0.9657505155 0.9520056844 + 0.9660770893 0.9660770893 0.9524638057 + 0.9664037228 0.9664037228 0.9529218078 + 0.9667302966 0.9667302966 0.9533798099 + 0.9670568705 0.9670568705 0.9538378716 + 0.9673835039 0.9673835039 0.9542958736 + 0.9677100778 0.9677100778 0.9547539949 + 0.9680343866 0.9680343866 0.9552072287 + 0.9683567286 0.9683567286 0.9556567073 + 0.9686790109 0.9686790109 0.9561061859 + 0.9690012932 0.9690012932 0.9565556049 + 0.9693235159 0.9693235159 0.9570050836 + 0.9696457982 0.9696457982 0.9574546218 + 0.9699680805 0.9699680805 0.9579041004 + 0.9702903032 0.9702903032 0.9583535790 + 0.9706125855 0.9706125855 0.9588031173 + 0.9709349275 0.9709349275 0.9592525959 + 0.9712525010 0.9712525010 0.9596999288 + 0.9715678096 0.9715678096 0.9601463079 + 0.9718831182 0.9718831182 0.9605926275 + 0.9721983075 0.9721983075 0.9610390067 + 0.9725136161 0.9725136161 0.9614853859 + 0.9728289247 0.9728289247 0.9619318247 + 0.9731441736 0.9731441736 0.9623782039 + 0.9734594226 0.9734594226 0.9628245234 + 0.9737746716 0.9737746716 0.9632709026 + 0.9740899801 0.9740899801 0.9637172818 + 0.9744006991 0.9744006991 0.9641577005 + 0.9747095108 0.9747095108 0.9645959735 + 0.9750183225 0.9750183225 0.9650343060 + 0.9753270745 0.9753270745 0.9654725194 + 0.9756358266 0.9756358266 0.9659107924 + 0.9759445786 0.9759445786 0.9663491249 + 0.9762533903 0.9762533903 0.9667872787 + 0.9765622020 0.9765622020 0.9672256112 + 0.9768708944 0.9768708944 0.9676638246 + 0.9771797061 0.9771797061 0.9681020975 + 0.9774832129 0.9774832129 0.9685348868 + 0.9777835011 0.9777835011 0.9689648747 + 0.9780837893 0.9780837893 0.9693949223 + 0.9783840775 0.9783840775 0.9698249102 + 0.9786844254 0.9786844254 0.9702548981 + 0.9789847136 0.9789847136 0.9706848264 + 0.9792850018 0.9792850018 0.9711148143 + 0.9795852900 0.9795852900 0.9715448022 + 0.9798855782 0.9798855782 0.9719747901 + 0.9801859260 0.9801859260 0.9724047780 + 0.9804825187 0.9804825187 0.9728298187 + 0.9807745814 0.9807745814 0.9732491970 + 0.9810665846 0.9810665846 0.9736686945 + 0.9813587070 0.9813587070 0.9740880728 + 0.9816508293 0.9816508293 0.9745075107 + 0.9819427729 0.9819427729 0.9749270082 + 0.9822348952 0.9822348952 0.9753463864 + 0.9825268984 0.9825268984 0.9757658243 + 0.9828190207 0.9828190207 0.9761853218 + 0.9831110239 0.9831110239 0.9766047001 + 0.9834020734 0.9834020734 0.9770221114 + 0.9836878181 0.9836878181 0.9774296284 + 0.9839735031 0.9839735031 0.9778370857 + 0.9842591882 0.9842591882 0.9782447219 + 0.9845448732 0.9845448732 0.9786521792 + 0.9848306179 0.9848306179 0.9790596962 + 0.9851163030 0.9851163030 0.9794672132 + 0.9854019880 0.9854019880 0.9798747897 + 0.9856876135 0.9856876135 0.9802823067 + 0.9859732985 0.9859732985 0.9806898236 + 0.9862589836 0.9862589836 0.9810972810 + 0.9865384102 0.9865384102 0.9814953208 + 0.9868156910 0.9868156910 0.9818902016 + 0.9870929122 0.9870929122 0.9822852015 + 0.9873701930 0.9873701930 0.9826802015 + 0.9876474142 0.9876474142 0.9830750823 + 0.9879245758 0.9879245758 0.9834700823 + 0.9882019162 0.9882019162 0.9838650823 + 0.9884790778 0.9884790778 0.9842600226 + 0.9887564182 0.9887564182 0.9846550226 + 0.9890335798 0.9890335798 0.9850500226 + 0.9893082976 0.9893082976 0.9854415059 + 0.9895743132 0.9895743132 0.9858223200 + 0.9898403287 0.9898403287 0.9862031937 + 0.9901062846 0.9901062846 0.9865840077 + 0.9903723001 0.9903723001 0.9869648218 + 0.9906383157 0.9906383157 0.9873455763 + 0.9909042120 0.9909042120 0.9877265096 + 0.9911702275 0.9911702275 0.9881073236 + 0.9914361835 0.9914361835 0.9884880781 + 0.9917021990 0.9917021990 0.9888688922 + 0.9919682145 0.9919682145 0.9892497063 + 0.9922304153 0.9922304153 0.9896146059 + 0.9924901128 0.9924901128 0.9899690151 + 0.9927496910 0.9927496910 0.9903233051 + 0.9930093288 0.9930093288 0.9906777143 + 0.9932690263 0.9932690263 0.9910321236 + 0.9935286045 0.9935286045 0.9913864136 + 0.9937881827 0.9937881827 0.9917408228 + 0.9940478206 0.9940478206 0.9920951724 + 0.9943075180 0.9943075180 0.9924495220 + 0.9945670962 0.9945670962 0.9928038716 + 0.9948266745 0.9948266745 0.9931582808 + 0.9950770140 0.9950770140 0.9934852719 + 0.9953256249 0.9953256249 0.9938076735 + 0.9955741167 0.9955741167 0.9941300750 + 0.9958227277 0.9958227277 0.9944524169 + 0.9960712194 0.9960712194 0.9947748184 + 0.9963197708 0.9963197708 0.9950972199 + 0.9965683222 0.9965683222 0.9954195023 + 0.9968168736 0.9968168736 0.9957419038 + 0.9970654249 0.9970654249 0.9960643053 + 0.9973139763 0.9973139763 0.9963865876 + 0.9975625277 0.9975625277 0.9967089891 + 0.9977846146 0.9977846146 0.9970085025 + 0.9980061054 0.9980061054 0.9973075986 + 0.9982277155 0.9982277155 0.9976068139 + 0.9984492064 0.9984492064 0.9979059100 + 0.9986708164 0.9986708164 0.9982051253 + 0.9988923073 0.9988923073 0.9985042214 + 0.9991137981 0.9991137981 0.9988033772 + 0.9993354082 0.9993354082 0.9991024733 + 0.9995568991 0.9995568991 0.9994016886 + 0.9997785091 0.9997785091 0.9997007847 + 1.0000000000 1.0000000000 1.0000000000 +} diff --git a/rpplugins/color_correction/resources/film_luts_raw/kodak_gold_200.spi1d b/rpplugins/color_correction/resources/film_luts_raw/kodak_gold_200.spi1d new file mode 100644 index 0000000..7681128 --- /dev/null +++ b/rpplugins/color_correction/resources/film_luts_raw/kodak_gold_200.spi1d @@ -0,0 +1,1030 @@ +Version 1 +From 0.0 1.0 +Length 1024 +Components 3 +{ + 0.0000000000 0.0000000000 0.0000000000 + 0.0069576460 0.0052925618 0.0033476830 + 0.0141364904 0.0107551003 0.0067514139 + 0.0207183994 0.0159495007 0.0101133399 + 0.0267989002 0.0208614096 0.0133742504 + 0.0324718915 0.0254526306 0.0165257901 + 0.0378164984 0.0299201701 0.0196132604 + 0.0428869314 0.0341088213 0.0225949902 + 0.0477258898 0.0381722189 0.0255131796 + 0.0523908511 0.0420860387 0.0283894595 + 0.0568610094 0.0458872616 0.0311939605 + 0.0611275584 0.0495900512 0.0339626707 + 0.0653016865 0.0531945191 0.0367048383 + 0.0693744496 0.0567364991 0.0393822007 + 0.0733573064 0.0602095909 0.0420081317 + 0.0771774426 0.0635916665 0.0445935093 + 0.0809165314 0.0668876693 0.0471374691 + 0.0845568478 0.0701269805 0.0496489182 + 0.0881353170 0.0733123422 0.0521427989 + 0.0916419923 0.0764425769 0.0546066016 + 0.0950766504 0.0795146525 0.0570084900 + 0.0984379798 0.0825331509 0.0593760982 + 0.1017495021 0.0855173692 0.0617147498 + 0.1049598977 0.0884445384 0.0640344396 + 0.1081260964 0.0913117006 0.0663272068 + 0.1112463027 0.0941295624 0.0686026216 + 0.1143177003 0.0968901590 0.0708457306 + 0.1173487976 0.0996170789 0.0730642602 + 0.1203667000 0.1023124009 0.0752720088 + 0.1233123019 0.1049759015 0.0774757266 + 0.1262118965 0.1076003984 0.0796506926 + 0.1290674955 0.1101882979 0.0817981884 + 0.1318753064 0.1127377972 0.0839270800 + 0.1346521974 0.1152800992 0.0860472471 + 0.1373953074 0.1178082004 0.0881496072 + 0.1401219070 0.1203086972 0.0902255625 + 0.1428176016 0.1227945015 0.0922822729 + 0.1454751045 0.1252799928 0.0943331197 + 0.1481045038 0.1277426928 0.0963695124 + 0.1507305056 0.1301932037 0.0983908027 + 0.1533288956 0.1326095015 0.1003959030 + 0.1558901072 0.1350027025 0.1023878008 + 0.1584240943 0.1373652965 0.1043625996 + 0.1609431952 0.1397027969 0.1063340977 + 0.1634577960 0.1420170069 0.1083092019 + 0.1659422070 0.1442991942 0.1102795005 + 0.1683879048 0.1465636939 0.1122395992 + 0.1708077043 0.1488011926 0.1141989976 + 0.1732032001 0.1510327011 0.1161565036 + 0.1755875945 0.1532423943 0.1181034967 + 0.1779661030 0.1554349959 0.1200399995 + 0.1803372949 0.1576205045 0.1219606996 + 0.1826853007 0.1597833931 0.1238709986 + 0.1850018948 0.1619350016 0.1257669926 + 0.1873046011 0.1640775949 0.1276451051 + 0.1896051019 0.1661971062 0.1295011044 + 0.1918939054 0.1682944000 0.1313541979 + 0.1941768974 0.1703854054 0.1332028955 + 0.1964391023 0.1724753976 0.1350436956 + 0.1986718029 0.1745598018 0.1368709952 + 0.2008887976 0.1766363978 0.1386903971 + 0.2030901015 0.1787001044 0.1405090988 + 0.2052837014 0.1807560027 0.1423261017 + 0.2074694037 0.1827982068 0.1441355944 + 0.2096378058 0.1848137975 0.1459414959 + 0.2117996961 0.1868076026 0.1477414072 + 0.2139513046 0.1887951046 0.1495409012 + 0.2160806060 0.1907595992 0.1513372064 + 0.2181894034 0.1927050054 0.1531285048 + 0.2202865928 0.1946384013 0.1549127996 + 0.2223830074 0.1965693980 0.1566943973 + 0.2244744003 0.1984919012 0.1584592015 + 0.2265536934 0.2003978044 0.1602202058 + 0.2286141068 0.2022926956 0.1619769037 + 0.2306680977 0.2041870058 0.1637236029 + 0.2327179015 0.2060835958 0.1654655933 + 0.2347580940 0.2079713047 0.1672006994 + 0.2367894948 0.2098497003 0.1689288020 + 0.2388225049 0.2117146999 0.1706545055 + 0.2408446074 0.2135720998 0.1723743975 + 0.2428611964 0.2154268026 0.1740881950 + 0.2448751032 0.2172740996 0.1757902950 + 0.2468796968 0.2191029936 0.1774809957 + 0.2488763928 0.2209150046 0.1791640073 + 0.2508633137 0.2227170020 0.1808429956 + 0.2528334856 0.2245123982 0.1825204939 + 0.2547827065 0.2263000011 0.1841987073 + 0.2567098141 0.2280700058 0.1858744025 + 0.2586239874 0.2298292071 0.1875447035 + 0.2605265081 0.2315824926 0.1892118007 + 0.2624250948 0.2333337963 0.1908793002 + 0.2643153071 0.2350836992 0.1925469935 + 0.2661927938 0.2368271947 0.1942107975 + 0.2680534124 0.2385641932 0.1958703995 + 0.2698996067 0.2402985990 0.1975174993 + 0.2717376053 0.2420333028 0.1991517991 + 0.2735638916 0.2437696010 0.2007769942 + 0.2753801942 0.2455032021 0.2023956031 + 0.2771906853 0.2472324073 0.2040095031 + 0.2789969146 0.2489607930 0.2056213021 + 0.2808091938 0.2506855130 0.2072338015 + 0.2826234102 0.2524011135 0.2088443041 + 0.2844350040 0.2541044950 0.2104482055 + 0.2862409055 0.2558018863 0.2120479047 + 0.2880494893 0.2574988008 0.2136453986 + 0.2898606062 0.2591859102 0.2152310014 + 0.2916708887 0.2608619034 0.2168077976 + 0.2934772968 0.2625282109 0.2183786035 + 0.2952775061 0.2641865015 0.2199451029 + 0.2970677912 0.2658401132 0.2215090990 + 0.2988429070 0.2674838006 0.2230720073 + 0.3006018996 0.2691144943 0.2246360928 + 0.3023515940 0.2707369030 0.2262039930 + 0.3040930927 0.2723526061 0.2277673930 + 0.3058268130 0.2739633918 0.2293279022 + 0.3075599968 0.2755722106 0.2308869064 + 0.3092887998 0.2771736085 0.2324458063 + 0.3110117018 0.2787660062 0.2339975983 + 0.3127267957 0.2803517878 0.2355509996 + 0.3144324124 0.2819328010 0.2371080071 + 0.3161234856 0.2835094035 0.2386678010 + 0.3178110123 0.2850857973 0.2402258068 + 0.3194932044 0.2866651118 0.2417753041 + 0.3211686909 0.2882451117 0.2433187068 + 0.3228329122 0.2898192108 0.2448568046 + 0.3244825006 0.2913886905 0.2463894933 + 0.3261260092 0.2929497957 0.2479178011 + 0.3277656138 0.2945039868 0.2494443953 + 0.3293995857 0.2960574031 0.2509700954 + 0.3310334086 0.2976092100 0.2524966896 + 0.3326669931 0.2991577983 0.2540231049 + 0.3343001902 0.3007017970 0.2555483878 + 0.3359291852 0.3022336960 0.2570703030 + 0.3375551999 0.3037579954 0.2585889101 + 0.3391782939 0.3052760959 0.2601051033 + 0.3408016860 0.3067946136 0.2616184056 + 0.3424184024 0.3083077967 0.2631227970 + 0.3440291882 0.3098174036 0.2646223903 + 0.3456344008 0.3113240898 0.2661170959 + 0.3472355008 0.3128254116 0.2675963044 + 0.3488337100 0.3143222034 0.2690717876 + 0.3504329920 0.3158083856 0.2705436051 + 0.3520256877 0.3172895908 0.2720068991 + 0.3536128998 0.3187673986 0.2734695077 + 0.3551953137 0.3202396035 0.2749320865 + 0.3567740023 0.3217110932 0.2763895094 + 0.3583478928 0.3231821060 0.2778449059 + 0.3599140942 0.3246476054 0.2792975903 + 0.3614780009 0.3261092901 0.2807494998 + 0.3630394042 0.3275642991 0.2822004855 + 0.3645978868 0.3290148973 0.2836417854 + 0.3661546111 0.3304624856 0.2850796878 + 0.3677040935 0.3318977952 0.2865127027 + 0.3692491949 0.3333328068 0.2879436016 + 0.3707874119 0.3347673118 0.2893734872 + 0.3723173141 0.3362007141 0.2908020020 + 0.3738436997 0.3376331925 0.2922300100 + 0.3753637075 0.3390626013 0.2936573029 + 0.3768812120 0.3404957056 0.2950794101 + 0.3783938885 0.3419339061 0.2964994907 + 0.3798997998 0.3433656096 0.2979145050 + 0.3814015985 0.3447945118 0.2993288934 + 0.3829030991 0.3462235928 0.3007413149 + 0.3844040930 0.3476490080 0.3021497130 + 0.3859013915 0.3490602970 0.3035539091 + 0.3873961866 0.3504692018 0.3049587905 + 0.3888866007 0.3518750966 0.3063640893 + 0.3903723955 0.3532764912 0.3077667952 + 0.3918546140 0.3546754122 0.3091700077 + 0.3933346868 0.3560653925 0.3105787933 + 0.3948141932 0.3574534059 0.3119877875 + 0.3962810040 0.3588356972 0.3133974075 + 0.3977459073 0.3602159917 0.3148044050 + 0.3992024958 0.3615838885 0.3162082136 + 0.4006575048 0.3629511893 0.3176136911 + 0.4021052122 0.3643172085 0.3190205097 + 0.4035489857 0.3656820059 0.3204261065 + 0.4049836993 0.3670449853 0.3218308985 + 0.4064174891 0.3684046865 0.3232277036 + 0.4078499079 0.3697603047 0.3246217966 + 0.4092806876 0.3711144030 0.3260087967 + 0.4107097983 0.3724671006 0.3273941875 + 0.4121398926 0.3738192022 0.3287746906 + 0.4135712087 0.3751707971 0.3301542997 + 0.4149979949 0.3765240014 0.3315235972 + 0.4164206088 0.3778783083 0.3328914046 + 0.4178411961 0.3792268932 0.3342565000 + 0.4192601144 0.3805715144 0.3356212080 + 0.4206768870 0.3819119930 0.3369806111 + 0.4220918119 0.3832496107 0.3383392990 + 0.4235030115 0.3845824897 0.3396934867 + 0.4249098897 0.3859112859 0.3410468102 + 0.4263136089 0.3872357011 0.3423964083 + 0.4277122915 0.3885548115 0.3437449038 + 0.4291099906 0.3898749053 0.3450933099 + 0.4305053949 0.3911963999 0.3464416862 + 0.4319001138 0.3925139904 0.3477911949 + 0.4332916141 0.3938207030 0.3491415083 + 0.4346827865 0.3951269984 0.3504894078 + 0.4360674918 0.3964309096 0.3518337011 + 0.4374521971 0.3977347016 0.3531750143 + 0.4388273954 0.3990345001 0.3545077145 + 0.4402016103 0.4003342092 0.3558402061 + 0.4415682852 0.4016295075 0.3571698070 + 0.4429320991 0.4029237032 0.3584994078 + 0.4442929029 0.4042161107 0.3598237038 + 0.4456507862 0.4055073857 0.3611471951 + 0.4470078051 0.4067941010 0.3624671996 + 0.4483624101 0.4080730081 0.3637853861 + 0.4497171044 0.4093518853 0.3651016057 + 0.4510729909 0.4106301963 0.3664149940 + 0.4524287879 0.4119085073 0.3677273989 + 0.4537774920 0.4131798148 0.3690330088 + 0.4551241994 0.4144499004 0.3703387082 + 0.4564689100 0.4157176912 0.3716449142 + 0.4578113854 0.4169836044 0.3729512095 + 0.4591516852 0.4182476103 0.3742561936 + 0.4604795873 0.4195050895 0.3755598962 + 0.4618076086 0.4207625091 0.3768633008 + 0.4631280005 0.4220119119 0.3781648874 + 0.4644466043 0.4232602119 0.3794665039 + 0.4657608867 0.4245094061 0.3807671964 + 0.4670695066 0.4257597029 0.3820675910 + 0.4683777988 0.4270094037 0.3833664060 + 0.4696762860 0.4282543957 0.3846625090 + 0.4709748924 0.4294993877 0.3859587014 + 0.4722695947 0.4307434857 0.3872511983 + 0.4735617936 0.4319871962 0.3885434866 + 0.4748536050 0.4332297146 0.3898344040 + 0.4761427939 0.4344683886 0.3911238909 + 0.4774321020 0.4357070923 0.3924132884 + 0.4787220955 0.4369412065 0.3936966956 + 0.4800123870 0.4381737113 0.3949801922 + 0.4813013077 0.4394079149 0.3962610066 + 0.4825831950 0.4406479895 0.3975391090 + 0.4838651121 0.4418880939 0.3988172114 + 0.4851444066 0.4431279004 0.4000911117 + 0.4864222109 0.4443677068 0.4013648033 + 0.4876995981 0.4456071854 0.4026384950 + 0.4889726043 0.4468455017 0.4039121866 + 0.4902456999 0.4480836987 0.4051857889 + 0.4915165007 0.4493125081 0.4064609110 + 0.4927848876 0.4505336881 0.4077362120 + 0.4940532148 0.4517548084 0.4090102911 + 0.4953213036 0.4529699087 0.4102798104 + 0.4965893030 0.4541845024 0.4115493000 + 0.4978551865 0.4553967118 0.4128125012 + 0.4991137087 0.4566031992 0.4140706956 + 0.5003721714 0.4578095973 0.4153288901 + 0.5016276836 0.4590105116 0.4165867865 + 0.5028806925 0.4602079988 0.4178445935 + 0.5041337013 0.4614056051 0.4191029072 + 0.5053765774 0.4626047909 0.4203636944 + 0.5066177249 0.4638043046 0.4216246009 + 0.5078586936 0.4650028944 0.4228836000 + 0.5090987086 0.4661977887 0.4241401851 + 0.5103386045 0.4673928022 0.4253968894 + 0.5115761161 0.4685871899 0.4266510904 + 0.5128089190 0.4697811902 0.4279040992 + 0.5140416026 0.4709751010 0.4291571975 + 0.5152726173 0.4721660018 0.4304040968 + 0.5165020823 0.4733552933 0.4316503108 + 0.5177316070 0.4745444953 0.4328961074 + 0.5189521909 0.4757269919 0.4341362119 + 0.5201696157 0.4769079983 0.4353761971 + 0.5213869810 0.4780888855 0.4366151094 + 0.5225998163 0.4792577922 0.4378497899 + 0.5238118768 0.4804260135 0.4390844107 + 0.5250239968 0.4815933108 0.4403162897 + 0.5262380242 0.4827486873 0.4415428042 + 0.5274519920 0.4839040935 0.4427692890 + 0.5286653042 0.4850594103 0.4439926147 + 0.5298718810 0.4862147868 0.4452114105 + 0.5310785174 0.4873701930 0.4464302063 + 0.5322846174 0.4885238111 0.4476467967 + 0.5334876776 0.4896706939 0.4488607943 + 0.5346907973 0.4908174872 0.4500747919 + 0.5358918905 0.4919629097 0.4512878060 + 0.5370826721 0.4931035042 0.4524998069 + 0.5382735133 0.4942440987 0.4537116885 + 0.5394629836 0.4953829944 0.4549197853 + 0.5406448841 0.4965158999 0.4561235011 + 0.5418269038 0.4976488054 0.4573271871 + 0.5430071950 0.4987801909 0.4585284889 + 0.5441747904 0.4999046922 0.4597266018 + 0.5453423858 0.5010291934 0.4609247148 + 0.5465098023 0.5021533966 0.4621219039 + 0.5476737022 0.5032743216 0.4633173048 + 0.5488376021 0.5043951869 0.4645127952 + 0.5500016212 0.5055161715 0.4657061100 + 0.5511487722 0.5066317916 0.4668928087 + 0.5522946715 0.5077472925 0.4680793881 + 0.5534405112 0.5088629127 0.4692654908 + 0.5545827150 0.5099775791 0.4704455137 + 0.5557237267 0.5110921264 0.4716255963 + 0.5568647981 0.5122066140 0.4728055894 + 0.5579981804 0.5133147240 0.4739825130 + 0.5591266751 0.5144196153 0.4751591980 + 0.5602552295 0.5155246258 0.4763357937 + 0.5613806248 0.5166273117 0.4775057137 + 0.5625013113 0.5177274942 0.4786727130 + 0.5636219978 0.5188276768 0.4798397124 + 0.5647404194 0.5199279785 0.4809997082 + 0.5658451915 0.5210285187 0.4821512997 + 0.5669500828 0.5221291184 0.4833030105 + 0.5680549145 0.5232295990 0.4844540060 + 0.5691527128 0.5243226886 0.4856021106 + 0.5702494979 0.5254151821 0.4867500961 + 0.5713462234 0.5265076756 0.4878982008 + 0.5724427104 0.5276014209 0.4890469909 + 0.5735387802 0.5286958218 0.4901959002 + 0.5746350288 0.5297902226 0.4913448989 + 0.5757296085 0.5308814049 0.4924908876 + 0.5768179297 0.5319637060 0.4936339855 + 0.5779061913 0.5330458879 0.4947771132 + 0.5789945722 0.5341281295 0.4959191084 + 0.5800734758 0.5352011919 0.4970515966 + 0.5811501741 0.5362728834 0.4981842041 + 0.5822268724 0.5373445749 0.4993166924 + 0.5832991004 0.5384107232 0.5004442930 + 0.5843636990 0.5394697189 0.5015696883 + 0.5854284167 0.5405287147 0.5026950240 + 0.5864930749 0.5415875912 0.5038194060 + 0.5875535011 0.5426415801 0.5049406290 + 0.5886135101 0.5436955094 0.5060616732 + 0.5896735787 0.5447493196 0.5071828961 + 0.5907285810 0.5458040833 0.5082973838 + 0.5917763710 0.5468599796 0.5094091892 + 0.5928242803 0.5479158163 0.5105209947 + 0.5938721895 0.5489715934 0.5116317272 + 0.5949155092 0.5500273705 0.5127375722 + 0.5959581733 0.5510830879 0.5138434768 + 0.5970007777 0.5521388054 0.5149493814 + 0.5980414748 0.5531933904 0.5160537958 + 0.5990775228 0.5542458892 0.5171571970 + 0.6001135111 0.5552983284 0.5182604790 + 0.6011496186 0.5563508272 0.5193638802 + 0.6021804810 0.5573993921 0.5204594731 + 0.6032091975 0.5584467053 0.5215548873 + 0.6042377949 0.5594938993 0.5226503015 + 0.6052662134 0.5605403781 0.5237420797 + 0.6062859893 0.5615794063 0.5248262882 + 0.6073058248 0.5626183152 0.5259104967 + 0.6083257198 0.5636572838 0.5269945860 + 0.6093432903 0.5646920800 0.5280733109 + 0.6103563905 0.5657204986 0.5291488171 + 0.6113694906 0.5667489171 0.5302242041 + 0.6123825908 0.5677773952 0.5312995911 + 0.6133952141 0.5688034892 0.5323687792 + 0.6144075990 0.5698282719 0.5334370732 + 0.6154199243 0.5708531737 0.5345054865 + 0.6164321899 0.5718780756 0.5355728865 + 0.6174443960 0.5728979111 0.5366333723 + 0.6184564233 0.5739170909 0.5376937985 + 0.6194685102 0.5749362707 0.5387542248 + 0.6204805970 0.5759549737 0.5398129225 + 0.6214926243 0.5769659281 0.5408675075 + 0.6225045919 0.5779768825 0.5419220924 + 0.6235166192 0.5789877772 0.5429766774 + 0.6245272756 0.5799971223 0.5440295935 + 0.6255301237 0.5809996724 0.5450801849 + 0.6265329719 0.5820024014 0.5461307168 + 0.6275358796 0.5830050111 0.5471813083 + 0.6285378933 0.5840060711 0.5482295156 + 0.6295374036 0.5850033760 0.5492755175 + 0.6305369139 0.5860008001 0.5503215790 + 0.6315364242 0.5869981050 0.5513677001 + 0.6325309277 0.5879935026 0.5524119735 + 0.6335136890 0.5889853239 0.5534552932 + 0.6344965100 0.5899770856 0.5544984937 + 0.6354792714 0.5909689069 0.5555416942 + 0.6364601254 0.5919576883 0.5565804243 + 0.6374369264 0.5929412246 0.5576159954 + 0.6384136081 0.5939248204 0.5586516261 + 0.6393904090 0.5949084163 0.5596871972 + 0.6403620839 0.5958868861 0.5607174039 + 0.6413215995 0.5968555808 0.5617434978 + 0.6422811151 0.5978243947 0.5627695918 + 0.6432405114 0.5987930894 0.5637956858 + 0.6441984773 0.5997601151 0.5648216009 + 0.6451513767 0.6007226706 0.5658472776 + 0.6461042762 0.6016852260 0.5668728948 + 0.6470571756 0.6026477218 0.5678985715 + 0.6480082870 0.6036084294 0.5689231753 + 0.6489437819 0.6045597792 0.5699462295 + 0.6498792171 0.6055111885 0.5709691048 + 0.6508147120 0.6064625978 0.5719920993 + 0.6517502069 0.6074140072 0.5730134845 + 0.6526796222 0.6083596945 0.5740293860 + 0.6536086798 0.6093053818 0.5750454068 + 0.6545377970 0.6102510095 0.5760613084 + 0.6554667950 0.6111965775 0.5770772099 + 0.6563835144 0.6121419072 0.5780894756 + 0.6572958231 0.6130869985 0.5791018009 + 0.6582080126 0.6140322089 0.5801141262 + 0.6591202021 0.6149773002 0.5811263919 + 0.6600306034 0.6159195900 0.5821347833 + 0.6609390974 0.6168593168 0.5831419230 + 0.6618475914 0.6177989841 0.5841491222 + 0.6627560854 0.6187387705 0.5851562023 + 0.6636629105 0.6196792722 0.5861611962 + 0.6645622253 0.6206220984 0.5871635079 + 0.6654614806 0.6215649247 0.5881658792 + 0.6663607955 0.6225078106 0.5891681910 + 0.6672601104 0.6234505773 0.5901697874 + 0.6681554914 0.6243839860 0.5911645889 + 0.6690502167 0.6253163815 0.5921593904 + 0.6699448824 0.6262487769 0.5931541920 + 0.6708396077 0.6271811724 0.5941489935 + 0.6717275977 0.6281095743 0.5951371193 + 0.6726074219 0.6290342212 0.5961226821 + 0.6734871864 0.6299588084 0.5971081853 + 0.6743670106 0.6308833957 0.5980938077 + 0.6752467752 0.6318072081 0.5990791917 + 0.6761245131 0.6327196956 0.6000642180 + 0.6770021915 0.6336323023 0.6010491848 + 0.6778799295 0.6345447898 0.6020342112 + 0.6787576079 0.6354573965 0.6030192971 + 0.6796311140 0.6363689899 0.6039971709 + 0.6805009842 0.6372799277 0.6049730778 + 0.6813709140 0.6381908059 0.6059491038 + 0.6822407246 0.6391018033 0.6069250703 + 0.6831105947 0.6400123835 0.6078994870 + 0.6839790940 0.6409156919 0.6088691950 + 0.6848475933 0.6418190002 0.6098389030 + 0.6857160926 0.6427223086 0.6108086705 + 0.6865844727 0.6436256766 0.6117783785 + 0.6874501705 0.6445271969 0.6127467155 + 0.6883115768 0.6454266906 0.6137142777 + 0.6891731024 0.6463261843 0.6146818995 + 0.6900346279 0.6472256780 0.6156495214 + 0.6908959746 0.6481251717 0.6166170239 + 0.6917508841 0.6490163803 0.6175795197 + 0.6926038861 0.6499059200 0.6185420156 + 0.6934568882 0.6507952809 0.6195045114 + 0.6943098903 0.6516848207 0.6204670072 + 0.6951622963 0.6525734067 0.6214286089 + 0.6960077286 0.6534568071 0.6223886013 + 0.6968531013 0.6543400884 0.6233485937 + 0.6976984739 0.6552234888 0.6243085861 + 0.6985439062 0.6561068296 0.6252685785 + 0.6993870735 0.6569851041 0.6262217164 + 0.7002261877 0.6578559279 0.6271703839 + 0.7010654211 0.6587265730 0.6281189919 + 0.7019044757 0.6595973969 0.6290677190 + 0.7027435899 0.6604681015 0.6300163269 + 0.7035796046 0.6613349915 0.6309583187 + 0.7044131756 0.6621994972 0.6318988800 + 0.7052468061 0.6630640030 0.6328393817 + 0.7060803771 0.6639283895 0.6337800026 + 0.7069140077 0.6647928953 0.6347205043 + 0.7077404857 0.6656516790 0.6356571913 + 0.7085642815 0.6665087938 0.6365938187 + 0.7093880773 0.6673660278 0.6375303864 + 0.7102118731 0.6682230830 0.6384670138 + 0.7110357881 0.6690803170 0.6394029856 + 0.7118616104 0.6699306965 0.6403322220 + 0.7126877904 0.6707803011 0.6412613988 + 0.7135139704 0.6716299057 0.6421905756 + 0.7143402100 0.6724795103 0.6431198120 + 0.7151665092 0.6733291149 0.6440477967 + 0.7159851789 0.6741706729 0.6449677944 + 0.7168028951 0.6750116944 0.6458877921 + 0.7176206708 0.6758527756 0.6468077898 + 0.7184385061 0.6766939163 0.6477277875 + 0.7192562819 0.6775348783 0.6486470103 + 0.7200725079 0.6783677936 0.6495617032 + 0.7208884954 0.6792001724 0.6504762769 + 0.7217044830 0.6800324917 0.6513909101 + 0.7225204110 0.6808648705 0.6523056030 + 0.7233363986 0.6816973090 0.6532199979 + 0.7241454124 0.6825289130 0.6541327238 + 0.7249531150 0.6833605170 0.6550455093 + 0.7257608771 0.6841921210 0.6559581757 + 0.7265685797 0.6850237250 0.6568709016 + 0.7273762822 0.6858553290 0.6577836275 + 0.7281739712 0.6866853833 0.6586869955 + 0.7289680243 0.6875150800 0.6595901251 + 0.7297620773 0.6883447766 0.6604931951 + 0.7305560708 0.6891744733 0.6613963842 + 0.7313501239 0.6900042295 0.6622995138 + 0.7321395278 0.6908270121 0.6631954908 + 0.7329254746 0.6916458011 0.6640897989 + 0.7337114811 0.6924644709 0.6649841070 + 0.7344974875 0.6932832003 0.6658784747 + 0.7352834940 0.6941019893 0.6667727828 + 0.7360627055 0.6949160099 0.6676589251 + 0.7368296981 0.6957229972 0.6685394049 + 0.7375966907 0.6965299845 0.6694198847 + 0.7383636832 0.6973370910 0.6703003049 + 0.7391306758 0.6981440783 0.6711807847 + 0.7398970723 0.6989498138 0.6720594168 + 0.7406572104 0.6997461915 0.6729338169 + 0.7414172292 0.7005426884 0.6738082767 + 0.7421773076 0.7013391256 0.6746826768 + 0.7429373860 0.7021355033 0.6755570769 + 0.7436974049 0.7029320002 0.6764315963 + 0.7444459200 0.7037230134 0.6772987247 + 0.7451906204 0.7045127153 0.6781656742 + 0.7459353209 0.7053024173 0.6790326238 + 0.7466799021 0.7060920000 0.6798995733 + 0.7474246025 0.7068817019 0.6807665825 + 0.7481679916 0.7076675892 0.6816290021 + 0.7489092946 0.7084479928 0.6824882030 + 0.7496504784 0.7092282772 0.6833475232 + 0.7503917217 0.7100086808 0.6842067242 + 0.7511329055 0.7107890844 0.6850659847 + 0.7518740892 0.7115694284 0.6859251857 + 0.7526044250 0.7123498917 0.6867846847 + 0.7533336878 0.7131304145 0.6876441836 + 0.7540628910 0.7139108777 0.6885036230 + 0.7547922134 0.7146914005 0.6893631220 + 0.7555214167 0.7154719234 0.6902225018 + 0.7562506199 0.7162482738 0.6910750866 + 0.7569795251 0.7170194983 0.6919236183 + 0.7577084899 0.7177907825 0.6927719712 + 0.7584375143 0.7185620070 0.6936205029 + 0.7591664791 0.7193332911 0.6944689751 + 0.7598955035 0.7201045156 0.6953169107 + 0.7606170177 0.7208759189 0.6961556077 + 0.7613371015 0.7216472030 0.6969943047 + 0.7620571852 0.7224184871 0.6978331208 + 0.7627773285 0.7231898904 0.6986718178 + 0.7634974122 0.7239611745 0.6995105147 + 0.7642151713 0.7247301936 0.7003443837 + 0.7649244070 0.7254924178 0.7011716962 + 0.7656335831 0.7262545228 0.7019990087 + 0.7663428783 0.7270166874 0.7028263211 + 0.7670521140 0.7277787924 0.7036535740 + 0.7677612901 0.7285410166 0.7044810057 + 0.7684661150 0.7293031812 0.7053043842 + 0.7691670060 0.7300654054 0.7061262727 + 0.7698678970 0.7308276296 0.7069482803 + 0.7705687284 0.7315897942 0.7077702880 + 0.7712696195 0.7323520184 0.7085922956 + 0.7719705105 0.7331141829 0.7094143033 + 0.7726665735 0.7338690162 0.7102290988 + 0.7733613253 0.7346221209 0.7110437751 + 0.7740560174 0.7353752255 0.7118585110 + 0.7747508287 0.7361282706 0.7126731873 + 0.7754455209 0.7368813753 0.7134879231 + 0.7761402130 0.7376344800 0.7143009901 + 0.7768254876 0.7383875847 0.7151066065 + 0.7775105238 0.7391408086 0.7159122229 + 0.7781955004 0.7398939133 0.7167177796 + 0.7788804173 0.7406470776 0.7175235152 + 0.7795653939 0.7414001822 0.7183290720 + 0.7802500725 0.7421522141 0.7191318870 + 0.7809323072 0.7428963184 0.7199280858 + 0.7816144824 0.7436404824 0.7207242846 + 0.7822967172 0.7443845868 0.7215204239 + 0.7829788923 0.7451288104 0.7223166227 + 0.7836611271 0.7458729148 0.7231128216 + 0.7843412757 0.7466160059 0.7239063978 + 0.7850098014 0.7473546267 0.7246955037 + 0.7856782079 0.7480933070 0.7254844904 + 0.7863466740 0.7488319278 0.7262734771 + 0.7870151997 0.7495706081 0.7270625234 + 0.7876836061 0.7503092289 0.7278516293 + 0.7883511186 0.7510460019 0.7286369205 + 0.7890127897 0.7517744899 0.7294149995 + 0.7896745801 0.7525030971 0.7301930785 + 0.7903363109 0.7532315850 0.7309712172 + 0.7909979820 0.7539601922 0.7317492962 + 0.7916597128 0.7546886802 0.7325273752 + 0.7923207879 0.7554165721 0.7333045006 + 0.7929738760 0.7561392784 0.7340788841 + 0.7936270237 0.7568619847 0.7348533273 + 0.7942801118 0.7575846910 0.7356275916 + 0.7949333191 0.7583073974 0.7364019752 + 0.7955864072 0.7590301037 0.7371764183 + 0.7962394953 0.7597528100 0.7379497886 + 0.7968860865 0.7604665160 0.7387167215 + 0.7975323200 0.7611799240 0.7394834757 + 0.7981784940 0.7618933916 0.7402504086 + 0.7988247275 0.7626067996 0.7410172820 + 0.7994709015 0.7633203268 0.7417842150 + 0.8001170754 0.7640337944 0.7425510883 + 0.8007584810 0.7647390962 0.7433149815 + 0.8013982177 0.7654420137 0.7440785766 + 0.8020377755 0.7661449909 0.7448422909 + 0.8026775122 0.7668480277 0.7456058860 + 0.8033171892 0.7675510049 0.7463694811 + 0.8039568067 0.7682539821 0.7471331954 + 0.8045893908 0.7689520717 0.7478901148 + 0.8052138090 0.7696456909 0.7486435175 + 0.8058382869 0.7703393102 0.7493969202 + 0.8064628243 0.7710329294 0.7501503825 + 0.8070873022 0.7717264891 0.7509037852 + 0.8077117801 0.7724201083 0.7516571879 + 0.8083351851 0.7731121182 0.7524083853 + 0.8089513183 0.7737967968 0.7531548738 + 0.8095672727 0.7744815946 0.7539014220 + 0.8101834059 0.7751662731 0.7546479106 + 0.8107994795 0.7758510709 0.7553943992 + 0.8114156127 0.7765358090 0.7561408877 + 0.8120316863 0.7772204876 0.7568873763 + 0.8126400709 0.7778990865 0.7576224804 + 0.8132457137 0.7785758972 0.7583565116 + 0.8138511777 0.7792527080 0.7590904236 + 0.8144568205 0.7799293995 0.7598243952 + 0.8150624037 0.7806062102 0.7605584264 + 0.8156679869 0.7812829018 0.7612923980 + 0.8162711859 0.7819581032 0.7620232105 + 0.8168674707 0.7826291919 0.7627500296 + 0.8174636960 0.7833003998 0.7634767890 + 0.8180599809 0.7839716077 0.7642034888 + 0.8186563253 0.7846428156 0.7649303079 + 0.8192526102 0.7853139043 0.7656571269 + 0.8198487759 0.7859851122 0.7663838863 + 0.8204402924 0.7866560817 0.7671036124 + 0.8210297227 0.7873269916 0.7678225040 + 0.8216190934 0.7879980206 0.7685413957 + 0.8222085834 0.7886688709 0.7692602873 + 0.8227980137 0.7893397808 0.7699791789 + 0.8233875036 0.7900106907 0.7706980705 + 0.8239762187 0.7906810045 0.7714146972 + 0.8245580792 0.7913463712 0.7721254230 + 0.8251398802 0.7920119166 0.7728360295 + 0.8257218003 0.7926774025 0.7735465765 + 0.8263037205 0.7933428288 0.7742571831 + 0.8268855214 0.7940083146 0.7749677896 + 0.8274673820 0.7946738005 0.7756783962 + 0.8280459046 0.7953346968 0.7763838172 + 0.8286194801 0.7959898114 0.7770854831 + 0.8291931152 0.7966449857 0.7777872086 + 0.8297666907 0.7973002195 0.7784888744 + 0.8303403258 0.7979552746 0.7791904807 + 0.8309139013 0.7986105084 0.7798922062 + 0.8314874768 0.7992656827 0.7805938721 + 0.8320547938 0.7999172211 0.7812880278 + 0.8326187134 0.8005670905 0.7819803953 + 0.8331826925 0.8012170196 0.7826728821 + 0.8337466121 0.8018668294 0.7833653092 + 0.8343105912 0.8025166988 0.7840577960 + 0.8348745704 0.8031666279 0.7847502232 + 0.8354384899 0.8038163781 0.7854425907 + 0.8359956145 0.8044540882 0.7861267924 + 0.8365511894 0.8050895929 0.7868108153 + 0.8371068239 0.8057252169 0.7874947786 + 0.8376625180 0.8063607216 0.7881788015 + 0.8382180929 0.8069962263 0.7888628244 + 0.8387737274 0.8076316714 0.7895467877 + 0.8393293023 0.8082672954 0.7902303934 + 0.8398807049 0.8088986278 0.7909095287 + 0.8404316902 0.8095297217 0.7915886045 + 0.8409826756 0.8101608157 0.7922676206 + 0.8415337205 0.8107919097 0.7929466963 + 0.8420847058 0.8114230037 0.7936257720 + 0.8426356912 0.8120540977 0.7943047881 + 0.8431866765 0.8126851916 0.7949832082 + 0.8437362909 0.8133051991 0.7956548929 + 0.8442857862 0.8139246702 0.7963265777 + 0.8448352814 0.8145442009 0.7969983816 + 0.8453847766 0.8151637912 0.7976701260 + 0.8459343910 0.8157833219 0.7983418107 + 0.8464838862 0.8164027929 0.7990134954 + 0.8470333815 0.8170223236 0.7996851802 + 0.8475741148 0.8176347017 0.8003575802 + 0.8481134772 0.8182463050 0.8010299802 + 0.8486528993 0.8188579082 0.8017024994 + 0.8491923213 0.8194695115 0.8023748994 + 0.8497316837 0.8200811148 0.8030472994 + 0.8502712250 0.8206927180 0.8037198186 + 0.8508105874 0.8213043213 0.8043922186 + 0.8513522744 0.8219084144 0.8050565720 + 0.8518949151 0.8225101233 0.8057200909 + 0.8524376154 0.8231118917 0.8063836098 + 0.8529801965 0.8237137198 0.8070471287 + 0.8535227776 0.8243154287 0.8077105284 + 0.8540654182 0.8249171972 0.8083739877 + 0.8546079993 0.8255189061 0.8090375066 + 0.8551477790 0.8261185288 0.8096969724 + 0.8556851149 0.8267164230 0.8103548288 + 0.8562222719 0.8273143172 0.8110125065 + 0.8567596078 0.8279122114 0.8116701841 + 0.8572968245 0.8285101056 0.8123279214 + 0.8578341007 0.8291079998 0.8129855990 + 0.8583713174 0.8297058940 0.8136432767 + 0.8589066863 0.8303020000 0.8142979741 + 0.8594359756 0.8308932185 0.8149477839 + 0.8599653244 0.8314844966 0.8155977130 + 0.8604946136 0.8320757151 0.8162475228 + 0.8610237837 0.8326669931 0.8168973923 + 0.8615530729 0.8332582116 0.8175472021 + 0.8620824218 0.8338493705 0.8181970716 + 0.8626117110 0.8344407082 0.8188468814 + 0.8631411791 0.8350260854 0.8194969296 + 0.8636707067 0.8356109262 0.8201467991 + 0.8642001748 0.8361955881 0.8207967877 + 0.8647297025 0.8367804289 0.8214467764 + 0.8652591705 0.8373650908 0.8220967054 + 0.8657886982 0.8379498124 0.8227466941 + 0.8663182259 0.8385345936 0.8233966231 + 0.8668442965 0.8391172886 0.8240422010 + 0.8673655987 0.8396975994 0.8246843815 + 0.8678870201 0.8402777910 0.8253266215 + 0.8684083223 0.8408579826 0.8259688020 + 0.8689296842 0.8414382935 0.8266109824 + 0.8694509864 0.8420184851 0.8272532225 + 0.8699724078 0.8425986767 0.8278954029 + 0.8704937100 0.8431789279 0.8285375834 + 0.8710048795 0.8437566757 0.8291798830 + 0.8715147972 0.8443341851 0.8298223019 + 0.8720247149 0.8449115753 0.8304646015 + 0.8725346923 0.8454890847 0.8311069012 + 0.8730446100 0.8460665941 0.8317492008 + 0.8735545278 0.8466441035 0.8323916197 + 0.8740643859 0.8472216129 0.8330339193 + 0.8745729923 0.8477984071 0.8336730003 + 0.8750782013 0.8483735919 0.8343076706 + 0.8755834103 0.8489488959 0.8349422812 + 0.8760886192 0.8495240808 0.8355768919 + 0.8765938282 0.8500993252 0.8362116218 + 0.8770989776 0.8506745100 0.8368461728 + 0.8776041865 0.8512498140 0.8374807835 + 0.8781093955 0.8518249989 0.8381155133 + 0.8786090016 0.8523975015 0.8387501836 + 0.8791047931 0.8529682755 0.8393849134 + 0.8796005249 0.8535389900 0.8400195837 + 0.8800961971 0.8541098237 0.8406543732 + 0.8805919886 0.8546805978 0.8412891030 + 0.8810877204 0.8552513719 0.8419238925 + 0.8815835118 0.8558220863 0.8425586224 + 0.8820791841 0.8563929200 0.8431932926 + 0.8825731277 0.8569598198 0.8438208103 + 0.8830664754 0.8575260043 0.8444479108 + 0.8835598826 0.8580921292 0.8450748920 + 0.8840534091 0.8586583138 0.8457019925 + 0.8845468163 0.8592243791 0.8463289738 + 0.8850402236 0.8597906232 0.8469560146 + 0.8855336905 0.8603568077 0.8475831151 + 0.8860270977 0.8609228730 0.8482097983 + 0.8865162134 0.8614861965 0.8488330245 + 0.8870049715 0.8620492816 0.8494560719 + 0.8874937892 0.8626124859 0.8500791788 + 0.8879824877 0.8631756902 0.8507024050 + 0.8884713054 0.8637387753 0.8513255119 + 0.8889601231 0.8643019795 0.8519486189 + 0.8894488811 0.8648651242 0.8525717854 + 0.8899376988 0.8654280901 0.8531945944 + 0.8904203176 0.8659834862 0.8538153768 + 0.8909028172 0.8665388227 0.8544362187 + 0.8913853765 0.8670940995 0.8550570011 + 0.8918679953 0.8676494956 0.8556777835 + 0.8923504949 0.8682047725 0.8562985063 + 0.8928331137 0.8687602282 0.8569192886 + 0.8933156133 0.8693155050 0.8575400710 + 0.8937981725 0.8698707819 0.8581606150 + 0.8942810297 0.8704199791 0.8587781191 + 0.8947638273 0.8709689975 0.8593956232 + 0.8952466846 0.8715180755 0.8600131869 + 0.8957294822 0.8720670938 0.8606306911 + 0.8962123990 0.8726161718 0.8612481952 + 0.8966951966 0.8731653094 0.8618656993 + 0.8971779943 0.8737143278 0.8624832034 + 0.8976609111 0.8742634058 0.8631008267 + 0.8981388211 0.8748087883 0.8637112975 + 0.8986158967 0.8753535748 0.8643215895 + 0.8990929723 0.8758984208 0.8649318814 + 0.8995701075 0.8764432073 0.8655421138 + 0.9000471234 0.8769881129 0.8661524057 + 0.9005241990 0.8775328994 0.8667626977 + 0.9010012746 0.8780776858 0.8673729897 + 0.9014782906 0.8786225915 0.8679832816 + 0.9019498825 0.8791623712 0.8685910106 + 0.9024183154 0.8796998262 0.8691979051 + 0.9028868079 0.8802371025 0.8698047996 + 0.9033551812 0.8807744980 0.8704116940 + 0.9038236737 0.8813118935 0.8710185289 + 0.9042921066 0.8818492293 0.8716254234 + 0.9047604799 0.8823866248 0.8722323179 + 0.9052289724 0.8829239011 0.8728392124 + 0.9056965113 0.8834607005 0.8734431267 + 0.9061623216 0.8839964867 0.8740432858 + 0.9066281915 0.8845322132 0.8746436238 + 0.9070940018 0.8850679994 0.8752437830 + 0.9075598121 0.8856037855 0.8758441210 + 0.9080256224 0.8861395121 0.8764442801 + 0.9084914923 0.8866752982 0.8770446181 + 0.9089573026 0.8872110248 0.8776447773 + 0.9094231129 0.8877468109 0.8782445788 + 0.9098821282 0.8882740736 0.8788375258 + 0.9103407860 0.8888012767 0.8794304132 + 0.9107996225 0.8893284202 0.8800233006 + 0.9112582803 0.8898556232 0.8806161284 + 0.9117169976 0.8903827071 0.8812090158 + 0.9121757150 0.8909099102 0.8818019032 + 0.9126343727 0.8914369941 0.8823947906 + 0.9130930901 0.8919641972 0.8829876184 + 0.9135512710 0.8924918771 0.8835765123 + 0.9140090942 0.8930202723 0.8841624260 + 0.9144667983 0.8935487270 0.8847482800 + 0.9149245024 0.8940771222 0.8853343129 + 0.9153823256 0.8946055174 0.8859202266 + 0.9158400297 0.8951339126 0.8865060806 + 0.9162976742 0.8956621885 0.8870919943 + 0.9167554975 0.8961905837 0.8876780272 + 0.9172132015 0.8967189789 0.8882638216 + 0.9176644087 0.8972421288 0.8888434768 + 0.9181149006 0.8977648020 0.8894230723 + 0.9185655117 0.8982874751 0.8900027871 + 0.9190160036 0.8988103271 0.8905823827 + 0.9194664955 0.8993330002 0.8911620975 + 0.9199171066 0.8998556733 0.8917416930 + 0.9203675985 0.9003784060 0.8923214078 + 0.9208182096 0.9009010792 0.8929010034 + 0.9212675095 0.9014238715 0.8934786916 + 0.9217131734 0.9019467831 0.8940525055 + 0.9221590161 0.9024696946 0.8946262002 + 0.9226046801 0.9029926062 0.8952000141 + 0.9230504036 0.9035155177 0.8957738280 + 0.9234961271 0.9040384293 0.8963475823 + 0.9239419103 0.9045612812 0.8969212770 + 0.9243875742 0.9050841928 0.8974950910 + 0.9248332977 0.9056071043 0.8980689049 + 0.9252752066 0.9061285257 0.8986396790 + 0.9257131219 0.9066482782 0.8992083073 + 0.9261509776 0.9071682096 0.8997768164 + 0.9265888929 0.9076880813 0.9003453851 + 0.9270266891 0.9082080126 0.9009140134 + 0.9274646044 0.9087278247 0.9014825821 + 0.9279025197 0.9092476964 0.9020512104 + 0.9283403754 0.9097676277 0.9026197791 + 0.9287782907 0.9102874994 0.9031882882 + 0.9292140007 0.9107999802 0.9037535191 + 0.9296483994 0.9113087058 0.9043173194 + 0.9300829172 0.9118173122 0.9048811793 + 0.9305173159 0.9123259783 0.9054449797 + 0.9309517741 0.9128345847 0.9060088992 + 0.9313861728 0.9133433104 0.9065728188 + 0.9318206906 0.9138519168 0.9071366191 + 0.9322550893 0.9143605828 0.9077004790 + 0.9326896071 0.9148693085 0.9082642794 + 0.9331244230 0.9153769016 0.9088249803 + 0.9335594177 0.9158840775 0.9093847871 + 0.9339944124 0.9163913131 0.9099445939 + 0.9344294071 0.9168984294 0.9105042815 + 0.9348644018 0.9174056053 0.9110640883 + 0.9352993965 0.9179127812 0.9116238952 + 0.9357343912 0.9184200168 0.9121837020 + 0.9361693859 0.9189271927 0.9127433896 + 0.9366044998 0.9194344282 0.9133031964 + 0.9370371103 0.9199361205 0.9138603806 + 0.9374685287 0.9204351902 0.9144166708 + 0.9378998876 0.9209342003 0.9149729013 + 0.9383313060 0.9214332104 0.9155290723 + 0.9387627244 0.9219322205 0.9160854220 + 0.9391940832 0.9224311709 0.9166415930 + 0.9396255016 0.9229301810 0.9171978831 + 0.9400569201 0.9234291911 0.9177541137 + 0.9404882789 0.9239282012 0.9183102846 + 0.9409155250 0.9244257212 0.9188649058 + 0.9413387179 0.9249218106 0.9194182158 + 0.9417619705 0.9254179001 0.9199715257 + 0.9421852231 0.9259139895 0.9205247760 + 0.9426084161 0.9264100790 0.9210780859 + 0.9430316091 0.9269062281 0.9216313958 + 0.9434548020 0.9274023175 0.9221848249 + 0.9438781142 0.9278984070 0.9227380753 + 0.9443013072 0.9283944964 0.9232913852 + 0.9447239041 0.9288893938 0.9238408208 + 0.9451450109 0.9293813109 0.9243822098 + 0.9455661178 0.9298732281 0.9249237180 + 0.9459871054 0.9303650856 0.9254652262 + 0.9464082122 0.9308570027 0.9260066748 + 0.9468291998 0.9313489199 0.9265481830 + 0.9472503066 0.9318407774 0.9270896912 + 0.9476714134 0.9323326945 0.9276311994 + 0.9480924010 0.9328246117 0.9281727076 + 0.9485135078 0.9333165288 0.9287142158 + 0.9489266276 0.9338006973 0.9292520881 + 0.9493390918 0.9342843890 0.9297899008 + 0.9497516155 0.9347680807 0.9303277731 + 0.9501640797 0.9352517724 0.9308655858 + 0.9505766034 0.9357355833 0.9314035177 + 0.9509891272 0.9362192750 0.9319412708 + 0.9514014721 0.9367030263 0.9324790835 + 0.9518139958 0.9371867180 0.9330170155 + 0.9522265196 0.9376704097 0.9335548282 + 0.9526365995 0.9381523132 0.9340875149 + 0.9530441761 0.9386324883 0.9346156716 + 0.9534518123 0.9391127229 0.9351440072 + 0.9538593888 0.9395927787 0.9356722236 + 0.9542670250 0.9400730133 0.9362003803 + 0.9546746016 0.9405531287 0.9367287159 + 0.9550821781 0.9410333037 0.9372568727 + 0.9554898143 0.9415134192 0.9377852082 + 0.9558972716 0.9419935942 0.9383134246 + 0.9563049078 0.9424737096 0.9388415813 + 0.9567065835 0.9429457784 0.9393643737 + 0.9571079016 0.9434173703 0.9398869872 + 0.9575092196 0.9438890219 0.9404097199 + 0.9579104185 0.9443606138 0.9409322739 + 0.9583116770 0.9448322058 0.9414550066 + 0.9587129951 0.9453037977 0.9419776797 + 0.9591141939 0.9457753897 0.9425002933 + 0.9595155120 0.9462471008 0.9430230260 + 0.9599167705 0.9467186928 0.9435455799 + 0.9603134990 0.9471881986 0.9440639019 + 0.9606987238 0.9476525784 0.9445734024 + 0.9610838294 0.9481170177 0.9450829029 + 0.9614689946 0.9485813975 0.9455924034 + 0.9618542194 0.9490458965 0.9461019039 + 0.9622393250 0.9495102763 0.9466114044 + 0.9626244903 0.9499747157 0.9471209049 + 0.9630097151 0.9504390955 0.9476304054 + 0.9633948803 0.9509035945 0.9481399059 + 0.9637799859 0.9513679743 0.9486494064 + 0.9641588926 0.9518290758 0.9491565824 + 0.9645323157 0.9522874951 0.9496620297 + 0.9649056196 0.9527457952 0.9501674175 + 0.9652789831 0.9532042146 0.9506728053 + 0.9656522870 0.9536625147 0.9511781931 + 0.9660257101 0.9541208744 0.9516835809 + 0.9663990140 0.9545791745 0.9521890283 + 0.9667723775 0.9550374746 0.9526944160 + 0.9671456814 0.9554958940 0.9531999230 + 0.9675191045 0.9559541941 0.9537053108 + 0.9678881764 0.9564117789 0.9542062283 + 0.9682552218 0.9568691254 0.9547054172 + 0.9686222076 0.9573262930 0.9552046061 + 0.9689893126 0.9577835798 0.9557037950 + 0.9693562984 0.9582408071 0.9562029839 + 0.9697232842 0.9586980939 0.9567021728 + 0.9700903296 0.9591553211 0.9572014213 + 0.9704573750 0.9596126080 0.9577006102 + 0.9708244205 0.9600697756 0.9581997991 + 0.9711914062 0.9605271220 0.9586989880 + 0.9715511799 0.9609804749 0.9591947794 + 0.9719079137 0.9614323974 0.9596894979 + 0.9722645283 0.9618843198 0.9601842165 + 0.9726212025 0.9623361230 0.9606788754 + 0.9729778767 0.9627879858 0.9611735940 + 0.9733346105 0.9632399082 0.9616683125 + 0.9736912847 0.9636917710 0.9621629715 + 0.9740480185 0.9641436934 0.9626576900 + 0.9744045734 0.9645954967 0.9631524086 + 0.9747613072 0.9650474191 0.9636471272 + 0.9751121998 0.9654958248 0.9641352892 + 0.9754595757 0.9659423232 0.9646201730 + 0.9758070111 0.9663887024 0.9651051164 + 0.9761543870 0.9668352008 0.9655900002 + 0.9765018225 0.9672815800 0.9660750031 + 0.9768491983 0.9677280784 0.9665598869 + 0.9771965146 0.9681745172 0.9670447707 + 0.9775438905 0.9686208963 0.9675297141 + 0.9778913260 0.9690673947 0.9680147171 + 0.9782387018 0.9695137739 0.9684996009 + 0.9785814285 0.9699571133 0.9689792991 + 0.9789180160 0.9703966975 0.9694532752 + 0.9792547226 0.9708362222 0.9699273109 + 0.9795914292 0.9712756872 0.9704012871 + 0.9799280763 0.9717152119 0.9708753228 + 0.9802647829 0.9721547961 0.9713492990 + 0.9806014895 0.9725943208 0.9718232751 + 0.9809380770 0.9730337858 0.9722973108 + 0.9812747836 0.9734733105 0.9727712870 + 0.9816114902 0.9739128947 0.9732453823 + 0.9819465280 0.9743511081 0.9737172723 + 0.9822719097 0.9747827053 0.9741798043 + 0.9825971723 0.9752143025 0.9746423960 + 0.9829226136 0.9756458998 0.9751049280 + 0.9832479954 0.9760774970 0.9755674005 + 0.9835733175 0.9765089750 0.9760299921 + 0.9838986993 0.9769405723 0.9764925241 + 0.9842240810 0.9773722291 0.9769549966 + 0.9845495224 0.9778038263 0.9774175286 + 0.9848747849 0.9782354236 0.9778801203 + 0.9852002263 0.9786669016 0.9783425927 + 0.9855154157 0.9790912867 0.9787945747 + 0.9858270288 0.9795132279 0.9792435169 + 0.9861387014 0.9799351096 0.9796923995 + 0.9864503741 0.9803571105 0.9801412225 + 0.9867621064 0.9807789922 0.9805901051 + 0.9870737791 0.9812008739 0.9810389876 + 0.9873855114 0.9816228747 0.9814878702 + 0.9876971245 0.9820448160 0.9819366932 + 0.9880087972 0.9824666977 0.9823855758 + 0.9883205295 0.9828886986 0.9828345180 + 0.9886283278 0.9833080173 0.9832788706 + 0.9889227748 0.9837185740 0.9837099910 + 0.9892172813 0.9841291904 0.9841409922 + 0.9895117879 0.9845399261 0.9845719934 + 0.9898062944 0.9849504828 0.9850029945 + 0.9901008010 0.9853610992 0.9854339957 + 0.9903953075 0.9857717156 0.9858649969 + 0.9906898141 0.9861822724 0.9862959981 + 0.9909843206 0.9865928888 0.9867269993 + 0.9912788272 0.9870036244 0.9871580005 + 0.9915732741 0.9874141812 0.9875890017 + 0.9918602109 0.9878157973 0.9880052805 + 0.9921419024 0.9882115126 0.9884120822 + 0.9924237132 0.9886071086 0.9888188839 + 0.9927054048 0.9890027046 0.9892256856 + 0.9929870963 0.9893983006 0.9896324873 + 0.9932689071 0.9897938967 0.9900392890 + 0.9935505986 0.9901894927 0.9904460907 + 0.9938322902 0.9905850887 0.9908528924 + 0.9941141009 0.9909806848 0.9912596941 + 0.9943957925 0.9913762808 0.9916664958 + 0.9946774840 0.9917719960 0.9920732975 + 0.9949371219 0.9921513796 0.9924513102 + 0.9951925874 0.9925280213 0.9928246140 + 0.9954481125 0.9929047227 0.9931977987 + 0.9957035780 0.9932813048 0.9935709834 + 0.9959591031 0.9936578870 0.9939442277 + 0.9962146282 0.9940345287 0.9943174124 + 0.9964702129 0.9944111109 0.9946905971 + 0.9967256784 0.9947876930 0.9950639009 + 0.9969812036 0.9951642752 0.9954370856 + 0.9972367287 0.9955409169 0.9958102703 + 0.9974921942 0.9959174991 0.9961835146 + 0.9977207184 0.9962887168 0.9965307713 + 0.9979485869 0.9966598749 0.9968776703 + 0.9981765151 0.9970309734 0.9972246289 + 0.9984045029 0.9974020720 0.9975715280 + 0.9986323714 0.9977731705 0.9979184866 + 0.9988602996 0.9981443882 0.9982653856 + 0.9990882874 0.9985154867 0.9986122847 + 0.9993162155 0.9988865852 0.9989591837 + 0.9995440841 0.9992576838 0.9993062019 + 0.9997720718 0.9996289015 0.9996531010 + 1.0000000000 1.0000000000 1.0000000000 +} diff --git a/rpplugins/color_correction/resources/film_luts_raw/kodak_kaf-2001.spi1d b/rpplugins/color_correction/resources/film_luts_raw/kodak_kaf-2001.spi1d new file mode 100644 index 0000000..5eb8e03 --- /dev/null +++ b/rpplugins/color_correction/resources/film_luts_raw/kodak_kaf-2001.spi1d @@ -0,0 +1,1030 @@ +Version 1 +From 0.0 1.0 +Length 1024 +Components 1 +{ + 0.0000000000 + 0.0007931371 + 0.0016355170 + 0.0025503801 + 0.0035146240 + 0.0045273229 + 0.0055715218 + 0.0066442778 + 0.0077339248 + 0.0088365739 + 0.0099448124 + 0.0110545401 + 0.0121633904 + 0.0132660801 + 0.0143607901 + 0.0154447202 + 0.0165135600 + 0.0175563600 + 0.0185688492 + 0.0195335001 + 0.0204569604 + 0.0213513691 + 0.0222338792 + 0.0231126193 + 0.0239920896 + 0.0248705894 + 0.0257443301 + 0.0266080908 + 0.0274574608 + 0.0282867905 + 0.0290999208 + 0.0299087707 + 0.0307223909 + 0.0315502807 + 0.0323930904 + 0.0332537815 + 0.0341344401 + 0.0350381099 + 0.0359668396 + 0.0369246788 + 0.0379154012 + 0.0389400795 + 0.0400040112 + 0.0411124304 + 0.0422693789 + 0.0434693992 + 0.0447056293 + 0.0459665395 + 0.0472429208 + 0.0485244282 + 0.0498028807 + 0.0510769486 + 0.0523513183 + 0.0536344387 + 0.0549293309 + 0.0562351793 + 0.0575465411 + 0.0588550903 + 0.0601528510 + 0.0614360608 + 0.0626917332 + 0.0639152676 + 0.0650884286 + 0.0662079304 + 0.0672680065 + 0.0682774335 + 0.0692317113 + 0.0701425374 + 0.0710024387 + 0.0718212798 + 0.0725976974 + 0.0733437091 + 0.0740561932 + 0.0747447014 + 0.0754096508 + 0.0760633573 + 0.0767156705 + 0.0773765966 + 0.0780583993 + 0.0787628815 + 0.0794979781 + 0.0802626163 + 0.0810654610 + 0.0819049180 + 0.0827899724 + 0.0837192386 + 0.0847032070 + 0.0857442319 + 0.0868611634 + 0.0880450904 + 0.0892995670 + 0.0906111673 + 0.0919737294 + 0.0933712497 + 0.0947946832 + 0.0962312222 + 0.0976707786 + 0.0991016179 + 0.1005088016 + 0.1018795967 + 0.1031991988 + 0.1044576988 + 0.1056412980 + 0.1067342982 + 0.1077463999 + 0.1087004021 + 0.1096137986 + 0.1104959026 + 0.1113545969 + 0.1121921018 + 0.1130077988 + 0.1137992963 + 0.1145685986 + 0.1153163984 + 0.1160470024 + 0.1167626977 + 0.1174698994 + 0.1181747988 + 0.1188858002 + 0.1196158975 + 0.1203754023 + 0.1211868003 + 0.1220536008 + 0.1229866967 + 0.1239702031 + 0.1250043064 + 0.1260707974 + 0.1271626055 + 0.1282667071 + 0.1293743998 + 0.1304752976 + 0.1315566003 + 0.1326127052 + 0.1336387992 + 0.1346348971 + 0.1355908066 + 0.1365199983 + 0.1374216974 + 0.1383025050 + 0.1391607970 + 0.1400025934 + 0.1408285946 + 0.1416438073 + 0.1424539983 + 0.1432684958 + 0.1440957040 + 0.1449375004 + 0.1457988024 + 0.1466775984 + 0.1475750059 + 0.1484851986 + 0.1494164020 + 0.1503666043 + 0.1513417959 + 0.1523495018 + 0.1534101069 + 0.1545234025 + 0.1556780040 + 0.1568565965 + 0.1580476016 + 0.1592365056 + 0.1604065001 + 0.1615456045 + 0.1626373976 + 0.1636672020 + 0.1646257043 + 0.1655281931 + 0.1663973033 + 0.1672482938 + 0.1680918038 + 0.1689291000 + 0.1697597057 + 0.1705808938 + 0.1713818014 + 0.1721594036 + 0.1729159951 + 0.1736537963 + 0.1743783057 + 0.1750947982 + 0.1758113056 + 0.1765365005 + 0.1772823930 + 0.1780716032 + 0.1789128035 + 0.1798152030 + 0.1807664931 + 0.1817689985 + 0.1828158051 + 0.1839095950 + 0.1850427985 + 0.1862190962 + 0.1874303073 + 0.1886713058 + 0.1899241060 + 0.1911779046 + 0.1924244016 + 0.1936572939 + 0.1948782951 + 0.1960881054 + 0.1972880065 + 0.1984702945 + 0.1996252984 + 0.2007281035 + 0.2017628998 + 0.2027094960 + 0.2036039978 + 0.2044609040 + 0.2053059042 + 0.2061520070 + 0.2070064992 + 0.2078751028 + 0.2087562978 + 0.2096406966 + 0.2105236948 + 0.2113939971 + 0.2122493982 + 0.2130886018 + 0.2139182985 + 0.2147479951 + 0.2155908048 + 0.2164690942 + 0.2174035013 + 0.2184235007 + 0.2195228934 + 0.2206815928 + 0.2218745053 + 0.2230865955 + 0.2243078947 + 0.2255353034 + 0.2267691046 + 0.2280129045 + 0.2292630970 + 0.2305141985 + 0.2317567021 + 0.2329764068 + 0.2341637015 + 0.2353121042 + 0.2364190072 + 0.2374805957 + 0.2384950072 + 0.2394600958 + 0.2403741032 + 0.2412285060 + 0.2420233935 + 0.2427742034 + 0.2434999943 + 0.2442153990 + 0.2449319065 + 0.2456566989 + 0.2463952005 + 0.2471493930 + 0.2479220033 + 0.2487130016 + 0.2495251000 + 0.2503561974 + 0.2512075901 + 0.2520760000 + 0.2529664040 + 0.2538853884 + 0.2548437119 + 0.2558579147 + 0.2569623888 + 0.2581419051 + 0.2593897879 + 0.2606801093 + 0.2619997859 + 0.2633245885 + 0.2646321058 + 0.2659066021 + 0.2671222091 + 0.2682681084 + 0.2693215907 + 0.2703152001 + 0.2712577879 + 0.2721709907 + 0.2730554938 + 0.2739250958 + 0.2747743130 + 0.2756054997 + 0.2764146030 + 0.2772051990 + 0.2779743075 + 0.2787271142 + 0.2794634998 + 0.2801890969 + 0.2809084058 + 0.2816320062 + 0.2823747098 + 0.2831506133 + 0.2839820981 + 0.2848649919 + 0.2858025134 + 0.2867873013 + 0.2878226936 + 0.2889021933 + 0.2900269926 + 0.2911930978 + 0.2923978865 + 0.2936300933 + 0.2948761880 + 0.2961241901 + 0.2973628938 + 0.2985885143 + 0.2998012006 + 0.3010047972 + 0.3021970987 + 0.3033716977 + 0.3045161963 + 0.3056159914 + 0.3066501915 + 0.3076123893 + 0.3085128963 + 0.3093748093 + 0.3102149069 + 0.3110443950 + 0.3118737936 + 0.3127109110 + 0.3135589957 + 0.3144189119 + 0.3152843118 + 0.3161520958 + 0.3170174956 + 0.3178755939 + 0.3187314868 + 0.3195927143 + 0.3204680979 + 0.3213739991 + 0.3223293126 + 0.3233569860 + 0.3244507909 + 0.3255977035 + 0.3267756999 + 0.3279756904 + 0.3291803002 + 0.3303748071 + 0.3315485120 + 0.3326843977 + 0.3337798119 + 0.3348152936 + 0.3358032107 + 0.3367348909 + 0.3376190960 + 0.3384444118 + 0.3392320871 + 0.3399783969 + 0.3406944871 + 0.3413780928 + 0.3420386910 + 0.3426808119 + 0.3433162868 + 0.3439547122 + 0.3446053863 + 0.3452802002 + 0.3459802866 + 0.3467136025 + 0.3474789858 + 0.3482855856 + 0.3491322994 + 0.3500328958 + 0.3509812057 + 0.3519834876 + 0.3530359864 + 0.3541389108 + 0.3552891910 + 0.3564738035 + 0.3576740026 + 0.3588739932 + 0.3600645959 + 0.3612402976 + 0.3623969853 + 0.3635292947 + 0.3646346033 + 0.3657099903 + 0.3667556047 + 0.3677704930 + 0.3687556982 + 0.3697125912 + 0.3706437945 + 0.3715595901 + 0.3724690080 + 0.3733772933 + 0.3742752969 + 0.3751674891 + 0.3760527074 + 0.3769319057 + 0.3778083026 + 0.3786880076 + 0.3795790076 + 0.3804906011 + 0.3814407885 + 0.3824321926 + 0.3834637105 + 0.3845176101 + 0.3855882883 + 0.3866708875 + 0.3877635002 + 0.3888686001 + 0.3899909854 + 0.3911277056 + 0.3922775984 + 0.3934313059 + 0.3945826888 + 0.3957261145 + 0.3968504965 + 0.3979482055 + 0.3990120888 + 0.4000467956 + 0.4010437131 + 0.4020088017 + 0.4029388130 + 0.4038451016 + 0.4047274888 + 0.4055930078 + 0.4064427018 + 0.4072813094 + 0.4081071913 + 0.4089260995 + 0.4097451866 + 0.4105694890 + 0.4114066064 + 0.4122569859 + 0.4131241143 + 0.4140050113 + 0.4148985147 + 0.4158008993 + 0.4167236090 + 0.4176675081 + 0.4186491966 + 0.4196803868 + 0.4207774997 + 0.4219251871 + 0.4231063128 + 0.4243052900 + 0.4255081117 + 0.4267005026 + 0.4278686941 + 0.4290013015 + 0.4300687015 + 0.4310568869 + 0.4319736958 + 0.4328454137 + 0.4336949885 + 0.4345388114 + 0.4353840053 + 0.4362317026 + 0.4370762110 + 0.4379085898 + 0.4387196004 + 0.4395040870 + 0.4402616024 + 0.4409970045 + 0.4417150915 + 0.4424203932 + 0.4431223869 + 0.4438334107 + 0.4445698857 + 0.4453583956 + 0.4462080896 + 0.4471251965 + 0.4480918944 + 0.4491102993 + 0.4501725137 + 0.4512811005 + 0.4524315000 + 0.4536258876 + 0.4548498988 + 0.4561010897 + 0.4573644996 + 0.4586338103 + 0.4599033892 + 0.4611744881 + 0.4624508917 + 0.4637391865 + 0.4650414884 + 0.4663577974 + 0.4676811099 + 0.4690015018 + 0.4703139961 + 0.4716050029 + 0.4728696048 + 0.4740908146 + 0.4752691984 + 0.4763813913 + 0.4774327874 + 0.4784271121 + 0.4793924987 + 0.4803338945 + 0.4812591970 + 0.4821656942 + 0.4830561876 + 0.4839268029 + 0.4847800136 + 0.4856149852 + 0.4864366055 + 0.4872506857 + 0.4880648851 + 0.4888868928 + 0.4897224009 + 0.4905739129 + 0.4914413095 + 0.4923292100 + 0.4932385087 + 0.4941751063 + 0.4951438010 + 0.4961484075 + 0.4971834123 + 0.4982456863 + 0.4993270040 + 0.5004199147 + 0.5015118122 + 0.5025907755 + 0.5036478043 + 0.5046734214 + 0.5056589842 + 0.5065951943 + 0.5074753761 + 0.5082963705 + 0.5090649724 + 0.5098019242 + 0.5105221868 + 0.5112395287 + 0.5119636059 + 0.5126994252 + 0.5134509206 + 0.5142197013 + 0.5150089860 + 0.5158177018 + 0.5166478157 + 0.5174968243 + 0.5183656812 + 0.5192511082 + 0.5201653838 + 0.5211125016 + 0.5221105218 + 0.5231735706 + 0.5243276954 + 0.5255516171 + 0.5268324018 + 0.5281450152 + 0.5294731259 + 0.5307943225 + 0.5320841074 + 0.5333306789 + 0.5345025063 + 0.5355963111 + 0.5366004109 + 0.5375565886 + 0.5384708047 + 0.5393584967 + 0.5402259827 + 0.5410857797 + 0.5419417024 + 0.5427981019 + 0.5436624289 + 0.5445290208 + 0.5453966260 + 0.5462577939 + 0.5471146107 + 0.5479719043 + 0.5488393903 + 0.5497273803 + 0.5506578088 + 0.5516471267 + 0.5527126789 + 0.5538355112 + 0.5549985170 + 0.5561832786 + 0.5573828816 + 0.5585942864 + 0.5598186255 + 0.5610554814 + 0.5623052716 + 0.5635616183 + 0.5648146272 + 0.5660511851 + 0.5672566295 + 0.5684217215 + 0.5695446134 + 0.5706257820 + 0.5716617107 + 0.5726498961 + 0.5735875964 + 0.5744670033 + 0.5752794743 + 0.5760352015 + 0.5767551064 + 0.5774592161 + 0.5781627893 + 0.5788754821 + 0.5796039104 + 0.5803539157 + 0.5811277032 + 0.5819321871 + 0.5827584863 + 0.5836037993 + 0.5844542980 + 0.5853049755 + 0.5861505866 + 0.5869960189 + 0.5878553987 + 0.5887522101 + 0.5897055268 + 0.5907446146 + 0.5918523073 + 0.5930091739 + 0.5941920877 + 0.5953928828 + 0.5965957046 + 0.5977848172 + 0.5989491940 + 0.6000605226 + 0.6011224985 + 0.6021242142 + 0.6030789018 + 0.6039801836 + 0.6048383713 + 0.6056500077 + 0.6064301133 + 0.6071758270 + 0.6078960896 + 0.6085894704 + 0.6092637181 + 0.6099225283 + 0.6105781794 + 0.6112405062 + 0.6119177938 + 0.6126191020 + 0.6133441925 + 0.6141006947 + 0.6148883104 + 0.6157158017 + 0.6165835857 + 0.6175035834 + 0.6184763908 + 0.6195145249 + 0.6206189990 + 0.6218029857 + 0.6230565906 + 0.6243699789 + 0.6257280111 + 0.6271185279 + 0.6285330057 + 0.6299641132 + 0.6314023137 + 0.6328353286 + 0.6342498064 + 0.6356307864 + 0.6369662285 + 0.6382427216 + 0.6394453049 + 0.6405580044 + 0.6415867805 + 0.6425542831 + 0.6434767246 + 0.6443691254 + 0.6452344060 + 0.6460803747 + 0.6469035745 + 0.6477041245 + 0.6484807730 + 0.6492365003 + 0.6499711871 + 0.6506897807 + 0.6513956785 + 0.6520953774 + 0.6527956128 + 0.6535081267 + 0.6542478800 + 0.6550295949 + 0.6558724046 + 0.6567714214 + 0.6577283144 + 0.6587334871 + 0.6597931981 + 0.6608967781 + 0.6620492935 + 0.6632428169 + 0.6644775271 + 0.6657373905 + 0.6670100093 + 0.6682801247 + 0.6695359945 + 0.6707767248 + 0.6719986200 + 0.6732079983 + 0.6743972898 + 0.6755645871 + 0.6766923070 + 0.6777756810 + 0.6787837744 + 0.6797292233 + 0.6806203127 + 0.6814811826 + 0.6823214889 + 0.6831535101 + 0.6839842200 + 0.6848192215 + 0.6856622100 + 0.6865146756 + 0.6873624921 + 0.6882051826 + 0.6890435219 + 0.6898779273 + 0.6907151937 + 0.6915640235 + 0.6924375296 + 0.6933465004 + 0.6943172812 + 0.6953549981 + 0.6964592934 + 0.6976081729 + 0.6987894177 + 0.6999887824 + 0.7011907101 + 0.7023807764 + 0.7035446763 + 0.7046695948 + 0.7057371736 + 0.7067508101 + 0.7077292204 + 0.7086814046 + 0.7096115947 + 0.7105264068 + 0.7114247084 + 0.7123047709 + 0.7131667137 + 0.7140098214 + 0.7148374915 + 0.7156537771 + 0.7164676785 + 0.7172846794 + 0.7181128860 + 0.7189571261 + 0.7198163867 + 0.7206944227 + 0.7215924859 + 0.7225160003 + 0.7234672904 + 0.7244563103 + 0.7254763842 + 0.7265270948 + 0.7275997996 + 0.7286885977 + 0.7297828197 + 0.7308688164 + 0.7319386005 + 0.7329788804 + 0.7339875102 + 0.7349454761 + 0.7358558774 + 0.7367025018 + 0.7374975085 + 0.7382442951 + 0.7389717102 + 0.7396886945 + 0.7404084206 + 0.7411383986 + 0.7418810129 + 0.7426424026 + 0.7434210181 + 0.7442209125 + 0.7450360060 + 0.7458639741 + 0.7466968894 + 0.7475343943 + 0.7483779788 + 0.7492403984 + 0.7501326203 + 0.7510781288 + 0.7520893216 + 0.7531732917 + 0.7543053031 + 0.7554739714 + 0.7566642761 + 0.7578607798 + 0.7590482831 + 0.7602115273 + 0.7613403201 + 0.7624225020 + 0.7634521127 + 0.7644327283 + 0.7653704882 + 0.7662618756 + 0.7671076059 + 0.7679154277 + 0.7686895132 + 0.7694332004 + 0.7701491714 + 0.7708417177 + 0.7715176940 + 0.7721850276 + 0.7728537917 + 0.7735335827 + 0.7742335796 + 0.7749583125 + 0.7757118940 + 0.7764955759 + 0.7773144841 + 0.7781693935 + 0.7790681720 + 0.7800117135 + 0.7810093164 + 0.7820671797 + 0.7831969857 + 0.7843930721 + 0.7856580019 + 0.7869743705 + 0.7883390784 + 0.7897359133 + 0.7911605239 + 0.7926027179 + 0.7940539122 + 0.7954995036 + 0.7969205976 + 0.7983062267 + 0.7996307015 + 0.8008906841 + 0.8020377755 + 0.8030900955 + 0.8040465713 + 0.8049607873 + 0.8058419228 + 0.8067098856 + 0.8075734973 + 0.8084387779 + 0.8093091846 + 0.8101882935 + 0.8110724092 + 0.8119565248 + 0.8128302097 + 0.8136907816 + 0.8145390153 + 0.8153827786 + 0.8162342906 + 0.8171085715 + 0.8180341125 + 0.8190286756 + 0.8201074004 + 0.8212432861 + 0.8224158287 + 0.8236094713 + 0.8248127103 + 0.8260108232 + 0.8271877766 + 0.8283281922 + 0.8294121027 + 0.8304437995 + 0.8314198852 + 0.8323469162 + 0.8332254887 + 0.8340582848 + 0.8348531723 + 0.8356149197 + 0.8363471031 + 0.8370530009 + 0.8377360106 + 0.8384007215 + 0.8390572071 + 0.8397147059 + 0.8403840065 + 0.8410733938 + 0.8417865038 + 0.8425278068 + 0.8432993889 + 0.8441076279 + 0.8449550271 + 0.8458499908 + 0.8467941880 + 0.8477939963 + 0.8488482833 + 0.8499671817 + 0.8511453867 + 0.8523722291 + 0.8536306024 + 0.8549143076 + 0.8562114239 + 0.8575189710 + 0.8588296771 + 0.8601360917 + 0.8614333272 + 0.8627083898 + 0.8639556766 + 0.8651599884 + 0.8663218021 + 0.8674148917 + 0.8684523106 + 0.8694357276 + 0.8703922033 + 0.8713268042 + 0.8722450137 + 0.8731473088 + 0.8740348220 + 0.8749024868 + 0.8757532239 + 0.8765848875 + 0.8774042130 + 0.8782153726 + 0.8790270090 + 0.8798487186 + 0.8806846738 + 0.8815388083 + 0.8824067116 + 0.8832883239 + 0.8841770291 + 0.8850684762 + 0.8859568238 + 0.8868265748 + 0.8876711726 + 0.8884992003 + 0.8893253803 + 0.8901607990 + 0.8910120130 + 0.8918834925 + 0.8927683234 + 0.8936566114 + 0.8945342898 + 0.8953920007 + 0.8962271810 + 0.8970484138 + 0.8978644013 + 0.8986830711 + 0.8995125890 + 0.9003558159 + 0.9012147188 + 0.9020918012 + 0.9029911757 + 0.9039173126 + 0.9048787951 + 0.9058734775 + 0.9069008231 + 0.9079614282 + 0.9090539217 + 0.9101731777 + 0.9113155007 + 0.9124684930 + 0.9136266112 + 0.9147831798 + 0.9159303904 + 0.9170637727 + 0.9181826115 + 0.9192898273 + 0.9203851819 + 0.9214702845 + 0.9225413203 + 0.9235910773 + 0.9246032834 + 0.9255704284 + 0.9264910221 + 0.9273847938 + 0.9282647967 + 0.9291424155 + 0.9300234914 + 0.9309046865 + 0.9317824841 + 0.9326478243 + 0.9334927201 + 0.9343230128 + 0.9351406097 + 0.9359554052 + 0.9367738962 + 0.9376012087 + 0.9384446144 + 0.9393029213 + 0.9401808977 + 0.9410789013 + 0.9420050979 + 0.9429584146 + 0.9439467192 + 0.9449679255 + 0.9460309148 + 0.9471349120 + 0.9482825994 + 0.9494689107 + 0.9506921768 + 0.9519376755 + 0.9531915188 + 0.9544414282 + 0.9556764960 + 0.9568939209 + 0.9580923915 + 0.9592747092 + 0.9604387283 + 0.9615803957 + 0.9626855850 + 0.9637448192 + 0.9647368789 + 0.9656659961 + 0.9665510058 + 0.9674115777 + 0.9682607055 + 0.9691076875 + 0.9699587822 + 0.9708169103 + 0.9716814160 + 0.9725438952 + 0.9734039903 + 0.9742600918 + 0.9751064181 + 0.9759439826 + 0.9767826200 + 0.9776347280 + 0.9785134792 + 0.9794371724 + 0.9804236293 + 0.9814878702 + 0.9826123118 + 0.9837834239 + 0.9849817157 + 0.9861915708 + 0.9873952866 + 0.9885756969 + 0.9897236228 + 0.9908238053 + 0.9918766022 + 0.9928745031 + 0.9938510060 + 0.9947990775 + 0.9957082272 + 0.9965645075 + 0.9973732829 + 0.9981198907 + 0.9988123775 + 0.9994353056 + 1.0000000000 +} diff --git a/rpplugins/color_correction/resources/film_luts_raw/kodak_kaf-3000.spi1d b/rpplugins/color_correction/resources/film_luts_raw/kodak_kaf-3000.spi1d new file mode 100644 index 0000000..179c1df --- /dev/null +++ b/rpplugins/color_correction/resources/film_luts_raw/kodak_kaf-3000.spi1d @@ -0,0 +1,1030 @@ +Version 1 +From 0.0 1.0 +Length 1024 +Components 1 +{ + 0.0000000000 + 0.0008239537 + 0.0017113760 + 0.0026572610 + 0.0036410000 + 0.0046517309 + 0.0056753629 + 0.0066966042 + 0.0077035818 + 0.0086956657 + 0.0096768690 + 0.0106551796 + 0.0116374604 + 0.0126282601 + 0.0136336396 + 0.0146547500 + 0.0156989004 + 0.0167712905 + 0.0178667009 + 0.0189784598 + 0.0201001503 + 0.0212287605 + 0.0223587994 + 0.0234838799 + 0.0245989803 + 0.0257005394 + 0.0267930105 + 0.0278819893 + 0.0289712399 + 0.0300603900 + 0.0311466791 + 0.0322293788 + 0.0333095305 + 0.0343901701 + 0.0354710110 + 0.0365408882 + 0.0375862904 + 0.0386093296 + 0.0396146104 + 0.0406112485 + 0.0416014791 + 0.0425814800 + 0.0435459092 + 0.0444903001 + 0.0454233699 + 0.0463445894 + 0.0472576804 + 0.0481645502 + 0.0490692593 + 0.0499759391 + 0.0508891717 + 0.0518166013 + 0.0527626611 + 0.0537226386 + 0.0546919592 + 0.0556649007 + 0.0566373095 + 0.0576051287 + 0.0585623085 + 0.0595092699 + 0.0604476705 + 0.0613846295 + 0.0623276606 + 0.0632801205 + 0.0642424524 + 0.0652119219 + 0.0661871582 + 0.0671750307 + 0.0681754425 + 0.0691855326 + 0.0701999068 + 0.0712177306 + 0.0722424909 + 0.0732808188 + 0.0743458495 + 0.0754341781 + 0.0765458792 + 0.0776749030 + 0.0788224265 + 0.0799827874 + 0.0811530426 + 0.0823262334 + 0.0834952369 + 0.0846570507 + 0.0858169273 + 0.0869782567 + 0.0881420672 + 0.0893090963 + 0.0904768184 + 0.0916401520 + 0.0927933380 + 0.0939279124 + 0.0950335264 + 0.0961028486 + 0.0971330479 + 0.0981383100 + 0.0991264507 + 0.1001088023 + 0.1010833979 + 0.1020457000 + 0.1029841006 + 0.1038997024 + 0.1047933027 + 0.1056651995 + 0.1065146998 + 0.1073456034 + 0.1081662029 + 0.1089894995 + 0.1098269969 + 0.1106915995 + 0.1115795970 + 0.1124866977 + 0.1134070009 + 0.1143371984 + 0.1152724028 + 0.1162075028 + 0.1171367019 + 0.1180611029 + 0.1189863980 + 0.1199202016 + 0.1209200025 + 0.1219737977 + 0.1230672970 + 0.1241782010 + 0.1253035069 + 0.1264393032 + 0.1275773048 + 0.1287124008 + 0.1298429966 + 0.1309712976 + 0.1321021020 + 0.1332444996 + 0.1343923956 + 0.1355278045 + 0.1366423070 + 0.1377331018 + 0.1388027072 + 0.1398545951 + 0.1408876032 + 0.1419010013 + 0.1428834945 + 0.1438401043 + 0.1447667032 + 0.1456668973 + 0.1465339959 + 0.1473750025 + 0.1481927037 + 0.1490017027 + 0.1498129964 + 0.1506288052 + 0.1514475048 + 0.1522585005 + 0.1530572027 + 0.1538338065 + 0.1545996070 + 0.1553678066 + 0.1561364979 + 0.1569079012 + 0.1576897949 + 0.1584908068 + 0.1593147069 + 0.1601596028 + 0.1610313058 + 0.1619254947 + 0.1628465056 + 0.1637898982 + 0.1647551060 + 0.1657350957 + 0.1667309999 + 0.1677470058 + 0.1687898934 + 0.1698749065 + 0.1710059941 + 0.1721913069 + 0.1734060049 + 0.1746453941 + 0.1758995950 + 0.1771610975 + 0.1784185022 + 0.1796668023 + 0.1809030026 + 0.1821372062 + 0.1833820045 + 0.1846434027 + 0.1859240979 + 0.1872127950 + 0.1884990036 + 0.1897740960 + 0.1910288036 + 0.1922529936 + 0.1934324950 + 0.1945621967 + 0.1956468970 + 0.1966817975 + 0.1976771951 + 0.1986268014 + 0.1995413005 + 0.2004172951 + 0.2012622952 + 0.2020770013 + 0.2028657049 + 0.2036325037 + 0.2043817043 + 0.2051236928 + 0.2058676034 + 0.2066213936 + 0.2074044049 + 0.2082141936 + 0.2090529948 + 0.2099052966 + 0.2107656002 + 0.2116280943 + 0.2124830037 + 0.2133235037 + 0.2141488940 + 0.2149658054 + 0.2157903016 + 0.2166465074 + 0.2175375968 + 0.2184633017 + 0.2194138020 + 0.2203830928 + 0.2213633060 + 0.2223457992 + 0.2233193070 + 0.2242776006 + 0.2252182066 + 0.2261507064 + 0.2270810008 + 0.2280130982 + 0.2289510965 + 0.2298972011 + 0.2308543026 + 0.2318239957 + 0.2328100950 + 0.2338117063 + 0.2348213047 + 0.2358337045 + 0.2368506938 + 0.2378790975 + 0.2389242053 + 0.2399875969 + 0.2410621047 + 0.2421357036 + 0.2432024926 + 0.2442667931 + 0.2453292012 + 0.2463901937 + 0.2474516928 + 0.2485162020 + 0.2495937049 + 0.2506928146 + 0.2518276870 + 0.2529919147 + 0.2541776896 + 0.2553750873 + 0.2565745115 + 0.2577669024 + 0.2589448988 + 0.2600898147 + 0.2612054944 + 0.2622891963 + 0.2633585930 + 0.2644208074 + 0.2654806077 + 0.2665413916 + 0.2676038146 + 0.2686690092 + 0.2697396874 + 0.2708159983 + 0.2718920112 + 0.2729560137 + 0.2739931047 + 0.2749989033 + 0.2759633064 + 0.2768782079 + 0.2777278125 + 0.2785072923 + 0.2792311013 + 0.2799170017 + 0.2805862129 + 0.2812471092 + 0.2819086015 + 0.2825776935 + 0.2832584083 + 0.2839589119 + 0.2846930027 + 0.2854613066 + 0.2862626016 + 0.2870804965 + 0.2879104912 + 0.2887445986 + 0.2895751894 + 0.2903952003 + 0.2912051082 + 0.2920134962 + 0.2928391099 + 0.2937021852 + 0.2946189046 + 0.2955986857 + 0.2966246903 + 0.2976948917 + 0.2987993956 + 0.2999471128 + 0.3011271954 + 0.3023349047 + 0.3035596907 + 0.3047932982 + 0.3060269952 + 0.3072519898 + 0.3084549904 + 0.3096269071 + 0.3107633889 + 0.3118777871 + 0.3129779100 + 0.3140724897 + 0.3151645064 + 0.3162542880 + 0.3173392117 + 0.3184188902 + 0.3194957972 + 0.3205688894 + 0.3216289878 + 0.3226647973 + 0.3236807883 + 0.3246811926 + 0.3256719112 + 0.3266536891 + 0.3276238143 + 0.3285810947 + 0.3295294940 + 0.3304790854 + 0.3314437866 + 0.3324182034 + 0.3333995938 + 0.3343864977 + 0.3353833854 + 0.3363946080 + 0.3374285102 + 0.3384769857 + 0.3395330906 + 0.3405885100 + 0.3416405916 + 0.3426834047 + 0.3437139094 + 0.3447251916 + 0.3457196951 + 0.3466978967 + 0.3476671875 + 0.3486328125 + 0.3495933115 + 0.3505493999 + 0.3514994979 + 0.3524489999 + 0.3534050882 + 0.3543708026 + 0.3553416133 + 0.3563007116 + 0.3572334945 + 0.3581455946 + 0.3590348959 + 0.3599027991 + 0.3607496023 + 0.3615792990 + 0.3623996973 + 0.3632219136 + 0.3640663028 + 0.3649503887 + 0.3658618033 + 0.3667995036 + 0.3677533865 + 0.3687168062 + 0.3696813881 + 0.3706347942 + 0.3715701103 + 0.3724884987 + 0.3733963072 + 0.3743011057 + 0.3752076924 + 0.3761194050 + 0.3770408034 + 0.3779734969 + 0.3789207041 + 0.3798849881 + 0.3808659017 + 0.3818587959 + 0.3828561008 + 0.3838579953 + 0.3848698139 + 0.3859066069 + 0.3869642019 + 0.3880375028 + 0.3891113997 + 0.3901838064 + 0.3912554085 + 0.3923274875 + 0.3934000134 + 0.3944740891 + 0.3955540955 + 0.3966433108 + 0.3977557123 + 0.3989006877 + 0.4000787139 + 0.4012784064 + 0.4024907053 + 0.4037069976 + 0.4049186110 + 0.4061144888 + 0.4072830081 + 0.4084154963 + 0.4095208943 + 0.4106051922 + 0.4116787910 + 0.4127461016 + 0.4138118029 + 0.4148772061 + 0.4159424007 + 0.4170075953 + 0.4180721939 + 0.4191268086 + 0.4201577902 + 0.4211621881 + 0.4221380055 + 0.4230895936 + 0.4240145087 + 0.4249120951 + 0.4257782996 + 0.4266144037 + 0.4274252057 + 0.4282115996 + 0.4289813936 + 0.4297375083 + 0.4304881990 + 0.4312418997 + 0.4320062995 + 0.4327985048 + 0.4336202145 + 0.4344716072 + 0.4353393018 + 0.4362154007 + 0.4370937943 + 0.4379679859 + 0.4388278127 + 0.4396711886 + 0.4405008852 + 0.4413329065 + 0.4421812892 + 0.4430595934 + 0.4439747036 + 0.4449261129 + 0.4459050000 + 0.4469138086 + 0.4479498863 + 0.4490180016 + 0.4501048923 + 0.4512071908 + 0.4523200095 + 0.4534398019 + 0.4545612931 + 0.4556761980 + 0.4567787051 + 0.4578686059 + 0.4589490891 + 0.4600251913 + 0.4611012936 + 0.4621792138 + 0.4632557929 + 0.4643296897 + 0.4654009044 + 0.4664717913 + 0.4675419927 + 0.4686031938 + 0.4696451128 + 0.4706639946 + 0.4716722965 + 0.4726729095 + 0.4736702144 + 0.4746587873 + 0.4756379128 + 0.4766108096 + 0.4775831103 + 0.4785614014 + 0.4795452058 + 0.4805310071 + 0.4815202951 + 0.4825159013 + 0.4835259020 + 0.4845573902 + 0.4856084883 + 0.4866689146 + 0.4877327979 + 0.4888001978 + 0.4898718894 + 0.4909470081 + 0.4920218885 + 0.4930953085 + 0.4941661954 + 0.4952344000 + 0.4963006973 + 0.4973612130 + 0.4984084964 + 0.4994311035 + 0.5004292727 + 0.5014035106 + 0.5023515224 + 0.5032755733 + 0.5041642785 + 0.5050222874 + 0.5058479905 + 0.5066505075 + 0.5074304938 + 0.5081961155 + 0.5089520812 + 0.5097069740 + 0.5104699135 + 0.5112537742 + 0.5120664239 + 0.5129058957 + 0.5137627721 + 0.5146341920 + 0.5155118704 + 0.5163893104 + 0.5172569752 + 0.5181056857 + 0.5189391971 + 0.5197678208 + 0.5206072927 + 0.5214716196 + 0.5223724246 + 0.5233045220 + 0.5242694020 + 0.5252612829 + 0.5262829065 + 0.5273327231 + 0.5284060836 + 0.5294969082 + 0.5305972099 + 0.5317053795 + 0.5328170061 + 0.5339269042 + 0.5350281000 + 0.5361132026 + 0.5371879935 + 0.5382577777 + 0.5393270850 + 0.5403997898 + 0.5414752960 + 0.5425496101 + 0.5436221957 + 0.5446935892 + 0.5457674861 + 0.5468341112 + 0.5478798747 + 0.5489076972 + 0.5499224067 + 0.5509316921 + 0.5519384742 + 0.5529379845 + 0.5539290905 + 0.5549092293 + 0.5558865070 + 0.5568640232 + 0.5578449965 + 0.5588300228 + 0.5598173738 + 0.5608099103 + 0.5618140101 + 0.5628398061 + 0.5638893247 + 0.5649536848 + 0.5660216212 + 0.5670881271 + 0.5681570768 + 0.5692278743 + 0.5702992082 + 0.5713713169 + 0.5724447966 + 0.5735238791 + 0.5746114850 + 0.5757126212 + 0.5768241882 + 0.5779408813 + 0.5790569782 + 0.5801681280 + 0.5812727213 + 0.5823650956 + 0.5834385157 + 0.5844845176 + 0.5854976773 + 0.5864800811 + 0.5874279737 + 0.5883439779 + 0.5892180204 + 0.5900630951 + 0.5908904076 + 0.5917155147 + 0.5925496817 + 0.5933985710 + 0.5942596197 + 0.5951249003 + 0.5959877968 + 0.5968421102 + 0.5976834297 + 0.5984950066 + 0.5992792249 + 0.6000332832 + 0.6007766724 + 0.6015186906 + 0.6022672057 + 0.6030321717 + 0.6038194895 + 0.6046321988 + 0.6054781079 + 0.6063600779 + 0.6072819233 + 0.6082324982 + 0.6092107296 + 0.6102107763 + 0.6112337708 + 0.6122769713 + 0.6133307219 + 0.6143916249 + 0.6154521704 + 0.6165164113 + 0.6175839901 + 0.6186556220 + 0.6197301745 + 0.6208109260 + 0.6219016910 + 0.6230133772 + 0.6241537929 + 0.6253302097 + 0.6265388727 + 0.6277642846 + 0.6289970875 + 0.6302282214 + 0.6314477921 + 0.6326466203 + 0.6338086724 + 0.6349387169 + 0.6360424757 + 0.6371321082 + 0.6382141113 + 0.6392921209 + 0.6403672099 + 0.6414381862 + 0.6425055265 + 0.6435723901 + 0.6446369290 + 0.6456918120 + 0.6467275023 + 0.6477332711 + 0.6487026811 + 0.6496292949 + 0.6505001187 + 0.6513100863 + 0.6520529985 + 0.6527563930 + 0.6534317136 + 0.6540933847 + 0.6547484994 + 0.6554052234 + 0.6560714245 + 0.6567540765 + 0.6574617028 + 0.6582099795 + 0.6589958072 + 0.6598116755 + 0.6606448889 + 0.6614922881 + 0.6623446941 + 0.6631942987 + 0.6640357971 + 0.6648727059 + 0.6657136083 + 0.6665757895 + 0.6674811244 + 0.6684336066 + 0.6694403887 + 0.6704826951 + 0.6715667248 + 0.6726835966 + 0.6738361716 + 0.6750171781 + 0.6762194037 + 0.6774324775 + 0.6786479950 + 0.6798574924 + 0.6810536981 + 0.6822184920 + 0.6833531857 + 0.6844527125 + 0.6855350137 + 0.6866068244 + 0.6876752973 + 0.6887421012 + 0.6898087859 + 0.6908742785 + 0.6919373870 + 0.6929990053 + 0.6940523982 + 0.6950901151 + 0.6961060762 + 0.6971120238 + 0.6981120706 + 0.6991108060 + 0.7001062036 + 0.7010952830 + 0.7020772099 + 0.7030572295 + 0.7040420771 + 0.7050337195 + 0.7060307860 + 0.7070298195 + 0.7080342174 + 0.7090519071 + 0.7100886703 + 0.7111470103 + 0.7122195959 + 0.7132937908 + 0.7143607140 + 0.7154163122 + 0.7164533138 + 0.7174721956 + 0.7184677124 + 0.7194433808 + 0.7204009295 + 0.7213470936 + 0.7222880721 + 0.7232226133 + 0.7241495252 + 0.7250617146 + 0.7259560227 + 0.7268221974 + 0.7276610136 + 0.7284513116 + 0.7291994095 + 0.7299144268 + 0.7306104898 + 0.7312946916 + 0.7319728136 + 0.7326508164 + 0.7333354950 + 0.7340328097 + 0.7347601056 + 0.7355272174 + 0.7363470793 + 0.7372058034 + 0.7380936742 + 0.7390053868 + 0.7399355173 + 0.7408784032 + 0.7418274879 + 0.7427803278 + 0.7437379956 + 0.7447054982 + 0.7456836104 + 0.7466775775 + 0.7476887703 + 0.7487217188 + 0.7497777939 + 0.7508600950 + 0.7519810796 + 0.7531362176 + 0.7543209195 + 0.7555187941 + 0.7567229867 + 0.7579241991 + 0.7591124177 + 0.7602767944 + 0.7614082098 + 0.7625083923 + 0.7635900974 + 0.7646592855 + 0.7657235861 + 0.7667865157 + 0.7678502202 + 0.7689155936 + 0.7699834704 + 0.7710577846 + 0.7721307278 + 0.7731891870 + 0.7742263079 + 0.7752460241 + 0.7762551904 + 0.7772603035 + 0.7782598138 + 0.7792512178 + 0.7802270055 + 0.7811887860 + 0.7821359038 + 0.7830716968 + 0.7839983106 + 0.7849181890 + 0.7858353853 + 0.7867543101 + 0.7876856923 + 0.7886385918 + 0.7896096706 + 0.7905899286 + 0.7915676236 + 0.7925336957 + 0.7934818268 + 0.7944025993 + 0.7952839136 + 0.7961304784 + 0.7969564199 + 0.7977765799 + 0.7986037731 + 0.7994433045 + 0.8003032207 + 0.8011813164 + 0.8020802736 + 0.8030009270 + 0.8039441705 + 0.8048942089 + 0.8058394194 + 0.8067725897 + 0.8077021837 + 0.8086333871 + 0.8095719814 + 0.8105241060 + 0.8114864826 + 0.8124600053 + 0.8134480119 + 0.8144549131 + 0.8154819012 + 0.8165273070 + 0.8175873160 + 0.8186547160 + 0.8197259903 + 0.8207991123 + 0.8218631744 + 0.8229097724 + 0.8239313960 + 0.8249354959 + 0.8259270191 + 0.8269088864 + 0.8278800249 + 0.8288375139 + 0.8297861814 + 0.8307325840 + 0.8316870928 + 0.8326554894 + 0.8336303234 + 0.8346098065 + 0.8355954289 + 0.8365911245 + 0.8376066089 + 0.8386394978 + 0.8396871090 + 0.8407385945 + 0.8417950273 + 0.8428555131 + 0.8439220190 + 0.8449907899 + 0.8460597992 + 0.8471270800 + 0.8481943011 + 0.8492627144 + 0.8503319025 + 0.8513954878 + 0.8524438739 + 0.8534613848 + 0.8544461131 + 0.8553860188 + 0.8562803864 + 0.8571103811 + 0.8578768969 + 0.8585957885 + 0.8592829704 + 0.8599522114 + 0.8606104255 + 0.8612663150 + 0.8619267941 + 0.8625972271 + 0.8632894158 + 0.8640218973 + 0.8647894859 + 0.8655846119 + 0.8664000034 + 0.8672314882 + 0.8680710793 + 0.8689119220 + 0.8697466254 + 0.8705791235 + 0.8714179993 + 0.8722798824 + 0.8731784225 + 0.8741275072 + 0.8751282096 + 0.8761690259 + 0.8772516847 + 0.8783689141 + 0.8795279264 + 0.8807160258 + 0.8819314837 + 0.8831598163 + 0.8843933940 + 0.8856235147 + 0.8868407011 + 0.8880308867 + 0.8891866803 + 0.8903077245 + 0.8914114833 + 0.8925023079 + 0.8935890198 + 0.8946737051 + 0.8957551122 + 0.8968315125 + 0.8979024887 + 0.8989741206 + 0.9000406861 + 0.9010896087 + 0.9021161199 + 0.9031258225 + 0.9041231871 + 0.9051136971 + 0.9060966969 + 0.9070687890 + 0.9080281854 + 0.9089828134 + 0.9099376798 + 0.9109022021 + 0.9118763208 + 0.9128565788 + 0.9138407707 + 0.9148361087 + 0.9158486128 + 0.9168851972 + 0.9179406762 + 0.9190021753 + 0.9200580716 + 0.9210987091 + 0.9221140742 + 0.9230914712 + 0.9240095019 + 0.9248781800 + 0.9257149100 + 0.9265410900 + 0.9273703098 + 0.9282112718 + 0.9290707111 + 0.9299505949 + 0.9308521152 + 0.9317784905 + 0.9327259064 + 0.9336796999 + 0.9346215725 + 0.9355351925 + 0.9364286065 + 0.9372990131 + 0.9381507039 + 0.9389857054 + 0.9398118854 + 0.9406411052 + 0.9414886832 + 0.9423733950 + 0.9433202744 + 0.9443135262 + 0.9453420043 + 0.9463896155 + 0.9474490881 + 0.9485102892 + 0.9495586157 + 0.9505851269 + 0.9515897036 + 0.9525790811 + 0.9535614848 + 0.9545397162 + 0.9555109143 + 0.9564700127 + 0.9574239254 + 0.9583799839 + 0.9593443274 + 0.9603207707 + 0.9613075852 + 0.9623004794 + 0.9633029103 + 0.9643172026 + 0.9653546214 + 0.9664106965 + 0.9674816728 + 0.9685521722 + 0.9696255922 + 0.9707052708 + 0.9717903733 + 0.9728767872 + 0.9739595056 + 0.9750362039 + 0.9761099815 + 0.9771819115 + 0.9782528877 + 0.9793108106 + 0.9803507924 + 0.9813615084 + 0.9823462963 + 0.9833049178 + 0.9842357039 + 0.9851344228 + 0.9859966040 + 0.9868291020 + 0.9876328707 + 0.9884179831 + 0.9891839027 + 0.9899348021 + 0.9906693101 + 0.9913892150 + 0.9920961857 + 0.9927936792 + 0.9934824109 + 0.9941564202 + 0.9948133826 + 0.9954445958 + 0.9960510731 + 0.9966241717 + 0.9971635938 + 0.9976590276 + 0.9981124997 + 0.9985358715 + 0.9989339113 + 0.9993115067 + 0.9996662736 + 1.0000000000 +} diff --git a/rpplugins/color_correction/resources/film_luts_raw/kodak_kai-0311.spi1d b/rpplugins/color_correction/resources/film_luts_raw/kodak_kai-0311.spi1d new file mode 100644 index 0000000..a382f09 --- /dev/null +++ b/rpplugins/color_correction/resources/film_luts_raw/kodak_kai-0311.spi1d @@ -0,0 +1,1030 @@ +Version 1 +From 0.0 1.0 +Length 1024 +Components 1 +{ + 0.0000000000 + 0.0016059499 + 0.0032039359 + 0.0047925338 + 0.0063681109 + 0.0079261437 + 0.0094620753 + 0.0109717799 + 0.0124478899 + 0.0138870701 + 0.0152903199 + 0.0166584495 + 0.0179926194 + 0.0192952193 + 0.0205696207 + 0.0218127500 + 0.0230190307 + 0.0241936091 + 0.0253404994 + 0.0264616702 + 0.0275589097 + 0.0286343992 + 0.0296888705 + 0.0307215601 + 0.0317354687 + 0.0327326916 + 0.0337138698 + 0.0346802585 + 0.0356336907 + 0.0365758091 + 0.0375103503 + 0.0384392217 + 0.0393667594 + 0.0402943417 + 0.0412232615 + 0.0421543792 + 0.0430876091 + 0.0440218188 + 0.0449589603 + 0.0459001884 + 0.0468437783 + 0.0477895401 + 0.0487375483 + 0.0496875793 + 0.0506395511 + 0.0515942089 + 0.0525525808 + 0.0535144582 + 0.0544794910 + 0.0554478317 + 0.0564199202 + 0.0573957488 + 0.0583746210 + 0.0593575612 + 0.0603439212 + 0.0613333285 + 0.0623258613 + 0.0633219033 + 0.0643215328 + 0.0653229132 + 0.0663260892 + 0.0673301816 + 0.0683355704 + 0.0693410188 + 0.0703461990 + 0.0713518485 + 0.0723578706 + 0.0733634382 + 0.0743684769 + 0.0753747523 + 0.0763814375 + 0.0773879215 + 0.0783942565 + 0.0794009119 + 0.0804076791 + 0.0814127624 + 0.0824181885 + 0.0834240466 + 0.0844298676 + 0.0854352489 + 0.0864404887 + 0.0874472633 + 0.0884538963 + 0.0894602016 + 0.0904667079 + 0.0914734229 + 0.0924795270 + 0.0934846178 + 0.0944902077 + 0.0954962522 + 0.0965018719 + 0.0975077078 + 0.0985157192 + 0.0995259583 + 0.1005385965 + 0.1015558019 + 0.1025787964 + 0.1036100015 + 0.1046487987 + 0.1056960970 + 0.1067529991 + 0.1078196988 + 0.1088960990 + 0.1099824011 + 0.1110825986 + 0.1121942028 + 0.1133178994 + 0.1144538969 + 0.1156022996 + 0.1167630032 + 0.1179357022 + 0.1191222966 + 0.1203233972 + 0.1215377003 + 0.1227634028 + 0.1240004003 + 0.1252481937 + 0.1265043020 + 0.1277696937 + 0.1290419996 + 0.1303198040 + 0.1316013932 + 0.1328857988 + 0.1341720074 + 0.1354583055 + 0.1367450058 + 0.1380295008 + 0.1393115968 + 0.1405912936 + 0.1418687999 + 0.1431439966 + 0.1444166005 + 0.1456868947 + 0.1469538957 + 0.1482183039 + 0.1494797021 + 0.1507384926 + 0.1519940048 + 0.1532454938 + 0.1544931978 + 0.1557371020 + 0.1569786072 + 0.1582174003 + 0.1594552994 + 0.1606920063 + 0.1619275063 + 0.1631624997 + 0.1643957943 + 0.1656281948 + 0.1668587029 + 0.1680880040 + 0.1693165004 + 0.1705441028 + 0.1717692018 + 0.1729893982 + 0.1742039025 + 0.1754093021 + 0.1766050011 + 0.1777881980 + 0.1789582074 + 0.1801135987 + 0.1812521964 + 0.1823734939 + 0.1834750026 + 0.1845587045 + 0.1856247932 + 0.1866752952 + 0.1877115965 + 0.1887340993 + 0.1897435039 + 0.1907389015 + 0.1917219013 + 0.1926929951 + 0.1936533004 + 0.1946032941 + 0.1955437064 + 0.1964759976 + 0.1974004060 + 0.1983195990 + 0.1992345005 + 0.2001473010 + 0.2010585964 + 0.2019691020 + 0.2028799951 + 0.2037910968 + 0.2047035992 + 0.2056163996 + 0.2065296024 + 0.2074443996 + 0.2083611935 + 0.2092798948 + 0.2101999074 + 0.2111200988 + 0.2120410055 + 0.2129642069 + 0.2138908952 + 0.2148218006 + 0.2157568038 + 0.2166953981 + 0.2176382989 + 0.2185852975 + 0.2195377946 + 0.2204961032 + 0.2214609981 + 0.2224321067 + 0.2234085947 + 0.2243912965 + 0.2253790945 + 0.2263737023 + 0.2273754030 + 0.2283847928 + 0.2294009030 + 0.2304224074 + 0.2314486951 + 0.2324783951 + 0.2335128933 + 0.2345526069 + 0.2355960011 + 0.2366417050 + 0.2376891971 + 0.2387381941 + 0.2397857010 + 0.2408334017 + 0.2418812960 + 0.2429291010 + 0.2439766973 + 0.2450250983 + 0.2460754067 + 0.2471272945 + 0.2481832057 + 0.2492412031 + 0.2503012121 + 0.2513638139 + 0.2524305880 + 0.2535029054 + 0.2545804977 + 0.2556641996 + 0.2567521036 + 0.2578442991 + 0.2589425147 + 0.2600479126 + 0.2611603141 + 0.2622781098 + 0.2634013891 + 0.2645292878 + 0.2656618953 + 0.2667996883 + 0.2679435015 + 0.2690925896 + 0.2702454925 + 0.2714022100 + 0.2725617886 + 0.2737230957 + 0.2748858929 + 0.2760506868 + 0.2772169113 + 0.2783834040 + 0.2795504928 + 0.2807163894 + 0.2818816900 + 0.2830451131 + 0.2842077017 + 0.2853684127 + 0.2865259051 + 0.2876791954 + 0.2888275087 + 0.2899697125 + 0.2911050022 + 0.2922331095 + 0.2933534086 + 0.2944662869 + 0.2955724895 + 0.2966713011 + 0.2977609038 + 0.2988406122 + 0.2999115884 + 0.3009747863 + 0.3020302951 + 0.3030776978 + 0.3041163087 + 0.3051471114 + 0.3061706126 + 0.3071883917 + 0.3082000911 + 0.3092052937 + 0.3102042973 + 0.3111982048 + 0.3121899068 + 0.3131796122 + 0.3141691983 + 0.3151580095 + 0.3161459863 + 0.3171347082 + 0.3181253076 + 0.3191179037 + 0.3201133013 + 0.3211115897 + 0.3221124113 + 0.3231154978 + 0.3241209090 + 0.3251287043 + 0.3261393011 + 0.3271540999 + 0.3281734884 + 0.3291963935 + 0.3302215934 + 0.3312487006 + 0.3322781920 + 0.3333105147 + 0.3343453109 + 0.3353832066 + 0.3364242017 + 0.3374665082 + 0.3385097980 + 0.3395538926 + 0.3405987024 + 0.3416439891 + 0.3426909149 + 0.3437392116 + 0.3447869122 + 0.3458350003 + 0.3468832076 + 0.3479309082 + 0.3489786088 + 0.3500263095 + 0.3510748148 + 0.3521223962 + 0.3531706035 + 0.3542183042 + 0.3552643061 + 0.3563081026 + 0.3573493958 + 0.3583877981 + 0.3594241142 + 0.3604596853 + 0.3614932895 + 0.3625242114 + 0.3635517061 + 0.3645758927 + 0.3655968010 + 0.3666146100 + 0.3676308095 + 0.3686437011 + 0.3696531951 + 0.3706597984 + 0.3716636896 + 0.3726654053 + 0.3736641109 + 0.3746609092 + 0.3756552041 + 0.3766474128 + 0.3776386082 + 0.3786295056 + 0.3796210885 + 0.3806126118 + 0.3816055954 + 0.3825981021 + 0.3835909069 + 0.3845843971 + 0.3855786026 + 0.3865729868 + 0.3875676095 + 0.3885630965 + 0.3895589113 + 0.3905552030 + 0.3915528059 + 0.3925518990 + 0.3935522139 + 0.3945525885 + 0.3955546916 + 0.3965587914 + 0.3975653052 + 0.3985737860 + 0.3995841146 + 0.4005962908 + 0.4016096890 + 0.4026258886 + 0.4036448896 + 0.4046654999 + 0.4056873918 + 0.4067110121 + 0.4077360928 + 0.4087626040 + 0.4097931087 + 0.4108271897 + 0.4118641913 + 0.4129031003 + 0.4139435887 + 0.4149853885 + 0.4160276055 + 0.4170711040 + 0.4181162119 + 0.4191623926 + 0.4202099144 + 0.4212583899 + 0.4223065972 + 0.4233539999 + 0.4244020879 + 0.4254502952 + 0.4264976084 + 0.4275454879 + 0.4285939932 + 0.4296421111 + 0.4306895137 + 0.4317376912 + 0.4327858984 + 0.4338330925 + 0.4348810017 + 0.4359295964 + 0.4369775951 + 0.4380249977 + 0.4390732050 + 0.4401214123 + 0.4411686063 + 0.4422164857 + 0.4432651997 + 0.4443131089 + 0.4453606009 + 0.4464088082 + 0.4474568963 + 0.4485040903 + 0.4495520890 + 0.4506008029 + 0.4516485929 + 0.4526961148 + 0.4537442923 + 0.4547924101 + 0.4558396041 + 0.4568876028 + 0.4579362869 + 0.4589839876 + 0.4600316882 + 0.4610798061 + 0.4621278942 + 0.4631750882 + 0.4642232060 + 0.4652718902 + 0.4663195014 + 0.4673672020 + 0.4684154093 + 0.4694634080 + 0.4705106914 + 0.4715586901 + 0.4726074934 + 0.4736549854 + 0.4747028053 + 0.4757508934 + 0.4767988920 + 0.4778462052 + 0.4788942039 + 0.4799430966 + 0.4809904993 + 0.4820382893 + 0.4830864966 + 0.4841342866 + 0.4851816893 + 0.4862298071 + 0.4872786999 + 0.4883260131 + 0.4893738031 + 0.4904220104 + 0.4914698005 + 0.4925172925 + 0.4935654104 + 0.4946143031 + 0.4956614971 + 0.4967094064 + 0.4977576137 + 0.4988053143 + 0.4998528063 + 0.5009009838 + 0.5019497871 + 0.5029969215 + 0.5040448904 + 0.5050930977 + 0.5061408281 + 0.5071883202 + 0.5082365870 + 0.5092852712 + 0.5103324056 + 0.5113804936 + 0.5124287009 + 0.5134763122 + 0.5145239234 + 0.5155721903 + 0.5166208148 + 0.5176678896 + 0.5187159777 + 0.5197641850 + 0.5208117962 + 0.5218594074 + 0.5229076743 + 0.5239562988 + 0.5250033736 + 0.5260515809 + 0.5270997882 + 0.5281472802 + 0.5291950107 + 0.5302432775 + 0.5312917829 + 0.5323389769 + 0.5333871245 + 0.5344352722 + 0.5354828238 + 0.5365304947 + 0.5375788808 + 0.5386273265 + 0.5396745205 + 0.5407227278 + 0.5417708755 + 0.5428183079 + 0.5438659787 + 0.5449144840 + 0.5459626913 + 0.5470100045 + 0.5480582118 + 0.5491064191 + 0.5501537919 + 0.5512015820 + 0.5522500873 + 0.5532981753 + 0.5543456078 + 0.5553936958 + 0.5564420223 + 0.5574892759 + 0.5585371256 + 0.5595856905 + 0.5606337190 + 0.5616810918 + 0.5627292991 + 0.5637775064 + 0.5648247004 + 0.5658726096 + 0.5669211745 + 0.5679692030 + 0.5690163970 + 0.5700634122 + 0.5711091757 + 0.5721533895 + 0.5731964707 + 0.5742384791 + 0.5752782226 + 0.5763154030 + 0.5773493052 + 0.5783768892 + 0.5793967247 + 0.5804104805 + 0.5814169049 + 0.5824149251 + 0.5834047794 + 0.5843868852 + 0.5853602290 + 0.5863254070 + 0.5872825980 + 0.5882346034 + 0.5891796947 + 0.5901175141 + 0.5910484195 + 0.5919718146 + 0.5928866863 + 0.5937936902 + 0.5946958065 + 0.5955929160 + 0.5964863896 + 0.5973765254 + 0.5982630849 + 0.5991474986 + 0.6000298262 + 0.6009125710 + 0.6017950773 + 0.6026778221 + 0.6035615206 + 0.6044462919 + 0.6053317189 + 0.6062173843 + 0.6071026921 + 0.6079885960 + 0.6088755727 + 0.6097620726 + 0.6106479764 + 0.6115351915 + 0.6124256849 + 0.6133217216 + 0.6142216921 + 0.6151272058 + 0.6160376072 + 0.6169527173 + 0.6178737283 + 0.6188027263 + 0.6197397113 + 0.6206821203 + 0.6216303110 + 0.6225833893 + 0.6235426068 + 0.6245095134 + 0.6254850030 + 0.6264699101 + 0.6274635792 + 0.6284654737 + 0.6294741035 + 0.6304889917 + 0.6315106750 + 0.6325399280 + 0.6335754991 + 0.6346142292 + 0.6356559992 + 0.6366981864 + 0.6377419233 + 0.6387875080 + 0.6398347020 + 0.6408823729 + 0.6419299841 + 0.6429790854 + 0.6440268755 + 0.6450746059 + 0.6461223960 + 0.6471703053 + 0.6482179761 + 0.6492655277 + 0.6503146887 + 0.6513624191 + 0.6524100900 + 0.6534578800 + 0.6545057893 + 0.6555535197 + 0.6566010714 + 0.6576502919 + 0.6586980224 + 0.6597455740 + 0.6607934833 + 0.6618412733 + 0.6628890038 + 0.6639366746 + 0.6649858952 + 0.6660335064 + 0.6670811772 + 0.6681290269 + 0.6691768169 + 0.6702244878 + 0.6712722778 + 0.6723213792 + 0.6733689904 + 0.6744167209 + 0.6754645109 + 0.6765123010 + 0.6775599718 + 0.6786078811 + 0.6796569228 + 0.6807044744 + 0.6817513704 + 0.6827965975 + 0.6838402748 + 0.6848834753 + 0.6859273911 + 0.6869723797 + 0.6880162954 + 0.6890599728 + 0.6901013255 + 0.6911396980 + 0.6921761036 + 0.6932122111 + 0.6942487955 + 0.6952843070 + 0.6963180900 + 0.6973488927 + 0.6983770728 + 0.6994026899 + 0.7004272938 + 0.7014517188 + 0.7024747133 + 0.7034965158 + 0.7045164704 + 0.7055342793 + 0.7065513730 + 0.7075693011 + 0.7085878849 + 0.7096056938 + 0.7106239200 + 0.7116401792 + 0.7126544118 + 0.7136672139 + 0.7146797776 + 0.7156928778 + 0.7167074084 + 0.7177237272 + 0.7187396884 + 0.7197557092 + 0.7207708955 + 0.7217856050 + 0.7227994204 + 0.7238122225 + 0.7248240113 + 0.7258350253 + 0.7268440127 + 0.7278503776 + 0.7288548946 + 0.7298564911 + 0.7308545709 + 0.7318491936 + 0.7328398228 + 0.7338244915 + 0.7348057032 + 0.7357832789 + 0.7367560267 + 0.7377241850 + 0.7386888862 + 0.7396495938 + 0.7406045794 + 0.7415547967 + 0.7425006032 + 0.7434419990 + 0.7443798780 + 0.7453150749 + 0.7462481856 + 0.7471804023 + 0.7481107712 + 0.7490395904 + 0.7499657869 + 0.7508903742 + 0.7518150210 + 0.7527397871 + 0.7536643744 + 0.7545883060 + 0.7555134296 + 0.7564398050 + 0.7573670149 + 0.7582947016 + 0.7592232227 + 0.7601537108 + 0.7610865235 + 0.7620201111 + 0.7629551888 + 0.7638924122 + 0.7648314238 + 0.7657712102 + 0.7667114735 + 0.7676535845 + 0.7685970068 + 0.7695416212 + 0.7704880238 + 0.7714353204 + 0.7723832130 + 0.7733322978 + 0.7742838264 + 0.7752370238 + 0.7761909962 + 0.7771469951 + 0.7781038880 + 0.7790613770 + 0.7800198793 + 0.7809798121 + 0.7819411755 + 0.7829020023 + 0.7838628888 + 0.7848243117 + 0.7857862115 + 0.7867478132 + 0.7877084017 + 0.7886680961 + 0.7896274924 + 0.7905864716 + 0.7915449142 + 0.7925025225 + 0.7934594154 + 0.7944151759 + 0.7953701019 + 0.7963243127 + 0.7972785234 + 0.7982317209 + 0.7991852760 + 0.8001390100 + 0.8010920286 + 0.8020442128 + 0.8029962182 + 0.8039492965 + 0.8049013019 + 0.8058534861 + 0.8068069220 + 0.8077614903 + 0.8087171912 + 0.8096737266 + 0.8106310964 + 0.8115898967 + 0.8125504851 + 0.8135117292 + 0.8144730926 + 0.8154355288 + 0.8163995743 + 0.8173645139 + 0.8183292150 + 0.8192948103 + 0.8202611208 + 0.8212277889 + 0.8221948743 + 0.8231617808 + 0.8241283894 + 0.8250942826 + 0.8260607123 + 0.8270269036 + 0.8279932737 + 0.8289610147 + 0.8299307227 + 0.8309032917 + 0.8318769932 + 0.8328524828 + 0.8338282704 + 0.8348054886 + 0.8357861042 + 0.8367711902 + 0.8377606273 + 0.8387532234 + 0.8397489190 + 0.8407462239 + 0.8417472839 + 0.8427532911 + 0.8437641859 + 0.8447790146 + 0.8457974195 + 0.8468207717 + 0.8478456736 + 0.8488733768 + 0.8499053717 + 0.8509420156 + 0.8519824147 + 0.8530250788 + 0.8540698290 + 0.8551142812 + 0.8561593294 + 0.8572056293 + 0.8582528830 + 0.8593006134 + 0.8603482842 + 0.8613973856 + 0.8624451160 + 0.8634920716 + 0.8645371199 + 0.8655791283 + 0.8666179776 + 0.8676548004 + 0.8686900735 + 0.8697226048 + 0.8707528710 + 0.8717787862 + 0.8727999926 + 0.8738167882 + 0.8748298287 + 0.8758404255 + 0.8768457770 + 0.8778470755 + 0.8788424730 + 0.8798323870 + 0.8808172941 + 0.8817983866 + 0.8827769756 + 0.8837512732 + 0.8847230077 + 0.8856912255 + 0.8866552711 + 0.8876156807 + 0.8885743022 + 0.8895329833 + 0.8904910088 + 0.8914486766 + 0.8924050927 + 0.8933603764 + 0.8943151832 + 0.8952693939 + 0.8962222934 + 0.8971732855 + 0.8981227875 + 0.8990685940 + 0.9000113010 + 0.9009503126 + 0.9018849134 + 0.9028136134 + 0.9037343860 + 0.9046463966 + 0.9055463076 + 0.9064350128 + 0.9073122144 + 0.9081791043 + 0.9090356827 + 0.9098809958 + 0.9107148051 + 0.9115344882 + 0.9123430252 + 0.9131417871 + 0.9139323235 + 0.9147145152 + 0.9154878259 + 0.9162527919 + 0.9170091748 + 0.9177588224 + 0.9185020924 + 0.9192394018 + 0.9199714065 + 0.9206994176 + 0.9214246869 + 0.9221466780 + 0.9228668809 + 0.9235867262 + 0.9243060946 + 0.9250255823 + 0.9257463217 + 0.9264692068 + 0.9271945953 + 0.9279209971 + 0.9286499023 + 0.9293829203 + 0.9301195741 + 0.9308602214 + 0.9316061139 + 0.9323577285 + 0.9331133962 + 0.9338728786 + 0.9346380830 + 0.9354091287 + 0.9361863136 + 0.9369704127 + 0.9377611279 + 0.9385566115 + 0.9393566251 + 0.9401628971 + 0.9409751892 + 0.9417932034 + 0.9426162839 + 0.9434437156 + 0.9442740083 + 0.9451068044 + 0.9459424019 + 0.9467787147 + 0.9476162195 + 0.9484547973 + 0.9492936134 + 0.9501317143 + 0.9509698153 + 0.9518089294 + 0.9526466727 + 0.9534838200 + 0.9543187022 + 0.9551491737 + 0.9559733272 + 0.9567909241 + 0.9575985074 + 0.9583951831 + 0.9591814876 + 0.9599570036 + 0.9607214928 + 0.9614744782 + 0.9622160196 + 0.9629415870 + 0.9636477828 + 0.9643381238 + 0.9650136828 + 0.9656763077 + 0.9663271904 + 0.9669669271 + 0.9675945044 + 0.9682068825 + 0.9688068032 + 0.9693955779 + 0.9699755907 + 0.9705489278 + 0.9711167216 + 0.9716787934 + 0.9722322226 + 0.9727811813 + 0.9733269215 + 0.9738715291 + 0.9744166136 + 0.9749621153 + 0.9755073190 + 0.9760522246 + 0.9765970707 + 0.9771423936 + 0.9776893854 + 0.9782382250 + 0.9787877202 + 0.9793367982 + 0.9798851013 + 0.9804323912 + 0.9809777737 + 0.9815199971 + 0.9820588231 + 0.9825943708 + 0.9831265211 + 0.9836531281 + 0.9841737151 + 0.9846891761 + 0.9851980805 + 0.9857000709 + 0.9861956239 + 0.9866847992 + 0.9871674180 + 0.9876440167 + 0.9881147146 + 0.9885799289 + 0.9890390038 + 0.9894917011 + 0.9899380803 + 0.9903783798 + 0.9908131957 + 0.9912436008 + 0.9916706085 + 0.9920943975 + 0.9925168157 + 0.9929386973 + 0.9933599234 + 0.9937797189 + 0.9941993952 + 0.9946184158 + 0.9950373173 + 0.9954559803 + 0.9958732724 + 0.9962888956 + 0.9967045188 + 0.9971199036 + 0.9975342751 + 0.9979482293 + 0.9983612895 + 0.9987732172 + 0.9991837740 + 0.9995930195 + 1.0000000000 +} diff --git a/rpplugins/color_correction/resources/film_luts_raw/kodak_kai-0372.spi1d b/rpplugins/color_correction/resources/film_luts_raw/kodak_kai-0372.spi1d new file mode 100644 index 0000000..11eae36 --- /dev/null +++ b/rpplugins/color_correction/resources/film_luts_raw/kodak_kai-0372.spi1d @@ -0,0 +1,1030 @@ +Version 1 +From 0.0 1.0 +Length 1024 +Components 1 +{ + 0.0000000000 + 0.0014187270 + 0.0028485169 + 0.0042931479 + 0.0057487562 + 0.0072099129 + 0.0086716842 + 0.0101303104 + 0.0115825599 + 0.0130244503 + 0.0144514600 + 0.0158604495 + 0.0172503907 + 0.0186199509 + 0.0199686904 + 0.0212968104 + 0.0226029102 + 0.0238885507 + 0.0251513291 + 0.0263916291 + 0.0276103709 + 0.0288079195 + 0.0299857892 + 0.0311455000 + 0.0322885215 + 0.0334165096 + 0.0345297195 + 0.0356270298 + 0.0367095582 + 0.0377803184 + 0.0388391204 + 0.0398863591 + 0.0409265012 + 0.0419625007 + 0.0429961495 + 0.0440296903 + 0.0450651906 + 0.0461052805 + 0.0471526794 + 0.0482083187 + 0.0492714494 + 0.0503420308 + 0.0514214598 + 0.0525106192 + 0.0536095686 + 0.0547187701 + 0.0558380783 + 0.0569689386 + 0.0581119917 + 0.0592671484 + 0.0604341701 + 0.0616126209 + 0.0628031567 + 0.0640061498 + 0.0652208924 + 0.0664469600 + 0.0676843375 + 0.0689309686 + 0.0701846108 + 0.0714438409 + 0.0727065727 + 0.0739705265 + 0.0752329826 + 0.0764907077 + 0.0777410120 + 0.0789828077 + 0.0802149475 + 0.0814361572 + 0.0826453418 + 0.0838416368 + 0.0850252435 + 0.0861970633 + 0.0873567313 + 0.0885045677 + 0.0896422267 + 0.0907687172 + 0.0918845534 + 0.0929897428 + 0.0940850228 + 0.0951717719 + 0.0962497294 + 0.0973178074 + 0.0983761922 + 0.0994268134 + 0.1004718989 + 0.1015126035 + 0.1025492996 + 0.1035822034 + 0.1046125963 + 0.1056426987 + 0.1066747978 + 0.1077087969 + 0.1087436005 + 0.1097813025 + 0.1108229011 + 0.1118687019 + 0.1129188985 + 0.1139732003 + 0.1150322035 + 0.1160956025 + 0.1171633974 + 0.1182366982 + 0.1193158031 + 0.1204013005 + 0.1214938983 + 0.1225937977 + 0.1236993000 + 0.1248105019 + 0.1259278059 + 0.1270509064 + 0.1281802952 + 0.1293144971 + 0.1304522008 + 0.1315927953 + 0.1327365935 + 0.1338832974 + 0.1350333989 + 0.1361864060 + 0.1373412013 + 0.1384979934 + 0.1396571994 + 0.1408192068 + 0.1419841945 + 0.1431522071 + 0.1443247050 + 0.1455022991 + 0.1466850936 + 0.1478727013 + 0.1490653008 + 0.1502631009 + 0.1514662057 + 0.1526743025 + 0.1538881063 + 0.1551087052 + 0.1563372016 + 0.1575720012 + 0.1588124931 + 0.1600576937 + 0.1613081992 + 0.1625638008 + 0.1638233066 + 0.1650867015 + 0.1663545072 + 0.1676256955 + 0.1688988060 + 0.1701712012 + 0.1714410037 + 0.1727070063 + 0.1739681065 + 0.1752225012 + 0.1764675975 + 0.1777033061 + 0.1789285988 + 0.1801432073 + 0.1813486964 + 0.1825450063 + 0.1837306023 + 0.1849053055 + 0.1860695928 + 0.1872238964 + 0.1883683056 + 0.1895032972 + 0.1906294972 + 0.1917479932 + 0.1928582937 + 0.1939616054 + 0.1950584054 + 0.1961483955 + 0.1972329021 + 0.1983121932 + 0.1993871927 + 0.2004588991 + 0.2015292943 + 0.2025997043 + 0.2036705017 + 0.2047414035 + 0.2058123052 + 0.2068836987 + 0.2079551965 + 0.2090263963 + 0.2100979984 + 0.2111708969 + 0.2122471929 + 0.2133263052 + 0.2144072950 + 0.2154909968 + 0.2165782005 + 0.2176689953 + 0.2187630981 + 0.2198591977 + 0.2209576964 + 0.2220599949 + 0.2231667042 + 0.2242773026 + 0.2253910005 + 0.2265066952 + 0.2276258022 + 0.2287493050 + 0.2298769057 + 0.2310086936 + 0.2321445048 + 0.2332839072 + 0.2344263941 + 0.2355709970 + 0.2367177010 + 0.2378668934 + 0.2390172035 + 0.2401686013 + 0.2413198054 + 0.2424692959 + 0.2436169982 + 0.2447617054 + 0.2459024042 + 0.2470397949 + 0.2481732070 + 0.2493015975 + 0.2504242957 + 0.2515400052 + 0.2526471913 + 0.2537457049 + 0.2548359036 + 0.2559179068 + 0.2569903135 + 0.2580535114 + 0.2591086030 + 0.2601554990 + 0.2611947060 + 0.2622261941 + 0.2632490993 + 0.2642633021 + 0.2652696073 + 0.2662687898 + 0.2672609985 + 0.2682465911 + 0.2692261040 + 0.2702012062 + 0.2711735070 + 0.2721416056 + 0.2731072903 + 0.2740713060 + 0.2750340104 + 0.2759960890 + 0.2769576907 + 0.2779189944 + 0.2788805068 + 0.2798438966 + 0.2808105946 + 0.2817816138 + 0.2827576995 + 0.2837403119 + 0.2847315073 + 0.2857330143 + 0.2867462039 + 0.2877714932 + 0.2888084948 + 0.2898587883 + 0.2909233868 + 0.2920028865 + 0.2930966914 + 0.2942047119 + 0.2953279912 + 0.2964681983 + 0.2976255119 + 0.2987984121 + 0.2999858856 + 0.3011890948 + 0.3024066985 + 0.3036352992 + 0.3048754930 + 0.3061271012 + 0.3073874116 + 0.3086515963 + 0.3099172115 + 0.3111822903 + 0.3124446869 + 0.3137021959 + 0.3149535060 + 0.3161973953 + 0.3174318075 + 0.3186556995 + 0.3198691010 + 0.3210715055 + 0.3222627044 + 0.3234440982 + 0.3246166110 + 0.3257783055 + 0.3269309998 + 0.3280749023 + 0.3292089999 + 0.3303337097 + 0.3314495981 + 0.3325574100 + 0.3336577117 + 0.3347519934 + 0.3358413875 + 0.3369264007 + 0.3380081058 + 0.3390851021 + 0.3401587903 + 0.3412316144 + 0.3423039913 + 0.3433766961 + 0.3444486856 + 0.3455202878 + 0.3465914130 + 0.3476617932 + 0.3487313986 + 0.3498007059 + 0.3508692086 + 0.3519366980 + 0.3530029953 + 0.3540687859 + 0.3551346064 + 0.3562012017 + 0.3572680950 + 0.3583359122 + 0.3594044149 + 0.3604733944 + 0.3615426123 + 0.3626110852 + 0.3636786044 + 0.3647457063 + 0.3658131063 + 0.3668813109 + 0.3679508865 + 0.3690212965 + 0.3700926006 + 0.3711653054 + 0.3722378910 + 0.3733103871 + 0.3743830025 + 0.3754549921 + 0.3765265942 + 0.3775976896 + 0.3786680102 + 0.3797375858 + 0.3808068037 + 0.3818753064 + 0.3829427958 + 0.3840090036 + 0.3850749135 + 0.3861418962 + 0.3872109056 + 0.3882800937 + 0.3893499076 + 0.3904218972 + 0.3914968073 + 0.3925746083 + 0.3936544955 + 0.3947367072 + 0.3958213925 + 0.3969092071 + 0.3980003893 + 0.3990949988 + 0.4001933932 + 0.4012970924 + 0.4024052918 + 0.4035159945 + 0.4046308994 + 0.4057500064 + 0.4068731964 + 0.4080010056 + 0.4091325998 + 0.4102680981 + 0.4114075899 + 0.4125505984 + 0.4136967063 + 0.4148448110 + 0.4159938991 + 0.4171437919 + 0.4182941914 + 0.4194458127 + 0.4205985963 + 0.4217509925 + 0.4229008853 + 0.4240474999 + 0.4251902997 + 0.4263280034 + 0.4274600148 + 0.4285857975 + 0.4297052026 + 0.4308179021 + 0.4319226146 + 0.4330177009 + 0.4341033101 + 0.4351783991 + 0.4362432957 + 0.4372982979 + 0.4383428991 + 0.4393776059 + 0.4404034913 + 0.4414204061 + 0.4424285889 + 0.4434289932 + 0.4444229007 + 0.4454112053 + 0.4463939071 + 0.4473721981 + 0.4483464062 + 0.4493157864 + 0.4502818882 + 0.4512456954 + 0.4522084892 + 0.4531711042 + 0.4541336894 + 0.4550961852 + 0.4560593963 + 0.4570237100 + 0.4579895139 + 0.4589586854 + 0.4599328041 + 0.4609122872 + 0.4618987143 + 0.4628936052 + 0.4638980031 + 0.4649139047 + 0.4659439027 + 0.4669868946 + 0.4680424035 + 0.4691106081 + 0.4701919854 + 0.4712862968 + 0.4723939002 + 0.4735164940 + 0.4746555984 + 0.4758110046 + 0.4769817889 + 0.4781683981 + 0.4793711007 + 0.4805893898 + 0.4818193913 + 0.4830603004 + 0.4843108952 + 0.4855696857 + 0.4868358970 + 0.4881083071 + 0.4893856049 + 0.4906665087 + 0.4919497073 + 0.4932326972 + 0.4945130944 + 0.4957897067 + 0.4970611036 + 0.4983257055 + 0.4995830953 + 0.5008316040 + 0.5020682216 + 0.5032951832 + 0.5045124292 + 0.5057162046 + 0.5069069862 + 0.5080850720 + 0.5092489123 + 0.5103979707 + 0.5115343928 + 0.5126597285 + 0.5137739182 + 0.5148767829 + 0.5159683228 + 0.5170493722 + 0.5181217790 + 0.5191835165 + 0.5202353001 + 0.5212790966 + 0.5223165751 + 0.5233479738 + 0.5243744254 + 0.5253980756 + 0.5264204144 + 0.5274419188 + 0.5284639001 + 0.5294873118 + 0.5305123925 + 0.5315392017 + 0.5325689912 + 0.5336017013 + 0.5346363187 + 0.5356730819 + 0.5367122293 + 0.5377532840 + 0.5387955904 + 0.5398390293 + 0.5408840179 + 0.5419310927 + 0.5429803729 + 0.5440319777 + 0.5450868011 + 0.5461450219 + 0.5472044945 + 0.5482643843 + 0.5493268967 + 0.5503926873 + 0.5514603257 + 0.5525295138 + 0.5535998940 + 0.5546712279 + 0.5557432771 + 0.5568156838 + 0.5578880906 + 0.5589600801 + 0.5600317717 + 0.5611037016 + 0.5621762276 + 0.5632488728 + 0.5643215775 + 0.5653941035 + 0.5664659739 + 0.5675367713 + 0.5686054826 + 0.5696707964 + 0.5707319975 + 0.5717889071 + 0.5728414059 + 0.5738887787 + 0.5749312043 + 0.5759691000 + 0.5770025849 + 0.5780308247 + 0.5790535808 + 0.5800703168 + 0.5810797811 + 0.5820823908 + 0.5830807090 + 0.5840756297 + 0.5850659013 + 0.5860515833 + 0.5870333910 + 0.5880113840 + 0.5889859200 + 0.5899571776 + 0.5909250975 + 0.5918905139 + 0.5928549767 + 0.5938175917 + 0.5947793126 + 0.5957412124 + 0.5967022181 + 0.5976634026 + 0.5986256003 + 0.5995882750 + 0.6005504727 + 0.6015123725 + 0.6024752855 + 0.6034411192 + 0.6044095755 + 0.6053802967 + 0.6063545942 + 0.6073334813 + 0.6083168983 + 0.6093050838 + 0.6102979183 + 0.6112931967 + 0.6122915149 + 0.6132950187 + 0.6143041849 + 0.6153184175 + 0.6163371205 + 0.6173605919 + 0.6183896065 + 0.6194241047 + 0.6204634905 + 0.6215072870 + 0.6225566268 + 0.6236104965 + 0.6246663928 + 0.6257253885 + 0.6267880201 + 0.6278533936 + 0.6289204955 + 0.6299880743 + 0.6310554743 + 0.6321223974 + 0.6331890821 + 0.6342563033 + 0.6353240013 + 0.6363924742 + 0.6374620795 + 0.6385326982 + 0.6396048069 + 0.6406791806 + 0.6417564750 + 0.6428371072 + 0.6439194083 + 0.6450036168 + 0.6460906863 + 0.6471815109 + 0.6482766867 + 0.6493766904 + 0.6504800916 + 0.6515864134 + 0.6526964903 + 0.6538105011 + 0.6549285054 + 0.6560505033 + 0.6571758986 + 0.6583045721 + 0.6594374180 + 0.6605746746 + 0.6617149115 + 0.6628565192 + 0.6639989018 + 0.6651424170 + 0.6662871838 + 0.6674332023 + 0.6685804129 + 0.6697282791 + 0.6708768010 + 0.6720256209 + 0.6731721759 + 0.6743155122 + 0.6754553914 + 0.6765918732 + 0.6777250171 + 0.6788529754 + 0.6799747944 + 0.6810904145 + 0.6821988225 + 0.6832993031 + 0.6843917966 + 0.6854761839 + 0.6865515113 + 0.6876170039 + 0.6886734962 + 0.6897208095 + 0.6907575727 + 0.6917873025 + 0.6928105950 + 0.6938270926 + 0.6948360205 + 0.6958370209 + 0.6968308091 + 0.6978185773 + 0.6988012791 + 0.6997786760 + 0.7007514834 + 0.7017211914 + 0.7026876807 + 0.7036520243 + 0.7046157122 + 0.7055789828 + 0.7065418959 + 0.7075042725 + 0.7084662914 + 0.7094286084 + 0.7103922963 + 0.7113580704 + 0.7123268843 + 0.7132992744 + 0.7142757773 + 0.7152578831 + 0.7162470222 + 0.7172421813 + 0.7182437181 + 0.7192531824 + 0.7202717066 + 0.7212985754 + 0.7223340273 + 0.7233784199 + 0.7244324088 + 0.7254965901 + 0.7265704274 + 0.7276533246 + 0.7287458181 + 0.7298483849 + 0.7309604883 + 0.7320820093 + 0.7332108021 + 0.7343450189 + 0.7354853153 + 0.7366309166 + 0.7377815247 + 0.7389364839 + 0.7400947213 + 0.7412542105 + 0.7424135208 + 0.7435715199 + 0.7447264194 + 0.7458763719 + 0.7470207214 + 0.7481592894 + 0.7492917776 + 0.7504174113 + 0.7515341043 + 0.7526403069 + 0.7537366748 + 0.7548218966 + 0.7558972239 + 0.7569634914 + 0.7580205798 + 0.7590687275 + 0.7601084113 + 0.7611390948 + 0.7621600032 + 0.7631716728 + 0.7641760707 + 0.7651739717 + 0.7661651969 + 0.7671486735 + 0.7681260109 + 0.7690988183 + 0.7700666189 + 0.7710312009 + 0.7719941735 + 0.7729566097 + 0.7739174962 + 0.7748776078 + 0.7758383155 + 0.7767999768 + 0.7777621150 + 0.7787244916 + 0.7796872258 + 0.7806501985 + 0.7816135883 + 0.7825772762 + 0.7835413218 + 0.7845047116 + 0.7854663730 + 0.7864274979 + 0.7873893976 + 0.7883517742 + 0.7893143296 + 0.7902770042 + 0.7912396193 + 0.7922011018 + 0.7931612134 + 0.7941213846 + 0.7950831056 + 0.7960450053 + 0.7970073223 + 0.7979699969 + 0.7989329100 + 0.7998961806 + 0.8008598089 + 0.8018236756 + 0.8027874231 + 0.8037496805 + 0.8047108054 + 0.8056722879 + 0.8066347241 + 0.8075972199 + 0.8085597754 + 0.8095226288 + 0.8104845881 + 0.8114448190 + 0.8124048710 + 0.8133671284 + 0.8143309951 + 0.8152961731 + 0.8162639141 + 0.8172360063 + 0.8182134032 + 0.8191961050 + 0.8201839924 + 0.8211780787 + 0.8221784234 + 0.8231853843 + 0.8242005110 + 0.8252243996 + 0.8262565136 + 0.8272976875 + 0.8283491135 + 0.8294097185 + 0.8304784894 + 0.8315557837 + 0.8326426744 + 0.8337395787 + 0.8348457217 + 0.8359597921 + 0.8370814919 + 0.8382107019 + 0.8393465281 + 0.8404887915 + 0.8416360021 + 0.8427860141 + 0.8439379930 + 0.8450908065 + 0.8462439775 + 0.8473960161 + 0.8485453725 + 0.8496916890 + 0.8508347273 + 0.8519737124 + 0.8531072140 + 0.8542333841 + 0.8553516269 + 0.8564621210 + 0.8575645089 + 0.8586577177 + 0.8597412109 + 0.8608148098 + 0.8618785143 + 0.8629317284 + 0.8639749885 + 0.8650091290 + 0.8660346270 + 0.8670523167 + 0.8680629730 + 0.8690673709 + 0.8700646162 + 0.8710550070 + 0.8720393777 + 0.8730176091 + 0.8739910126 + 0.8749604225 + 0.8759278059 + 0.8768939972 + 0.8778584003 + 0.8788213134 + 0.8797836900 + 0.8807460070 + 0.8817077279 + 0.8826689720 + 0.8836311102 + 0.8845937848 + 0.8855553865 + 0.8865150809 + 0.8874728084 + 0.8884277940 + 0.8893800974 + 0.8903309107 + 0.8912788033 + 0.8922230005 + 0.8931636810 + 0.8941028714 + 0.8950411081 + 0.8959773779 + 0.8969107866 + 0.8978416920 + 0.8987693787 + 0.8996942043 + 0.9006167054 + 0.9015371799 + 0.9024555087 + 0.9033702016 + 0.9042806029 + 0.9051871896 + 0.9060915709 + 0.9069947004 + 0.9078966975 + 0.9087975025 + 0.9096974730 + 0.9105958939 + 0.9114922881 + 0.9123886228 + 0.9132850766 + 0.9141798019 + 0.9150691032 + 0.9159536958 + 0.9168338180 + 0.9177089930 + 0.9185785055 + 0.9194408059 + 0.9202948809 + 0.9211413264 + 0.9219813943 + 0.9228157997 + 0.9236447215 + 0.9244682193 + 0.9252852798 + 0.9260939956 + 0.9268960953 + 0.9276924133 + 0.9284831285 + 0.9292683005 + 0.9300467968 + 0.9308174849 + 0.9315804839 + 0.9323381186 + 0.9330930114 + 0.9338461757 + 0.9345973730 + 0.9353471994 + 0.9360958934 + 0.9368441105 + 0.9375926256 + 0.9383410811 + 0.9390903115 + 0.9398398995 + 0.9405894279 + 0.9413390756 + 0.9420892000 + 0.9428393245 + 0.9435886741 + 0.9443354011 + 0.9450780153 + 0.9458169937 + 0.9465532899 + 0.9472861886 + 0.9480143785 + 0.9487375021 + 0.9494557977 + 0.9501700997 + 0.9508795142 + 0.9515821934 + 0.9522789717 + 0.9529712796 + 0.9536584020 + 0.9543386102 + 0.9550122023 + 0.9556815028 + 0.9563481808 + 0.9570119977 + 0.9576709867 + 0.9583243728 + 0.9589740038 + 0.9596223235 + 0.9602677822 + 0.9609097242 + 0.9615486264 + 0.9621847272 + 0.9628177285 + 0.9634479284 + 0.9640747905 + 0.9646962881 + 0.9653108716 + 0.9659178257 + 0.9665163755 + 0.9671065211 + 0.9676873088 + 0.9682564139 + 0.9688133001 + 0.9693595767 + 0.9698956013 + 0.9704216719 + 0.9709377885 + 0.9714441895 + 0.9719427228 + 0.9724339247 + 0.9729166031 + 0.9733896852 + 0.9738553166 + 0.9743154049 + 0.9747707248 + 0.9752202034 + 0.9756631851 + 0.9761012197 + 0.9765369296 + 0.9769701958 + 0.9774006009 + 0.9778288007 + 0.9782562256 + 0.9786834121 + 0.9791104794 + 0.9795380831 + 0.9799662828 + 0.9803938866 + 0.9808201194 + 0.9812436104 + 0.9816619754 + 0.9820752144 + 0.9824826717 + 0.9828830957 + 0.9832751155 + 0.9836578965 + 0.9840303063 + 0.9843910933 + 0.9847406745 + 0.9850798845 + 0.9854090214 + 0.9857276082 + 0.9860363007 + 0.9863356948 + 0.9866275191 + 0.9869117141 + 0.9871860147 + 0.9874522090 + 0.9877108932 + 0.9879605770 + 0.9882022738 + 0.9884371161 + 0.9886657000 + 0.9888893962 + 0.9891092777 + 0.9893258214 + 0.9895405769 + 0.9897546768 + 0.9899684191 + 0.9901812077 + 0.9903942943 + 0.9906080961 + 0.9908217788 + 0.9910365939 + 0.9912521243 + 0.9914677143 + 0.9916833043 + 0.9918984771 + 0.9921129942 + 0.9923266172 + 0.9925395846 + 0.9927518964 + 0.9929633737 + 0.9931753278 + 0.9933875799 + 0.9935998917 + 0.9938135147 + 0.9940276146 + 0.9942417741 + 0.9944561124 + 0.9946699739 + 0.9948837757 + 0.9950978160 + 0.9953122139 + 0.9955270886 + 0.9957417846 + 0.9959560037 + 0.9961696267 + 0.9963824153 + 0.9965956211 + 0.9968093038 + 0.9970229864 + 0.9972379208 + 0.9974533916 + 0.9976689816 + 0.9978845716 + 0.9980998039 + 0.9983143210 + 0.9985278249 + 0.9987403750 + 0.9989517927 + 0.9991620183 + 0.9993718863 + 0.9995810986 + 0.9997903705 + 1.0000000000 +} diff --git a/rpplugins/color_correction/resources/film_luts_raw/kodak_kai-1010.spi1d b/rpplugins/color_correction/resources/film_luts_raw/kodak_kai-1010.spi1d new file mode 100644 index 0000000..8fb1df7 --- /dev/null +++ b/rpplugins/color_correction/resources/film_luts_raw/kodak_kai-1010.spi1d @@ -0,0 +1,1030 @@ +Version 1 +From 0.0 1.0 +Length 1024 +Components 1 +{ + 0.0000000000 + 0.0015970930 + 0.0032108270 + 0.0048384252 + 0.0064732390 + 0.0081081763 + 0.0097375941 + 0.0113548804 + 0.0129528800 + 0.0145261399 + 0.0160703696 + 0.0175831709 + 0.0190630294 + 0.0205102507 + 0.0219259299 + 0.0233127493 + 0.0246715993 + 0.0260010492 + 0.0272994898 + 0.0285670608 + 0.0298028998 + 0.0310098194 + 0.0321902186 + 0.0333435684 + 0.0344703794 + 0.0355738886 + 0.0366554409 + 0.0377166718 + 0.0387589782 + 0.0397843607 + 0.0407951698 + 0.0417945310 + 0.0427865982 + 0.0437750705 + 0.0447619408 + 0.0457485691 + 0.0467366986 + 0.0477271006 + 0.0487186685 + 0.0497123487 + 0.0507081710 + 0.0517065898 + 0.0527076609 + 0.0537111685 + 0.0547169782 + 0.0557249896 + 0.0567362607 + 0.0577516407 + 0.0587707087 + 0.0597942285 + 0.0608223192 + 0.0618541911 + 0.0628895611 + 0.0639279112 + 0.0649689585 + 0.0660121813 + 0.0670581907 + 0.0681073666 + 0.0691590682 + 0.0702132285 + 0.0712696612 + 0.0723281205 + 0.0733884126 + 0.0744497478 + 0.0755119175 + 0.0765746608 + 0.0776376799 + 0.0787018836 + 0.0797673315 + 0.0808331519 + 0.0818990618 + 0.0829651132 + 0.0840317011 + 0.0850984082 + 0.0861652717 + 0.0872325823 + 0.0882994309 + 0.0893664882 + 0.0904344097 + 0.0915023014 + 0.0925698727 + 0.0936371982 + 0.0947050005 + 0.0957735702 + 0.0968423486 + 0.0979111120 + 0.0989789367 + 0.1000462994 + 0.1011143997 + 0.1021834984 + 0.1032544971 + 0.1043291986 + 0.1054088995 + 0.1064950973 + 0.1075880006 + 0.1086886004 + 0.1097972989 + 0.1109144986 + 0.1120416969 + 0.1131796017 + 0.1143285036 + 0.1154886037 + 0.1166604012 + 0.1178442016 + 0.1190397963 + 0.1202476025 + 0.1214689016 + 0.1227027997 + 0.1239494979 + 0.1252094954 + 0.1264819056 + 0.1277655959 + 0.1290591955 + 0.1303616017 + 0.1316712052 + 0.1329866052 + 0.1343073994 + 0.1356315017 + 0.1369580030 + 0.1382858008 + 0.1396144927 + 0.1409430057 + 0.1422718018 + 0.1436003000 + 0.1449290067 + 0.1462575048 + 0.1475863010 + 0.1489147991 + 0.1502435058 + 0.1515720040 + 0.1529008001 + 0.1542291939 + 0.1555580050 + 0.1568865031 + 0.1582152992 + 0.1595436931 + 0.1608725041 + 0.1622010022 + 0.1635297984 + 0.1648582071 + 0.1661870033 + 0.1675153971 + 0.1688434035 + 0.1701688021 + 0.1714915931 + 0.1728098989 + 0.1741224974 + 0.1754271984 + 0.1767227948 + 0.1780070066 + 0.1792788059 + 0.1805343926 + 0.1817727983 + 0.1829933971 + 0.1841960996 + 0.1853809059 + 0.1865482926 + 0.1876983047 + 0.1888300031 + 0.1899435073 + 0.1910407990 + 0.1921222061 + 0.1931896061 + 0.1942428052 + 0.1952829063 + 0.1963098943 + 0.1973251998 + 0.1983291954 + 0.1993234009 + 0.2003085017 + 0.2012864053 + 0.2022587955 + 0.2032283992 + 0.2041957974 + 0.2051616013 + 0.2061273009 + 0.2070931047 + 0.2080595940 + 0.2090270072 + 0.2099955976 + 0.2109649032 + 0.2119348943 + 0.2129058987 + 0.2138797939 + 0.2148582041 + 0.2158416957 + 0.2168301046 + 0.2178225964 + 0.2188192010 + 0.2198204994 + 0.2208279073 + 0.2218416035 + 0.2228616029 + 0.2238875031 + 0.2249186039 + 0.2259557992 + 0.2269994020 + 0.2280489057 + 0.2291045040 + 0.2301660031 + 0.2312328964 + 0.2323053926 + 0.2333831042 + 0.2344655991 + 0.2355525047 + 0.2366431057 + 0.2377368063 + 0.2388329953 + 0.2399305999 + 0.2410296053 + 0.2421302944 + 0.2432314008 + 0.2443311065 + 0.2454299033 + 0.2465299964 + 0.2476332933 + 0.2487404048 + 0.2498511970 + 0.2509643137 + 0.2520790994 + 0.2531974018 + 0.2543210089 + 0.2554507852 + 0.2565864921 + 0.2577267885 + 0.2588709891 + 0.2600202858 + 0.2611759901 + 0.2623381019 + 0.2635067105 + 0.2646813989 + 0.2658607960 + 0.2670449913 + 0.2682338953 + 0.2694280148 + 0.2706277072 + 0.2718321085 + 0.2730394900 + 0.2742492855 + 0.2754603922 + 0.2766728103 + 0.2778874040 + 0.2791036963 + 0.2803192139 + 0.2815321982 + 0.2827436030 + 0.2839539051 + 0.2851620913 + 0.2863675058 + 0.2875689864 + 0.2887648046 + 0.2899549007 + 0.2911390960 + 0.2923170924 + 0.2934887111 + 0.2946529090 + 0.2958090901 + 0.2969568968 + 0.2980965972 + 0.2992289066 + 0.3003537953 + 0.3014717996 + 0.3025816977 + 0.3036831915 + 0.3047770858 + 0.3058654070 + 0.3069495857 + 0.3080292046 + 0.3091028929 + 0.3101705909 + 0.3112339079 + 0.3122943938 + 0.3133535087 + 0.3144116104 + 0.3154678941 + 0.3165228963 + 0.3175787926 + 0.3186368942 + 0.3196958899 + 0.3207564056 + 0.3218187094 + 0.3228828907 + 0.3239508867 + 0.3250220120 + 0.3260951936 + 0.3271706104 + 0.3282474875 + 0.3293263912 + 0.3304072917 + 0.3314906955 + 0.3325760067 + 0.3336637020 + 0.3347538114 + 0.3358460069 + 0.3369395137 + 0.3380326927 + 0.3391278088 + 0.3402253985 + 0.3413242996 + 0.3424232900 + 0.3435212970 + 0.3446190953 + 0.3457185030 + 0.3468185961 + 0.3479177952 + 0.3490158916 + 0.3501127958 + 0.3512093127 + 0.3523041010 + 0.3533973098 + 0.3544895947 + 0.3555799127 + 0.3566688895 + 0.3577584922 + 0.3588475883 + 0.3599354923 + 0.3610216081 + 0.3621057868 + 0.3631885946 + 0.3642696142 + 0.3653489947 + 0.3664267957 + 0.3675036132 + 0.3685795963 + 0.3696550131 + 0.3707289100 + 0.3718005121 + 0.3728711009 + 0.3739413917 + 0.3750106096 + 0.3760792017 + 0.3771468997 + 0.3782134950 + 0.3792808056 + 0.3803485930 + 0.3814165890 + 0.3824853003 + 0.3835538924 + 0.3846215010 + 0.3856872022 + 0.3867521882 + 0.3878181875 + 0.3888849020 + 0.3899520934 + 0.3910199106 + 0.3920885026 + 0.3931584954 + 0.3942297995 + 0.3953022957 + 0.3963758051 + 0.3974499106 + 0.3985247016 + 0.3996005952 + 0.4006777108 + 0.4017564952 + 0.4028376937 + 0.4039207101 + 0.4050048888 + 0.4060907960 + 0.4071780145 + 0.4082660973 + 0.4093562067 + 0.4104484916 + 0.4115422070 + 0.4126375020 + 0.4137335122 + 0.4148307145 + 0.4159297049 + 0.4170301855 + 0.4181306064 + 0.4192298055 + 0.4203279912 + 0.4214271009 + 0.4225274920 + 0.4236279130 + 0.4247274995 + 0.4258260131 + 0.4269242883 + 0.4280230105 + 0.4291217029 + 0.4302200079 + 0.4313178957 + 0.4324154854 + 0.4335126877 + 0.4346086085 + 0.4357028902 + 0.4367968142 + 0.4378911853 + 0.4389862120 + 0.4400813878 + 0.4411762953 + 0.4422703981 + 0.4433647990 + 0.4444605112 + 0.4455575943 + 0.4466555119 + 0.4477527142 + 0.4488491118 + 0.4499464929 + 0.4510458112 + 0.4521470070 + 0.4532484114 + 0.4543491900 + 0.4554497004 + 0.4565511048 + 0.4576537907 + 0.4587570131 + 0.4598602057 + 0.4609631896 + 0.4620659947 + 0.4631690979 + 0.4642724097 + 0.4653758109 + 0.4664795995 + 0.4675835967 + 0.4686864913 + 0.4697881043 + 0.4708893895 + 0.4719910920 + 0.4730935991 + 0.4741966128 + 0.4752987921 + 0.4763998985 + 0.4775001109 + 0.4785997868 + 0.4797008038 + 0.4808028042 + 0.4819043875 + 0.4830043018 + 0.4841024876 + 0.4852007926 + 0.4863008857 + 0.4874025881 + 0.4885045886 + 0.4896053970 + 0.4907051027 + 0.4918052852 + 0.4929065108 + 0.4940088987 + 0.4951120019 + 0.4962143004 + 0.4973159134 + 0.4984172881 + 0.4995189011 + 0.5006219745 + 0.5017260909 + 0.5028306842 + 0.5039374232 + 0.5050470233 + 0.5061581731 + 0.5072711706 + 0.5083870292 + 0.5095049739 + 0.5106257796 + 0.5117477775 + 0.5128695965 + 0.5139923096 + 0.5151175261 + 0.5162450075 + 0.5173735023 + 0.5185019970 + 0.5196316242 + 0.5207641125 + 0.5218989849 + 0.5230355859 + 0.5241733193 + 0.5253111720 + 0.5264499187 + 0.5275893807 + 0.5287293792 + 0.5298690200 + 0.5310084820 + 0.5321471095 + 0.5332846045 + 0.5344207883 + 0.5355551839 + 0.5366871953 + 0.5378178954 + 0.5389484763 + 0.5400791168 + 0.5412082076 + 0.5423350930 + 0.5434600115 + 0.5445839763 + 0.5457080007 + 0.5468308926 + 0.5479511023 + 0.5490679741 + 0.5501825213 + 0.5512952805 + 0.5524055958 + 0.5535135269 + 0.5546203852 + 0.5557265282 + 0.5568308234 + 0.5579332709 + 0.5590345860 + 0.5601357222 + 0.5612370968 + 0.5623382926 + 0.5634381175 + 0.5645357966 + 0.5656321049 + 0.5667272210 + 0.5678204894 + 0.5689107776 + 0.5699964166 + 0.5710760951 + 0.5721501112 + 0.5732188821 + 0.5742821097 + 0.5753387213 + 0.5763881803 + 0.5774298906 + 0.5784643292 + 0.5794925094 + 0.5805140138 + 0.5815274119 + 0.5825325847 + 0.5835304260 + 0.5845211148 + 0.5855050087 + 0.5864828229 + 0.5874555707 + 0.5884236097 + 0.5893865824 + 0.5903437138 + 0.5912957191 + 0.5922436714 + 0.5931885242 + 0.5941303968 + 0.5950701833 + 0.5960083008 + 0.5969455242 + 0.5978826284 + 0.5988199711 + 0.5997573733 + 0.6006944180 + 0.6016309261 + 0.6025679111 + 0.6035056710 + 0.6044442058 + 0.6053841710 + 0.6063274741 + 0.6072760224 + 0.6082304716 + 0.6091914177 + 0.6101577878 + 0.6111288071 + 0.6121054292 + 0.6130893230 + 0.6140809059 + 0.6150801778 + 0.6160869002 + 0.6171011925 + 0.6181237102 + 0.6191561222 + 0.6201986074 + 0.6212494969 + 0.6223081946 + 0.6233735085 + 0.6244443059 + 0.6255208850 + 0.6266024113 + 0.6276888251 + 0.6287800074 + 0.6298750043 + 0.6309717894 + 0.6320694089 + 0.6331679225 + 0.6342682838 + 0.6353698969 + 0.6364706755 + 0.6375694871 + 0.6386672854 + 0.6397666931 + 0.6408684254 + 0.6419709921 + 0.6430730224 + 0.6441742182 + 0.6452761889 + 0.6463810205 + 0.6474881172 + 0.6485970020 + 0.6497082114 + 0.6508216262 + 0.6519368887 + 0.6530544162 + 0.6541745067 + 0.6552979946 + 0.6564245224 + 0.6575521231 + 0.6586806178 + 0.6598100066 + 0.6609410048 + 0.6620740294 + 0.6632086039 + 0.6643440127 + 0.6654803157 + 0.6666182280 + 0.6677569747 + 0.6688960791 + 0.6700353026 + 0.6711744070 + 0.6723119020 + 0.6734473109 + 0.6745814085 + 0.6757146120 + 0.6768456101 + 0.6779726744 + 0.6790955067 + 0.6802144051 + 0.6813290119 + 0.6824392080 + 0.6835449934 + 0.6846470833 + 0.6857451797 + 0.6868383884 + 0.6879264116 + 0.6890088916 + 0.6900870204 + 0.6911612749 + 0.6922308803 + 0.6932950020 + 0.6943535805 + 0.6954085231 + 0.6964603066 + 0.6975083947 + 0.6985530257 + 0.6995959282 + 0.7006379962 + 0.7016788721 + 0.7027179003 + 0.7037551999 + 0.7047919035 + 0.7058281898 + 0.7068638206 + 0.7078987956 + 0.7089341879 + 0.7099704742 + 0.7110071182 + 0.7120435834 + 0.7130793929 + 0.7141141295 + 0.7151473761 + 0.7161788940 + 0.7172086835 + 0.7182366848 + 0.7192623019 + 0.7202852964 + 0.7213062048 + 0.7223259211 + 0.7233440876 + 0.7243599892 + 0.7253736258 + 0.7263845205 + 0.7273933291 + 0.7283999920 + 0.7294043899 + 0.7304064035 + 0.7314063907 + 0.7324048877 + 0.7334017158 + 0.7343968749 + 0.7353904247 + 0.7363826036 + 0.7373743057 + 0.7383652925 + 0.7393556833 + 0.7403460741 + 0.7413364053 + 0.7423262000 + 0.7433158755 + 0.7443063855 + 0.7452973723 + 0.7462878227 + 0.7472770810 + 0.7482659221 + 0.7492548823 + 0.7502439022 + 0.7512320876 + 0.7522203922 + 0.7532092929 + 0.7541986108 + 0.7551875114 + 0.7561764121 + 0.7571650743 + 0.7581533194 + 0.7591395974 + 0.7601243854 + 0.7611085773 + 0.7620921731 + 0.7630745769 + 0.7640557885 + 0.7650362253 + 0.7660158277 + 0.7669950724 + 0.7679738998 + 0.7689527273 + 0.7699314952 + 0.7709106803 + 0.7718899846 + 0.7728688121 + 0.7738466263 + 0.7748246789 + 0.7758036852 + 0.7767832279 + 0.7777634859 + 0.7787454724 + 0.7797296047 + 0.7807155252 + 0.7817035913 + 0.7826942801 + 0.7836887836 + 0.7846868038 + 0.7856897116 + 0.7866985202 + 0.7877131104 + 0.7887325287 + 0.7897546887 + 0.7907801867 + 0.7918102145 + 0.7928441763 + 0.7938814163 + 0.7949218750 + 0.7959659100 + 0.7970144153 + 0.7980663180 + 0.7991213799 + 0.8001785874 + 0.8012385964 + 0.8023005128 + 0.8033639193 + 0.8044286966 + 0.8054934740 + 0.8065580130 + 0.8076239824 + 0.8086903095 + 0.8097563982 + 0.8108221292 + 0.8118875027 + 0.8129522204 + 0.8140147924 + 0.8150777221 + 0.8161420822 + 0.8172072172 + 0.8182731867 + 0.8193401098 + 0.8204079866 + 0.8214777708 + 0.8225491047 + 0.8236216903 + 0.8246955872 + 0.8257701993 + 0.8268460035 + 0.8279229999 + 0.8290016055 + 0.8300824761 + 0.8311660886 + 0.8322516084 + 0.8333384991 + 0.8344269991 + 0.8355159163 + 0.8366057277 + 0.8376973867 + 0.8387901783 + 0.8398838043 + 0.8409780264 + 0.8420727849 + 0.8431686759 + 0.8442658782 + 0.8453642130 + 0.8464624882 + 0.8475595713 + 0.8486564159 + 0.8497542143 + 0.8508523703 + 0.8519496918 + 0.8530451059 + 0.8541380763 + 0.8552293777 + 0.8563184738 + 0.8574041724 + 0.8584862947 + 0.8595638275 + 0.8606367111 + 0.8617051244 + 0.8627687097 + 0.8638274074 + 0.8648813963 + 0.8659303784 + 0.8669738770 + 0.8680111766 + 0.8690428734 + 0.8700705171 + 0.8710942268 + 0.8721132874 + 0.8731275201 + 0.8741363287 + 0.8751401901 + 0.8761405945 + 0.8771389127 + 0.8781350851 + 0.8791291118 + 0.8801203966 + 0.8811098933 + 0.8820986748 + 0.8830870986 + 0.8840739131 + 0.8850582242 + 0.8860396743 + 0.8870177269 + 0.8879904747 + 0.8889573812 + 0.8899183869 + 0.8908733130 + 0.8918204904 + 0.8927587271 + 0.8936867714 + 0.8946046233 + 0.8955129981 + 0.8964123726 + 0.8973016739 + 0.8981794715 + 0.8990461230 + 0.8999027014 + 0.9007506967 + 0.9015905857 + 0.9024220705 + 0.9032449722 + 0.9040595293 + 0.9048662186 + 0.9056664705 + 0.9064612985 + 0.9072514176 + 0.9080368280 + 0.9088181257 + 0.9095960855 + 0.9103735089 + 0.9111509919 + 0.9119281173 + 0.9127063155 + 0.9134865999 + 0.9142683744 + 0.9150518179 + 0.9158385992 + 0.9166294932 + 0.9174247980 + 0.9182245731 + 0.9190281034 + 0.9198362827 + 0.9206498861 + 0.9214689732 + 0.9222937822 + 0.9231243134 + 0.9239605069 + 0.9248024225 + 0.9256507754 + 0.9265056252 + 0.9273657203 + 0.9282308221 + 0.9291006923 + 0.9299767017 + 0.9308583736 + 0.9317452908 + 0.9326366186 + 0.9335306883 + 0.9344261289 + 0.9353219867 + 0.9362199903 + 0.9371207952 + 0.9380227923 + 0.9389240742 + 0.9398236871 + 0.9407200813 + 0.9416117072 + 0.9424964190 + 0.9433727860 + 0.9442400932 + 0.9450957775 + 0.9459366202 + 0.9467617273 + 0.9475710988 + 0.9483641982 + 0.9491404891 + 0.9498987198 + 0.9506378770 + 0.9513601065 + 0.9520673156 + 0.9527601004 + 0.9534382224 + 0.9541031122 + 0.9547548890 + 0.9553934932 + 0.9560201764 + 0.9566345811 + 0.9572381973 + 0.9578328729 + 0.9584187269 + 0.9589971900 + 0.9595693946 + 0.9601373076 + 0.9607033134 + 0.9612680078 + 0.9618327022 + 0.9623975158 + 0.9629616737 + 0.9635255933 + 0.9640890956 + 0.9646533728 + 0.9652183056 + 0.9657815099 + 0.9663417935 + 0.9668993950 + 0.9674541950 + 0.9680057764 + 0.9685540199 + 0.9690970778 + 0.9696341753 + 0.9701663256 + 0.9706926942 + 0.9712131023 + 0.9717286825 + 0.9722387791 + 0.9727417827 + 0.9732379913 + 0.9737278819 + 0.9742118120 + 0.9746910930 + 0.9751664996 + 0.9756376147 + 0.9761040211 + 0.9765653014 + 0.9770221114 + 0.9774755836 + 0.9779269099 + 0.9783759117 + 0.9788222909 + 0.9792655706 + 0.9797067046 + 0.9801476002 + 0.9805889726 + 0.9810296893 + 0.9814689755 + 0.9819055796 + 0.9823380709 + 0.9827659726 + 0.9831880927 + 0.9836019874 + 0.9840061069 + 0.9844006896 + 0.9847850204 + 0.9851579070 + 0.9855204225 + 0.9858720899 + 0.9862110019 + 0.9865372181 + 0.9868519902 + 0.9871559739 + 0.9874501824 + 0.9877349734 + 0.9880086184 + 0.9882714152 + 0.9885252118 + 0.9887697101 + 0.9890058041 + 0.9892352223 + 0.9894577861 + 0.9896727204 + 0.9898800850 + 0.9900823832 + 0.9902830720 + 0.9904839993 + 0.9906855226 + 0.9908869267 + 0.9910880923 + 0.9912897944 + 0.9914922714 + 0.9916949272 + 0.9918974042 + 0.9920992851 + 0.9923006296 + 0.9925016761 + 0.9927030206 + 0.9929041266 + 0.9931046963 + 0.9933041930 + 0.9935020804 + 0.9936985970 + 0.9938936234 + 0.9940873981 + 0.9942802787 + 0.9944714904 + 0.9946609735 + 0.9948499203 + 0.9950379729 + 0.9952244163 + 0.9954094291 + 0.9955927134 + 0.9957733750 + 0.9959521890 + 0.9961301088 + 0.9963076711 + 0.9964857101 + 0.9966629744 + 0.9968385100 + 0.9970129728 + 0.9971876144 + 0.9973618984 + 0.9975370169 + 0.9977136254 + 0.9978904128 + 0.9980655909 + 0.9982392192 + 0.9984129071 + 0.9985876083 + 0.9987636805 + 0.9989405274 + 0.9991179705 + 0.9992954731 + 0.9994722009 + 0.9996479750 + 0.9998239875 + 1.0000000000 +} diff --git a/rpplugins/color_correction/resources/film_luts_raw/kodak_kodachrome_200.spi1d b/rpplugins/color_correction/resources/film_luts_raw/kodak_kodachrome_200.spi1d new file mode 100644 index 0000000..05790a8 --- /dev/null +++ b/rpplugins/color_correction/resources/film_luts_raw/kodak_kodachrome_200.spi1d @@ -0,0 +1,1030 @@ +Version 1 +From 0.0 1.0 +Length 1024 +Components 3 +{ + 0.0000000000 0.0000000000 0.0000000000 + 0.0001730574 0.0002039562 0.0002358485 + 0.0003522631 0.0004149732 0.0004803593 + 0.0005379661 0.0006318853 0.0007290206 + 0.0007310679 0.0008542882 0.0009827145 + 0.0009340477 0.0010819150 0.0012466050 + 0.0011457250 0.0013172789 0.0015175150 + 0.0013664630 0.0015590760 0.0017966420 + 0.0015953979 0.0018074680 0.0020813060 + 0.0018292820 0.0020661030 0.0023712160 + 0.0020738509 0.0023327931 0.0026701461 + 0.0023281691 0.0026087810 0.0029817061 + 0.0025920530 0.0028905689 0.0033033220 + 0.0028679480 0.0031836890 0.0036326619 + 0.0031529539 0.0034913400 0.0039701960 + 0.0034448660 0.0038095911 0.0043217931 + 0.0037472011 0.0041361330 0.0046877442 + 0.0040617771 0.0044678152 0.0050627491 + 0.0043859989 0.0048073409 0.0054407581 + 0.0047217272 0.0051559508 0.0058272062 + 0.0050699208 0.0055170869 0.0062212390 + 0.0054345722 0.0058912761 0.0066273510 + 0.0058116391 0.0062767328 0.0070466590 + 0.0062011848 0.0066723628 0.0074762749 + 0.0066031339 0.0070798998 0.0079114493 + 0.0070177661 0.0075020911 0.0083535369 + 0.0074442741 0.0079338206 0.0088046975 + 0.0078795254 0.0083771208 0.0092653846 + 0.0083278697 0.0088326121 0.0097344546 + 0.0087915091 0.0092987726 0.0102126198 + 0.0092691761 0.0097725317 0.0107003897 + 0.0097623114 0.0102546504 0.0111954799 + 0.0102694500 0.0107495701 0.0116990302 + 0.0107906098 0.0112578301 0.0122114504 + 0.0113268001 0.0117790196 0.0127311097 + 0.0118786199 0.0123126702 0.0132614998 + 0.0124431401 0.0128612900 0.0138018904 + 0.0130219003 0.0134234196 0.0143521996 + 0.0136152301 0.0139996996 0.0149130402 + 0.0142232198 0.0145876799 0.0154852197 + 0.0148449196 0.0151869999 0.0160684697 + 0.0154783595 0.0158025604 0.0166603103 + 0.0161256995 0.0164336897 0.0172653906 + 0.0167863201 0.0170805994 0.0178804602 + 0.0174631495 0.0177476797 0.0185050704 + 0.0181544498 0.0184269901 0.0191421397 + 0.0188641995 0.0191224609 0.0197905600 + 0.0195880793 0.0198333003 0.0204491094 + 0.0203275606 0.0205603093 0.0211143699 + 0.0210811403 0.0212992709 0.0217879806 + 0.0218534302 0.0220546499 0.0224671308 + 0.0226451308 0.0228254497 0.0231546499 + 0.0234524105 0.0236116406 0.0238485206 + 0.0242763907 0.0244143009 0.0245480109 + 0.0251218900 0.0252302606 0.0252581500 + 0.0259851404 0.0260641407 0.0259789899 + 0.0268620700 0.0269184001 0.0267140791 + 0.0277548693 0.0277873296 0.0274658203 + 0.0286648702 0.0286731608 0.0282310992 + 0.0295908507 0.0295777693 0.0290101692 + 0.0305334404 0.0304972902 0.0298030600 + 0.0314947292 0.0314330608 0.0306055099 + 0.0324744582 0.0323868990 0.0314168893 + 0.0334764086 0.0333601981 0.0322372504 + 0.0344995111 0.0343528390 0.0330651999 + 0.0355402492 0.0353610590 0.0339045897 + 0.0365981199 0.0363844894 0.0347526409 + 0.0376747511 0.0374244489 0.0356094018 + 0.0387722701 0.0384774804 0.0364748016 + 0.0398925804 0.0395460315 0.0373485014 + 0.0410357118 0.0406353809 0.0382347293 + 0.0421971716 0.0417462699 0.0391340293 + 0.0433758609 0.0428716205 0.0400448591 + 0.0445724390 0.0440130197 0.0409630090 + 0.0457868986 0.0451716594 0.0418913700 + 0.0470213406 0.0463434607 0.0428329296 + 0.0482786596 0.0475279316 0.0437831692 + 0.0495616607 0.0487296283 0.0447406098 + 0.0508708991 0.0499518812 0.0457080491 + 0.0522039905 0.0511935391 0.0466858111 + 0.0535621308 0.0524507686 0.0476739705 + 0.0549456812 0.0537222885 0.0486743301 + 0.0563542917 0.0550098717 0.0496832319 + 0.0577872396 0.0563169084 0.0507013202 + 0.0592435412 0.0576429814 0.0517350510 + 0.0607235916 0.0589821301 0.0527782217 + 0.0622299090 0.0603348911 0.0538305715 + 0.0637641624 0.0617051981 0.0548948608 + 0.0653300881 0.0630972311 0.0559714995 + 0.0669195279 0.0645076036 0.0570586994 + 0.0685284436 0.0659297109 0.0581539795 + 0.0701561198 0.0673606992 0.0592579208 + 0.0718030334 0.0688040778 0.0603738800 + 0.0734695569 0.0702652484 0.0615030490 + 0.0751590133 0.0717460513 0.0626446307 + 0.0768723935 0.0732394904 0.0637940615 + 0.0786073431 0.0747426003 0.0649530664 + 0.0803640932 0.0762560293 0.0661245733 + 0.0821429417 0.0777818337 0.0673098490 + 0.0839471966 0.0793204084 0.0685084313 + 0.0857824534 0.0808681324 0.0697233528 + 0.0876402482 0.0824251175 0.0709487796 + 0.0895186588 0.0839939788 0.0721847713 + 0.0914160535 0.0855768770 0.0734331012 + 0.0933414400 0.0871768892 0.0746951923 + 0.0952875987 0.0887894779 0.0759687126 + 0.0972552076 0.0904145017 0.0772481188 + 0.0992452875 0.0920512825 0.0785354823 + 0.1012666970 0.0936988667 0.0798321664 + 0.1033084020 0.0953587517 0.0811416209 + 0.1053688005 0.0970306993 0.0824629217 + 0.1074498966 0.0987144411 0.0837924406 + 0.1095537990 0.1004106030 0.0851297081 + 0.1116733998 0.1021208018 0.0864788592 + 0.1138081029 0.1038433984 0.0878428370 + 0.1159645021 0.1055795997 0.0892181471 + 0.1181332022 0.1073433980 0.0906047598 + 0.1203133017 0.1091196015 0.0920063481 + 0.1225123033 0.1109066978 0.0934172571 + 0.1247252971 0.1127050966 0.0948378369 + 0.1269482970 0.1145213023 0.0962786898 + 0.1291864067 0.1163515970 0.0977344289 + 0.1314398050 0.1182034016 0.0992026329 + 0.1337047964 0.1200674996 0.1006904021 + 0.1359920055 0.1219405010 0.1021960005 + 0.1382973045 0.1238282993 0.1037138999 + 0.1406147927 0.1257331967 0.1052495018 + 0.1429530978 0.1276489943 0.1068022996 + 0.1453036964 0.1295824945 0.1083668992 + 0.1476657987 0.1315266043 0.1099525020 + 0.1500508040 0.1334788054 0.1115524024 + 0.1524461955 0.1354573965 0.1131626964 + 0.1548593938 0.1374479979 0.1147975996 + 0.1572892964 0.1394518018 0.1164444983 + 0.1597270072 0.1414680034 0.1181050986 + 0.1621783972 0.1434909999 0.1197827980 + 0.1646371931 0.1455283016 0.1214680970 + 0.1671067029 0.1475757957 0.1231684014 + 0.1695881933 0.1496292949 0.1248828992 + 0.1720747054 0.1517004967 0.1266061962 + 0.1745768040 0.1537802070 0.1283615977 + 0.1770841032 0.1558783948 0.1301272064 + 0.1796021014 0.1579937041 0.1319141984 + 0.1821261942 0.1601195037 0.1337158978 + 0.1846542060 0.1622675061 0.1355265975 + 0.1871972978 0.1644203067 0.1373614073 + 0.1897435039 0.1665845066 0.1392045021 + 0.1922962070 0.1687586010 0.1410738975 + 0.1948485970 0.1709450036 0.1429603994 + 0.1974000037 0.1731521040 0.1448680013 + 0.1999529004 0.1753689051 0.1467960030 + 0.2025073022 0.1776115000 0.1487334073 + 0.2050623000 0.1798598021 0.1506955028 + 0.2076175958 0.1821341962 0.1526625007 + 0.2101784945 0.1844155937 0.1546497941 + 0.2127404958 0.1867152005 0.1566448063 + 0.2153038979 0.1890224069 0.1586592048 + 0.2178677022 0.1913391948 0.1606916934 + 0.2204349041 0.1936641932 0.1627465039 + 0.2230034024 0.1959953010 0.1648250967 + 0.2255780995 0.1983426064 0.1669203043 + 0.2281538993 0.2006970942 0.1690406948 + 0.2307337970 0.2030775994 0.1711710989 + 0.2333167940 0.2054647952 0.1733302027 + 0.2359074056 0.2078783959 0.1754958034 + 0.2384988964 0.2102957964 0.1776867956 + 0.2410926074 0.2127331942 0.1798807979 + 0.2436847985 0.2151719928 0.1820942014 + 0.2462743968 0.2176246047 0.1843084991 + 0.2488645017 0.2200776041 0.1865465939 + 0.2514558136 0.2225456983 0.1887851954 + 0.2540476024 0.2250140011 0.1910569072 + 0.2566407025 0.2275063992 0.1933290064 + 0.2592354119 0.2299994975 0.1956388056 + 0.2618348897 0.2325156033 0.1979486048 + 0.2644349933 0.2350329012 0.2002822012 + 0.2670376897 0.2375658005 0.2026163042 + 0.2696410120 0.2401002944 0.2049711943 + 0.2722525895 0.2426490933 0.2073276043 + 0.2748641074 0.2452007979 0.2097111940 + 0.2774798870 0.2477629036 0.2120991051 + 0.2800959945 0.2503288984 0.2145109028 + 0.2827027142 0.2529033124 0.2169295996 + 0.2853069007 0.2554830909 0.2193607986 + 0.2879045010 0.2580693960 0.2217984051 + 0.2904979885 0.2606629133 0.2242448032 + 0.2930887938 0.2632611990 0.2266992033 + 0.2956756949 0.2658706009 0.2291606069 + 0.2982619107 0.2684814036 0.2316346020 + 0.3008450866 0.2711029053 0.2341126055 + 0.3034282923 0.2737244070 0.2366093993 + 0.3060013056 0.2763522863 0.2391061932 + 0.3085739017 0.2789807022 0.2416251004 + 0.3111369014 0.2816146910 0.2441447973 + 0.3136956990 0.2842512131 0.2466782033 + 0.3162499070 0.2868914008 0.2492164969 + 0.3187974095 0.2895368934 0.2517606020 + 0.3213433921 0.2921831906 0.2543109953 + 0.3238751888 0.2948344946 0.2568640113 + 0.3264068961 0.2974858880 0.2594281137 + 0.3289282918 0.3001478016 0.2619921863 + 0.3314462900 0.3028118908 0.2645705938 + 0.3339582086 0.3054809868 0.2671507895 + 0.3364607096 0.3081552088 0.2697336972 + 0.3389630914 0.3108294010 0.2723186910 + 0.3414388001 0.3135038018 0.2749026120 + 0.3439145088 0.3161781132 0.2774826884 + 0.3463768065 0.3188591003 0.2800627947 + 0.3488295972 0.3215422034 0.2826369107 + 0.3512794971 0.3242281079 0.2852098048 + 0.3537116945 0.3269194067 0.2877875865 + 0.3561440110 0.3296107054 0.2903720140 + 0.3585642874 0.3322994113 0.2929564118 + 0.3609788120 0.3349879086 0.2955451012 + 0.3633924127 0.3376730978 0.2981339097 + 0.3658021092 0.3403542042 0.3007180095 + 0.3682116866 0.3430353105 0.3032977879 + 0.3706200123 0.3457179964 0.3058773875 + 0.3730275035 0.3484008908 0.3084514141 + 0.3754344881 0.3510805964 0.3110255003 + 0.3778376877 0.3537563086 0.3135905862 + 0.3802408874 0.3564321101 0.3161478043 + 0.3826422989 0.3591000140 0.3187049925 + 0.3850421906 0.3617669940 0.3212369084 + 0.3874421120 0.3644312024 0.3237684965 + 0.3898290098 0.3670895100 0.3262920082 + 0.3922148049 0.3697476983 0.3288041949 + 0.3945944011 0.3723874092 0.3313164115 + 0.3969587982 0.3750202060 0.3338195086 + 0.3993231058 0.3776504993 0.3363206089 + 0.4016804099 0.3802587092 0.3388189077 + 0.4040333927 0.3828668892 0.3413054943 + 0.4063864946 0.3854654133 0.3437921107 + 0.4087263942 0.3880515099 0.3462659121 + 0.4110653996 0.3906376958 0.3487288952 + 0.4134008884 0.3932111859 0.3511919975 + 0.4157232046 0.3957807124 0.3536264896 + 0.4180454910 0.3983494937 0.3560566008 + 0.4203620851 0.4009037912 0.3584819138 + 0.4226720035 0.4034580886 0.3608815968 + 0.4249818921 0.4060049951 0.3632813096 + 0.4272814989 0.4085350931 0.3656719923 + 0.4295763969 0.4110653102 0.3680498004 + 0.4318712056 0.4135862887 0.3704276979 + 0.4341445863 0.4160991907 0.3727912009 + 0.4364148080 0.4186122119 0.3751470149 + 0.4386841953 0.4211213887 0.3775027096 + 0.4409301877 0.4236291945 0.3798316121 + 0.4431762993 0.4261370003 0.3821555972 + 0.4454182088 0.4286366105 0.3844789863 + 0.4476383030 0.4311352968 0.3867709041 + 0.4498583972 0.4336335957 0.3890627027 + 0.4520725906 0.4361194074 0.3913497925 + 0.4542694986 0.4386051893 0.3936108947 + 0.4564662874 0.4410878122 0.3958719075 + 0.4586519897 0.4435504973 0.3981297910 + 0.4608140886 0.4460130930 0.4003787935 + 0.4629763067 0.4484688938 0.4026277065 + 0.4651244879 0.4508990049 0.4048694074 + 0.4672470987 0.4533290863 0.4070971012 + 0.4693697989 0.4557510018 0.4093249142 + 0.4714809954 0.4581488967 0.4115391076 + 0.4735712111 0.4605467916 0.4137321115 + 0.4756614864 0.4629383981 0.4159250855 + 0.4777419865 0.4653125107 0.4181059897 + 0.4798024893 0.4676867127 0.4202688932 + 0.4818629026 0.4700528085 0.4224317074 + 0.4839158952 0.4723933935 0.4245786965 + 0.4859476089 0.4747340083 0.4266997874 + 0.4879794121 0.4770675004 0.4288209081 + 0.4900068939 0.4793699086 0.4309298098 + 0.4920125008 0.4816722870 0.4330140054 + 0.4940181971 0.4839723110 0.4350981116 + 0.4960232973 0.4862492085 0.4371761978 + 0.4980137050 0.4885261953 0.4392358065 + 0.5000041127 0.4908030927 0.4412953854 + 0.5019946098 0.4930540919 0.4433520138 + 0.5039594769 0.4953044951 0.4453881085 + 0.5059207082 0.4975548983 0.4474242032 + 0.5078818798 0.4997824132 0.4494602084 + 0.5098254085 0.5020049810 0.4514681101 + 0.5117604136 0.5042275190 0.4534752965 + 0.5136954188 0.5064237118 0.4554825127 + 0.5156211853 0.5086045861 0.4574632049 + 0.5175352097 0.5107855201 0.4594367146 + 0.5194491744 0.5129476190 0.4614103138 + 0.5213580728 0.5150821805 0.4633643031 + 0.5232421756 0.5172169209 0.4653035104 + 0.5251262784 0.5193458796 0.4672426879 + 0.5270103812 0.5214424729 0.4691694975 + 0.5288773179 0.5235390067 0.4710688889 + 0.5307416916 0.5256354809 0.4729683995 + 0.5326061249 0.5277007818 0.4748673141 + 0.5344613791 0.5297605991 0.4767382145 + 0.5363087058 0.5318204165 0.4786092043 + 0.5381559134 0.5338671207 0.4804801047 + 0.5400000215 0.5359017849 0.4823342860 + 0.5418263078 0.5379365087 0.4841809869 + 0.5436527133 0.5399680138 0.4860278070 + 0.5454791188 0.5419824719 0.4878644049 + 0.5472977161 0.5439968705 0.4896807075 + 0.5491135716 0.5460113287 0.4914970100 + 0.5509294868 0.5480144024 0.4933133125 + 0.5527412295 0.5500137210 0.4951044023 + 0.5545426011 0.5520130992 0.4968936145 + 0.5563439727 0.5540094972 0.4986828864 + 0.5581454039 0.5559996963 0.5004619956 + 0.5599331260 0.5579897761 0.5022308230 + 0.5617172718 0.5599799752 0.5039995909 + 0.5635015965 0.5619543791 0.5057681203 + 0.5652781725 0.5639256835 0.5075237751 + 0.5670350790 0.5658969283 0.5092794895 + 0.5687919259 0.5678616166 0.5110352039 + 0.5705487728 0.5698119998 0.5127810836 + 0.5722795725 0.5717625022 0.5145177245 + 0.5740000010 0.5737128854 0.5162543058 + 0.5757204890 0.5756404996 0.5179908276 + 0.5774372816 0.5775611997 0.5197011828 + 0.5791262984 0.5794818997 0.5214105248 + 0.5808153152 0.5813961029 0.5231198072 + 0.5825042129 0.5832800865 0.5248202085 + 0.5841786861 0.5851641297 0.5265055895 + 0.5858368874 0.5870479941 0.5281910896 + 0.5874952078 0.5889140964 0.5298765898 + 0.5891535282 0.5907651186 0.5315344930 + 0.5907946825 0.5926162004 0.5331832170 + 0.5924314260 0.5944672227 0.5348318219 + 0.5940682292 0.5962749720 0.5364782810 + 0.5957034230 0.5980765820 0.5381013751 + 0.5973179936 0.5998781919 0.5397245884 + 0.5989326239 0.6016728878 0.5413476825 + 0.6005473137 0.6034333706 0.5429692268 + 0.6021553278 0.6051939130 0.5445882082 + 0.6037486792 0.6069543958 0.5462071896 + 0.6053420901 0.6087045074 0.5478262901 + 0.6069355011 0.6104400754 0.5494415760 + 0.6085183024 0.6121757030 0.5510547757 + 0.6100909710 0.6139113903 0.5526679754 + 0.6116636992 0.6156324148 0.5542811751 + 0.6132364273 0.6173446774 0.5558875799 + 0.6147910953 0.6190569997 0.5574927926 + 0.6163368225 0.6207693219 0.5590980053 + 0.6178824902 0.6224603057 0.5607026815 + 0.6194280982 0.6241456866 0.5622801781 + 0.6209585071 0.6258311272 0.5638577938 + 0.6224846840 0.6275166273 0.5654352903 + 0.6240109205 0.6291700006 0.5670077801 + 0.6255372167 0.6308205724 0.5685514212 + 0.6270471811 0.6324712038 0.5700950027 + 0.6285545826 0.6341215968 0.5716385841 + 0.6300619841 0.6357386112 0.5731750131 + 0.6315693855 0.6373555064 0.5746886730 + 0.6330655813 0.6389724016 0.5762023926 + 0.6345605254 0.6405878067 0.5777161121 + 0.6360552907 0.6421716809 0.5792214870 + 0.6375501156 0.6437556744 0.5807061791 + 0.6390339136 0.6453396082 0.5821908116 + 0.6405161023 0.6469221711 0.5836755037 + 0.6419982910 0.6484758854 0.5851554871 + 0.6434804797 0.6500297189 0.5866240859 + 0.6449518800 0.6515833735 0.5880926847 + 0.6464208961 0.6531370878 0.5895612240 + 0.6478899121 0.6546549797 0.5910267234 + 0.6493589282 0.6561728716 0.5924829245 + 0.6508315802 0.6576908231 0.5939390063 + 0.6523056030 0.6592087150 0.5953950882 + 0.6537796259 0.6606941223 0.5968484879 + 0.6552537084 0.6621763706 0.5982881188 + 0.6567261219 0.6636587977 0.5997276902 + 0.6581972837 0.6651412249 0.6011673808 + 0.6596685052 0.6666092873 0.6026061773 + 0.6611397266 0.6680734754 0.6040263772 + 0.6626036763 0.6695376039 0.6054465771 + 0.6640564799 0.6710017920 0.6068667769 + 0.6655092835 0.6724609733 0.6082869768 + 0.6669620872 0.6739168167 0.6096944213 + 0.6684113145 0.6753727198 0.6110997796 + 0.6698417068 0.6768286228 0.6125053167 + 0.6712719798 0.6782851815 0.6139106750 + 0.6727023125 0.6797429919 0.6153100133 + 0.6741325855 0.6812009215 0.6167058945 + 0.6755437255 0.6826586723 0.6181018949 + 0.6769521236 0.6841160059 0.6194978952 + 0.6783605218 0.6855689287 0.6208894253 + 0.6797689795 0.6870219111 0.6222738028 + 0.6811653972 0.6884748936 0.6236581206 + 0.6825522780 0.6899278760 0.6250424981 + 0.6839390993 0.6913648248 0.6264259219 + 0.6853259206 0.6927976012 0.6277984977 + 0.6867079735 0.6942304969 0.6291711926 + 0.6880686283 0.6956632733 0.6305438280 + 0.6894292831 0.6970888972 0.6319164038 + 0.6907898784 0.6985052824 0.6332756281 + 0.6921504736 0.6999217272 0.6346296072 + 0.6934959888 0.7013381124 0.6359835863 + 0.6948367953 0.7027540803 0.6373376250 + 0.6961774826 0.7041571140 0.6386855245 + 0.6975182295 0.7055600882 0.6400206089 + 0.6988571882 0.7069631219 0.6413556933 + 0.7001917958 0.7083662152 0.6426907778 + 0.7015264034 0.7097566724 0.6440259218 + 0.7028610110 0.7111378908 0.6453583837 + 0.7041956186 0.7125192285 0.6466904879 + 0.7055236101 0.7139005065 0.6480225921 + 0.7068496943 0.7152801752 0.6493546963 + 0.7081757784 0.7166393995 0.6506857872 + 0.7095018029 0.7179986238 0.6520152092 + 0.7108235955 0.7193577886 0.6533446908 + 0.7121292949 0.7207170129 0.6546741128 + 0.7134348750 0.7220675945 0.6560035944 + 0.7147405148 0.7234103084 0.6573339105 + 0.7160462141 0.7247529030 0.6586644053 + 0.7173392177 0.7260956168 0.6599950194 + 0.7186235189 0.7274382114 0.6613255143 + 0.7199078798 0.7287701964 0.6626539230 + 0.7211923003 0.7301012278 0.6639747024 + 0.7224767208 0.7314321995 0.6652954817 + 0.7237458229 0.7327631712 0.6666163206 + 0.7250137925 0.7340887785 0.6679372191 + 0.7262817025 0.7353991866 0.6692438722 + 0.7275496721 0.7367095947 0.6705400944 + 0.7288151979 0.7380200028 0.6718363166 + 0.7300717235 0.7393304110 0.6731324792 + 0.7313283086 0.7406290770 0.6744287014 + 0.7325847745 0.7419185042 0.6757104993 + 0.7338414192 0.7432078719 0.6769903898 + 0.7350922823 0.7444974184 0.6782702208 + 0.7363361716 0.7457867861 0.6795499921 + 0.7375801206 0.7470659018 0.6808269024 + 0.7388241291 0.7483425140 0.6820834875 + 0.7400680184 0.7496191263 0.6833400726 + 0.7413054109 0.7508956790 0.6845965981 + 0.7425388098 0.7521722913 0.6858531833 + 0.7437722087 0.7534267902 0.6871013045 + 0.7450056076 0.7546814084 0.6883319020 + 0.7462391257 0.7559359074 0.6895623803 + 0.7474638224 0.7571905255 0.6907929778 + 0.7486857176 0.7584406137 0.6920235753 + 0.7499076128 0.7596641779 0.6932476759 + 0.7511295080 0.7608876824 0.6944645047 + 0.7523514032 0.7621111870 0.6956813931 + 0.7535635829 0.7633348107 0.6968982816 + 0.7547737956 0.7645512819 0.6981152296 + 0.7559840083 0.7657446265 0.6993272901 + 0.7571942210 0.7669377923 0.7005357742 + 0.7584043741 0.7681310773 0.7017441988 + 0.7596076727 0.7693244219 0.7029526830 + 0.7608097196 0.7705097795 0.7041612267 + 0.7620118260 0.7716736197 0.7053571939 + 0.7632138729 0.7728374004 0.7065454125 + 0.7644159794 0.7740011811 0.7077335715 + 0.7655978799 0.7751650810 0.7089217901 + 0.7667754889 0.7763243914 0.7101098895 + 0.7679529786 0.7774704099 0.7112854123 + 0.7691305876 0.7786164284 0.7124524117 + 0.7703080773 0.7797623873 0.7136192918 + 0.7714644074 0.7809084058 0.7147862911 + 0.7726129889 0.7820516229 0.7159532905 + 0.7737615705 0.7831820846 0.7171167135 + 0.7749102116 0.7843126059 0.7182772160 + 0.7760587931 0.7854431868 0.7194375992 + 0.7771977186 0.7865737081 0.7205979824 + 0.7783300877 0.7877029777 0.7217584252 + 0.7794623971 0.7888091207 0.7229158282 + 0.7805947065 0.7899152040 0.7240688205 + 0.7817270160 0.7910214067 0.7252218723 + 0.7828512192 0.7921274900 0.7263749242 + 0.7839630246 0.7932336926 0.7275279164 + 0.7850748897 0.7943174243 0.7286769748 + 0.7861866951 0.7953978181 0.7298130989 + 0.7872986197 0.7964780927 0.7309491038 + 0.7884055972 0.7975584865 0.7320852280 + 0.7894845009 0.7986388803 0.7332212925 + 0.7905632854 0.7997053862 0.7343574166 + 0.7916421294 0.8007637262 0.7354778051 + 0.7927209735 0.8018221259 0.7365983129 + 0.7937998176 0.8028805256 0.7377187014 + 0.7948549986 0.8039388061 0.7388392091 + 0.7959054112 0.8049921989 0.7399595976 + 0.7969558835 0.8060358167 0.7410690188 + 0.7980064154 0.8070793748 0.7421737909 + 0.7990568280 0.8081229925 0.7432786822 + 0.8000957966 0.8091667295 0.7443835735 + 0.8011217117 0.8102102876 0.7454885244 + 0.8021476269 0.8112317920 0.7465876937 + 0.8031734824 0.8122528791 0.7476770878 + 0.8041993976 0.8132740259 0.7487664819 + 0.8052238822 0.8142951727 0.7498558760 + 0.8062176704 0.8153163195 0.7509453297 + 0.8072115183 0.8163194060 0.7520347238 + 0.8082051873 0.8173090816 0.7531046867 + 0.8091989756 0.8182986975 0.7541738749 + 0.8101927042 0.8192883730 0.7552431822 + 0.8111652136 0.8202779889 0.7563123703 + 0.8121206760 0.8212653995 0.7573816776 + 0.8130761981 0.8222320080 0.7584378123 + 0.8140317798 0.8231986761 0.7594807744 + 0.8149873018 0.8241654038 0.7605237961 + 0.8159424067 0.8251320720 0.7615668178 + 0.8168678880 0.8260987997 0.7626097202 + 0.8177933097 0.8270537257 0.7636526823 + 0.8187186718 0.8279997706 0.7646675706 + 0.8196440935 0.8289458752 0.7656818032 + 0.8205695152 0.8298919797 0.7666959763 + 0.8214858174 0.8308380842 0.7677102089 + 0.8223888278 0.8317841887 0.7687243819 + 0.8232917786 0.8327031732 0.7697293162 + 0.8241947889 0.8336216807 0.7707198262 + 0.8250979185 0.8345401883 0.7717103958 + 0.8260009289 0.8354586959 0.7727010250 + 0.8268916011 0.8363772035 0.7736914754 + 0.8277779818 0.8372876048 0.7746821046 + 0.8286644816 0.8381816149 0.7756630182 + 0.8295509219 0.8390756845 0.7766405940 + 0.8304374218 0.8399696946 0.7776182890 + 0.8313233852 0.8408638239 0.7785959840 + 0.8321877122 0.8417577744 0.7795736194 + 0.8330519795 0.8426352143 0.7805503011 + 0.8339163065 0.8435022831 0.7815071940 + 0.8347805738 0.8443694711 0.7824640870 + 0.8356449008 0.8452367187 0.7834209204 + 0.8365029097 0.8461037874 0.7843778133 + 0.8373395801 0.8469709754 0.7853347063 + 0.8381764293 0.8478137851 0.7862827182 + 0.8390132189 0.8486523032 0.7872080207 + 0.8398498893 0.8494908214 0.7881333232 + 0.8406866789 0.8503292203 0.7890586257 + 0.8415160179 0.8511676788 0.7899839282 + 0.8423328996 0.8520057797 0.7909091711 + 0.8431499004 0.8528186083 0.7918230891 + 0.8439669013 0.8536313176 0.7927232981 + 0.8447839022 0.8544440269 0.7936236262 + 0.8456009030 0.8552566767 0.7945237756 + 0.8464123011 0.8560693860 0.7954239845 + 0.8472172022 0.8568791151 0.7963243127 + 0.8480221033 0.8576657772 0.7972148061 + 0.8488271236 0.8584524989 0.7980977297 + 0.8496320248 0.8592392206 0.7989805937 + 0.8504369259 0.8600258827 0.7998635173 + 0.8512371778 0.8608126044 0.8007463813 + 0.8520324230 0.8615955114 0.8016293049 + 0.8528277278 0.8623574972 0.8024988174 + 0.8536229134 0.8631194234 0.8033595085 + 0.8544182181 0.8638814092 0.8042201996 + 0.8552135229 0.8646433949 0.8050808907 + 0.8559978008 0.8654053211 0.8059417009 + 0.8567681909 0.8661652207 0.8068023920 + 0.8575387001 0.8669108748 0.8076456189 + 0.8583090901 0.8676565289 0.8084762096 + 0.8590794802 0.8684021235 0.8093069196 + 0.8598498702 0.8691477776 0.8101375103 + 0.8606119752 0.8698933721 0.8109682202 + 0.8613570929 0.8706384897 0.8117988706 + 0.8621020913 0.8713684082 0.8126195073 + 0.8628472090 0.8720982075 0.8134300709 + 0.8635922074 0.8728280067 0.8142405748 + 0.8643373251 0.8735578060 0.8150511980 + 0.8650797009 0.8742876053 0.8158618212 + 0.8658074141 0.8750174046 0.8166723847 + 0.8665351272 0.8757197857 0.8174800873 + 0.8672627807 0.8764181733 0.8182824254 + 0.8679904938 0.8771166205 0.8190848231 + 0.8687182069 0.8778150082 0.8198871017 + 0.8694459200 0.8785135150 0.8206894994 + 0.8701534271 0.8792119026 0.8214918971 + 0.8708590865 0.8798918724 0.8222925067 + 0.8715646863 0.8805618882 0.8230811954 + 0.8722702861 0.8812319040 0.8238700032 + 0.8729758859 0.8819019794 0.8246586919 + 0.8736816049 0.8825719953 0.8254473805 + 0.8743742704 0.8832420111 0.8262361884 + 0.8750584722 0.8839061260 0.8270248771 + 0.8757427931 0.8845593929 0.8277987242 + 0.8764269948 0.8852127194 0.8285697103 + 0.8771111965 0.8858659863 0.8293406963 + 0.8777955174 0.8865193725 0.8301116824 + 0.8784751296 0.8871726990 0.8308827281 + 0.8791388869 0.8878260255 0.8316535950 + 0.8798025846 0.8884590268 0.8324189782 + 0.8804662824 0.8890919089 0.8331785202 + 0.8811300993 0.8897247910 0.8339378834 + 0.8817937970 0.8903576732 0.8346974254 + 0.8824576139 0.8909906745 0.8354569077 + 0.8831110001 0.8916236162 0.8362162709 + 0.8837615848 0.8922482729 0.8369745016 + 0.8844121099 0.8928667903 0.8377140760 + 0.8850625753 0.8934854269 0.8384537101 + 0.8857132196 0.8941038847 0.8391932845 + 0.8863636851 0.8947224021 0.8399327993 + 0.8870092034 0.8953409195 0.8406723738 + 0.8876399994 0.8959586024 0.8414120078 + 0.8882709146 0.8965657949 0.8421400785 + 0.8889017105 0.8971729279 0.8428595066 + 0.8895326257 0.8977800012 0.8435789943 + 0.8901634216 0.8983871937 0.8442984223 + 0.8907942772 0.8989943266 0.8450179100 + 0.8914089799 0.8996015191 0.8457372785 + 0.8920158744 0.9001982212 0.8464565277 + 0.8926227093 0.9007843733 0.8471537828 + 0.8932296038 0.9013705850 0.8478512168 + 0.8938364983 0.9019567966 0.8485484719 + 0.8944432735 0.9025430083 0.8492457867 + 0.8950501084 0.9031292200 0.8499431014 + 0.8956450820 0.9037153721 0.8506404161 + 0.8962401152 0.9042838812 0.8513295054 + 0.8968350887 0.9048495293 0.8520048261 + 0.8974301815 0.9054149985 0.8526800871 + 0.8980252147 0.9059805274 0.8533554077 + 0.8986201882 0.9065459967 0.8540307283 + 0.8992115259 0.9071115851 0.8547059894 + 0.8997929096 0.9076750875 0.8553813100 + 0.9003742933 0.9082267284 0.8560460806 + 0.9009556174 0.9087783098 0.8567056060 + 0.9015370011 0.9093298912 0.8573651910 + 0.9021183848 0.9098814726 0.8580247760 + 0.9026998281 0.9104331136 0.8586843014 + 0.9032738805 0.9109846950 0.8593438864 + 0.9038397074 0.9115307927 0.8600034714 + 0.9044054747 0.9120668769 0.8606566191 + 0.9049713016 0.9126030207 0.8613088727 + 0.9055371284 0.9131391048 0.8619611859 + 0.9061030149 0.9136751294 0.8626134992 + 0.9066687822 0.9142112136 0.8632658124 + 0.9072257876 0.9147472978 0.8639181256 + 0.9077767730 0.9152768850 0.8645702004 + 0.9083276987 0.9157999158 0.8652151227 + 0.9088786840 0.9163230062 0.8658599854 + 0.9094297290 0.9168459773 0.8665049076 + 0.9099807143 0.9173690081 0.8671498895 + 0.9105315804 0.9178919792 0.8677948117 + 0.9110671878 0.9184150100 0.8684396744 + 0.9115940928 0.9189338088 0.8690823913 + 0.9121209979 0.9194490910 0.8697077036 + 0.9126479030 0.9199643731 0.8703330159 + 0.9131749272 0.9204797149 0.8709583282 + 0.9137017727 0.9209951162 0.8715835214 + 0.9142286777 0.9215103984 0.8722087741 + 0.9147396088 0.9220256805 0.8728340864 + 0.9152405262 0.9225335121 0.8734576106 + 0.9157413244 0.9230350852 0.8740668297 + 0.9162421227 0.9235367775 0.8746759892 + 0.9167429805 0.9240384102 0.8752852082 + 0.9172437787 0.9245399833 0.8758944273 + 0.9177445769 0.9250416756 0.8765035868 + 0.9182330966 0.9255433083 0.8771128058 + 0.9187096953 0.9260321856 0.8777214885 + 0.9191861749 0.9265064001 0.8783164024 + 0.9196627736 0.9269806743 0.8789111972 + 0.9201393127 0.9274548888 0.8795061111 + 0.9206159115 0.9279291034 0.8801010251 + 0.9210923910 0.9284033775 0.8806958199 + 0.9215654731 0.9288775921 0.8812906742 + 0.9220311046 0.9293445945 0.8818855286 + 0.9224967957 0.9297950268 0.8824583292 + 0.9229624271 0.9302453995 0.8830280900 + 0.9234281182 0.9306957722 0.8835980296 + 0.9238938093 0.9311462045 0.8841677904 + 0.9243593812 0.9315965772 0.8847376108 + 0.9248239994 0.9320470095 0.8853073716 + 0.9252728820 0.9324961901 0.8858771920 + 0.9257218242 0.9329271913 0.8864341974 + 0.9261707067 0.9333581924 0.8869844079 + 0.9266195893 0.9337891936 0.8875344992 + 0.9270685911 0.9342203140 0.8880845904 + 0.9275174737 0.9346513152 0.8886348009 + 0.9279664159 0.9350823164 0.8891848922 + 0.9283986092 0.9355133772 0.8897349834 + 0.9288244843 0.9359328151 0.8902794123 + 0.9292504191 0.9363483191 0.8908125758 + 0.9296762943 0.9367638826 0.8913459182 + 0.9301022291 0.9371793866 0.8918790817 + 0.9305281043 0.9375948906 0.8924124241 + 0.9309539795 0.9380103946 0.8929455876 + 0.9313746095 0.9384258986 0.8934788108 + 0.9317831993 0.9388350248 0.8940120935 + 0.9321917892 0.9392321110 0.8945347071 + 0.9326003790 0.9396290779 0.8950567245 + 0.9330090880 0.9400262237 0.8955786824 + 0.9334176779 0.9404231906 0.8961006999 + 0.9338263273 0.9408202767 0.8966227770 + 0.9342349172 0.9412173033 0.8971447945 + 0.9346324205 0.9416143894 0.8976668119 + 0.9350271821 0.9419872165 0.8981863856 + 0.9354221225 0.9423564076 0.8987035155 + 0.9358168840 0.9427254796 0.8992205262 + 0.9362118244 0.9430946708 0.8997374773 + 0.9366065860 0.9434638023 0.9002544880 + 0.9370014071 0.9438329935 0.9007714987 + 0.9373939037 0.9442021251 0.9012885094 + 0.9377782941 0.9445647001 0.9018055797 + 0.9381626844 0.9449126720 0.9023094177 + 0.9385470748 0.9452607036 0.9028121829 + 0.9389315844 0.9456086159 0.9033150077 + 0.9393159747 0.9459565878 0.9038177729 + 0.9397004247 0.9463046193 0.9043205976 + 0.9400848150 0.9466525912 0.9048234224 + 0.9404577017 0.9470005035 0.9053261876 + 0.9408218265 0.9473389983 0.9058225155 + 0.9411860108 0.9476727843 0.9063037038 + 0.9415500760 0.9480065703 0.9067848921 + 0.9419142008 0.9483404160 0.9072660804 + 0.9422783852 0.9486742020 0.9077473283 + 0.9426425099 0.9490079880 0.9082283974 + 0.9430066943 0.9493417740 0.9087095857 + 0.9433518052 0.9496756196 0.9091907740 + 0.9436928034 0.9499998093 0.9096608162 + 0.9440338016 0.9503235817 0.9101228118 + 0.9443747997 0.9506472945 0.9105848074 + 0.9447157979 0.9509710073 0.9110468030 + 0.9450569153 0.9512947202 0.9115087986 + 0.9453979135 0.9516184926 0.9119707942 + 0.9457389116 0.9519422054 0.9124327898 + 0.9460589290 0.9522647262 0.9128947854 + 0.9463787079 0.9525792003 0.9133455157 + 0.9466984868 0.9528936744 0.9137930870 + 0.9470183253 0.9532083273 0.9142407179 + 0.9473382235 0.9535228014 0.9146882296 + 0.9476580024 0.9538373947 0.9151358008 + 0.9479777813 0.9541519284 0.9155833721 + 0.9482966065 0.9544664025 0.9160308838 + 0.9486029744 0.9547755718 0.9164785147 + 0.9489094019 0.9550681114 0.9169083238 + 0.9492158294 0.9553607106 0.9173362255 + 0.9495223165 0.9556531906 0.9177641273 + 0.9498286843 0.9559456706 0.9181920290 + 0.9501351118 0.9562382102 0.9186198115 + 0.9504414797 0.9565308094 0.9190477133 + 0.9507477880 0.9568232894 0.9194756150 + 0.9510523081 0.9571123123 0.9199035168 + 0.9513568878 0.9573916793 0.9203202724 + 0.9516614079 0.9576711059 0.9207363725 + 0.9519659877 0.9579504728 0.9211524725 + 0.9522706270 0.9582298994 0.9215685129 + 0.9525750875 0.9585093260 0.9219846129 + 0.9528797269 0.9587886930 0.9224005938 + 0.9531841874 0.9590681195 0.9228166938 + 0.9534816146 0.9593474865 0.9232327938 + 0.9537789822 0.9596264958 0.9236450791 + 0.9540762901 0.9599055052 0.9240568280 + 0.9543737173 0.9601845145 0.9244685769 + 0.9546710253 0.9604635239 0.9248803854 + 0.9549683928 0.9607424736 0.9252920747 + 0.9552657008 0.9610214829 0.9257038832 + 0.9555630088 0.9613004923 0.9261155725 + 0.9558495283 0.9615790844 0.9265273809 + 0.9561336040 0.9618505239 0.9269320965 + 0.9564176202 0.9621219039 0.9273340702 + 0.9567016959 0.9623932838 0.9277362227 + 0.9569857121 0.9626647234 0.9281383157 + 0.9572697878 0.9629361033 0.9285402894 + 0.9575538039 0.9632074833 0.9289423823 + 0.9578378797 0.9634789228 0.9293444157 + 0.9581202269 0.9637503028 0.9297465086 + 0.9584012032 0.9640163779 0.9301460981 + 0.9586821795 0.9642812014 0.9305431843 + 0.9589632154 0.9645460248 0.9309402704 + 0.9592441916 0.9648107886 0.9313374758 + 0.9595252872 0.9650756121 0.9317346215 + 0.9598063231 0.9653403759 0.9321317077 + 0.9600872993 0.9656051993 0.9325287938 + 0.9603686929 0.9658700228 0.9329259992 + 0.9606518149 0.9661340714 0.9333214760 + 0.9609349966 0.9663974047 0.9337096810 + 0.9612181187 0.9666607976 0.9340978265 + 0.9615011811 0.9669241905 0.9344859719 + 0.9617843032 0.9671875238 0.9348741770 + 0.9620674253 0.9674509168 0.9352623820 + 0.9623506069 0.9677141905 0.9356505871 + 0.9626337290 0.9679775834 0.9360387921 + 0.9629138708 0.9682406783 0.9364269972 + 0.9631931782 0.9685000777 0.9368088841 + 0.9634724855 0.9687594771 0.9371889234 + 0.9637517929 0.9690188169 0.9375690222 + 0.9640312195 0.9692782164 0.9379490018 + 0.9643105268 0.9695376158 0.9383289814 + 0.9645897746 0.9697968960 0.9387090802 + 0.9648690820 0.9700562954 0.9390891194 + 0.9651448727 0.9703155756 0.9394692183 + 0.9654085040 0.9705702066 0.9398465157 + 0.9656721950 0.9708209038 0.9402164221 + 0.9659358263 0.9710716009 0.9405863881 + 0.9661995173 0.9713222980 0.9409562945 + 0.9664632082 0.9715729952 0.9413263202 + 0.9667267799 0.9718236923 0.9416962266 + 0.9669904709 0.9720743895 0.9420661926 + 0.9672541022 0.9723250866 0.9424360991 + 0.9675124884 0.9725757241 0.9428061247 + 0.9677672982 0.9728142023 0.9431679249 + 0.9680221081 0.9730519056 0.9435257912 + 0.9682769179 0.9732896090 0.9438837171 + 0.9685317278 0.9735273123 0.9442415833 + 0.9687864780 0.9737650752 0.9445996284 + 0.9690412879 0.9740027785 0.9449574947 + 0.9692960978 0.9742404819 0.9453154206 + 0.9695509076 0.9744781852 0.9456732869 + 0.9698060155 0.9747121930 0.9460312128 + 0.9700611830 0.9749348760 0.9463843107 + 0.9703164101 0.9751574993 0.9467371702 + 0.9705715179 0.9753801823 0.9470902085 + 0.9708266854 0.9756028056 0.9474431276 + 0.9710819125 0.9758254886 0.9477961063 + 0.9713370800 0.9760481715 0.9481490254 + 0.9715921879 0.9762707949 0.9485020041 + 0.9718468189 0.9764934778 0.9488549829 + 0.9720928073 0.9767106771 0.9492064714 + 0.9723387957 0.9769214988 0.9495524764 + 0.9725847840 0.9771322012 0.9498984814 + 0.9728307724 0.9773430228 0.9502444863 + 0.9730768204 0.9775537848 0.9505904913 + 0.9733228087 0.9777646065 0.9509364963 + 0.9735687971 0.9779753089 0.9512825012 + 0.9738147855 0.9781860709 0.9516285062 + 0.9740588069 0.9783968925 0.9519745111 + 0.9742915034 0.9786027074 0.9523156285 + 0.9745242000 0.9788047075 0.9526464939 + 0.9747567773 0.9790067077 0.9529774189 + 0.9749894738 0.9792087078 0.9533084035 + 0.9752221704 0.9794108272 0.9536393285 + 0.9754549265 0.9796128273 0.9539703131 + 0.9756876230 0.9798148274 0.9543011785 + 0.9759202003 0.9800168276 0.9546322227 + 0.9761514068 0.9802188277 0.9549630880 + 0.9763734937 0.9804111123 0.9552907944 + 0.9765955806 0.9805964828 0.9556127787 + 0.9768176079 0.9807819128 0.9559348226 + 0.9770396948 0.9809672832 0.9562568069 + 0.9772617817 0.9811527133 0.9565787911 + 0.9774839282 0.9813380837 0.9569007754 + 0.9777060151 0.9815235138 0.9572228193 + 0.9779281020 0.9817088842 0.9575446844 + 0.9781497121 0.9818943143 0.9578667283 + 0.9783595204 0.9820705056 0.9581860900 + 0.9785693884 0.9822378159 0.9584987760 + 0.9787791967 0.9824051261 0.9588115811 + 0.9789891243 0.9825723767 0.9591243267 + 0.9791988730 0.9827396870 0.9594370723 + 0.9794088006 0.9829071164 0.9597498178 + 0.9796186090 0.9830744267 0.9600626230 + 0.9798284769 0.9832416773 0.9603753090 + 0.9800382853 0.9834089875 0.9606881142 + 0.9802370071 0.9835721850 0.9609987736 + 0.9804332852 0.9837269783 0.9612951279 + 0.9806296825 0.9838817716 0.9615914822 + 0.9808260202 0.9840366244 0.9618877769 + 0.9810224175 0.9841914177 0.9621840715 + 0.9812188148 0.9843462110 0.9624804258 + 0.9814150929 0.9845011234 0.9627767205 + 0.9816114902 0.9846559167 0.9630730152 + 0.9818078279 0.9848107100 0.9633693099 + 0.9819964767 0.9849649072 0.9636656046 + 0.9821782112 0.9851077199 0.9639506936 + 0.9823600054 0.9852504730 0.9642338157 + 0.9825417995 0.9853932858 0.9645169973 + 0.9827235937 0.9855362177 0.9648001790 + 0.9829053879 0.9856789708 0.9650833011 + 0.9830871224 0.9858217835 0.9653664827 + 0.9832689166 0.9859645963 0.9656497240 + 0.9834507108 0.9861074090 0.9659329057 + 0.9836298227 0.9862502217 0.9662160277 + 0.9837905765 0.9863815904 0.9664933085 + 0.9839512706 0.9865074158 0.9667642713 + 0.9841120243 0.9866331816 0.9670352936 + 0.9842727780 0.9867590070 0.9673063159 + 0.9844334722 0.9868847728 0.9675772786 + 0.9845942855 0.9870105982 0.9678484201 + 0.9847549796 0.9871364236 0.9681193829 + 0.9849156737 0.9872621894 0.9683904052 + 0.9850764871 0.9873880148 0.9686614275 + 0.9852262139 0.9875094891 0.9689320922 + 0.9853692055 0.9876127243 0.9691805243 + 0.9855121970 0.9877158999 0.9694290161 + 0.9856551886 0.9878190160 0.9696773887 + 0.9857981801 0.9879221916 0.9699258208 + 0.9859411120 0.9880254269 0.9701743126 + 0.9860841036 0.9881286025 0.9704226851 + 0.9862270951 0.9882317781 0.9706711769 + 0.9863700867 0.9883350134 0.9709196091 + 0.9865130186 0.9884381890 0.9711681008 + 0.9866449833 0.9885314703 0.9714096785 + 0.9867771268 0.9886183739 0.9716426134 + 0.9869090915 0.9887052774 0.9718756080 + 0.9870411754 0.9887921810 0.9721086025 + 0.9871733189 0.9888790846 0.9723415971 + 0.9873052835 0.9889659882 0.9725744724 + 0.9874374270 0.9890528917 0.9728075266 + 0.9875693917 0.9891397953 0.9730405211 + 0.9877014756 0.9892266989 0.9732735157 + 0.9878289104 0.9893134832 0.9735063910 + 0.9879450202 0.9893946052 0.9737377763 + 0.9880610704 0.9894750714 0.9739686251 + 0.9881772995 0.9895555973 0.9741994739 + 0.9882934093 0.9896361232 0.9744303226 + 0.9884095192 0.9897165895 0.9746611714 + 0.9885256886 0.9897971153 0.9748920202 + 0.9886417985 0.9898777008 0.9751229286 + 0.9887579083 0.9899582267 0.9753537774 + 0.9888740778 0.9900386930 0.9755846262 + 0.9889798164 0.9901186228 0.9758154750 + 0.9890741706 0.9901947975 0.9760391712 + 0.9891685247 0.9902709723 0.9762626886 + 0.9892628193 0.9903472066 0.9764863253 + 0.9893571138 0.9904233813 0.9767099023 + 0.9894514084 0.9904996157 0.9769334793 + 0.9895458221 0.9905757904 0.9771571159 + 0.9896401167 0.9906520247 0.9773806930 + 0.9897344112 0.9907281995 0.9776043296 + 0.9898287058 0.9908043742 0.9778279066 + 0.9899169207 0.9908795953 0.9780502915 + 0.9900001884 0.9909514785 0.9782621861 + 0.9900833964 0.9910233021 0.9784740806 + 0.9901666045 0.9910951853 0.9786859751 + 0.9902498126 0.9911670089 0.9788979292 + 0.9903330207 0.9912388921 0.9791098237 + 0.9904162884 0.9913107157 0.9793217182 + 0.9904994965 0.9913825989 0.9795336127 + 0.9905827045 0.9914544225 0.9797455072 + 0.9906659126 0.9915261865 0.9799574018 + 0.9907503128 0.9915974736 0.9801694751 + 0.9908356071 0.9916664958 0.9803833961 + 0.9909210205 0.9917355180 0.9805971980 + 0.9910063744 0.9918044806 0.9808109999 + 0.9910917878 0.9918735027 0.9810249209 + 0.9911772013 0.9919425249 0.9812387228 + 0.9912626147 0.9920114875 0.9814525247 + 0.9913480282 0.9920805097 0.9816663861 + 0.9914333820 0.9921495914 0.9818801880 + 0.9915186763 0.9922186136 0.9820939898 + 0.9916055202 0.9922881126 0.9823077917 + 0.9916943908 0.9923617244 0.9825233221 + 0.9917833805 0.9924353957 0.9827387929 + 0.9918723106 0.9925091267 0.9829543233 + 0.9919611812 0.9925826788 0.9831697941 + 0.9920501709 0.9926564097 0.9833853245 + 0.9921391010 0.9927300215 0.9836007953 + 0.9922280908 0.9928036928 0.9838163257 + 0.9923170209 0.9928774238 0.9840317965 + 0.9924060106 0.9929509759 0.9842473269 + 0.9924944043 0.9930247068 0.9844626784 + 0.9925794005 0.9931048155 0.9846640825 + 0.9926643968 0.9931856990 0.9848614931 + 0.9927493930 0.9932667017 0.9850590229 + 0.9928343892 0.9933475852 0.9852564931 + 0.9929193854 0.9934285283 0.9854540229 + 0.9930043817 0.9935094714 0.9856514931 + 0.9930893779 0.9935904145 0.9858490229 + 0.9931743741 0.9936712980 0.9860464931 + 0.9932593703 0.9937523007 0.9862440228 + 0.9933443069 0.9938331842 0.9864414930 + 0.9934259057 0.9939159155 0.9866343737 + 0.9935063124 0.9940000772 0.9868218899 + 0.9935867786 0.9940842986 0.9870094061 + 0.9936671853 0.9941684008 0.9871969223 + 0.9937477112 0.9942526221 0.9873843789 + 0.9938281178 0.9943367243 0.9875720143 + 0.9939085841 0.9944208860 0.9877594709 + 0.9939889908 0.9945051074 0.9879469872 + 0.9940693974 0.9945892096 0.9881345034 + 0.9941499233 0.9946733713 0.9883220792 + 0.9942312241 0.9947574139 0.9885097146 + 0.9943147898 0.9948405027 0.9887015224 + 0.9943982959 0.9949235916 0.9888933897 + 0.9944819212 0.9950066805 0.9890851974 + 0.9945654869 0.9950898290 0.9892770052 + 0.9946489930 0.9951729178 0.9894688129 + 0.9947326183 0.9952560067 0.9896606803 + 0.9948161840 0.9953390956 0.9898524880 + 0.9948996902 0.9954221845 0.9900442958 + 0.9949833155 0.9955052733 0.9902361035 + 0.9950668812 0.9955884218 0.9904279709 + 0.9951515198 0.9956672788 0.9906188846 + 0.9952365160 0.9957426190 0.9908090234 + 0.9953215122 0.9958178997 0.9909991026 + 0.9954065084 0.9958932996 0.9911891818 + 0.9954916239 0.9959685802 0.9913793206 + 0.9955766201 0.9960439205 0.9915693998 + 0.9956616163 0.9961193204 0.9917594790 + 0.9957466722 0.9961946011 0.9919496179 + 0.9958317280 0.9962698817 0.9921396971 + 0.9959167242 0.9963452816 0.9923297763 + 0.9960017800 0.9964206219 0.9925199151 + 0.9960864782 0.9964954853 0.9927043915 + 0.9961711764 0.9965702891 0.9928877950 + 0.9962558746 0.9966450930 0.9930710793 + 0.9963405728 0.9967198968 0.9932544231 + 0.9964252710 0.9967947006 0.9934378266 + 0.9965100288 0.9968695045 0.9936211109 + 0.9965947270 0.9969443083 0.9938043952 + 0.9966794252 0.9970191121 0.9939877987 + 0.9967641234 0.9970939159 0.9941710830 + 0.9968488216 0.9971687198 0.9943544269 + 0.9969335198 0.9972440004 0.9945374727 + 0.9970176220 0.9973254204 0.9947144985 + 0.9971017241 0.9974067807 0.9948914051 + 0.9971858859 0.9974880815 0.9950683117 + 0.9972699881 0.9975695014 0.9952452779 + 0.9973540902 0.9976508021 0.9954221845 + 0.9974381924 0.9977322221 0.9955992103 + 0.9975224137 0.9978135824 0.9957761168 + 0.9976065159 0.9978948832 0.9959530830 + 0.9976906180 0.9979763031 0.9961299896 + 0.9977747798 0.9980576038 0.9963068962 + 0.9978600740 0.9981396198 0.9964826107 + 0.9979493022 0.9982247949 0.9966511130 + 0.9980384707 0.9983099103 0.9968194962 + 0.9981275797 0.9983950257 0.9969878793 + 0.9982168078 0.9984800816 0.9971563220 + 0.9983059764 0.9985653162 0.9973248243 + 0.9983952045 0.9986503720 0.9974932075 + 0.9984843731 0.9987354875 0.9976615906 + 0.9985736012 0.9988206029 0.9978299737 + 0.9986627102 0.9989057779 0.9979984760 + 0.9987518787 0.9989908934 0.9981669188 + 0.9988439083 0.9990757704 0.9983330965 + 0.9989489913 0.9991598725 0.9984846115 + 0.9990540743 0.9992439151 0.9986361265 + 0.9991592169 0.9993278980 0.9987877011 + 0.9992642999 0.9994118810 0.9989392161 + 0.9993693829 0.9994959235 0.9990907907 + 0.9994745255 0.9995799065 0.9992423058 + 0.9995796084 0.9996638894 0.9993938208 + 0.9996846914 0.9997479916 0.9995453954 + 0.9997897744 0.9998319745 0.9996969104 + 0.9998949170 0.9999160171 0.9998484850 + 1.0000000000 1.0000000000 1.0000000000 +} diff --git a/rpplugins/color_correction/resources/film_luts_raw/kodak_kodachrome_25.spi1d b/rpplugins/color_correction/resources/film_luts_raw/kodak_kodachrome_25.spi1d new file mode 100644 index 0000000..b450b1b --- /dev/null +++ b/rpplugins/color_correction/resources/film_luts_raw/kodak_kodachrome_25.spi1d @@ -0,0 +1,1030 @@ +Version 1 +From 0.0 1.0 +Length 1024 +Components 3 +{ + 0.0000000000 0.0000000000 0.0000000000 + 0.0001187211 0.0001161198 0.0001305900 + 0.0002416660 0.0002335670 0.0002639299 + 0.0003686174 0.0003530100 0.0003996764 + 0.0004986166 0.0004744168 0.0005390237 + 0.0006320932 0.0005989556 0.0006801367 + 0.0007689670 0.0007275027 0.0008226076 + 0.0009098884 0.0008590615 0.0009674262 + 0.0010546240 0.0009952968 0.0011148060 + 0.0012056520 0.0011357040 0.0012659699 + 0.0013610790 0.0012804960 0.0014208819 + 0.0015210240 0.0014290370 0.0015805050 + 0.0016857639 0.0015831300 0.0017423360 + 0.0018555140 0.0017423540 0.0019072110 + 0.0020300581 0.0019068220 0.0020741550 + 0.0022078981 0.0020767010 0.0022443461 + 0.0023916010 0.0022511871 0.0024184019 + 0.0025805370 0.0024301831 0.0025977520 + 0.0027740600 0.0026134001 0.0027815269 + 0.0029722259 0.0028022721 0.0029672419 + 0.0031753390 0.0029984950 0.0031548510 + 0.0033845089 0.0032002409 0.0033454280 + 0.0036013669 0.0034078530 0.0035393371 + 0.0038235600 0.0036215940 0.0037365381 + 0.0040512760 0.0038406281 0.0039370959 + 0.0042870231 0.0040662498 0.0041424572 + 0.0045294450 0.0042975969 0.0043519312 + 0.0047791190 0.0045345472 0.0045640962 + 0.0050357901 0.0047785440 0.0047785449 + 0.0052975160 0.0050289081 0.0049969312 + 0.0055647590 0.0052849171 0.0052185720 + 0.0058401441 0.0055476031 0.0054451409 + 0.0061251819 0.0058162622 0.0056769978 + 0.0064190081 0.0060910610 0.0059134620 + 0.0067208251 0.0063716578 0.0061544981 + 0.0070298752 0.0066589769 0.0064014881 + 0.0073465379 0.0069537512 0.0066520870 + 0.0076715760 0.0072558299 0.0069075110 + 0.0080045266 0.0075645968 0.0071683591 + 0.0083457762 0.0078814235 0.0074348552 + 0.0086941188 0.0082036890 0.0077047022 + 0.0090481956 0.0085330773 0.0079792934 + 0.0094094584 0.0088689746 0.0082590310 + 0.0097797252 0.0092114061 0.0085430183 + 0.0101604396 0.0095595680 0.0088318810 + 0.0105508799 0.0099120708 0.0091247372 + 0.0109501397 0.0102693997 0.0094229234 + 0.0113572897 0.0106335897 0.0097273486 + 0.0117729101 0.0110058896 0.0100365505 + 0.0121964402 0.0113846296 0.0103524001 + 0.0126260100 0.0117704803 0.0106731104 + 0.0130626997 0.0121654198 0.0109990695 + 0.0135076502 0.0125680296 0.0113301203 + 0.0139606902 0.0129768401 0.0116658099 + 0.0144202998 0.0133933499 0.0120067801 + 0.0148866000 0.0138179902 0.0123553397 + 0.0153607102 0.0142508997 0.0127089303 + 0.0158437602 0.0146913100 0.0130658597 + 0.0163364708 0.0151374601 0.0134272100 + 0.0168359205 0.0155895501 0.0137940804 + 0.0173442401 0.0160493609 0.0141672902 + 0.0178608205 0.0165161695 0.0145466598 + 0.0183882900 0.0169901606 0.0149336299 + 0.0189235695 0.0174715705 0.0153278597 + 0.0194664709 0.0179615095 0.0157276094 + 0.0200162604 0.0184623506 0.0161328409 + 0.0205752291 0.0189736001 0.0165440794 + 0.0211429205 0.0194928199 0.0169631094 + 0.0217175093 0.0200189203 0.0173870400 + 0.0222972203 0.0205519404 0.0178171601 + 0.0228821803 0.0210929699 0.0182553697 + 0.0234732702 0.0216418691 0.0187003091 + 0.0240713898 0.0221973900 0.0191515498 + 0.0246774498 0.0227600299 0.0196103808 + 0.0252923407 0.0233312007 0.0200770292 + 0.0259165801 0.0239111893 0.0205497108 + 0.0265481994 0.0245017596 0.0210285001 + 0.0271885395 0.0251027998 0.0215149205 + 0.0278372504 0.0257091504 0.0220096204 + 0.0284956601 0.0263228696 0.0225120597 + 0.0291631296 0.0269445796 0.0230217203 + 0.0298364591 0.0275744200 0.0235392991 + 0.0305197891 0.0282128304 0.0240652803 + 0.0312113408 0.0288609006 0.0246002506 + 0.0319130905 0.0295199603 0.0251446608 + 0.0326239392 0.0301856901 0.0256962199 + 0.0333417691 0.0308586191 0.0262538604 + 0.0340690203 0.0315388404 0.0268181600 + 0.0347989090 0.0322262309 0.0273908004 + 0.0355309397 0.0329242386 0.0279702805 + 0.0362654515 0.0336307585 0.0285563804 + 0.0370042995 0.0343444385 0.0291495994 + 0.0377499983 0.0350654498 0.0297501199 + 0.0385023095 0.0357952416 0.0303586796 + 0.0392612107 0.0365385190 0.0309723206 + 0.0400277786 0.0372893997 0.0315904692 + 0.0408011489 0.0380479097 0.0322141387 + 0.0415779687 0.0388149507 0.0328444093 + 0.0423575304 0.0395870805 0.0334823392 + 0.0431431308 0.0403656401 0.0341259614 + 0.0439345613 0.0411506817 0.0347744413 + 0.0447305702 0.0419436581 0.0354271904 + 0.0455311611 0.0427440405 0.0360897183 + 0.0463386402 0.0435508788 0.0367595218 + 0.0471522398 0.0443644710 0.0374358408 + 0.0479747392 0.0451885909 0.0381190106 + 0.0488112308 0.0460180305 0.0388101190 + 0.0496566407 0.0468529202 0.0395072289 + 0.0505135618 0.0476984307 0.0402105600 + 0.0513870418 0.0485514998 0.0409212708 + 0.0522648282 0.0494111106 0.0416350588 + 0.0531454012 0.0502829701 0.0423520505 + 0.0540309697 0.0511616506 0.0430774391 + 0.0549204089 0.0520450994 0.0438090898 + 0.0558179915 0.0529359803 0.0445459113 + 0.0567257814 0.0538352691 0.0452902392 + 0.0576398782 0.0547406413 0.0460413806 + 0.0585679710 0.0556575507 0.0467979498 + 0.0595032796 0.0565782711 0.0475642905 + 0.0604466088 0.0575027503 0.0483360402 + 0.0614023097 0.0584334396 0.0491129309 + 0.0623621605 0.0593668409 0.0499006808 + 0.0633294508 0.0603048317 0.0506933182 + 0.0643018410 0.0612500012 0.0514932014 + 0.0652783364 0.0621989109 0.0522950403 + 0.0662618205 0.0631573200 0.0530990995 + 0.0672477037 0.0641201437 0.0539113805 + 0.0682398304 0.0650890917 0.0547297895 + 0.0692377687 0.0660655573 0.0555534288 + 0.0702422187 0.0670448914 0.0563857108 + 0.0712599233 0.0680295005 0.0572213605 + 0.0722822472 0.0690181032 0.0580649488 + 0.0733231679 0.0700139031 0.0589125901 + 0.0743673295 0.0710175782 0.0597636290 + 0.0754222274 0.0720258802 0.0606212094 + 0.0764820576 0.0730462894 0.0614807904 + 0.0775483102 0.0740699619 0.0623459816 + 0.0786194429 0.0751056671 0.0632140934 + 0.0796934590 0.0761416107 0.0640869290 + 0.0807745531 0.0771779865 0.0649647191 + 0.0818573833 0.0782172531 0.0658454672 + 0.0829574317 0.0792589337 0.0667318478 + 0.0840600133 0.0803091377 0.0676197112 + 0.0851803720 0.0813626423 0.0685161799 + 0.0863037184 0.0824246481 0.0694149882 + 0.0874389708 0.0834880322 0.0703213289 + 0.0885784179 0.0845618397 0.0712313801 + 0.0897280127 0.0856374800 0.0721469596 + 0.0908830017 0.0867242888 0.0730709806 + 0.0920473710 0.0878123492 0.0740019605 + 0.0932181776 0.0889043733 0.0749416873 + 0.0943980217 0.0899982378 0.0758856833 + 0.0955819637 0.0910960734 0.0768347234 + 0.0967710093 0.0921994597 0.0777852014 + 0.0979645699 0.0933120996 0.0787435994 + 0.0991635621 0.0944301113 0.0797032714 + 0.1003675982 0.0955557898 0.0806734487 + 0.1015781984 0.0966856703 0.0816444829 + 0.1027939990 0.0978211835 0.0826287419 + 0.1040176004 0.0989596322 0.0836134627 + 0.1052478999 0.1001020968 0.0846056491 + 0.1064907983 0.1012483984 0.0855979323 + 0.1077373996 0.1024006978 0.0865952373 + 0.1089940965 0.1035557985 0.0875926092 + 0.1102522984 0.1047163978 0.0886019021 + 0.1115181968 0.1058802009 0.0896116272 + 0.1127844006 0.1070526987 0.0906278268 + 0.1140555963 0.1082267985 0.0916445777 + 0.1153267995 0.1094079986 0.0926688984 + 0.1166016012 0.1105891988 0.0936945230 + 0.1178767011 0.1117718965 0.0947236270 + 0.1191575974 0.1129546016 0.0957538188 + 0.1204406992 0.1141434982 0.0967877209 + 0.1217328012 0.1153329015 0.0978235975 + 0.1230328009 0.1165269986 0.0988596827 + 0.1243387014 0.1177226007 0.0998959318 + 0.1256576031 0.1189235002 0.1009349972 + 0.1269775033 0.1201286018 0.1019790992 + 0.1283123046 0.1213376969 0.1030249000 + 0.1296471059 0.1225541010 0.1040780023 + 0.1309920996 0.1237716004 0.1051312014 + 0.1323397011 0.1249968037 0.1061976030 + 0.1336949021 0.1262219995 0.1072641984 + 0.1350574046 0.1274487972 0.1083405018 + 0.1364232004 0.1286759973 0.1094200984 + 0.1378028989 0.1299048960 0.1105057970 + 0.1391825974 0.1311350018 0.1115979999 + 0.1405749023 0.1323675066 0.1126938015 + 0.1419695020 0.1336061060 0.1138031036 + 0.1433696002 0.1348447949 0.1149123013 + 0.1447755992 0.1360920966 0.1160330996 + 0.1461827010 0.1373400986 0.1171550006 + 0.1476009935 0.1385940015 0.1182890981 + 0.1490193009 0.1398521960 0.1194318980 + 0.1504455954 0.1411112994 0.1205772012 + 0.1518757045 0.1423743069 0.1217304021 + 0.1533088982 0.1436371952 0.1228836030 + 0.1547531039 0.1449093074 0.1240445971 + 0.1561972052 0.1461839974 0.1252069026 + 0.1576558948 0.1474615037 0.1263778955 + 0.1591195017 0.1487443000 0.1275596023 + 0.1605871022 0.1500270963 0.1287415028 + 0.1620666981 0.1513230950 0.1299324036 + 0.1635462940 0.1526210010 0.1311233938 + 0.1650296003 0.1539209038 0.1323246062 + 0.1665142030 0.1552240998 0.1335338056 + 0.1680004001 0.1565274000 0.1347434968 + 0.1694938987 0.1578350067 0.1359594017 + 0.1709873974 0.1591434032 0.1371753067 + 0.1724853069 0.1604537964 0.1383929998 + 0.1739861071 0.1617684960 0.1396120936 + 0.1754869968 0.1630831063 0.1408315003 + 0.1769933999 0.1644009054 0.1420598030 + 0.1784998029 0.1657195985 0.1432881951 + 0.1800076067 0.1670403928 0.1445214003 + 0.1815180033 0.1683724970 0.1457598060 + 0.1830282956 0.1697044969 0.1469981968 + 0.1845442951 0.1710446030 0.1482491940 + 0.1860629022 0.1723918021 0.1495018005 + 0.1875815988 0.1737388968 0.1507571042 + 0.1891085953 0.1750912964 0.1520196050 + 0.1906356961 0.1764443964 0.1532821953 + 0.1921654046 0.1777988970 0.1545532942 + 0.1937022060 0.1791588962 0.1558299065 + 0.1952389926 0.1805189997 0.1571063995 + 0.1967843026 0.1818803996 0.1583925039 + 0.1983377039 0.1832433045 0.1596792042 + 0.1998911053 0.1846061945 0.1609704942 + 0.2014496028 0.1859742999 0.1622772068 + 0.2030100971 0.1873442978 0.1635839045 + 0.2045706064 0.1887143999 0.1648986936 + 0.2061385065 0.1900894940 0.1662220061 + 0.2077071965 0.1914649010 0.1675451994 + 0.2092768997 0.1928412020 0.1688794047 + 0.2108619064 0.1942230016 0.1702177972 + 0.2124470025 0.1956048012 0.1715561002 + 0.2140337974 0.1969860941 0.1729072928 + 0.2156284004 0.1983664036 0.1742596030 + 0.2172230035 0.1997465938 0.1756128073 + 0.2188204974 0.2011310011 0.1769745052 + 0.2204252034 0.2025205046 0.1783363074 + 0.2220298946 0.2039099038 0.1797029972 + 0.2236385942 0.2053045928 0.1810847074 + 0.2252545953 0.2067034990 0.1824664026 + 0.2268707007 0.2081024051 0.1838538945 + 0.2284909934 0.2095097005 0.1852518022 + 0.2301183045 0.2109221071 0.1866496950 + 0.2317456007 0.2123343945 0.1880539954 + 0.2333762050 0.2137437016 0.1894665956 + 0.2350125015 0.2151515931 0.1908791959 + 0.2366486937 0.2165593952 0.1922982931 + 0.2382874936 0.2179677039 0.1937243044 + 0.2399311960 0.2193762958 0.1951504052 + 0.2415750027 0.2207849026 0.1965806931 + 0.2432212979 0.2221989036 0.1980153024 + 0.2448745072 0.2236157060 0.1994500011 + 0.2465275973 0.2250325978 0.2008942068 + 0.2481831014 0.2264544070 0.2023486942 + 0.2498493940 0.2278795987 0.2038031965 + 0.2515155971 0.2293048054 0.2052644044 + 0.2531822920 0.2307375968 0.2067341059 + 0.2548569143 0.2321777046 0.2082037032 + 0.2565315068 0.2336179018 0.2096809000 + 0.2582060993 0.2350665033 0.2111717016 + 0.2598899007 0.2365286052 0.2126623988 + 0.2615750134 0.2379907966 0.2141568065 + 0.2632600963 0.2394558936 0.2156627029 + 0.2649540901 0.2409311980 0.2171684951 + 0.2666524947 0.2424065024 0.2186762989 + 0.2683508992 0.2438821048 0.2202025950 + 0.2700530887 0.2453690022 0.2217289060 + 0.2717601955 0.2468558997 0.2232550979 + 0.2734673023 0.2483427972 0.2247944027 + 0.2751758993 0.2498389930 0.2263347954 + 0.2768929005 0.2513372898 0.2278753072 + 0.2786099911 0.2528356910 0.2294308990 + 0.2803269923 0.2543384135 0.2309931070 + 0.2820504904 0.2558448911 0.2325553000 + 0.2837752998 0.2573513091 0.2341264933 + 0.2854999900 0.2588596940 0.2357089967 + 0.2872273922 0.2603740990 0.2372916043 + 0.2889575064 0.2618885040 0.2388751954 + 0.2906875908 0.2634029090 0.2404648066 + 0.2924185097 0.2649247050 0.2420545071 + 0.2941546142 0.2664470971 0.2436441034 + 0.2958906889 0.2679696083 0.2452432960 + 0.2976269126 0.2694908977 0.2468443960 + 0.2993660867 0.2710112929 0.2484454066 + 0.3011066020 0.2725316882 0.2500450909 + 0.3028470874 0.2740519941 0.2516433001 + 0.3045875132 0.2755717933 0.2532413900 + 0.3063274026 0.2770917118 0.2548404038 + 0.3080672026 0.2786116004 0.2564507127 + 0.3098070920 0.2801361978 0.2580609918 + 0.3115398884 0.2816629112 0.2596713006 + 0.3132705092 0.2831897140 0.2612847984 + 0.3150011003 0.2847178876 0.2629001141 + 0.3167325854 0.2862516940 0.2645153999 + 0.3184674084 0.2877854109 0.2661319077 + 0.3202022016 0.2893190980 0.2677547932 + 0.3219369948 0.2908464968 0.2693777084 + 0.3236666918 0.2923713028 0.2710005045 + 0.3253937066 0.2938959897 0.2726289034 + 0.3271206915 0.2954205871 0.2742598951 + 0.3288466036 0.2969438136 0.2758910060 + 0.3305548131 0.2984670103 0.2775225043 + 0.3322629035 0.2999902070 0.2791568041 + 0.3339709938 0.3015184104 0.2807911932 + 0.3356797099 0.3030506968 0.2824254930 + 0.3373891115 0.3045830131 0.2840622962 + 0.3390985131 0.3061152101 0.2857011855 + 0.3408079147 0.3076440990 0.2873399854 + 0.3425270021 0.3091726899 0.2889789045 + 0.3442499042 0.3107013106 0.2906231880 + 0.3459726870 0.3122313023 0.2922680080 + 0.3476955891 0.3137654960 0.2939127982 + 0.3494232893 0.3152998090 0.2955600917 + 0.3511509895 0.3168340027 0.2972145975 + 0.3528788090 0.3183681071 0.2988691032 + 0.3546074033 0.3199020922 0.3005236089 + 0.3563388884 0.3214359879 0.3021857142 + 0.3580704033 0.3229700029 0.3038538992 + 0.3598020077 0.3245058954 0.3055221140 + 0.3615402877 0.3260425031 0.3071902990 + 0.3632878065 0.3275789917 0.3088661134 + 0.3650352955 0.3291155100 0.3105435967 + 0.3667826951 0.3306686878 0.3122211099 + 0.3685362041 0.3322221935 0.3138988018 + 0.3702940941 0.3337756097 0.3155812025 + 0.3720518947 0.3353295028 0.3172636032 + 0.3738098145 0.3368858099 0.3189460039 + 0.3755826056 0.3384419978 0.3206303120 + 0.3773621023 0.3399981856 0.3223223090 + 0.3791415989 0.3415560126 0.3240141869 + 0.3809210956 0.3431178033 0.3257062137 + 0.3827106953 0.3446795046 0.3274028003 + 0.3845036030 0.3462412059 0.3291088939 + 0.3862965107 0.3478037119 0.3308149874 + 0.3880893886 0.3493674099 0.3325211108 + 0.3898766935 0.3509311080 0.3342320919 + 0.3916623890 0.3524948061 0.3359496891 + 0.3934481144 0.3540599942 0.3376674056 + 0.3952338099 0.3556275070 0.3393850923 + 0.3970318139 0.3571951091 0.3411099911 + 0.3988335133 0.3587625921 0.3428429961 + 0.4006352127 0.3603334129 0.3445760012 + 0.4024369121 0.3619092107 0.3463088870 + 0.4042539001 0.3634850085 0.3480437994 + 0.4060774148 0.3650608063 0.3497805893 + 0.4079008996 0.3666354120 0.3515174985 + 0.4097244143 0.3682079017 0.3532544076 + 0.4115552008 0.3697803915 0.3549940884 + 0.4133909941 0.3713529110 0.3567374945 + 0.4152266979 0.3729279935 0.3584809899 + 0.4170624912 0.3745107949 0.3602243960 + 0.4189001918 0.3760935962 0.3619695008 + 0.4207401872 0.3776763082 0.3637174964 + 0.4225800931 0.3792597950 0.3654656112 + 0.4244200885 0.3808481097 0.3672136962 + 0.4262587130 0.3824365139 0.3689666986 + 0.4280926883 0.3840247989 0.3707352877 + 0.4299268126 0.3856132030 0.3725039065 + 0.4317609072 0.3872022033 0.3742724061 + 0.4335947931 0.3887912929 0.3760411143 + 0.4354149997 0.3903804123 0.3778105080 + 0.4372350872 0.3919695020 0.3795798123 + 0.4390552044 0.3935660124 0.3813492060 + 0.4408754110 0.3951654136 0.3831185997 + 0.4426893890 0.3967649043 0.3848997056 + 0.4445011020 0.3983643949 0.3866828084 + 0.4463126957 0.3999699950 0.3884659111 + 0.4481244087 0.4015834928 0.3902488947 + 0.4499397874 0.4031969011 0.3920351863 + 0.4517613053 0.4048103988 0.3938237131 + 0.4535827041 0.4064252973 0.3956122100 + 0.4554041922 0.4080508053 0.3974005878 + 0.4572255909 0.4096763134 0.3991900980 + 0.4590497911 0.4113017917 0.4009819925 + 0.4608739018 0.4129272997 0.4027737975 + 0.4626981020 0.4145581126 0.4045656919 + 0.4645222127 0.4161905944 0.4063574970 + 0.4663369954 0.4178231061 0.4081600904 + 0.4681450129 0.4194557071 0.4099633992 + 0.4699530005 0.4210889935 0.4117667079 + 0.4717608988 0.4227238894 0.4135699868 + 0.4735681117 0.4243587852 0.4153786004 + 0.4753684103 0.4259937108 0.4171918035 + 0.4771685898 0.4276286066 0.4190050066 + 0.4789687991 0.4292654097 0.4208182096 + 0.4807690084 0.4309025109 0.4226312041 + 0.4825682044 0.4325394928 0.4244414866 + 0.4843665957 0.4341765046 0.4262517989 + 0.4861649871 0.4358190894 0.4280619919 + 0.4879634082 0.4374710917 0.4298723042 + 0.4897617102 0.4391230941 0.4316802025 + 0.4915564060 0.4407750964 0.4334864914 + 0.4933511019 0.4424270988 0.4352926910 + 0.4951457083 0.4440836906 0.4370990098 + 0.4969404042 0.4457412958 0.4389046133 + 0.4987323880 0.4473989010 0.4406982064 + 0.5005198121 0.4490565062 0.4424918890 + 0.5023072958 0.4507141113 0.4442855120 + 0.5040947795 0.4523720145 0.4460791945 + 0.5058822036 0.4540297985 0.4478673041 + 0.5076612830 0.4556876123 0.4496487081 + 0.5094367862 0.4573453963 0.4514302015 + 0.5112122893 0.4589950144 0.4532116055 + 0.5129877925 0.4606379867 0.4549930990 + 0.5147632957 0.4622808993 0.4567654133 + 0.5165187120 0.4639238119 0.4585354924 + 0.5182737112 0.4655668139 0.4603056014 + 0.5200287104 0.4672066867 0.4620757997 + 0.5217838287 0.4688459933 0.4638450146 + 0.5235412717 0.4704853892 0.4656072855 + 0.5253081918 0.4721247852 0.4673697054 + 0.5270751119 0.4737643003 0.4691320062 + 0.5288419724 0.4754061103 0.4708943069 + 0.5306090117 0.4770478904 0.4726507962 + 0.5323774219 0.4786897004 0.4743973911 + 0.5341482759 0.4803315997 0.4761438966 + 0.5359191895 0.4819717109 0.4778904021 + 0.5376901031 0.4836075008 0.4796369076 + 0.5394610167 0.4852432907 0.4813722968 + 0.5412335992 0.4868789911 0.4830994010 + 0.5430079103 0.4885148108 0.4848263860 + 0.5447822213 0.4901467860 0.4865534008 + 0.5465564728 0.4917733967 0.4882805049 + 0.5483307838 0.4934000075 0.4900054038 + 0.5500996709 0.4950265884 0.4917294979 + 0.5518643856 0.4966531992 0.4934537113 + 0.5536291003 0.4982692897 0.4951778054 + 0.5553938746 0.4998747110 0.4969018996 + 0.5571585894 0.5014801025 0.4986188114 + 0.5589029789 0.5030853748 0.5003340244 + 0.5606324077 0.5046908259 0.5020492077 + 0.5623617768 0.5062916875 0.5037645102 + 0.5640913248 0.5078886151 0.5054796934 + 0.5658206940 0.5094854236 0.5071663260 + 0.5675324798 0.5110822916 0.5088484883 + 0.5692291260 0.5126792192 0.5105305910 + 0.5709257126 0.5142681003 0.5122128129 + 0.5726222992 0.5158489943 0.5138949156 + 0.5743188858 0.5174300075 0.5155733228 + 0.5760101080 0.5190109015 0.5172510743 + 0.5776947141 0.5205919147 0.5189288259 + 0.5793792009 0.5221624970 0.5206065774 + 0.5810636878 0.5237188935 0.5222843289 + 0.5827482939 0.5252754092 0.5239499807 + 0.5844303966 0.5268318057 0.5256124735 + 0.5861067772 0.5283882022 0.5272750854 + 0.5877830982 0.5299438238 0.5289375782 + 0.5894594789 0.5314972997 0.5306000710 + 0.5911359191 0.5330507159 0.5322602987 + 0.5928109884 0.5346041918 0.5339192748 + 0.5944728255 0.5361576080 0.5355783105 + 0.5961346030 0.5377094746 0.5372374058 + 0.5977964997 0.5392475128 0.5388963819 + 0.5994582772 0.5407854915 0.5405499935 + 0.6011201143 0.5423235297 0.5421981215 + 0.6027656794 0.5438615084 0.5438463092 + 0.6044077277 0.5453994274 0.5454944968 + 0.6060497165 0.5469250083 0.5471426845 + 0.6076918244 0.5484485030 0.5487864017 + 0.6093338132 0.5499718785 0.5504183173 + 0.6109706163 0.5514953732 0.5520501733 + 0.6126019955 0.5530188084 0.5536820292 + 0.6142334938 0.5545319915 0.5553138852 + 0.6158648729 0.5560368896 0.5569456816 + 0.6174963713 0.5575417876 0.5585566759 + 0.6191260219 0.5590466857 0.5601673126 + 0.6207424998 0.5605515838 0.5617777705 + 0.6223589182 0.5620545745 0.5633884072 + 0.6239753962 0.5635496974 0.5649989843 + 0.6255918741 0.5650447011 0.5666049719 + 0.6272084117 0.5665397048 0.5682082772 + 0.6288107038 0.5680348277 0.5698117018 + 0.6304064989 0.5695297718 0.5714150071 + 0.6320024133 0.5710126162 0.5730183125 + 0.6335982084 0.5724920034 0.5746158957 + 0.6351940036 0.5739712715 0.5761947036 + 0.6367834806 0.5754505992 0.5777735114 + 0.6383458972 0.5769299269 0.5793523788 + 0.6399083138 0.5784004927 0.5809311867 + 0.6414706707 0.5798507929 0.5825099945 + 0.6430330873 0.5813010931 0.5840647817 + 0.6445955038 0.5827513933 0.5856127143 + 0.6461372972 0.5842016935 0.5871605873 + 0.6476672888 0.5856518745 0.5887084007 + 0.6491973996 0.5870863795 0.5902562737 + 0.6507273912 0.5885158777 0.5917943120 + 0.6522575021 0.5899453759 0.5933035016 + 0.6537867785 0.5913748741 0.5948126912 + 0.6552811861 0.5928043723 0.5963220000 + 0.6567755938 0.5942304730 0.5978311896 + 0.6582700014 0.5956394076 0.5993403792 + 0.6597645283 0.5970482826 0.6008219123 + 0.6612588763 0.5984572768 0.6022902131 + 0.6627463102 0.5998662114 0.6037583947 + 0.6642202735 0.6012750864 0.6052265763 + 0.6656942964 0.6026799083 0.6066948771 + 0.6671683192 0.6040807962 0.6081615090 + 0.6686422825 0.6054816842 0.6095842719 + 0.6701163054 0.6068825722 0.6110069752 + 0.6715676188 0.6082835793 0.6124296784 + 0.6730042100 0.6096845269 0.6138523817 + 0.6744406819 0.6110807061 0.6152750850 + 0.6758772135 0.6124755740 0.6166884899 + 0.6773136854 0.6138706207 0.6180831194 + 0.6787502170 0.6152656078 0.6194776297 + 0.6801577210 0.6166605949 0.6208721995 + 0.6815580130 0.6180554032 0.6222668290 + 0.6829584241 0.6194347143 0.6236612797 + 0.6843587160 0.6208140254 0.6250466704 + 0.6857591271 0.6221933961 0.6264250875 + 0.6871594191 0.6235727072 0.6278035045 + 0.6885198951 0.6249520779 0.6291819215 + 0.6898779273 0.6263288856 0.6305602789 + 0.6912357807 0.6276934147 0.6319386959 + 0.6925938129 0.6290578842 0.6332967877 + 0.6939517856 0.6304224133 0.6346477866 + 0.6953091025 0.6317868829 0.6359987855 + 0.6966227889 0.6331512928 0.6373497844 + 0.6979364753 0.6345124841 0.6387007833 + 0.6992502213 0.6358644962 0.6400517821 + 0.7005639076 0.6372163892 0.6413751841 + 0.7018774748 0.6385684013 0.6426938176 + 0.7031903863 0.6399202943 0.6440123916 + 0.7044675946 0.6412723064 0.6453310251 + 0.7057446837 0.6426153183 0.6466495991 + 0.7070218921 0.6439368129 0.6479681730 + 0.7082989812 0.6452583075 0.6492698789 + 0.7095761895 0.6465796828 0.6505696774 + 0.7108533978 0.6479011774 0.6518694162 + 0.7121080160 0.6492226720 0.6531692147 + 0.7133617997 0.6505348086 0.6544690132 + 0.7146157026 0.6518198252 0.6557686925 + 0.7158694863 0.6531049013 0.6570504904 + 0.7171233296 0.6543899179 0.6583297849 + 0.7183771133 0.6556748748 0.6596090198 + 0.7195919752 0.6569600105 0.6608883142 + 0.7207996845 0.6582419872 0.6621676087 + 0.7220073938 0.6595075130 0.6634469032 + 0.7232151031 0.6607730985 0.6647216082 + 0.7244228721 0.6620386243 0.6659951806 + 0.7256305814 0.6633040905 0.6672688723 + 0.7268121243 0.6645696759 0.6685425043 + 0.7279800177 0.6658352017 0.6698160768 + 0.7291477919 0.6670749784 0.6710897088 + 0.7303156257 0.6683145165 0.6723518968 + 0.7314835191 0.6695539951 0.6736078858 + 0.7326512933 0.6707934737 0.6748638749 + 0.7338057160 0.6720330119 0.6761198044 + 0.7349399924 0.6732723713 0.6773757935 + 0.7360742092 0.6744793057 0.6786317229 + 0.7372084260 0.6756755710 0.6798825264 + 0.7383427024 0.6768718958 0.6811262965 + 0.7394769192 0.6780682206 0.6823701859 + 0.7406092882 0.6792644858 0.6836140156 + 0.7417197227 0.6804608107 0.6848577857 + 0.7428302169 0.6816480756 0.6861016750 + 0.7439405918 0.6828244925 0.6873413920 + 0.7450510263 0.6840010285 0.6885573864 + 0.7461614013 0.6851773858 0.6897733212 + 0.7472717762 0.6863538027 0.6909891963 + 0.7483662963 0.6875302196 0.6922051907 + 0.7494534254 0.6887052059 0.6934211254 + 0.7505404949 0.6898639202 0.6946370006 + 0.7516276240 0.6910225153 0.6958392859 + 0.7527148128 0.6921812296 0.6970379949 + 0.7538018823 0.6933398843 0.6982367039 + 0.7548860908 0.6944984794 0.6994354129 + 0.7559602857 0.6956571937 0.7006341219 + 0.7570344210 0.6968036890 0.7018327713 + 0.7581086159 0.6979433894 0.7030227184 + 0.7591826916 0.6990832090 0.7041977048 + 0.7602568865 0.7002230287 0.7053728104 + 0.7613310218 0.7013627291 0.7065479159 + 0.7623906136 0.7025024891 0.7077229023 + 0.7634438276 0.7036383748 0.7088980079 + 0.7644969225 0.7047494054 0.7100731134 + 0.7655500174 0.7058604956 0.7112265229 + 0.7666031122 0.7069715858 0.7123770118 + 0.7676562071 0.7080826759 0.7135276198 + 0.7687063813 0.7091938257 0.7146781087 + 0.7697265148 0.7103049159 0.7158285975 + 0.7707465887 0.7114003897 0.7169790864 + 0.7717667222 0.7124834061 0.7181215286 + 0.7727867961 0.7135664225 0.7192468047 + 0.7738069296 0.7146493793 0.7203720808 + 0.7748268843 0.7157322764 0.7214972973 + 0.7758402824 0.7168152928 0.7226225734 + 0.7768442035 0.7178983092 0.7237479091 + 0.7778481245 0.7189552784 0.7248731256 + 0.7788519859 0.7200095057 0.7259737253 + 0.7798559070 0.7210636735 0.7270630002 + 0.7808597088 0.7221180201 0.7281523943 + 0.7818635702 0.7231721878 0.7292417288 + 0.7828533053 0.7242264152 0.7303311229 + 0.7838358283 0.7252786756 0.7314203978 + 0.7848182917 0.7263221145 0.7325097919 + 0.7858008742 0.7273653746 0.7335510850 + 0.7867833972 0.7284088135 0.7345916033 + 0.7877659202 0.7294521928 0.7356320024 + 0.7887483835 0.7304955721 0.7366725206 + 0.7897030711 0.7315390110 0.7377129793 + 0.7906526923 0.7325803041 0.7387534976 + 0.7916023135 0.7336180806 0.7397875190 + 0.7925518751 0.7346559763 0.7407963872 + 0.7935014963 0.7356938720 0.7418051958 + 0.7944511175 0.7367317080 0.7428141236 + 0.7954006791 0.7377696037 0.7438229918 + 0.7963156104 0.7388074994 0.7448318005 + 0.7972288132 0.7398343086 0.7458407283 + 0.7981420159 0.7408506870 0.7468411922 + 0.7990550995 0.7418671250 0.7478262782 + 0.7999683022 0.7428835034 0.7488114238 + 0.8008813858 0.7438998818 0.7497966290 + 0.8017945886 0.7449163795 0.7507817149 + 0.8026857972 0.7459328175 0.7517668009 + 0.8035765886 0.7469387054 0.7527520061 + 0.8044673800 0.7479367852 0.7537305951 + 0.8053581119 0.7489348054 0.7547006011 + 0.8062489033 0.7499328852 0.7556706071 + 0.8071396947 0.7509309053 0.7566406131 + 0.8080304861 0.7519289255 0.7576106191 + 0.8089057207 0.7529270053 0.7585806251 + 0.8097798228 0.7539178133 0.7595505714 + 0.8106539249 0.7549026012 0.7605128884 + 0.8115280271 0.7558873892 0.7614648938 + 0.8124021888 0.7568721771 0.7624170184 + 0.8132762909 0.7578570843 0.7633690834 + 0.8141503930 0.7588418722 0.7643210888 + 0.8150117993 0.7598267198 0.7652732134 + 0.8158702850 0.7607942820 0.7662252188 + 0.8167288899 0.7617409825 0.7671691775 + 0.8175873756 0.7626876831 0.7680981755 + 0.8184459805 0.7636343837 0.7690271735 + 0.8193045259 0.7645810843 0.7699561715 + 0.8201630116 0.7655277848 0.7708852887 + 0.8210126758 0.7664744854 0.7718142867 + 0.8218567967 0.7674121261 0.7727432847 + 0.8227009177 0.7683262229 0.7736694813 + 0.8235449791 0.7692403197 0.7745841146 + 0.8243891001 0.7701544166 0.7754986882 + 0.8252332211 0.7710685134 0.7764133215 + 0.8260772824 0.7719824910 0.7773278952 + 0.8269128799 0.7728965878 0.7782425284 + 0.8277320266 0.7738102078 0.7791571021 + 0.8285509944 0.7747033834 0.7800716758 + 0.8293700814 0.7755966783 0.7809833884 + 0.8301892281 0.7764899135 0.7818949223 + 0.8310083151 0.7773832083 0.7828063965 + 0.8318274021 0.7782763839 0.7837178707 + 0.8326464295 0.7791696787 0.7846295238 + 0.8334459066 0.7800629139 0.7855409980 + 0.8342450261 0.7809472084 0.7864524722 + 0.8350440860 0.7818276286 0.7873616815 + 0.8358432055 0.7827079892 0.7882695794 + 0.8366423845 0.7835882902 0.7891774774 + 0.8374415040 0.7844687104 0.7900853753 + 0.8382406235 0.7853490710 0.7909933925 + 0.8390303850 0.7862293720 0.7919012904 + 0.8398123980 0.7871022224 0.7928091884 + 0.8405944705 0.7879561782 0.7937148809 + 0.8413766026 0.7888103127 0.7946143746 + 0.8421586156 0.7896643281 0.7955139279 + 0.8429406881 0.7905182838 0.7964133024 + 0.8437227011 0.7913722992 0.7973127961 + 0.8445037007 0.7922263741 0.7982122898 + 0.8452532887 0.7930803895 0.7991117835 + 0.8460028768 0.7939234972 0.8000112772 + 0.8467524052 0.7947638035 0.8008962870 + 0.8475019932 0.7956042290 0.8017777801 + 0.8482515812 0.7964444757 0.8026592135 + 0.8490012288 0.7972847819 0.8035405874 + 0.8497508168 0.7981252074 0.8044220209 + 0.8504915833 0.7989655137 0.8053035140 + 0.8512210250 0.7998054028 0.8061848879 + 0.8519504070 0.8006436229 0.8070607185 + 0.8526797891 0.8014817834 0.8079198003 + 0.8534091711 0.8023201227 0.8087788820 + 0.8541386127 0.8031582832 0.8096380234 + 0.8548679948 0.8039965034 0.8104969859 + 0.8555973768 0.8048347831 0.8113561273 + 0.8563107252 0.8056730032 0.8122152090 + 0.8570188284 0.8065040112 0.8130742908 + 0.8577268720 0.8073294759 0.8139200807 + 0.8584349751 0.8081550002 0.8147575855 + 0.8591430783 0.8089805841 0.8155952096 + 0.8598511815 0.8098061085 0.8164327741 + 0.8605592251 0.8106316924 0.8172702789 + 0.8612673283 0.8114572167 0.8181079030 + 0.8619577289 0.8122826815 0.8189455271 + 0.8626478910 0.8130952716 0.8197829723 + 0.8633381128 0.8139054179 0.8205946088 + 0.8640282750 0.8147153854 0.8214033842 + 0.8647184968 0.8155254722 0.8222122192 + 0.8654087186 0.8163354993 0.8230209947 + 0.8660988808 0.8171455860 0.8238298297 + 0.8667852283 0.8179556131 0.8246386051 + 0.8674482107 0.8187654018 0.8254473805 + 0.8681111932 0.8195549250 0.8262543082 + 0.8687742949 0.8203443289 0.8270450234 + 0.8694372773 0.8211337924 0.8278357983 + 0.8701003194 0.8219231963 0.8286265135 + 0.8707633018 0.8227127194 0.8294172883 + 0.8714262843 0.8235021830 0.8302080035 + 0.8720872998 0.8242915869 0.8309987783 + 0.8727403283 0.8250802159 0.8317894936 + 0.8733932972 0.8258609772 0.8325753212 + 0.8740463257 0.8266419172 0.8333438039 + 0.8746992946 0.8274227977 0.8341122866 + 0.8753523231 0.8282036781 0.8348808289 + 0.8760052919 0.8289846182 0.8356493115 + 0.8766583204 0.8297654986 0.8364177942 + 0.8773071170 0.8305463791 0.8371862173 + 0.8779379725 0.8313267827 0.8379547000 + 0.8785688877 0.8321037292 0.8387172222 + 0.8791998029 0.8328806162 0.8394616246 + 0.8798307180 0.8336575031 0.8402060866 + 0.8804615736 0.8344345093 0.8409506083 + 0.8810924888 0.8352113962 0.8416950703 + 0.8817234039 0.8359882832 0.8424395919 + 0.8823524117 0.8367652297 0.8431841135 + 0.8829597831 0.8375415206 0.8439285755 + 0.8835672736 0.8383017182 0.8446694016 + 0.8841748238 0.8390619159 0.8453953266 + 0.8847821951 0.8398221135 0.8461210728 + 0.8853896856 0.8405823112 0.8468469977 + 0.8859971762 0.8413426280 0.8475728035 + 0.8866046071 0.8421028256 0.8482987285 + 0.8872120976 0.8428630233 0.8490244746 + 0.8877959847 0.8436232209 0.8497503996 + 0.8883770108 0.8443626761 0.8504748940 + 0.8889580965 0.8450992703 0.8511757255 + 0.8895391226 0.8458358049 0.8518766165 + 0.8901200891 0.8465722799 0.8525773883 + 0.8907011151 0.8473088145 0.8532782793 + 0.8912820816 0.8480454087 0.8539791107 + 0.8918631077 0.8487818837 0.8546800017 + 0.8924347758 0.8495184183 0.8553807735 + 0.8930004239 0.8502457142 0.8560817242 + 0.8935660124 0.8509672284 0.8567734957 + 0.8941316009 0.8516888022 0.8574634194 + 0.8946971893 0.8524103165 0.8581532240 + 0.8952628970 0.8531318903 0.8588430882 + 0.8958284855 0.8538534045 0.8595330119 + 0.8963940740 0.8545749784 0.8602228761 + 0.8969566822 0.8552964926 0.8609126806 + 0.8975095749 0.8560137153 0.8616026044 + 0.8980625272 0.8567193747 0.8622909784 + 0.8986153007 0.8574250937 0.8629779816 + 0.8991681933 0.8581306934 0.8636649847 + 0.8997210264 0.8588364124 0.8643519878 + 0.9002739191 0.8595420718 0.8650388718 + 0.9008268118 0.8602476716 0.8657258749 + 0.9013795853 0.8609533906 0.8664128780 + 0.9019126892 0.8616591096 0.8670998812 + 0.9024397731 0.8623467088 0.8677850962 + 0.9029669166 0.8630310297 0.8684529066 + 0.9034940004 0.8637151718 0.8691207170 + 0.9040210843 0.8643994927 0.8697885871 + 0.9045482278 0.8650836945 0.8704563975 + 0.9050753117 0.8657680154 0.8711242080 + 0.9056023955 0.8664522171 0.8717920184 + 0.9061269760 0.8671364784 0.8724598885 + 0.9066426754 0.8678159714 0.8731276989 + 0.9071583152 0.8684850931 0.8737882972 + 0.9076738954 0.8691542149 0.8744438291 + 0.9081895947 0.8698232174 0.8750993013 + 0.9087051749 0.8704922795 0.8757547736 + 0.9092208147 0.8711614013 0.8764103055 + 0.9097363949 0.8718305230 0.8770657778 + 0.9102520943 0.8724995852 0.8777213097 + 0.9107689857 0.8731687069 0.8783767223 + 0.9112870097 0.8738380075 0.8790321946 + 0.9118049741 0.8745074868 0.8796920180 + 0.9123229980 0.8751769066 0.8803519011 + 0.9128410220 0.8758463264 0.8810117245 + 0.9133591056 0.8765158057 0.8816714883 + 0.9138771296 0.8771852255 0.8823313117 + 0.9143950939 0.8778547049 0.8829911947 + 0.9149131179 0.8785241246 0.8836510181 + 0.9154273868 0.8791936040 0.8843107820 + 0.9159408808 0.8798611164 0.8849681020 + 0.9164543748 0.8805286884 0.8856195807 + 0.9169679284 0.8811962008 0.8862711191 + 0.9174814224 0.8818637133 0.8869225979 + 0.9179949164 0.8825312853 0.8875740767 + 0.9185084105 0.8831987977 0.8882256746 + 0.9190219045 0.8838664293 0.8888772130 + 0.9195353985 0.8845338821 0.8895286918 + 0.9200410843 0.8851994872 0.8901801705 + 0.9205467105 0.8858562112 0.8908231258 + 0.9210522175 0.8865129948 0.8914582133 + 0.9215577841 0.8871697187 0.8920934200 + 0.9220634103 0.8878263831 0.8927285075 + 0.9225689769 0.8884831071 0.8933635950 + 0.9230744839 0.8891397715 0.8939986825 + 0.9235801101 0.8897964954 0.8946338892 + 0.9240844846 0.8904532194 0.8952689767 + 0.9245653152 0.8911066055 0.8959041238 + 0.9250460863 0.8917511106 0.8965278268 + 0.9255269170 0.8923956156 0.8971452713 + 0.9260076880 0.8930401206 0.8977627754 + 0.9264885187 0.8936846256 0.8983802795 + 0.9269692898 0.8943290710 0.8989977241 + 0.9274501204 0.8949735761 0.8996152282 + 0.9279310107 0.8956180811 0.9002326727 + 0.9284117222 0.8962625861 0.9008501768 + 0.9288892150 0.8969045281 0.9014676809 + 0.9293668270 0.8975396156 0.9020715952 + 0.9298443198 0.8981747031 0.9026690125 + 0.9303218126 0.8988097906 0.9032663703 + 0.9307994246 0.8994448185 0.9038637877 + 0.9312769175 0.9000799060 0.9044612050 + 0.9317544103 0.9007149935 0.9050586224 + 0.9322319031 0.9013500810 0.9056559801 + 0.9327095151 0.9019851089 0.9062533975 + 0.9331722856 0.9026165009 0.9068508148 + 0.9336332083 0.9032307267 0.9074404240 + 0.9340941906 0.9038448930 0.9080247879 + 0.9345551133 0.9044591188 0.9086092114 + 0.9350160956 0.9050732851 0.9091936946 + 0.9354770780 0.9056875110 0.9097781181 + 0.9359380007 0.9063016772 0.9103624821 + 0.9363989830 0.9069159031 0.9109470248 + 0.9368600249 0.9075301290 0.9115313888 + 0.9373095036 0.9081442952 0.9121158719 + 0.9377532005 0.9087433815 0.9126855135 + 0.9381968975 0.9093422294 0.9132357836 + 0.9386405945 0.9099410176 0.9137859941 + 0.9390842915 0.9105398059 0.9143362045 + 0.9395279884 0.9111385942 0.9148864746 + 0.9399716854 0.9117373824 0.9154366851 + 0.9404153824 0.9123361707 0.9159868956 + 0.9408590794 0.9129350185 0.9165371060 + 0.9412962198 0.9135338068 0.9170873761 + 0.9417200089 0.9141229987 0.9176347852 + 0.9421437979 0.9147080183 0.9181675911 + 0.9425675869 0.9152929187 0.9187005162 + 0.9429913759 0.9158778191 0.9192333221 + 0.9434152246 0.9164627194 0.9197661877 + 0.9438390136 0.9170476198 0.9202991128 + 0.9442628026 0.9176325202 0.9208319187 + 0.9446865916 0.9182174802 0.9213647842 + 0.9451104999 0.9188023806 0.9218975902 + 0.9455274940 0.9193829298 0.9224305153 + 0.9459438920 0.9199525118 0.9229544997 + 0.9463601708 0.9205220938 0.9234762192 + 0.9467766285 0.9210916758 0.9239978790 + 0.9471930265 0.9216613173 0.9245195985 + 0.9476093054 0.9222308993 0.9250413775 + 0.9480257034 0.9228004813 0.9255630970 + 0.9484419823 0.9233701229 0.9260848165 + 0.9488583803 0.9239397049 0.9266064763 + 0.9492663741 0.9245092869 0.9271281958 + 0.9496603012 0.9250699878 0.9276459217 + 0.9500542879 0.9256283045 0.9281548262 + 0.9504482150 0.9261865020 0.9286637902 + 0.9508420825 0.9267448187 0.9291728139 + 0.9512361288 0.9273030758 0.9296817780 + 0.9516299963 0.9278613925 0.9301908016 + 0.9520239234 0.9284197092 0.9306998253 + 0.9524179101 0.9289779067 0.9312087297 + 0.9528117776 0.9295362234 0.9317176938 + 0.9531949759 0.9300904870 0.9322267175 + 0.9535744190 0.9306278229 0.9327245951 + 0.9539538026 0.9311652184 0.9332185984 + 0.9543331861 0.9317024946 0.9337126017 + 0.9547126293 0.9322397709 0.9342067242 + 0.9550918937 0.9327772260 0.9347007275 + 0.9554712772 0.9333145022 0.9351947904 + 0.9558507204 0.9338517785 0.9356887937 + 0.9562301040 0.9343891144 0.9361827970 + 0.9566094875 0.9349265099 0.9366769195 + 0.9569786787 0.9354528785 0.9371693134 + 0.9573479295 0.9359676838 0.9376392961 + 0.9577171206 0.9364824891 0.9381092787 + 0.9580863714 0.9369972944 0.9385793209 + 0.9584556222 0.9375120997 0.9390493035 + 0.9588248134 0.9380269051 0.9395192862 + 0.9591940045 0.9385417104 0.9399893880 + 0.9595631957 0.9390563965 0.9404593706 + 0.9599325061 0.9395712018 0.9409294128 + 0.9602993131 0.9400860071 0.9413993955 + 0.9606528878 0.9405859709 0.9418666959 + 0.9610065818 0.9410789013 0.9423272014 + 0.9613602161 0.9415717125 0.9427877069 + 0.9617139101 0.9420645237 0.9432482123 + 0.9620674849 0.9425572753 0.9437087178 + 0.9624211788 0.9430500865 0.9441692233 + 0.9627748728 0.9435428977 0.9446297288 + 0.9631285071 0.9440357089 0.9450901747 + 0.9634822011 0.9445285201 0.9455507994 + 0.9638335109 0.9450212717 0.9460113049 + 0.9641757011 0.9455037117 0.9464758039 + 0.9645178914 0.9459828138 0.9469466209 + 0.9648600817 0.9464619160 0.9474173784 + 0.9652022719 0.9469410181 0.9478881955 + 0.9655445218 0.9474201202 0.9483590126 + 0.9658865929 0.9478992224 0.9488298297 + 0.9662287831 0.9483783245 0.9493005872 + 0.9665709734 0.9488574266 0.9497714043 + 0.9669132233 0.9493365288 0.9502422214 + 0.9672523737 0.9498155713 0.9507129788 + 0.9675732851 0.9502952099 0.9511811733 + 0.9678940773 0.9507750273 0.9516453743 + 0.9682149887 0.9512547255 0.9521095753 + 0.9685357809 0.9517344236 0.9525737166 + 0.9688566923 0.9522141814 0.9530379176 + 0.9691774845 0.9526938796 0.9535021186 + 0.9694983959 0.9531735778 0.9539663196 + 0.9698193073 0.9536533952 0.9544305205 + 0.9701400995 0.9541330934 0.9548947215 + 0.9704610109 0.9546129107 0.9553589225 + 0.9707775712 0.9550942779 0.9558221102 + 0.9710940123 0.9555768967 0.9562827945 + 0.9714105129 0.9560595751 0.9567434788 + 0.9717268944 0.9565421939 0.9572042227 + 0.9720433950 0.9570248127 0.9576649070 + 0.9723598957 0.9575073719 0.9581255913 + 0.9726762772 0.9579899907 0.9585862756 + 0.9729927778 0.9584727287 0.9590470195 + 0.9733092785 0.9589552879 0.9595077038 + 0.9736257195 0.9594379067 0.9599683881 + 0.9739437103 0.9599211216 0.9604294896 + 0.9742622972 0.9604055285 0.9608955979 + 0.9745808840 0.9608898163 0.9613618255 + 0.9748994708 0.9613741040 0.9618278742 + 0.9752181768 0.9618583918 0.9622939825 + 0.9755368233 0.9623427987 0.9627602100 + 0.9758554101 0.9628270864 0.9632263184 + 0.9761739969 0.9633113742 0.9636924267 + 0.9764927030 0.9637957215 0.9641585946 + 0.9768112898 0.9642801285 0.9646247029 + 0.9771254063 0.9647644162 0.9650908113 + 0.9774289727 0.9652258158 0.9655427933 + 0.9777324796 0.9656870961 0.9659900069 + 0.9780361056 0.9661483765 0.9664372206 + 0.9783396125 0.9666097164 0.9668844938 + 0.9786431789 0.9670709968 0.9673317075 + 0.9789466858 0.9675322771 0.9677789211 + 0.9792503119 0.9679936171 0.9682261944 + 0.9795538187 0.9684548974 0.9686734080 + 0.9798573852 0.9689161777 0.9691206217 + 0.9801608920 0.9693775177 0.9695677757 + 0.9804582000 0.9698340297 0.9700127244 + 0.9807540178 0.9702861905 0.9704523087 + 0.9810497165 0.9707384109 0.9708918929 + 0.9813454151 0.9711905718 0.9713315964 + 0.9816411734 0.9716427922 0.9717711806 + 0.9819368720 0.9720950127 0.9722108245 + 0.9822325706 0.9725471139 0.9726504087 + 0.9825283885 0.9729992747 0.9730899930 + 0.9828240871 0.9734514952 0.9735295773 + 0.9831197858 0.9739037156 0.9739692807 + 0.9834141135 0.9743558764 0.9744089246 + 0.9837012887 0.9748013020 0.9748445153 + 0.9839885831 0.9752463102 0.9752789736 + 0.9842758179 0.9756913185 0.9757133722 + 0.9845629930 0.9761363268 0.9761477709 + 0.9848502874 0.9765812755 0.9765822291 + 0.9851375222 0.9770262837 0.9770166278 + 0.9854248166 0.9774712920 0.9774510264 + 0.9857119918 0.9779163003 0.9778854251 + 0.9859992266 0.9783613086 0.9783198237 + 0.9862865210 0.9788061976 0.9787542224 + 0.9865726829 0.9792487025 0.9791879058 + 0.9868577123 0.9796836972 0.9796146154 + 0.9871426225 0.9801185727 0.9800413847 + 0.9874275923 0.9805535078 0.9804680943 + 0.9877125025 0.9809883833 0.9808948040 + 0.9879974723 0.9814233184 0.9813215733 + 0.9882823825 0.9818581939 0.9817482829 + 0.9885674119 0.9822931886 0.9821749926 + 0.9888523221 0.9827281237 0.9826018214 + 0.9891372919 0.9831629992 0.9830284715 + 0.9894222021 0.9835978746 0.9834551811 + 0.9896981120 0.9840263128 0.9838774800 + 0.9899675846 0.9844464064 0.9842901230 + 0.9902371764 0.9848663807 0.9847027063 + 0.9905067086 0.9852864146 0.9851151705 + 0.9907763004 0.9857063890 0.9855278134 + 0.9910457730 0.9861264825 0.9859403968 + 0.9913154244 0.9865465164 0.9863529205 + 0.9915848970 0.9869664907 0.9867655039 + 0.9918544888 0.9873865843 0.9871780276 + 0.9921240211 0.9878066182 0.9875906110 + 0.9923936129 0.9882265925 0.9880031943 + 0.9926524758 0.9886332750 0.9884101152 + 0.9929050803 0.9890270233 0.9888089895 + 0.9931576252 0.9894207120 0.9892079830 + 0.9934101105 0.9898144007 0.9896069169 + 0.9936627150 0.9902082086 0.9900057912 + 0.9939152002 0.9906018972 0.9904047251 + 0.9941678047 0.9909955859 0.9908037186 + 0.9944202900 0.9913892746 0.9912025928 + 0.9946727753 0.9917830229 0.9916015267 + 0.9949253798 0.9921767116 0.9920004010 + 0.9951779246 0.9925704002 0.9923992753 + 0.9954192042 0.9929419160 0.9927871823 + 0.9956508279 0.9932870269 0.9931579232 + 0.9958823919 0.9936321974 0.9935287237 + 0.9961140156 0.9939773083 0.9938995242 + 0.9963455796 0.9943224788 0.9942703247 + 0.9965772033 0.9946675897 0.9946411252 + 0.9968088269 0.9950128198 0.9950119257 + 0.9970403910 0.9953578711 0.9953826070 + 0.9972720146 0.9957031012 0.9957534075 + 0.9975035191 0.9960482121 0.9961242080 + 0.9977350831 0.9963933825 0.9964950085 + 0.9979518056 0.9967247844 0.9968441129 + 0.9981380105 0.9970226288 0.9971309900 + 0.9983242154 0.9973202944 0.9974179268 + 0.9985104203 0.9976180196 0.9977048039 + 0.9986966252 0.9979158044 0.9979916811 + 0.9988827705 0.9982135296 0.9982786179 + 0.9990689754 0.9985113144 0.9985654950 + 0.9992551804 0.9988089800 0.9988523722 + 0.9994413853 0.9991068244 0.9991393089 + 0.9996275902 0.9994044900 0.9994261861 + 0.9998137951 0.9997022748 0.9997131228 + 1.0000000000 1.0000000000 1.0000000000 +} diff --git a/rpplugins/color_correction/resources/film_luts_raw/kodak_kodachrome_64.spi1d b/rpplugins/color_correction/resources/film_luts_raw/kodak_kodachrome_64.spi1d new file mode 100644 index 0000000..1de002a --- /dev/null +++ b/rpplugins/color_correction/resources/film_luts_raw/kodak_kodachrome_64.spi1d @@ -0,0 +1,1030 @@ +Version 1 +From 0.0 1.0 +Length 1024 +Components 3 +{ + 0.0000000000 0.0000000000 0.0000000000 + 0.0001951461 0.0001957432 0.0001951461 + 0.0003971827 0.0004013765 0.0003971827 + 0.0006093314 0.0006168035 0.0006093314 + 0.0008331265 0.0008421433 0.0008331265 + 0.0010693250 0.0010800430 0.0010693250 + 0.0013165741 0.0013327420 0.0013165741 + 0.0015723180 0.0015964990 0.0015723180 + 0.0018371070 0.0018691909 0.0018371070 + 0.0021111390 0.0021534991 0.0021111390 + 0.0023975959 0.0024501081 0.0023975959 + 0.0026947369 0.0027620669 0.0026947369 + 0.0030043761 0.0030861360 0.0030043761 + 0.0033243729 0.0034196740 0.0033243729 + 0.0036564060 0.0037631679 0.0036564060 + 0.0040000519 0.0041189152 0.0040000519 + 0.0043583522 0.0044872048 0.0043583522 + 0.0047301622 0.0048662322 0.0047301622 + 0.0051159370 0.0052598631 0.0051159370 + 0.0055168238 0.0056668199 0.0055168238 + 0.0059318189 0.0060855579 0.0059318189 + 0.0063606128 0.0065190848 0.0063606128 + 0.0068039121 0.0069621201 0.0068039121 + 0.0072610150 0.0074171298 0.0072610150 + 0.0077324822 0.0078812325 0.0077324822 + 0.0082186935 0.0083566681 0.0082186935 + 0.0087195607 0.0088426983 0.0087195607 + 0.0092373807 0.0093412735 0.0092373807 + 0.0097713200 0.0098493528 0.0097713200 + 0.0103215296 0.0103719197 0.0103215296 + 0.0108859697 0.0109069496 0.0108859697 + 0.0114682503 0.0114534898 0.0114682503 + 0.0120688202 0.0120149804 0.0120688202 + 0.0126871103 0.0125900703 0.0126871103 + 0.0133261904 0.0131813204 0.0133261904 + 0.0139810601 0.0137880603 0.0139810601 + 0.0146569004 0.0144142900 0.0146569004 + 0.0153518198 0.0150552802 0.0153518198 + 0.0160680693 0.0157083794 0.0160680693 + 0.0168081895 0.0163766202 0.0168081895 + 0.0175653305 0.0170597993 0.0175653305 + 0.0183405094 0.0177551508 0.0183405094 + 0.0191343091 0.0184656195 0.0191343091 + 0.0199443996 0.0191936009 0.0199443996 + 0.0207724404 0.0199350491 0.0207724404 + 0.0216247104 0.0206901692 0.0216247104 + 0.0224967394 0.0214668401 0.0224967394 + 0.0233900901 0.0222598594 0.0233900901 + 0.0243038405 0.0230733994 0.0243038405 + 0.0252429191 0.0239060391 0.0252429191 + 0.0262041409 0.0247574691 0.0262041409 + 0.0271870699 0.0256274194 0.0271870699 + 0.0281923302 0.0265152995 0.0281923302 + 0.0292217396 0.0274243094 0.0292217396 + 0.0302699897 0.0283501595 0.0302699897 + 0.0313403010 0.0292933993 0.0313403010 + 0.0324379094 0.0302557293 0.0324379094 + 0.0335581601 0.0312350094 0.0335581601 + 0.0347037092 0.0322324112 0.0347037092 + 0.0358735509 0.0332520008 0.0358735509 + 0.0370708592 0.0342949703 0.0370708592 + 0.0382963195 0.0353550985 0.0382963195 + 0.0395508707 0.0364397392 0.0395508707 + 0.0408340394 0.0375451893 0.0408340394 + 0.0421415716 0.0386712812 0.0421415716 + 0.0434691012 0.0398181006 0.0434691012 + 0.0448197499 0.0409855917 0.0448197499 + 0.0461917110 0.0421767011 0.0461917110 + 0.0475859195 0.0433861688 0.0475859195 + 0.0489974618 0.0446146913 0.0489974618 + 0.0504221395 0.0458587706 0.0504221395 + 0.0518664904 0.0471218303 0.0518664904 + 0.0533314086 0.0484039001 0.0533314086 + 0.0548129790 0.0497035906 0.0548129790 + 0.0563097298 0.0510205887 0.0563097298 + 0.0578255616 0.0523589589 0.0578255616 + 0.0593563803 0.0537226684 0.0593563803 + 0.0609117001 0.0551059917 0.0609117001 + 0.0624887496 0.0565031916 0.0624887496 + 0.0640849099 0.0579188913 0.0640849099 + 0.0657032207 0.0593533292 0.0657032207 + 0.0673418716 0.0608051494 0.0673418716 + 0.0690022632 0.0622783490 0.0690022632 + 0.0706820935 0.0637728870 0.0706820935 + 0.0723833889 0.0652925819 0.0723833889 + 0.0741088763 0.0668374375 0.0741088763 + 0.0758581236 0.0684004799 0.0758581236 + 0.0776309818 0.0699783191 0.0776309818 + 0.0794283003 0.0715712607 0.0794283003 + 0.0812476426 0.0731753632 0.0812476426 + 0.0830830187 0.0747953877 0.0830830187 + 0.0849313214 0.0764375329 0.0849313214 + 0.0867945403 0.0780991465 0.0867945403 + 0.0886720195 0.0797795132 0.0886720195 + 0.0905641615 0.0814804882 0.0905641615 + 0.0924730599 0.0832031295 0.0924730599 + 0.0944008604 0.0849441215 0.0944008604 + 0.0963497087 0.0866999105 0.0963497087 + 0.0983169824 0.0884718299 0.0983169824 + 0.1002992019 0.0902594104 0.1002992019 + 0.1022920981 0.0920619667 0.1022920981 + 0.1043059006 0.0938806906 0.1043059006 + 0.1063338965 0.0957234576 0.1063338965 + 0.1083754003 0.0975851119 0.1083754003 + 0.1104298979 0.0994653329 0.1104298979 + 0.1125015020 0.1013638005 0.1125015020 + 0.1145863980 0.1032824963 0.1145863980 + 0.1166832000 0.1052192971 0.1166832000 + 0.1187919974 0.1071742028 0.1187919974 + 0.1209281981 0.1091483980 0.1209281981 + 0.1230840012 0.1111427024 0.1230840012 + 0.1252560019 0.1131450012 0.1252560019 + 0.1274449974 0.1151549965 0.1274449974 + 0.1296389997 0.1171758026 0.1296389997 + 0.1318369955 0.1192134991 0.1318369955 + 0.1340391934 0.1212674007 0.1340391934 + 0.1362587065 0.1233419999 0.1362587065 + 0.1384842992 0.1254397035 0.1384842992 + 0.1407155991 0.1275476962 0.1407155991 + 0.1429519951 0.1296651959 0.1429519951 + 0.1451932937 0.1317926049 0.1451932937 + 0.1474387050 0.1339260936 0.1474387050 + 0.1496894062 0.1360657066 0.1496894062 + 0.1519508958 0.1382188946 0.1519508958 + 0.1542215943 0.1403802931 0.1542215943 + 0.1564984024 0.1425506026 0.1564984024 + 0.1587806046 0.1447318047 0.1587806046 + 0.1610693038 0.1469233930 0.1610693038 + 0.1633670926 0.1491298974 0.1633670926 + 0.1656686068 0.1513458043 0.1656686068 + 0.1679760069 0.1535694003 0.1679760069 + 0.1702944934 0.1558119059 0.1702944934 + 0.1726182997 0.1580559015 0.1726182997 + 0.1749459952 0.1603008062 0.1749459952 + 0.1772750020 0.1625521928 0.1772750020 + 0.1796054989 0.1648124009 0.1796054989 + 0.1819469035 0.1670871973 0.1819469035 + 0.1842930019 0.1693769991 0.1842930019 + 0.1866527051 0.1716732979 0.1866527051 + 0.1890151054 0.1739847064 0.1890151054 + 0.1913814992 0.1763011068 0.1913814992 + 0.1937530041 0.1786264926 0.1937530041 + 0.1961268932 0.1809585989 0.1961268932 + 0.1984995008 0.1832942963 0.1984995008 + 0.2008748949 0.1856396049 0.2008748949 + 0.2032615989 0.1879891008 0.2032615989 + 0.2056463957 0.1903553009 0.2056463957 + 0.2080287933 0.1927254945 0.2080287933 + 0.2104109973 0.1951016933 0.2104109973 + 0.2127932012 0.1974837035 0.2127932012 + 0.2151795030 0.1998693049 0.2151795030 + 0.2175665051 0.2022628039 0.2175665051 + 0.2199523002 0.2046581060 0.2199523002 + 0.2223390937 0.2070544064 0.2223390937 + 0.2247312069 0.2094524950 0.2247312069 + 0.2271240950 0.2118602991 0.2271240950 + 0.2295188010 0.2142691016 0.2295188010 + 0.2319131047 0.2166801989 0.2319131047 + 0.2343070954 0.2190932930 0.2343070954 + 0.2366984040 0.2215093970 0.2366984040 + 0.2390874028 0.2239297926 0.2390874028 + 0.2414730936 0.2263545990 0.2414730936 + 0.2438565046 0.2287807018 0.2438565046 + 0.2462437004 0.2312079072 0.2462437004 + 0.2486331016 0.2336384058 0.2486331016 + 0.2510172129 0.2360707074 0.2510172129 + 0.2533988059 0.2385022044 0.2533988059 + 0.2557758093 0.2409331948 0.2557758093 + 0.2581504881 0.2433750033 0.2581504881 + 0.2605293095 0.2458223999 0.2605293095 + 0.2629100978 0.2482777983 0.2629100978 + 0.2652882934 0.2507374883 0.2652882934 + 0.2676649988 0.2532019913 0.2676649988 + 0.2700409889 0.2556692958 0.2700409889 + 0.2724165916 0.2581461072 0.2724165916 + 0.2747870982 0.2606298029 0.2747870982 + 0.2771523893 0.2631142139 0.2771523893 + 0.2795102894 0.2655993104 0.2795102894 + 0.2818570137 0.2680785954 0.2818570137 + 0.2842001915 0.2705487907 0.2842001915 + 0.2865338027 0.2730177939 0.2865338027 + 0.2888650894 0.2754839063 0.2888650894 + 0.2911804914 0.2779509127 0.2911804914 + 0.2934958041 0.2804240882 0.2934958041 + 0.2957996130 0.2828972936 0.2957996130 + 0.2981027961 0.2853642106 0.2981027961 + 0.3004046082 0.2878307104 0.3004046082 + 0.3027057946 0.2902925909 0.3027057946 + 0.3050028980 0.2927531898 0.3050028980 + 0.3072963953 0.2952114940 0.3072963953 + 0.3095870912 0.2976680100 0.3095870912 + 0.3118711114 0.3001233041 0.3118711114 + 0.3141548038 0.3025760055 0.3141548038 + 0.3164271116 0.3050285876 0.3164271116 + 0.3186993897 0.3074803948 0.3186993897 + 0.3209618926 0.3099322915 0.3209618926 + 0.3232209980 0.3123745024 0.3232209980 + 0.3254742026 0.3148137033 0.3254742026 + 0.3277195096 0.3172554970 0.3277195096 + 0.3299638033 0.3197003901 0.3299638033 + 0.3321967125 0.3221448064 0.3321967125 + 0.3344297111 0.3245866895 0.3344297111 + 0.3366633058 0.3270285130 0.3366633058 + 0.3388971984 0.3294712901 0.3388971984 + 0.3411270976 0.3319145143 0.3411270976 + 0.3433490098 0.3343560100 0.3433490098 + 0.3455708921 0.3367947936 0.3455708921 + 0.3477726877 0.3392334878 0.3477726877 + 0.3499726951 0.3416740894 0.3499726951 + 0.3521771133 0.3441148996 0.3521771133 + 0.3543866873 0.3465546072 0.3543866873 + 0.3565962017 0.3489935100 0.3565962017 + 0.3587929904 0.3514319956 0.3587929904 + 0.3609898984 0.3538624048 0.3609898984 + 0.3631897867 0.3562928140 0.3631897867 + 0.3653928041 0.3587242961 0.3653928041 + 0.3675957918 0.3611567020 0.3675957918 + 0.3697830141 0.3635889888 0.3697830141 + 0.3719697893 0.3660191894 0.3719697893 + 0.3741520047 0.3684493899 0.3741520047 + 0.3763279915 0.3708696961 0.3763279915 + 0.3785040975 0.3732793927 0.3785040975 + 0.3806638122 0.3756890893 0.3806638122 + 0.3828206062 0.3780809045 0.3828206062 + 0.3849751055 0.3804706931 0.3849751055 + 0.3871222138 0.3828578889 0.3871222138 + 0.3892692924 0.3852390945 0.3892692924 + 0.3914063871 0.3876202106 0.3914063871 + 0.3935371041 0.3899951875 0.3935371041 + 0.3956677020 0.3923670948 0.3956677020 + 0.3977789879 0.3947389126 0.3977789879 + 0.3998892009 0.3970890045 0.3998892009 + 0.4019930959 0.3994390965 0.4019930959 + 0.4040785134 0.4017911851 0.4040785134 + 0.4061638117 0.4041475952 0.4061638117 + 0.4082497060 0.4065040052 0.4082497060 + 0.4103358984 0.4088486135 0.4103358984 + 0.4124220908 0.4111852944 0.4124220908 + 0.4144963026 0.4135220051 0.4144963026 + 0.4165670872 0.4158436060 0.4165670872 + 0.4186378121 0.4181624949 0.4186378121 + 0.4206883013 0.4204812944 0.4206883013 + 0.4227387011 0.4227986038 0.4227387011 + 0.4247851968 0.4251160026 0.4247851968 + 0.4268149137 0.4274305999 0.4268149137 + 0.4288446903 0.4297378063 0.4288446903 + 0.4308727980 0.4320450127 0.4308727980 + 0.4328976870 0.4343562126 0.4328976870 + 0.4349226058 0.4366728067 0.4349226058 + 0.4369452894 0.4389894009 0.4369452894 + 0.4389654100 0.4412983954 0.4389654100 + 0.4409855008 0.4436013103 0.4409855008 + 0.4429948926 0.4459043145 0.4429948926 + 0.4449959099 0.4482020140 0.4449959099 + 0.4469969869 0.4504969120 0.4469969869 + 0.4489865005 0.4527918994 0.4489865005 + 0.4509691894 0.4550856948 0.4509691894 + 0.4529519081 0.4573791921 0.4529519081 + 0.4549242854 0.4596726894 0.4549242854 + 0.4568913877 0.4619601071 0.4568913877 + 0.4588586092 0.4642454982 0.4588586092 + 0.4608167112 0.4665308893 0.4608167112 + 0.4627703130 0.4688045979 0.4627703130 + 0.4647239149 0.4710747004 0.4647239149 + 0.4666719139 0.4733447134 0.4666719139 + 0.4686164856 0.4756112993 0.4686164856 + 0.4705610871 0.4778766036 0.4705610871 + 0.4724955857 0.4801419973 0.4724955857 + 0.4744223058 0.4823893905 0.4744223058 + 0.4763489962 0.4846282899 0.4763489962 + 0.4782694876 0.4868671000 0.4782694876 + 0.4801832139 0.4890891910 0.4801832139 + 0.4820967913 0.4912990928 0.4820967913 + 0.4840039015 0.4935089946 0.4840039015 + 0.4858981967 0.4957109988 0.4858981967 + 0.4877924025 0.4979032874 0.4877924025 + 0.4896839857 0.5000956059 0.4896839857 + 0.4915628135 0.5022779703 0.4915628135 + 0.4934414923 0.5044360161 0.4934414923 + 0.4953202009 0.5065940022 0.4953202009 + 0.4971916080 0.5087499022 0.4971916080 + 0.4990628064 0.5108857751 0.4990628064 + 0.5009341240 0.5130217075 0.5009341240 + 0.5027933121 0.5151576996 0.5027933121 + 0.5046482086 0.5172629952 0.5046482086 + 0.5065031052 0.5193634033 0.5065031052 + 0.5083466172 0.5214638710 0.5083466172 + 0.5101770759 0.5235527754 0.5101770759 + 0.5120074749 0.5256341100 0.5120074749 + 0.5138359070 0.5277153850 0.5138359070 + 0.5156533122 0.5297918916 0.5156533122 + 0.5174707174 0.5318573117 0.5174707174 + 0.5192881227 0.5339226127 0.5192881227 + 0.5211005211 0.5359879732 0.5211005211 + 0.5229117274 0.5380240083 0.5229117274 + 0.5247228742 0.5400587916 0.5247228742 + 0.5265293121 0.5420935750 0.5265293121 + 0.5283294916 0.5441210866 0.5283294916 + 0.5301296711 0.5461434126 0.5301296711 + 0.5319293737 0.5481657982 0.5319293737 + 0.5337138772 0.5501838923 0.5337138772 + 0.5354983807 0.5521820784 0.5354983807 + 0.5372828841 0.5541803241 0.5372828841 + 0.5390647054 0.5561785102 0.5390647054 + 0.5408445001 0.5581638813 0.5408445001 + 0.5426242948 0.5601447225 0.5426242948 + 0.5444021821 0.5621253848 0.5444021821 + 0.5461611152 0.5640997291 0.5461611152 + 0.5479199290 0.5660542846 0.5479199290 + 0.5496788025 0.5680087805 0.5496788025 + 0.5514246821 0.5699632764 0.5514246821 + 0.5531604886 0.5718948841 0.5531604886 + 0.5548964143 0.5738177896 0.5548964143 + 0.5566322207 0.5757405758 0.5566322207 + 0.5583571196 0.5776597857 0.5583571196 + 0.5600818992 0.5795599818 0.5600818992 + 0.5618067980 0.5814602971 0.5618067980 + 0.5635148287 0.5833604932 0.5635148287 + 0.5651975274 0.5852445960 0.5651975274 + 0.5668801069 0.5871161819 0.5668801069 + 0.5685628057 0.5889877081 0.5685628057 + 0.5702366233 0.5908592939 0.5702366233 + 0.5719075203 0.5926998258 0.5719075203 + 0.5735784769 0.5945379734 0.5735784769 + 0.5752487183 0.5963761210 0.5752487183 + 0.5769106746 0.5982087851 0.5769106746 + 0.5785726905 0.6000252962 0.5785726905 + 0.5802345872 0.6018419266 0.5802345872 + 0.5818874240 0.6036584973 0.5818874240 + 0.5835233927 0.6054543257 0.5835233927 + 0.5851594210 0.6072319746 0.5851594210 + 0.5867953897 0.6090096831 0.5867953897 + 0.5884160995 0.6107872725 0.5884160995 + 0.5900263786 0.6125335097 0.5900263786 + 0.5916365981 0.6142706275 0.5916365981 + 0.5932468176 0.6160078049 0.5932468176 + 0.5948414207 0.6177449226 0.5948414207 + 0.5964319110 0.6194577217 0.5964319110 + 0.5980222821 0.6211699843 0.5980222821 + 0.5996127725 0.6228823066 0.5996127725 + 0.6011689901 0.6245880127 0.6011689901 + 0.6027231812 0.6262522936 0.6027231812 + 0.6042773724 0.6279166937 0.6042773724 + 0.6058307290 0.6295809746 0.6058307290 + 0.6073688269 0.6312366724 0.6073688269 + 0.6089069843 0.6328672767 0.6089069843 + 0.6104450822 0.6344978213 0.6104450822 + 0.6119816899 0.6361284256 0.6119816899 + 0.6135081053 0.6377481818 0.6135081053 + 0.6150345206 0.6393465996 0.6150345206 + 0.6165608764 0.6409450173 0.6165608764 + 0.6180859804 0.6425433755 0.6180859804 + 0.6196045876 0.6441305876 0.6196045876 + 0.6211233139 0.6456986070 0.6211233139 + 0.6226419210 0.6472666860 0.6226419210 + 0.6241582036 0.6488348246 0.6241582036 + 0.6256613135 0.6503942013 0.6256613135 + 0.6271644831 0.6519383788 0.6271644831 + 0.6286675930 0.6534824967 0.6286675930 + 0.6301684976 0.6550266743 0.6301684976 + 0.6316462159 0.6565703154 0.6316462159 + 0.6331238747 0.6581128836 0.6331238747 + 0.6346017122 0.6596555114 0.6346017122 + 0.6360793710 0.6611980796 0.6360793710 + 0.6375383735 0.6627355218 0.6375383735 + 0.6389971972 0.6642531753 0.6389971972 + 0.6404560208 0.6657708883 0.6404560208 + 0.6419147849 0.6672887206 0.6419147849 + 0.6433644891 0.6688051224 0.6433644891 + 0.6448125243 0.6703053713 0.6448125243 + 0.6462605000 0.6718056202 0.6462605000 + 0.6477084756 0.6733058095 0.6477084756 + 0.6491544247 0.6748061180 0.6491544247 + 0.6505993009 0.6762984991 0.6505993009 + 0.6520441771 0.6777899265 0.6520441771 + 0.6534891129 0.6792812943 0.6534891129 + 0.6549304724 0.6807727218 0.6549304724 + 0.6563671231 0.6822533011 0.6563671231 + 0.6578037143 0.6837282181 0.6578037143 + 0.6592403054 0.6852030158 0.6592403054 + 0.6606746912 0.6866778731 0.6606746912 + 0.6620953083 0.6881393194 0.6620953083 + 0.6635159254 0.6895787120 0.6635159254 + 0.6649364829 0.6910182238 0.6649364829 + 0.6663571000 0.6924576163 0.6663571000 + 0.6677600145 0.6938955784 0.6677600145 + 0.6691588163 0.6953092813 0.6691588163 + 0.6705574989 0.6967229843 0.6705574989 + 0.6719563007 0.6981366873 0.6719563007 + 0.6733427048 0.6995503902 0.6733427048 + 0.6747133136 0.7009537220 0.6747133136 + 0.6760839224 0.7023522854 0.6760839224 + 0.6774544120 0.7037507892 0.6774544120 + 0.6788250208 0.7051494122 0.6788250208 + 0.6801913977 0.7065389752 0.6801913977 + 0.6815578938 0.7079041004 0.6815578938 + 0.6829243898 0.7092692852 0.6829243898 + 0.6842908859 0.7106345296 0.6842908859 + 0.6856526136 0.7119995952 0.6856526136 + 0.6870101094 0.7133480906 0.6870101094 + 0.6883677244 0.7146925926 0.6883677244 + 0.6897252202 0.7160370946 0.6897252202 + 0.6910821199 0.7173815966 0.6910821199 + 0.6924132109 0.7187203765 0.6924132109 + 0.6937443018 0.7200453877 0.6937443018 + 0.6950753927 0.7213705182 0.6950753927 + 0.6964064837 0.7226955295 0.6964064837 + 0.6977304816 0.7240206003 0.6977304816 + 0.6990460753 0.7253168225 0.6990460753 + 0.7003617287 0.7266023755 0.7003617287 + 0.7016773224 0.7278879881 0.7016773224 + 0.7029929161 0.7291736007 0.7029929161 + 0.7043045759 0.7304561734 0.7043045759 + 0.7056154013 0.7317163944 0.7056154013 + 0.7069262266 0.7329766154 0.7069262266 + 0.7082371116 0.7342368960 0.7082371116 + 0.7095441818 0.7354971170 0.7095441818 + 0.7108336091 0.7367405891 0.7108336091 + 0.7121229768 0.7379640937 0.7121229768 + 0.7134124041 0.7391875982 0.7134124041 + 0.7147017717 0.7404111028 0.7147017717 + 0.7159798741 0.7416346073 0.7159798741 + 0.7172445059 0.7428414226 0.7172445059 + 0.7185090184 0.7440423965 0.7185090184 + 0.7197735906 0.7452433705 0.7197735906 + 0.7210381031 0.7464445233 0.7210381031 + 0.7222943902 0.7476454973 0.7222943902 + 0.7235469222 0.7488263845 0.7235469222 + 0.7247992754 0.7500069737 0.7247992754 + 0.7260518074 0.7511875033 0.7260518074 + 0.7273042202 0.7523680925 0.7273042202 + 0.7285580039 0.7535430193 0.7285580039 + 0.7298120260 0.7546893954 0.7298120260 + 0.7310661077 0.7558357120 0.7310661077 + 0.7323200703 0.7569820881 0.7323200703 + 0.7335740924 0.7581285238 0.7335740924 + 0.7348139286 0.7592620850 0.7348139286 + 0.7360535264 0.7603654861 0.7360535264 + 0.7372931838 0.7614690065 0.7372931838 + 0.7385329008 0.7625724077 0.7385329008 + 0.7397707105 0.7636758089 0.7397707105 + 0.7409819961 0.7647761106 0.7409819961 + 0.7421932817 0.7658712268 0.7421932817 + 0.7434046865 0.7669662833 0.7434046865 + 0.7446159720 0.7680615187 0.7446159720 + 0.7458249927 0.7691565752 0.7458249927 + 0.7470089793 0.7702389956 0.7470089793 + 0.7481930852 0.7713027000 0.7481930852 + 0.7493770719 0.7723662853 0.7493770719 + 0.7505611181 0.7734299898 0.7505611181 + 0.7517436147 0.7744936943 0.7517436147 + 0.7528991103 0.7755483985 0.7528991103 + 0.7540546060 0.7765882015 0.7540546060 + 0.7552101016 0.7776281238 0.7552101016 + 0.7563655972 0.7786679268 0.7563655972 + 0.7575210929 0.7797077894 0.7575210929 + 0.7586535215 0.7807422280 0.7586535215 + 0.7597848773 0.7817639112 0.7597848773 + 0.7609164119 0.7827855945 0.7609164119 + 0.7620478868 0.7838072181 0.7620478868 + 0.7631794214 0.7848289013 0.7631794214 + 0.7643039823 0.7858467102 0.7643039823 + 0.7654271126 0.7868434787 0.7654271126 + 0.7665501833 0.7878404260 0.7665501833 + 0.7676733136 0.7888373137 0.7676733136 + 0.7687965035 0.7898342013 0.7687965035 + 0.7699062824 0.7908310890 0.7699062824 + 0.7710080147 0.7917973995 0.7710080147 + 0.7721098065 0.7927626967 0.7721098065 + 0.7732115984 0.7937279940 0.7732115984 + 0.7743132710 0.7946931720 0.7743132710 + 0.7754092216 0.7956585288 0.7754092216 + 0.7764948010 0.7966089845 0.7764948010 + 0.7775803804 0.7975537777 0.7775803804 + 0.7786660790 0.7984985113 0.7786660790 + 0.7797517180 0.7994433045 0.7797517180 + 0.7808365822 0.8003879786 0.7808365822 + 0.7819091082 0.8013278842 0.7819091082 + 0.7829815745 0.8022608757 0.7829815745 + 0.7840539813 0.8031939268 0.7840539813 + 0.7851265073 0.8041269183 0.7851265073 + 0.7861989737 0.8050599098 0.7861989737 + 0.7872558832 0.8059914708 0.7872558832 + 0.7883058190 0.8068947196 0.7883058190 + 0.7893555760 0.8077979088 0.7893555760 + 0.7904053926 0.8087010980 0.7904053926 + 0.7914553285 0.8096042871 0.7914553285 + 0.7924997807 0.8105074763 0.7924997807 + 0.7935289741 0.8113902807 0.7935289741 + 0.7945582867 0.8122608066 0.7945582867 + 0.7955874801 0.8131312728 0.7955874801 + 0.7966167927 0.8140019178 0.7966167927 + 0.7976459861 0.8148723841 0.7976459861 + 0.7986531258 0.8157399297 0.7986531258 + 0.7996534705 0.8165895939 0.7996534705 + 0.8006538749 0.8174393773 0.8006538749 + 0.8016542792 0.8182891011 0.8016542792 + 0.8026548028 0.8191388249 0.8026548028 + 0.8036468029 0.8199884892 0.8036468029 + 0.8046095967 0.8208152056 0.8046095967 + 0.8055725098 0.8216269016 0.8055725098 + 0.8065354228 0.8224384785 0.8065354228 + 0.8074982762 0.8232501745 0.8074982762 + 0.8084611893 0.8240618110 0.8084611893 + 0.8094077110 0.8248733878 0.8094077110 + 0.8103441000 0.8256731033 0.8103441000 + 0.8112804890 0.8264726996 0.8112804890 + 0.8122168779 0.8272724152 0.8122168779 + 0.8131533265 0.8280720711 0.8131533265 + 0.8140897155 0.8288717270 0.8140897155 + 0.8150094748 0.8296630979 0.8150094748 + 0.8159283996 0.8304389119 0.8159283996 + 0.8168473244 0.8312146068 0.8168473244 + 0.8177661896 0.8319904208 0.8177661896 + 0.8186851144 0.8327661157 0.8186851144 + 0.8195986152 0.8335418105 0.8195986152 + 0.8204926848 0.8343117237 0.8204926848 + 0.8213868737 0.8350778818 0.8213868737 + 0.8222811222 0.8358440995 0.8222811222 + 0.8231751919 0.8366103768 0.8231751919 + 0.8240693808 0.8373765945 0.8240693808 + 0.8249509931 0.8381428719 0.8249509931 + 0.8258157969 0.8389006257 0.8258157969 + 0.8266806006 0.8396567106 0.8266806006 + 0.8275455236 0.8404127955 0.8275455236 + 0.8284103274 0.8411688805 0.8284103274 + 0.8292750716 0.8419250250 0.8292750716 + 0.8301308751 0.8426809907 0.8301308751 + 0.8309800029 0.8434000015 0.8309800029 + 0.8318290710 0.8441187143 0.8318290710 + 0.8326780796 0.8448373079 0.8326780796 + 0.8335272074 0.8455560207 0.8335272074 + 0.8343762755 0.8462746143 0.8343762755 + 0.8352112174 0.8469917774 0.8352112174 + 0.8360387087 0.8476917148 0.8360387087 + 0.8368662000 0.8483915925 0.8368662000 + 0.8376936913 0.8490914702 0.8376936913 + 0.8385211825 0.8497914076 0.8385211825 + 0.8393486738 0.8504914045 0.8393486738 + 0.8401600718 0.8511893749 0.8401600718 + 0.8409640193 0.8518716097 0.8409640193 + 0.8417677879 0.8525537848 0.8417677879 + 0.8425716162 0.8532360196 0.8425716162 + 0.8433753848 0.8539181948 0.8433753848 + 0.8441792130 0.8546004295 0.8441792130 + 0.8449677825 0.8552805781 0.8449677825 + 0.8457477093 0.8559337258 0.8457477093 + 0.8465275764 0.8565866947 0.8465275764 + 0.8473075032 0.8572397828 0.8473075032 + 0.8480873704 0.8578928709 0.8480873704 + 0.8488671780 0.8585458994 0.8488671780 + 0.8496319056 0.8591989875 0.8496319056 + 0.8503823876 0.8598427773 0.8503823876 + 0.8511329889 0.8604860902 0.8511329889 + 0.8518834710 0.8611295223 0.8518834710 + 0.8526340723 0.8617728949 0.8526340723 + 0.8533846736 0.8624163270 0.8533846736 + 0.8541216850 0.8630596995 0.8541216850 + 0.8548328876 0.8636872172 0.8548328876 + 0.8555439711 0.8643105030 0.8555439711 + 0.8562551737 0.8649337888 0.8562551737 + 0.8569663167 0.8655570149 0.8569663167 + 0.8576774001 0.8661803007 0.8576774001 + 0.8583872914 0.8668035865 0.8583872914 + 0.8590850830 0.8674191236 0.8590850830 + 0.8597828150 0.8680282831 0.8597828150 + 0.8604806066 0.8686373830 0.8604806066 + 0.8611783981 0.8692466021 0.8611783981 + 0.8618761897 0.8698558211 0.8618761897 + 0.8625739813 0.8704649806 0.8625739813 + 0.8632513881 0.8710712790 0.8632513881 + 0.8639233112 0.8716691136 0.8639233112 + 0.8645951748 0.8722668886 0.8645951748 + 0.8652670979 0.8728647232 0.8652670979 + 0.8659390211 0.8734624982 0.8659390211 + 0.8666108847 0.8740602732 0.8666108847 + 0.8672788739 0.8746581078 0.8672788739 + 0.8679410815 0.8752396703 0.8679410815 + 0.8686032891 0.8758190274 0.8686032891 + 0.8692653775 0.8763983250 0.8692653775 + 0.8699275851 0.8769776225 0.8699275851 + 0.8705897927 0.8775568008 0.8705897927 + 0.8712518811 0.8781360984 0.8712518811 + 0.8719059825 0.8787040114 0.8719059825 + 0.8725597262 0.8792570233 0.8725597262 + 0.8732132912 0.8798100948 0.8732132912 + 0.8738669753 0.8803631067 0.8738669753 + 0.8745207191 0.8809161186 0.8745207191 + 0.8751742840 0.8814691901 0.8751742840 + 0.8758152127 0.8820222020 0.8758152127 + 0.8764392734 0.8825591207 0.8764392734 + 0.8770633936 0.8830946088 0.8770633936 + 0.8776875138 0.8836302161 0.8776875138 + 0.8783116937 0.8841657043 0.8783116937 + 0.8789358139 0.8847011924 0.8789358139 + 0.8795598745 0.8852367997 0.8795598745 + 0.8801736236 0.8857638836 0.8801736236 + 0.8807854056 0.8862745762 0.8807854056 + 0.8813971281 0.8867853284 0.8813971281 + 0.8820089102 0.8872959018 0.8820089102 + 0.8826205730 0.8878065944 0.8826205730 + 0.8832324147 0.8883172870 0.8832324147 + 0.8838424087 0.8888279796 0.8838424087 + 0.8844444752 0.8893265724 0.8844444752 + 0.8850466013 0.8898196220 0.8850466013 + 0.8856487274 0.8903126717 0.8856487274 + 0.8862507939 0.8908057213 0.8862507939 + 0.8868529201 0.8912987709 0.8868529201 + 0.8874549866 0.8917918205 0.8874549866 + 0.8880429268 0.8922848105 0.8880429268 + 0.8886129260 0.8927574158 0.8886129260 + 0.8891829252 0.8932290077 0.8891829252 + 0.8897529840 0.8937007189 0.8897529840 + 0.8903229833 0.8941723108 0.8903229833 + 0.8908931017 0.8946439028 0.8908931017 + 0.8914631009 0.8951156139 0.8914631009 + 0.8920254111 0.8955851793 0.8920254111 + 0.8925833702 0.8960440755 0.8925833702 + 0.8931413889 0.8965029716 0.8931413889 + 0.8936994076 0.8969618082 0.8936994076 + 0.8942574263 0.8974207044 0.8942574263 + 0.8948153257 0.8978796005 0.8948153257 + 0.8953732848 0.8983384967 0.8953732848 + 0.8959251046 0.8987923265 0.8959251046 + 0.8964747787 0.8992335200 0.8964747787 + 0.8970245719 0.8996747136 0.8970245719 + 0.8975743055 0.9001159072 0.8975743055 + 0.8981240988 0.9005571008 0.8981240988 + 0.8986737728 0.9009982944 0.8986737728 + 0.8992236257 0.9014394283 0.8992236257 + 0.8997610211 0.9018741846 0.8997610211 + 0.9002953172 0.9022963047 0.9002953172 + 0.9008296132 0.9027183056 0.9008296132 + 0.9013640285 0.9031404257 0.9013640285 + 0.9018983245 0.9035624266 0.9018983245 + 0.9024326205 0.9039844871 0.9024326205 + 0.9029669166 0.9044064879 0.9029669166 + 0.9034835100 0.9048255086 0.9034835100 + 0.9039946795 0.9052377939 0.9039946795 + 0.9045059085 0.9056500196 0.9045059085 + 0.9050170779 0.9060623050 0.9050170779 + 0.9055283070 0.9064744711 0.9055283070 + 0.9060394764 0.9068868160 0.9060394764 + 0.9065507054 0.9072989821 0.9065507054 + 0.9070444107 0.9077087045 0.9070444107 + 0.9075291157 0.9081088901 0.9075291157 + 0.9080138206 0.9085091949 0.9080138206 + 0.9084984064 0.9089093804 0.9084984064 + 0.9089831114 0.9093096256 0.9089831114 + 0.9094678164 0.9097098708 0.9094678164 + 0.9099525213 0.9101101160 0.9099525213 + 0.9104328752 0.9105101824 0.9104328752 + 0.9109085202 0.9109075069 0.9109085202 + 0.9113841057 0.9113047719 0.9113841057 + 0.9118596911 0.9117019773 0.9118596911 + 0.9123352170 0.9120993018 0.9123352170 + 0.9128108025 0.9124966264 0.9128108025 + 0.9132863879 0.9128937721 0.9132863879 + 0.9137566090 0.9132910967 0.9137566090 + 0.9142068028 0.9136837125 0.9142068028 + 0.9146568775 0.9140750170 0.9146568775 + 0.9151070714 0.9144663215 0.9151070714 + 0.9155572057 0.9148576260 0.9155572057 + 0.9160073996 0.9152488708 0.9160073996 + 0.9164574742 0.9156401753 0.9164574742 + 0.9169077277 0.9160314798 0.9169077277 + 0.9173452258 0.9164192080 0.9173452258 + 0.9177808166 0.9168025851 0.9177808166 + 0.9182164073 0.9171860218 0.9182164073 + 0.9186519980 0.9175693989 0.9186519980 + 0.9190875292 0.9179527760 0.9190875292 + 0.9195231199 0.9183362126 0.9195231199 + 0.9199587107 0.9187195897 0.9199587107 + 0.9203907251 0.9191030860 0.9203907251 + 0.9208180904 0.9194877148 0.9208180904 + 0.9212455153 0.9198724031 0.9212455153 + 0.9216729999 0.9202570915 0.9216729999 + 0.9221004248 0.9206417203 0.9221004248 + 0.9225277901 0.9210264087 0.9225277901 + 0.9229552746 0.9214110970 0.9229552746 + 0.9233826995 0.9217957258 0.9233826995 + 0.9237878919 0.9221795201 0.9237878919 + 0.9241918921 0.9225625992 0.9241918921 + 0.9245958924 0.9229457974 0.9245958924 + 0.9249997735 0.9233288765 0.9249997735 + 0.9254037738 0.9237120152 0.9254037738 + 0.9258077741 0.9240950942 0.9258077741 + 0.9262117743 0.9244781733 0.9262117743 + 0.9266104102 0.9248613119 0.9266104102 + 0.9269998074 0.9252420068 0.9269998074 + 0.9273892045 0.9256225824 0.9273892045 + 0.9277786016 0.9260032177 0.9277786016 + 0.9281679988 0.9263836741 0.9281679988 + 0.9285573959 0.9267643094 0.9285573959 + 0.9289467931 0.9271448851 0.9289467931 + 0.9293361902 0.9275255203 0.9293361902 + 0.9297145009 0.9279053807 0.9297145009 + 0.9300879240 0.9282836914 0.9300879240 + 0.9304612875 0.9286620021 0.9304612875 + 0.9308347106 0.9290403128 0.9308347106 + 0.9312080741 0.9294186831 0.9312080741 + 0.9315814972 0.9297969937 0.9315814972 + 0.9319549203 0.9301753044 0.9319549203 + 0.9323282838 0.9305536151 0.9323282838 + 0.9326866269 0.9309234023 0.9326866269 + 0.9330440164 0.9312868118 0.9330440164 + 0.9334015250 0.9316502810 0.9334015250 + 0.9337589741 0.9320136905 0.9337589741 + 0.9341164827 0.9323772192 0.9341164827 + 0.9344739914 0.9327406287 0.9344739914 + 0.9348315001 0.9331040978 0.9348315001 + 0.9351881146 0.9334675074 0.9351881146 + 0.9355376959 0.9338105917 0.9355376959 + 0.9358873963 0.9341468215 0.9358873963 + 0.9362370968 0.9344829917 0.9362370968 + 0.9365866780 0.9348192215 0.9365866780 + 0.9369363785 0.9351553917 0.9369363785 + 0.9372860789 0.9354916215 0.9372860789 + 0.9376357794 0.9358279109 0.9376357794 + 0.9379813075 0.9361640811 0.9379813075 + 0.9383106828 0.9364855886 0.9383106828 + 0.9386399984 0.9368044734 0.9386399984 + 0.9389693141 0.9371232986 0.9389693141 + 0.9392986298 0.9374421239 0.9392986298 + 0.9396280050 0.9377608895 0.9396280050 + 0.9399573207 0.9380797148 0.9399573207 + 0.9402865767 0.9383985996 0.9402865767 + 0.9406142831 0.9387174249 0.9406142831 + 0.9409353733 0.9390224218 0.9409353733 + 0.9412565231 0.9393249750 0.9412565231 + 0.9415774941 0.9396277070 0.9415774941 + 0.9418985844 0.9399303198 0.9418985844 + 0.9422196746 0.9402328730 0.9422196746 + 0.9425407052 0.9405354857 0.9425407052 + 0.9428617954 0.9408380985 0.9428617954 + 0.9431818128 0.9411407113 0.9431818128 + 0.9434933066 0.9414327741 0.9434933066 + 0.9438048005 0.9417217970 0.9438048005 + 0.9441161752 0.9420107007 0.9441161752 + 0.9444277287 0.9422997236 0.9444277287 + 0.9447392225 0.9425886273 0.9447392225 + 0.9450505972 0.9428775907 0.9450505972 + 0.9453620911 0.9431664944 0.9453620911 + 0.9456735849 0.9434555173 0.9456735849 + 0.9459661841 0.9437438250 0.9459661841 + 0.9462574720 0.9440317750 0.9462574720 + 0.9465487003 0.9443197250 0.9465487003 + 0.9468399882 0.9446076155 0.9468399882 + 0.9471312165 0.9448956251 0.9471312165 + 0.9474225044 0.9451835155 0.9474225044 + 0.9477136731 0.9454715252 0.9477136731 + 0.9480050206 0.9457594156 0.9480050206 + 0.9482976794 0.9460437298 0.9482976794 + 0.9485909939 0.9463211894 0.9485909939 + 0.9488844275 0.9465987086 0.9488844275 + 0.9491778016 0.9468762279 0.9491778016 + 0.9494711757 0.9471536875 0.9494711757 + 0.9497646093 0.9474310875 0.9497646093 + 0.9500579834 0.9477086067 0.9500579834 + 0.9503514171 0.9479861259 0.9503514171 + 0.9506422281 0.9482635856 0.9506422281 + 0.9509274960 0.9485384226 0.9509274960 + 0.9512127042 0.9488133192 0.9512127042 + 0.9514979720 0.9490882158 0.9514979720 + 0.9517831802 0.9493629932 0.9517831802 + 0.9520685077 0.9496378899 0.9520685077 + 0.9523537159 0.9499127269 0.9523537159 + 0.9526389241 0.9501876235 0.9526389241 + 0.9529241920 0.9504625201 0.9529241920 + 0.9532032013 0.9507294893 0.9532032013 + 0.9534810781 0.9509904981 0.9534810781 + 0.9537590742 0.9512513876 0.9537590742 + 0.9540370703 0.9515123963 0.9540370703 + 0.9543150067 0.9517734051 0.9543150067 + 0.9545930028 0.9520342946 0.9545930028 + 0.9548709989 0.9522953033 0.9548709989 + 0.9551489949 0.9525561929 0.9551489949 + 0.9554250240 0.9528167844 0.9554250240 + 0.9556970000 0.9530668259 0.9556970000 + 0.9559689760 0.9533166885 0.9559689760 + 0.9562410712 0.9535666108 0.9562410712 + 0.9565131068 0.9538165927 0.9565131068 + 0.9567850828 0.9540665150 0.9567850828 + 0.9570571184 0.9543164968 0.9570571184 + 0.9573290944 0.9545664191 0.9573290944 + 0.9576011896 0.9548164010 0.9576011896 + 0.9578632116 0.9550620914 0.9578632116 + 0.9581208229 0.9553020000 0.9581208229 + 0.9583783746 0.9555419087 0.9583783746 + 0.9586359859 0.9557818174 0.9586359859 + 0.9588935971 0.9560217261 0.9588935971 + 0.9591512084 0.9562615156 0.9591512084 + 0.9594088197 0.9565014243 0.9594088197 + 0.9596663713 0.9567412734 0.9596663713 + 0.9599239826 0.9569811821 0.9599239826 + 0.9601870775 0.9572148919 0.9601870775 + 0.9604502916 0.9574459791 0.9604502916 + 0.9607136250 0.9576771259 0.9607136250 + 0.9609768987 0.9579082131 0.9609768987 + 0.9612401128 0.9581393003 0.9612401128 + 0.9615033865 0.9583703876 0.9615033865 + 0.9617667198 0.9586014748 0.9617667198 + 0.9620298743 0.9588325024 0.9620298743 + 0.9622896910 0.9590635896 0.9622896910 + 0.9625295997 0.9592813849 0.9625295997 + 0.9627695084 0.9594975710 0.9627695084 + 0.9630094171 0.9597136974 0.9630094171 + 0.9632493258 0.9599298835 0.9632493258 + 0.9634891748 0.9601460099 0.9634891748 + 0.9637290835 0.9603621960 0.9637290835 + 0.9639688730 0.9605783820 0.9639688730 + 0.9642087817 0.9607945085 0.9642087817 + 0.9644483924 0.9610106945 0.9644483924 + 0.9646872282 0.9612244964 0.9646872282 + 0.9649258852 0.9614382982 0.9649258852 + 0.9651646018 0.9616519809 0.9651646018 + 0.9654033184 0.9618657827 0.9654033184 + 0.9656419754 0.9620795846 0.9656419754 + 0.9658808112 0.9622933865 0.9658808112 + 0.9661195278 0.9625071883 0.9661195278 + 0.9663581848 0.9627209902 0.9663581848 + 0.9665971994 0.9629346728 0.9665971994 + 0.9668369889 0.9631499052 0.9668369889 + 0.9670768976 0.9633650780 0.9670768976 + 0.9673168063 0.9635801911 0.9673168063 + 0.9675567150 0.9637954235 0.9675567150 + 0.9677965045 0.9640105963 0.9677965045 + 0.9680364132 0.9642258286 0.9680364132 + 0.9682763219 0.9644410014 0.9682763219 + 0.9685161114 0.9646561146 0.9685161114 + 0.9687551260 0.9648712873 0.9687551260 + 0.9689875245 0.9650797844 0.9689875245 + 0.9692199230 0.9652873874 0.9692199230 + 0.9694522023 0.9654949903 0.9694522023 + 0.9696846008 0.9657025933 0.9696846008 + 0.9699168801 0.9659103155 0.9699168801 + 0.9701492786 0.9661179185 0.9701492786 + 0.9703816175 0.9663255215 0.9703816175 + 0.9706140161 0.9665331244 0.9706140161 + 0.9708464146 0.9667407274 0.9708464146 + 0.9710645080 0.9669466019 0.9710645080 + 0.9712811708 0.9671518207 0.9712811708 + 0.9714977741 0.9673569202 0.9714977741 + 0.9717144966 0.9675620198 0.9717144966 + 0.9719312191 0.9677671790 0.9719312191 + 0.9721478820 0.9679722786 0.9721478820 + 0.9723646045 0.9681774974 0.9723646045 + 0.9725812078 0.9683825970 0.9725812078 + 0.9727978706 0.9685876966 0.9727978706 + 0.9730128050 0.9687932730 0.9730128050 + 0.9732266068 0.9689996243 0.9732266068 + 0.9734402895 0.9692057967 0.9734402895 + 0.9736539721 0.9694120884 0.9736539721 + 0.9738677144 0.9696183205 0.9738677144 + 0.9740815163 0.9698246121 0.9740815163 + 0.9742951989 0.9700307846 0.9742951989 + 0.9745088816 0.9702370763 0.9745088816 + 0.9747226834 0.9704433084 0.9747226834 + 0.9749327898 0.9706496000 0.9749327898 + 0.9751276970 0.9708499908 0.9751276970 + 0.9753227234 0.9710503817 0.9753227234 + 0.9755175710 0.9712507129 0.9755175710 + 0.9757124782 0.9714511037 0.9757124782 + 0.9759075046 0.9716514945 0.9759075046 + 0.9761024117 0.9718518853 0.9761024117 + 0.9762973785 0.9720522761 0.9762973785 + 0.9764922857 0.9722527266 0.9764922857 + 0.9766871929 0.9724531174 0.9766871929 + 0.9768773913 0.9726468921 0.9768773913 + 0.9770653844 0.9728342891 0.9770653844 + 0.9772533774 0.9730216265 0.9772533774 + 0.9774413109 0.9732090235 0.9774413109 + 0.9776293039 0.9733963013 0.9776293039 + 0.9778172970 0.9735835791 0.9778172970 + 0.9780052900 0.9737709761 0.9780052900 + 0.9781932235 0.9739583135 0.9781932235 + 0.9783812165 0.9741457105 0.9783812165 + 0.9785689116 0.9743329883 0.9785689116 + 0.9787533879 0.9745092988 0.9787533879 + 0.9789379239 0.9746842980 0.9789379239 + 0.9791222811 0.9748592973 0.9791222811 + 0.9793068171 0.9750342965 0.9793068171 + 0.9794911742 0.9752092957 0.9794911742 + 0.9796757102 0.9753842950 0.9796757102 + 0.9798601270 0.9755592942 0.9798601270 + 0.9800446033 0.9757342935 0.9800446033 + 0.9802290201 0.9759092927 0.9802290201 + 0.9804099202 0.9760805964 0.9804099202 + 0.9805839062 0.9762361050 0.9805839062 + 0.9807580113 0.9763916731 0.9807580113 + 0.9809321165 0.9765471816 0.9809321165 + 0.9811062217 0.9767026901 0.9811062217 + 0.9812802076 0.9768583179 0.9812802076 + 0.9814543128 0.9770138264 0.9814543128 + 0.9816284180 0.9771692753 0.9816284180 + 0.9818025231 0.9773249030 0.9818025231 + 0.9819766283 0.9774804115 0.9819766283 + 0.9821426272 0.9776375294 0.9821426272 + 0.9823012948 0.9777972102 0.9823012948 + 0.9824600816 0.9779568911 0.9824600816 + 0.9826188087 0.9781165719 0.9826188087 + 0.9827775955 0.9782761931 0.9827775955 + 0.9829363227 0.9784358740 0.9829363227 + 0.9830951095 0.9785956144 0.9830951095 + 0.9832537770 0.9787552953 0.9832537770 + 0.9834125042 0.9789149761 0.9834125042 + 0.9835712910 0.9790747166 0.9835712910 + 0.9837297201 0.9792376757 0.9837297201 + 0.9838877916 0.9794046283 0.9838877916 + 0.9840459824 0.9795715213 0.9840459824 + 0.9842041135 0.9797384143 0.9842041135 + 0.9843623042 0.9799053073 0.9843623042 + 0.9845203757 0.9800723195 0.9845203757 + 0.9846786261 0.9802392125 0.9846786261 + 0.9848366976 0.9804061055 0.9848366976 + 0.9849948883 0.9805729985 0.9849948883 + 0.9851530194 0.9807398915 0.9851530194 + 0.9853115082 0.9809073210 0.9853115082 + 0.9854704142 0.9810754061 0.9854704142 + 0.9856293201 0.9812434912 0.9856293201 + 0.9857881069 0.9814115167 0.9857881069 + 0.9859470129 0.9815796018 0.9859470129 + 0.9861057997 0.9817476869 0.9861057997 + 0.9862647057 0.9819157124 0.9862647057 + 0.9864236116 0.9820837975 0.9864236116 + 0.9865823984 0.9822518826 0.9865823984 + 0.9867413044 0.9824199080 0.9867413044 + 0.9868972898 0.9825896025 0.9868972898 + 0.9870492816 0.9827628732 0.9870492816 + 0.9872012138 0.9829362035 0.9872012138 + 0.9873532057 0.9831094742 0.9873532057 + 0.9875051975 0.9832828045 0.9875051975 + 0.9876571894 0.9834560752 0.9876571894 + 0.9878091812 0.9836292863 0.9878091812 + 0.9879611731 0.9838026166 0.9879611731 + 0.9881131053 0.9839758873 0.9881131053 + 0.9882650971 0.9841492176 0.9882650971 + 0.9884155989 0.9843227863 0.9884155989 + 0.9885584116 0.9845007062 0.9885584116 + 0.9887011051 0.9846786261 0.9887011051 + 0.9888437986 0.9848564863 0.9888437986 + 0.9889864922 0.9850344062 0.9889864922 + 0.9891293049 0.9852123260 0.9891293049 + 0.9892719984 0.9853901863 0.9892719984 + 0.9894146919 0.9855681062 0.9894146919 + 0.9895573854 0.9857460260 0.9895573854 + 0.9897001982 0.9859238863 0.9897001982 + 0.9898428917 0.9861018062 0.9898428917 + 0.9899815917 0.9862813950 0.9899815917 + 0.9901192784 0.9864618182 0.9901192784 + 0.9902570248 0.9866421819 0.9902570248 + 0.9903945923 0.9868224859 0.9903945923 + 0.9905322790 0.9870029092 0.9905322790 + 0.9906700253 0.9871832728 0.9906700253 + 0.9908077121 0.9873635769 0.9908077121 + 0.9909452796 0.9875440001 0.9909452796 + 0.9910830259 0.9877244234 0.9910830259 + 0.9912207127 0.9879047871 0.9912207127 + 0.9913563728 0.9880853295 0.9913563728 + 0.9914879799 0.9882667065 0.9914879799 + 0.9916195273 0.9884480238 0.9916195273 + 0.9917510152 0.9886294007 0.9917510152 + 0.9918825030 0.9888107181 0.9918825030 + 0.9920139909 0.9889919758 0.9920139909 + 0.9921454787 0.9891734123 0.9921454787 + 0.9922770262 0.9893547297 0.9922770262 + 0.9924085140 0.9895361066 0.9924085140 + 0.9925400019 0.9897174239 0.9925400019 + 0.9926714897 0.9898986816 0.9926714897 + 0.9928073883 0.9900819063 0.9928073883 + 0.9929450154 0.9902659059 0.9929450154 + 0.9930827022 0.9904500246 0.9930827022 + 0.9932203293 0.9906340241 0.9932203293 + 0.9933580160 0.9908180833 0.9933580160 + 0.9934955835 0.9910022020 0.9934955835 + 0.9936332107 0.9911862016 0.9936332107 + 0.9937708974 0.9913703203 0.9937708974 + 0.9939085245 0.9915543795 0.9939085245 + 0.9940462112 0.9917383790 0.9940462112 + 0.9941837192 0.9919224977 0.9941837192 + 0.9943144917 0.9921045899 0.9943144917 + 0.9944453835 0.9922866821 0.9944453835 + 0.9945762157 0.9924687147 0.9945762157 + 0.9947069883 0.9926506877 0.9947069883 + 0.9948378205 0.9928327799 0.9948378205 + 0.9949685931 0.9930148125 0.9949685931 + 0.9950994253 0.9931967854 0.9950994253 + 0.9952301979 0.9933788776 0.9952301979 + 0.9953609705 0.9935609102 0.9953609705 + 0.9954918027 0.9937428832 0.9954918027 + 0.9956232905 0.9939253926 0.9956232905 + 0.9957578778 0.9941105843 0.9957578778 + 0.9958925843 0.9942957163 0.9958925843 + 0.9960271716 0.9944809079 0.9960271716 + 0.9961618781 0.9946660995 0.9961618781 + 0.9962965250 0.9948512912 0.9962965250 + 0.9964311123 0.9950364232 0.9964311123 + 0.9965658188 0.9952216148 0.9965658188 + 0.9967004061 0.9954068065 0.9967004061 + 0.9968351126 0.9955918789 0.9968351126 + 0.9969696999 0.9957770705 0.9969696999 + 0.9971042275 0.9959601164 0.9971042275 + 0.9972379804 0.9961351752 0.9972379804 + 0.9973717928 0.9963101745 0.9973717928 + 0.9975057244 0.9964852929 0.9975057244 + 0.9976394773 0.9966604114 0.9976394773 + 0.9977734089 0.9968354702 0.9977734089 + 0.9979072213 0.9970105290 0.9979072213 + 0.9980410933 0.9971855879 0.9980410933 + 0.9981749058 0.9973607063 0.9981749058 + 0.9983087778 0.9975357056 0.9983087778 + 0.9984425902 0.9977108240 0.9984425902 + 0.9985756874 0.9978886843 0.9985756874 + 0.9987052083 0.9980806112 0.9987052083 + 0.9988346100 0.9982725978 0.9988346100 + 0.9989640713 0.9984645247 0.9989640713 + 0.9990935922 0.9986563921 0.9990935922 + 0.9992231131 0.9988483787 0.9992231131 + 0.9993525743 0.9990403056 0.9993525743 + 0.9994820952 0.9992322922 0.9994820952 + 0.9996114969 0.9994242191 0.9996114969 + 0.9997410178 0.9996160865 0.9997410178 + 0.9998704791 0.9998080730 0.9998704791 + 1.0000000000 1.0000000000 1.0000000000 +} diff --git a/rpplugins/color_correction/resources/film_luts_raw/kodak_max_zoom_800.spi1d b/rpplugins/color_correction/resources/film_luts_raw/kodak_max_zoom_800.spi1d new file mode 100644 index 0000000..bb80ebd --- /dev/null +++ b/rpplugins/color_correction/resources/film_luts_raw/kodak_max_zoom_800.spi1d @@ -0,0 +1,1030 @@ +Version 1 +From 0.0 1.0 +Length 1024 +Components 3 +{ + 0.0000000000 0.0000000000 0.0000000000 + 0.0084391097 0.0075763101 0.0055803522 + 0.0169892292 0.0151253100 0.0110553904 + 0.0246818494 0.0219931193 0.0160910394 + 0.0317661613 0.0282940008 0.0208101291 + 0.0382325202 0.0340048485 0.0251940992 + 0.0441172384 0.0393486507 0.0293568596 + 0.0496861897 0.0445001610 0.0333589911 + 0.0550585985 0.0493195914 0.0371792093 + 0.0601223111 0.0539280511 0.0408726782 + 0.0649642274 0.0583757199 0.0444436409 + 0.0695851371 0.0626427680 0.0479431897 + 0.0740094930 0.0667798966 0.0513359718 + 0.0783147216 0.0707852617 0.0546398088 + 0.0825306326 0.0747059137 0.0578773208 + 0.0866608396 0.0785023794 0.0610598996 + 0.0907057226 0.0822077468 0.0641641617 + 0.0946363509 0.0858238488 0.0672321990 + 0.0984090120 0.0893622264 0.0702527389 + 0.1020661965 0.0928608030 0.0732008815 + 0.1056471020 0.0963046327 0.0760966092 + 0.1091898009 0.0996690318 0.0789577886 + 0.1126779020 0.1029520035 0.0817804411 + 0.1161487997 0.1061682031 0.0845761225 + 0.1195472032 0.1093337014 0.0873135701 + 0.1229045019 0.1124323979 0.0900195017 + 0.1262066960 0.1155048013 0.0926894471 + 0.1294586062 0.1185453981 0.0953314528 + 0.1326504052 0.1215455979 0.0979523510 + 0.1357606053 0.1245016977 0.1005545035 + 0.1388241053 0.1273857951 0.1031209007 + 0.1418274045 0.1302534044 0.1056765020 + 0.1447373033 0.1330838054 0.1081990004 + 0.1476096958 0.1358837932 0.1106970012 + 0.1504617035 0.1386432946 0.1131801978 + 0.1533035040 0.1413915008 0.1156400964 + 0.1561179012 0.1440995932 0.1180797964 + 0.1589269936 0.1467884034 0.1204816997 + 0.1617161930 0.1494296938 0.1228761971 + 0.1644722074 0.1520594060 0.1252495944 + 0.1672009975 0.1546591967 0.1275874972 + 0.1699149013 0.1572349966 0.1299159974 + 0.1725970954 0.1597743034 0.1322304010 + 0.1752271056 0.1622851938 0.1345029026 + 0.1778230965 0.1647903025 0.1367422938 + 0.1803787053 0.1672617942 0.1389641017 + 0.1828950047 0.1697237939 0.1411608011 + 0.1853982061 0.1721518934 0.1433494985 + 0.1878785938 0.1745534986 0.1455025971 + 0.1903571934 0.1769458950 0.1476327926 + 0.1928332001 0.1793050021 0.1497652978 + 0.1952915937 0.1816422045 0.1519078016 + 0.1977207959 0.1839872003 0.1540307999 + 0.2001152039 0.1863050014 0.1561508030 + 0.2025077045 0.1886059940 0.1582663059 + 0.2049013972 0.1908763051 0.1603844017 + 0.2072762996 0.1931104958 0.1624784023 + 0.2096343935 0.1953328997 0.1645596027 + 0.2119597048 0.1975608021 0.1666202992 + 0.2142512947 0.1997732073 0.1686652005 + 0.2165051997 0.2019650936 0.1706995964 + 0.2187242955 0.2041545063 0.1727278978 + 0.2209309936 0.2063177973 0.1747494042 + 0.2231297940 0.2084506005 0.1767428070 + 0.2253059000 0.2105776966 0.1787129939 + 0.2274693996 0.2127068937 0.1806745976 + 0.2296334058 0.2148050070 0.1826314926 + 0.2317734957 0.2168878019 0.1845801026 + 0.2338978052 0.2189736068 0.1865082979 + 0.2360040992 0.2210465968 0.1884184927 + 0.2380760014 0.2230933011 0.1903171986 + 0.2401296049 0.2251244932 0.1922022998 + 0.2421852946 0.2271171063 0.1940843016 + 0.2442210019 0.2290779948 0.1959476024 + 0.2462366074 0.2310225964 0.1977925003 + 0.2482510954 0.2329605967 0.1996293068 + 0.2502493858 0.2348946929 0.2014590949 + 0.2522226870 0.2368202060 0.2032801062 + 0.2541834116 0.2387333065 0.2050863057 + 0.2561317980 0.2406367958 0.2068803012 + 0.2580586970 0.2425450981 0.2086673975 + 0.2599673867 0.2444512993 0.2104519010 + 0.2618735135 0.2463417053 0.2122323960 + 0.2637856007 0.2482246011 0.2140039951 + 0.2656947076 0.2501086891 0.2157679945 + 0.2675924003 0.2519941926 0.2175332010 + 0.2694917023 0.2538610101 0.2192887962 + 0.2713840008 0.2557184100 0.2210364938 + 0.2732622921 0.2575724125 0.2227811962 + 0.2751278877 0.2594226897 0.2245233059 + 0.2769821882 0.2612658143 0.2262614965 + 0.2788152099 0.2630968094 0.2279942930 + 0.2806366980 0.2649213970 0.2297101021 + 0.2824515104 0.2667475939 0.2314116955 + 0.2842657864 0.2685596049 0.2331091017 + 0.2860780060 0.2703500092 0.2348040938 + 0.2878656983 0.2721207142 0.2364936024 + 0.2896395028 0.2738777995 0.2381702960 + 0.2914094925 0.2756209075 0.2398329973 + 0.2931736112 0.2773512006 0.2414873987 + 0.2949214876 0.2790701985 0.2431395948 + 0.2966547906 0.2807764113 0.2447883040 + 0.2983818054 0.2824758887 0.2464286983 + 0.3001014888 0.2841669023 0.2480624020 + 0.3017992973 0.2858343124 0.2496916056 + 0.3034814894 0.2875004113 0.2513076067 + 0.3051558137 0.2891632915 0.2529129982 + 0.3068262041 0.2908203900 0.2545062900 + 0.3085027933 0.2924638093 0.2560915053 + 0.3101766109 0.2941013873 0.2576715052 + 0.3118444085 0.2957335114 0.2592464983 + 0.3135068119 0.2973626852 0.2608287036 + 0.3151695132 0.2989872992 0.2624095082 + 0.3168335855 0.3006061018 0.2639889121 + 0.3184846938 0.3022069037 0.2655547857 + 0.3201304972 0.3038052917 0.2671144009 + 0.3217692077 0.3054029942 0.2686659992 + 0.3234055936 0.3069913089 0.2702147961 + 0.3250352144 0.3085735142 0.2717638910 + 0.3266384900 0.3101415038 0.2733153105 + 0.3282344043 0.3117021918 0.2748562098 + 0.3298248947 0.3132582009 0.2763910890 + 0.3314053118 0.3148199916 0.2779105008 + 0.3329854906 0.3163794875 0.2794237137 + 0.3345662951 0.3179340065 0.2809270918 + 0.3361378908 0.3194747865 0.2824262977 + 0.3377039135 0.3210082948 0.2839238942 + 0.3392634988 0.3225387931 0.2854253054 + 0.3408218026 0.3240653872 0.2869231999 + 0.3423773050 0.3255797923 0.2884125113 + 0.3439236879 0.3270798028 0.2898918986 + 0.3454602063 0.3285647929 0.2913635075 + 0.3469888866 0.3300414979 0.2928242981 + 0.3485142887 0.3315150142 0.2942822874 + 0.3500323892 0.3329941928 0.2957330048 + 0.3515473902 0.3344734013 0.2971836030 + 0.3530417979 0.3359495103 0.2986334860 + 0.3545320034 0.3374226987 0.3000814021 + 0.3560110033 0.3388882875 0.3015252054 + 0.3574849069 0.3403522074 0.3029659092 + 0.3589515090 0.3418137133 0.3044033051 + 0.3604162931 0.3432742059 0.3058296144 + 0.3618794084 0.3447338939 0.3072482944 + 0.3633390963 0.3461844921 0.3086608946 + 0.3647964895 0.3476294875 0.3100705147 + 0.3662520945 0.3490661085 0.3114804029 + 0.3677066863 0.3504985869 0.3128904998 + 0.3691571951 0.3519344032 0.3143031001 + 0.3706058860 0.3533715010 0.3157165051 + 0.3720482886 0.3548054099 0.3171201050 + 0.3734880090 0.3562380075 0.3185209036 + 0.3749237061 0.3576630950 0.3199110925 + 0.3763574958 0.3590848148 0.3212977052 + 0.3777863979 0.3605031073 0.3226788938 + 0.3792122900 0.3619194031 0.3240576982 + 0.3806298971 0.3633339107 0.3254354894 + 0.3820405006 0.3647469878 0.3268128037 + 0.3834429979 0.3661527932 0.3281848133 + 0.3848352134 0.3675504029 0.3295519948 + 0.3862208128 0.3689433932 0.3309170902 + 0.3875918090 0.3703270853 0.3322786987 + 0.3889611959 0.3717108071 0.3336370885 + 0.3903222978 0.3730942905 0.3349848986 + 0.3916833997 0.3744777143 0.3363322914 + 0.3930288851 0.3758434951 0.3376722932 + 0.3943736851 0.3772087991 0.3390122950 + 0.3957099915 0.3785588145 0.3403486907 + 0.3970431089 0.3799039125 0.3416841924 + 0.3983731866 0.3812474012 0.3430136144 + 0.3996999860 0.3825891912 0.3443383873 + 0.4010235071 0.3839282095 0.3456582129 + 0.4023340046 0.3852578998 0.3469654024 + 0.4036445916 0.3865875006 0.3482725918 + 0.4049448073 0.3878997862 0.3495655954 + 0.4062437117 0.3892104924 0.3508580923 + 0.4075376093 0.3905136883 0.3521454036 + 0.4088271856 0.3918113112 0.3534295857 + 0.4101122916 0.3931080997 0.3547120988 + 0.4113762975 0.3944020867 0.3559896052 + 0.4126402140 0.3956961036 0.3572671115 + 0.4138968885 0.3969767988 0.3585371077 + 0.4151513875 0.3982538879 0.3598057032 + 0.4164057970 0.3995262980 0.3610734046 + 0.4176602066 0.4007898867 0.3623399138 + 0.4189145863 0.4020535052 0.3636063933 + 0.4201653004 0.4033161998 0.3648683131 + 0.4214152992 0.4045788944 0.3661297858 + 0.4226615131 0.4058408141 0.3673880100 + 0.4239003062 0.4071016014 0.3686417937 + 0.4251390994 0.4083622992 0.3698956072 + 0.4263815880 0.4096068144 0.3711366951 + 0.4276249111 0.4108476937 0.3723761141 + 0.4288657010 0.4120868146 0.3736143112 + 0.4300980866 0.4133198857 0.3748500049 + 0.4313304126 0.4145531058 0.3760857880 + 0.4325571954 0.4157873988 0.3773151934 + 0.4337803125 0.4170222878 0.3785417974 + 0.4350034893 0.4182572067 0.3797681034 + 0.4362299144 0.4194813967 0.3809858859 + 0.4374563098 0.4207052886 0.3822036982 + 0.4386776090 0.4219268858 0.3834176064 + 0.4398860931 0.4231427014 0.3846245110 + 0.4410946071 0.4243586063 0.3858315051 + 0.4422994852 0.4255749881 0.3870328963 + 0.4435017109 0.4267917871 0.3882313073 + 0.4447039068 0.4280084968 0.3894298077 + 0.4459021091 0.4292202890 0.3906225860 + 0.4470992088 0.4304310977 0.3918147981 + 0.4482960999 0.4316413999 0.3930067122 + 0.4494735003 0.4328393936 0.3941971064 + 0.4506509900 0.4340375066 0.3953875005 + 0.4518275857 0.4352346957 0.3965758979 + 0.4530000091 0.4364287853 0.3977586031 + 0.4541724920 0.4376227856 0.3989411891 + 0.4553438127 0.4388133883 0.4001224041 + 0.4565126896 0.4399971962 0.4013010859 + 0.4576815069 0.4411810040 0.4024797976 + 0.4588429928 0.4423573911 0.4036575854 + 0.4599938095 0.4435240030 0.4048345089 + 0.4611446857 0.4446905851 0.4060113132 + 0.4622924924 0.4458532035 0.4071837068 + 0.4634366930 0.4470112920 0.4083524048 + 0.4645808041 0.4481694102 0.4095211029 + 0.4657213092 0.4493247867 0.4106839895 + 0.4668577015 0.4504772127 0.4118421078 + 0.4679940939 0.4516296983 0.4130002856 + 0.4691272080 0.4527780116 0.4141499102 + 0.4702562094 0.4539214969 0.4152916968 + 0.4713852108 0.4550648928 0.4164333940 + 0.4725120962 0.4562053084 0.4175724983 + 0.4736359119 0.4573408067 0.4187080860 + 0.4747596085 0.4584763944 0.4198437035 + 0.4758782089 0.4596096873 0.4209780991 + 0.4769828022 0.4607372880 0.4221099913 + 0.4780873954 0.4618648887 0.4232420027 + 0.4791901112 0.4629899859 0.4243740141 + 0.4802770019 0.4640980959 0.4255062938 + 0.4813640118 0.4652062058 0.4266386926 + 0.4824509025 0.4663142860 0.4277710021 + 0.4835343957 0.4674096107 0.4288952053 + 0.4846175909 0.4685041010 0.4300192893 + 0.4857007861 0.4695985019 0.4311434031 + 0.4867846966 0.4706852138 0.4322606921 + 0.4878689945 0.4717684984 0.4333756864 + 0.4889532924 0.4728518128 0.4344907105 + 0.4900343120 0.4739331901 0.4356062114 + 0.4911102951 0.4750120044 0.4367220104 + 0.4921863079 0.4760906994 0.4378378987 + 0.4932622910 0.4771688879 0.4389531910 + 0.4943380952 0.4782414138 0.4400649071 + 0.4954138100 0.4793137908 0.4411765039 + 0.4964896142 0.4803862870 0.4422881901 + 0.4975619018 0.4814558029 0.4433946908 + 0.4986326098 0.4825241864 0.4444997013 + 0.4997034073 0.4835925102 0.4456045926 + 0.5007709861 0.4846589863 0.4467051029 + 0.5018302202 0.4857206941 0.4477970898 + 0.5028892756 0.4867824912 0.4488891065 + 0.5039485097 0.4878442883 0.4499810040 + 0.5050029755 0.4888986051 0.4510704875 + 0.5060563087 0.4899514019 0.4521594942 + 0.5071097016 0.4910041988 0.4532485902 + 0.5081599951 0.4920547903 0.4543373883 + 0.5092030168 0.4931007922 0.4554258883 + 0.5102459788 0.4941467047 0.4565143883 + 0.5112890005 0.4951925874 0.4576028883 + 0.5123233795 0.4962320924 0.4586854875 + 0.5133545995 0.4972695112 0.4597668052 + 0.5143858790 0.4983069003 0.4608480036 + 0.5154163241 0.4993439913 0.4619261920 + 0.5164411068 0.5003792048 0.4629918933 + 0.5174658895 0.5014144182 0.4640575945 + 0.5184906721 0.5024495721 0.4651232958 + 0.5195080042 0.5034834743 0.4661859870 + 0.5205168128 0.5045161247 0.4672459960 + 0.5215256214 0.5055487752 0.4683060944 + 0.5225343704 0.5065814257 0.4693661034 + 0.5235391855 0.5076125264 0.4704234004 + 0.5245428085 0.5086430907 0.4714801013 + 0.5255464911 0.5096737742 0.4725368917 + 0.5265501142 0.5107042789 0.4735935032 + 0.5275589824 0.5117307901 0.4746482074 + 0.5285679102 0.5127573013 0.4757030010 + 0.5295767188 0.5137838721 0.4767577052 + 0.5305829048 0.5148088932 0.4778087139 + 0.5315781236 0.5158286095 0.4788492024 + 0.5325732827 0.5168482065 0.4798896909 + 0.5335685015 0.5178679228 0.4809302986 + 0.5345616937 0.5188835859 0.4819678068 + 0.5355507731 0.5198920965 0.4830011129 + 0.5365399122 0.5209006071 0.4840342999 + 0.5375291109 0.5219091773 0.4850674868 + 0.5385140777 0.5229142904 0.4861018956 + 0.5394936800 0.5239152908 0.4871374071 + 0.5404732823 0.5249161720 0.4881727993 + 0.5414528847 0.5259171724 0.4892083108 + 0.5424301028 0.5269111991 0.4902406037 + 0.5434045196 0.5278977156 0.4912700951 + 0.5443788171 0.5288841724 0.4922995865 + 0.5453531742 0.5298706889 0.4933289886 + 0.5463275909 0.5308517814 0.4943523109 + 0.5473020077 0.5318266153 0.4953694046 + 0.5482764244 0.5328012705 0.4963865876 + 0.5492507815 0.5337759852 0.4974038005 + 0.5502228141 0.5347477794 0.4984166026 + 0.5511909127 0.5357149243 0.4994237125 + 0.5521588922 0.5366820097 0.5004308820 + 0.5531268716 0.5376489758 0.5014380217 + 0.5540925264 0.5386124253 0.5024443269 + 0.5550501943 0.5395649076 0.5034484267 + 0.5560079813 0.5405173898 0.5044525266 + 0.5569657087 0.5414698124 0.5054566264 + 0.5579233170 0.5424215198 0.5064595938 + 0.5588781238 0.5433623791 0.5074540973 + 0.5598328710 0.5443031788 0.5084484816 + 0.5607876778 0.5452440977 0.5094429851 + 0.5617424846 0.5461850166 0.5104374886 + 0.5626881123 0.5471224189 0.5114172101 + 0.5636314154 0.5480589867 0.5123947859 + 0.5645747781 0.5489956737 0.5133724809 + 0.5655180812 0.5499323010 0.5143501163 + 0.5664566755 0.5508654118 0.5153220296 + 0.5673907995 0.5517954230 0.5162897706 + 0.5683248043 0.5527253747 0.5172575712 + 0.5692589283 0.5536553860 0.5182253718 + 0.5701919794 0.5545833111 0.5191931129 + 0.5711194873 0.5555014014 0.5201603770 + 0.5720471144 0.5564193726 0.5211277008 + 0.5729746819 0.5573375225 0.5220949054 + 0.5739021897 0.5582554936 0.5230622292 + 0.5748242736 0.5591751933 0.5240322948 + 0.5757443905 0.5600954294 0.5250031948 + 0.5766643882 0.5610156059 0.5259739757 + 0.5775845051 0.5619357824 0.5269448757 + 0.5785031915 0.5628547072 0.5279111862 + 0.5794178843 0.5637699962 0.5288679004 + 0.5803325176 0.5646852851 0.5298246741 + 0.5812472105 0.5656005740 0.5307815075 + 0.5821619034 0.5665159225 0.5317382216 + 0.5830687881 0.5674222708 0.5326874852 + 0.5839726925 0.5683256984 0.5336347222 + 0.5848765969 0.5692290068 0.5345818996 + 0.5857805014 0.5701323152 0.5355291963 + 0.5866835713 0.5710356236 0.5364757776 + 0.5875809193 0.5719385743 0.5374200940 + 0.5884782076 0.5728415251 0.5383644104 + 0.5893754959 0.5737444758 0.5393087268 + 0.5902727246 0.5746474266 0.5402529836 + 0.5911679864 0.5755448937 0.5411959887 + 0.5920606852 0.5764362812 0.5421379209 + 0.5929535031 0.5773277283 0.5430796742 + 0.5938463211 0.5782189965 0.5440214872 + 0.5947390795 0.5791103840 0.5449634194 + 0.5956212878 0.5799939036 0.5458949208 + 0.5964996219 0.5808746815 0.5468239188 + 0.5973780155 0.5817555785 0.5477527976 + 0.5982564092 0.5826364160 0.5486817956 + 0.5991346836 0.5835173130 0.5496106148 + 0.6000012755 0.5843989253 0.5505310297 + 0.6008672118 0.5852805972 0.5514513254 + 0.6017332077 0.5861622095 0.5523716807 + 0.6025990844 0.5870438814 0.5532919765 + 0.6034640074 0.5879251957 0.5542123914 + 0.6043193936 0.5888038874 0.5551329255 + 0.6051747203 0.5896825194 0.5560534000 + 0.6060299873 0.5905610919 0.5569739938 + 0.6068853140 0.5914397240 0.5578945279 + 0.6077398062 0.5923171043 0.5588160753 + 0.6085901856 0.5931892991 0.5597410798 + 0.6094405055 0.5940614939 0.5606660247 + 0.6102908254 0.5949336886 0.5615910292 + 0.6111412048 0.5958060026 0.5625159144 + 0.6119889021 0.5966781974 0.5634377003 + 0.6128252149 0.5975505114 0.5643500090 + 0.6136614084 0.5984228253 0.5652621984 + 0.6144977212 0.5992950201 0.5661745071 + 0.6153339148 0.6001672745 0.5670866966 + 0.6161686182 0.6010373831 0.5679973960 + 0.6169930100 0.6018946171 0.5689010024 + 0.6178174019 0.6027516723 0.5698046088 + 0.6186416745 0.6036089063 0.5707082152 + 0.6194661260 0.6044660807 0.5716118813 + 0.6202905178 0.6053230762 0.5725151896 + 0.6211113930 0.6061736941 0.5734145045 + 0.6219323277 0.6070241928 0.5743138194 + 0.6227532029 0.6078748107 0.5752130747 + 0.6235740781 0.6087254286 0.5761123896 + 0.6243950725 0.6095759273 0.5770117044 + 0.6252127886 0.6104241014 0.5779047012 + 0.6260297894 0.6112717986 0.5787969232 + 0.6268466711 0.6121194959 0.5796890259 + 0.6276636720 0.6129671931 0.5805811286 + 0.6284806728 0.6138148904 0.5814732909 + 0.6292939782 0.6146571040 0.5823628902 + 0.6301044226 0.6154950857 0.5832508206 + 0.6309146881 0.6163331270 0.5841388106 + 0.6317250729 0.6171712279 0.5850268006 + 0.6325353980 0.6180092096 0.5859146714 + 0.6333454847 0.6188457012 0.5868017077 + 0.6341544986 0.6196774244 0.5876858830 + 0.6349633932 0.6205092072 0.5885701776 + 0.6357724071 0.6213408709 0.5894544721 + 0.6365814209 0.6221725941 0.5903387070 + 0.6373903155 0.6230043173 0.5912230015 + 0.6381942034 0.6238338947 0.5921056867 + 0.6389968991 0.6246629953 0.5929881930 + 0.6397994757 0.6254922152 0.5938706994 + 0.6406021714 0.6263213158 0.5947532058 + 0.6414049268 0.6271504164 0.5956355929 + 0.6422066092 0.6279762983 0.5965138078 + 0.6430063248 0.6287959814 0.5973852873 + 0.6438059807 0.6296157837 0.5982567072 + 0.6446056962 0.6304355264 0.5991281271 + 0.6454054117 0.6312552094 0.5999996066 + 0.6462051868 0.6320748925 0.6008710265 + 0.6469957829 0.6328898072 0.6017335057 + 0.6477838159 0.6337034106 0.6025940776 + 0.6485717297 0.6345170736 0.6034547091 + 0.6493597031 0.6353306770 0.6043154001 + 0.6501476765 0.6361442804 0.6051759720 + 0.6509342790 0.6369585991 0.6060351729 + 0.6517130733 0.6377763152 0.6068887711 + 0.6524918079 0.6385939717 0.6077424288 + 0.6532706022 0.6394116879 0.6085960269 + 0.6540492773 0.6402294040 0.6094496250 + 0.6548280716 0.6410471201 0.6103032231 + 0.6556051970 0.6418619156 0.6111536026 + 0.6563801169 0.6426733732 0.6120008230 + 0.6571549773 0.6434847713 0.6128481030 + 0.6579298973 0.6442962289 0.6136953235 + 0.6587048173 0.6451076269 0.6145424843 + 0.6594796777 0.6459190249 0.6153897047 + 0.6602489948 0.6467270255 0.6162346005 + 0.6610152721 0.6475332975 0.6170787215 + 0.6617817283 0.6483396292 0.6179227829 + 0.6625480056 0.6491457820 0.6187667847 + 0.6633144021 0.6499521136 0.6196109056 + 0.6640806794 0.6507583857 0.6204549074 + 0.6648426056 0.6515669823 0.6212937236 + 0.6656033993 0.6523761153 0.6221314073 + 0.6663640738 0.6531851888 0.6229692101 + 0.6671249270 0.6539943218 0.6238070130 + 0.6678856015 0.6548035145 0.6246448159 + 0.6686462760 0.6556125879 0.6254826188 + 0.6694011092 0.6564118862 0.6263144016 + 0.6701549292 0.6572096944 0.6271455884 + 0.6709085703 0.6580076218 0.6279767752 + 0.6716623902 0.6588053703 0.6288080215 + 0.6724160910 0.6596031785 0.6296392083 + 0.6731699109 0.6604009867 0.6304703951 + 0.6739165187 0.6611961722 0.6312931180 + 0.6746615767 0.6619908214 0.6321147084 + 0.6754066944 0.6627854109 0.6329362988 + 0.6761518121 0.6635800004 0.6337578297 + 0.6768969893 0.6643745899 0.6345794201 + 0.6776421070 0.6651691794 0.6354010105 + 0.6783866882 0.6659619808 0.6362180114 + 0.6791309714 0.6667541862 0.6370335817 + 0.6798753738 0.6675463915 0.6378492713 + 0.6806197762 0.6683385968 0.6386650205 + 0.6813641787 0.6691308022 0.6394807100 + 0.6821085215 0.6699230075 0.6402962804 + 0.6828457713 0.6707084775 0.6411076188 + 0.6835768819 0.6714885235 0.6419157982 + 0.6843081117 0.6722685099 0.6427239776 + 0.6850392222 0.6730484962 0.6435320973 + 0.6857702732 0.6738284826 0.6443402767 + 0.6865015030 0.6746084094 0.6451485157 + 0.6872311234 0.6753873229 0.6459537148 + 0.6879568100 0.6761630774 0.6467525959 + 0.6886826158 0.6769388914 0.6475514174 + 0.6894083023 0.6777147055 0.6483502984 + 0.6901339889 0.6784905195 0.6491491199 + 0.6908596754 0.6792662740 0.6499480009 + 0.6915854216 0.6800420880 0.6507468224 + 0.6923050880 0.6808115244 0.6515396833 + 0.6930242777 0.6815804243 0.6523323059 + 0.6937434077 0.6823492050 0.6531249285 + 0.6944625974 0.6831181049 0.6539174914 + 0.6951817274 0.6838870049 0.6547101140 + 0.6959009171 0.6846559048 0.6555026770 + 0.6966161728 0.6854197979 0.6562970281 + 0.6973273754 0.6861783862 0.6570926905 + 0.6980385184 0.6869369745 0.6578884721 + 0.6987496018 0.6876956224 0.6586841941 + 0.6994606853 0.6884542108 0.6594799757 + 0.7001718283 0.6892127991 0.6602758169 + 0.7008829117 0.6899713874 0.6610714793 + 0.7015895844 0.6907256246 0.6618655920 + 0.7022960782 0.6914795041 0.6626598239 + 0.7030025125 0.6922335029 0.6634538770 + 0.7037090063 0.6929875016 0.6642479897 + 0.7044153810 0.6937413812 0.6650421023 + 0.7051218152 0.6944953799 0.6658362150 + 0.7058250904 0.6952432990 0.6666283011 + 0.7065216899 0.6959791780 0.6674168706 + 0.7072182894 0.6967151165 0.6682054996 + 0.7079148889 0.6974509954 0.6689941287 + 0.7086114287 0.6981868744 0.6697826982 + 0.7093080282 0.6989226937 0.6705713272 + 0.7100046277 0.6996585727 0.6713598967 + 0.7106981277 0.7003877759 0.6721469760 + 0.7113897204 0.7011129260 0.6729333997 + 0.7120811939 0.7018380165 0.6737198234 + 0.7127727866 0.7025631070 0.6745061278 + 0.7134643793 0.7032880783 0.6752924919 + 0.7141559720 0.7040132284 0.6760789156 + 0.7148475051 0.7047383189 0.6768652201 + 0.7155426741 0.7054607272 0.6776456833 + 0.7162386775 0.7061824799 0.6784251928 + 0.7169346809 0.7069042921 0.6792047024 + 0.7176308036 0.7076261044 0.6799842715 + 0.7183268070 0.7083479166 0.6807637811 + 0.7190228105 0.7090697289 0.6815432906 + 0.7197188139 0.7097914815 0.6823228002 + 0.7204080224 0.7105045915 0.6830921769 + 0.7210965157 0.7112171054 0.6838611960 + 0.7217851281 0.7119296193 0.6846302748 + 0.7224736214 0.7126420140 0.6853992939 + 0.7231621742 0.7133545280 0.6861683130 + 0.7238507271 0.7140669823 0.6869373918 + 0.7245392799 0.7147794962 0.6877064109 + 0.7252277136 0.7154844999 0.6884679794 + 0.7259160280 0.7161890268 0.6892294884 + 0.7266044021 0.7168934941 0.6899909973 + 0.7272927165 0.7175980806 0.6907523870 + 0.7279810905 0.7183026075 0.6915138960 + 0.7286694050 0.7190070748 0.6922754049 + 0.7293577790 0.7197117209 0.6930367947 + 0.7300446033 0.7204123139 0.6937997937 + 0.7307311893 0.7211123109 0.6945629120 + 0.7314177752 0.7218121886 0.6953259706 + 0.7321043015 0.7225121856 0.6960890889 + 0.7327908874 0.7232121825 0.6968522072 + 0.7334774733 0.7239121795 0.6976153255 + 0.7341641188 0.7246121764 0.6983783841 + 0.7348474860 0.7253112793 0.6991379261 + 0.7355294824 0.7260100842 0.6998959780 + 0.7362114787 0.7267090082 0.7006539702 + 0.7368934155 0.7274078131 0.7014120817 + 0.7375754118 0.7281066179 0.7021701932 + 0.7382574081 0.7288054228 0.7029281855 + 0.7389392853 0.7295042276 0.7036862969 + 0.7396183014 0.7302008867 0.7044391036 + 0.7402927279 0.7308946252 0.7051851749 + 0.7409670949 0.7315883040 0.7059314251 + 0.7416415811 0.7322819829 0.7066774964 + 0.7423160076 0.7329757214 0.7074236870 + 0.7429903746 0.7336694002 0.7081698179 + 0.7436649203 0.7343631983 0.7089160085 + 0.7443389893 0.7350566983 0.7096619010 + 0.7450042963 0.7357468009 0.7104052901 + 0.7456694841 0.7364367843 0.7111486793 + 0.7463346720 0.7371268868 0.7118921280 + 0.7469999790 0.7378168702 0.7126353979 + 0.7476652265 0.7385069728 0.7133787870 + 0.7483304739 0.7391970158 0.7141221762 + 0.7489957213 0.7398871183 0.7148655057 + 0.7496609092 0.7405748963 0.7156080008 + 0.7503259182 0.7412611246 0.7163497806 + 0.7509909868 0.7419472933 0.7170916200 + 0.7516561151 0.7426335216 0.7178335190 + 0.7523211241 0.7433196902 0.7185752988 + 0.7529861927 0.7440059185 0.7193170786 + 0.7536513209 0.7446920872 0.7200589180 + 0.7543162704 0.7453783154 0.7208005786 + 0.7549796104 0.7460603714 0.7215341926 + 0.7556427717 0.7467426062 0.7222678065 + 0.7563059926 0.7474247217 0.7230014205 + 0.7569692731 0.7481067777 0.7237349749 + 0.7576324940 0.7487888932 0.7244685888 + 0.7582957149 0.7494711280 0.7252022028 + 0.7589588761 0.7501531839 0.7259358168 + 0.7596207261 0.7508332729 0.7266669273 + 0.7602791786 0.7515090108 0.7273933887 + 0.7609376907 0.7521848083 0.7281197906 + 0.7615962029 0.7528604865 0.7288463116 + 0.7622547150 0.7535362244 0.7295727134 + 0.7629132271 0.7542120218 0.7302991152 + 0.7635716796 0.7548877001 0.7310255766 + 0.7642301917 0.7555633783 0.7317519784 + 0.7648857832 0.7562360168 0.7324793935 + 0.7655386925 0.7569059134 0.7332075834 + 0.7661917210 0.7575758100 0.7339357734 + 0.7668445706 0.7582457066 0.7346640229 + 0.7674975991 0.7589156032 0.7353920937 + 0.7681505084 0.7595854998 0.7361202836 + 0.7688034773 0.7602553964 0.7368484735 + 0.7694563866 0.7609252930 0.7375766039 + 0.7701069713 0.7615932822 0.7383013964 + 0.7707563043 0.7622603774 0.7390245795 + 0.7714055777 0.7629274726 0.7397478223 + 0.7720549107 0.7635946274 0.7404710054 + 0.7727041841 0.7642617226 0.7411941886 + 0.7733533978 0.7649288177 0.7419173717 + 0.7740026712 0.7655959129 0.7426406145 + 0.7746520042 0.7662630081 0.7433637977 + 0.7752993703 0.7669281960 0.7440791726 + 0.7759457231 0.7675923109 0.7447909713 + 0.7765920162 0.7682564259 0.7455028296 + 0.7772383094 0.7689204812 0.7462146282 + 0.7778846025 0.7695845962 0.7469264269 + 0.7785308957 0.7702487111 0.7476382256 + 0.7791771889 0.7709128261 0.7483499050 + 0.7798236012 0.7715768814 0.7490617037 + 0.7804623246 0.7722384930 0.7497718930 + 0.7810946703 0.7728980184 0.7504810095 + 0.7817270756 0.7735574841 0.7511901259 + 0.7823594213 0.7742168903 0.7518991232 + 0.7829918265 0.7748764157 0.7526081800 + 0.7836241722 0.7755358815 0.7533171773 + 0.7842565775 0.7761954069 0.7540262938 + 0.7848889828 0.7768548727 0.7547354102 + 0.7855191231 0.7775127292 0.7554432154 + 0.7861444950 0.7781673074 0.7561488748 + 0.7867699265 0.7788218856 0.7568545938 + 0.7873954177 0.7794765830 0.7575603127 + 0.7880207896 0.7801312208 0.7582659721 + 0.7886462212 0.7807857990 0.7589715719 + 0.7892715931 0.7814403772 0.7596772909 + 0.7898970842 0.7820950150 0.7603830099 + 0.7905223966 0.7827494740 0.7610880733 + 0.7911401987 0.7833991051 0.7617810965 + 0.7917578816 0.7840486765 0.7624740005 + 0.7923756838 0.7846983075 0.7631670237 + 0.7929934859 0.7853478789 0.7638599873 + 0.7936112285 0.7859973907 0.7645528913 + 0.7942289710 0.7866470218 0.7652459145 + 0.7948467135 0.7872965932 0.7659388185 + 0.7954645157 0.7879462242 0.7666317821 + 0.7960770130 0.7885926962 0.7673208714 + 0.7966856956 0.7892370224 0.7680076957 + 0.7972943783 0.7898812890 0.7686944008 + 0.7979031205 0.7905256152 0.7693811059 + 0.7985118032 0.7911698818 0.7700678110 + 0.7991204858 0.7918142080 0.7707545757 + 0.7997291088 0.7924584746 0.7714412808 + 0.8003377914 0.7931028008 0.7721279860 + 0.8009464741 0.7937468290 0.7728148103 + 0.8015543222 0.7943841815 0.7735018730 + 0.8021621108 0.7950215936 0.7741889954 + 0.8027698994 0.7956590056 0.7748761773 + 0.8033776879 0.7962964177 0.7755632997 + 0.8039855957 0.7969338298 0.7762504816 + 0.8045933843 0.7975711823 0.7769376040 + 0.8052011728 0.7982085943 0.7776247859 + 0.8058090210 0.7988460064 0.7783119082 + 0.8064159751 0.7994800806 0.7789977193 + 0.8070214987 0.8001086712 0.7796815038 + 0.8076270223 0.8007372022 0.7803652883 + 0.8082324862 0.8013656735 0.7810490131 + 0.8088380098 0.8019942045 0.7817327976 + 0.8094434738 0.8026227951 0.7824165225 + 0.8100489974 0.8032513261 0.7831003070 + 0.8106545210 0.8038797975 0.7837840915 + 0.8112599850 0.8045083284 0.7844678164 + 0.8118627071 0.8051316142 0.7851473093 + 0.8124632239 0.8057510257 0.7858238816 + 0.8130636811 0.8063703775 0.7865005732 + 0.8136641979 0.8069897890 0.7871773243 + 0.8142647147 0.8076092005 0.7878538966 + 0.8148651719 0.8082286119 0.7885305882 + 0.8154656887 0.8088480234 0.7892072201 + 0.8160662055 0.8094673753 0.7898839116 + 0.8166667223 0.8100867867 0.7905604839 + 0.8172659874 0.8107038736 0.7912366986 + 0.8178647161 0.8113198876 0.7919127941 + 0.8184633851 0.8119359016 0.7925887704 + 0.8190621138 0.8125519156 0.7932648063 + 0.8196607828 0.8131679296 0.7939407825 + 0.8202595115 0.8137838840 0.7946168184 + 0.8208581805 0.8143998981 0.7952927947 + 0.8214569092 0.8150159121 0.7959687710 + 0.8220555782 0.8156319261 0.7966448069 + 0.8226491213 0.8162443042 0.7973200083 + 0.8232396245 0.8168547153 0.7979946733 + 0.8238301873 0.8174651861 0.7986695170 + 0.8244208097 0.8180755973 0.7993443012 + 0.8250113726 0.8186861277 0.8000190258 + 0.8256019950 0.8192964792 0.8006938100 + 0.8261926174 0.8199068904 0.8013685942 + 0.8267831802 0.8205174208 0.8020433187 + 0.8273738027 0.8211277723 0.8027181029 + 0.8279619217 0.8217353821 0.8033875227 + 0.8285475969 0.8223400116 0.8040519953 + 0.8291332126 0.8229447007 0.8047165871 + 0.8297188878 0.8235492706 0.8053811789 + 0.8303046227 0.8241540194 0.8060457110 + 0.8308901787 0.8247585893 0.8067103028 + 0.8314759135 0.8253632784 0.8073748946 + 0.8320615888 0.8259679079 0.8080394864 + 0.8326472044 0.8265725970 0.8087040186 + 0.8332327008 0.8271760941 0.8093675971 + 0.8338174224 0.8277755976 0.8100281954 + 0.8344022036 0.8283752203 0.8106889129 + 0.8349869251 0.8289747834 0.8113495111 + 0.8355717063 0.8295742869 0.8120101094 + 0.8361564279 0.8301739097 0.8126708269 + 0.8367410898 0.8307734132 0.8133314252 + 0.8373258710 0.8313729763 0.8139920831 + 0.8379105926 0.8319725990 0.8146526814 + 0.8384953737 0.8325721025 0.8153132796 + 0.8390772939 0.8331714272 0.8159744740 + 0.8396586180 0.8337705731 0.8166357279 + 0.8402400017 0.8343697786 0.8172969222 + 0.8408213258 0.8349689245 0.8179581165 + 0.8414027095 0.8355680704 0.8186193109 + 0.8419839740 0.8361672759 0.8192806244 + 0.8425654173 0.8367664814 0.8199418187 + 0.8431466818 0.8373656869 0.8206030130 + 0.8437281251 0.8379648924 0.8212642074 + 0.8443076015 0.8385624290 0.8219218254 + 0.8448830247 0.8391563296 0.8225721121 + 0.8454583883 0.8397501707 0.8232223988 + 0.8460338116 0.8403440118 0.8238726258 + 0.8466091752 0.8409379125 0.8245229125 + 0.8471845984 0.8415316939 0.8251731992 + 0.8477599025 0.8421255946 0.8258234859 + 0.8483353257 0.8427193761 0.8264737129 + 0.8489106894 0.8433132768 0.8271239996 + 0.8494861126 0.8439071178 0.8277742863 + 0.8500558138 0.8444991112 0.8284201026 + 0.8506222963 0.8450899720 0.8290638924 + 0.8511888981 0.8456808925 0.8297076821 + 0.8517553806 0.8462718129 0.8303514719 + 0.8523219228 0.8468626738 0.8309952021 + 0.8528885245 0.8474537134 0.8316389918 + 0.8534550071 0.8480445743 0.8322827816 + 0.8540216088 0.8486354947 0.8329265118 + 0.8545880914 0.8492264152 0.8335703015 + 0.8551546931 0.8498172760 0.8342140913 + 0.8557175994 0.8504027724 0.8348590136 + 0.8562799096 0.8509873748 0.8355041742 + 0.8568422794 0.8515719771 0.8361492753 + 0.8574045897 0.8521565795 0.8367943764 + 0.8579670191 0.8527411819 0.8374394774 + 0.8585293293 0.8533257842 0.8380845785 + 0.8590915799 0.8539103866 0.8387296796 + 0.8596540093 0.8544949889 0.8393748999 + 0.8602163196 0.8550797105 0.8400200009 + 0.8607786894 0.8556643128 0.8406651020 + 0.8613408804 0.8562449217 0.8413107991 + 0.8619030714 0.8568252921 0.8419564962 + 0.8624653816 0.8574056029 0.8426023126 + 0.8630275726 0.8579859734 0.8432480097 + 0.8635898232 0.8585664034 0.8438937068 + 0.8641520739 0.8591467738 0.8445394039 + 0.8647143245 0.8597272038 0.8451852202 + 0.8652765155 0.8603075743 0.8458309174 + 0.8658387065 0.8608880043 0.8464766145 + 0.8664010167 0.8614683747 0.8471223116 + 0.8669610023 0.8620395064 0.8477607965 + 0.8675208092 0.8626096249 0.8483986259 + 0.8680804968 0.8631796241 0.8490363955 + 0.8686403036 0.8637496829 0.8496742249 + 0.8691999912 0.8643196821 0.8503119946 + 0.8697597980 0.8648898005 0.8509498835 + 0.8703196049 0.8654597998 0.8515877128 + 0.8708792925 0.8660299182 0.8522254825 + 0.8714390993 0.8665999174 0.8528633118 + 0.8719987869 0.8671699762 0.8535010815 + 0.8725550175 0.8677337766 0.8541374803 + 0.8731096983 0.8682951927 0.8547734022 + 0.8736643195 0.8688564897 0.8554093242 + 0.8742190003 0.8694179058 0.8560451865 + 0.8747736216 0.8699792027 0.8566811085 + 0.8753283024 0.8705404997 0.8573169708 + 0.8758829236 0.8711019158 0.8579528928 + 0.8764376044 0.8716632128 0.8585888147 + 0.8769922256 0.8722246289 0.8592246175 + 0.8775469065 0.8727859259 0.8598604798 + 0.8781003952 0.8733474016 0.8604974151 + 0.8786519766 0.8739091754 0.8611357212 + 0.8792036176 0.8744710088 0.8617740870 + 0.8797551990 0.8750327826 0.8624123931 + 0.8803067803 0.8755946755 0.8630506992 + 0.8808584213 0.8761565089 0.8636891246 + 0.8814098835 0.8767182827 0.8643273711 + 0.8819615245 0.8772801161 0.8649656773 + 0.8825131059 0.8778418899 0.8656041026 + 0.8830646873 0.8784037232 0.8662424088 + 0.8836163282 0.8789654970 0.8668807149 + 0.8841652870 0.8795219064 0.8675110936 + 0.8847140074 0.8800777793 0.8681409955 + 0.8852627277 0.8806337714 0.8687707782 + 0.8858113885 0.8811897039 0.8694006205 + 0.8863601089 0.8817455769 0.8700305223 + 0.8869088292 0.8823016286 0.8706603050 + 0.8874574900 0.8828575015 0.8712900877 + 0.8880062103 0.8834133744 0.8719198704 + 0.8885548711 0.8839693069 0.8725497723 + 0.8891035914 0.8845252991 0.8731796145 + 0.8896498084 0.8850799799 0.8738080263 + 0.8901898265 0.8856320977 0.8744335175 + 0.8907297850 0.8861840963 0.8750590086 + 0.8912699223 0.8867360950 0.8756844997 + 0.8918098807 0.8872882128 0.8763099909 + 0.8923500180 0.8878402114 0.8769354820 + 0.8928899765 0.8883923292 0.8775609732 + 0.8934299946 0.8889443278 0.8781865239 + 0.8939700723 0.8894963861 0.8788120151 + 0.8945100904 0.8900483847 0.8794375062 + 0.8950502276 0.8906005025 0.8800629973 + 0.8955878019 0.8911523819 0.8806902766 + 0.8961235285 0.8917043209 0.8813189268 + 0.8966590762 0.8922562003 0.8819475174 + 0.8971948028 0.8928080201 0.8825762272 + 0.8977304101 0.8933598995 0.8832048178 + 0.8982660770 0.8939117789 0.8838335276 + 0.8988016844 0.8944637179 0.8844621181 + 0.8993372917 0.8950155973 0.8850907087 + 0.8998730183 0.8955674171 0.8857194185 + 0.9004086256 0.8961192966 0.8863480091 + 0.9009442925 0.8966711760 0.8869767189 + 0.9014744759 0.8972206712 0.8876035810 + 0.9020017982 0.8977689147 0.8882297873 + 0.9025291800 0.8983170986 0.8888558745 + 0.9030565023 0.8988652825 0.8894820213 + 0.9035838246 0.8994135261 0.8901082277 + 0.9041110873 0.8999617100 0.8907343149 + 0.9046384096 0.9005097747 0.8913604021 + 0.9051656723 0.9010580182 0.8919866085 + 0.9056929946 0.9016062021 0.8926126957 + 0.9062203169 0.9021543860 0.8932387829 + 0.9067475796 0.9027026296 0.8938649893 + 0.9072715044 0.9032499790 0.8944861889 + 0.9077931046 0.9037966728 0.8951045275 + 0.9083147049 0.9043434858 0.8957228065 + 0.9088363051 0.9048901796 0.8963410854 + 0.9093579054 0.9054369926 0.8969594240 + 0.9098795056 0.9059836864 0.8975777030 + 0.9104011059 0.9065304995 0.8981959224 + 0.9109227061 0.9070771933 0.8988142014 + 0.9114443064 0.9076240063 0.8994324803 + 0.9119659066 0.9081707001 0.9000508189 + 0.9124875069 0.9087175131 0.9006690979 + 0.9130079150 0.9092611074 0.9012864828 + 0.9135265946 0.9098002911 0.9019027948 + 0.9140452743 0.9103394747 0.9025191069 + 0.9145638943 0.9108787179 0.9031354189 + 0.9150825739 0.9114179015 0.9037516713 + 0.9156013131 0.9119570851 0.9043679833 + 0.9161199927 0.9124963284 0.9049841762 + 0.9166386724 0.9130355120 0.9056004882 + 0.9171572924 0.9135746956 0.9062168002 + 0.9176759720 0.9141138792 0.9068331122 + 0.9181947112 0.9146531224 0.9074494243 + 0.9187132120 0.9151920080 0.9080653191 + 0.9192286134 0.9157255292 0.9086763859 + 0.9197440147 0.9162589908 0.9092875123 + 0.9202594161 0.9167925715 0.9098985791 + 0.9207748175 0.9173260927 0.9105097055 + 0.9212902188 0.9178596735 0.9111207724 + 0.9218056202 0.9183931947 0.9117318988 + 0.9223210216 0.9189267159 0.9123430252 + 0.9228364229 0.9194602966 0.9129540920 + 0.9233518243 0.9199938178 0.9135652184 + 0.9238672256 0.9205272794 0.9141762853 + 0.9243826270 0.9210609198 0.9147874117 + 0.9248952866 0.9215934277 0.9153928161 + 0.9254056215 0.9221249819 0.9159939289 + 0.9259160161 0.9226565957 0.9165949821 + 0.9264264107 0.9231882095 0.9171959758 + 0.9269366860 0.9237198830 0.9177970886 + 0.9274470806 0.9242514968 0.9183982015 + 0.9279574752 0.9247831106 0.9189993143 + 0.9284678102 0.9253147840 0.9196004272 + 0.9289782047 0.9258463979 0.9202014208 + 0.9294885993 0.9263780117 0.9208024740 + 0.9299988747 0.9269096255 0.9214035869 + 0.9305093288 0.9274412990 0.9220046997 + 0.9310135245 0.9279668927 0.9225972295 + 0.9315168858 0.9284918904 0.9231889248 + 0.9320203066 0.9290168881 0.9237805009 + 0.9325237870 0.9295418262 0.9243721962 + 0.9330272079 0.9300668240 0.9249637723 + 0.9335306287 0.9305917025 0.9255555272 + 0.9340341091 0.9311167002 0.9261471033 + 0.9345374703 0.9316416979 0.9267387986 + 0.9350408912 0.9321665764 0.9273303747 + 0.9355443120 0.9326915741 0.9279221296 + 0.9360477924 0.9332165718 0.9285137057 + 0.9365504980 0.9337409139 0.9291048050 + 0.9370446801 0.9342573285 0.9296892881 + 0.9375388026 0.9347736835 0.9302738905 + 0.9380329847 0.9352902174 0.9308584929 + 0.9385271072 0.9358065724 0.9314429760 + 0.9390212893 0.9363229871 0.9320275784 + 0.9395154119 0.9368394017 0.9326121807 + 0.9400095940 0.9373558760 0.9331967235 + 0.9405037165 0.9378722906 0.9337813258 + 0.9409978986 0.9383887053 0.9343659282 + 0.9414920211 0.9389051199 0.9349504113 + 0.9419862032 0.9394215941 0.9355350137 + 0.9424793124 0.9399371743 0.9361184239 + 0.9429621100 0.9404459000 0.9366925955 + 0.9434450269 0.9409546256 0.9372667074 + 0.9439278841 0.9414631724 0.9378408194 + 0.9444106817 0.9419718981 0.9384148717 + 0.9448935986 0.9424806237 0.9389889836 + 0.9453763962 0.9429891706 0.9395630956 + 0.9458593130 0.9434978962 0.9401373267 + 0.9463421106 0.9440066218 0.9407113791 + 0.9468250275 0.9445152283 0.9412854910 + 0.9473078847 0.9450238943 0.9418596029 + 0.9477906823 0.9455326200 0.9424337149 + 0.9482735991 0.9460412264 0.9430078268 + 0.9487515092 0.9465460181 0.9435728788 + 0.9492291808 0.9470505714 0.9441375732 + 0.9497069120 0.9475551844 0.9447023273 + 0.9501845837 0.9480597973 0.9452670813 + 0.9506623149 0.9485644102 0.9458317757 + 0.9511399865 0.9490690231 0.9463965297 + 0.9516175985 0.9495735168 0.9469612241 + 0.9520953298 0.9500781298 0.9475259781 + 0.9525730014 0.9505826831 0.9480906725 + 0.9530506730 0.9510872960 0.9486554265 + 0.9535284042 0.9515919089 0.9492201209 + 0.9540060759 0.9520965219 0.9497848749 + 0.9544798732 0.9525997043 0.9503433108 + 0.9549517035 0.9531021118 0.9508985281 + 0.9554234743 0.9536045194 0.9514538050 + 0.9558951855 0.9541069269 0.9520090222 + 0.9563670158 0.9546092749 0.9525641799 + 0.9568387270 0.9551116824 0.9531193972 + 0.9573104978 0.9556140900 0.9536746740 + 0.9577823281 0.9561164975 0.9542298913 + 0.9582539797 0.9566189051 0.9547851086 + 0.9587258101 0.9571213722 0.9553403258 + 0.9591975212 0.9576237798 0.9558954835 + 0.9596692920 0.9581261873 0.9564508200 + 0.9601396918 0.9586272836 0.9570031166 + 0.9606035948 0.9591223001 0.9575427771 + 0.9610674977 0.9596173167 0.9580823779 + 0.9615314007 0.9601122737 0.9586220980 + 0.9619953036 0.9606072903 0.9591618180 + 0.9624592066 0.9611024261 0.9597014189 + 0.9629231095 0.9615973830 0.9602410793 + 0.9633870125 0.9620923996 0.9607807994 + 0.9638509154 0.9625874162 0.9613204002 + 0.9643148184 0.9630824924 0.9618601203 + 0.9647787809 0.9635775089 0.9623997808 + 0.9652426839 0.9640725255 0.9629393816 + 0.9657065868 0.9645674825 0.9634791017 + 0.9661654830 0.9650583267 0.9640104771 + 0.9666200876 0.9655454755 0.9645349979 + 0.9670745730 0.9660326242 0.9650595188 + 0.9675291777 0.9665197730 0.9655839801 + 0.9679837823 0.9670069218 0.9661085010 + 0.9684383869 0.9674940705 0.9666330218 + 0.9688928723 0.9679812193 0.9671574831 + 0.9693474770 0.9684684277 0.9676818848 + 0.9698020816 0.9689555764 0.9682064056 + 0.9702566862 0.9694427252 0.9687309265 + 0.9707111716 0.9699298739 0.9692553878 + 0.9711657763 0.9704170227 0.9697799087 + 0.9716203809 0.9709041715 0.9703044295 + 0.9720690846 0.9713829756 0.9708178043 + 0.9725155234 0.9718586206 0.9713271856 + 0.9729619026 0.9723342061 0.9718365073 + 0.9734084010 0.9728097916 0.9723458290 + 0.9738547802 0.9732853770 0.9728550911 + 0.9743012190 0.9737610221 0.9733644724 + 0.9747477174 0.9742366076 0.9738737941 + 0.9751940966 0.9747121930 0.9743831158 + 0.9756405950 0.9751877785 0.9748924971 + 0.9760869741 0.9756634235 0.9754018188 + 0.9765334129 0.9761390090 0.9759110808 + 0.9769799113 0.9766145945 0.9764205217 + 0.9774262905 0.9770901799 0.9769297838 + 0.9778676033 0.9775533080 0.9774206877 + 0.9783070087 0.9780119061 0.9779049754 + 0.9787464142 0.9784705043 0.9783893824 + 0.9791858196 0.9789291024 0.9788737893 + 0.9796252251 0.9793877006 0.9793581963 + 0.9800645709 0.9798462987 0.9798424840 + 0.9805039763 0.9803048968 0.9803268909 + 0.9809433818 0.9807634950 0.9808112979 + 0.9813829064 0.9812219739 0.9812957048 + 0.9818223119 0.9816805720 0.9817801118 + 0.9822617173 0.9821392298 0.9822643995 + 0.9827011228 0.9825978279 0.9827488065 + 0.9831405282 0.9830564260 0.9832332134 + 0.9835739136 0.9835022092 0.9837002158 + 0.9840028286 0.9839385152 0.9841542840 + 0.9844316244 0.9843747020 0.9846084714 + 0.9848604798 0.9848110080 0.9850625992 + 0.9852893949 0.9852473140 0.9855167866 + 0.9857181907 0.9856835008 0.9859709144 + 0.9861471057 0.9861198068 0.9864251018 + 0.9865760207 0.9865561128 0.9868792295 + 0.9870048165 0.9869922996 0.9873334169 + 0.9874336720 0.9874286056 0.9877874851 + 0.9878625870 0.9878647923 0.9882416725 + 0.9882913828 0.9883010983 0.9886958003 + 0.9887202978 0.9887374043 0.9891499877 + 0.9891455173 0.9891687036 0.9895961881 + 0.9895583987 0.9895836115 0.9900164008 + 0.9899712801 0.9899985790 0.9904366136 + 0.9903842807 0.9904134870 0.9908568263 + 0.9907972217 0.9908285141 0.9912769794 + 0.9912101030 0.9912434220 0.9916970730 + 0.9916231036 0.9916582704 0.9921172857 + 0.9920359850 0.9920732975 0.9925374985 + 0.9924489260 0.9924882054 0.9929577112 + 0.9928618073 0.9929031134 0.9933779240 + 0.9932748079 0.9933180809 0.9937980771 + 0.9936876893 0.9937329888 0.9942182899 + 0.9941005707 0.9941480160 0.9946383834 + 0.9945135117 0.9945629239 0.9950585961 + 0.9949113131 0.9949585795 0.9954301715 + 0.9953026772 0.9953464270 0.9957817197 + 0.9956942201 0.9957342148 0.9961332083 + 0.9960855842 0.9961220026 0.9964848161 + 0.9964770079 0.9965097904 0.9968363047 + 0.9968684912 0.9968975782 0.9971877933 + 0.9972599149 0.9972854257 0.9975392818 + 0.9976513982 0.9976732135 0.9978908896 + 0.9980428219 0.9980610013 0.9982423782 + 0.9984341860 0.9984487891 0.9985939264 + 0.9988257289 0.9988365769 0.9989454150 + 0.9992170930 0.9992244244 0.9992970228 + 0.9996085763 0.9996122122 0.9996485114 + 1.0000000000 1.0000000000 1.0000000000 +} diff --git a/rpplugins/color_correction/resources/film_luts_raw/kodak_portra_100t.spi1d b/rpplugins/color_correction/resources/film_luts_raw/kodak_portra_100t.spi1d new file mode 100644 index 0000000..b71e38e --- /dev/null +++ b/rpplugins/color_correction/resources/film_luts_raw/kodak_portra_100t.spi1d @@ -0,0 +1,1030 @@ +Version 1 +From 0.0 1.0 +Length 1024 +Components 3 +{ + 0.0000000000 0.0000000000 0.0000000000 + 0.0078889886 0.0072905929 0.0057835742 + 0.0155280400 0.0142424498 0.0110800304 + 0.0223259609 0.0204148795 0.0157516599 + 0.0282847900 0.0258345399 0.0199356508 + 0.0338022411 0.0308287591 0.0238022301 + 0.0387409404 0.0354198888 0.0274327602 + 0.0434868000 0.0397184007 0.0308620799 + 0.0479348600 0.0437957905 0.0341565795 + 0.0521249995 0.0477067716 0.0373548716 + 0.0560929887 0.0514680110 0.0404086895 + 0.0599000603 0.0551049784 0.0433653891 + 0.0636395887 0.0585507713 0.0462335311 + 0.0673073381 0.0619252101 0.0490648411 + 0.0708674565 0.0652377531 0.0518452115 + 0.0742941722 0.0684634522 0.0545356311 + 0.0776154101 0.0715824589 0.0571359284 + 0.0808518305 0.0746066868 0.0596979707 + 0.0840119570 0.0775315836 0.0622345991 + 0.0870610103 0.0803711265 0.0647289529 + 0.0900357366 0.0831752867 0.0671606734 + 0.0929580331 0.0859571993 0.0695598572 + 0.0958346874 0.0887065008 0.0719215125 + 0.0986543819 0.0914179012 0.0742511526 + 0.1014280990 0.0940862000 0.0765401274 + 0.1041439995 0.0967277288 0.0788079128 + 0.1068262011 0.0993322283 0.0810511932 + 0.1094703972 0.1018816978 0.0832685530 + 0.1121027023 0.1043870971 0.0854593366 + 0.1147300974 0.1068421006 0.0876216292 + 0.1173269004 0.1092239022 0.0897513777 + 0.1198854968 0.1115904003 0.0918506086 + 0.1224000975 0.1139374003 0.0939252079 + 0.1248695031 0.1162879989 0.0959772170 + 0.1273149997 0.1186162010 0.0980132222 + 0.1297475994 0.1209222972 0.1000507995 + 0.1321358979 0.1232006028 0.1020739973 + 0.1344795972 0.1254397035 0.1040984020 + 0.1368041933 0.1276575029 0.1060978994 + 0.1391019970 0.1298466027 0.1080757976 + 0.1413698047 0.1320064962 0.1100341976 + 0.1435928941 0.1341473013 0.1119635031 + 0.1457892954 0.1362611055 0.1138700023 + 0.1479541063 0.1383730024 0.1157647967 + 0.1501048058 0.1404493004 0.1176467985 + 0.1522224993 0.1425213069 0.1195039973 + 0.1543388963 0.1445824057 0.1213504001 + 0.1564362943 0.1466197073 0.1231838018 + 0.1585174948 0.1486462057 0.1250088066 + 0.1605857015 0.1506392062 0.1268348992 + 0.1626347005 0.1526177973 0.1286439002 + 0.1646862030 0.1546075940 0.1304429024 + 0.1667335927 0.1565793008 0.1322406977 + 0.1687652022 0.1585436016 0.1340295970 + 0.1707780957 0.1604935974 0.1357980967 + 0.1727759987 0.1624072939 0.1375523061 + 0.1747658998 0.1643151045 0.1393052936 + 0.1767490953 0.1662092954 0.1410588026 + 0.1787372977 0.1680783033 0.1427990049 + 0.1807080060 0.1699371934 0.1445256025 + 0.1826650947 0.1718004048 0.1462455988 + 0.1846058965 0.1736536026 0.1479606032 + 0.1865195930 0.1754879057 0.1496645957 + 0.1884177029 0.1773201972 0.1513437033 + 0.1903073043 0.1791377962 0.1530140042 + 0.1921796948 0.1809280068 0.1546792984 + 0.1940302998 0.1827086061 0.1563450992 + 0.1958549023 0.1844934970 0.1580031067 + 0.1976682991 0.1862594038 0.1596433967 + 0.1994695961 0.1880051941 0.1612734050 + 0.2012577057 0.1897480041 0.1628941000 + 0.2030259073 0.1914830059 0.1645098031 + 0.2047819048 0.1931872070 0.1661248058 + 0.2065176964 0.1948740035 0.1677244008 + 0.2082248926 0.1965582073 0.1693145037 + 0.2099235952 0.1982422024 0.1708988994 + 0.2116315067 0.1999278069 0.1724735051 + 0.2133346945 0.2015964985 0.1740391999 + 0.2150184065 0.2032589018 0.1755944937 + 0.2167019993 0.2049262971 0.1771457046 + 0.2183800042 0.2065898031 0.1786843985 + 0.2200523019 0.2082391977 0.1802140027 + 0.2217144072 0.2098809928 0.1817325056 + 0.2233763039 0.2115218937 0.1832381040 + 0.2250375003 0.2131509036 0.1847354025 + 0.2266878933 0.2147578001 0.1862273067 + 0.2283222973 0.2163494974 0.1877095997 + 0.2299540937 0.2179363966 0.1891891062 + 0.2315769047 0.2195288986 0.1906653941 + 0.2331923991 0.2211087048 0.1921359003 + 0.2347972989 0.2226725072 0.1936012954 + 0.2363962978 0.2242244929 0.1950621009 + 0.2379969060 0.2257725000 0.1965180039 + 0.2395913005 0.2273270935 0.1979725063 + 0.2411745936 0.2288744003 0.1994252056 + 0.2427513003 0.2304067016 0.2008765042 + 0.2443210930 0.2319256067 0.2023257017 + 0.2458810061 0.2334371954 0.2037705034 + 0.2474320978 0.2349530011 0.2052136958 + 0.2489770949 0.2364764959 0.2066580951 + 0.2505179048 0.2380003035 0.2081031054 + 0.2520565093 0.2395125926 0.2095465064 + 0.2535842061 0.2410165966 0.2109802067 + 0.2551011145 0.2425200939 0.2124101967 + 0.2566075027 0.2440229058 0.2138369977 + 0.2581019104 0.2455164939 0.2152577937 + 0.2595993876 0.2469965965 0.2166765928 + 0.2610979974 0.2484685034 0.2180949003 + 0.2625960112 0.2499337047 0.2195139974 + 0.2640933990 0.2513996959 0.2209234983 + 0.2655884027 0.2528609037 0.2223280966 + 0.2670783103 0.2543111145 0.2237278074 + 0.2685579062 0.2557500899 0.2251172066 + 0.2700324059 0.2571833134 0.2265006006 + 0.2715004086 0.2586081922 0.2278756052 + 0.2729619145 0.2600342035 0.2292470932 + 0.2744210064 0.2614606023 0.2306170017 + 0.2758783996 0.2628875077 0.2319861054 + 0.2773306072 0.2643063962 0.2333521992 + 0.2787795067 0.2657200098 0.2347161025 + 0.2802197933 0.2671194077 0.2360662967 + 0.2816554010 0.2685183883 0.2374131978 + 0.2830832005 0.2699165940 0.2387543023 + 0.2845051885 0.2713209987 0.2400884926 + 0.2859246135 0.2727270126 0.2414194047 + 0.2873364091 0.2741222978 0.2427445948 + 0.2887467146 0.2755121887 0.2440689951 + 0.2901543975 0.2768926919 0.2453920990 + 0.2915565968 0.2782715857 0.2467114031 + 0.2929557860 0.2796497047 0.2480283976 + 0.2943511903 0.2810314000 0.2493402064 + 0.2957446873 0.2824105918 0.2506507039 + 0.2971296012 0.2837719917 0.2519558966 + 0.2985079885 0.2851282954 0.2532579899 + 0.2998743057 0.2864750028 0.2545535862 + 0.3012337983 0.2878203988 0.2558461130 + 0.3025875092 0.2891646028 0.2571358085 + 0.3039326966 0.2905083001 0.2584241033 + 0.3052744865 0.2918517888 0.2597118020 + 0.3066090047 0.2931913137 0.2609947026 + 0.3079420924 0.2945300043 0.2622764111 + 0.3092617095 0.2958604097 0.2635529041 + 0.3105807900 0.2971901000 0.2648288012 + 0.3119010031 0.2985129058 0.2660990953 + 0.3132201135 0.2998352051 0.2673687041 + 0.3145304024 0.3011538088 0.2686296105 + 0.3158377111 0.3024721146 0.2698898911 + 0.3171265125 0.3037881851 0.2711451054 + 0.3184145093 0.3051016033 0.2723999918 + 0.3196972907 0.3063997030 0.2736532986 + 0.3209798932 0.3076966107 0.2749058902 + 0.3222613931 0.3089852929 0.2761533856 + 0.3235423863 0.3102742136 0.2774004936 + 0.3248170912 0.3115651011 0.2786423862 + 0.3260917962 0.3128559887 0.2798843086 + 0.3273518085 0.3141461015 0.2811206877 + 0.3286117911 0.3154362142 0.2823570967 + 0.3298718929 0.3167093098 0.2835853994 + 0.3311319947 0.3179805875 0.2848125100 + 0.3323861063 0.3192439079 0.2860355973 + 0.3336383998 0.3205048144 0.2872571945 + 0.3348825872 0.3217664957 0.2884761989 + 0.3361215889 0.3230285943 0.2896933854 + 0.3373571038 0.3242911100 0.2909066081 + 0.3385877907 0.3255540133 0.2921139002 + 0.3398196995 0.3268145919 0.2933216989 + 0.3410564065 0.3280658126 0.2945317924 + 0.3422931135 0.3293170929 0.2957417965 + 0.3435252011 0.3305566907 0.2969467938 + 0.3447571099 0.3317956924 0.2981514931 + 0.3459787965 0.3330340087 0.2993502021 + 0.3471955061 0.3342720866 0.3005459011 + 0.3484120071 0.3355073035 0.3017396927 + 0.3496277034 0.3367376029 0.3029299974 + 0.3508433104 0.3379676044 0.3041202128 + 0.3520529866 0.3391881883 0.3053084910 + 0.3532628119 0.3404087126 0.3064967096 + 0.3544704020 0.3416185081 0.3076831102 + 0.3556770086 0.3428226113 0.3088682890 + 0.3568829894 0.3440254033 0.3100539148 + 0.3580872118 0.3452241123 0.3112407029 + 0.3592914045 0.3464227021 0.3124274015 + 0.3604977131 0.3476234078 0.3136095107 + 0.3617044985 0.3488247097 0.3147901893 + 0.3629097939 0.3500243127 0.3159680068 + 0.3641118109 0.3512204885 0.3171392083 + 0.3653138876 0.3524166942 0.3183102906 + 0.3665078878 0.3536022007 0.3194763064 + 0.3677001894 0.3547854125 0.3206410110 + 0.3688907921 0.3559671938 0.3218050003 + 0.3700768948 0.3571453989 0.3229666948 + 0.3712630868 0.3583235145 0.3241283894 + 0.3724423051 0.3595018089 0.3252857924 + 0.3736186028 0.3606801927 0.3264412880 + 0.3747946024 0.3618564010 0.3275963068 + 0.3759672940 0.3630137146 0.3287459016 + 0.3771401048 0.3641709983 0.3298955858 + 0.3783135116 0.3653210104 0.3310425878 + 0.3794879019 0.3664624989 0.3321863115 + 0.3806622028 0.3676039875 0.3333300054 + 0.3818334043 0.3687413037 0.3344663978 + 0.3830037117 0.3698773980 0.3356004953 + 0.3841735125 0.3710137904 0.3367342949 + 0.3853363097 0.3721551001 0.3378620148 + 0.3864991069 0.3732962906 0.3389897943 + 0.3876604140 0.3744358122 0.3401161134 + 0.3888185024 0.3755710125 0.3412387073 + 0.3899765909 0.3767063022 0.3423613906 + 0.3911325037 0.3778327107 0.3434790969 + 0.3922863007 0.3789506853 0.3445914984 + 0.3934400976 0.3800686896 0.3457039893 + 0.3945881128 0.3811818957 0.3468174934 + 0.3957333863 0.3822929859 0.3479315042 + 0.3968786001 0.3834039867 0.3490453959 + 0.3980174065 0.3845176995 0.3501490057 + 0.3991548121 0.3856320083 0.3512499034 + 0.4002921879 0.3867461979 0.3523508012 + 0.4014247954 0.3878605962 0.3534472883 + 0.4025569856 0.3889749944 0.3545432985 + 0.4036892951 0.3900893927 0.3556393087 + 0.4048125148 0.3911888003 0.3567320108 + 0.4059354067 0.3922877014 0.3578243852 + 0.4070582986 0.3933865130 0.3589169085 + 0.4081676006 0.3944776952 0.3600068986 + 0.4092766047 0.3955687881 0.3610968888 + 0.4103856981 0.3966597915 0.3621867895 + 0.4114840925 0.3977529109 0.3632732928 + 0.4125820994 0.3988460898 0.3643594980 + 0.4136799872 0.3999392986 0.3654457033 + 0.4147689044 0.4010387957 0.3665322065 + 0.4158565998 0.4021390080 0.3676187098 + 0.4169442952 0.4032391906 0.3687050939 + 0.4180271924 0.4043292999 0.3697864115 + 0.4191086888 0.4054166079 0.3708660007 + 0.4201901853 0.4065037966 0.3719455004 + 0.4212687910 0.4075860977 0.3730236888 + 0.4223456979 0.4086655080 0.3741010129 + 0.4234224856 0.4097448885 0.3751783073 + 0.4244934916 0.4108251035 0.3762541115 + 0.4255565107 0.4119066000 0.3773277998 + 0.4266194999 0.4129880965 0.3784016073 + 0.4276801050 0.4140700102 0.3794747889 + 0.4287301898 0.4151534140 0.3805457950 + 0.4297803044 0.4162367880 0.3816167116 + 0.4308303893 0.4173201919 0.3826876879 + 0.4318735898 0.4183954000 0.3837552965 + 0.4329161942 0.4194698036 0.3848226070 + 0.4339587092 0.4205440879 0.3858897984 + 0.4349972010 0.4216128886 0.3869574070 + 0.4360328019 0.4226776063 0.3880251944 + 0.4370684922 0.4237422943 0.3890931010 + 0.4381031096 0.4248071015 0.3901597857 + 0.4391340017 0.4258719981 0.3912216127 + 0.4401648939 0.4269368947 0.3922834098 + 0.4411959052 0.4280017018 0.3933452070 + 0.4422194064 0.4290623963 0.3943997025 + 0.4432410896 0.4301218987 0.3954519928 + 0.4442627132 0.4311814904 0.3965043128 + 0.4452854097 0.4322386980 0.3975546062 + 0.4463103116 0.4332911074 0.3986003101 + 0.4473350942 0.4343433976 0.3996460140 + 0.4483599067 0.4353958070 0.4006916881 + 0.4493798018 0.4364373982 0.4017345905 + 0.4503985941 0.4374763966 0.4027766883 + 0.4514173865 0.4385155141 0.4038187861 + 0.4524323940 0.4395537078 0.4048602879 + 0.4534361959 0.4405891001 0.4059000015 + 0.4544399977 0.4416244924 0.4069396853 + 0.4554437995 0.4426599145 0.4079793990 + 0.4564459026 0.4436990917 0.4090223908 + 0.4574469030 0.4447405040 0.4100672901 + 0.4584479928 0.4457817972 0.4111123085 + 0.4594491124 0.4468230903 0.4121572077 + 0.4604510069 0.4478600025 0.4131881893 + 0.4614529908 0.4488969147 0.4142186940 + 0.4624550045 0.4499337971 0.4152492881 + 0.4634560049 0.4509662986 0.4162780941 + 0.4644544125 0.4519883096 0.4173018932 + 0.4654527009 0.4530102015 0.4183256924 + 0.4664511085 0.4540322125 0.4193494916 + 0.4674443901 0.4550513029 0.4203704000 + 0.4684332907 0.4560678899 0.4213885963 + 0.4694221020 0.4570845068 0.4224067032 + 0.4704109132 0.4581010938 0.4234248996 + 0.4714013934 0.4591206014 0.4244410992 + 0.4723925889 0.4601413012 0.4254566133 + 0.4733838141 0.4611620009 0.4264720976 + 0.4743750095 0.4621827006 0.4274876118 + 0.4753603935 0.4631980062 0.4285031855 + 0.4763449132 0.4642125070 0.4295187891 + 0.4773294032 0.4652270079 0.4305343926 + 0.4783138931 0.4662415087 0.4315499961 + 0.4792841971 0.4672405124 0.4325644970 + 0.4802536964 0.4682387114 0.4335789979 + 0.4812232852 0.4692369103 0.4345934987 + 0.4821928144 0.4702351093 0.4356079996 + 0.4831587970 0.4712263942 0.4366190135 + 0.4841246903 0.4722175002 0.4376297891 + 0.4850907028 0.4732086957 0.4386407137 + 0.4860565960 0.4741998911 0.4396516085 + 0.4870223999 0.4751932025 0.4406566024 + 0.4879881144 0.4761866033 0.4416612983 + 0.4889538884 0.4771799147 0.4426659942 + 0.4899196029 0.4781732857 0.4436706901 + 0.4908815026 0.4791612923 0.4446693063 + 0.4918429852 0.4801487923 0.4456669092 + 0.4928044081 0.4811362028 0.4466646016 + 0.4937658906 0.4821236134 0.4476622045 + 0.4947195053 0.4831021130 0.4486567080 + 0.4956707954 0.4840778112 0.4496499896 + 0.4966219962 0.4850535095 0.4506433010 + 0.4975732863 0.4860292077 0.4516366124 + 0.4985210896 0.4869993031 0.4526301026 + 0.4994663000 0.4879654050 0.4536238015 + 0.5004115105 0.4889315069 0.4546175897 + 0.5013567209 0.4898976088 0.4556112885 + 0.5022984147 0.4908634126 0.4566054046 + 0.5032333732 0.4918287992 0.4576002955 + 0.5041682720 0.4927941859 0.4585951865 + 0.5051032901 0.4937596023 0.4595901966 + 0.5060374737 0.4947249889 0.4605847895 + 0.5069562197 0.4956893921 0.4615682960 + 0.5078749061 0.4966539145 0.4625518024 + 0.5087934732 0.4976184070 0.4635351896 + 0.5097122192 0.4985828996 0.4645186961 + 0.5106272101 0.4995400012 0.4654968977 + 0.5115404725 0.5004938245 0.4664725959 + 0.5124536753 0.5014476180 0.4674482942 + 0.5133669972 0.5024012923 0.4684239030 + 0.5142818093 0.5033521056 0.4693973958 + 0.5152004957 0.5042945743 0.4703643918 + 0.5161191821 0.5052371025 0.4713312984 + 0.5170379281 0.5061795712 0.4722982943 + 0.5179566145 0.5071220994 0.4732652009 + 0.5188748837 0.5080627203 0.4742276073 + 0.5197929740 0.5090026855 0.4751887023 + 0.5207111835 0.5099428296 0.4761497974 + 0.5216293931 0.5108827949 0.4771108925 + 0.5225464106 0.5118234158 0.4780718088 + 0.5234599113 0.5127655268 0.4790318906 + 0.5243734121 0.5137075186 0.4799919128 + 0.5252867937 0.5146496296 0.4809519947 + 0.5262002945 0.5155916810 0.4819121063 + 0.5271133780 0.5165237784 0.4828720093 + 0.5280262232 0.5174506903 0.4838317931 + 0.5289388895 0.5183774829 0.4847916067 + 0.5298516750 0.5193043947 0.4857513011 + 0.5307645202 0.5202311873 0.4867111146 + 0.5316731930 0.5211473107 0.4876579940 + 0.5325819254 0.5220631957 0.4886044860 + 0.5334905982 0.5229790807 0.4895510077 + 0.5343992710 0.5238950253 0.4904974997 + 0.5353068709 0.5248103142 0.4914431870 + 0.5362116098 0.5257238150 0.4923861027 + 0.5371162891 0.5266373754 0.4933289886 + 0.5380210280 0.5275508761 0.4942719936 + 0.5389257073 0.5284643769 0.4952149093 + 0.5398265719 0.5293797851 0.4961544871 + 0.5407235026 0.5302973986 0.4970901012 + 0.5416203141 0.5312148929 0.4980256855 + 0.5425171256 0.5321325064 0.4989612997 + 0.5434139967 0.5330500007 0.4998969138 + 0.5443124175 0.5339617729 0.5008286834 + 0.5452117920 0.5348700881 0.5017580986 + 0.5461112261 0.5357784033 0.5026873946 + 0.5470106006 0.5366867185 0.5036168098 + 0.5479100943 0.5375949740 0.5045462251 + 0.5488089919 0.5384951830 0.5054730773 + 0.5497077107 0.5393918157 0.5063987970 + 0.5506064892 0.5402885079 0.5073245764 + 0.5515052080 0.5411852002 0.5082504153 + 0.5524039268 0.5420818925 0.5091760755 + 0.5533022285 0.5429762006 0.5100972056 + 0.5542001724 0.5438696742 0.5110161901 + 0.5550982952 0.5447632074 0.5119352937 + 0.5559964180 0.5456566811 0.5128542781 + 0.5568944216 0.5465502143 0.5137733221 + 0.5577896833 0.5474457145 0.5146881938 + 0.5586835146 0.5483422875 0.5156006813 + 0.5595772862 0.5492389202 0.5165132880 + 0.5604711175 0.5501356125 0.5174257755 + 0.5613648891 0.5510321856 0.5183383822 + 0.5622547269 0.5519235730 0.5192475915 + 0.5631409883 0.5528106093 0.5201537013 + 0.5640273094 0.5536975861 0.5210598111 + 0.5649135709 0.5545846224 0.5219659209 + 0.5657997727 0.5554715991 0.5228719711 + 0.5666835904 0.5563544035 0.5237771869 + 0.5675624013 0.5572292209 0.5246803164 + 0.5684412718 0.5581040978 0.5255835056 + 0.5693200827 0.5589789152 0.5264865756 + 0.5701988935 0.5598536730 0.5273898244 + 0.5710769296 0.5607281923 0.5282927155 + 0.5719450116 0.5615991950 0.5291919112 + 0.5728130937 0.5624700785 0.5300911069 + 0.5736811757 0.5633410215 0.5309904218 + 0.5745493174 0.5642119050 0.5318896174 + 0.5754173994 0.5650827885 0.5327888131 + 0.5762851238 0.5659552813 0.5336858034 + 0.5771527290 0.5668284297 0.5345818996 + 0.5780202746 0.5677015185 0.5354781151 + 0.5788878798 0.5685747266 0.5363742113 + 0.5797554851 0.5694478154 0.5372703075 + 0.5806217790 0.5703194737 0.5381652713 + 0.5814853907 0.5711885095 0.5390577912 + 0.5823488832 0.5720576048 0.5399503112 + 0.5832124949 0.5729265809 0.5408427119 + 0.5840761065 0.5737956762 0.5417351723 + 0.5849397182 0.5746647120 0.5426276922 + 0.5858016014 0.5755252838 0.5435200930 + 0.5866631269 0.5763844252 0.5444124937 + 0.5875247121 0.5772435069 0.5453047752 + 0.5883861780 0.5781025290 0.5461971760 + 0.5892478228 0.5789616108 0.5470895171 + 0.5901088119 0.5798196197 0.5479819179 + 0.5909687281 0.5806747079 0.5488741994 + 0.5918287039 0.5815299153 0.5497664213 + 0.5926886201 0.5823850036 0.5506587029 + 0.5935484767 0.5832400918 0.5515509844 + 0.5944083929 0.5840952992 0.5524433255 + 0.5952606797 0.5849506259 0.5533313751 + 0.5961092114 0.5858058929 0.5542173982 + 0.5969576836 0.5866612196 0.5551033020 + 0.5978062153 0.5875164866 0.5559893250 + 0.5986546874 0.5883718729 0.5568752289 + 0.5995032191 0.5892271996 0.5577610731 + 0.6003429294 0.5900741816 0.5586416721 + 0.6011822820 0.5909208059 0.5595219135 + 0.6020215750 0.5917673707 0.5604020953 + 0.6028609872 0.5926139951 0.5612822771 + 0.6037002802 0.5934606194 0.5621625185 + 0.6045382023 0.5943056941 0.5630425215 + 0.6053689718 0.5951434970 0.5639213920 + 0.6061998010 0.5959812999 0.5648003221 + 0.6070305705 0.5968191028 0.5656793118 + 0.6078615189 0.5976567864 0.5665581822 + 0.6086922884 0.5984945893 0.5674371123 + 0.6095213890 0.5993313789 0.5683159828 + 0.6103464961 0.6001660228 0.5691947937 + 0.6111717224 0.6010006070 0.5700736046 + 0.6119968891 0.6018350720 0.5709522963 + 0.6128221154 0.6026697159 0.5718311071 + 0.6136472821 0.6035043001 0.5727099180 + 0.6144716144 0.6043398976 0.5735872984 + 0.6152943969 0.6051772237 0.5744621754 + 0.6161171794 0.6060143709 0.5753371716 + 0.6169400215 0.6068516970 0.5762121081 + 0.6177628040 0.6076890230 0.5770869851 + 0.6185857058 0.6085262895 0.5779619813 + 0.6194078922 0.6093611121 0.5788385272 + 0.6202291846 0.6101909280 0.5797184110 + 0.6210504770 0.6110206842 0.5805981755 + 0.6218718290 0.6118505001 0.5814781189 + 0.6226930022 0.6126803756 0.5823580027 + 0.6235142946 0.6135101914 0.5832378268 + 0.6243357062 0.6143385172 0.5841162801 + 0.6251572967 0.6151615977 0.5849894285 + 0.6259788871 0.6159847975 0.5858625770 + 0.6268004775 0.6168079972 0.5867357254 + 0.6276221275 0.6176310778 0.5876088738 + 0.6284437180 0.6184542775 0.5884820223 + 0.6292651892 0.6192772985 0.5893549919 + 0.6300833821 0.6200963259 0.5902221799 + 0.6309016943 0.6209151745 0.5910894275 + 0.6317198873 0.6217342019 0.5919566154 + 0.6325381994 0.6225532293 0.5928236842 + 0.6333565116 0.6233721972 0.5936908722 + 0.6341747046 0.6241912246 0.5945581198 + 0.6349883080 0.6250126958 0.5954239964 + 0.6358004212 0.6258351207 0.5962893963 + 0.6366125941 0.6266574860 0.5971549153 + 0.6374247074 0.6274797916 0.5980203152 + 0.6382368207 0.6283022165 0.5988857746 + 0.6390489936 0.6291245222 0.5997511744 + 0.6398593783 0.6299480796 0.6006168723 + 0.6406673789 0.6307734847 0.6014829874 + 0.6414753199 0.6315988898 0.6023491025 + 0.6422833204 0.6324242949 0.6032152176 + 0.6430912018 0.6332497001 0.6040812731 + 0.6438992023 0.6340751052 0.6049473882 + 0.6447070837 0.6349005103 0.6058135033 + 0.6455112100 0.6357209086 0.6066793203 + 0.6463152170 0.6365411878 0.6075451970 + 0.6471192241 0.6373614073 0.6084110141 + 0.6479231119 0.6381816268 0.6092767715 + 0.6487271190 0.6390019059 0.6101427078 + 0.6495311260 0.6398221254 0.6110085249 + 0.6503347754 0.6406397820 0.6118733883 + 0.6511383057 0.6414539814 0.6127370000 + 0.6519417763 0.6422681808 0.6136006117 + 0.6527453065 0.6430823803 0.6144642234 + 0.6535487771 0.6438966990 0.6153277755 + 0.6543523073 0.6447108984 0.6161913872 + 0.6551557779 0.6455250978 0.6170549989 + 0.6559563279 0.6463404298 0.6179105043 + 0.6567561030 0.6471558809 0.6187639832 + 0.6575558782 0.6479713917 0.6196174026 + 0.6583557129 0.6487870216 0.6204708219 + 0.6591554880 0.6496024728 0.6213243008 + 0.6599553227 0.6504179835 0.6221777201 + 0.6607547998 0.6512334943 0.6230304241 + 0.6615508795 0.6520485878 0.6238759756 + 0.6623470187 0.6528638005 0.6247217059 + 0.6631432176 0.6536788940 0.6255673170 + 0.6639392972 0.6544939876 0.6264129281 + 0.6647353768 0.6553090811 0.6272584796 + 0.6655315161 0.6561242938 0.6281040907 + 0.6663259268 0.6569358706 0.6289486289 + 0.6671159267 0.6577392220 0.6297904253 + 0.6679059863 0.6585425735 0.6306322813 + 0.6686959863 0.6593459845 0.6314740777 + 0.6694861054 0.6601492763 0.6323158741 + 0.6702761054 0.6609526873 0.6331576705 + 0.6710662246 0.6617559791 0.6339995265 + 0.6718522906 0.6625568271 0.6348415017 + 0.6726325750 0.6633538008 0.6356834769 + 0.6734127998 0.6641507149 0.6365255713 + 0.6741930842 0.6649476886 0.6373677254 + 0.6749733090 0.6657446027 0.6382098198 + 0.6757534742 0.6665415764 0.6390517950 + 0.6765338182 0.6673386097 0.6398938894 + 0.6773107052 0.6681358814 0.6407364011 + 0.6780828834 0.6689336896 0.6415793896 + 0.6788551211 0.6697314978 0.6424224973 + 0.6796272993 0.6705293059 0.6432656050 + 0.6803994775 0.6713271141 0.6441085935 + 0.6811717153 0.6721249223 0.6449517012 + 0.6819438934 0.6729226708 0.6457946897 + 0.6827138066 0.6737201810 0.6466346979 + 0.6834788918 0.6745169163 0.6474680901 + 0.6842439771 0.6753137112 0.6483014226 + 0.6850091219 0.6761105061 0.6491346955 + 0.6857742071 0.6769071817 0.6499680281 + 0.6865392923 0.6777039766 0.6508014202 + 0.6873043776 0.6785007715 0.6516346931 + 0.6880689263 0.6792957187 0.6524670720 + 0.6888297200 0.6800801754 0.6532937884 + 0.6895905137 0.6808646917 0.6541203856 + 0.6903513074 0.6816490889 0.6549469829 + 0.6911121011 0.6824336052 0.6557736993 + 0.6918728948 0.6832181215 0.6566002965 + 0.6926336884 0.6840025187 0.6574270129 + 0.6933944821 0.6847869754 0.6582536101 + 0.6941537261 0.6855652928 0.6590738297 + 0.6949126720 0.6863427758 0.6598929167 + 0.6956717968 0.6871201992 0.6607121229 + 0.6964308023 0.6878976226 0.6615312099 + 0.6971898079 0.6886749864 0.6623502970 + 0.6979488134 0.6894524097 0.6631695032 + 0.6987078190 0.6902298927 0.6639885902 + 0.6994645000 0.6910073161 0.6648052931 + 0.7002186179 0.6917846799 0.6656193733 + 0.7009727955 0.6925622225 0.6664335132 + 0.7017269731 0.6933395863 0.6672475934 + 0.7024810910 0.6941171288 0.6680616140 + 0.7032353282 0.6948944926 0.6688756943 + 0.7039895058 0.6956719756 0.6696897745 + 0.7047435045 0.6964492798 0.6705039144 + 0.7054880261 0.6972190738 0.6713137031 + 0.7062326074 0.6979889870 0.6721233726 + 0.7069771290 0.6987587810 0.6729332209 + 0.7077215910 0.6995285749 0.6737430096 + 0.7084661722 0.7002984881 0.6745527983 + 0.7092106938 0.7010682821 0.6753625274 + 0.7099552751 0.7018380761 0.6761723161 + 0.7106971145 0.7026013136 0.6769785881 + 0.7114353776 0.7033559084 0.6777802110 + 0.7121738195 0.7041105032 0.6785817742 + 0.7129122019 0.7048650980 0.6793833971 + 0.7136505246 0.7056195736 0.6801850200 + 0.7143889070 0.7063742280 0.6809865236 + 0.7151272893 0.7071288228 0.6817880869 + 0.7158656120 0.7078834176 0.6825897098 + 0.7165970206 0.7086318135 0.6833915710 + 0.7173261046 0.7093781829 0.6841934919 + 0.7180553079 0.7101244926 0.6849954128 + 0.7187843919 0.7108709216 0.6857973933 + 0.7195134759 0.7116172910 0.6865993142 + 0.7202426791 0.7123637199 0.6874011755 + 0.7209718227 0.7131100893 0.6882030964 + 0.7217009068 0.7138565183 0.6890050769 + 0.7224162817 0.7146016955 0.6897974014 + 0.7231312990 0.7153468132 0.6905894279 + 0.7238463163 0.7160919905 0.6913813949 + 0.7245612144 0.7168372273 0.6921733022 + 0.7252761722 0.7175822854 0.6929653287 + 0.7259911895 0.7183275223 0.6937571764 + 0.7267062068 0.7190726995 0.6945492029 + 0.7274206877 0.7198178172 0.6953408718 + 0.7281301022 0.7205628157 0.6961287260 + 0.7288395166 0.7213078141 0.6969165802 + 0.7295488715 0.7220528126 0.6977043748 + 0.7302582860 0.7227978110 0.6984922886 + 0.7309677005 0.7235428095 0.6992802024 + 0.7316771150 0.7242878079 0.7000679970 + 0.7323865294 0.7250328064 0.7008559108 + 0.7330961823 0.7257779241 0.7016434073 + 0.7338085175 0.7265239954 0.7024263740 + 0.7345207930 0.7272701263 0.7032094002 + 0.7352331281 0.7280163169 0.7039923072 + 0.7359454036 0.7287623882 0.7047752738 + 0.7366576791 0.7295085192 0.7055583000 + 0.7373700142 0.7302545905 0.7063413262 + 0.7380822897 0.7310007215 0.7071242929 + 0.7387946248 0.7317467928 0.7079071999 + 0.7395036817 0.7324852943 0.7086831927 + 0.7402127981 0.7332236171 0.7094588876 + 0.7409217954 0.7339618206 0.7102347016 + 0.7416307926 0.7347000837 0.7110103965 + 0.7423397899 0.7354382873 0.7117860913 + 0.7430489063 0.7361766100 0.7125617862 + 0.7437579036 0.7369148731 0.7133374810 + 0.7444669008 0.7376530766 0.7141131759 + 0.7451686263 0.7383893132 0.7148858905 + 0.7458680272 0.7391248941 0.7156574726 + 0.7465673089 0.7398604155 0.7164289951 + 0.7472665906 0.7405959964 0.7172005773 + 0.7479659915 0.7413315177 0.7179722190 + 0.7486652732 0.7420669794 0.7187438011 + 0.7493646145 0.7428026199 0.7195153832 + 0.7500640154 0.7435380816 0.7202870250 + 0.7507627010 0.7442746162 0.7210568786 + 0.7514607906 0.7450124025 0.7218245268 + 0.7521588206 0.7457501888 0.7225919962 + 0.7528567910 0.7464879751 0.7233595252 + 0.7535548210 0.7472257018 0.7241271138 + 0.7542527914 0.7479634881 0.7248945832 + 0.7549508214 0.7487012744 0.7256621718 + 0.7556489110 0.7494391203 0.7264297009 + 0.7563468814 0.7501769066 0.7271971703 + 0.7570462227 0.7509121895 0.7279605269 + 0.7577455044 0.7516474724 0.7287237048 + 0.7584449053 0.7523828149 0.7294868827 + 0.7591441870 0.7531180978 0.7302501202 + 0.7598435879 0.7538533807 0.7310132980 + 0.7605429292 0.7545887232 0.7317764163 + 0.7612422109 0.7553240061 0.7325395942 + 0.7619416118 0.7560592890 0.7333027720 + 0.7626401782 0.7567914128 0.7340652943 + 0.7633376718 0.7575193048 0.7348269820 + 0.7640352249 0.7582470775 0.7355887294 + 0.7647327781 0.7589750290 0.7363502979 + 0.7654302716 0.7597029209 0.7371119857 + 0.7661278844 0.7604308128 0.7378736138 + 0.7668253779 0.7611585855 0.7386353016 + 0.7675229907 0.7618864775 0.7393969297 + 0.7682204843 0.7626144290 0.7401586175 + 0.7689135075 0.7633404136 0.7409185767 + 0.7696049809 0.7640656829 0.7416778803 + 0.7702965140 0.7647910714 0.7424373031 + 0.7709881067 0.7655165195 0.7431966066 + 0.7716795802 0.7662419081 0.7439560294 + 0.7723711133 0.7669671774 0.7447152734 + 0.7730625868 0.7676926255 0.7454746962 + 0.7737541199 0.7684180140 0.7462341189 + 0.7744455934 0.7691434026 0.7469934225 + 0.7751392722 0.7698696852 0.7477499843 + 0.7758330107 0.7705960274 0.7485064268 + 0.7765266895 0.7713223100 0.7492629290 + 0.7772204280 0.7720487118 0.7500193119 + 0.7779141068 0.7727749944 0.7507756948 + 0.7786077857 0.7735012770 0.7515321970 + 0.7793015242 0.7742276788 0.7522885799 + 0.7799953222 0.7749540210 0.7530450225 + 0.7806888223 0.7756797075 0.7538012266 + 0.7813785076 0.7763937712 0.7545518279 + 0.7820681930 0.7771078944 0.7553023100 + 0.7827579975 0.7778220177 0.7560529113 + 0.7834476829 0.7785360217 0.7568033934 + 0.7841374874 0.7792500854 0.7575538754 + 0.7848271728 0.7799642086 0.7583044767 + 0.7855169773 0.7806782722 0.7590550184 + 0.7862067223 0.7813923955 0.7598056197 + 0.7868962884 0.7821062803 0.7605561018 + 0.7875761986 0.7828112841 0.7613086104 + 0.7882561088 0.7835162878 0.7620609999 + 0.7889360785 0.7842212915 0.7628135085 + 0.7896159887 0.7849262953 0.7635658979 + 0.7902958989 0.7856312990 0.7643182874 + 0.7909759283 0.7863363028 0.7650707960 + 0.7916557789 0.7870413065 0.7658231854 + 0.7923356891 0.7877463102 0.7665756941 + 0.7930157185 0.7884513736 0.7673280835 + 0.7936940193 0.7891541123 0.7680817842 + 0.7943720818 0.7898566127 0.7688357830 + 0.7950502038 0.7905589938 0.7695897222 + 0.7957283258 0.7912613750 0.7703436017 + 0.7964063883 0.7919638157 0.7710976005 + 0.7970845103 0.7926663160 0.7718514800 + 0.7977625728 0.7933686972 0.7726054788 + 0.7984406948 0.7940710783 0.7733594179 + 0.7991188169 0.7947735190 0.7741132975 + 0.7997971773 0.7954763770 0.7748653293 + 0.8004758954 0.7961794734 0.7756156921 + 0.8011544943 0.7968826890 0.7763661146 + 0.8018332124 0.7975857854 0.7771165967 + 0.8025118113 0.7982890010 0.7778670192 + 0.8031905293 0.7989920974 0.7786175013 + 0.8038691282 0.7996953130 0.7793679237 + 0.8045477867 0.8003984094 0.7801182866 + 0.8052263856 0.8011015058 0.7808688283 + 0.8059049249 0.8018025160 0.7816187143 + 0.8065828085 0.8024935126 0.7823663950 + 0.8072608113 0.8031843901 0.7831140757 + 0.8079386950 0.8038753867 0.7838618159 + 0.8086165786 0.8045663238 0.7846094966 + 0.8092945218 0.8052573204 0.7853571773 + 0.8099725246 0.8059481978 0.7861049175 + 0.8106504083 0.8066391945 0.7868525982 + 0.8113282919 0.8073300719 0.7876002789 + 0.8120061755 0.8080211282 0.7883480191 + 0.8126829267 0.8087062240 0.7890954018 + 0.8133587837 0.8093882203 0.7898424864 + 0.8140347004 0.8100702167 0.7905896902 + 0.8147106767 0.8107520938 0.7913368940 + 0.8153865933 0.8114340901 0.7920840979 + 0.8160626292 0.8121160865 0.7928311825 + 0.8167384863 0.8127980828 0.7935783863 + 0.8174144030 0.8134800196 0.7943255901 + 0.8180903792 0.8141620159 0.7950726748 + 0.8187662959 0.8148440123 0.7958198786 + 0.8194429874 0.8155233860 0.7965657711 + 0.8201196194 0.8162028193 0.7973116040 + 0.8207963109 0.8168823123 0.7980574965 + 0.8214728832 0.8175616860 0.7988033891 + 0.8221495748 0.8182411194 0.7995492220 + 0.8228263259 0.8189204931 0.8002951145 + 0.8235028982 0.8195999265 0.8010408878 + 0.8241795897 0.8202794194 0.8017867804 + 0.8248562217 0.8209587932 0.8025326133 + 0.8255324960 0.8216388822 0.8032788038 + 0.8262073994 0.8223220706 0.8040260077 + 0.8268823028 0.8230053782 0.8047732711 + 0.8275572062 0.8236886263 0.8055204749 + 0.8282319903 0.8243718743 0.8062677979 + 0.8289068937 0.8250551224 0.8070150018 + 0.8295817971 0.8257383108 0.8077623248 + 0.8302565813 0.8264216185 0.8085095286 + 0.8309314847 0.8271048069 0.8092567921 + 0.8316063881 0.8277881145 0.8100039959 + 0.8322811723 0.8284710050 0.8107491732 + 0.8329560161 0.8291531205 0.8114882708 + 0.8336306810 0.8298351169 0.8122274280 + 0.8343054056 0.8305171728 0.8129665256 + 0.8349801898 0.8311992884 0.8137056231 + 0.8356549144 0.8318814039 0.8144447207 + 0.8363295794 0.8325635195 0.8151838183 + 0.8370043039 0.8332455754 0.8159229159 + 0.8376790881 0.8339275718 0.8166620135 + 0.8383538127 0.8346096873 0.8174011111 + 0.8390284777 0.8352907896 0.8181397915 + 0.8397032022 0.8359678984 0.8188765049 + 0.8403778076 0.8366451263 0.8196132779 + 0.8410524726 0.8373221755 0.8203501105 + 0.8417270780 0.8379992843 0.8210868835 + 0.8424018025 0.8386765122 0.8218235970 + 0.8430765271 0.8393536210 0.8225604296 + 0.8437510729 0.8400307298 0.8232972026 + 0.8444257975 0.8407077789 0.8240339756 + 0.8451004028 0.8413850069 0.8247706890 + 0.8457751274 0.8420621157 0.8255075216 + 0.8464422822 0.8427348137 0.8262410164 + 0.8471094966 0.8434073925 0.8269745111 + 0.8477767110 0.8440800905 0.8277080059 + 0.8484439254 0.8447527289 0.8284415007 + 0.8491110802 0.8454254270 0.8291749954 + 0.8497782946 0.8460981250 0.8299083710 + 0.8504455090 0.8467707038 0.8306419253 + 0.8511127234 0.8474434018 0.8313754201 + 0.8517798185 0.8481160998 0.8321089149 + 0.8524469733 0.8487886786 0.8328424096 + 0.8531115055 0.8494626284 0.8335720897 + 0.8537746072 0.8501369953 0.8342999220 + 0.8544377089 0.8508114219 0.8350275755 + 0.8551008105 0.8514857888 0.8357554078 + 0.8557639122 0.8521602154 0.8364831209 + 0.8564270735 0.8528345823 0.8372108936 + 0.8570901752 0.8535091281 0.8379387259 + 0.8577532768 0.8541834950 0.8386663795 + 0.8584163785 0.8548579216 0.8393942118 + 0.8590794802 0.8555322886 0.8401219249 + 0.8597424030 0.8562076092 0.8408495188 + 0.8604043722 0.8568869233 0.8415760994 + 0.8610665202 0.8575661778 0.8423027992 + 0.8617284894 0.8582454920 0.8430293798 + 0.8623905182 0.8589248061 0.8437560797 + 0.8630526066 0.8596040010 0.8444827199 + 0.8637145758 0.8602833152 0.8452093005 + 0.8643766046 0.8609626293 0.8459360003 + 0.8650386930 0.8616418839 0.8466625810 + 0.8657007217 0.8623211980 0.8473892212 + 0.8663626909 0.8630003929 0.8481159210 + 0.8670225143 0.8636755943 0.8488407731 + 0.8676806092 0.8643475175 0.8495643139 + 0.8683385849 0.8650195003 0.8502879143 + 0.8689966798 0.8656914234 0.8510113955 + 0.8696547747 0.8663634062 0.8517348766 + 0.8703128099 0.8670353889 0.8524584770 + 0.8709709048 0.8677073121 0.8531820178 + 0.8716288805 0.8683792949 0.8539056182 + 0.8722869754 0.8690512180 0.8546290994 + 0.8729450703 0.8697232008 0.8553525805 + 0.8736031055 0.8703951836 0.8560761809 + 0.8742563128 0.8710637093 0.8567957282 + 0.8749082088 0.8717314005 0.8575140834 + 0.8755602241 0.8723990917 0.8582326174 + 0.8762121201 0.8730667830 0.8589509726 + 0.8768640161 0.8737344742 0.8596695065 + 0.8775159717 0.8744022846 0.8603879809 + 0.8781679273 0.8750699759 0.8611063957 + 0.8788198829 0.8757377267 0.8618249297 + 0.8794717789 0.8764054179 0.8625432849 + 0.8801236749 0.8770731091 0.8632618189 + 0.8807756901 0.8777408004 0.8639801741 + 0.8814250231 0.8784101009 0.8646934032 + 0.8820741177 0.8790795803 0.8654057980 + 0.8827230930 0.8797491193 0.8661181927 + 0.8833721280 0.8804187179 0.8668307066 + 0.8840212226 0.8810881972 0.8675431013 + 0.8846701980 0.8817576766 0.8682554960 + 0.8853191733 0.8824272156 0.8689680099 + 0.8859683275 0.8830966949 0.8696804047 + 0.8866173029 0.8837661743 0.8703927994 + 0.8872662783 0.8844357133 0.8711053133 + 0.8879153728 0.8851051927 0.8718177080 + 0.8885645270 0.8857750893 0.8725255728 + 0.8892136812 0.8864449859 0.8732324839 + 0.8898627758 0.8871150017 0.8739395142 + 0.8905119896 0.8877848983 0.8746464252 + 0.8911612034 0.8884547949 0.8753533959 + 0.8918102980 0.8891248107 0.8760603070 + 0.8924595118 0.8897947073 0.8767672777 + 0.8931086063 0.8904647231 0.8774741888 + 0.8937578201 0.8911346197 0.8781810999 + 0.8944069743 0.8918045163 0.8788880706 + 0.8950561285 0.8924744725 0.8795949817 + 0.8957039118 0.8931388259 0.8802983165 + 0.8963508010 0.8937997222 0.8809992075 + 0.8969975710 0.8944606185 0.8817002177 + 0.8976445198 0.8951215148 0.8824012280 + 0.8982914090 0.8957824111 0.8831021786 + 0.8989382982 0.8964433074 0.8838031888 + 0.8995851278 0.8971043229 0.8845040798 + 0.9002320170 0.8977652192 0.8852050900 + 0.9008789062 0.8984261155 0.8859061003 + 0.9015257955 0.8990870118 0.8866071105 + 0.9021726847 0.8997479081 0.8873080015 + 0.9028183222 0.9004076123 0.8880085945 + 0.9034605026 0.9010636806 0.8887078166 + 0.9041026831 0.9017199278 0.8894069791 + 0.9047449231 0.9023761153 0.8901063204 + 0.9053872228 0.9030323029 0.8908054829 + 0.9060294032 0.9036884904 0.8915048242 + 0.9066715837 0.9043446183 0.8922039866 + 0.9073138237 0.9050008059 0.8929033279 + 0.9079560041 0.9056569934 0.8936024904 + 0.9085981846 0.9063131809 0.8943017721 + 0.9092404246 0.9069694281 0.8950009942 + 0.9098826051 0.9076254964 0.8957002759 + 0.9105213881 0.9082816243 0.8964002132 + 0.9111589789 0.9089375138 0.8971003890 + 0.9117966294 0.9095935225 0.8978006244 + 0.9124342203 0.9102494717 0.8985008001 + 0.9130718112 0.9109054804 0.8992009759 + 0.9137094021 0.9115614891 0.8999012709 + 0.9143469930 0.9122173786 0.9006015062 + 0.9149845839 0.9128733873 0.9013016820 + 0.9156221747 0.9135293961 0.9020019174 + 0.9162598252 0.9141854048 0.9027020931 + 0.9168974161 0.9148412943 0.9034023285 + 0.9175344110 0.9154965281 0.9041017890 + 0.9181634784 0.9161416292 0.9047920108 + 0.9187926054 0.9167866707 0.9054822922 + 0.9194216728 0.9174317718 0.9061725140 + 0.9200507998 0.9180769920 0.9068626761 + 0.9206799865 0.9187220931 0.9075530171 + 0.9213091135 0.9193671942 0.9082431793 + 0.9219381809 0.9200122952 0.9089334011 + 0.9225673079 0.9206575155 0.9096236825 + 0.9231963754 0.9213026166 0.9103139043 + 0.9238255024 0.9219477177 0.9110041857 + 0.9244546294 0.9225928187 0.9116944075 + 0.9250795841 0.9232333899 0.9123820066 + 0.9256916046 0.9238601923 0.9130614996 + 0.9263036847 0.9244869947 0.9137409925 + 0.9269157052 0.9251136780 0.9144204855 + 0.9275277853 0.9257404804 0.9150999784 + 0.9281398058 0.9263672233 0.9157794714 + 0.9287518263 0.9269940257 0.9164590836 + 0.9293639064 0.9276207089 0.9171385765 + 0.9299759269 0.9282475114 0.9178181291 + 0.9305880070 0.9288743138 0.9184976220 + 0.9312000275 0.9295009971 0.9191771150 + 0.9318121076 0.9301277995 0.9198566079 + 0.9324201941 0.9307510853 0.9205334187 + 0.9330167174 0.9313644767 0.9212021232 + 0.9336131811 0.9319778085 0.9218708873 + 0.9342097044 0.9325911999 0.9225397110 + 0.9348061085 0.9332044721 0.9232084155 + 0.9354025722 0.9338178039 0.9238771796 + 0.9359990954 0.9344311953 0.9245458841 + 0.9365956187 0.9350445271 0.9252147079 + 0.9371920824 0.9356579185 0.9258834720 + 0.9377886057 0.9362711906 0.9265521765 + 0.9383851290 0.9368845820 0.9272210002 + 0.9389814734 0.9374979138 0.9278897047 + 0.9395771027 0.9381104708 0.9285578728 + 0.9401646256 0.9387161732 0.9292200804 + 0.9407520294 0.9393218756 0.9298822880 + 0.9413393736 0.9399275780 0.9305444956 + 0.9419268966 0.9405332804 0.9312068224 + 0.9425143003 0.9411389232 0.9318689704 + 0.9431017041 0.9417446256 0.9325311780 + 0.9436892271 0.9423503280 0.9331933856 + 0.9442765713 0.9429559708 0.9338555932 + 0.9448639750 0.9435616732 0.9345179200 + 0.9454514980 0.9441673756 0.9351801276 + 0.9460389018 0.9447730780 0.9358422756 + 0.9466264248 0.9453787804 0.9365044832 + 0.9472072124 0.9459720850 0.9371623993 + 0.9477860928 0.9465619922 0.9378191233 + 0.9483650923 0.9471517801 0.9384757876 + 0.9489439726 0.9477416277 0.9391323924 + 0.9495229721 0.9483314753 0.9397891164 + 0.9501019120 0.9489213228 0.9404457211 + 0.9506809115 0.9495111704 0.9411023855 + 0.9512599111 0.9501010180 0.9417591095 + 0.9518387914 0.9506909251 0.9424157143 + 0.9524177909 0.9512807131 0.9430723786 + 0.9529966712 0.9518705010 0.9437291026 + 0.9535756707 0.9524604082 0.9443857074 + 0.9541510940 0.9530453086 0.9450407028 + 0.9547178149 0.9536182880 0.9456915855 + 0.9552845955 0.9541913867 0.9463424087 + 0.9558513761 0.9547644258 0.9469932914 + 0.9564182162 0.9553375244 0.9476441145 + 0.9569848776 0.9559105039 0.9482949972 + 0.9575517178 0.9564834833 0.9489458203 + 0.9581184983 0.9570565820 0.9495967031 + 0.9586852789 0.9576296210 0.9502475262 + 0.9592519999 0.9582027197 0.9508984089 + 0.9598187804 0.9587756991 0.9515491724 + 0.9603856206 0.9593486786 0.9522001147 + 0.9609522820 0.9599217772 0.9528508782 + 0.9615089297 0.9604855180 0.9534955025 + 0.9620596170 0.9610437751 0.9541364908 + 0.9626103044 0.9616020918 0.9547774792 + 0.9631609917 0.9621605277 0.9554185271 + 0.9637116790 0.9627187848 0.9560595155 + 0.9642623067 0.9632771015 0.9567005038 + 0.9648129940 0.9638354182 0.9573414922 + 0.9653636813 0.9643937945 0.9579824805 + 0.9659144282 0.9649521112 0.9586235285 + 0.9664651155 0.9655104280 0.9592645168 + 0.9670158029 0.9660686851 0.9599055052 + 0.9675664902 0.9666271210 0.9605464935 + 0.9681171775 0.9671853781 0.9611874819 + 0.9686546922 0.9677324295 0.9618178010 + 0.9691889882 0.9682767987 0.9624454975 + 0.9697234035 0.9688212276 0.9630730748 + 0.9702578187 0.9693654776 0.9637007713 + 0.9707921147 0.9699099064 0.9643284082 + 0.9713264704 0.9704542160 0.9649561048 + 0.9718608856 0.9709985852 0.9655836821 + 0.9723951817 0.9715428948 0.9662113786 + 0.9729295969 0.9720873237 0.9668390155 + 0.9734640121 0.9726316929 0.9674667120 + 0.9739983082 0.9731760025 0.9680942893 + 0.9745327234 0.9737203717 0.9687219858 + 0.9750670791 0.9742646813 0.9693496227 + 0.9755846262 0.9747933149 0.9699637890 + 0.9760981202 0.9753180742 0.9705746174 + 0.9766116142 0.9758427739 0.9711853862 + 0.9771251082 0.9763675928 0.9717962742 + 0.9776384830 0.9768922925 0.9724071026 + 0.9781519771 0.9774171114 0.9730178714 + 0.9786654711 0.9779418111 0.9736286998 + 0.9791790247 0.9784665704 0.9742395878 + 0.9796923995 0.9789913297 0.9748504162 + 0.9802058935 0.9795160890 0.9754611850 + 0.9807193875 0.9800407887 0.9760720730 + 0.9812328815 0.9805656075 0.9766829014 + 0.9817463160 0.9810903072 0.9772937298 + 0.9822406173 0.9815968871 0.9778919816 + 0.9827232957 0.9820926189 0.9784827828 + 0.9832059741 0.9825881720 0.9790735841 + 0.9836887121 0.9830839038 0.9796643257 + 0.9841712713 0.9835795164 0.9802551270 + 0.9846540093 0.9840751886 0.9808458090 + 0.9851366878 0.9845708013 0.9814366102 + 0.9856194258 0.9850664735 0.9820274115 + 0.9861021042 0.9855620861 0.9826180935 + 0.9865847826 0.9860578179 0.9832088947 + 0.9870674014 0.9865533710 0.9837995768 + 0.9875500798 0.9870491028 0.9843903780 + 0.9880328178 0.9875447154 0.9849811792 + 0.9885063171 0.9880321026 0.9855628014 + 0.9889544845 0.9884964824 0.9861189723 + 0.9894027114 0.9889609218 0.9866752028 + 0.9898508787 0.9894253016 0.9872314930 + 0.9902991056 0.9898896813 0.9877877235 + 0.9907472730 0.9903541207 0.9883438945 + 0.9911954999 0.9908185005 0.9889001250 + 0.9916437268 0.9912828803 0.9894564152 + 0.9920918941 0.9917473197 0.9900125861 + 0.9925400019 0.9922116995 0.9905688167 + 0.9929882288 0.9926760793 0.9911249876 + 0.9934363961 0.9931405187 0.9916812778 + 0.9938846231 0.9936048985 0.9922375083 + 0.9943327904 0.9940692782 0.9927936792 + 0.9947488904 0.9945036173 0.9933192730 + 0.9951528907 0.9949263930 0.9938331842 + 0.9955567718 0.9953492284 0.9943470955 + 0.9959607124 0.9957720041 0.9948610067 + 0.9963645935 0.9961947799 0.9953749180 + 0.9967685938 0.9966176152 0.9958888292 + 0.9971724749 0.9970403910 0.9964026809 + 0.9975764155 0.9974632263 0.9969165921 + 0.9979804158 0.9978860021 0.9974305034 + 0.9983842969 0.9983087778 0.9979444146 + 0.9987881780 0.9987316132 0.9984583259 + 0.9991921186 0.9991543889 0.9989721775 + 0.9995961189 0.9995772243 0.9994860888 + 1.0000000000 1.0000000000 1.0000000000 +} diff --git a/rpplugins/color_correction/resources/film_luts_raw/kodak_portra_160nc.spi1d b/rpplugins/color_correction/resources/film_luts_raw/kodak_portra_160nc.spi1d new file mode 100644 index 0000000..e61ba0e --- /dev/null +++ b/rpplugins/color_correction/resources/film_luts_raw/kodak_portra_160nc.spi1d @@ -0,0 +1,1030 @@ +Version 1 +From 0.0 1.0 +Length 1024 +Components 3 +{ + 0.0000000000 0.0000000000 0.0000000000 + 0.0104342103 0.0097368704 0.0081004426 + 0.0202932805 0.0187927708 0.0152669698 + 0.0287755504 0.0266450606 0.0213894807 + 0.0361699387 0.0334015600 0.0267654601 + 0.0427807011 0.0394648015 0.0316598192 + 0.0487997085 0.0450807586 0.0361505710 + 0.0544521399 0.0502359308 0.0404325016 + 0.0596807487 0.0550900213 0.0445077084 + 0.0646303892 0.0597528182 0.0484247990 + 0.0693302229 0.0641593412 0.0521505699 + 0.0737845525 0.0683351308 0.0556968004 + 0.0780915692 0.0723901764 0.0591261685 + 0.0822694898 0.0763313472 0.0624415018 + 0.0863260701 0.0801697522 0.0657054484 + 0.0902359709 0.0839016736 0.0689003170 + 0.0940105170 0.0874804035 0.0719991401 + 0.0976487026 0.0909066126 0.0750158876 + 0.1011712030 0.0942689478 0.0779601783 + 0.1046311036 0.0975821987 0.0808535069 + 0.1080254018 0.1008832976 0.0837027133 + 0.1113561988 0.1041185036 0.0864896476 + 0.1146244034 0.1072700024 0.0892440900 + 0.1178375036 0.1103363037 0.0919481963 + 0.1209478006 0.1133145019 0.0945950523 + 0.1239672974 0.1161829010 0.0971959010 + 0.1269288063 0.1190017015 0.0997639596 + 0.1298519969 0.1217684969 0.1022854969 + 0.1327518970 0.1245191991 0.1047450975 + 0.1356167048 0.1272488981 0.1071709991 + 0.1384285986 0.1299587935 0.1095672026 + 0.1411979049 0.1326563060 0.1119202971 + 0.1438945979 0.1353050023 0.1142712981 + 0.1465526074 0.1378984004 0.1166002005 + 0.1491758972 0.1404460073 0.1189038008 + 0.1517738998 0.1429633051 0.1211721972 + 0.1543568969 0.1454481930 0.1234188005 + 0.1569266021 0.1478973031 0.1256408989 + 0.1594693065 0.1503026038 0.1278519034 + 0.1619731039 0.1526698023 0.1300269067 + 0.1644496024 0.1550289989 0.1322003007 + 0.1668978930 0.1573766023 0.1343421042 + 0.1693100929 0.1597099006 0.1364780068 + 0.1717022955 0.1620142013 0.1385955065 + 0.1740535051 0.1643050015 0.1406960934 + 0.1763895005 0.1665803045 0.1427800953 + 0.1786942929 0.1688499004 0.1448349953 + 0.1809858978 0.1710920930 0.1468731016 + 0.1832552999 0.1733157039 0.1488973945 + 0.1855040044 0.1754987985 0.1508941948 + 0.1877363026 0.1776573956 0.1528868973 + 0.1899455935 0.1797675043 0.1548427939 + 0.1921364963 0.1818484068 0.1567813009 + 0.1943152994 0.1839254946 0.1587089002 + 0.1964662969 0.1859872043 0.1605975032 + 0.1986126006 0.1880321950 0.1624716967 + 0.2007299960 0.1900521070 0.1643451005 + 0.2028377950 0.1920509040 0.1662126929 + 0.2049141973 0.1940355003 0.1680644006 + 0.2069772035 0.1960064024 0.1699177027 + 0.2090151012 0.1979558021 0.1717617065 + 0.2110265940 0.1998984069 0.1735890955 + 0.2130140960 0.2018423975 0.1754163951 + 0.2149661928 0.2037782073 0.1772357970 + 0.2169061005 0.2057027072 0.1790401042 + 0.2188301980 0.2076229006 0.1808345020 + 0.2207366973 0.2095226049 0.1826318949 + 0.2226286978 0.2114018947 0.1844107956 + 0.2245007008 0.2132596970 0.1861657947 + 0.2263693064 0.2151038945 0.1879153997 + 0.2282283008 0.2169471979 0.1896584928 + 0.2300662994 0.2187916934 0.1913760006 + 0.2318931073 0.2206248939 0.1930719018 + 0.2337073982 0.2224474996 0.1947627068 + 0.2355096936 0.2242646962 0.1964586973 + 0.2373178005 0.2260648012 0.1981409937 + 0.2391194999 0.2278497964 0.1998063028 + 0.2409114987 0.2296245992 0.2014670074 + 0.2427058071 0.2313791960 0.2031272948 + 0.2444884032 0.2331136018 0.2047773004 + 0.2462590933 0.2348330021 0.2064110041 + 0.2480255961 0.2365438938 0.2080343962 + 0.2497811019 0.2382504940 0.2096567005 + 0.2515194118 0.2399522066 0.2112801969 + 0.2532550991 0.2416505069 0.2129054964 + 0.2549892068 0.2433426976 0.2145148963 + 0.2567017972 0.2450259030 0.2161193043 + 0.2584092021 0.2467028052 0.2177298963 + 0.2601015866 0.2483644933 0.2193389982 + 0.2617790103 0.2500090897 0.2209367007 + 0.2634465098 0.2516413033 0.2225185931 + 0.2651093900 0.2532702088 0.2240934074 + 0.2667602897 0.2549068034 0.2256740034 + 0.2683969140 0.2565379143 0.2272486985 + 0.2700237036 0.2581647933 0.2288096994 + 0.2716447115 0.2597900033 0.2303546071 + 0.2732641101 0.2614181042 0.2318903059 + 0.2748670876 0.2630349994 0.2334287018 + 0.2764695883 0.2646454871 0.2349649072 + 0.2780736983 0.2662520111 0.2364968956 + 0.2796798050 0.2678571939 0.2380219996 + 0.2812705934 0.2694469988 0.2395333946 + 0.2828595936 0.2710259855 0.2410411984 + 0.2844449878 0.2725957036 0.2425480038 + 0.2860139906 0.2741582990 0.2440553010 + 0.2875689864 0.2757219076 0.2455565929 + 0.2891198993 0.2772797048 0.2470498979 + 0.2906715870 0.2788243890 0.2485287040 + 0.2922109962 0.2803615928 0.2500022054 + 0.2937461138 0.2818956077 0.2514745891 + 0.2952778041 0.2834267020 0.2529469132 + 0.2968105972 0.2849394083 0.2543964088 + 0.2983357012 0.2864452004 0.2558352947 + 0.2998512089 0.2879436016 0.2572622895 + 0.3013514876 0.2894333899 0.2586838007 + 0.3028486967 0.2909137011 0.2601067126 + 0.3043426871 0.2923789024 0.2615340948 + 0.3058384061 0.2938305140 0.2629559040 + 0.3073315024 0.2952756882 0.2643721104 + 0.3088150918 0.2967103124 0.2657704055 + 0.3102928102 0.2981418073 0.2671636939 + 0.3117668927 0.2995713055 0.2685531974 + 0.3132205009 0.3009906113 0.2699464858 + 0.3146683872 0.3024047017 0.2713372111 + 0.3161059022 0.3038088977 0.2727209032 + 0.3175452054 0.3052091897 0.2740899920 + 0.3189851940 0.3066073060 0.2754499018 + 0.3204107881 0.3079979122 0.2767995894 + 0.3218325078 0.3093867898 0.2781487107 + 0.3232437968 0.3107711971 0.2794989049 + 0.3246552944 0.3121513128 0.2808524072 + 0.3260669112 0.3135269880 0.2822099924 + 0.3274610937 0.3148944974 0.2835561037 + 0.3288491964 0.3162589073 0.2848969996 + 0.3302272856 0.3176145852 0.2862280905 + 0.3316037059 0.3189670146 0.2875579000 + 0.3329727948 0.3203001022 0.2888858914 + 0.3343341947 0.3216342926 0.2902134955 + 0.3356775939 0.3229714930 0.2915399969 + 0.3370169997 0.3243103921 0.2928608954 + 0.3383513093 0.3256517947 0.2941726148 + 0.3396857977 0.3269968033 0.2954798043 + 0.3410206139 0.3283447921 0.2967823148 + 0.3423599005 0.3296887875 0.2980845869 + 0.3437018096 0.3310303092 0.2993867099 + 0.3450402915 0.3323693871 0.3006789982 + 0.3463771939 0.3337073028 0.3019658029 + 0.3477115035 0.3350473046 0.3032433093 + 0.3490447998 0.3363879919 0.3045162857 + 0.3503681123 0.3377214968 0.3057813048 + 0.3516876996 0.3390519917 0.3070425987 + 0.3530015051 0.3403775096 0.3083038032 + 0.3543129861 0.3417007923 0.3095650971 + 0.3556298018 0.3430233002 0.3108316958 + 0.3569492996 0.3443453014 0.3121018112 + 0.3582645059 0.3456591964 0.3133673072 + 0.3595766127 0.3469670117 0.3146286905 + 0.3608855009 0.3482683003 0.3158847988 + 0.3621911108 0.3495621085 0.3171336055 + 0.3634957969 0.3508524001 0.3183821142 + 0.3647992015 0.3521358073 0.3196297884 + 0.3661004901 0.3534179032 0.3208785057 + 0.3673923910 0.3546931148 0.3221335113 + 0.3686844110 0.3559682965 0.3233886063 + 0.3699693084 0.3572291136 0.3246343136 + 0.3712542057 0.3584896028 0.3258793950 + 0.3725373149 0.3597457111 0.3271150887 + 0.3738197982 0.3610003889 0.3283470869 + 0.3750964105 0.3622534871 0.3295781016 + 0.3763675094 0.3635050952 0.3308078945 + 0.3776369989 0.3647533059 0.3320389092 + 0.3789013028 0.3659900129 0.3332746923 + 0.3801654875 0.3672266901 0.3345105052 + 0.3814153969 0.3684552014 0.3357368112 + 0.3826642036 0.3696827888 0.3369618058 + 0.3838984966 0.3709067106 0.3381794989 + 0.3851222992 0.3721277118 0.3393906951 + 0.3863449097 0.3733451962 0.3406014144 + 0.3875628114 0.3745481074 0.3418095112 + 0.3887807131 0.3757509887 0.3430176079 + 0.3899891078 0.3769412935 0.3442226052 + 0.3911952078 0.3781279922 0.3454265893 + 0.3923954070 0.3793081939 0.3466267884 + 0.3935852945 0.3804757893 0.3478181064 + 0.3947750926 0.3816434145 0.3490093946 + 0.3959554136 0.3828100860 0.3501937985 + 0.3971343935 0.3839766979 0.3513768911 + 0.3983117044 0.3851422071 0.3525578976 + 0.3994863927 0.3863059878 0.3537346125 + 0.4006612003 0.3874697983 0.3549112976 + 0.4018234015 0.3886323869 0.3560853004 + 0.4029830992 0.3897947073 0.3572584987 + 0.4041410089 0.3909561932 0.3584313095 + 0.4052937031 0.3921152949 0.3596020937 + 0.4064464867 0.3932743073 0.3607727885 + 0.4075922072 0.3944297135 0.3619342148 + 0.4087341130 0.3955830038 0.3630889952 + 0.4098758996 0.3967362046 0.3642438948 + 0.4110023081 0.3978854120 0.3653908968 + 0.4121286869 0.3990345001 0.3665375113 + 0.4132547975 0.4001820982 0.3676846027 + 0.4143803120 0.4013260901 0.3688332140 + 0.4155057073 0.4024702013 0.3699817061 + 0.4166313112 0.4036095142 0.3711296916 + 0.4177572131 0.4047453105 0.3722772896 + 0.4188829958 0.4058811963 0.3734247983 + 0.4199970961 0.4070141912 0.3745591044 + 0.4211089909 0.4081465006 0.3756898940 + 0.4222208858 0.4092785120 0.3768205941 + 0.4233328998 0.4104020000 0.3779422939 + 0.4244450033 0.4115254879 0.3790639043 + 0.4255572855 0.4126478136 0.3801856935 + 0.4266704023 0.4137653112 0.3813084066 + 0.4277834892 0.4148826897 0.3824310899 + 0.4288921058 0.4160000980 0.3835541010 + 0.4299925864 0.4171172976 0.3846774995 + 0.4310930073 0.4182344079 0.3858009875 + 0.4321939051 0.4193536937 0.3869203925 + 0.4332954884 0.4204756916 0.3880335093 + 0.4343971014 0.4215976894 0.3891465962 + 0.4354996085 0.4227164984 0.3902549148 + 0.4366030097 0.4238317907 0.3913570940 + 0.4377062917 0.4249469936 0.3924593031 + 0.4388040006 0.4260604084 0.3935610950 + 0.4398961961 0.4271718860 0.3946624100 + 0.4409883022 0.4282833934 0.3957636952 + 0.4420804083 0.4293954074 0.3968654871 + 0.4431723058 0.4305078983 0.3979677856 + 0.4442642033 0.4316205084 0.3990701139 + 0.4453507066 0.4327288866 0.4001703858 + 0.4464294016 0.4338311851 0.4012669921 + 0.4475080073 0.4349335134 0.4023635983 + 0.4485828876 0.4360336959 0.4034568965 + 0.4496490061 0.4371289909 0.4045400023 + 0.4507152140 0.4382242858 0.4056229889 + 0.4517813921 0.4393191934 0.4067057967 + 0.4528484046 0.4404121935 0.4077850878 + 0.4539153874 0.4415051043 0.4088644981 + 0.4549823999 0.4425981045 0.4099437892 + 0.4560458958 0.4436711967 0.4110217094 + 0.4571090937 0.4447430074 0.4120995104 + 0.4581724107 0.4458146989 0.4131771922 + 0.4592300057 0.4468767941 0.4142549038 + 0.4602853060 0.4479345977 0.4153324962 + 0.4613406062 0.4489924014 0.4164102077 + 0.4623945951 0.4500474930 0.4174832106 + 0.4634467959 0.4510987103 0.4185484946 + 0.4644989967 0.4521498978 0.4196138084 + 0.4655506909 0.4532003999 0.4206787944 + 0.4665969014 0.4542433918 0.4217385948 + 0.4676432014 0.4552864134 0.4227983057 + 0.4686895013 0.4563294947 0.4238579869 + 0.4697276056 0.4573652148 0.4249185920 + 0.4707626998 0.4583980143 0.4259794950 + 0.4717977941 0.4594308138 0.4270403981 + 0.4728317857 0.4604609907 0.4280979037 + 0.4738632143 0.4614850879 0.4291453958 + 0.4748947024 0.4625090957 0.4301928878 + 0.4759261906 0.4635331929 0.4312404990 + 0.4769518971 0.4645487964 0.4322755933 + 0.4779764116 0.4655626118 0.4333074987 + 0.4790009856 0.4665764868 0.4343394041 + 0.4800215960 0.4675863981 0.4353694916 + 0.4810340106 0.4685879052 0.4363949895 + 0.4820463955 0.4695892930 0.4374206066 + 0.4830586910 0.4705908000 0.4384461045 + 0.4840714037 0.4715859890 0.4394738078 + 0.4850840867 0.4725790918 0.4405022860 + 0.4860967994 0.4735723138 0.4415307939 + 0.4871076941 0.4745646119 0.4425587952 + 0.4881089032 0.4755522013 0.4435825944 + 0.4891101122 0.4765397906 0.4446065128 + 0.4901114106 0.4775272906 0.4456303120 + 0.4911071956 0.4785116911 0.4466493130 + 0.4920977056 0.4794926047 0.4476625025 + 0.4930881858 0.4804734886 0.4486756027 + 0.4940786958 0.4814544916 0.4496887922 + 0.4950703979 0.4824301004 0.4506951869 + 0.4960624874 0.4834043086 0.4516992867 + 0.4970546067 0.4843784869 0.4527033865 + 0.4980463088 0.4853524864 0.4537074864 + 0.4990282059 0.4863195121 0.4547115862 + 0.5000100732 0.4872865975 0.4557158053 + 0.5009920001 0.4882535934 0.4567199051 + 0.5019717216 0.4892205000 0.4577234983 + 0.5029439926 0.4901863933 0.4587247968 + 0.5039163828 0.4911524057 0.4597260952 + 0.5048887134 0.4921183884 0.4607273936 + 0.5058619976 0.4930835068 0.4617233872 + 0.5068370104 0.4940471947 0.4627084136 + 0.5078119040 0.4950107932 0.4636934102 + 0.5087867975 0.4959745109 0.4646784067 + 0.5097575188 0.4969376922 0.4656594992 + 0.5107231736 0.4979003966 0.4666348100 + 0.5116888285 0.4988631010 0.4676100016 + 0.5126544833 0.4998258054 0.4685853124 + 0.5136160254 0.5007869005 0.4695602953 + 0.5145732164 0.5017461777 0.4705348015 + 0.5155304074 0.5027055740 0.4715093076 + 0.5164874792 0.5036649108 0.4724838138 + 0.5174427032 0.5046222210 0.4734596908 + 0.5183954835 0.5055770278 0.4744375944 + 0.5193483829 0.5065317750 0.4754154980 + 0.5203012228 0.5074865818 0.4763934016 + 0.5212494731 0.5084401965 0.4773665071 + 0.5221908092 0.5093917847 0.4783307016 + 0.5231320858 0.5103434920 0.4792948067 + 0.5240733027 0.5112950802 0.4802590013 + 0.5250124931 0.5122454166 0.4812211096 + 0.5259457231 0.5131919980 0.4821757078 + 0.5268787742 0.5141385794 0.4831303060 + 0.5278120041 0.5150852203 0.4840849936 + 0.5287448764 0.5160313845 0.4850395918 + 0.5296741724 0.5169715881 0.4859933853 + 0.5306035280 0.5179117918 0.4869472086 + 0.5315328836 0.5188519955 0.4879010022 + 0.5324621797 0.5197921991 0.4888547957 + 0.5333819985 0.5207303166 0.4898129106 + 0.5343000293 0.5216680169 0.4907721877 + 0.5352180004 0.5226057172 0.4917314053 + 0.5361359715 0.5235434175 0.4926905930 + 0.5370497108 0.5244811177 0.4936460853 + 0.5379598141 0.5254188180 0.4945977032 + 0.5388697982 0.5263565183 0.4955492914 + 0.5397799015 0.5272942185 0.4965009093 + 0.5406906009 0.5282303095 0.4974510968 + 0.5416039824 0.5291588902 0.4983924925 + 0.5425174832 0.5300874114 0.4993340075 + 0.5434309244 0.5310158730 0.5002753735 + 0.5443444252 0.5319445133 0.5012168884 + 0.5452517867 0.5328708887 0.5021572113 + 0.5461574793 0.5337966084 0.5030971766 + 0.5470631123 0.5347223878 0.5040370822 + 0.5479686856 0.5356481075 0.5049769878 + 0.5488722920 0.5365749002 0.5059170723 + 0.5497710109 0.5375043154 0.5068572760 + 0.5506697893 0.5384337902 0.5077975988 + 0.5515685081 0.5393632054 0.5087379217 + 0.5524672270 0.5402926207 0.5096781850 + 0.5533673763 0.5412126780 0.5106148124 + 0.5542681217 0.5421293974 0.5115498900 + 0.5551686883 0.5430461168 0.5124850273 + 0.5560693741 0.5439627767 0.5134201050 + 0.5569679737 0.5448786020 0.5143538713 + 0.5578554273 0.5457888842 0.5152763128 + 0.5587428212 0.5466991067 0.5161986947 + 0.5596302152 0.5476093888 0.5171210766 + 0.5605176091 0.5485196114 0.5180435181 + 0.5614027977 0.5494297743 0.5189639926 + 0.5622857213 0.5503401160 0.5198820829 + 0.5631685853 0.5512502789 0.5208001733 + 0.5640513897 0.5521605015 0.5217183828 + 0.5649343133 0.5530707240 0.5226364732 + 0.5658143759 0.5539742112 0.5235576034 + 0.5666937232 0.5548753738 0.5244798064 + 0.5675728917 0.5557765961 0.5254021287 + 0.5684521794 0.5566778183 0.5263242722 + 0.5693315268 0.5575789213 0.5272465944 + 0.5701966882 0.5584716201 0.5281707048 + 0.5710616112 0.5593640208 0.5290948749 + 0.5719264746 0.5602563024 0.5300192237 + 0.5727913976 0.5611487031 0.5309433937 + 0.5736559033 0.5620400906 0.5318667889 + 0.5745171905 0.5629237890 0.5327801108 + 0.5753784776 0.5638076067 0.5336934924 + 0.5762398243 0.5646913052 0.5346068144 + 0.5771011114 0.5655751228 0.5355200768 + 0.5779622793 0.5664567947 0.5364326835 + 0.5788232088 0.5673298240 0.5373411775 + 0.5796840787 0.5682027936 0.5382497907 + 0.5805448890 0.5690757036 0.5391582847 + 0.5814058185 0.5699486732 0.5400668979 + 0.5822650790 0.5708199739 0.5409761071 + 0.5831186175 0.5716847777 0.5418882966 + 0.5839720964 0.5725495219 0.5428004861 + 0.5848255754 0.5734142065 0.5437126756 + 0.5856791139 0.5742788911 0.5446249247 + 0.5865321159 0.5751429796 0.5455365181 + 0.5873820782 0.5760030746 0.5464432240 + 0.5882321000 0.5768632293 0.5473498702 + 0.5890821218 0.5777233839 0.5482565165 + 0.5899320841 0.5785834789 0.5491632223 + 0.5907821059 0.5794435143 0.5500699282 + 0.5916317105 0.5802974105 0.5509622097 + 0.5924813151 0.5811514258 0.5518543720 + 0.5933309793 0.5820053816 0.5527465940 + 0.5941805840 0.5828593969 0.5536388159 + 0.5950301886 0.5837132931 0.5545309782 + 0.5958740115 0.5845609903 0.5554181933 + 0.5967167020 0.5854074955 0.5563042164 + 0.5975593925 0.5862538815 0.5571901202 + 0.5984022021 0.5871003866 0.5580760837 + 0.5992448926 0.5879467726 0.5589619875 + 0.6000844836 0.5887897015 0.5598490238 + 0.6009218097 0.5896298885 0.5607368946 + 0.6017590761 0.5904700756 0.5616248250 + 0.6025965214 0.5913102031 0.5625126958 + 0.6034337878 0.5921503901 0.5634006262 + 0.6042696834 0.5929887891 0.5642879009 + 0.6051009893 0.5938212872 0.5651726723 + 0.6059322953 0.5946537852 0.5660576224 + 0.6067636013 0.5954862833 0.5669425130 + 0.6075949073 0.5963187218 0.5678274035 + 0.6084262133 0.5971512198 0.5687121749 + 0.6092525721 0.5979760885 0.5695930719 + 0.6100782156 0.5987992883 0.5704730153 + 0.6109036803 0.5996224880 0.5713528991 + 0.6117292047 0.6004456878 0.5722327232 + 0.6125547886 0.6012688875 0.5731126070 + 0.6133785844 0.6020901203 0.5739895105 + 0.6141995192 0.6029073000 0.5748600960 + 0.6150202751 0.6037245989 0.5757306814 + 0.6158410907 0.6045418978 0.5766013265 + 0.6166620255 0.6053591967 0.5774719119 + 0.6174827814 0.6061763763 0.5783424973 + 0.6182973981 0.6069906950 0.5792120099 + 0.6191102862 0.6078041792 0.5800812840 + 0.6199231744 0.6086177230 0.5809506178 + 0.6207361817 0.6094312072 0.5818198919 + 0.6215491295 0.6102446914 0.5826891065 + 0.6223602295 0.6110575199 0.5835583806 + 0.6231619120 0.6118662953 0.5844280720 + 0.6239635944 0.6126750708 0.5852977037 + 0.6247653961 0.6134839058 0.5861672759 + 0.6255670786 0.6142926812 0.5870369077 + 0.6263688207 0.6151015162 0.5879064798 + 0.6271702051 0.6159092188 0.5887740254 + 0.6279712915 0.6167153120 0.5896387100 + 0.6287723780 0.6175215244 0.5905032754 + 0.6295735240 0.6183276176 0.5913679004 + 0.6303744912 0.6191337705 0.5922325850 + 0.6311755776 0.6199399233 0.5930972099 + 0.6319767833 0.6207464933 0.5939545035 + 0.6327779293 0.6215533018 0.5948076844 + 0.6335790753 0.6223601103 0.5956608057 + 0.6343802810 0.6231669188 0.5965139866 + 0.6351814866 0.6239737272 0.5973672271 + 0.6359826922 0.6247804761 0.5982202888 + 0.6367757916 0.6255866289 0.5990706086 + 0.6375672221 0.6263926029 0.5999200940 + 0.6383585930 0.6271985173 0.6007695794 + 0.6391499043 0.6280043721 0.6016191244 + 0.6399412751 0.6288104057 0.6024686098 + 0.6407327056 0.6296163201 0.6033179760 + 0.6415246129 0.6304203272 0.6041709185 + 0.6423165202 0.6312239766 0.6050243974 + 0.6431084275 0.6320276260 0.6058778763 + 0.6439003944 0.6328312755 0.6067314744 + 0.6446923018 0.6336349845 0.6075850129 + 0.6454842091 0.6344386935 0.6084384918 + 0.6462714076 0.6352415085 0.6092901230 + 0.6470577121 0.6360440850 0.6101412773 + 0.6478440166 0.6368467808 0.6109923720 + 0.6486303806 0.6376494169 0.6118435860 + 0.6494166851 0.6384519935 0.6126946807 + 0.6502029896 0.6392546892 0.6135458946 + 0.6509804726 0.6400555968 0.6143918037 + 0.6517549157 0.6408560276 0.6152355075 + 0.6525294185 0.6416562796 0.6160792112 + 0.6533038020 0.6424565911 0.6169229150 + 0.6540781856 0.6432569027 0.6177666187 + 0.6548526883 0.6440572739 0.6186103225 + 0.6556271911 0.6448554993 0.6194509268 + 0.6564018726 0.6456521153 0.6202887297 + 0.6571764946 0.6464486718 0.6211264729 + 0.6579511762 0.6472452879 0.6219642162 + 0.6587259173 0.6480419040 0.6228020191 + 0.6595004797 0.6488385201 0.6236398220 + 0.6602733731 0.6496348977 0.6244779825 + 0.6610416770 0.6504310966 0.6253173947 + 0.6618101001 0.6512271762 0.6261568069 + 0.6625784039 0.6520233750 0.6269962192 + 0.6633468270 0.6528195143 0.6278355718 + 0.6641150713 0.6536157131 0.6286749244 + 0.6648834944 0.6544117928 0.6295142770 + 0.6656407118 0.6552035809 0.6303495765 + 0.6663972139 0.6559950113 0.6311843991 + 0.6671535969 0.6567865014 0.6320192814 + 0.6679100990 0.6575778723 0.6328541040 + 0.6686664820 0.6583693027 0.6336889267 + 0.6694229841 0.6591607928 0.6345236897 + 0.6701784730 0.6599478722 0.6353541017 + 0.6709331274 0.6607304215 0.6361792088 + 0.6716876030 0.6615129113 0.6370043159 + 0.6724421978 0.6622954011 0.6378294230 + 0.6731967926 0.6630778909 0.6386544704 + 0.6739513278 0.6638603210 0.6394795775 + 0.6747059226 0.6646428108 0.6403046846 + 0.6754562259 0.6654220223 0.6411225200 + 0.6762061715 0.6662008762 0.6419395804 + 0.6769562960 0.6669799089 0.6427568197 + 0.6777064204 0.6677588820 0.6435738802 + 0.6784564257 0.6685379148 0.6443911195 + 0.6792064905 0.6693168283 0.6452081800 + 0.6799539924 0.6700953245 0.6460253000 + 0.6806966066 0.6708728075 0.6468420029 + 0.6814391017 0.6716501713 0.6476588249 + 0.6821817160 0.6724277139 0.6484755278 + 0.6829242706 0.6732050776 0.6492922902 + 0.6836668253 0.6739826202 0.6501089931 + 0.6844093800 0.6747599840 0.6509258151 + 0.6851518154 0.6755318046 0.6517397165 + 0.6858941913 0.6762999892 0.6525517702 + 0.6866366267 0.6770682931 0.6533638239 + 0.6873788834 0.6778365970 0.6541758180 + 0.6881213188 0.6786047816 0.6549878716 + 0.6888636947 0.6793730855 0.6557999253 + 0.6896060705 0.6801413894 0.6566119194 + 0.6903458238 0.6809049249 0.6574186087 + 0.6910849214 0.6816673875 0.6582239866 + 0.6918240786 0.6824299097 0.6590293050 + 0.6925632954 0.6831923723 0.6598346829 + 0.6933023930 0.6839548945 0.6606400013 + 0.6940416098 0.6847174168 0.6614453793 + 0.6947807074 0.6854798794 0.6622506976 + 0.6955140829 0.6862388253 0.6630463004 + 0.6962471008 0.6869974136 0.6638408899 + 0.6969801188 0.6877560019 0.6646354795 + 0.6977130771 0.6885147095 0.6654301882 + 0.6984460950 0.6892732978 0.6662247777 + 0.6991791129 0.6900318861 0.6670194268 + 0.6999120116 0.6907905936 0.6678140163 + 0.7006403208 0.6915383935 0.6686055064 + 0.7013683915 0.6922855973 0.6693965793 + 0.7020965219 0.6930328012 0.6701877713 + 0.7028244734 0.6937800050 0.6709790230 + 0.7035526037 0.6945272088 0.6717702150 + 0.7042806745 0.6952744126 0.6725614071 + 0.7050086856 0.6960216165 0.6733525991 + 0.7057327032 0.6967638135 0.6741454005 + 0.7064561248 0.6975051165 0.6749384999 + 0.7071794868 0.6982464194 0.6757315993 + 0.7079027891 0.6989877820 0.6765246987 + 0.7086262107 0.6997290850 0.6773177981 + 0.7093495727 0.7004703879 0.6781108975 + 0.7100729942 0.7012118101 0.6789039969 + 0.7107927203 0.7019538879 0.6796910167 + 0.7115108967 0.7026965022 0.6804748774 + 0.7122290134 0.7034389973 0.6812587976 + 0.7129471898 0.7041814923 0.6820427775 + 0.7136653066 0.7049241066 0.6828266978 + 0.7143834829 0.7056666017 0.6836106181 + 0.7151015997 0.7064090967 0.6843945980 + 0.7158182263 0.7071503997 0.6851742268 + 0.7165327072 0.7078899145 0.6859470010 + 0.7172471285 0.7086293101 0.6867198944 + 0.7179616094 0.7093688250 0.6874927282 + 0.7186759710 0.7101082206 0.6882656217 + 0.7193905115 0.7108476758 0.6890385151 + 0.7201048732 0.7115870714 0.6898112893 + 0.7208188772 0.7123262882 0.6905841231 + 0.7215241194 0.7130588889 0.6913529038 + 0.7222291827 0.7137916088 0.6921218038 + 0.7229344249 0.7145242095 0.6928905845 + 0.7236396074 0.7152568102 0.6936594248 + 0.7243446708 0.7159894109 0.6944282055 + 0.7250499129 0.7167220712 0.6951969862 + 0.7257549763 0.7174546719 0.6959658861 + 0.7264562845 0.7181851268 0.6967344284 + 0.7271547914 0.7189137936 0.6975026131 + 0.7278531790 0.7196425796 0.6982707977 + 0.7285516262 0.7203713059 0.6990389824 + 0.7292500734 0.7210999727 0.6998072267 + 0.7299485207 0.7218288183 0.7005754113 + 0.7306470275 0.7225574851 0.7013435960 + 0.7313454151 0.7232862115 0.7021117806 + 0.7320457101 0.7240095735 0.7028660774 + 0.7327460051 0.7247328758 0.7036200762 + 0.7334461808 0.7254562974 0.7043740153 + 0.7341464758 0.7261795998 0.7051280141 + 0.7348467708 0.7269030213 0.7058818936 + 0.7355470061 0.7276263237 0.7066358924 + 0.7362473011 0.7283496857 0.7073897719 + 0.7369453907 0.7290710211 0.7081403732 + 0.7376388907 0.7297881246 0.7088832259 + 0.7383323908 0.7305051088 0.7096260190 + 0.7390258908 0.7312222123 0.7103686929 + 0.7397195101 0.7319391966 0.7111114860 + 0.7404130101 0.7326561809 0.7118542194 + 0.7411065102 0.7333732843 0.7125970125 + 0.7418000102 0.7340903282 0.7133396864 + 0.7424902916 0.7348045707 0.7140802741 + 0.7431777716 0.7355164289 0.7148187757 + 0.7438653708 0.7362282276 0.7155572176 + 0.7445529103 0.7369400263 0.7162957191 + 0.7452403903 0.7376518250 0.7170342207 + 0.7459279895 0.7383636832 0.7177727222 + 0.7466155291 0.7390754819 0.7185112238 + 0.7473030090 0.7397872806 0.7192496061 + 0.7479922771 0.7404950857 0.7199897766 + 0.7486823797 0.7412006855 0.7207309008 + 0.7493724227 0.7419062853 0.7214720249 + 0.7500625253 0.7426118851 0.7222132087 + 0.7507526278 0.7433174849 0.7229542732 + 0.7514426708 0.7440230846 0.7236953974 + 0.7521327734 0.7447286844 0.7244365215 + 0.7528228760 0.7454342842 0.7251777053 + 0.7535089850 0.7461348772 0.7259193063 + 0.7541931868 0.7468327880 0.7266612053 + 0.7548773885 0.7475308180 0.7274032235 + 0.7555614710 0.7482287288 0.7281451225 + 0.7562456727 0.7489265800 0.7288870215 + 0.7569298744 0.7496244907 0.7296289802 + 0.7576140165 0.7503225207 0.7303708792 + 0.7582982183 0.7510203719 0.7311127782 + 0.7589793801 0.7517145872 0.7318496704 + 0.7596583962 0.7524058223 0.7325822115 + 0.7603374124 0.7530969977 0.7333146930 + 0.7610164285 0.7537881732 0.7340471148 + 0.7616953254 0.7544794083 0.7347795963 + 0.7623742819 0.7551705837 0.7355120778 + 0.7630532980 0.7558618188 0.7362444997 + 0.7637323141 0.7565529943 0.7369769812 + 0.7644116879 0.7572417259 0.7377079725 + 0.7650921941 0.7579252720 0.7384359241 + 0.7657725811 0.7586089969 0.7391638756 + 0.7664530277 0.7592927217 0.7398918271 + 0.7671334147 0.7599763274 0.7406197190 + 0.7678138018 0.7606599927 0.7413476110 + 0.7684941888 0.7613437176 0.7420756221 + 0.7691746950 0.7620273232 0.7428035140 + 0.7698547840 0.7627109885 0.7435314059 + 0.7705252171 0.7633913159 0.7442615032 + 0.7711957097 0.7640715837 0.7449914813 + 0.7718660831 0.7647519708 0.7457215190 + 0.7725365162 0.7654322982 0.7464514971 + 0.7732068896 0.7661126852 0.7471815944 + 0.7738773227 0.7667930126 0.7479115725 + 0.7745476961 0.7674732804 0.7486416101 + 0.7752181292 0.7681537271 0.7493717074 + 0.7758864760 0.7688329220 0.7501016855 + 0.7765535116 0.7695114017 0.7508317232 + 0.7772204876 0.7701898217 0.7515617013 + 0.7778875232 0.7708683014 0.7522916794 + 0.7785544991 0.7715467215 0.7530217767 + 0.7792214155 0.7722252011 0.7537518144 + 0.7798883915 0.7729036212 0.7544817924 + 0.7805554271 0.7735821009 0.7552117705 + 0.7812224030 0.7742605805 0.7559416890 + 0.7818884850 0.7749400735 0.7566617131 + 0.7825545073 0.7756196856 0.7573816776 + 0.7832205892 0.7762991786 0.7581015825 + 0.7838866711 0.7769787908 0.7588216066 + 0.7845528126 0.7776582837 0.7595415711 + 0.7852188945 0.7783377767 0.7602615952 + 0.7858849764 0.7790173888 0.7609816194 + 0.7865511179 0.7796968818 0.7617015839 + 0.7872148752 0.7803745866 0.7624198198 + 0.7878748178 0.7810488939 0.7631347179 + 0.7885347009 0.7817232013 0.7638494968 + 0.7891945839 0.7823975086 0.7645643950 + 0.7898545265 0.7830718756 0.7652792931 + 0.7905144095 0.7837461829 0.7659941912 + 0.7911742926 0.7844204903 0.7667090893 + 0.7918342948 0.7850949168 0.7674239278 + 0.7924941778 0.7857692242 0.7681388259 + 0.7931510806 0.7864413261 0.7688534856 + 0.7938057780 0.7871118188 0.7695679069 + 0.7944605947 0.7877823114 0.7702823877 + 0.7951152921 0.7884528041 0.7709968090 + 0.7957701087 0.7891234159 0.7717112899 + 0.7964249253 0.7897939086 0.7724257112 + 0.7970796227 0.7904644012 0.7731400728 + 0.7977343798 0.7911348939 0.7738546133 + 0.7983890772 0.7918053865 0.7745689750 + 0.7990390062 0.7924752831 0.7752832174 + 0.7996864915 0.7931450009 0.7759972811 + 0.8003339767 0.7938145995 0.7767112851 + 0.8009815216 0.7944843173 0.7774252892 + 0.8016290069 0.7951539159 0.7781392932 + 0.8022764921 0.7958235741 0.7788534164 + 0.8029239774 0.7964931726 0.7795674205 + 0.8035715222 0.7971628904 0.7802814245 + 0.8042190075 0.7978324890 0.7809954882 + 0.8048598766 0.7984976172 0.7817047834 + 0.8054972887 0.7991601825 0.7824113965 + 0.8061345816 0.7998228073 0.7831178904 + 0.8067719936 0.8004853725 0.7838245034 + 0.8074094057 0.8011479974 0.7845311165 + 0.8080468178 0.8018106222 0.7852376103 + 0.8086841106 0.8024731874 0.7859442234 + 0.8093215227 0.8031358123 0.7866507769 + 0.8099588752 0.8037983775 0.7873573899 + 0.8105943203 0.8044582009 0.7880617976 + 0.8112279177 0.8051152229 0.7887639999 + 0.8118613958 0.8057723045 0.7894663215 + 0.8124949932 0.8064293265 0.7901685238 + 0.8131284714 0.8070862889 0.7908707261 + 0.8137621284 0.8077433109 0.7915729880 + 0.8143956065 0.8084002733 0.7922751904 + 0.8150292039 0.8090572953 0.7929773927 + 0.8156626821 0.8097143769 0.7936797142 + 0.8162947893 0.8103706837 0.7943819761 + 0.8169224262 0.8110250235 0.7950844765 + 0.8175500035 0.8116793036 0.7957870960 + 0.8181775808 0.8123335838 0.7964897156 + 0.8188052177 0.8129879236 0.7971922755 + 0.8194326758 0.8136422038 0.7978948951 + 0.8200603127 0.8142964244 0.7985973954 + 0.8206878901 0.8149507046 0.7993000150 + 0.8213155270 0.8156049848 0.8000025749 + 0.8219431043 0.8162593246 0.8007051945 + 0.8225635290 0.8169105053 0.8014042974 + 0.8231825829 0.8175610900 0.8021026254 + 0.8238015771 0.8182116747 0.8028008938 + 0.8244206905 0.8188623190 0.8034992814 + 0.8250398040 0.8195129037 0.8041976094 + 0.8256589174 0.8201634884 0.8048958778 + 0.8262779117 0.8208140731 0.8055942059 + 0.8268970251 0.8214647174 0.8062925935 + 0.8275160789 0.8221153021 0.8069909215 + 0.8281350136 0.8227658272 0.8076866269 + 0.8287534714 0.8234161139 0.8083760738 + 0.8293719888 0.8240664005 0.8090655804 + 0.8299906254 0.8247166872 0.8097550869 + 0.8306090832 0.8253669739 0.8104445934 + 0.8312276006 0.8260173798 0.8111341000 + 0.8318461776 0.8266677260 0.8118236065 + 0.8324646950 0.8273180127 0.8125131130 + 0.8330832124 0.8279682994 0.8132026196 + 0.8337017298 0.8286185861 0.8138921261 + 0.8343204260 0.8292688131 0.8145787716 + 0.8349391818 0.8299189210 0.8152639866 + 0.8355578780 0.8305690289 0.8159490824 + 0.8361766934 0.8312191963 0.8166342974 + 0.8367953897 0.8318693042 0.8173193932 + 0.8374142051 0.8325194716 0.8180044889 + 0.8380329013 0.8331695795 0.8186897039 + 0.8386517167 0.8338196874 0.8193747997 + 0.8392704129 0.8344699144 0.8200598955 + 0.8398892283 0.8351200223 0.8207451105 + 0.8405013084 0.8357700706 0.8214318156 + 0.8411123753 0.8364201188 0.8221188188 + 0.8417235017 0.8370702267 0.8228058219 + 0.8423346281 0.8377202749 0.8234927058 + 0.8429456949 0.8383703232 0.8241797090 + 0.8435568213 0.8390203714 0.8248667121 + 0.8441678882 0.8396704197 0.8255537152 + 0.8447790146 0.8403205276 0.8262405992 + 0.8453900814 0.8409705162 0.8269276023 + 0.8460012078 0.8416206241 0.8276146054 + 0.8466123939 0.8422645926 0.8282997012 + 0.8472235799 0.8429083228 0.8289846778 + 0.8478348255 0.8435521126 0.8296697140 + 0.8484458923 0.8441957831 0.8303546906 + 0.8490570784 0.8448395133 0.8310397267 + 0.8496683240 0.8454831839 0.8317247033 + 0.8502795100 0.8461269736 0.8324096799 + 0.8508906960 0.8467707038 0.8330947161 + 0.8515018821 0.8474143744 0.8337796926 + 0.8521130085 0.8480581045 0.8344647288 + 0.8527246714 0.8486986756 0.8351467848 + 0.8533365130 0.8493388295 0.8358284831 + 0.8539482951 0.8499789834 0.8365101814 + 0.8545600176 0.8506191969 0.8371918797 + 0.8551717997 0.8512594104 0.8378735781 + 0.8557835817 0.8518995047 0.8385552764 + 0.8563953042 0.8525397182 0.8392369151 + 0.8570070863 0.8531798720 0.8399186134 + 0.8576189280 0.8538200259 0.8406003118 + 0.8582305908 0.8544601798 0.8412820101 + 0.8588374257 0.8550989032 0.8419591784 + 0.8594421744 0.8557369709 0.8426344991 + 0.8600469828 0.8563752174 0.8433098197 + 0.8606517911 0.8570132852 0.8439850211 + 0.8612565994 0.8576514125 0.8446602821 + 0.8618612885 0.8582894802 0.8453356028 + 0.8624660969 0.8589276075 0.8460108042 + 0.8630709052 0.8595656753 0.8466861248 + 0.8636757135 0.8602039218 0.8473613858 + 0.8642805219 0.8608419895 0.8480365872 + 0.8648855090 0.8614770174 0.8487117887 + 0.8654909730 0.8621069193 0.8493868113 + 0.8660963774 0.8627368212 0.8500617146 + 0.8667019010 0.8633667231 0.8507366776 + 0.8673073053 0.8639966249 0.8514117002 + 0.8679128289 0.8646265268 0.8520867229 + 0.8685181737 0.8652564287 0.8527616262 + 0.8691236973 0.8658862710 0.8534365892 + 0.8697291017 0.8665162921 0.8541116118 + 0.8703346252 0.8671461940 0.8547865152 + 0.8709400296 0.8677760959 0.8554614782 + 0.8715463281 0.8684011102 0.8561388254 + 0.8721526861 0.8690257072 0.8568162918 + 0.8727591038 0.8696503043 0.8574938178 + 0.8733655214 0.8702749014 0.8581712842 + 0.8739719987 0.8708994985 0.8588488102 + 0.8745784163 0.8715240955 0.8595262766 + 0.8751847744 0.8721486926 0.8602038026 + 0.8757911921 0.8727732897 0.8608813286 + 0.8763976097 0.8733978868 0.8615587950 + 0.8770040274 0.8740224242 0.8622363210 + 0.8776084781 0.8746458292 0.8629111052 + 0.8782086968 0.8752664924 0.8635792732 + 0.8788089752 0.8758872151 0.8642475009 + 0.8794091940 0.8765078187 0.8649157286 + 0.8800094724 0.8771284819 0.8655838966 + 0.8806096911 0.8777492046 0.8662521243 + 0.8812100291 0.8783698082 0.8669202924 + 0.8818103075 0.8789904714 0.8675885201 + 0.8824105263 0.8796111941 0.8682566881 + 0.8830108047 0.8802317977 0.8689249158 + 0.8836110234 0.8808525205 0.8695930839 + 0.8842111826 0.8814677000 0.8702577949 + 0.8848112822 0.8820785880 0.8709195852 + 0.8854113817 0.8826894164 0.8715813160 + 0.8860116005 0.8833001852 0.8722429872 + 0.8866117001 0.8839110136 0.8729047775 + 0.8872117996 0.8845217824 0.8735665083 + 0.8878118992 0.8851326108 0.8742281795 + 0.8884119987 0.8857433796 0.8748900294 + 0.8890120983 0.8863543272 0.8755517006 + 0.8896123171 0.8869650960 0.8762133718 + 0.8902124166 0.8875759244 0.8768752217 + 0.8908076882 0.8881832957 0.8775365949 + 0.8914005160 0.8887888193 0.8781977892 + 0.8919934034 0.8893944025 0.8788589835 + 0.8925861716 0.8899999857 0.8795201778 + 0.8931789994 0.8906055093 0.8801813722 + 0.8937718272 0.8912110925 0.8808426261 + 0.8943647146 0.8918166757 0.8815038204 + 0.8949574828 0.8924221992 0.8821650147 + 0.8955503106 0.8930277824 0.8828263283 + 0.8961430788 0.8936333060 0.8834875226 + 0.8967359066 0.8942388892 0.8841487169 + 0.8973246217 0.8948436975 0.8848111033 + 0.8979104757 0.8954480290 0.8854743838 + 0.8984965086 0.8960524201 0.8861377835 + 0.8990824223 0.8966566920 0.8868011236 + 0.8996682763 0.8972610235 0.8874644041 + 0.9002543092 0.8978654146 0.8881276846 + 0.9008402228 0.8984696865 0.8887910247 + 0.9014261961 0.8990740180 0.8894543052 + 0.9020121098 0.8996782899 0.8901175857 + 0.9025980234 0.9002826810 0.8907809258 + 0.9031839967 0.9008870125 0.8914443254 + 0.9037700891 0.9014902115 0.8921037912 + 0.9043565989 0.9020918012 0.8927577138 + 0.9049429893 0.9026933908 0.8934116960 + 0.9055293798 0.9032949805 0.8940656185 + 0.9061157703 0.9038965702 0.8947194815 + 0.9067022800 0.9044982195 0.8953734040 + 0.9072886705 0.9050998092 0.8960273266 + 0.9078751206 0.9057013988 0.8966811895 + 0.9084615707 0.9063029885 0.8973351121 + 0.9090480208 0.9069045782 0.8979889750 + 0.9096344113 0.9075062275 0.8986428976 + 0.9102206826 0.9081075191 0.8992965221 + 0.9108051062 0.9087041020 0.8999441266 + 0.9113894105 0.9093006849 0.9005916119 + 0.9119737744 0.9098973274 0.9012390971 + 0.9125580788 0.9104939103 0.9018865824 + 0.9131425023 0.9110904932 0.9025341868 + 0.9137269258 0.9116870761 0.9031816721 + 0.9143111706 0.9122837186 0.9038292170 + 0.9148955941 0.9128803015 0.9044768214 + 0.9154798985 0.9134768844 0.9051243067 + 0.9160643220 0.9140735269 0.9057717919 + 0.9166486263 0.9146699905 0.9064192772 + 0.9172297716 0.9152629972 0.9070658088 + 0.9178082943 0.9158529043 0.9077115059 + 0.9183868766 0.9164428711 0.9083572030 + 0.9189653993 0.9170327783 0.9090027809 + 0.9195439816 0.9176228046 0.9096484780 + 0.9201225042 0.9182127118 0.9102941155 + 0.9207010865 0.9188026786 0.9109398127 + 0.9212796092 0.9193927050 0.9115853906 + 0.9218580723 0.9199826121 0.9122310877 + 0.9224367142 0.9205725789 0.9128767252 + 0.9230151772 0.9211624861 0.9135224223 + 0.9235938191 0.9217525125 0.9141680002 + 0.9241641760 0.9223377109 0.9148079753 + 0.9247336984 0.9229223728 0.9154471159 + 0.9253032207 0.9235070944 0.9160863161 + 0.9258726239 0.9240918159 0.9167255163 + 0.9264420867 0.9246764183 0.9173647165 + 0.9270116091 0.9252610803 0.9180039167 + 0.9275810719 0.9258458018 0.9186431170 + 0.9281504750 0.9264305234 0.9192823172 + 0.9287199974 0.9270151854 0.9199213982 + 0.9292895198 0.9275997877 0.9205605984 + 0.9298589826 0.9281845093 0.9211997986 + 0.9304273725 0.9287682176 0.9218379855 + 0.9309837222 0.9293403029 0.9224632978 + 0.9315400124 0.9299123883 0.9230884910 + 0.9320963025 0.9304844737 0.9237136841 + 0.9326524734 0.9310566187 0.9243389964 + 0.9332088232 0.9316285849 0.9249641895 + 0.9337651134 0.9322006702 0.9255895019 + 0.9343214035 0.9327728152 0.9262146950 + 0.9348776937 0.9333449006 0.9268398881 + 0.9354339242 0.9339169860 0.9274652004 + 0.9359902143 0.9344890118 0.9280903935 + 0.9365465045 0.9350610971 0.9287157059 + 0.9371017814 0.9356322885 0.9293395877 + 0.9376482964 0.9361947179 0.9299502969 + 0.9381946921 0.9367572069 0.9305610061 + 0.9387412071 0.9373196959 0.9311717153 + 0.9392877221 0.9378821254 0.9317824244 + 0.9398341775 0.9384446144 0.9323930740 + 0.9403805733 0.9390071034 0.9330037832 + 0.9409270883 0.9395694733 0.9336146116 + 0.9414736032 0.9401320219 0.9342253208 + 0.9420201182 0.9406945109 0.9348359704 + 0.9425665140 0.9412570000 0.9354466796 + 0.9431130290 0.9418194294 0.9360573888 + 0.9436594844 0.9423819184 0.9366680980 + 0.9441972971 0.9429398775 0.9372712970 + 0.9447346926 0.9434977174 0.9378741980 + 0.9452720881 0.9440554976 0.9384769797 + 0.9458096027 0.9446132779 0.9390798807 + 0.9463469982 0.9451711178 0.9396827221 + 0.9468843937 0.9457287788 0.9402856231 + 0.9474219084 0.9462866187 0.9408884048 + 0.9479593039 0.9468443990 0.9414913058 + 0.9484966993 0.9474021792 0.9420940876 + 0.9490342140 0.9479600191 0.9426969290 + 0.9495716095 0.9485177994 0.9432997704 + 0.9501090050 0.9490755796 0.9439026117 + 0.9506387115 0.9496260285 0.9444972873 + 0.9511643052 0.9501724839 0.9450876117 + 0.9516900182 0.9507189989 0.9456778765 + 0.9522156119 0.9512655139 0.9462682009 + 0.9527412057 0.9518120289 0.9468585253 + 0.9532667994 0.9523584843 0.9474487901 + 0.9537923932 0.9529049993 0.9480391145 + 0.9543179870 0.9534515142 0.9486293197 + 0.9548435807 0.9539980292 0.9492195845 + 0.9553691745 0.9545444846 0.9498099089 + 0.9558948278 0.9550909996 0.9504001737 + 0.9564204216 0.9556375146 0.9509904981 + 0.9569442272 0.9561818838 0.9515780210 + 0.9574593902 0.9567170143 0.9521524906 + 0.9579746127 0.9572520852 0.9527270198 + 0.9584897757 0.9577872157 0.9533016086 + 0.9590049982 0.9583222866 0.9538760781 + 0.9595202208 0.9588574171 0.9544506073 + 0.9600353837 0.9593924880 0.9550250769 + 0.9605506063 0.9599276185 0.9555996060 + 0.9610658288 0.9604626298 0.9561740756 + 0.9615809917 0.9609977007 0.9567486048 + 0.9620962143 0.9615327716 0.9573231936 + 0.9626114964 0.9620679021 0.9578977227 + 0.9631267190 0.9626029730 0.9584721923 + 0.9636358023 0.9631323218 0.9590396285 + 0.9641396999 0.9636566043 0.9596006870 + 0.9646437168 0.9641808867 0.9601618052 + 0.9651476145 0.9647052288 0.9607229829 + 0.9656515121 0.9652295113 0.9612841010 + 0.9661555290 0.9657537937 0.9618452787 + 0.9666594267 0.9662780762 0.9624063969 + 0.9671633244 0.9668024182 0.9629675150 + 0.9676672816 0.9673267007 0.9635286927 + 0.9681711793 0.9678509831 0.9640898108 + 0.9686750770 0.9683753252 0.9646509886 + 0.9691790938 0.9688996077 0.9652121067 + 0.9696829915 0.9694238901 0.9657732248 + 0.9701765180 0.9699373245 0.9663273096 + 0.9706659913 0.9704464078 0.9668784738 + 0.9711555243 0.9709556103 0.9674296975 + 0.9716449976 0.9714648128 0.9679809809 + 0.9721345901 0.9719740152 0.9685322046 + 0.9726241231 0.9724830985 0.9690834880 + 0.9731135964 0.9729923010 0.9696347117 + 0.9736031294 0.9735015035 0.9701858759 + 0.9740926027 0.9740107059 0.9707372189 + 0.9745820761 0.9745197892 0.9712883830 + 0.9750717282 0.9750289917 0.9718397260 + 0.9755612016 0.9755381942 0.9723908901 + 0.9760506749 0.9760473967 0.9729421139 + 0.9765306115 0.9765431881 0.9734861851 + 0.9770072103 0.9770342112 0.9740275145 + 0.9774836898 0.9775252938 0.9745689034 + 0.9779602885 0.9780163765 0.9751102924 + 0.9784368277 0.9785073996 0.9756516814 + 0.9789134264 0.9789984822 0.9761930704 + 0.9793899059 0.9794895053 0.9767343998 + 0.9798665047 0.9799805880 0.9772757888 + 0.9803431034 0.9804716110 0.9778171778 + 0.9808195829 0.9809626937 0.9783586264 + 0.9812961817 0.9814537764 0.9789000154 + 0.9817727208 0.9819447994 0.9794412851 + 0.9822493196 0.9824358821 0.9799826741 + 0.9827123284 0.9829128981 0.9805108905 + 0.9831652045 0.9833794236 0.9810290933 + 0.9836181998 0.9838458896 0.9815472960 + 0.9840711951 0.9843124151 0.9820654988 + 0.9845240712 0.9847788811 0.9825838208 + 0.9849771261 0.9852454066 0.9831020236 + 0.9854301214 0.9857119918 0.9836202264 + 0.9858829975 0.9861785173 0.9841384292 + 0.9863359928 0.9866449833 0.9846565723 + 0.9867889881 0.9871115088 0.9851748943 + 0.9872419238 0.9875779748 0.9856930971 + 0.9876949191 0.9880445004 0.9862112999 + 0.9881477952 0.9885110855 0.9867295027 + 0.9885957837 0.9889689088 0.9872413278 + 0.9890270829 0.9893978834 0.9877312779 + 0.9894583821 0.9898269176 0.9882212877 + 0.9898896813 0.9902558923 0.9887112975 + 0.9903209805 0.9906849265 0.9892013073 + 0.9907522798 0.9911139011 0.9896913171 + 0.9911835790 0.9915428758 0.9901813269 + 0.9916148782 0.9919719100 0.9906713963 + 0.9920461774 0.9924008846 0.9911614060 + 0.9924774766 0.9928299189 0.9916514158 + 0.9929087758 0.9932588935 0.9921414256 + 0.9933400750 0.9936879277 0.9926313758 + 0.9937713742 0.9941169024 0.9931213856 + 0.9942026734 0.9945458770 0.9936113954 + 0.9946215749 0.9949464798 0.9940770864 + 0.9950352907 0.9953352213 0.9945327044 + 0.9954490066 0.9957239032 0.9949883223 + 0.9958627224 0.9961127043 0.9954438806 + 0.9962764978 0.9965013862 0.9958994985 + 0.9966902137 0.9968901277 0.9963551760 + 0.9971039295 0.9972789288 0.9968107939 + 0.9975175858 0.9976676106 0.9972664118 + 0.9979314208 0.9980562925 0.9977220297 + 0.9983450770 0.9984450936 0.9981775880 + 0.9987587929 0.9988337755 0.9986332059 + 0.9991725087 0.9992225170 0.9990888238 + 0.9995862842 0.9996113181 0.9995443821 + 1.0000000000 1.0000000000 1.0000000000 +} diff --git a/rpplugins/color_correction/resources/film_luts_raw/kodak_portra_160vc.spi1d b/rpplugins/color_correction/resources/film_luts_raw/kodak_portra_160vc.spi1d new file mode 100644 index 0000000..1025144 --- /dev/null +++ b/rpplugins/color_correction/resources/film_luts_raw/kodak_portra_160vc.spi1d @@ -0,0 +1,1030 @@ +Version 1 +From 0.0 1.0 +Length 1024 +Components 3 +{ + 0.0000000000 0.0000000000 0.0000000000 + 0.0077699851 0.0072091222 0.0057455739 + 0.0153281903 0.0140618198 0.0110133700 + 0.0220492706 0.0201340895 0.0156183802 + 0.0279948898 0.0255677104 0.0198130608 + 0.0334264189 0.0305160508 0.0236329101 + 0.0383813009 0.0350662991 0.0272729397 + 0.0430751182 0.0393643305 0.0306853205 + 0.0474476218 0.0434310399 0.0339677408 + 0.0515641496 0.0472853705 0.0371497907 + 0.0555446185 0.0509948209 0.0402266905 + 0.0594275706 0.0545908697 0.0432020612 + 0.0631866604 0.0580725186 0.0460699908 + 0.0668074489 0.0614085086 0.0488363616 + 0.0702805966 0.0646550804 0.0515515506 + 0.0736529976 0.0678500831 0.0542215705 + 0.0769146830 0.0709684193 0.0568457693 + 0.0801084563 0.0739683583 0.0594256707 + 0.0832033977 0.0768856406 0.0619675815 + 0.0862210765 0.0797707886 0.0644541681 + 0.0891883075 0.0826155171 0.0668781176 + 0.0921097621 0.0853902176 0.0692649484 + 0.0950033367 0.0881099030 0.0716069788 + 0.0978709385 0.0907903165 0.0739388466 + 0.1006767005 0.0934374928 0.0762372017 + 0.1034490988 0.0960375518 0.0785102323 + 0.1061699986 0.0985936001 0.0807417631 + 0.1088621020 0.1011143997 0.0829524100 + 0.1115100011 0.1035860032 0.0851420909 + 0.1141035035 0.1060298979 0.0873048082 + 0.1166575998 0.1084465012 0.0894576833 + 0.1191660017 0.1108224019 0.0915750787 + 0.1216190010 0.1131646037 0.0936675370 + 0.1240210012 0.1154721975 0.0957391188 + 0.1263785958 0.1177325025 0.0977701619 + 0.1287032962 0.1199773997 0.0997919589 + 0.1309965998 0.1222233996 0.1018017009 + 0.1332729012 0.1244523004 0.1037892997 + 0.1355164945 0.1266828030 0.1057759970 + 0.1377673000 0.1288989931 0.1077485010 + 0.1400064975 0.1310786009 0.1096967012 + 0.1422519982 0.1332331002 0.1116394028 + 0.1444955021 0.1353804022 0.1135682017 + 0.1467241049 0.1374987066 0.1154882982 + 0.1489524990 0.1396068931 0.1173892990 + 0.1511590034 0.1416790038 0.1192753017 + 0.1533526033 0.1437290013 0.1211493984 + 0.1555102021 0.1457712948 0.1229984984 + 0.1576402932 0.1477762014 0.1248319969 + 0.1597459018 0.1497581005 0.1266517043 + 0.1618217975 0.1517187059 0.1284562945 + 0.1638692021 0.1536567956 0.1302371025 + 0.1658921987 0.1555901021 0.1320014000 + 0.1678850949 0.1574811935 0.1337444037 + 0.1698528975 0.1593548954 0.1354825944 + 0.1718069017 0.1612353027 0.1372071058 + 0.1737360060 0.1631090939 0.1389127970 + 0.1756428927 0.1649706960 0.1406110972 + 0.1775456071 0.1668394953 0.1423041970 + 0.1794250011 0.1687040031 0.1439954042 + 0.1812936962 0.1705541015 0.1456899941 + 0.1831597984 0.1724057049 0.1473833025 + 0.1850039065 0.1742419004 0.1490696967 + 0.1868477017 0.1760638058 0.1507641971 + 0.1886914074 0.1778782010 0.1524640024 + 0.1905229986 0.1796796024 0.1541469991 + 0.1923421025 0.1814686954 0.1558177024 + 0.1941601038 0.1832399964 0.1574839056 + 0.1959781945 0.1850111932 0.1591470987 + 0.1978068054 0.1867780983 0.1608041972 + 0.1996330023 0.1885201037 0.1624432057 + 0.2014473975 0.1902448982 0.1640713960 + 0.2032514960 0.1919703931 0.1656913012 + 0.2050576061 0.1936956942 0.1672880948 + 0.2068455070 0.1953990012 0.1688698977 + 0.2086115927 0.1970870048 0.1704351008 + 0.2103770971 0.1987718940 0.1719868034 + 0.2121285051 0.2004460990 0.1735249013 + 0.2138638943 0.2020982951 0.1750528961 + 0.2155895978 0.2037346959 0.1765847057 + 0.2173081934 0.2053682953 0.1781219989 + 0.2190068960 0.2069963962 0.1796503961 + 0.2206840962 0.2086153030 0.1811677068 + 0.2223511040 0.2102248967 0.1826826036 + 0.2240124047 0.2118259966 0.1841962934 + 0.2256612033 0.2134266943 0.1857064962 + 0.2272907943 0.2150333971 0.1872134954 + 0.2289057970 0.2166189998 0.1887131035 + 0.2305078059 0.2181905061 0.1902053952 + 0.2321005017 0.2197569013 0.1916909963 + 0.2336920053 0.2213245928 0.1931720972 + 0.2352899015 0.2228953987 0.1946519017 + 0.2368838936 0.2244486064 0.1961286962 + 0.2384622991 0.2259978950 0.1976062059 + 0.2400310934 0.2275449038 0.1990849972 + 0.2415942997 0.2290931940 0.2005598992 + 0.2431554943 0.2306476980 0.2020221055 + 0.2447042018 0.2321884036 0.2034724057 + 0.2462362051 0.2337166965 0.2049137056 + 0.2477615029 0.2352366000 0.2063475996 + 0.2492882013 0.2367514074 0.2077756971 + 0.2508074939 0.2382549047 0.2092022002 + 0.2523134053 0.2397526950 0.2106287032 + 0.2538112998 0.2412422001 0.2120527029 + 0.2553072870 0.2427164018 0.2134691030 + 0.2568025887 0.2441851944 0.2148848027 + 0.2582916915 0.2456547022 0.2162963003 + 0.2597728968 0.2471264005 0.2177021056 + 0.2612324953 0.2485917062 0.2190997005 + 0.2626926899 0.2500481904 0.2204964012 + 0.2641533017 0.2514964044 0.2218922973 + 0.2656058967 0.2529383004 0.2232878953 + 0.2670469880 0.2543821037 0.2246783972 + 0.2684782147 0.2558273077 0.2260642052 + 0.2699055076 0.2572557926 0.2274404019 + 0.2713302076 0.2586747110 0.2288105041 + 0.2727521956 0.2600823939 0.2301730961 + 0.2741548121 0.2614834905 0.2315272987 + 0.2755548060 0.2628856003 0.2328795046 + 0.2769533098 0.2642917037 0.2342298031 + 0.2783550918 0.2656919062 0.2355791926 + 0.2797575891 0.2670885921 0.2369273007 + 0.2811529040 0.2684741020 0.2382656932 + 0.2825410068 0.2698574066 0.2396034002 + 0.2839199007 0.2712377012 0.2409401983 + 0.2853043079 0.2726213932 0.2422693074 + 0.2866902053 0.2740063071 0.2435951978 + 0.2880729139 0.2753944993 0.2449122965 + 0.2894502878 0.2767789960 0.2462285012 + 0.2908177972 0.2781563997 0.2475429028 + 0.2921772897 0.2795270979 0.2488564998 + 0.2935316861 0.2808933854 0.2501694858 + 0.2948884964 0.2822520137 0.2514741123 + 0.2962454855 0.2836092114 0.2527768016 + 0.2975969017 0.2849698961 0.2540780902 + 0.2989454865 0.2863264978 0.2553772032 + 0.3002853096 0.2876687944 0.2566682100 + 0.3016225100 0.2890065014 0.2579559088 + 0.3029560149 0.2903367877 0.2592380047 + 0.3042886853 0.2916674018 0.2605186999 + 0.3056207895 0.2929981947 0.2617981136 + 0.3069526851 0.2943269908 0.2630766928 + 0.3082844913 0.2956545949 0.2643547952 + 0.3096182942 0.2969661951 0.2656278014 + 0.3109529912 0.2982715070 0.2668986917 + 0.3122856021 0.2995666862 0.2681745887 + 0.3136177063 0.3008590043 0.2694520056 + 0.3149411976 0.3021504879 0.2707208097 + 0.3162628114 0.3034417927 0.2719872892 + 0.3175767064 0.3047347069 0.2732458115 + 0.3188889921 0.3060280085 0.2745023072 + 0.3202066123 0.3073163033 0.2757557929 + 0.3215256035 0.3086032867 0.2770085931 + 0.3228304088 0.3098782003 0.2782612145 + 0.3241305947 0.3111487925 0.2795138955 + 0.3254284859 0.3124164939 0.2807643116 + 0.3267253041 0.3136827946 0.2820135057 + 0.3280225098 0.3149532080 0.2832610905 + 0.3293201029 0.3162268996 0.2845073938 + 0.3306170106 0.3174982071 0.2857488990 + 0.3319132030 0.3187662959 0.2869836092 + 0.3332048953 0.3200294971 0.2882154882 + 0.3344849050 0.3212794960 0.2894394994 + 0.3357647061 0.3225289881 0.2906630933 + 0.3370434046 0.3237726986 0.2918823063 + 0.3383221924 0.3250164092 0.2931014895 + 0.3395951092 0.3262596130 0.2943179011 + 0.3408671021 0.3275027871 0.2955336869 + 0.3421292007 0.3287386000 0.2967428863 + 0.3433851898 0.3299694955 0.2979474962 + 0.3446362913 0.3311983943 0.2991509140 + 0.3458774090 0.3324227929 0.3003517985 + 0.3471182883 0.3336473107 0.3015527129 + 0.3483507931 0.3348652124 0.3027420044 + 0.3495832980 0.3360829949 0.3039312065 + 0.3508102000 0.3373039961 0.3051137030 + 0.3520343006 0.3385266066 0.3062925041 + 0.3532547951 0.3397471011 0.3074702024 + 0.3544664085 0.3409624100 0.3086448014 + 0.3556779921 0.3421775997 0.3098194897 + 0.3568766117 0.3433755934 0.3109912872 + 0.3580735922 0.3445712030 0.3121627867 + 0.3592629135 0.3457629979 0.3133305013 + 0.3604426980 0.3469501138 0.3144932091 + 0.3616225123 0.3481371999 0.3156560063 + 0.3627896905 0.3493269086 0.3168224096 + 0.3639565110 0.3505167067 0.3179889917 + 0.3651241064 0.3517034054 0.3191502094 + 0.3662925065 0.3528864980 0.3203046918 + 0.3674609065 0.3540695012 0.3214592934 + 0.3686209023 0.3552398086 0.3226110041 + 0.3697803020 0.3564088047 0.3237625062 + 0.3709327877 0.3575739861 0.3249132931 + 0.3720724881 0.3587315083 0.3260628879 + 0.3732121885 0.3598890007 0.3272125125 + 0.3743419051 0.3610461056 0.3283613026 + 0.3754678965 0.3622029126 0.3295099139 + 0.3765943944 0.3633604050 0.3306581080 + 0.3777253032 0.3645246029 0.3318021894 + 0.3788562119 0.3656888902 0.3329462111 + 0.3799856901 0.3668493927 0.3340887129 + 0.3811131120 0.3680044115 0.3352287114 + 0.3822405040 0.3691594899 0.3363687098 + 0.3833586872 0.3703058958 0.3375062048 + 0.3844727874 0.3714483976 0.3386425078 + 0.3855867982 0.3725908995 0.3397788107 + 0.3867011964 0.3737317026 0.3409082890 + 0.3878157139 0.3748725057 0.3420371115 + 0.3889299929 0.3760136962 0.3431653976 + 0.3900434077 0.3771579862 0.3442898989 + 0.3911567926 0.3783023059 0.3454144001 + 0.3922654092 0.3794414103 0.3465386033 + 0.3933632076 0.3805679977 0.3476622999 + 0.3944610059 0.3816947043 0.3487859070 + 0.3955565989 0.3828161955 0.3499088883 + 0.3966492116 0.3839308023 0.3510310948 + 0.3977417946 0.3850454092 0.3521533012 + 0.3988339901 0.3861593008 0.3532767892 + 0.3999255896 0.3872723877 0.3544014096 + 0.4010173082 0.3883855045 0.3555260003 + 0.4021055102 0.3894925117 0.3566437066 + 0.4031910896 0.3905951083 0.3577559888 + 0.4042766988 0.3916975856 0.3588683009 + 0.4053548872 0.3927960992 0.3599740863 + 0.4064280987 0.3938918114 0.3610751033 + 0.4075013101 0.3949874938 0.3621760905 + 0.4085747004 0.3960804939 0.3632729053 + 0.4096482992 0.3971712887 0.3643661141 + 0.4107218087 0.3982622027 0.3654592037 + 0.4117960930 0.3993507028 0.3665483892 + 0.4128710926 0.4004369974 0.3676328957 + 0.4139460921 0.4015232921 0.3687174916 + 0.4150182009 0.4026117027 0.3698010147 + 0.4160853922 0.4037036896 0.3708826005 + 0.4171527028 0.4047957063 0.3719643056 + 0.4182184935 0.4058865011 0.3730461895 + 0.4192796946 0.4069728851 0.3741292059 + 0.4203408957 0.4080593884 0.3752123117 + 0.4214020073 0.4091454148 0.3762952089 + 0.4224613011 0.4102149904 0.3773654103 + 0.4235205054 0.4112845063 0.3784357011 + 0.4245797992 0.4123539925 0.3795059025 + 0.4256359935 0.4134182930 0.3805727065 + 0.4266915023 0.4144811928 0.3816384077 + 0.4277468920 0.4155440927 0.3827041090 + 0.4287993014 0.4166063070 0.3837668896 + 0.4298486114 0.4176676869 0.3848268092 + 0.4308980107 0.4187290967 0.3858866096 + 0.4319469929 0.4197882116 0.3869450092 + 0.4329943061 0.4208357930 0.3879956901 + 0.4340417087 0.4218834043 0.3890464008 + 0.4350889921 0.4229309857 0.3900969923 + 0.4361298084 0.4239682853 0.3911440074 + 0.4371689856 0.4250029922 0.3921900094 + 0.4382081926 0.4260376990 0.3932358921 + 0.4392425120 0.4270702899 0.3942803144 + 0.4402691126 0.4280996025 0.3953221142 + 0.4412955940 0.4291290045 0.3963639140 + 0.4423221946 0.4301582873 0.3974055946 + 0.4433423877 0.4311893880 0.3984431028 + 0.4443620145 0.4322207868 0.3994801044 + 0.4453817010 0.4332520962 0.4005171955 + 0.4464051127 0.4342832863 0.4015508890 + 0.4474340975 0.4353140891 0.4025794864 + 0.4484629929 0.4363448918 0.4036081135 + 0.4494918883 0.4373758137 0.4046367109 + 0.4505175948 0.4384073019 0.4056606889 + 0.4515425861 0.4394389093 0.4066838920 + 0.4525676072 0.4404704869 0.4077070057 + 0.4535906017 0.4415003955 0.4087300897 + 0.4546070099 0.4425247014 0.4097532928 + 0.4556233883 0.4435490072 0.4107764065 + 0.4566397965 0.4445734024 0.4117994905 + 0.4576533139 0.4455991089 0.4128246903 + 0.4586645961 0.4466257989 0.4138514996 + 0.4596759081 0.4476524889 0.4148781896 + 0.4606871903 0.4486792088 0.4159049988 + 0.4616912901 0.4497005045 0.4169327021 + 0.4626944065 0.4507211149 0.4179604948 + 0.4636974931 0.4517416060 0.4189884067 + 0.4646998942 0.4527609050 0.4200156033 + 0.4656972885 0.4537692964 0.4210371971 + 0.4666947126 0.4547776878 0.4220587909 + 0.4676921070 0.4557861090 0.4230804145 + 0.4686877131 0.4567916095 0.4241015017 + 0.4696792960 0.4577902853 0.4251210093 + 0.4706709981 0.4587889910 0.4261406064 + 0.4716626108 0.4597877860 0.4271601140 + 0.4726535082 0.4607864022 0.4281783998 + 0.4736435115 0.4617848992 0.4291948974 + 0.4746335149 0.4627833962 0.4302113950 + 0.4756234884 0.4637818933 0.4312278926 + 0.4766106009 0.4647786915 0.4322431087 + 0.4775952101 0.4657739997 0.4332571924 + 0.4785799086 0.4667693079 0.4342711866 + 0.4795644879 0.4677644968 0.4352853000 + 0.4805473983 0.4687533975 0.4362984002 + 0.4815289080 0.4697372913 0.4373108149 + 0.4825105071 0.4707211852 0.4383231103 + 0.4834921062 0.4717051089 0.4393354952 + 0.4844721854 0.4726847112 0.4403477013 + 0.4854511917 0.4736607075 0.4413597882 + 0.4864301980 0.4746366143 0.4423719049 + 0.4874091148 0.4756126106 0.4433839917 + 0.4883851111 0.4765883088 0.4443916976 + 0.4893577993 0.4775637090 0.4453943074 + 0.4903304875 0.4785391092 0.4463968873 + 0.4913032055 0.4795145094 0.4473994076 + 0.4922738075 0.4804913104 0.4484009147 + 0.4932405055 0.4814707935 0.4494000971 + 0.4942072034 0.4824503064 0.4503993094 + 0.4951739907 0.4834297895 0.4513984025 + 0.4961400926 0.4844071865 0.4523966908 + 0.4971033931 0.4853728116 0.4533889890 + 0.4980666041 0.4863384068 0.4543812871 + 0.4990297854 0.4873039126 0.4553737044 + 0.4999929965 0.4882695079 0.4563660026 + 0.5009500980 0.4892266095 0.4573510885 + 0.5019065142 0.4901829064 0.4583353102 + 0.5028629899 0.4911391139 0.4593194127 + 0.5038195252 0.4920954108 0.4603036046 + 0.5047739148 0.4930514991 0.4612889886 + 0.5057268739 0.4940074086 0.4622752070 + 0.5066800117 0.4949632883 0.4632613957 + 0.5076330900 0.4959192872 0.4642477036 + 0.5085847974 0.4968729913 0.4652321041 + 0.5095326900 0.4978204072 0.4662106931 + 0.5104805231 0.4987677932 0.4671893120 + 0.5114284158 0.4997152090 0.4681679010 + 0.5123761892 0.5006626248 0.4691464901 + 0.5133184791 0.5016015172 0.4701164067 + 0.5142596960 0.5025386214 0.4710843861 + 0.5152009130 0.5034757853 0.4720525146 + 0.5161420703 0.5044130087 0.4730204940 + 0.5170794725 0.5053501725 0.4739845991 + 0.5180101991 0.5062875152 0.4749414027 + 0.5189409852 0.5072247982 0.4758982956 + 0.5198717117 0.5081620812 0.4768550992 + 0.5208024979 0.5090993047 0.4778119028 + 0.5217247009 0.5100327730 0.4787622094 + 0.5226451755 0.5109654069 0.4797109962 + 0.5235655904 0.5118979812 0.4806598127 + 0.5244860053 0.5128306150 0.4816085100 + 0.5254061222 0.5137627125 0.4825567007 + 0.5263252258 0.5146926045 0.4835023880 + 0.5272442102 0.5156226158 0.4844481051 + 0.5281633139 0.5165526271 0.4853937924 + 0.5290824175 0.5174825191 0.4863395095 + 0.5299966931 0.5184153914 0.4872838855 + 0.5309072733 0.5193507075 0.4882271886 + 0.5318177938 0.5202859044 0.4891706109 + 0.5327283740 0.5212211013 0.4901140034 + 0.5336390138 0.5221564174 0.4910573065 + 0.5345441103 0.5230833292 0.4919950068 + 0.5354480147 0.5240085125 0.4929313958 + 0.5363519788 0.5249336958 0.4938678145 + 0.5372558832 0.5258588791 0.4948042035 + 0.5381596088 0.5267838836 0.4957407117 + 0.5390570760 0.5277035236 0.4966802001 + 0.5399546027 0.5286231041 0.4976195991 + 0.5408521295 0.5295426846 0.4985590875 + 0.5417495966 0.5304622054 0.4994986057 + 0.5426462889 0.5313823819 0.5004374981 + 0.5435394049 0.5323048830 0.5013735890 + 0.5444325805 0.5332273841 0.5023097992 + 0.5453258157 0.5341498852 0.5032458901 + 0.5462188721 0.5350723863 0.5041819811 + 0.5471100807 0.5359948874 0.5051165819 + 0.5479956269 0.5369172096 0.5060467720 + 0.5488811731 0.5378395915 0.5069770217 + 0.5497667789 0.5387619138 0.5079072118 + 0.5506523848 0.5396841764 0.5088372827 + 0.5515369177 0.5406029820 0.5097665787 + 0.5524184704 0.5415124297 0.5106934905 + 0.5533000827 0.5424216986 0.5116204023 + 0.5541815758 0.5433310866 0.5125473142 + 0.5550631881 0.5442404747 0.5134742260 + 0.5559430122 0.5451484919 0.5144008994 + 0.5568165183 0.5460516214 0.5153269768 + 0.5576900840 0.5469545722 0.5162531734 + 0.5585635900 0.5478577018 0.5171793103 + 0.5594370961 0.5487607121 0.5181055069 + 0.5603092909 0.5496640205 0.5190312862 + 0.5611693859 0.5505691171 0.5199540257 + 0.5620294809 0.5514742732 0.5208765864 + 0.5628895760 0.5523794293 0.5217992067 + 0.5637496710 0.5532845855 0.5227218866 + 0.5646098852 0.5541896820 0.5236445069 + 0.5654671192 0.5550884008 0.5245587230 + 0.5663241148 0.5559865236 0.5254719853 + 0.5671809912 0.5568845272 0.5263851881 + 0.5680379868 0.5577825904 0.5272983909 + 0.5688949227 0.5586807132 0.5282117128 + 0.5697519183 0.5595684052 0.5291250944 + 0.5706089139 0.5604503751 0.5300387144 + 0.5714659095 0.5613324046 0.5309522748 + 0.5723227859 0.5622143745 0.5318658948 + 0.5731797814 0.5630964041 0.5327795148 + 0.5740355849 0.5639759898 0.5336920023 + 0.5748888254 0.5648500919 0.5346015096 + 0.5757420063 0.5657241940 0.5355110765 + 0.5765951872 0.5665982962 0.5364207029 + 0.5774484873 0.5674723983 0.5373303294 + 0.5783017278 0.5683465004 0.5382397771 + 0.5791468024 0.5692207813 0.5391464233 + 0.5799911022 0.5700951219 0.5400525928 + 0.5808354020 0.5709695220 0.5409587026 + 0.5816797018 0.5718438029 0.5418648720 + 0.5825240016 0.5727180839 0.5427711010 + 0.5833687782 0.5735895038 0.5436769128 + 0.5842140913 0.5744568110 0.5445824265 + 0.5850595236 0.5753241181 0.5454878807 + 0.5859047771 0.5761914253 0.5463933945 + 0.5867500901 0.5770586729 0.5472989082 + 0.5875955224 0.5779259801 0.5482044220 + 0.5884351730 0.5787826777 0.5491033792 + 0.5892739892 0.5796378255 0.5500012040 + 0.5901129246 0.5804927945 0.5508990288 + 0.5909516811 0.5813478231 0.5517967939 + 0.5917904973 0.5822029114 0.5526946187 + 0.5926260948 0.5830556154 0.5535923243 + 0.5934513211 0.5839005113 0.5544894934 + 0.5942764282 0.5847454071 0.5553867221 + 0.5951015949 0.5855903029 0.5562840104 + 0.5959268212 0.5864353180 0.5571811795 + 0.5967519283 0.5872802138 0.5580784082 + 0.5975750089 0.5881240964 0.5589731932 + 0.5983961225 0.5889670253 0.5598654747 + 0.5992172956 0.5898098946 0.5607578158 + 0.6000384092 0.5906528234 0.5616500974 + 0.6008595824 0.5914956927 0.5625423789 + 0.6016806960 0.5923386216 0.5634347200 + 0.6025013924 0.5931785107 0.5643216968 + 0.6033217907 0.5940173864 0.5652067065 + 0.6041421890 0.5948563218 0.5660917163 + 0.6049627066 0.5956951976 0.5669767261 + 0.6057831049 0.5965340734 0.5678616762 + 0.6066035032 0.5973730087 0.5687466860 + 0.6074202061 0.5982081890 0.5696277022 + 0.6082363725 0.5990427732 0.5705081224 + 0.6090525985 0.5998774171 0.5713884830 + 0.6098688245 0.6007121205 0.5722689033 + 0.6106849909 0.6015467048 0.5731493235 + 0.6115012169 0.6023812890 0.5740296841 + 0.6123086214 0.6032109857 0.5749081969 + 0.6131153107 0.6040402055 0.5757864714 + 0.6139221191 0.6048694849 0.5766646862 + 0.6147289276 0.6056988239 0.5775430202 + 0.6155356765 0.6065281034 0.5784212947 + 0.6163424850 0.6073573232 0.5792995095 + 0.6171492934 0.6081854105 0.5801749825 + 0.6179562211 0.6090133786 0.5810500979 + 0.6187630296 0.6098414063 0.5819252133 + 0.6195698977 0.6106693745 0.5828003287 + 0.6203767061 0.6114974022 0.5836755037 + 0.6211835742 0.6123253107 0.5845506191 + 0.6219863296 0.6131554246 0.5854259729 + 0.6227880716 0.6139858961 0.5863015056 + 0.6235898733 0.6148164272 0.5871769786 + 0.6243916750 0.6156468987 0.5880525112 + 0.6251934767 0.6164774895 0.5889279842 + 0.6259952784 0.6173080206 0.5898035169 + 0.6267918944 0.6181306243 0.5906723738 + 0.6275851727 0.6189482212 0.5915369987 + 0.6283785105 0.6197658777 0.5924015045 + 0.6291717887 0.6205834746 0.5932661295 + 0.6299651265 0.6214010715 0.5941306949 + 0.6307584047 0.6222187877 0.5949952006 + 0.6315498948 0.6230332851 0.5958583951 + 0.6323379278 0.6238421202 0.5967187881 + 0.6331260204 0.6246507764 0.5975791812 + 0.6339139938 0.6254594922 0.5984395146 + 0.6347020268 0.6262683272 0.5992999077 + 0.6354900002 0.6270769835 0.6001603007 + 0.6362780929 0.6278856993 0.6010206938 + 0.6370700002 0.6286913753 0.6018776298 + 0.6378619075 0.6294969916 0.6027345061 + 0.6386538148 0.6303027272 0.6035913825 + 0.6394457817 0.6311082840 0.6044483185 + 0.6402376890 0.6319140196 0.6053051949 + 0.6410297155 0.6327196956 0.6061620116 + 0.6418200135 0.6335238814 0.6070173979 + 0.6426091194 0.6343269944 0.6078712940 + 0.6433981061 0.6351301074 0.6087253094 + 0.6441872120 0.6359332204 0.6095792055 + 0.6449761987 0.6367362738 0.6104332209 + 0.6457653046 0.6375393867 0.6112871170 + 0.6465541720 0.6383423209 0.6121410131 + 0.6473349929 0.6391350031 0.6129897237 + 0.6481158733 0.6399276853 0.6138383746 + 0.6488966942 0.6407204270 0.6146870852 + 0.6496775150 0.6415132284 0.6155357957 + 0.6504582763 0.6423059106 0.6163845062 + 0.6512390971 0.6430985928 0.6172332168 + 0.6520215869 0.6438899040 0.6180806756 + 0.6528064013 0.6446790099 0.6189264059 + 0.6535912752 0.6454681754 0.6197721958 + 0.6543760896 0.6462572813 0.6206179261 + 0.6551610231 0.6470463872 0.6214635968 + 0.6559458971 0.6478356123 0.6223093271 + 0.6567307115 0.6486247182 0.6231549978 + 0.6575127840 0.6494132280 0.6240007281 + 0.6582934856 0.6502012014 0.6248463988 + 0.6590741873 0.6509892941 0.6256921291 + 0.6598550081 0.6517773867 0.6265377998 + 0.6606357098 0.6525654793 0.6273834109 + 0.6614164114 0.6533535719 0.6282290816 + 0.6621971726 0.6541417241 0.6290748119 + 0.6629760265 0.6549354196 0.6299114823 + 0.6637545228 0.6557300091 0.6307469010 + 0.6645330787 0.6565244794 0.6315823197 + 0.6653115749 0.6573191285 0.6324176788 + 0.6660900712 0.6581135988 0.6332530975 + 0.6668686867 0.6589081883 0.6340885758 + 0.6676471829 0.6597027183 0.6349239945 + 0.6684235930 0.6604955792 0.6357483864 + 0.6691998839 0.6612884998 0.6365724802 + 0.6699762940 0.6620813012 0.6373966932 + 0.6707525849 0.6628742218 0.6382207870 + 0.6715289950 0.6636670232 0.6390450001 + 0.6723052859 0.6644598842 0.6398692131 + 0.6730816960 0.6652526855 0.6406933069 + 0.6738588214 0.6660354733 0.6415144801 + 0.6746358275 0.6668183208 0.6423355937 + 0.6754128933 0.6676011086 0.6431567073 + 0.6761900187 0.6683838964 0.6439778209 + 0.6769670844 0.6691666842 0.6447988749 + 0.6777442098 0.6699494123 0.6456201077 + 0.6785212159 0.6707322001 0.6464412212 + 0.6792948246 0.6715126038 0.6472591758 + 0.6800680757 0.6722927094 0.6480770111 + 0.6808413863 0.6730728745 0.6488947272 + 0.6816146970 0.6738529801 0.6497125030 + 0.6823881269 0.6746330857 0.6505302191 + 0.6831613779 0.6754133105 0.6513479948 + 0.6839346886 0.6761934161 0.6521657705 + 0.6847041249 0.6769770980 0.6529843807 + 0.6854723096 0.6777619720 0.6538034081 + 0.6862404943 0.6785469055 0.6546223760 + 0.6870086193 0.6793317199 0.6554414034 + 0.6877768040 0.6801165938 0.6562603116 + 0.6885449886 0.6809015274 0.6570792794 + 0.6893131137 0.6816864014 0.6578983068 + 0.6900815964 0.6824722290 0.6587166190 + 0.6908504963 0.6832591295 0.6595342159 + 0.6916193962 0.6840459108 0.6603516936 + 0.6923881769 0.6848328114 0.6611691713 + 0.6931570768 0.6856197119 0.6619867086 + 0.6939259768 0.6864064932 0.6628043056 + 0.6946948171 0.6871933937 0.6636217833 + 0.6954628825 0.6879794002 0.6644390821 + 0.6962239146 0.6887571216 0.6652535796 + 0.6969848275 0.6895347238 0.6660680771 + 0.6977458000 0.6903123856 0.6668826938 + 0.6985067725 0.6910901070 0.6676971912 + 0.6992678046 0.6918678284 0.6685116887 + 0.7000287175 0.6926453710 0.6693261862 + 0.7007896900 0.6934230924 0.6701408029 + 0.7015470862 0.6941987276 0.6709529757 + 0.7023022771 0.6949729919 0.6717637181 + 0.7030575275 0.6957471967 0.6725745201 + 0.7038127184 0.6965215206 0.6733852029 + 0.7045679092 0.6972957850 0.6741960049 + 0.7053231001 0.6980701089 0.6750066876 + 0.7060784101 0.6988443136 0.6758173704 + 0.7068333030 0.6996185780 0.6766281128 + 0.7075828910 0.7003933787 0.6774358153 + 0.7083325982 0.7011681199 0.6782433987 + 0.7090821862 0.7019429207 0.6790511012 + 0.7098318934 0.7027176023 0.6798588037 + 0.7105816007 0.7034922838 0.6806665063 + 0.7113311887 0.7042670846 0.6814742088 + 0.7120808959 0.7050418258 0.6822819114 + 0.7128294110 0.7058115005 0.6830887198 + 0.7135760784 0.7065724730 0.6838940978 + 0.7143228054 0.7073335052 0.6846994758 + 0.7150694132 0.7080944777 0.6855047941 + 0.7158160806 0.7088556290 0.6863101721 + 0.7165628076 0.7096166015 0.6871154904 + 0.7173094749 0.7103775740 0.6879209280 + 0.7180560827 0.7111386061 0.6887263060 + 0.7187995911 0.7118936777 0.6895337105 + 0.7195408940 0.7126445174 0.6903426051 + 0.7202820778 0.7133952975 0.6911514997 + 0.7210233808 0.7141461968 0.6919603944 + 0.7217646241 0.7148969769 0.6927692890 + 0.7225059271 0.7156478763 0.6935781837 + 0.7232471704 0.7163987160 0.6943870783 + 0.7239884138 0.7171496153 0.6951959729 + 0.7247272134 0.7178981900 0.6960002184 + 0.7254649997 0.7186459899 0.6968023777 + 0.7262027860 0.7193936706 0.6976047158 + 0.7269405723 0.7201414108 0.6984068751 + 0.7276784182 0.7208890915 0.6992090940 + 0.7284160852 0.7216367722 0.7000113130 + 0.7291538715 0.7223845124 0.7008134723 + 0.7298917174 0.7231323123 0.7016156912 + 0.7306271195 0.7238802910 0.7024155259 + 0.7313616276 0.7246286273 0.7032142282 + 0.7320960760 0.7253767848 0.7040128708 + 0.7328305244 0.7261251211 0.7048115730 + 0.7335649729 0.7268732786 0.7056102753 + 0.7342994809 0.7276216149 0.7064089775 + 0.7350339890 0.7283697724 0.7072076797 + 0.7357683778 0.7291179895 0.7080063820 + 0.7364991903 0.7298579812 0.7088025808 + 0.7372276783 0.7305926085 0.7095971107 + 0.7379561067 0.7313271761 0.7103915811 + 0.7386844754 0.7320618033 0.7111861110 + 0.7394129038 0.7327963710 0.7119805217 + 0.7401413918 0.7335309982 0.7127749920 + 0.7408698201 0.7342656255 0.7135695219 + 0.7415981889 0.7350000739 0.7143639922 + 0.7423244119 0.7357305884 0.7151564956 + 0.7430471778 0.7364547253 0.7159457207 + 0.7437700033 0.7371786833 0.7167348862 + 0.7444928288 0.7379027009 0.7175241113 + 0.7452155948 0.7386267781 0.7183133960 + 0.7459384203 0.7393507957 0.7191026211 + 0.7466611862 0.7400748730 0.7198917866 + 0.7473840117 0.7407988906 0.7206810117 + 0.7481065989 0.7415227294 0.7214697003 + 0.7488253713 0.7422428727 0.7222498059 + 0.7495442033 0.7429631948 0.7230297923 + 0.7502629757 0.7436835170 0.7238097787 + 0.7509818077 0.7444037199 0.7245898843 + 0.7517006993 0.7451239824 0.7253698707 + 0.7524194717 0.7458441854 0.7261499763 + 0.7531383038 0.7465645075 0.7269300222 + 0.7538570762 0.7472847104 0.7277100086 + 0.7545717955 0.7480040193 0.7284893990 + 0.7552838922 0.7487226725 0.7292684913 + 0.7559961081 0.7494413853 0.7300475240 + 0.7567083240 0.7501600981 0.7308264971 + 0.7574204206 0.7508788109 0.7316055894 + 0.7581325769 0.7515975237 0.7323846221 + 0.7588447928 0.7523161769 0.7331635952 + 0.7595570087 0.7530348897 0.7339426875 + 0.7602682710 0.7537531853 0.7347213030 + 0.7609707117 0.7544673085 0.7354943752 + 0.7616729736 0.7551813126 0.7362675071 + 0.7623752952 0.7558953166 0.7370406985 + 0.7630776167 0.7566093802 0.7378137708 + 0.7637799978 0.7573233843 0.7385869026 + 0.7644823194 0.7580373883 0.7393599749 + 0.7651845813 0.7587515116 0.7401331067 + 0.7658869028 0.7594655156 0.7409062982 + 0.7665888071 0.7601786256 0.7416762710 + 0.7672901750 0.7608903050 0.7424415946 + 0.7679914832 0.7616019845 0.7432069182 + 0.7686929107 0.7623137236 0.7439723015 + 0.7693942189 0.7630254030 0.7447376251 + 0.7700955868 0.7637370825 0.7455030084 + 0.7707968950 0.7644488811 0.7462682724 + 0.7714983225 0.7651606202 0.7470335960 + 0.7721995711 0.7658722997 0.7477989793 + 0.7729007006 0.7665820122 0.7485641241 + 0.7736015916 0.7672904134 0.7493289709 + 0.7743026018 0.7679988742 0.7500939965 + 0.7750034928 0.7687073946 0.7508589029 + 0.7757043839 0.7694157958 0.7516239285 + 0.7764053941 0.7701243162 0.7523887753 + 0.7771062851 0.7708327174 0.7531538010 + 0.7778071761 0.7715411782 0.7539188266 + 0.7785081267 0.7722496986 0.7546836734 + 0.7792059779 0.7729594111 0.7554478049 + 0.7799026966 0.7736696005 0.7562115788 + 0.7805994153 0.7743797898 0.7569754124 + 0.7812960744 0.7750899196 0.7577391863 + 0.7819927931 0.7758001089 0.7585030198 + 0.7826895118 0.7765102983 0.7592667937 + 0.7833861709 0.7772204876 0.7600306273 + 0.7840828896 0.7779306769 0.7607944012 + 0.7847796082 0.7786409259 0.7615581751 + 0.7854750156 0.7793545127 0.7623156905 + 0.7861698866 0.7800694704 0.7630702257 + 0.7868646979 0.7807846069 0.7638248205 + 0.7875596285 0.7814996243 0.7645792961 + 0.7882543802 0.7822147012 0.7653338909 + 0.7889491916 0.7829297185 0.7660884261 + 0.7896441221 0.7836447954 0.7668430209 + 0.7903388739 0.7843598127 0.7675974965 + 0.7910338044 0.7850748897 0.7683520913 + 0.7917258739 0.7857853770 0.7691050172 + 0.7924156785 0.7864919901 0.7698563933 + 0.7931054831 0.7871986032 0.7706078887 + 0.7937952876 0.7879050970 0.7713593245 + 0.7944852114 0.7886117101 0.7721108198 + 0.7951750159 0.7893183231 0.7728621960 + 0.7958648205 0.7900248766 0.7736136913 + 0.7965546250 0.7907314897 0.7743651271 + 0.7972444296 0.7914381027 0.7751166224 + 0.7979317904 0.7921432853 0.7758662105 + 0.7986127138 0.7928448915 0.7766107917 + 0.7992935777 0.7935463786 0.7773553729 + 0.7999745011 0.7942479253 0.7781000733 + 0.8006554246 0.7949494123 0.7788447142 + 0.8013362885 0.7956508994 0.7795892954 + 0.8020172119 0.7963523865 0.7803338766 + 0.8026980758 0.7970538735 0.7810785174 + 0.8033789992 0.7977554798 0.7818232179 + 0.8040599227 0.7984570265 0.7825677991 + 0.8047353029 0.7991585135 0.7833089828 + 0.8054097891 0.7998598814 0.7840498090 + 0.8060843945 0.8005614281 0.7847905159 + 0.8067588806 0.8012629151 0.7855312228 + 0.8074334264 0.8019642830 0.7862719893 + 0.8081079721 0.8026658297 0.7870126963 + 0.8087825179 0.8033673167 0.7877534032 + 0.8094571233 0.8040686846 0.7884941101 + 0.8101316094 0.8047701716 0.7892348766 + 0.8108057976 0.8054717779 0.7899757028 + 0.8114792705 0.8061736822 0.7907167077 + 0.8121528029 0.8068755865 0.7914577127 + 0.8128262758 0.8075774908 0.7921987772 + 0.8134996891 0.8082793951 0.7929397821 + 0.8141732216 0.8089812994 0.7936807871 + 0.8148466945 0.8096832037 0.7944217920 + 0.8155202270 0.8103851080 0.7951627970 + 0.8161935806 0.8110868931 0.7959039211 + 0.8168671131 0.8117887974 0.7966449261 + 0.8175389767 0.8124853969 0.7973858118 + 0.8182101250 0.8131793737 0.7981265783 + 0.8188812733 0.8138735294 0.7988674045 + 0.8195524216 0.8145676255 0.7996081710 + 0.8202236295 0.8152617216 0.8003489971 + 0.8208947182 0.8159558177 0.8010898232 + 0.8215658069 0.8166497946 0.8018305898 + 0.8222370148 0.8173438907 0.8025714159 + 0.8229081035 0.8180379868 0.8033121824 + 0.8235793114 0.8187320828 0.8040530086 + 0.8242446780 0.8194221854 0.8047931194 + 0.8249096274 0.8201119900 0.8055329919 + 0.8255745173 0.8208016753 0.8062729836 + 0.8262394071 0.8214914203 0.8070129156 + 0.8269042969 0.8221811056 0.8077529073 + 0.8275691867 0.8228709102 0.8084927797 + 0.8282340169 0.8235605955 0.8092327714 + 0.8288989067 0.8242502809 0.8099727035 + 0.8295637965 0.8249400258 0.8107126951 + 0.8302286863 0.8256297708 0.8114526272 + 0.8308899999 0.8263183832 0.8121870756 + 0.8315511942 0.8270071149 0.8129215240 + 0.8322123885 0.8276957870 0.8136559129 + 0.8328735828 0.8283843994 0.8143903017 + 0.8335347772 0.8290730715 0.8151246905 + 0.8341959715 0.8297618032 0.8158590198 + 0.8348572254 0.8304504156 0.8165934086 + 0.8355184197 0.8311390877 0.8173277974 + 0.8361796141 0.8318278193 0.8180621862 + 0.8368408084 0.8325163722 0.8187965751 + 0.8374971747 0.8331937194 0.8195257187 + 0.8381533027 0.8338699937 0.8202543855 + 0.8388093710 0.8345463872 0.8209831119 + 0.8394654989 0.8352227807 0.8217117190 + 0.8401216269 0.8358991742 0.8224403858 + 0.8407776952 0.8365755081 0.8231691122 + 0.8414338231 0.8372519016 0.8238977790 + 0.8420898914 0.8379282951 0.8246265054 + 0.8427460194 0.8386046886 0.8253551722 + 0.8434020877 0.8392810822 0.8260837793 + 0.8440536261 0.8399528265 0.8268138170 + 0.8447033763 0.8406227827 0.8275440931 + 0.8453533053 0.8412929177 0.8282744884 + 0.8460031152 0.8419629931 0.8290048838 + 0.8466529846 0.8426330090 0.8297352195 + 0.8473027945 0.8433030844 0.8304656148 + 0.8479527235 0.8439732194 0.8311958909 + 0.8486024737 0.8446431756 0.8319262862 + 0.8492524028 0.8453133106 0.8326566815 + 0.8499022126 0.8459833860 0.8333870173 + 0.8505504727 0.8466514945 0.8341168165 + 0.8511967063 0.8473168015 0.8348454833 + 0.8518428206 0.8479821086 0.8355743289 + 0.8524889946 0.8486474156 0.8363031149 + 0.8531351089 0.8493127227 0.8370317817 + 0.8537812829 0.8499780297 0.8377606273 + 0.8544273973 0.8506432772 0.8384894133 + 0.8550735712 0.8513085842 0.8392181993 + 0.8557196856 0.8519738913 0.8399469256 + 0.8563657999 0.8526391983 0.8406757116 + 0.8570119739 0.8533045053 0.8414044976 + 0.8576570153 0.8539714217 0.8421310186 + 0.8583019972 0.8546383977 0.8428574204 + 0.8589469790 0.8553053737 0.8435838223 + 0.8595920205 0.8559722900 0.8443102241 + 0.8602368832 0.8566393256 0.8450366259 + 0.8608819246 0.8573063016 0.8457630277 + 0.8615269065 0.8579732180 0.8464894295 + 0.8621718884 0.8586401939 0.8472157717 + 0.8628168702 0.8593072295 0.8479421139 + 0.8634617925 0.8599740863 0.8486685157 + 0.8641055226 0.8606404066 0.8493939042 + 0.8647466898 0.8613052964 0.8501170874 + 0.8653877974 0.8619701266 0.8508402705 + 0.8660289049 0.8626350164 0.8515635729 + 0.8666700125 0.8632999063 0.8522868156 + 0.8673111796 0.8639646769 0.8530099988 + 0.8679522872 0.8646296263 0.8537331820 + 0.8685933948 0.8652945161 0.8544564843 + 0.8692345023 0.8659592867 0.8551797271 + 0.8698757291 0.8666241765 0.8559029102 + 0.8705167770 0.8672891259 0.8566260934 + 0.8711531758 0.8679519296 0.8573492169 + 0.8717862964 0.8686133027 0.8580722213 + 0.8724194169 0.8692746758 0.8587951064 + 0.8730524182 0.8699361086 0.8595181108 + 0.8736854792 0.8705974221 0.8602411151 + 0.8743184805 0.8712587953 0.8609640002 + 0.8749516010 0.8719202280 0.8616870046 + 0.8755847216 0.8725816011 0.8624100089 + 0.8762177229 0.8732429147 0.8631328940 + 0.8768507838 0.8739042878 0.8638558984 + 0.8774839044 0.8745657206 0.8645789027 + 0.8781164885 0.8752220869 0.8652966022 + 0.8787490129 0.8758761287 0.8660116792 + 0.8793814778 0.8765301108 0.8667268157 + 0.8800138831 0.8771839738 0.8674418926 + 0.8806464076 0.8778380156 0.8681570888 + 0.8812788725 0.8784919977 0.8688722253 + 0.8819113970 0.8791459799 0.8695873022 + 0.8825438023 0.8798000216 0.8703024983 + 0.8831763268 0.8804540038 0.8710175753 + 0.8838087916 0.8811079860 0.8717327118 + 0.8844413161 0.8817619085 0.8724479079 + 0.8850709200 0.8824151754 0.8731632233 + 0.8856989741 0.8830680847 0.8738787770 + 0.8863270283 0.8837209940 0.8745942712 + 0.8869550824 0.8843739033 0.8753098845 + 0.8875830770 0.8850268126 0.8760253787 + 0.8882111907 0.8856797218 0.8767408729 + 0.8888391852 0.8863325715 0.8774564862 + 0.8894672990 0.8869854808 0.8781719804 + 0.8900952935 0.8876383901 0.8788874745 + 0.8907234073 0.8882912993 0.8796030879 + 0.8913514018 0.8889442086 0.8803185821 + 0.8919770122 0.8895980120 0.8810324073 + 0.8925994039 0.8902531266 0.8817437887 + 0.8932216763 0.8909081221 0.8824552298 + 0.8938440084 0.8915631771 0.8831664920 + 0.8944662809 0.8922182918 0.8838778734 + 0.8950886130 0.8928732872 0.8845893145 + 0.8957110047 0.8935284019 0.8853006959 + 0.8963332772 0.8941833973 0.8860120773 + 0.8969556093 0.8948385119 0.8867235184 + 0.8975778818 0.8954935074 0.8874347806 + 0.8982002735 0.8961486220 0.8881462216 + 0.8988224864 0.8968032002 0.8888574839 + 0.8994441032 0.8974525928 0.8895666003 + 0.9000657201 0.8981019258 0.8902757764 + 0.9006872773 0.8987513185 0.8909850121 + 0.9013088942 0.8994005919 0.8916941881 + 0.9019305110 0.9000499845 0.8924034238 + 0.9025521278 0.9006993771 0.8931125998 + 0.9031736851 0.9013487101 0.8938217759 + 0.9037953019 0.9019981027 0.8945308924 + 0.9044169188 0.9026473761 0.8952401280 + 0.9050384760 0.9032968283 0.8959493041 + 0.9056600928 0.9039461017 0.8966584802 + 0.9062818885 0.9045925736 0.8973668218 + 0.9069039822 0.9052367806 0.8980745077 + 0.9075260162 0.9058809876 0.8987820745 + 0.9081479907 0.9065251946 0.8994898200 + 0.9087700844 0.9071695209 0.9001973867 + 0.9093921185 0.9078137279 0.9009050727 + 0.9100140929 0.9084578753 0.9016128182 + 0.9106361866 0.9091020823 0.9023203850 + 0.9112582207 0.9097462893 0.9030280709 + 0.9118801951 0.9103906155 0.9037356973 + 0.9125022888 0.9110348225 0.9044433832 + 0.9131243229 0.9116790295 0.9051510096 + 0.9137399197 0.9123209715 0.9058520794 + 0.9143548012 0.9129626751 0.9065523744 + 0.9149696827 0.9136044979 0.9072527885 + 0.9155846834 0.9142462015 0.9079532027 + 0.9161996245 0.9148880243 0.9086536169 + 0.9168145061 0.9155297875 0.9093539715 + 0.9174293876 0.9161714911 0.9100543261 + 0.9180443883 0.9168133140 0.9107546806 + 0.9186593294 0.9174550176 0.9114550948 + 0.9192742109 0.9180967808 0.9121555090 + 0.9198892117 0.9187384844 0.9128558040 + 0.9205033779 0.9193800092 0.9135550857 + 0.9211103916 0.9200189710 0.9142435193 + 0.9217175245 0.9206579924 0.9149317741 + 0.9223244786 0.9212968946 0.9156202078 + 0.9229314923 0.9219359159 0.9163085222 + 0.9235386252 0.9225748777 0.9169968963 + 0.9241455793 0.9232137799 0.9176852107 + 0.9247527122 0.9238528013 0.9183735847 + 0.9253597260 0.9244918227 0.9190618992 + 0.9259667993 0.9251307845 0.9197502732 + 0.9265738130 0.9257696867 0.9204387069 + 0.9271808863 0.9264087081 0.9211270213 + 0.9277874231 0.9270467758 0.9218143225 + 0.9283900261 0.9276784062 0.9224932790 + 0.9289926887 0.9283099771 0.9231721759 + 0.9295952916 0.9289416075 0.9238511920 + 0.9301978946 0.9295731783 0.9245300889 + 0.9308004975 0.9302048087 0.9252091050 + 0.9314031005 0.9308363795 0.9258880019 + 0.9320058227 0.9314680099 0.9265670180 + 0.9326084256 0.9320995212 0.9272459149 + 0.9332110286 0.9327310920 0.9279248714 + 0.9338135719 0.9333627224 0.9286038876 + 0.9344161749 0.9339942932 0.9292827845 + 0.9350188971 0.9346259236 0.9299618006 + 0.9356135726 0.9352514148 0.9306330085 + 0.9362081289 0.9358767867 0.9313039184 + 0.9368026257 0.9365020990 0.9319748878 + 0.9373971820 0.9371274710 0.9326457977 + 0.9379916787 0.9377527833 0.9333167076 + 0.9385861754 0.9383780956 0.9339876771 + 0.9391806722 0.9390035272 0.9346585870 + 0.9397752285 0.9396287799 0.9353296161 + 0.9403697252 0.9402542114 0.9360005260 + 0.9409642816 0.9408795238 0.9366714954 + 0.9415587783 0.9415047765 0.9373424053 + 0.9421532750 0.9421302080 0.9380133748 + 0.9427425861 0.9427515268 0.9386783242 + 0.9433292150 0.9433708787 0.9393401742 + 0.9439157844 0.9439901710 0.9400020242 + 0.9445024133 0.9446095824 0.9406638741 + 0.9450889826 0.9452288747 0.9413257837 + 0.9456756115 0.9458482265 0.9419876933 + 0.9462621808 0.9464675784 0.9426494837 + 0.9468489289 0.9470868707 0.9433113933 + 0.9474354982 0.9477062821 0.9439733028 + 0.9480221272 0.9483255744 0.9446350932 + 0.9486086965 0.9489449263 0.9452970028 + 0.9491953254 0.9495642781 0.9459589124 + 0.9497808814 0.9501816034 0.9466190934 + 0.9503620863 0.9507901073 0.9472720027 + 0.9509434104 0.9513986707 0.9479249120 + 0.9515246153 0.9520071745 0.9485778809 + 0.9521058798 0.9526157975 0.9492307901 + 0.9526870847 0.9532243013 0.9498836994 + 0.9532684088 0.9538329244 0.9505366087 + 0.9538496137 0.9544414878 0.9511895776 + 0.9544308782 0.9550499916 0.9518424869 + 0.9550120831 0.9556586146 0.9524953961 + 0.9555934072 0.9562671185 0.9531484246 + 0.9561746120 0.9568756819 0.9538012743 + 0.9567558765 0.9574841857 0.9544541836 + 0.9573335052 0.9580839872 0.9551010728 + 0.9579079747 0.9586765170 0.9557430148 + 0.9584826231 0.9592689872 0.9563847780 + 0.9590572119 0.9598613977 0.9570267200 + 0.9596316814 0.9604539275 0.9576684833 + 0.9602062702 0.9610463977 0.9583104253 + 0.9607809186 0.9616388083 0.9589521885 + 0.9613553882 0.9622312784 0.9595940709 + 0.9619299769 0.9628238082 0.9602360129 + 0.9625046253 0.9634162784 0.9608777761 + 0.9630790949 0.9640086889 0.9615197182 + 0.9636536837 0.9646012187 0.9621614814 + 0.9642282724 0.9651936889 0.9628034234 + 0.9647949934 0.9657722712 0.9634308219 + 0.9653589129 0.9663459063 0.9640529156 + 0.9659227133 0.9669194818 0.9646750093 + 0.9664865732 0.9674929976 0.9652972221 + 0.9670504928 0.9680665731 0.9659193158 + 0.9676142931 0.9686402082 0.9665414095 + 0.9681782126 0.9692137837 0.9671635032 + 0.9687420726 0.9697872996 0.9677855968 + 0.9693059921 0.9703608751 0.9684076905 + 0.9698697925 0.9709345102 0.9690297842 + 0.9704337120 0.9715080857 0.9696519971 + 0.9709975719 0.9720816016 0.9702740908 + 0.9715613723 0.9726551771 0.9708961844 + 0.9721186161 0.9732081294 0.9714968801 + 0.9726734757 0.9737539291 0.9720901847 + 0.9732283950 0.9742997289 0.9726834893 + 0.9737833142 0.9748454094 0.9732767940 + 0.9743381739 0.9753912091 0.9738700986 + 0.9748930931 0.9759370089 0.9744634032 + 0.9754480124 0.9764826894 0.9750567079 + 0.9760028720 0.9770284891 0.9756498933 + 0.9765577912 0.9775742888 0.9762431979 + 0.9771127105 0.9781200290 0.9768365026 + 0.9776676297 0.9786658287 0.9774298072 + 0.9782224894 0.9792116284 0.9780231118 + 0.9787774086 0.9797573090 0.9786164165 + 0.9793238044 0.9802883863 0.9791917205 + 0.9798640013 0.9808087945 0.9797537923 + 0.9804041982 0.9813292027 0.9803159237 + 0.9809442759 0.9818496108 0.9808779955 + 0.9814844728 0.9823700190 0.9814401269 + 0.9820247293 0.9828904271 0.9820021987 + 0.9825649261 0.9834107757 0.9825642705 + 0.9831050038 0.9839311838 0.9831264019 + 0.9836452007 0.9844515920 0.9836884737 + 0.9841853976 0.9849720001 0.9842506051 + 0.9847255945 0.9854924083 0.9848126769 + 0.9852656722 0.9860128760 0.9853748083 + 0.9858059287 0.9865332842 0.9859368205 + 0.9863404036 0.9870470166 0.9864904881 + 0.9868565202 0.9875389934 0.9870164990 + 0.9873725176 0.9880309105 0.9875423908 + 0.9878885150 0.9885228872 0.9880682826 + 0.9884045124 0.9890148044 0.9885942936 + 0.9889205098 0.9895067811 0.9891201854 + 0.9894366264 0.9899986982 0.9896460772 + 0.9899526238 0.9904906750 0.9901720881 + 0.9904686213 0.9909825921 0.9906979799 + 0.9909846187 0.9914746284 0.9912238717 + 0.9915006161 0.9919664860 0.9917498827 + 0.9920166731 0.9924585223 0.9922757745 + 0.9925326705 0.9929504991 0.9928017855 + 0.9930487275 0.9934424162 0.9933276772 + 0.9935505986 0.9939172864 0.9938179255 + 0.9940466881 0.9943851829 0.9942935109 + 0.9945427775 0.9948530793 0.9947689772 + 0.9950389266 0.9953209758 0.9952446222 + 0.9955350161 0.9957888722 0.9957200885 + 0.9960311055 0.9962568283 0.9961956739 + 0.9965273142 0.9967247248 0.9966711998 + 0.9970234036 0.9971926212 0.9971467257 + 0.9975194931 0.9976605177 0.9976223111 + 0.9980155826 0.9981284142 0.9980977774 + 0.9985116720 0.9985963106 0.9985734224 + 0.9990078211 0.9990642071 0.9990488887 + 0.9995039105 0.9995321035 0.9995244741 + 1.0000000000 1.0000000000 1.0000000000 +} diff --git a/rpplugins/color_correction/resources/film_luts_raw/kodak_portra_400nc.spi1d b/rpplugins/color_correction/resources/film_luts_raw/kodak_portra_400nc.spi1d new file mode 100644 index 0000000..b475f26 --- /dev/null +++ b/rpplugins/color_correction/resources/film_luts_raw/kodak_portra_400nc.spi1d @@ -0,0 +1,1030 @@ +Version 1 +From 0.0 1.0 +Length 1024 +Components 3 +{ + 0.0000000000 0.0000000000 0.0000000000 + 0.0114686396 0.0107471403 0.0087564439 + 0.0217512399 0.0202643294 0.0160814300 + 0.0303464700 0.0281717796 0.0221705399 + 0.0377242714 0.0349318609 0.0275946204 + 0.0443095490 0.0409396514 0.0324226208 + 0.0503021218 0.0464737117 0.0369786993 + 0.0558728315 0.0517093204 0.0412629806 + 0.0610256903 0.0566021390 0.0452965386 + 0.0659263134 0.0612265393 0.0491837002 + 0.0706434101 0.0656422004 0.0528963394 + 0.0751574785 0.0698595867 0.0564641915 + 0.0794606581 0.0738903284 0.0599343516 + 0.0835847408 0.0778156295 0.0632929727 + 0.0876147822 0.0816217065 0.0665517896 + 0.0915386677 0.0853431597 0.0697500929 + 0.0953285396 0.0889591500 0.0728649125 + 0.0989516675 0.0924931094 0.0759018511 + 0.1024663970 0.0958689004 0.0788350999 + 0.1058961004 0.0991332605 0.0816867501 + 0.1092602983 0.1023299024 0.0844683573 + 0.1125695035 0.1054401994 0.0872167125 + 0.1157974973 0.1085370034 0.0899668783 + 0.1189695969 0.1115973964 0.0926889405 + 0.1221098974 0.1145918965 0.0953712016 + 0.1251875013 0.1175365001 0.0979943499 + 0.1281960011 0.1204660982 0.1005420014 + 0.1311468929 0.1233218014 0.1030569002 + 0.1340449005 0.1260855943 0.1055212021 + 0.1368933022 0.1287900954 0.1079170033 + 0.1396844983 0.1314754933 0.1103053018 + 0.1424379051 0.1341181993 0.1126656979 + 0.1451424062 0.1367079020 0.1150159985 + 0.1478171945 0.1392980963 0.1173409969 + 0.1504548937 0.1418841928 0.1196570992 + 0.1530500054 0.1444393992 0.1219561994 + 0.1555911005 0.1469538957 0.1242327988 + 0.1581020057 0.1494355053 0.1264850050 + 0.1605874002 0.1518718004 0.1287028939 + 0.1630426943 0.1542987972 0.1308919936 + 0.1654826999 0.1566974074 0.1330559999 + 0.1679003984 0.1590469033 0.1351830959 + 0.1703007966 0.1613458991 0.1372949034 + 0.1726765931 0.1636165977 0.1393575966 + 0.1750312001 0.1658513993 0.1414173990 + 0.1773743033 0.1680632979 0.1434593946 + 0.1796950996 0.1702526957 0.1454783976 + 0.1819853038 0.1724139005 0.1474941969 + 0.1842298955 0.1745467931 0.1494760960 + 0.1864486933 0.1766640991 0.1514540017 + 0.1886311024 0.1787831932 0.1534274966 + 0.1907832026 0.1809104979 0.1553764045 + 0.1929026991 0.1830410957 0.1573255062 + 0.1950244009 0.1851601005 0.1592600048 + 0.1971314996 0.1872643977 0.1611716002 + 0.1992381066 0.1893534064 0.1630840003 + 0.2013241053 0.1914180070 0.1649879962 + 0.2034000009 0.1934722960 0.1668666005 + 0.2054556012 0.1955029964 0.1687465012 + 0.2074957937 0.1975183934 0.1706251055 + 0.2095358968 0.1995349973 0.1724743992 + 0.2115648985 0.2015223950 0.1743170023 + 0.2135839015 0.2034906000 0.1761588007 + 0.2155832052 0.2054294050 0.1779755950 + 0.2175676972 0.2073418945 0.1797723025 + 0.2195197046 0.2092444003 0.1815697998 + 0.2214522064 0.2111348063 0.1833599955 + 0.2233704031 0.2130120993 0.1851364970 + 0.2252652049 0.2148773074 0.1868986040 + 0.2271434069 0.2167267948 0.1886556000 + 0.2290212065 0.2185603976 0.1903920025 + 0.2308852971 0.2203781009 0.1921014935 + 0.2327376008 0.2221764028 0.1937994957 + 0.2345706969 0.2239618003 0.1954976022 + 0.2363775074 0.2257477045 0.1971796006 + 0.2381743938 0.2275269926 0.1988390982 + 0.2399536967 0.2292968929 0.2004887015 + 0.2417089045 0.2310636044 0.2021429986 + 0.2434546947 0.2328283936 0.2037986070 + 0.2451961935 0.2345885932 0.2054408938 + 0.2469274998 0.2363439947 0.2070686072 + 0.2486505061 0.2380899042 0.2086946070 + 0.2503683865 0.2398183942 0.2103239000 + 0.2520723045 0.2415340990 0.2119438946 + 0.2537688017 0.2432458997 0.2135417014 + 0.2554596066 0.2449575067 0.2151297927 + 0.2571457028 0.2466547936 0.2167214006 + 0.2588266134 0.2483399063 0.2183215022 + 0.2605035007 0.2500117123 0.2199174017 + 0.2621727884 0.2516688108 0.2215020061 + 0.2638291121 0.2533113062 0.2230799049 + 0.2654761076 0.2549428046 0.2246621996 + 0.2671324015 0.2565666139 0.2262382060 + 0.2687830031 0.2581740022 0.2278027982 + 0.2704266906 0.2597663105 0.2293560058 + 0.2720651031 0.2613466978 0.2309001982 + 0.2737013996 0.2629151940 0.2324444950 + 0.2753258049 0.2644810081 0.2339832038 + 0.2769433856 0.2660413086 0.2355152965 + 0.2785556018 0.2675940990 0.2370389998 + 0.2801620960 0.2691347897 0.2385461032 + 0.2817465067 0.2706714869 0.2400489002 + 0.2833232880 0.2722041011 0.2415542006 + 0.2848966122 0.2737326026 0.2430642992 + 0.2864696980 0.2752566040 0.2445680946 + 0.2880344093 0.2767753899 0.2460584939 + 0.2895927131 0.2782889903 0.2475391030 + 0.2911433876 0.2797945142 0.2490137070 + 0.2926709950 0.2812936008 0.2504926920 + 0.2941831052 0.2827874124 0.2519704103 + 0.2956764996 0.2842740119 0.2534419000 + 0.2971622944 0.2857593000 0.2548941076 + 0.2986418903 0.2872450948 0.2563388944 + 0.3001124859 0.2887324095 0.2577767074 + 0.3015663028 0.2902269065 0.2592169046 + 0.3030163050 0.2917178869 0.2606565952 + 0.3044652939 0.2931961119 0.2620925903 + 0.3059149981 0.2946687043 0.2635230124 + 0.3073624074 0.2961393893 0.2649494112 + 0.3087939918 0.2976126969 0.2663621902 + 0.3102258146 0.2990801930 0.2677738965 + 0.3116576970 0.3005422950 0.2691845894 + 0.3130910993 0.3019973040 0.2705928087 + 0.3145203888 0.3034510911 0.2719972134 + 0.3159373105 0.3049038947 0.2733885944 + 0.3173550963 0.3063476980 0.2747704983 + 0.3187735975 0.3077847958 0.2761443853 + 0.3201943040 0.3092113137 0.2775141895 + 0.3216128945 0.3106358945 0.2788833082 + 0.3230192065 0.3120585084 0.2802532911 + 0.3244253993 0.3134770095 0.2816143036 + 0.3258317113 0.3148897886 0.2829608023 + 0.3272288144 0.3162913918 0.2842969000 + 0.3286210001 0.3176868856 0.2856262922 + 0.3300077021 0.3190723956 0.2869521081 + 0.3313938081 0.3204556108 0.2882770896 + 0.3327834904 0.3218250871 0.2896099091 + 0.3341748118 0.3231914043 0.2909416854 + 0.3355718851 0.3245447874 0.2922688127 + 0.3369680941 0.3258947134 0.2935900092 + 0.3383626044 0.3272379041 0.2948979139 + 0.3397515118 0.3285779953 0.2962028980 + 0.3411338925 0.3299140036 0.2975037992 + 0.3425045013 0.3312394917 0.2988072932 + 0.3438651860 0.3325557113 0.3001132905 + 0.3452149034 0.3338659108 0.3014146984 + 0.3465574980 0.3351719081 0.3027124107 + 0.3478950858 0.3364771008 0.3039973974 + 0.3492299020 0.3377816975 0.3052738011 + 0.3505575955 0.3390836120 0.3065445125 + 0.3518814147 0.3403840065 0.3078114986 + 0.3531937003 0.3416804969 0.3090800047 + 0.3544990122 0.3429746926 0.3103496134 + 0.3558034003 0.3442664146 0.3116236925 + 0.3571070135 0.3455562890 0.3129017055 + 0.3584021032 0.3468429148 0.3141731024 + 0.3596883118 0.3481261134 0.3154368103 + 0.3609679937 0.3494060040 0.3166972995 + 0.3622376919 0.3506805003 0.3179521859 + 0.3635073900 0.3519532084 0.3192068040 + 0.3647772074 0.3532207906 0.3204610050 + 0.3660452962 0.3544875979 0.3217146099 + 0.3672988117 0.3557465971 0.3229593039 + 0.3685522974 0.3570055962 0.3242039979 + 0.3697921932 0.3582544923 0.3254339099 + 0.3710305989 0.3595022857 0.3266617060 + 0.3722676039 0.3607459962 0.3278838992 + 0.3735038042 0.3619877994 0.3291031122 + 0.3747293949 0.3632284999 0.3303220868 + 0.3759411871 0.3644677997 0.3315409124 + 0.3771511018 0.3657064140 0.3327583075 + 0.3783504069 0.3669404984 0.3339653015 + 0.3795498013 0.3681747019 0.3351722956 + 0.3807409108 0.3694047034 0.3363747001 + 0.3819305003 0.3706338108 0.3375759125 + 0.3831126988 0.3718604147 0.3387717009 + 0.3842875063 0.3730843961 0.3399612010 + 0.3854615092 0.3743064106 0.3411506116 + 0.3866302967 0.3755132854 0.3423393965 + 0.3877991140 0.3767201900 0.3435282111 + 0.3889720142 0.3779211938 0.3447239101 + 0.3901464939 0.3791198134 0.3459227979 + 0.3913210928 0.3803184032 0.3471212983 + 0.3924961090 0.3815169036 0.3483184874 + 0.3936710954 0.3827154934 0.3495157063 + 0.3948434889 0.3839044869 0.3507024050 + 0.3960154057 0.3850910068 0.3518857956 + 0.3971866965 0.3862751126 0.3530685008 + 0.3983570039 0.3874529898 0.3542487919 + 0.3995273113 0.3886308074 0.3554292023 + 0.4006893039 0.3898057938 0.3566128016 + 0.4018486142 0.3909797966 0.3577977121 + 0.4030069113 0.3921526968 0.3589808941 + 0.4041604102 0.3933204114 0.3601540029 + 0.4053137898 0.3944880962 0.3613269925 + 0.4064702988 0.3956514001 0.3624922931 + 0.4076293111 0.3968113065 0.3636507988 + 0.4087882042 0.3979710937 0.3648093045 + 0.4099336863 0.3991281092 0.3659642935 + 0.4110778868 0.4002847970 0.3671188951 + 0.4122214019 0.4014416039 0.3682743013 + 0.4133622944 0.4025982916 0.3694328070 + 0.4145030975 0.4037550092 0.3705911934 + 0.4156427979 0.4049058855 0.3717437983 + 0.4167811871 0.4060513079 0.3728901148 + 0.4179196954 0.4071967900 0.3740364909 + 0.4190456867 0.4083349109 0.3751721084 + 0.4201678038 0.4094707966 0.3763037920 + 0.4212898910 0.4106067121 0.3774355054 + 0.4224098921 0.4117316902 0.3785631061 + 0.4235298932 0.4128564000 0.3796902895 + 0.4246496856 0.4139792919 0.3808172047 + 0.4257684946 0.4150904119 0.3819408119 + 0.4268873036 0.4162015915 0.3830643892 + 0.4280022085 0.4173096120 0.3841860890 + 0.4291062951 0.4184089899 0.3853017092 + 0.4302105010 0.4195083976 0.3864172995 + 0.4313144088 0.4206028879 0.3875293136 + 0.4324178994 0.4216887951 0.3886339068 + 0.4335213900 0.4227746129 0.3897385001 + 0.4346221089 0.4238578081 0.3908396959 + 0.4357188940 0.4249371886 0.3919354081 + 0.4368157089 0.4260165095 0.3930310011 + 0.4379082918 0.4270943105 0.3941242993 + 0.4389953017 0.4281699061 0.3952139020 + 0.4400823116 0.4292455018 0.3963035047 + 0.4411674142 0.4303215146 0.3973940909 + 0.4422496855 0.4313979149 0.3984861970 + 0.4433319867 0.4324742854 0.3995783925 + 0.4444083869 0.4335477054 0.4006663859 + 0.4454728067 0.4346148074 0.4017446041 + 0.4465371966 0.4356819093 0.4028229117 + 0.4475978017 0.4367474020 0.4038993120 + 0.4486451149 0.4378075898 0.4049679935 + 0.4496923983 0.4388678074 0.4060367942 + 0.4507394135 0.4399277866 0.4071055055 + 0.4517830014 0.4409854114 0.4081743062 + 0.4528265893 0.4420430064 0.4092431962 + 0.4538702071 0.4431006014 0.4103119969 + 0.4549070001 0.4441545904 0.4113866985 + 0.4559428096 0.4452080131 0.4124625027 + 0.4569785893 0.4462614954 0.4135383964 + 0.4580070078 0.4473111033 0.4146097898 + 0.4590308964 0.4483582973 0.4156782031 + 0.4600548148 0.4494056106 0.4167467058 + 0.4610792100 0.4504511952 0.4178118110 + 0.4621045887 0.4514938891 0.4188697040 + 0.4631299078 0.4525366127 0.4199275970 + 0.4641552866 0.4535791874 0.4209854901 + 0.4651829898 0.4546158910 0.4220423996 + 0.4662106931 0.4556525946 0.4230993092 + 0.4672383964 0.4566892982 0.4241561890 + 0.4682591856 0.4577207863 0.4252122045 + 0.4692761898 0.4587494135 0.4262678027 + 0.4702933133 0.4597780108 0.4273233116 + 0.4713107944 0.4608063996 0.4283765852 + 0.4723303020 0.4618338943 0.4294205010 + 0.4733496904 0.4628615081 0.4304643869 + 0.4743691981 0.4638890922 0.4315083921 + 0.4753845930 0.4649214149 0.4325434864 + 0.4763987958 0.4659551084 0.4335753918 + 0.4774129987 0.4669888914 0.4346072972 + 0.4784238040 0.4680216014 0.4356386065 + 0.4794248044 0.4690510035 0.4366680086 + 0.4804258049 0.4700804055 0.4376974106 + 0.4814268053 0.4711098969 0.4387268126 + 0.4824292958 0.4721364081 0.4397540987 + 0.4834325016 0.4731616974 0.4407801926 + 0.4844357967 0.4741868973 0.4418064058 + 0.4854384959 0.4752117991 0.4428318143 + 0.4864360988 0.4762332141 0.4438445866 + 0.4874337018 0.4772545099 0.4448573887 + 0.4884313047 0.4782758951 0.4458701015 + 0.4894233942 0.4792912900 0.4468775094 + 0.4904080927 0.4802986085 0.4478765130 + 0.4913927913 0.4813058972 0.4488754869 + 0.4923774898 0.4823131859 0.4498746097 + 0.4933621883 0.4833154976 0.4508705139 + 0.4943468869 0.4843156934 0.4518648982 + 0.4953315854 0.4853160083 0.4528594017 + 0.4963161945 0.4863162041 0.4538537860 + 0.4972892106 0.4873186946 0.4548524916 + 0.4982616901 0.4883211851 0.4558514953 + 0.4992341995 0.4893237948 0.4568504989 + 0.5002049804 0.4903247058 0.4578497112 + 0.5011661053 0.4913162887 0.4588507116 + 0.5021272898 0.4923079908 0.4598517120 + 0.5030884743 0.4932996035 0.4608527124 + 0.5040500164 0.4942877889 0.4618506134 + 0.5050122142 0.4952678084 0.4628399909 + 0.5059744120 0.4962477982 0.4638293982 + 0.5069364905 0.4972277880 0.4648188055 + 0.5078973770 0.4982069135 0.4658063948 + 0.5088561773 0.4991844893 0.4667905867 + 0.5098149180 0.5001621842 0.4677748084 + 0.5107737184 0.5011398196 0.4687590897 + 0.5117294192 0.5021172762 0.4697437882 + 0.5126808882 0.5030944943 0.4707294106 + 0.5136322975 0.5040717721 0.4717150033 + 0.5145838261 0.5050491095 0.4727005959 + 0.5155330896 0.5060225725 0.4736824036 + 0.5164790154 0.5069903135 0.4746578038 + 0.5174250007 0.5079579949 0.4756332040 + 0.5183709264 0.5089256763 0.4766086042 + 0.5193127990 0.5098916888 0.4775812924 + 0.5202462077 0.5108541250 0.4785476029 + 0.5211796165 0.5118165016 0.4795139134 + 0.5221130252 0.5127789974 0.4804801941 + 0.5230445862 0.5137407780 0.4814454019 + 0.5239686966 0.5147001743 0.4824050069 + 0.5248929262 0.5156595111 0.4833647013 + 0.5258170962 0.5166189075 0.4843243062 + 0.5267412066 0.5175781846 0.4852839112 + 0.5276607275 0.5185251236 0.4862455130 + 0.5285801291 0.5194721222 0.4872071147 + 0.5294994712 0.5204190016 0.4881686866 + 0.5304189920 0.5213660002 0.4891302884 + 0.5313292146 0.5223047137 0.4900931120 + 0.5322365761 0.5232409239 0.4910562038 + 0.5331441164 0.5241770744 0.4920192957 + 0.5340514779 0.5251134038 0.4929825068 + 0.5349549055 0.5260437131 0.4939421117 + 0.5358536243 0.5269672871 0.4948973954 + 0.5367524028 0.5278909802 0.4958527088 + 0.5376511216 0.5288146138 0.4968079925 + 0.5385501981 0.5297368169 0.4977625012 + 0.5394514799 0.5306468010 0.4987092912 + 0.5403528214 0.5315569043 0.4996561110 + 0.5412541032 0.5324670076 0.5006029010 + 0.5421553850 0.5333769917 0.5015497208 + 0.5430505276 0.5342804193 0.5024966002 + 0.5439429879 0.5351806879 0.5034434199 + 0.5448353887 0.5360810161 0.5043902993 + 0.5457279086 0.5369812846 0.5053371191 + 0.5466185808 0.5378801227 0.5062835217 + 0.5475032926 0.5387730002 0.5072280169 + 0.5483881235 0.5396658778 0.5081725121 + 0.5492727757 0.5405586958 0.5091168880 + 0.5501574874 0.5414515734 0.5100613832 + 0.5510445833 0.5423436761 0.5109959245 + 0.5519328117 0.5432354808 0.5119252205 + 0.5528209805 0.5441272259 0.5128543973 + 0.5537092090 0.5450189710 0.5137836933 + 0.5545967221 0.5459102988 0.5147123933 + 0.5554770827 0.5467962027 0.5156326890 + 0.5563575029 0.5476821065 0.5165529251 + 0.5572379231 0.5485680103 0.5174731016 + 0.5581182837 0.5494539142 0.5183933973 + 0.5589959025 0.5503361821 0.5193132758 + 0.5598695874 0.5512136221 0.5202329159 + 0.5607432723 0.5520910025 0.5211526155 + 0.5616170168 0.5529683828 0.5220721960 + 0.5624907017 0.5538457036 0.5229917765 + 0.5633659959 0.5547165871 0.5239105821 + 0.5642418861 0.5555846095 0.5248289704 + 0.5651177168 0.5564525723 0.5257474184 + 0.5659936070 0.5573204756 0.5266659260 + 0.5668694973 0.5581884980 0.5275843143 + 0.5677334070 0.5590493083 0.5284937024 + 0.5685961246 0.5599092841 0.5294020176 + 0.5694587827 0.5607693791 0.5303102136 + 0.5703215003 0.5616294146 0.5312184095 + 0.5711839199 0.5624892712 0.5321263075 + 0.5720422268 0.5633450747 0.5330240726 + 0.5729004741 0.5642009974 0.5339217782 + 0.5737587214 0.5650569201 0.5348194838 + 0.5746170282 0.5659127235 0.5357171893 + 0.5754747987 0.5667679906 0.5366147161 + 0.5763297081 0.5676189065 0.5375100970 + 0.5771846175 0.5684698820 0.5384054184 + 0.5780395269 0.5693207979 0.5393007994 + 0.5788943768 0.5701717734 0.5401961803 + 0.5797473192 0.5710228086 0.5410919785 + 0.5805879831 0.5718737841 0.5419911146 + 0.5814288259 0.5727248788 0.5428900719 + 0.5822694898 0.5735759735 0.5437892079 + 0.5831102133 0.5744271278 0.5446882248 + 0.5839506984 0.5752779245 0.5455867052 + 0.5847879052 0.5761266947 0.5464770794 + 0.5856251717 0.5769755244 0.5473675132 + 0.5864624977 0.5778242946 0.5482578874 + 0.5872997046 0.5786731243 0.5491483212 + 0.5881369710 0.5795218945 0.5500386953 + 0.5889738798 0.5803651810 0.5509185791 + 0.5898107290 0.5812082887 0.5517979264 + 0.5906475782 0.5820513964 0.5526772141 + 0.5914844871 0.5828943849 0.5535565019 + 0.5923212767 0.5837374926 0.5544357896 + 0.5931525826 0.5845798850 0.5553128123 + 0.5939822793 0.5854220986 0.5561890006 + 0.5948119760 0.5862641931 0.5570651889 + 0.5956416130 0.5871064067 0.5579413772 + 0.5964713097 0.5879485011 0.5588176250 + 0.5972992182 0.5887913704 0.5596930981 + 0.5981255174 0.5896348953 0.5605677962 + 0.5989518166 0.5904784799 0.5614423752 + 0.5997781157 0.5913220048 0.5623170733 + 0.6006044149 0.5921655297 0.5631917715 + 0.6014305949 0.5930098891 0.5640664101 + 0.6022564769 0.5938585997 0.5649405122 + 0.6030824184 0.5947071910 0.5658146739 + 0.6039084196 0.5955557823 0.5666887760 + 0.6047343016 0.5964043736 0.5675628781 + 0.6055601835 0.5972530246 0.5684370995 + 0.6063808799 0.5980986953 0.5693032742 + 0.6072000861 0.5989435911 0.5701668262 + 0.6080192924 0.5997886062 0.5710303783 + 0.6088384986 0.6006335020 0.5718938708 + 0.6096577048 0.6014783978 0.5727574229 + 0.6104760170 0.6023222804 0.5736197233 + 0.6112921238 0.6031637192 0.5744786263 + 0.6121081710 0.6040052176 0.5753375292 + 0.6129242778 0.6048465967 0.5761963725 + 0.6137403846 0.6056880951 0.5770552158 + 0.6145564914 0.6065294743 0.5779141188 + 0.6153724194 0.6073685288 0.5787752271 + 0.6161882877 0.6082066298 0.5796372294 + 0.6170042157 0.6090446711 0.5804991722 + 0.6178200245 0.6098828912 0.5813611746 + 0.6186358929 0.6107209921 0.5822231770 + 0.6194511056 0.6115579009 0.5830852985 + 0.6202605963 0.6123844981 0.5839483142 + 0.6210700870 0.6132110953 0.5848112106 + 0.6218796968 0.6140376925 0.5856742263 + 0.6226891875 0.6148642898 0.5865371823 + 0.6234986782 0.6156908870 0.5874001980 + 0.6243069768 0.6165152192 0.5882589817 + 0.6251134276 0.6173359752 0.5891109109 + 0.6259198189 0.6181567907 0.5899628997 + 0.6267263293 0.6189776063 0.5908148289 + 0.6275327206 0.6197984219 0.5916668177 + 0.6283391118 0.6206191778 0.5925186872 + 0.6291438937 0.6214398742 0.5933675170 + 0.6299477220 0.6222605109 0.5942140818 + 0.6307514906 0.6230810285 0.5950608253 + 0.6315551996 0.6239016056 0.5959073901 + 0.6323590279 0.6247221231 0.5967540145 + 0.6331627965 0.6255427003 0.5976006985 + 0.6339570284 0.6263571978 0.5984491706 + 0.6347482204 0.6271697283 0.5992982984 + 0.6355394125 0.6279821992 0.6001474261 + 0.6363306046 0.6287947297 0.6009964943 + 0.6371217966 0.6296073198 0.6018456221 + 0.6379129887 0.6304197907 0.6026948094 + 0.6387022138 0.6312273741 0.6035407782 + 0.6394910812 0.6320338845 0.6043862104 + 0.6402798891 0.6328405142 0.6052315235 + 0.6410686970 0.6336470246 0.6060767770 + 0.6418575048 0.6344534755 0.6069220901 + 0.6426463127 0.6352599859 0.6077674031 + 0.6434336901 0.6360661983 0.6086056828 + 0.6442208290 0.6368721128 0.6094418764 + 0.6450079083 0.6376780868 0.6102781296 + 0.6457949877 0.6384841204 0.6111143827 + 0.6465821266 0.6392900944 0.6119505763 + 0.6473692060 0.6400961280 0.6127868295 + 0.6481484771 0.6408988237 0.6136180162 + 0.6489244103 0.6417000294 0.6144466996 + 0.6497004032 0.6425011158 0.6152755022 + 0.6504762769 0.6433023214 0.6161041856 + 0.6512522101 0.6441034079 0.6169329286 + 0.6520280838 0.6449046135 0.6177616119 + 0.6528034210 0.6457012296 0.6185904145 + 0.6535782218 0.6464933753 0.6194192767 + 0.6543530226 0.6472855210 0.6202481985 + 0.6551278234 0.6480777264 0.6210771203 + 0.6559026241 0.6488698125 0.6219059825 + 0.6566773057 0.6496618986 0.6227349043 + 0.6574509144 0.6504533291 0.6235638261 + 0.6582205296 0.6512417793 0.6243926287 + 0.6589900851 0.6520304084 0.6252213120 + 0.6597597003 0.6528189778 0.6260501146 + 0.6605293155 0.6536074877 0.6268787980 + 0.6612988710 0.6543961167 0.6277076006 + 0.6620684266 0.6551846862 0.6285362840 + 0.6628314257 0.6559717059 0.6293578744 + 0.6635934114 0.6567586064 0.6301782727 + 0.6643555164 0.6575453877 0.6309986711 + 0.6651175022 0.6583322883 0.6318191290 + 0.6658794880 0.6591191292 0.6326395273 + 0.6666415930 0.6599059105 0.6334599257 + 0.6674026251 0.6606888175 0.6342766881 + 0.6681625247 0.6614663005 0.6350883245 + 0.6689224243 0.6622439027 0.6359000206 + 0.6696822047 0.6630213857 0.6367117167 + 0.6704421043 0.6637989879 0.6375232935 + 0.6712018847 0.6645764709 0.6383349895 + 0.6719617844 0.6653540134 0.6391466856 + 0.6727159023 0.6661242843 0.6399570704 + 0.6734694839 0.6668937802 0.6407673955 + 0.6742231250 0.6676632762 0.6415776014 + 0.6749765873 0.6684327722 0.6423879266 + 0.6757302284 0.6692023277 0.6431981921 + 0.6764838099 0.6699718237 0.6440083981 + 0.6772350073 0.6707385778 0.6448181868 + 0.6779803038 0.6714984775 0.6456267834 + 0.6787256002 0.6722583771 0.6464353204 + 0.6794708967 0.6730182767 0.6472437978 + 0.6802163124 0.6737781763 0.6480523944 + 0.6809616089 0.6745380759 0.6488608718 + 0.6817069054 0.6752979755 0.6496694088 + 0.6824505925 0.6760519147 0.6504725218 + 0.6831930876 0.6768013239 0.6512712836 + 0.6839357018 0.6775506735 0.6520701051 + 0.6846781969 0.6783000827 0.6528689265 + 0.6854206920 0.6790493727 0.6536676884 + 0.6861631870 0.6797987819 0.6544665098 + 0.6869056821 0.6805481911 0.6552652717 + 0.6876466274 0.6812918782 0.6560565233 + 0.6883869171 0.6820340157 0.6568452716 + 0.6891273260 0.6827760935 0.6576340795 + 0.6898676157 0.6835181713 0.6584228873 + 0.6906079054 0.6842603087 0.6592115760 + 0.6913483143 0.6850023866 0.6600003839 + 0.6920886040 0.6857444048 0.6607891917 + 0.6928188801 0.6864817142 0.6615756750 + 0.6935479045 0.6872183084 0.6623616815 + 0.6942768097 0.6879549026 0.6631476879 + 0.6950057745 0.6886916161 0.6639338136 + 0.6957347989 0.6894282103 0.6647198200 + 0.6964638233 0.6901648045 0.6655058861 + 0.6971927285 0.6909013987 0.6662918925 + 0.6979197860 0.6916376948 0.6670784950 + 0.6986466050 0.6923738718 0.6678652167 + 0.6993734241 0.6931101084 0.6686518788 + 0.7001003027 0.6938462853 0.6694386005 + 0.7008271217 0.6945825219 0.6702252030 + 0.7015538812 0.6953186989 0.6710119247 + 0.7022808194 0.6960549951 0.6717985868 + 0.7030063272 0.6967895031 0.6725746989 + 0.7037315965 0.6975237131 0.6733481884 + 0.7044569254 0.6982578039 0.6741216779 + 0.7051821947 0.6989920139 0.6748952270 + 0.7059075236 0.6997262239 0.6756685972 + 0.7066327929 0.7004603744 0.6764420867 + 0.7073581219 0.7011945248 0.6772155762 + 0.7080765963 0.7019280195 0.6779829264 + 0.7087914944 0.7026610970 0.6787465811 + 0.7095062733 0.7033942938 0.6795102954 + 0.7102211714 0.7041273713 0.6802740097 + 0.7109360099 0.7048605084 0.6810376048 + 0.7116509080 0.7055935860 0.6818013191 + 0.7123658061 0.7063267231 0.6825649738 + 0.7130801082 0.7070569992 0.6833276749 + 0.7137935758 0.7077823877 0.6840885878 + 0.7145071030 0.7085077763 0.6848495007 + 0.7152206898 0.7092332244 0.6856104732 + 0.7159342170 0.7099586129 0.6863713861 + 0.7166476846 0.7106840014 0.6871322989 + 0.7173612118 0.7114093900 0.6878932714 + 0.7180746794 0.7121347785 0.6886541843 + 0.7187874913 0.7128537893 0.6894174218 + 0.7195001841 0.7135729194 0.6901807785 + 0.7202129960 0.7142918706 0.6909440756 + 0.7209258080 0.7150110006 0.6917073727 + 0.7216385007 0.7157300115 0.6924707294 + 0.7223513126 0.7164490223 0.6932340264 + 0.7230641246 0.7171680927 0.6939973235 + 0.7237719297 0.7178853154 0.6947563887 + 0.7244753242 0.7186009884 0.6955114007 + 0.7251787782 0.7193167210 0.6962664127 + 0.7258821726 0.7200323939 0.6970214248 + 0.7265856862 0.7207481265 0.6977763772 + 0.7272890806 0.7214637995 0.6985313892 + 0.7279925942 0.7221794128 0.6992864013 + 0.7286959887 0.7228950858 0.7000414133 + 0.7293974161 0.7236070037 0.7007868290 + 0.7300986052 0.7243188024 0.7015315890 + 0.7307999134 0.7250304818 0.7022762895 + 0.7315011024 0.7257422209 0.7030211091 + 0.7322024107 0.7264540195 0.7037658095 + 0.7329035997 0.7271656990 0.7045106292 + 0.7336049080 0.7278773785 0.7052553296 + 0.7343035936 0.7285876274 0.7059991956 + 0.7349956036 0.7292935252 0.7067406774 + 0.7356876731 0.7299994826 0.7074822187 + 0.7363798022 0.7307054996 0.7082235813 + 0.7370718122 0.7314115167 0.7089651227 + 0.7377638817 0.7321174741 0.7097066045 + 0.7384558916 0.7328234911 0.7104480267 + 0.7391480207 0.7335295081 0.7111895084 + 0.7398372293 0.7342340946 0.7119327188 + 0.7405235767 0.7349374294 0.7126777768 + 0.7412099838 0.7356405854 0.7134228945 + 0.7418963909 0.7363438010 0.7141680121 + 0.7425827980 0.7370470762 0.7149130702 + 0.7432692051 0.7377502918 0.7156581879 + 0.7439556122 0.7384536266 0.7164033055 + 0.7446420193 0.7391567826 0.7171484232 + 0.7453268766 0.7398598194 0.7178943753 + 0.7460108995 0.7405626178 0.7186409831 + 0.7466949224 0.7412652969 0.7193875909 + 0.7473788857 0.7419680953 0.7201341987 + 0.7480629086 0.7426708937 0.7208808064 + 0.7487468719 0.7433736920 0.7216274142 + 0.7494308949 0.7440764904 0.7223740220 + 0.7501149178 0.7447792292 0.7231205106 + 0.7507920861 0.7454807758 0.7238616943 + 0.7514652014 0.7461814880 0.7245994210 + 0.7521383166 0.7468823195 0.7253370285 + 0.7528113127 0.7475829720 0.7260746956 + 0.7534844279 0.7482838035 0.7268123031 + 0.7541574836 0.7489845753 0.7275499105 + 0.7548305988 0.7496852875 0.7282875776 + 0.7555037141 0.7503861189 0.7290251851 + 0.7561715245 0.7510858178 0.7297608852 + 0.7568343878 0.7517846227 0.7304946780 + 0.7574973106 0.7524833083 0.7312284708 + 0.7581601739 0.7531821132 0.7319623232 + 0.7588232160 0.7538809180 0.7326961160 + 0.7594860792 0.7545796037 0.7334299088 + 0.7601490021 0.7552784085 0.7341635823 + 0.7608119249 0.7559772134 0.7348973751 + 0.7614743710 0.7566753030 0.7356321216 + 0.7621356845 0.7573720217 0.7363687754 + 0.7627969980 0.7580686808 0.7371054888 + 0.7634583116 0.7587653995 0.7378422022 + 0.7641196251 0.7594621181 0.7385789156 + 0.7647809982 0.7601587772 0.7393156290 + 0.7654423118 0.7608554959 0.7400524020 + 0.7661036253 0.7615522146 0.7407891154 + 0.7667648792 0.7622489929 0.7415258288 + 0.7674220204 0.7629417777 0.7422630191 + 0.7680791020 0.7636345029 0.7430003285 + 0.7687361240 0.7643272877 0.7437375188 + 0.7693930864 0.7650200725 0.7444748282 + 0.7700502276 0.7657127976 0.7452120185 + 0.7707071900 0.7664055824 0.7459493279 + 0.7713642120 0.7670983076 0.7466865182 + 0.7720212936 0.7677910924 0.7474238276 + 0.7726746202 0.7684819102 0.7481557727 + 0.7733249068 0.7691711783 0.7488833070 + 0.7739751935 0.7698603868 0.7496107817 + 0.7746254802 0.7705495954 0.7503383160 + 0.7752758265 0.7712389231 0.7510657907 + 0.7759261131 0.7719280720 0.7517933249 + 0.7765762806 0.7726173997 0.7525207996 + 0.7772266269 0.7733066082 0.7532482743 + 0.7778769135 0.7739958167 0.7539758086 + 0.7785270810 0.7746813893 0.7546988130 + 0.7791771889 0.7753669024 0.7554215789 + 0.7798274159 0.7760524154 0.7561445236 + 0.7804775238 0.7767379284 0.7568672895 + 0.7811276913 0.7774235010 0.7575901747 + 0.7817777991 0.7781090140 0.7583130002 + 0.7824279070 0.7787945271 0.7590358853 + 0.7830780745 0.7794799805 0.7597587109 + 0.7837272286 0.7801622152 0.7604821920 + 0.7843742967 0.7808375955 0.7612072229 + 0.7850214839 0.7815129757 0.7619320750 + 0.7856686115 0.7821882963 0.7626569867 + 0.7863156796 0.7828636765 0.7633818984 + 0.7869629264 0.7835391164 0.7641068101 + 0.7876099944 0.7842144966 0.7648317218 + 0.7882571220 0.7848898768 0.7655565739 + 0.7889041901 0.7855653167 0.7662814856 + 0.7895485163 0.7862368822 0.7670075297 + 0.7901902795 0.7869054079 0.7677345276 + 0.7908321023 0.7875739932 0.7684614062 + 0.7914739847 0.7882425189 0.7691884041 + 0.7921158075 0.7889109850 0.7699152827 + 0.7927575707 0.7895795107 0.7706422806 + 0.7933995128 0.7902479768 0.7713692188 + 0.7940412760 0.7909166217 0.7720962167 + 0.7946830988 0.7915850878 0.7728230953 + 0.7953270078 0.7922512889 0.7735466957 + 0.7959719896 0.7929161191 0.7742683291 + 0.7966169715 0.7935810089 0.7749899030 + 0.7972620130 0.7942458987 0.7757114768 + 0.7979069948 0.7949107289 0.7764332294 + 0.7985519171 0.7955756187 0.7771548033 + 0.7991968989 0.7962405086 0.7778763771 + 0.7998418808 0.7969053984 0.7785980105 + 0.8004869223 0.7975702286 0.7793195844 + 0.8011307120 0.7982336879 0.7800378203 + 0.8017739058 0.7988961935 0.7807539105 + 0.8024169803 0.7995588183 0.7814698815 + 0.8030601144 0.8002213836 0.7821859121 + 0.8037033081 0.8008840084 0.7829018831 + 0.8043463826 0.8015465140 0.7836179137 + 0.8049895763 0.8022090793 0.7843340039 + 0.8056327105 0.8028717041 0.7850499749 + 0.8062757850 0.8035342097 0.7857660055 + 0.8069155812 0.8041942716 0.7864825130 + 0.8075515032 0.8048514128 0.7871994972 + 0.8081874251 0.8055086136 0.7879164815 + 0.8088234067 0.8061658144 0.7886335254 + 0.8094593287 0.8068230152 0.7893505096 + 0.8100953102 0.8074802160 0.7900676131 + 0.8107311726 0.8081374168 0.7907845974 + 0.8113672137 0.8087946177 0.7915015817 + 0.8120030761 0.8094516993 0.7922186255 + 0.8126395941 0.8101087809 0.7929350138 + 0.8132783771 0.8107650876 0.7936488986 + 0.8139171004 0.8114215136 0.7943627834 + 0.8145558834 0.8120778203 0.7950767279 + 0.8151946068 0.8127341866 0.7957904935 + 0.8158333898 0.8133906126 0.7965043783 + 0.8164721131 0.8140469193 0.7972183228 + 0.8171108961 0.8147032857 0.7979322076 + 0.8177496195 0.8153595924 0.7986459732 + 0.8183884025 0.8160160184 0.7993599176 + 0.8190252781 0.8166726828 0.8000699878 + 0.8196616769 0.8173294067 0.8007791042 + 0.8202980757 0.8179860711 0.8014882803 + 0.8209344745 0.8186429143 0.8021973968 + 0.8215708733 0.8192995787 0.8029065132 + 0.8222072721 0.8199563026 0.8036156297 + 0.8228437901 0.8206130862 0.8043248057 + 0.8234801888 0.8212698102 0.8050339222 + 0.8241165876 0.8219264746 0.8057429790 + 0.8247510195 0.8225817084 0.8064500093 + 0.8253805041 0.8232325912 0.8071511984 + 0.8260099292 0.8238834739 0.8078523874 + 0.8266394138 0.8245344758 0.8085535169 + 0.8272687793 0.8251854181 0.8092547059 + 0.8278983235 0.8258364201 0.8099558949 + 0.8285278082 0.8264873028 0.8106570840 + 0.8291571736 0.8271383047 0.8113582730 + 0.8297867179 0.8277891874 0.8120595217 + 0.8304160833 0.8284401298 0.8127607107 + 0.8310465217 0.8290880919 0.8134608269 + 0.8316774964 0.8297342062 0.8141604066 + 0.8323084116 0.8303803205 0.8148599267 + 0.8329393864 0.8310263753 0.8155595064 + 0.8335703015 0.8316724896 0.8162590265 + 0.8342012763 0.8323186040 0.8169584870 + 0.8348321915 0.8329647779 0.8176581264 + 0.8354632258 0.8336108923 0.8183575869 + 0.8360940814 0.8342570066 0.8190571070 + 0.8367251158 0.8349031210 0.8197566867 + 0.8373507261 0.8355441093 0.8204557896 + 0.8379753232 0.8361840844 0.8211548924 + 0.8385999203 0.8368241787 0.8218539953 + 0.8392245173 0.8374642134 0.8225530982 + 0.8398491144 0.8381041884 0.8232522011 + 0.8404737711 0.8387442231 0.8239513040 + 0.8410984278 0.8393843174 0.8246504068 + 0.8417230248 0.8400242925 0.8253493905 + 0.8423476219 0.8406643271 0.8260484934 + 0.8429722190 0.8413044214 0.8267475963 + 0.8435915112 0.8419380188 0.8274425268 + 0.8442103863 0.8425710201 0.8281369209 + 0.8448292017 0.8432040811 0.8288313746 + 0.8454480767 0.8438372016 0.8295258284 + 0.8460670114 0.8444703221 0.8302202821 + 0.8466858268 0.8451033831 0.8309146762 + 0.8473047018 0.8457365036 0.8316091895 + 0.8479235768 0.8463695049 0.8323035836 + 0.8485423923 0.8470026255 0.8329980969 + 0.8491613269 0.8476356864 0.8336924911 + 0.8497756720 0.8482635021 0.8343786001 + 0.8503894210 0.8488906026 0.8350632787 + 0.8510032296 0.8495177031 0.8357480764 + 0.8516169190 0.8501448035 0.8364328146 + 0.8522306085 0.8507717848 0.8371176124 + 0.8528444171 0.8513988853 0.8378022909 + 0.8534581065 0.8520259857 0.8384870291 + 0.8540717959 0.8526530266 0.8391718268 + 0.8546856046 0.8532801270 0.8398565054 + 0.8552992940 0.8539072275 0.8405413032 + 0.8559076786 0.8545295000 0.8412235975 + 0.8565136194 0.8551496863 0.8419046998 + 0.8571195006 0.8557698727 0.8425859213 + 0.8577255011 0.8563901186 0.8432670832 + 0.8583313823 0.8570103049 0.8439481854 + 0.8589373231 0.8576303720 0.8446294069 + 0.8595432043 0.8582506180 0.8453105092 + 0.8601492047 0.8588708043 0.8459916711 + 0.8607550859 0.8594909906 0.8466727734 + 0.8613610268 0.8601111770 0.8473539948 + 0.8619657755 0.8607302904 0.8480353951 + 0.8625686765 0.8613476157 0.8487172723 + 0.8631715178 0.8619648814 0.8493992090 + 0.8637742996 0.8625822067 0.8500810862 + 0.8643772006 0.8631994724 0.8507630825 + 0.8649799824 0.8638167977 0.8514450192 + 0.8655828238 0.8644341230 0.8521268964 + 0.8661857247 0.8650513291 0.8528087735 + 0.8667885065 0.8656685948 0.8534907103 + 0.8673914075 0.8662859201 0.8541725874 + 0.8679941893 0.8669031858 0.8548545241 + 0.8685936928 0.8675162196 0.8555287719 + 0.8691927195 0.8681287169 0.8562021255 + 0.8697918057 0.8687412143 0.8568754196 + 0.8703907728 0.8693537116 0.8575487137 + 0.8709899187 0.8699662089 0.8582220078 + 0.8715888858 0.8705787063 0.8588953018 + 0.8721879721 0.8711912036 0.8595685959 + 0.8727869987 0.8718037009 0.8602418900 + 0.8733860850 0.8724161983 0.8609151840 + 0.8739851117 0.8730286956 0.8615884781 + 0.8745809793 0.8736391068 0.8622589707 + 0.8751688004 0.8742442727 0.8629223108 + 0.8757566214 0.8748494983 0.8635854721 + 0.8763445020 0.8754547238 0.8642486930 + 0.8769323230 0.8760598898 0.8649119735 + 0.8775202036 0.8766651750 0.8655751944 + 0.8781080246 0.8772704005 0.8662384152 + 0.8786959052 0.8778756261 0.8669016957 + 0.8792837262 0.8784807920 0.8675649166 + 0.8798714876 0.8790860176 0.8682280779 + 0.8804594278 0.8796913028 0.8688914180 + 0.8810451031 0.8802946210 0.8695524931 + 0.8816289902 0.8808963895 0.8702116013 + 0.8822128773 0.8814982176 0.8708708286 + 0.8827967048 0.8820999861 0.8715299964 + 0.8833805919 0.8827018142 0.8721891046 + 0.8839644790 0.8833035827 0.8728482723 + 0.8845484257 0.8839052916 0.8735073805 + 0.8851323128 0.8845071197 0.8741666079 + 0.8857161999 0.8851088881 0.8748257756 + 0.8863000274 0.8857107162 0.8754848838 + 0.8868839145 0.8863124847 0.8761441112 + 0.8874658942 0.8869127035 0.8768044114 + 0.8880469203 0.8875120878 0.8774654865 + 0.8886278272 0.8881114721 0.8781265020 + 0.8892087936 0.8887107968 0.8787875772 + 0.8897898197 0.8893101811 0.8794485927 + 0.8903707266 0.8899096251 0.8801097274 + 0.8909516931 0.8905088902 0.8807706833 + 0.8915325999 0.8911082745 0.8814318180 + 0.8921136260 0.8917077184 0.8820927739 + 0.8926944733 0.8923069835 0.8827539086 + 0.8932754993 0.8929064274 0.8834149241 + 0.8938503861 0.8935058713 0.8840740919 + 0.8944211006 0.8941053748 0.8847320080 + 0.8949918151 0.8947049975 0.8853899240 + 0.8955624104 0.8953045011 0.8860477805 + 0.8961331248 0.8959041238 0.8867056966 + 0.8967037797 0.8965036273 0.8873636127 + 0.8972744942 0.8971031904 0.8880215287 + 0.8978450894 0.8977026939 0.8886793852 + 0.8984158039 0.8983023167 0.8893373013 + 0.8989865184 0.8989018202 0.8899952173 + 0.8995571733 0.8995013237 0.8906530738 + 0.9001259804 0.9000989199 0.8913081884 + 0.9006919265 0.9006931782 0.8919588923 + 0.9012578726 0.9012876153 0.8926094770 + 0.9018238187 0.9018818736 0.8932601810 + 0.9023898244 0.9024763107 0.8939108849 + 0.9029557109 0.9030706286 0.8945615888 + 0.9035217166 0.9036650062 0.8952121735 + 0.9040876031 0.9042593241 0.8958628774 + 0.9046536088 0.9048537016 0.8965135813 + 0.9052194953 0.9054480195 0.8971642852 + 0.9057855010 0.9060423970 0.8978149295 + 0.9063512087 0.9066365957 0.8984653950 + 0.9069120884 0.9072268009 0.8991103768 + 0.9074729085 0.9078170061 0.8997554183 + 0.9080337882 0.9084072113 0.9004002810 + 0.9085947275 0.9089974165 0.9010453224 + 0.9091554880 0.9095876217 0.9016903043 + 0.9097164273 0.9101778865 0.9023352265 + 0.9102773070 0.9107680917 0.9029802084 + 0.9108381867 0.9113582969 0.9036251903 + 0.9113990068 0.9119485021 0.9042701721 + 0.9119598866 0.9125387073 0.9049150944 + 0.9125208259 0.9131289124 0.9055600762 + 0.9130790234 0.9137184024 0.9062044024 + 0.9136350155 0.9143071771 0.9068480134 + 0.9141910076 0.9148960114 0.9074916244 + 0.9147469997 0.9154847860 0.9081352949 + 0.9153029919 0.9160736799 0.9087789059 + 0.9158589840 0.9166625142 0.9094225168 + 0.9164149761 0.9172512889 0.9100661874 + 0.9169710279 0.9178401232 0.9107097983 + 0.9175270200 0.9184290171 0.9113535285 + 0.9180830121 0.9190177917 0.9119970798 + 0.9186390042 0.9196066260 0.9126406908 + 0.9191949964 0.9201954007 0.9132844210 + 0.9197478294 0.9207763076 0.9139227867 + 0.9203000069 0.9213560820 0.9145606160 + 0.9208523035 0.9219357967 0.9151983261 + 0.9214046001 0.9225155711 0.9158360958 + 0.9219568968 0.9230954051 0.9164738059 + 0.9225091934 0.9236751795 0.9171115756 + 0.9230613708 0.9242548943 0.9177492857 + 0.9236137271 0.9248347282 0.9183871150 + 0.9241660237 0.9254145026 0.9190248251 + 0.9247183204 0.9259942770 0.9196625948 + 0.9252706170 0.9265739918 0.9203003049 + 0.9258226752 0.9271532297 0.9209372997 + 0.9263734221 0.9277231097 0.9215620756 + 0.9269239902 0.9282929897 0.9221869111 + 0.9274746776 0.9288629889 0.9228116870 + 0.9280253053 0.9294329286 0.9234365225 + 0.9285759926 0.9300028086 0.9240614176 + 0.9291266203 0.9305726886 0.9246861935 + 0.9296773076 0.9311426282 0.9253110290 + 0.9302278757 0.9317126274 0.9259358048 + 0.9307786226 0.9322825074 0.9265605807 + 0.9313291907 0.9328523874 0.9271854162 + 0.9318798780 0.9334223270 0.9278101921 + 0.9324297905 0.9339916706 0.9284340143 + 0.9329723716 0.9345554709 0.9290462136 + 0.9335150719 0.9351192117 0.9296582937 + 0.9340577126 0.9356828928 0.9302704930 + 0.9346002936 0.9362466931 0.9308826923 + 0.9351428747 0.9368103743 0.9314947724 + 0.9356855154 0.9373741150 0.9321069717 + 0.9362280965 0.9379379153 0.9327191114 + 0.9367706776 0.9385015965 0.9333313107 + 0.9373133183 0.9390652776 0.9339435101 + 0.9378558993 0.9396290779 0.9345555902 + 0.9383984804 0.9401928186 0.9351677895 + 0.9389411211 0.9407566190 0.9357799292 + 0.9394807220 0.9413191080 0.9363880754 + 0.9400200844 0.9418814778 0.9369959235 + 0.9405596256 0.9424440265 0.9376037717 + 0.9410989881 0.9430063963 0.9382116795 + 0.9416384101 0.9435688853 0.9388195276 + 0.9421778917 0.9441313148 0.9394273758 + 0.9427173138 0.9446938038 0.9400352836 + 0.9432566762 0.9452561736 0.9406430721 + 0.9437962174 0.9458187222 0.9412509799 + 0.9443355799 0.9463812113 0.9418588877 + 0.9448750019 0.9469435811 0.9424667954 + 0.9454144835 0.9475061297 0.9430745840 + 0.9459543228 0.9480664730 0.9436799884 + 0.9464944005 0.9486256838 0.9442839026 + 0.9470344782 0.9491848946 0.9448878169 + 0.9475746155 0.9497442245 0.9454916716 + 0.9481146932 0.9503033757 0.9460955858 + 0.9486547709 0.9508627057 0.9466995001 + 0.9491950274 0.9514219165 0.9473034143 + 0.9497351050 0.9519811869 0.9479073286 + 0.9502751827 0.9525403976 0.9485111833 + 0.9508153200 0.9530997276 0.9491150975 + 0.9513553977 0.9536588788 0.9497190118 + 0.9518954754 0.9542182088 0.9503229856 + 0.9524348974 0.9547764063 0.9509251714 + 0.9529715180 0.9553294778 0.9515191913 + 0.9535080194 0.9558826089 0.9521132112 + 0.9540445209 0.9564357996 0.9527071714 + 0.9545810819 0.9569888711 0.9533010721 + 0.9551175833 0.9575420022 0.9538950920 + 0.9556540847 0.9580950737 0.9544891119 + 0.9561907053 0.9586482048 0.9550830722 + 0.9567272067 0.9592013955 0.9556770921 + 0.9572637081 0.9597545266 0.9562711120 + 0.9578003287 0.9603075981 0.9568650723 + 0.9583367705 0.9608607292 0.9574589729 + 0.9588732719 0.9614138007 0.9580529928 + 0.9594082236 0.9619622827 0.9586417079 + 0.9599416256 0.9625064731 0.9592257142 + 0.9604749084 0.9630507231 0.9598097205 + 0.9610083103 0.9635949135 0.9603936076 + 0.9615417123 0.9641392231 0.9609776139 + 0.9620749950 0.9646834135 0.9615616202 + 0.9626083970 0.9652276039 0.9621456265 + 0.9631417990 0.9657717943 0.9627295136 + 0.9636752009 0.9663161039 0.9633135200 + 0.9642084837 0.9668602943 0.9638975263 + 0.9647418857 0.9674044847 0.9644814134 + 0.9652752876 0.9679486752 0.9650654197 + 0.9658085704 0.9684929848 0.9656494260 + 0.9663383961 0.9690269232 0.9662256837 + 0.9668667912 0.9695569277 0.9667990208 + 0.9673951864 0.9700868130 0.9673721790 + 0.9679235816 0.9706168175 0.9679455161 + 0.9684519768 0.9711467028 0.9685187936 + 0.9689803720 0.9716767073 0.9690920115 + 0.9695087075 0.9722065926 0.9696652889 + 0.9700371027 0.9727365971 0.9702386260 + 0.9705654979 0.9732664824 0.9708117843 + 0.9710938931 0.9737964272 0.9713851213 + 0.9716222882 0.9743263721 0.9719583988 + 0.9721506834 0.9748563170 0.9725316167 + 0.9726790786 0.9753863215 0.9731048942 + 0.9732028842 0.9759041071 0.9736629725 + 0.9737251997 0.9764174819 0.9742156267 + 0.9742473960 0.9769309759 0.9747681022 + 0.9747695923 0.9774444103 0.9753205776 + 0.9752919078 0.9779577851 0.9758731723 + 0.9758141041 0.9784712195 0.9764257073 + 0.9763363004 0.9789845943 0.9769781828 + 0.9768586159 0.9794980288 0.9775307178 + 0.9773808122 0.9800114036 0.9780833125 + 0.9779031277 0.9805248976 0.9786357880 + 0.9784253240 0.9810382724 0.9791883230 + 0.9789475203 0.9815517068 0.9797409177 + 0.9794697762 0.9820650816 0.9802933931 + 0.9799848199 0.9825599790 0.9808300734 + 0.9804943800 0.9830408096 0.9813547134 + 0.9810041189 0.9835215807 0.9818794131 + 0.9815136790 0.9840024114 0.9824039936 + 0.9820232987 0.9844831824 0.9829286933 + 0.9825329781 0.9849640131 0.9834532738 + 0.9830425978 0.9854447842 0.9839779735 + 0.9835522175 0.9859256148 0.9845026135 + 0.9840617776 0.9864063859 0.9850273132 + 0.9845715165 0.9868872166 0.9855518937 + 0.9850810766 0.9873679876 0.9860765934 + 0.9855906963 0.9878488183 0.9866011739 + 0.9861003757 0.9883295894 0.9871258736 + 0.9866076112 0.9888011813 0.9876428843 + 0.9871065021 0.9892416000 0.9881339073 + 0.9876055121 0.9896820188 0.9886249900 + 0.9881045222 0.9901223779 0.9891160131 + 0.9886034727 0.9905629158 0.9896070957 + 0.9891024828 0.9910032749 0.9900981188 + 0.9896014929 0.9914436936 0.9905890822 + 0.9901003838 0.9918841124 0.9910802245 + 0.9905993938 0.9923244715 0.9915711880 + 0.9910984039 0.9927648902 0.9920622706 + 0.9915974140 0.9932053089 0.9925532937 + 0.9920964241 0.9936457276 0.9930443764 + 0.9925953746 0.9940860868 0.9935353994 + 0.9930943847 0.9945266247 0.9940264821 + 0.9935892224 0.9949312806 0.9944710732 + 0.9940823913 0.9953212142 0.9948964119 + 0.9945755005 0.9957110882 0.9953216910 + 0.9950686097 0.9961010218 0.9957470298 + 0.9955617785 0.9964908957 0.9961723089 + 0.9960548878 0.9968808293 0.9965975881 + 0.9965479970 0.9972707033 0.9970229268 + 0.9970412254 0.9976605773 0.9974482059 + 0.9975342751 0.9980505109 0.9978734851 + 0.9980275035 0.9984403849 0.9982988238 + 0.9985206127 0.9988303185 0.9987241030 + 0.9990137219 0.9992201924 0.9991493821 + 0.9995068908 0.9996101260 0.9995747209 + 1.0000000000 1.0000000000 1.0000000000 +} diff --git a/rpplugins/color_correction/resources/film_luts_raw/kodak_portra_400vc.spi1d b/rpplugins/color_correction/resources/film_luts_raw/kodak_portra_400vc.spi1d new file mode 100644 index 0000000..3bbe6e7 --- /dev/null +++ b/rpplugins/color_correction/resources/film_luts_raw/kodak_portra_400vc.spi1d @@ -0,0 +1,1030 @@ +Version 1 +From 0.0 1.0 +Length 1024 +Components 3 +{ + 0.0000000000 0.0000000000 0.0000000000 + 0.0086291339 0.0078005488 0.0061553409 + 0.0166279394 0.0149212098 0.0115477303 + 0.0234502498 0.0210635699 0.0162159093 + 0.0294977706 0.0264640693 0.0204165298 + 0.0349041112 0.0313926600 0.0242713001 + 0.0398604982 0.0359628201 0.0279128905 + 0.0445825197 0.0402758084 0.0313868709 + 0.0489878207 0.0443142913 0.0346947797 + 0.0532177314 0.0482137911 0.0378837399 + 0.0572355017 0.0519315116 0.0409737006 + 0.0610651597 0.0555156991 0.0439543799 + 0.0647805408 0.0590067990 0.0468649715 + 0.0684034899 0.0623898692 0.0496960990 + 0.0719185919 0.0656935796 0.0524532497 + 0.0753464922 0.0688895881 0.0551457889 + 0.0786892101 0.0719943792 0.0577957407 + 0.0819205269 0.0749978498 0.0603696108 + 0.0850563273 0.0779183879 0.0628900677 + 0.0881082267 0.0807836503 0.0653679967 + 0.0910997614 0.0836165026 0.0678165331 + 0.0940506533 0.0864003077 0.0702505037 + 0.0969373211 0.0891356766 0.0726604089 + 0.0997503623 0.0918305814 0.0750340968 + 0.1025146991 0.0944881588 0.0773660317 + 0.1052661017 0.0971041918 0.0796465725 + 0.1079823002 0.0997008383 0.0818920732 + 0.1106742024 0.1022529975 0.0840972289 + 0.1133475006 0.1047334000 0.0862670168 + 0.1159679964 0.1071522981 0.0884032026 + 0.1185553968 0.1095331982 0.0905269608 + 0.1210843995 0.1118893027 0.0926406905 + 0.1235641018 0.1142370030 0.0947492719 + 0.1260133982 0.1165516973 0.0968295410 + 0.1284331977 0.1188732013 0.0988966897 + 0.1308183968 0.1211699992 0.1009425968 + 0.1331772059 0.1234538034 0.1029729024 + 0.1355085969 0.1256996989 0.1049892977 + 0.1378096938 0.1279380023 0.1069732010 + 0.1400966942 0.1301369965 0.1089397967 + 0.1423414052 0.1323242038 0.1109104976 + 0.1445591003 0.1344671994 0.1128705963 + 0.1467431933 0.1365955025 0.1148163974 + 0.1489122063 0.1386837959 0.1167598963 + 0.1510476023 0.1407471001 0.1186747029 + 0.1531807929 0.1428090930 0.1205610037 + 0.1553075016 0.1448387057 0.1224154979 + 0.1574216038 0.1468652934 0.1242436990 + 0.1595198959 0.1488717943 0.1260575950 + 0.1615947932 0.1508519948 0.1278496981 + 0.1636703014 0.1528411955 0.1296253949 + 0.1657373011 0.1548041999 0.1313930005 + 0.1677850038 0.1567573994 0.1331461966 + 0.1698163003 0.1587090939 0.1349010020 + 0.1718430966 0.1606369019 0.1366534978 + 0.1738559008 0.1625535041 0.1383929998 + 0.1758597046 0.1644703001 0.1401329041 + 0.1778582931 0.1663694978 0.1418718994 + 0.1798356026 0.1682510972 0.1436001062 + 0.1817937940 0.1701292992 0.1453143060 + 0.1837290972 0.1719716042 0.1470246017 + 0.1856500059 0.1737944931 0.1487206072 + 0.1875600070 0.1756183952 0.1504009068 + 0.1894560009 0.1774290055 0.1520728022 + 0.1913280934 0.1792113930 0.1537348032 + 0.1931733042 0.1809861064 0.1554002017 + 0.1949937940 0.1827580035 0.1570577025 + 0.1968041956 0.1845048070 0.1587098986 + 0.1985995024 0.1862314939 0.1603520066 + 0.2003758997 0.1879574060 0.1619874984 + 0.2021435946 0.1896872967 0.1636175960 + 0.2039009035 0.1914020032 0.1652458012 + 0.2056314051 0.1931017041 0.1668601930 + 0.2073460072 0.1948022991 0.1684632003 + 0.2090656012 0.1965142041 0.1700568050 + 0.2107871026 0.1982153952 0.1716396064 + 0.2125017941 0.1999046952 0.1732196957 + 0.2142132074 0.2015919983 0.1747861952 + 0.2159194946 0.2032641023 0.1763374954 + 0.2176184952 0.2049120069 0.1778807938 + 0.2193064988 0.2065432072 0.1794188023 + 0.2209898978 0.2081688046 0.1809532940 + 0.2226741016 0.2097914070 0.1824879944 + 0.2243521959 0.2114066035 0.1840219945 + 0.2260199040 0.2130115032 0.1855459064 + 0.2276818007 0.2146048993 0.1870635003 + 0.2293322980 0.2161996961 0.1885785013 + 0.2309723049 0.2177951932 0.1900880039 + 0.2325980961 0.2193817049 0.1915943027 + 0.2342166007 0.2209558040 0.1930999011 + 0.2358343005 0.2225205004 0.1946053058 + 0.2374477983 0.2240840048 0.1961077005 + 0.2390588969 0.2256534994 0.1975979954 + 0.2406685948 0.2272066027 0.1990832984 + 0.2422688007 0.2287465930 0.2005632073 + 0.2438556999 0.2302782983 0.2020380944 + 0.2454296947 0.2318089008 0.2035095990 + 0.2469906062 0.2333444953 0.2049811035 + 0.2485449016 0.2348676026 0.2064442933 + 0.2500948012 0.2363775969 0.2079003006 + 0.2516424954 0.2378765941 0.2093524039 + 0.2531889081 0.2393742949 0.2107995003 + 0.2547358871 0.2408725023 0.2122382969 + 0.2562828064 0.2423699051 0.2136691064 + 0.2578260899 0.2438611984 0.2150931954 + 0.2593621910 0.2453383952 0.2165144980 + 0.2608925104 0.2468091995 0.2179322988 + 0.2624158859 0.2482766062 0.2193447053 + 0.2639254928 0.2497424036 0.2207508981 + 0.2654292881 0.2512080073 0.2221533954 + 0.2669275999 0.2526736856 0.2235517055 + 0.2684175968 0.2541224957 0.2249393016 + 0.2699044943 0.2555668056 0.2263229042 + 0.2713881135 0.2570067048 0.2277022004 + 0.2728621960 0.2584454119 0.2290780991 + 0.2743291855 0.2598778009 0.2304508984 + 0.2757858038 0.2613000870 0.2318188995 + 0.2772283852 0.2627094984 0.2331835032 + 0.2786627114 0.2641144991 0.2345474958 + 0.2800801098 0.2655147016 0.2359123975 + 0.2814942896 0.2669171095 0.2372698933 + 0.2829064131 0.2683207989 0.2386226058 + 0.2843183875 0.2697081864 0.2399670929 + 0.2857283056 0.2710885108 0.2413100004 + 0.2871338129 0.2724551857 0.2426497042 + 0.2885296047 0.2738170922 0.2439855933 + 0.2899203002 0.2751764059 0.2453195006 + 0.2913027108 0.2765411139 0.2466553003 + 0.2926810980 0.2779048085 0.2479909062 + 0.2940480113 0.2792651057 0.2493253052 + 0.2954030931 0.2806189060 0.2506527901 + 0.2967463136 0.2819663882 0.2519730926 + 0.2980836928 0.2833054066 0.2532927990 + 0.2994191051 0.2846412957 0.2546122074 + 0.3007619083 0.2859781981 0.2559292912 + 0.3021047115 0.2873162031 0.2572456896 + 0.3034440875 0.2886605859 0.2585586011 + 0.3047791123 0.2899999022 0.2598730028 + 0.3061031103 0.2913272977 0.2611911893 + 0.3074271083 0.2926500142 0.2625049949 + 0.3087511957 0.2939665914 0.2638128996 + 0.3100728095 0.2952839136 0.2651130855 + 0.3113921881 0.2966020107 0.2664063871 + 0.3127081990 0.2979249954 0.2676930130 + 0.3140223026 0.2992509007 0.2689754069 + 0.3153294921 0.3005655110 0.2702546120 + 0.3166336119 0.3018752038 0.2715322971 + 0.3179413080 0.3031772077 0.2728073001 + 0.3192504048 0.3044762909 0.2740811110 + 0.3205552101 0.3057742119 0.2753461003 + 0.3218581975 0.3070715070 0.2766075134 + 0.3231492043 0.3083544075 0.2778604031 + 0.3244349062 0.3096314073 0.2791095972 + 0.3257190883 0.3108929992 0.2803491056 + 0.3270024955 0.3121466935 0.2815833986 + 0.3282819092 0.3133935034 0.2828159034 + 0.3295584023 0.3146354854 0.2840468884 + 0.3308312893 0.3158772886 0.2852747142 + 0.3321002126 0.3171189129 0.2864989042 + 0.3333649933 0.3183605075 0.2877179980 + 0.3346219063 0.3196018934 0.2889271975 + 0.3358792067 0.3208408952 0.2901360095 + 0.3371385932 0.3220691979 0.2913432121 + 0.3383980095 0.3232975006 0.2925504148 + 0.3396492004 0.3245128095 0.2937470973 + 0.3409003019 0.3257280886 0.2949436903 + 0.3421368003 0.3269419074 0.2961353958 + 0.3433690071 0.3281553984 0.2973257005 + 0.3445987105 0.3293735981 0.2985163927 + 0.3458260894 0.3305962980 0.2997077107 + 0.3470515013 0.3318206072 0.3008984029 + 0.3482699096 0.3330497146 0.3020871878 + 0.3494882882 0.3342789114 0.3032760024 + 0.3507004976 0.3354977071 0.3044616878 + 0.3519122005 0.3367156088 0.3056469858 + 0.3531202972 0.3379318118 0.3068349957 + 0.3543255925 0.3391467035 0.3080250025 + 0.3555307984 0.3403621018 0.3092128932 + 0.3567352891 0.3415792882 0.3103924990 + 0.3579396904 0.3427965045 0.3115719855 + 0.3591400981 0.3439978957 0.3127532005 + 0.3603394926 0.3451952934 0.3139348030 + 0.3615379930 0.3463875949 0.3151153028 + 0.3627347052 0.3475709856 0.3162938058 + 0.3639313877 0.3487544060 0.3174723089 + 0.3651260138 0.3499352038 0.3186487854 + 0.3663201928 0.3511157036 0.3198249936 + 0.3675152957 0.3522970974 0.3210014999 + 0.3687118888 0.3534801006 0.3221786916 + 0.3699085116 0.3546631038 0.3233557940 + 0.3711037934 0.3558301926 0.3245329857 + 0.3722988069 0.3569942117 0.3257102966 + 0.3734931946 0.3581548035 0.3268885911 + 0.3746860027 0.3593055010 0.3280701935 + 0.3758786917 0.3604561985 0.3292517960 + 0.3770669103 0.3616054058 0.3304269016 + 0.3782525063 0.3627535999 0.3315981925 + 0.3794381022 0.3639019132 0.3327696025 + 0.3806130886 0.3650487065 0.3339313865 + 0.3817881048 0.3661954105 0.3350929916 + 0.3829604089 0.3673394918 0.3362526000 + 0.3841269910 0.3684779108 0.3374074101 + 0.3852936029 0.3696162999 0.3385623097 + 0.3864552975 0.3707447052 0.3397139013 + 0.3876137137 0.3718662858 0.3408631980 + 0.3887721896 0.3729878962 0.3420126140 + 0.3899284899 0.3741044998 0.3431645036 + 0.3910844922 0.3752200007 0.3443169892 + 0.3922401071 0.3763357997 0.3454687893 + 0.3933893144 0.3774558902 0.3466030955 + 0.3945386112 0.3785760105 0.3477374911 + 0.3956862092 0.3796963990 0.3488697112 + 0.3968279064 0.3808178902 0.3499937057 + 0.3979696035 0.3819392920 0.3511176109 + 0.3991076052 0.3830555975 0.3522385061 + 0.4002385139 0.3841623068 0.3533534110 + 0.4013693929 0.3852689862 0.3544682860 + 0.4024933875 0.3863726854 0.3555805981 + 0.4036085010 0.3874725103 0.3566895127 + 0.4047234952 0.3885723054 0.3577983975 + 0.4058330059 0.3896723092 0.3589071929 + 0.4069365859 0.3907727003 0.3600156903 + 0.4080401957 0.3918730021 0.3611243069 + 0.4091409147 0.3929738104 0.3622342050 + 0.4102385938 0.3940750062 0.3633455932 + 0.4113362134 0.3951762021 0.3644570112 + 0.4124296904 0.3962723017 0.3655647933 + 0.4135183096 0.3973628879 0.3666686118 + 0.4146068990 0.3984535933 0.3677723110 + 0.4156936109 0.3995419145 0.3688744903 + 0.4167774022 0.4006268978 0.3699742854 + 0.4178611040 0.4017120004 0.3710741103 + 0.4189420044 0.4027974904 0.3721716106 + 0.4200159013 0.4038844109 0.3732632101 + 0.4210897088 0.4049712121 0.3743548989 + 0.4221613109 0.4060561061 0.3754456043 + 0.4232189953 0.4071291983 0.3765301108 + 0.4242765903 0.4082024097 0.3776144981 + 0.4253341854 0.4092755914 0.3786988854 + 0.4263879955 0.4103333056 0.3797815144 + 0.4274415076 0.4113903046 0.3808639050 + 0.4284951091 0.4124472141 0.3819462955 + 0.4295487106 0.4134993851 0.3830277026 + 0.4306023121 0.4145495892 0.3841085136 + 0.4316559136 0.4155999124 0.3851892948 + 0.4327076077 0.4166513085 0.3862665892 + 0.4337567091 0.4177044034 0.3873386979 + 0.4348058105 0.4187574983 0.3884108961 + 0.4358538985 0.4198100865 0.3894824088 + 0.4368919134 0.4208576977 0.3905462921 + 0.4379299879 0.4219053984 0.3916102946 + 0.4389680028 0.4229530990 0.3926742971 + 0.4400067031 0.4239928126 0.3937354982 + 0.4410456121 0.4250294864 0.3947955072 + 0.4420844913 0.4260661900 0.3958554864 + 0.4431211054 0.4271000028 0.3969140053 + 0.4441522956 0.4281272888 0.3979691863 + 0.4451833963 0.4291546047 0.3990243077 + 0.4462144971 0.4301818907 0.4000793993 + 0.4472317100 0.4312092960 0.4011329114 + 0.4482460916 0.4322367013 0.4021860957 + 0.4492605031 0.4332641959 0.4032391906 + 0.4502733946 0.4342932105 0.4042918980 + 0.4512828887 0.4353255928 0.4053437114 + 0.4522925019 0.4363580048 0.4063954949 + 0.4533020854 0.4373905063 0.4074473083 + 0.4543111026 0.4384124875 0.4084874094 + 0.4553197920 0.4394313991 0.4095237851 + 0.4563286006 0.4404503107 0.4105601907 + 0.4573364854 0.4414677918 0.4115959108 + 0.4583398104 0.4424777925 0.4126274884 + 0.4593431056 0.4434877038 0.4136590958 + 0.4603464007 0.4444975853 0.4146907032 + 0.4613440037 0.4455075860 0.4157181084 + 0.4623357058 0.4465177059 0.4167410135 + 0.4633274078 0.4475277066 0.4177640080 + 0.4643191993 0.4485377967 0.4187869132 + 0.4653109908 0.4495514035 0.4198037088 + 0.4663026929 0.4505659938 0.4208188057 + 0.4672945142 0.4515804946 0.4218339026 + 0.4682861865 0.4525944889 0.4228489995 + 0.4692744911 0.4535953999 0.4238614142 + 0.4702627957 0.4545961916 0.4248737097 + 0.4712511003 0.4555971026 0.4258860946 + 0.4722385108 0.4565958977 0.4268980026 + 0.4732227027 0.4575876892 0.4279080927 + 0.4742070138 0.4585795999 0.4289183021 + 0.4751912951 0.4595713913 0.4299283922 + 0.4761728942 0.4605633020 0.4309360981 + 0.4771496952 0.4615552127 0.4319396913 + 0.4781264961 0.4625470936 0.4329431951 + 0.4791032970 0.4635390043 0.4339466989 + 0.4800817966 0.4645307064 0.4349519014 + 0.4810624123 0.4655222893 0.4359593987 + 0.4820429981 0.4665139019 0.4369668067 + 0.4830236137 0.4675053954 0.4379743040 + 0.4840019941 0.4684920907 0.4389804900 + 0.4849779904 0.4694738090 0.4399853051 + 0.4859539866 0.4704554975 0.4409902096 + 0.4869301021 0.4714370966 0.4419949949 + 0.4879001081 0.4724138081 0.4429973066 + 0.4888631999 0.4733850062 0.4439963996 + 0.4898262918 0.4743562043 0.4449956119 + 0.4907892942 0.4753274024 0.4459947944 + 0.4917517006 0.4762980044 0.4469918907 + 0.4927130938 0.4772675931 0.4479857981 + 0.4936743975 0.4782372117 0.4489797056 + 0.4946357012 0.4792068005 0.4499736130 + 0.4955956042 0.4801762998 0.4509660006 + 0.4965516925 0.4811457098 0.4519538879 + 0.4975079000 0.4821150899 0.4529418051 + 0.4984639883 0.4830844998 0.4539296925 + 0.4994196892 0.4840534031 0.4549174011 + 0.5003700852 0.4850172102 0.4559034109 + 0.5013206005 0.4859808981 0.4568893015 + 0.5022711158 0.4869445860 0.4578751922 + 0.5032215118 0.4879083037 0.4588611126 + 0.5041645169 0.4888612032 0.4598459005 + 0.5051059127 0.4898119867 0.4608305097 + 0.5060474277 0.4907627106 0.4618149996 + 0.5069888234 0.4917134941 0.4627996087 + 0.5079312921 0.4926620126 0.4637798965 + 0.5088745952 0.4936085045 0.4647563100 + 0.5098178983 0.4945549965 0.4657326937 + 0.5107612014 0.4955014884 0.4667089880 + 0.5117039084 0.4964486957 0.4676840901 + 0.5126433969 0.4973995090 0.4686524868 + 0.5135828853 0.4983502924 0.4696210027 + 0.5145223737 0.4993009865 0.4705893993 + 0.5154619217 0.5002518296 0.4715577960 + 0.5163952708 0.5012043118 0.4725238979 + 0.5173267126 0.5021573901 0.4734891057 + 0.5182582140 0.5031105280 0.4744544029 + 0.5191895962 0.5040636063 0.4754197001 + 0.5201197863 0.5050135255 0.4763843119 + 0.5210466981 0.5059555173 0.4773474038 + 0.5219736099 0.5068973899 0.4783104062 + 0.5229005218 0.5078393817 0.4792734981 + 0.5238274932 0.5087813735 0.4802365899 + 0.5247486830 0.5097197294 0.4811953008 + 0.5256680846 0.5106567144 0.4821526110 + 0.5265874267 0.5115938187 0.4831098914 + 0.5275068283 0.5125308037 0.4840672016 + 0.5284252763 0.5134680271 0.4850249887 + 0.5293390155 0.5144063234 0.4859859049 + 0.5302528143 0.5153445005 0.4869467914 + 0.5311664939 0.5162826777 0.4879077077 + 0.5320801735 0.5172209740 0.4888687134 + 0.5329914093 0.5181534290 0.4898253977 + 0.5338997245 0.5190796256 0.4907774925 + 0.5348079801 0.5200058222 0.4917295873 + 0.5357164145 0.5209320784 0.4926817119 + 0.5366247296 0.5218582749 0.4936338067 + 0.5375316739 0.5227739215 0.4945797026 + 0.5384383202 0.5236862898 0.4955236018 + 0.5393447876 0.5245985985 0.4964675009 + 0.5402513742 0.5255110264 0.4974114001 + 0.5411579013 0.5264232755 0.4983552992 + 0.5420578122 0.5273302197 0.4992960095 + 0.5429574251 0.5282369256 0.5002363920 + 0.5438570976 0.5291436911 0.5011768937 + 0.5447567105 0.5300503969 0.5021173954 + 0.5456550717 0.5309572220 0.5030577779 + 0.5465437174 0.5318645835 0.5039975047 + 0.5474323034 0.5327720046 0.5049371123 + 0.5483208895 0.5336794257 0.5058767796 + 0.5492094755 0.5345867872 0.5068165064 + 0.5500965118 0.5354917049 0.5077555180 + 0.5509771109 0.5363870263 0.5086914897 + 0.5518578291 0.5372822881 0.5096275210 + 0.5527384281 0.5381776094 0.5105633736 + 0.5536190271 0.5390728712 0.5114994049 + 0.5545002222 0.5399649739 0.5124346018 + 0.5553833246 0.5408456922 0.5133668780 + 0.5562664866 0.5417262912 0.5142992139 + 0.5571495891 0.5426068902 0.5152313709 + 0.5580328107 0.5434876084 0.5161637068 + 0.5589159131 0.5443671942 0.5170946121 + 0.5597988963 0.5452414751 0.5180175900 + 0.5606818795 0.5461158156 0.5189406872 + 0.5615649223 0.5469899774 0.5198637843 + 0.5624479055 0.5478643179 0.5207868218 + 0.5633308887 0.5487385988 0.5217097998 + 0.5642132163 0.5496147871 0.5226305127 + 0.5650954247 0.5504909158 0.5235512257 + 0.5659775734 0.5513671041 0.5244718790 + 0.5668599010 0.5522431731 0.5253925920 + 0.5677421093 0.5531194210 0.5263133049 + 0.5686208010 0.5539948940 0.5272328854 + 0.5694987178 0.5548701882 0.5281524062 + 0.5703766942 0.5557454824 0.5290718079 + 0.5712546110 0.5566208959 0.5299912095 + 0.5721325874 0.5574961901 0.5309106112 + 0.5730063915 0.5583639145 0.5318285227 + 0.5738772154 0.5592259765 0.5327451229 + 0.5747479200 0.5600880980 0.5336617231 + 0.5756186843 0.5609502196 0.5345783234 + 0.5764895082 0.5618122816 0.5354949236 + 0.5773584247 0.5626726747 0.5364094973 + 0.5782213807 0.5635278821 0.5373175144 + 0.5790842772 0.5643829703 0.5382254124 + 0.5799472928 0.5652381182 0.5391334295 + 0.5808103085 0.5660933256 0.5400413871 + 0.5816733241 0.5669484138 0.5409492850 + 0.5825272799 0.5678043962 0.5418502092 + 0.5833795071 0.5686606169 0.5427495241 + 0.5842316747 0.5695167184 0.5436487794 + 0.5850839019 0.5703728795 0.5445482135 + 0.5859361291 0.5712291002 0.5454475284 + 0.5867881775 0.5720869899 0.5463449955 + 0.5876401067 0.5729479790 0.5472388864 + 0.5884919167 0.5738090873 0.5481327772 + 0.5893437862 0.5746700764 0.5490267277 + 0.5901955962 0.5755311847 0.5499206781 + 0.5910475254 0.5763922930 0.5508146286 + 0.5918961763 0.5772445202 0.5517038107 + 0.5927441716 0.5780944824 0.5525919199 + 0.5935921073 0.5789445043 0.5534799099 + 0.5944401026 0.5797945857 0.5543678999 + 0.5952879786 0.5806446075 0.5552558899 + 0.5961351991 0.5814933777 0.5561434031 + 0.5969787836 0.5823364854 0.5570282936 + 0.5978223085 0.5831795931 0.5579131246 + 0.5986657739 0.5840227008 0.5587978959 + 0.5995092988 0.5848656893 0.5596827865 + 0.6003528833 0.5857087970 0.5605676174 + 0.6011931896 0.5865523219 0.5614522099 + 0.6020298004 0.5873963237 0.5623363853 + 0.6028664112 0.5882403255 0.5632206202 + 0.6037030220 0.5890843272 0.5641047955 + 0.6045395732 0.5899283290 0.5649890900 + 0.6053761840 0.5907722712 0.5658733249 + 0.6062102914 0.5916194916 0.5667579174 + 0.6070430875 0.5924683213 0.5676426291 + 0.6078760028 0.5933170915 0.5685272813 + 0.6087087989 0.5941658020 0.5694121122 + 0.6095417142 0.5950145721 0.5702968240 + 0.6103746295 0.5958634019 0.5711815953 + 0.6112043858 0.5967034101 0.5720716119 + 0.6120336056 0.5975413918 0.5729628205 + 0.6128627062 0.5983793736 0.5738540292 + 0.6136919260 0.5992174149 0.5747451782 + 0.6145210862 0.6000553966 0.5756365061 + 0.6153501868 0.6008933783 0.5765277147 + 0.6161777973 0.6017255187 0.5774099231 + 0.6170051098 0.6025568247 0.5782908201 + 0.6178324223 0.6033880115 0.5791717172 + 0.6186597943 0.6042193174 0.5800524950 + 0.6194871068 0.6050505042 0.5809333920 + 0.6203144193 0.6058818102 0.5818142295 + 0.6211380959 0.6067138910 0.5826920271 + 0.6219611764 0.6075462103 0.5835691094 + 0.6227841973 0.6083784103 0.5844463110 + 0.6236072779 0.6092107296 0.5853233933 + 0.6244302988 0.6100429893 0.5862005949 + 0.6252533793 0.6108751893 0.5870776772 + 0.6260753274 0.6117079258 0.5879529119 + 0.6268969178 0.6125406027 0.5888274908 + 0.6277183890 0.6133733988 0.5897021294 + 0.6285399199 0.6142061949 0.5905765891 + 0.6293615103 0.6150388718 0.5914512277 + 0.6301829815 0.6158717275 0.5923258066 + 0.6310017109 0.6166999936 0.5932002068 + 0.6318179965 0.6175248027 0.5940744281 + 0.6326344013 0.6183496118 0.5949487090 + 0.6334508061 0.6191744208 0.5958228707 + 0.6342670918 0.6199991703 0.5966970921 + 0.6350834966 0.6208239794 0.5975713730 + 0.6358969808 0.6216465235 0.5984457135 + 0.6367033720 0.6224632263 0.5993201137 + 0.6375098228 0.6232798100 0.6001945138 + 0.6383162141 0.6240965128 0.6010689735 + 0.6391226053 0.6249132156 0.6019433737 + 0.6399289966 0.6257297993 0.6028177738 + 0.6407353878 0.6265465021 0.6036921740 + 0.6415356994 0.6273627281 0.6045618057 + 0.6423354745 0.6281787753 0.6054310799 + 0.6431353092 0.6289948821 0.6063002944 + 0.6439350843 0.6298109889 0.6071695089 + 0.6447349191 0.6306270957 0.6080387235 + 0.6455346942 0.6314432025 0.6089078784 + 0.6463314891 0.6322597861 0.6097748876 + 0.6471250057 0.6330770850 0.6106392741 + 0.6479185820 0.6338943243 0.6115037799 + 0.6487122178 0.6347116232 0.6123682261 + 0.6495056748 0.6355288029 0.6132326722 + 0.6502993107 0.6363461018 0.6140971184 + 0.6510928869 0.6371632814 0.6149616241 + 0.6518819928 0.6379770041 0.6158189178 + 0.6526708007 0.6387906075 0.6166757941 + 0.6534597278 0.6396042109 0.6175327897 + 0.6542485952 0.6404178143 0.6183897257 + 0.6550374031 0.6412314177 0.6192467213 + 0.6558262706 0.6420449018 0.6201035976 + 0.6566126943 0.6428549886 0.6209588051 + 0.6573941112 0.6436582804 0.6218106151 + 0.6581755280 0.6444615722 0.6226623058 + 0.6589568853 0.6452649236 0.6235139966 + 0.6597383022 0.6460682154 0.6243656874 + 0.6605197191 0.6468715072 0.6252173781 + 0.6613010168 0.6476747990 0.6260691881 + 0.6620833874 0.6484764218 0.6269180179 + 0.6628664136 0.6492767930 0.6277649999 + 0.6636493206 0.6500772834 0.6286119819 + 0.6644322872 0.6508777738 0.6294590831 + 0.6652151942 0.6516783237 0.6303061247 + 0.6659982204 0.6524788141 0.6311531067 + 0.6667811275 0.6532791853 0.6320002079 + 0.6675598025 0.6540803909 0.6328403950 + 0.6683375835 0.6548817754 0.6336792111 + 0.6691154242 0.6556832194 0.6345179081 + 0.6698932052 0.6564844847 0.6353567243 + 0.6706709862 0.6572859287 0.6361954212 + 0.6714488268 0.6580871940 0.6370341778 + 0.6722266078 0.6588885784 0.6378728747 + 0.6729933023 0.6596770287 0.6387121081 + 0.6737592816 0.6604645252 0.6395512223 + 0.6745253205 0.6612520814 0.6403903961 + 0.6752912998 0.6620395780 0.6412295103 + 0.6760572791 0.6628271937 0.6420686841 + 0.6768233180 0.6636146903 0.6429077983 + 0.6775892973 0.6644023061 0.6437469721 + 0.6783525944 0.6651803851 0.6445764899 + 0.6791155934 0.6659579873 0.6454054117 + 0.6798787117 0.6667355895 0.6462342739 + 0.6806417704 0.6675131917 0.6470631957 + 0.6814048886 0.6682907939 0.6478921175 + 0.6821680069 0.6690683961 0.6487209797 + 0.6829311252 0.6698459983 0.6495499015 + 0.6836892962 0.6706212759 0.6503704190 + 0.6844468117 0.6713961959 0.6511895061 + 0.6852043271 0.6721711755 0.6520085931 + 0.6859617829 0.6729462147 0.6528277993 + 0.6867192984 0.6737210751 0.6536468863 + 0.6874766946 0.6744961143 0.6544659734 + 0.6882342100 0.6752710938 0.6552851796 + 0.6889876127 0.6760479808 0.6560990810 + 0.6897391081 0.6768258810 0.6569107175 + 0.6904906034 0.6776037216 0.6577221751 + 0.6912420988 0.6783815026 0.6585338116 + 0.6919935942 0.6791594028 0.6593453884 + 0.6927450895 0.6799371839 0.6601569057 + 0.6934965849 0.6807150841 0.6609684825 + 0.6942445040 0.6814894080 0.6617767215 + 0.6949872971 0.6822587848 0.6625800729 + 0.6957302094 0.6830282211 0.6633834243 + 0.6964730024 0.6837977171 0.6641867757 + 0.6972159147 0.6845670938 0.6649901867 + 0.6979587078 0.6853365898 0.6657935977 + 0.6987016201 0.6861060262 0.6665970087 + 0.6994444132 0.6868749261 0.6674001813 + 0.7001873255 0.6876338124 0.6682003736 + 0.7009301782 0.6883925796 0.6690005064 + 0.7016730905 0.6891514063 0.6698006988 + 0.7024160028 0.6899102926 0.6706007719 + 0.7031589150 0.6906691194 0.6714010239 + 0.7039018273 0.6914280057 0.6722010970 + 0.7046446800 0.6921867728 0.6730012894 + 0.7053861022 0.6929436922 0.6738013029 + 0.7061262727 0.6936991215 0.6746010780 + 0.7068666220 0.6944546103 0.6754009128 + 0.7076067924 0.6952099800 0.6762006879 + 0.7083470821 0.6959655285 0.6770005226 + 0.7090873718 0.6967208982 0.6778002977 + 0.7098276019 0.6974763870 0.6786001921 + 0.7105678916 0.6982318759 0.6794000268 + 0.7113052011 0.6989892721 0.6801937222 + 0.7120423913 0.6997467875 0.6809874177 + 0.7127797008 0.7005043030 0.6817811728 + 0.7135170102 0.7012618184 0.6825749278 + 0.7142542005 0.7020192742 0.6833686233 + 0.7149915099 0.7027767897 0.6841623187 + 0.7157288194 0.7035343051 0.6849560142 + 0.7164642215 0.7042888999 0.6857504845 + 0.7171959281 0.7050374746 0.6865466833 + 0.7179275155 0.7057859898 0.6873428822 + 0.7186592221 0.7065346241 0.6881390810 + 0.7193908095 0.7072831988 0.6889352798 + 0.7201225162 0.7080317736 0.6897314191 + 0.7208541036 0.7087804079 0.6905276179 + 0.7215858102 0.7095289826 0.6913238168 + 0.7223190069 0.7102715969 0.6921185255 + 0.7230535150 0.7110090256 0.6929119229 + 0.7237880230 0.7117465138 0.6937052011 + 0.7245225906 0.7124840021 0.6944985986 + 0.7252570987 0.7132214904 0.6952919960 + 0.7259916067 0.7139589787 0.6960853934 + 0.7267261147 0.7146965265 0.6968787909 + 0.7274606228 0.7154340148 0.6976721883 + 0.7281941175 0.7161688209 0.6984621882 + 0.7289270163 0.7169021964 0.6992504001 + 0.7296599150 0.7176355720 0.7000386715 + 0.7303928137 0.7183690071 0.7008268833 + 0.7311257720 0.7191023827 0.7016150951 + 0.7318586707 0.7198358178 0.7024034262 + 0.7325916290 0.7205691934 0.7031915784 + 0.7333245277 0.7213026285 0.7039797902 + 0.7340542078 0.7220379114 0.7047694921 + 0.7347822189 0.7227740884 0.7055600286 + 0.7355102897 0.7235103846 0.7063505054 + 0.7362383008 0.7242466211 0.7071409822 + 0.7369663715 0.7249829173 0.7079313993 + 0.7376943827 0.7257190943 0.7087218761 + 0.7384225130 0.7264553905 0.7095124125 + 0.7391505241 0.7271916270 0.7103028893 + 0.7398774028 0.7279284000 0.7110937238 + 0.7406033874 0.7286654115 0.7118847966 + 0.7413293719 0.7294024825 0.7126759291 + 0.7420554161 0.7301396132 0.7134671211 + 0.7427814007 0.7308766842 0.7142581940 + 0.7435073853 0.7316136956 0.7150493264 + 0.7442334294 0.7323508263 0.7158403993 + 0.7449594140 0.7330878973 0.7166314721 + 0.7456837893 0.7338215709 0.7174229026 + 0.7464053035 0.7345489264 0.7182146907 + 0.7471268177 0.7352762222 0.7190064788 + 0.7478482127 0.7360035181 0.7197983265 + 0.7485697269 0.7367308140 0.7205901146 + 0.7492911816 0.7374581099 0.7213820219 + 0.7500126958 0.7381855249 0.7221738100 + 0.7507342100 0.7389128208 0.7229655981 + 0.7514556050 0.7396399975 0.7237573266 + 0.7521721721 0.7403625846 0.7245445251 + 0.7528889179 0.7410852909 0.7253317833 + 0.7536056042 0.7418079972 0.7261189818 + 0.7543221712 0.7425305843 0.7269061804 + 0.7550389171 0.7432532907 0.7276934981 + 0.7557556033 0.7439759970 0.7284806967 + 0.7564721704 0.7446985841 0.7292678952 + 0.7571889162 0.7454212904 0.7300552130 + 0.7579010725 0.7461451888 0.7308400273 + 0.7586101890 0.7468699813 0.7316231132 + 0.7593191862 0.7475947738 0.7324061990 + 0.7600283027 0.7483196259 0.7331892848 + 0.7607374191 0.7490442991 0.7339723706 + 0.7614464164 0.7497690916 0.7347555161 + 0.7621554732 0.7504938841 0.7355386019 + 0.7628644705 0.7512186766 0.7363216877 + 0.7635735869 0.7519437075 0.7371047735 + 0.7642832994 0.7526741028 0.7378858924 + 0.7649930120 0.7534046173 0.7386670709 + 0.7657027245 0.7541350126 0.7394481897 + 0.7664124966 0.7548654079 0.7402294278 + 0.7671222091 0.7555958033 0.7410104871 + 0.7678319216 0.7563263178 0.7417917252 + 0.7685415745 0.7570567131 0.7425727844 + 0.7692512870 0.7577871084 0.7433540225 + 0.7699596882 0.7585147023 0.7441341877 + 0.7706660032 0.7592375278 0.7449126244 + 0.7713723183 0.7599601746 0.7456911206 + 0.7720785737 0.7606830001 0.7464696169 + 0.7727848887 0.7614058256 0.7472481132 + 0.7734912038 0.7621284723 0.7480264902 + 0.7741973996 0.7628512979 0.7488049865 + 0.7749037147 0.7635740042 0.7495834827 + 0.7756100297 0.7642968297 0.7503619790 + 0.7763124108 0.7650169730 0.7511404753 + 0.7770121098 0.7657353282 0.7519189715 + 0.7777118087 0.7664536238 0.7526975274 + 0.7784113884 0.7671719790 0.7534760833 + 0.7791110873 0.7678902745 0.7542545795 + 0.7798107266 0.7686086297 0.7550330758 + 0.7805104256 0.7693269849 0.7558116913 + 0.7812101245 0.7700452805 0.7565901875 + 0.7819097042 0.7707635760 0.7573688030 + 0.7826066017 0.7714834213 0.7581411004 + 0.7833021283 0.7722039223 0.7589104176 + 0.7839977145 0.7729244232 0.7596796751 + 0.7846931815 0.7736448050 0.7604489923 + 0.7853888273 0.7743653059 0.7612183094 + 0.7860842943 0.7750858068 0.7619876266 + 0.7867798805 0.7758061886 0.7627568841 + 0.7874754071 0.7765266895 0.7635262012 + 0.7881708741 0.7772471905 0.7642955184 + 0.7888624072 0.7779653072 0.7650622725 + 0.7895516157 0.7786822915 0.7658277750 + 0.7902408838 0.7793992162 0.7665932775 + 0.7909300923 0.7801160812 0.7673587799 + 0.7916194201 0.7808331251 0.7681242824 + 0.7923086286 0.7815499902 0.7688897848 + 0.7929978967 0.7822669148 0.7696552873 + 0.7936871052 0.7829838991 0.7704207897 + 0.7943763733 0.7837008238 0.7711862922 + 0.7950640917 0.7844138741 0.7719494104 + 0.7957503200 0.7851232290 0.7727103233 + 0.7964366078 0.7858325243 0.7734711170 + 0.7971227765 0.7865418196 0.7742319703 + 0.7978091240 0.7872511744 0.7749928236 + 0.7984952927 0.7879605293 0.7757536769 + 0.7991815209 0.7886698246 0.7765144706 + 0.7998678088 0.7893791199 0.7772753835 + 0.8005539775 0.7900884151 0.7780361772 + 0.8012402058 0.7907962799 0.7787957788 + 0.8019264936 0.7914993763 0.7795513272 + 0.8026127219 0.7922024131 0.7803066969 + 0.8032988906 0.7929055095 0.7810621262 + 0.8039851189 0.7936086059 0.7818176150 + 0.8046712875 0.7943117023 0.7825729847 + 0.8053575754 0.7950147986 0.7833284140 + 0.8060438037 0.7957177758 0.7840839028 + 0.8067299724 0.7964208722 0.7848392725 + 0.8074162006 0.7971240282 0.7855947018 + 0.8081002235 0.7978271842 0.7863516212 + 0.8087838292 0.7985303998 0.7871088982 + 0.8094673753 0.7992336154 0.7878661156 + 0.8101509809 0.7999367714 0.7886233926 + 0.8108345866 0.8006399870 0.7893806100 + 0.8115181923 0.8013432026 0.7901378274 + 0.8122016788 0.8020464778 0.7908951044 + 0.8128852844 0.8027496934 0.7916523218 + 0.8135688901 0.8034529090 0.7924095988 + 0.8142508864 0.8041560054 0.7931652069 + 0.8149294853 0.8048589826 0.7939171791 + 0.8156080842 0.8055620790 0.7946692705 + 0.8162866831 0.8062651157 0.7954213023 + 0.8169652820 0.8069680929 0.7961732745 + 0.8176438808 0.8076711297 0.7969254255 + 0.8183224797 0.8083741069 0.7976773977 + 0.8190010190 0.8090770841 0.7984294295 + 0.8196796179 0.8097801208 0.7991815209 + 0.8203582168 0.8104832172 0.7999334931 + 0.8210343719 0.8111814260 0.8006806970 + 0.8217092156 0.8118773103 0.8014255166 + 0.8223841190 0.8125730753 0.8021702170 + 0.8230590224 0.8132688999 0.8029149175 + 0.8237338066 0.8139647245 0.8036596775 + 0.8244087100 0.8146606088 0.8044043779 + 0.8250836134 0.8153563738 0.8051490784 + 0.8257583976 0.8160521984 0.8058938980 + 0.8264333010 0.8167480230 0.8066385984 + 0.8271082044 0.8174437881 0.8073834181 + 0.8277801871 0.8181331158 0.8081256151 + 0.8284516931 0.8188214898 0.8088673949 + 0.8291233182 0.8195099235 0.8096091747 + 0.8297948837 0.8201981783 0.8103510141 + 0.8304665089 0.8208866119 0.8110929132 + 0.8311380148 0.8215749860 0.8118346930 + 0.8318095803 0.8222633004 0.8125764728 + 0.8324812055 0.8229516745 0.8133183122 + 0.8331527710 0.8236399889 0.8140602112 + 0.8338242769 0.8243284225 0.8148019910 + 0.8344954848 0.8250157833 0.8155404925 + 0.8351665735 0.8257030845 0.8162788153 + 0.8358377218 0.8263903856 0.8170171976 + 0.8365089297 0.8270778060 0.8177555203 + 0.8371800184 0.8277651072 0.8184939027 + 0.8378511071 0.8284524083 0.8192322254 + 0.8385221958 0.8291397095 0.8199704885 + 0.8391934037 0.8298270702 0.8207088709 + 0.8398644924 0.8305143714 0.8214471936 + 0.8405355811 0.8312016726 0.8221855760 + 0.8412041068 0.8318877816 0.8229212165 + 0.8418722749 0.8325737119 0.8236564994 + 0.8425405025 0.8332597017 0.8243917823 + 0.8432086706 0.8339456916 0.8251271248 + 0.8438770175 0.8346316218 0.8258624077 + 0.8445451856 0.8353176117 0.8265976906 + 0.8452134132 0.8360034823 0.8273329735 + 0.8458815813 0.8366894722 0.8280683160 + 0.8465498090 0.8373754025 0.8288035989 + 0.8472179770 0.8380613923 0.8295388818 + 0.8478839993 0.8387414813 0.8302717209 + 0.8485488892 0.8394191861 0.8310034275 + 0.8492138982 0.8400970101 0.8317350745 + 0.8498789072 0.8407747149 0.8324669003 + 0.8505439162 0.8414524198 0.8331986070 + 0.8512089252 0.8421301842 0.8339303136 + 0.8518738747 0.8428078890 0.8346620202 + 0.8525388837 0.8434855938 0.8353937864 + 0.8532038927 0.8441634178 0.8361254930 + 0.8538689017 0.8448411226 0.8368571997 + 0.8545317054 0.8455154896 0.8375867009 + 0.8551911116 0.8461846709 0.8383126259 + 0.8558505177 0.8468537927 0.8390386105 + 0.8565099835 0.8475229740 0.8397644758 + 0.8571693897 0.8481922150 0.8404904008 + 0.8578287959 0.8488612771 0.8412163258 + 0.8584882021 0.8495305181 0.8419421911 + 0.8591476083 0.8501995802 0.8426681161 + 0.8598070145 0.8508688211 0.8433941007 + 0.8604664207 0.8515380025 0.8441200256 + 0.8611258268 0.8522071242 0.8448458910 + 0.8617823720 0.8528741002 0.8455688953 + 0.8624386787 0.8535410166 0.8462917209 + 0.8630949855 0.8542078137 0.8470144272 + 0.8637512922 0.8548746109 0.8477371931 + 0.8644075990 0.8555414081 0.8484598994 + 0.8650639057 0.8562082052 0.8491827250 + 0.8657202125 0.8568751216 0.8499054909 + 0.8663765192 0.8575419188 0.8506281972 + 0.8670328259 0.8582087159 0.8513510227 + 0.8676890731 0.8588755131 0.8520737290 + 0.8683446050 0.8595426083 0.8527960777 + 0.8689982891 0.8602101803 0.8535174727 + 0.8696519136 0.8608778119 0.8542389870 + 0.8703055978 0.8615455031 0.8549603820 + 0.8709592223 0.8622130752 0.8556818962 + 0.8716129065 0.8628807068 0.8564032912 + 0.8722665906 0.8635482788 0.8571248055 + 0.8729202151 0.8642160296 0.8578462005 + 0.8735738993 0.8648836017 0.8585677147 + 0.8742275238 0.8655511737 0.8592891097 + 0.8748812079 0.8662188053 0.8600106239 + 0.8755341172 0.8668799996 0.8607301712 + 0.8761864901 0.8675361276 0.8614482284 + 0.8768388033 0.8681921959 0.8621662855 + 0.8774911761 0.8688483238 0.8628842831 + 0.8781434894 0.8695043921 0.8636023998 + 0.8787959218 0.8701604009 0.8643205166 + 0.8794481754 0.8708165288 0.8650385141 + 0.8801006079 0.8714725971 0.8657565713 + 0.8807529211 0.8721287251 0.8664746284 + 0.8814052939 0.8727847934 0.8671926856 + 0.8820576072 0.8734409213 0.8679106832 + 0.8827077150 0.8740913868 0.8686279058 + 0.8833565116 0.8747391105 0.8693444729 + 0.8840054274 0.8753867745 0.8700612187 + 0.8846542835 0.8760343790 0.8707777858 + 0.8853030801 0.8766821027 0.8714944720 + 0.8859519958 0.8773298264 0.8722112179 + 0.8866009116 0.8779774904 0.8729277849 + 0.8872497082 0.8786250949 0.8736444712 + 0.8878986239 0.8792728186 0.8743610978 + 0.8885474205 0.8799204826 0.8750777841 + 0.8891962767 0.8805680871 0.8757944107 + 0.8898416162 0.8812143803 0.8765113950 + 0.8904845715 0.8818597794 0.8772286177 + 0.8911275268 0.8825051785 0.8779457808 + 0.8917704821 0.8831505775 0.8786630034 + 0.8924134970 0.8837959766 0.8793802857 + 0.8930563927 0.8844413757 0.8800975084 + 0.8936994076 0.8850867748 0.8808146715 + 0.8943423033 0.8857321143 0.8815318942 + 0.8949853182 0.8863775134 0.8822491169 + 0.8956282735 0.8870229125 0.8829662800 + 0.8962712288 0.8876683116 0.8836835027 + 0.8969116211 0.8883140087 0.8844001293 + 0.8975483775 0.8889601827 0.8851156831 + 0.8981850743 0.8896064162 0.8858312964 + 0.8988217711 0.8902524710 0.8865469098 + 0.8994585276 0.8908987045 0.8872625232 + 0.9000952244 0.8915448785 0.8879780769 + 0.9007319212 0.8921909928 0.8886936903 + 0.9013686180 0.8928372264 0.8894093037 + 0.9020053148 0.8934834003 0.8901249170 + 0.9026420116 0.8941295147 0.8908404112 + 0.9032788277 0.8947756886 0.8915560246 + 0.9039149880 0.8954212070 0.8922712803 + 0.9045432806 0.8960561156 0.8929808736 + 0.9051715732 0.8966909051 0.8936905265 + 0.9057999253 0.8973258138 0.8944001794 + 0.9064282179 0.8979606032 0.8951097727 + 0.9070565104 0.8985955119 0.8958194256 + 0.9076849222 0.8992303014 0.8965290189 + 0.9083132148 0.8998652101 0.8972386718 + 0.9089415073 0.9004999995 0.8979483247 + 0.9095697999 0.9011349082 0.8986579180 + 0.9101980925 0.9017696977 0.8993675113 + 0.9108263850 0.9024046063 0.9000772238 + 0.9114509225 0.9030348063 0.9007843137 + 0.9120721817 0.9036613703 0.9014893770 + 0.9126935005 0.9042879939 0.9021945000 + 0.9133148193 0.9049146175 0.9028996229 + 0.9139360785 0.9055411816 0.9036046267 + 0.9145573974 0.9061678052 0.9043096900 + 0.9151787162 0.9067944288 0.9050148129 + 0.9157999754 0.9074209929 0.9057198763 + 0.9164212942 0.9080476165 0.9064249992 + 0.9170426130 0.9086741805 0.9071301222 + 0.9176638722 0.9093006849 0.9078351855 + 0.9182853103 0.9099273086 0.9085403085 + 0.9188956022 0.9105505943 0.9092364907 + 0.9195045829 0.9111735225 0.9099317789 + 0.9201136827 0.9117963910 0.9106270075 + 0.9207227826 0.9124193192 0.9113222957 + 0.9213318229 0.9130421281 0.9120175242 + 0.9219409227 0.9136649966 0.9127128124 + 0.9225499034 0.9142879248 0.9134079814 + 0.9231590033 0.9149107933 0.9141033292 + 0.9237679839 0.9155337214 0.9147984982 + 0.9243770838 0.9161565900 0.9154937863 + 0.9249861240 0.9167795181 0.9161890149 + 0.9255942106 0.9174020886 0.9168831706 + 0.9261904955 0.9180212021 0.9175652862 + 0.9267867804 0.9186403751 0.9182474017 + 0.9273831248 0.9192596078 0.9189295173 + 0.9279794097 0.9198787808 0.9196115732 + 0.9285756946 0.9204980135 0.9202936888 + 0.9291719794 0.9211171269 0.9209758043 + 0.9297683239 0.9217363000 0.9216579199 + 0.9303646088 0.9223554730 0.9223399758 + 0.9309607744 0.9229747057 0.9230220914 + 0.9315571189 0.9235938787 0.9237042069 + 0.9321534038 0.9242129922 0.9243863225 + 0.9327489734 0.9248315096 0.9250671268 + 0.9333375096 0.9254437089 0.9257367849 + 0.9339259863 0.9260557890 0.9264063835 + 0.9345145226 0.9266679287 0.9270759821 + 0.9351029992 0.9272801280 0.9277455807 + 0.9356915951 0.9278922081 0.9284152985 + 0.9362800717 0.9285042882 0.9290848970 + 0.9368686080 0.9291164875 0.9297544956 + 0.9374570847 0.9297286272 0.9304240942 + 0.9380456209 0.9303408265 0.9310936928 + 0.9386342168 0.9309529066 0.9317634106 + 0.9392226934 0.9315649867 0.9324330091 + 0.9398112297 0.9321771860 0.9331026077 + 0.9403957725 0.9327827096 0.9337632060 + 0.9409803152 0.9333879948 0.9344233274 + 0.9415647984 0.9339932799 0.9350835085 + 0.9421492815 0.9345986247 0.9357436895 + 0.9427338243 0.9352039099 0.9364038110 + 0.9433181882 0.9358091950 0.9370639920 + 0.9439026713 0.9364144802 0.9377241731 + 0.9444872141 0.9370198250 0.9383842945 + 0.9450716972 0.9376251101 0.9390444756 + 0.9456561804 0.9382303953 0.9397047162 + 0.9462407231 0.9388356805 0.9403647780 + 0.9468250871 0.9394410253 0.9410250187 + 0.9474024773 0.9400426149 0.9416800141 + 0.9479761124 0.9406421781 0.9423323274 + 0.9485496879 0.9412418008 0.9429845214 + 0.9491233230 0.9418414831 0.9436367750 + 0.9496968985 0.9424411058 0.9442890882 + 0.9502704740 0.9430407286 0.9449412823 + 0.9508441091 0.9436402917 0.9455935955 + 0.9514176846 0.9442399740 0.9462457895 + 0.9519913197 0.9448395967 0.9468981028 + 0.9525648952 0.9454392195 0.9475504160 + 0.9531384706 0.9460387826 0.9482026100 + 0.9537121058 0.9466385245 0.9488549232 + 0.9542835951 0.9472373724 0.9495049119 + 0.9548454881 0.9478332996 0.9501445293 + 0.9554073811 0.9484291077 0.9507842064 + 0.9559693933 0.9490249753 0.9514238238 + 0.9565312862 0.9496209025 0.9520635009 + 0.9570931792 0.9502167106 0.9527031779 + 0.9576550722 0.9508125782 0.9533427954 + 0.9582170248 0.9514083862 0.9539824724 + 0.9587789178 0.9520043135 0.9546220899 + 0.9593408108 0.9526001811 0.9552618265 + 0.9599027038 0.9531959891 0.9559013844 + 0.9604645967 0.9537919164 0.9565411210 + 0.9610264897 0.9543877244 0.9571806788 + 0.9615818262 0.9549801946 0.9578106999 + 0.9621313214 0.9555696845 0.9584323764 + 0.9626806974 0.9561592937 0.9590541124 + 0.9632301927 0.9567487836 0.9596757293 + 0.9637796879 0.9573382735 0.9602974057 + 0.9643291831 0.9579278827 0.9609190822 + 0.9648786783 0.9585173726 0.9615408182 + 0.9654281735 0.9591069221 0.9621623755 + 0.9659777284 0.9596964717 0.9627841115 + 0.9665271044 0.9602860212 0.9634057879 + 0.9670765996 0.9608755112 0.9640274048 + 0.9676260948 0.9614651203 0.9646490812 + 0.9681755900 0.9620546103 0.9652708173 + 0.9687122703 0.9626389146 0.9658780098 + 0.9692441821 0.9632211924 0.9664797187 + 0.9697760940 0.9638035297 0.9670814276 + 0.9703080058 0.9643858075 0.9676830769 + 0.9708399177 0.9649680853 0.9682847857 + 0.9713717103 0.9655504227 0.9688864946 + 0.9719036222 0.9661327004 0.9694882035 + 0.9724354744 0.9667149782 0.9700899124 + 0.9729673862 0.9672973156 0.9706916213 + 0.9734992981 0.9678795934 0.9712932706 + 0.9740310907 0.9684618711 0.9718949795 + 0.9745630026 0.9690440893 0.9724966288 + 0.9750949144 0.9696264267 0.9730982780 + 0.9756121039 0.9702054262 0.9736818075 + 0.9761241078 0.9707831144 0.9742587805 + 0.9766359925 0.9713609219 0.9748356938 + 0.9771479964 0.9719387293 0.9754127264 + 0.9776600003 0.9725164175 0.9759895802 + 0.9781718850 0.9730942249 0.9765666127 + 0.9786838889 0.9736719131 0.9771435857 + 0.9791958928 0.9742497206 0.9777204990 + 0.9797077775 0.9748274088 0.9782974720 + 0.9802197814 0.9754052162 0.9788743854 + 0.9807317853 0.9759829044 0.9794514179 + 0.9812437296 0.9765607119 0.9800282717 + 0.9817556739 0.9771384001 0.9806053042 + 0.9822546244 0.9777116776 0.9811592102 + 0.9827439189 0.9782817960 0.9816957712 + 0.9832330942 0.9788517952 0.9822325110 + 0.9837223291 0.9794217944 0.9827690721 + 0.9842115045 0.9799917936 0.9833058119 + 0.9847007990 0.9805617929 0.9838423729 + 0.9851899743 0.9811317921 0.9843789935 + 0.9856792092 0.9817017913 0.9849156737 + 0.9861685038 0.9822717905 0.9854522943 + 0.9866576791 0.9828417897 0.9859889746 + 0.9871469140 0.9834119081 0.9865255952 + 0.9876360893 0.9839819074 0.9870622754 + 0.9881253839 0.9845519066 0.9875988960 + 0.9886041284 0.9851186275 0.9881225228 + 0.9890480042 0.9856745005 0.9886025786 + 0.9894918799 0.9862303734 0.9890826941 + 0.9899358153 0.9867863059 0.9895628095 + 0.9903796911 0.9873421788 0.9900428057 + 0.9908236265 0.9878981113 0.9905229211 + 0.9912675023 0.9884539843 0.9910029769 + 0.9917113781 0.9890099168 0.9914829731 + 0.9921553135 0.9895657897 0.9919630885 + 0.9925991893 0.9901217222 0.9924432039 + 0.9930431247 0.9906775951 0.9929233193 + 0.9934868813 0.9912334085 0.9934033155 + 0.9939308167 0.9917892814 0.9938833714 + 0.9943746924 0.9923452139 0.9943634868 + 0.9947882295 0.9928944707 0.9947875738 + 0.9951890707 0.9934411049 0.9951885939 + 0.9955899715 0.9939876795 0.9955894947 + 0.9959908724 0.9945343137 0.9959905148 + 0.9963918924 0.9950808287 0.9963914156 + 0.9967927933 0.9956274033 0.9967923760 + 0.9971936941 0.9961739779 0.9971932769 + 0.9975945950 0.9967206120 0.9975942969 + 0.9979954958 0.9972671270 0.9979951978 + 0.9983963966 0.9978137016 0.9983962178 + 0.9987972975 0.9983602762 0.9987971187 + 0.9991981983 0.9989069104 0.9991980791 + 0.9995990992 0.9994534254 0.9995989799 + 1.0000000000 1.0000000000 1.0000000000 +} diff --git a/rpplugins/color_correction/resources/film_luts_raw/kodak_portra_800.spi1d b/rpplugins/color_correction/resources/film_luts_raw/kodak_portra_800.spi1d new file mode 100644 index 0000000..754cb9b --- /dev/null +++ b/rpplugins/color_correction/resources/film_luts_raw/kodak_portra_800.spi1d @@ -0,0 +1,1030 @@ +Version 1 +From 0.0 1.0 +Length 1024 +Components 3 +{ + 0.0000000000 0.0000000000 0.0000000000 + 0.0088124285 0.0079260534 0.0079260534 + 0.0173182599 0.0154689904 0.0154689904 + 0.0250097904 0.0223134402 0.0223134402 + 0.0318675414 0.0285592694 0.0285592694 + 0.0382458083 0.0343292207 0.0343292207 + 0.0440907888 0.0397338495 0.0397338495 + 0.0496913791 0.0447938815 0.0447938815 + 0.0549593382 0.0496262200 0.0496262200 + 0.0600188002 0.0542288311 0.0542288311 + 0.0648257434 0.0586788617 0.0586788617 + 0.0694660619 0.0629591122 0.0629591122 + 0.0739658996 0.0670659617 0.0670659617 + 0.0782863200 0.0710892603 0.0710892603 + 0.0824507698 0.0749912113 0.0749912113 + 0.0864929035 0.0788405612 0.0788405612 + 0.0904697403 0.0825625733 0.0825625733 + 0.0943273082 0.0861979574 0.0861979574 + 0.0981024578 0.0897707865 0.0897707865 + 0.1018401012 0.0932211131 0.0932211131 + 0.1054691002 0.0966563523 0.0966563523 + 0.1090489030 0.1000294015 0.1000294015 + 0.1125440001 0.1033191979 0.1033191979 + 0.1159221008 0.1065331027 0.1065331027 + 0.1192713007 0.1097005978 0.1097005978 + 0.1225581989 0.1128138974 0.1128138974 + 0.1257860959 0.1158875003 0.1158875003 + 0.1289588958 0.1189555973 0.1189555973 + 0.1321441978 0.1219801009 0.1219801009 + 0.1352636069 0.1249566972 0.1249566972 + 0.1383159012 0.1278752983 0.1278752983 + 0.1413581967 0.1307422966 0.1307422966 + 0.1443576962 0.1336016953 0.1336016953 + 0.1472717971 0.1364331990 0.1364331990 + 0.1501350999 0.1392025054 0.1392025054 + 0.1529815942 0.1419408023 0.1419408023 + 0.1558008045 0.1446657926 0.1446657926 + 0.1586032957 0.1473688930 0.1473688930 + 0.1613503993 0.1500454992 0.1500454992 + 0.1640668958 0.1526847035 0.1526847035 + 0.1667777002 0.1552831978 0.1552831978 + 0.1694519967 0.1578582972 0.1578582972 + 0.1720923930 0.1604107022 0.1604107022 + 0.1746968031 0.1629472971 0.1629472971 + 0.1772591025 0.1654641926 0.1654641926 + 0.1797759980 0.1679515988 0.1679515988 + 0.1822800934 0.1704009026 0.1704009026 + 0.1847687066 0.1728225946 0.1728225946 + 0.1872310042 0.1752288938 0.1752288938 + 0.1896561980 0.1776168942 0.1776168942 + 0.1920384020 0.1799840033 0.1799840033 + 0.1944015026 0.1823205948 0.1823205948 + 0.1967525929 0.1846179962 0.1846179962 + 0.1990911067 0.1869053990 0.1869053990 + 0.2014010996 0.1891890019 0.1891890019 + 0.2037014961 0.1914498061 0.1914498061 + 0.2060168982 0.1936779022 0.1936779022 + 0.2083324045 0.1958771050 0.1958771050 + 0.2106439024 0.1980604976 0.1980604976 + 0.2129282951 0.2002373040 0.2002373040 + 0.2151844054 0.2024063021 0.2024063021 + 0.2174350023 0.2045633942 0.2045633942 + 0.2196764946 0.2067063004 0.2067063004 + 0.2219022959 0.2088321000 0.2088321000 + 0.2241204977 0.2109334022 0.2109334022 + 0.2263171971 0.2130157053 0.2130157053 + 0.2284786999 0.2150927931 0.2150927931 + 0.2306168973 0.2171598971 0.2171598971 + 0.2327332944 0.2192052007 0.2192052007 + 0.2348272949 0.2212346047 0.2212346047 + 0.2369115055 0.2232697010 0.2232697010 + 0.2389767021 0.2253111005 0.2253111005 + 0.2410169989 0.2273571938 0.2273571938 + 0.2430370003 0.2294019014 0.2294019014 + 0.2450459003 0.2314381003 0.2314381003 + 0.2470474988 0.2334637046 0.2334637046 + 0.2490427047 0.2354702950 0.2354702950 + 0.2510350049 0.2374535054 0.2374535054 + 0.2530182004 0.2394181937 0.2394181937 + 0.2549867928 0.2413693964 0.2413693964 + 0.2569330931 0.2433117926 0.2433117926 + 0.2588599026 0.2452446073 0.2452446073 + 0.2607747018 0.2471683025 0.2471683025 + 0.2626813948 0.2490822971 0.2490822971 + 0.2645846903 0.2509844899 0.2509844899 + 0.2664898038 0.2528660893 0.2528660893 + 0.2683837116 0.2547389865 0.2547389865 + 0.2702631950 0.2566035986 0.2566035986 + 0.2721140981 0.2584480941 0.2584480941 + 0.2739478052 0.2602775097 0.2602775097 + 0.2757706046 0.2620961070 0.2620961070 + 0.2775853872 0.2639020085 0.2639020085 + 0.2794038057 0.2656953037 0.2656953037 + 0.2812230885 0.2674824893 0.2674824893 + 0.2830418050 0.2692643106 0.2692643106 + 0.2848351002 0.2710475922 0.2710475922 + 0.2866136134 0.2728300095 0.2728300095 + 0.2883686125 0.2746050954 0.2746050954 + 0.2901135087 0.2763741016 0.2763741016 + 0.2918516994 0.2781391144 0.2781391144 + 0.2935769856 0.2798882127 0.2798882127 + 0.2953031063 0.2816232145 0.2816232145 + 0.2970305085 0.2833353877 0.2833353877 + 0.2987627089 0.2850272954 0.2850272954 + 0.3004961908 0.2867107093 0.2867107093 + 0.3022179008 0.2883763909 0.2883763909 + 0.3039326966 0.2900390029 0.2900390029 + 0.3056339025 0.2916957140 0.2916957140 + 0.3073236048 0.2933523953 0.2933523953 + 0.3090057075 0.2950091958 0.2950091958 + 0.3106757104 0.2966647148 0.2966647148 + 0.3123432994 0.2983194888 0.2983194888 + 0.3140107989 0.2999661863 0.2999661863 + 0.3156793118 0.3016082942 0.3016082942 + 0.3173511028 0.3032361865 0.3032361865 + 0.3190175891 0.3048543036 0.3048543036 + 0.3206757009 0.3064570129 0.3064570129 + 0.3223229051 0.3080512881 0.3080512881 + 0.3239594102 0.3096374869 0.3096374869 + 0.3255836964 0.3112207055 0.3112207055 + 0.3271996081 0.3128018975 0.3128018975 + 0.3288047910 0.3143788874 0.3143788874 + 0.3304041922 0.3159537017 0.3159537017 + 0.3320013881 0.3175298870 0.3175298870 + 0.3335976005 0.3191067874 0.3191067874 + 0.3351888955 0.3206779063 0.3206779063 + 0.3367778063 0.3222463131 0.3222463131 + 0.3383550048 0.3238070011 0.3238070011 + 0.3399255872 0.3253633976 0.3253633976 + 0.3414827883 0.3269123137 0.3269123137 + 0.3430297971 0.3284555078 0.3284555078 + 0.3445636928 0.3299894929 0.3299894929 + 0.3460822105 0.3315128088 0.3315128088 + 0.3475958109 0.3330293894 0.3330293894 + 0.3490990102 0.3345321119 0.3345321119 + 0.3506017923 0.3360328078 0.3360328078 + 0.3521026969 0.3375233114 0.3375233114 + 0.3536036015 0.3390137851 0.3390137851 + 0.3551059067 0.3404915035 0.3404915035 + 0.3566082120 0.3419683874 0.3419683874 + 0.3580994904 0.3434371054 0.3434371054 + 0.3595857024 0.3449020982 0.3449020982 + 0.3610610068 0.3463630974 0.3463630974 + 0.3625203967 0.3478182852 0.3478182852 + 0.3639777005 0.3492721915 0.3492721915 + 0.3654133976 0.3507139981 0.3507139981 + 0.3668490946 0.3521556854 0.3521556854 + 0.3682768941 0.3535880148 0.3535880148 + 0.3697017133 0.3550168872 0.3550168872 + 0.3711271882 0.3564417064 0.3564417064 + 0.3725540042 0.3578588068 0.3578588068 + 0.3739807904 0.3592759073 0.3592759073 + 0.3754133880 0.3606815040 0.3606815040 + 0.3768466115 0.3620859981 0.3620859981 + 0.3782753050 0.3634850979 0.3634850979 + 0.3796978891 0.3648771048 0.3648771048 + 0.3811204135 0.3662689924 0.3662689924 + 0.3825325072 0.3676514030 0.3676514030 + 0.3839435875 0.3690330088 0.3690330088 + 0.3853504956 0.3704110980 0.3704110980 + 0.3867498934 0.3717832863 0.3717832863 + 0.3881492913 0.3731555045 0.3731555045 + 0.3895345032 0.3745233119 0.3745233119 + 0.3909151852 0.3758895993 0.3758895993 + 0.3922944069 0.3772548139 0.3772548139 + 0.3936628103 0.3786112964 0.3786112964 + 0.3950310946 0.3799678087 0.3799678087 + 0.3963941932 0.3813194036 0.3813194036 + 0.3977501988 0.3826650083 0.3826650083 + 0.3991062939 0.3840106130 0.3840106130 + 0.4004457891 0.3853495121 0.3853495121 + 0.4017783105 0.3866856992 0.3866856992 + 0.4031107128 0.3880218863 0.3880218863 + 0.4044226110 0.3893507123 0.3893507123 + 0.4057329893 0.3906790018 0.3906790018 + 0.4070420861 0.3920061886 0.3920061886 + 0.4083415866 0.3933256865 0.3933256865 + 0.4096410871 0.3946452141 0.3946452141 + 0.4109367132 0.3959634900 0.3959634900 + 0.4122210145 0.3972786963 0.3972786963 + 0.4135052860 0.3985939026 0.3985939026 + 0.4147841930 0.3999078870 0.3999078870 + 0.4160529971 0.4012196958 0.4012196958 + 0.4173217118 0.4025315046 0.4025315046 + 0.4185839891 0.4038358033 0.4038358033 + 0.4198360145 0.4051288962 0.4051288962 + 0.4210878909 0.4064218998 0.4064218998 + 0.4223288000 0.4077093899 0.4077093899 + 0.4235515893 0.4089880884 0.4089880884 + 0.4247742891 0.4102669060 0.4102669060 + 0.4259923995 0.4115405083 0.4115405083 + 0.4272009134 0.4128041863 0.4128041863 + 0.4284093082 0.4140678942 0.4140678942 + 0.4296151102 0.4153267145 0.4153267145 + 0.4308117032 0.4165697992 0.4165697992 + 0.4320083857 0.4178129137 0.4178129137 + 0.4332041144 0.4190546870 0.4190546870 + 0.4343877137 0.4202808142 0.4202808142 + 0.4355713129 0.4215069115 0.4215069115 + 0.4367547929 0.4227330089 0.4227330089 + 0.4379391968 0.4239530861 0.4239530861 + 0.4391236901 0.4251722991 0.4251722991 + 0.4403083026 0.4263913929 0.4263913929 + 0.4414936900 0.4276081026 0.4276081026 + 0.4426796138 0.4288231134 0.4288231134 + 0.4438655972 0.4300382137 0.4300382137 + 0.4450480044 0.4312498868 0.4312498868 + 0.4462217093 0.4324539900 0.4324539900 + 0.4473954141 0.4336580038 0.4336580038 + 0.4485690892 0.4348619878 0.4348619878 + 0.4497332871 0.4360530078 0.4360530078 + 0.4508967996 0.4372431040 0.4372431040 + 0.4520604014 0.4384332895 0.4384332895 + 0.4532183111 0.4396133125 0.4396133125 + 0.4543708861 0.4407838881 0.4407838881 + 0.4555234909 0.4419544041 0.4419544041 + 0.4566758871 0.4431242943 0.4431242943 + 0.4578221142 0.4442783892 0.4442783892 + 0.4589683115 0.4454325140 0.4454325140 + 0.4601145089 0.4465866089 0.4465866089 + 0.4612562060 0.4477371871 0.4477371871 + 0.4623934925 0.4488846064 0.4488846064 + 0.4635308087 0.4500319064 0.4500319064 + 0.4646682143 0.4511792958 0.4511792958 + 0.4657953978 0.4523159862 0.4523159862 + 0.4669215977 0.4534518123 0.4534518123 + 0.4680477977 0.4545876086 0.4545876086 + 0.4691722989 0.4557209909 0.4557209909 + 0.4702917933 0.4568476975 0.4568476975 + 0.4714111984 0.4579744935 0.4579744935 + 0.4725306928 0.4591012895 0.4591012895 + 0.4736500978 0.4602225125 0.4602225125 + 0.4747695029 0.4613394141 0.4613394141 + 0.4758889973 0.4624564052 0.4624564052 + 0.4770084023 0.4635733068 0.4635733068 + 0.4781275094 0.4646795094 0.4646795094 + 0.4792464077 0.4657829106 0.4657829106 + 0.4803653955 0.4668863118 0.4668863118 + 0.4814842939 0.4679895937 0.4679895937 + 0.4825977981 0.4690910876 0.4690910876 + 0.4837110043 0.4701924026 0.4701924026 + 0.4848242104 0.4712938070 0.4712938070 + 0.4859367907 0.4723945856 0.4723945856 + 0.4870401919 0.4734885097 0.4734885097 + 0.4881435037 0.4745824933 0.4745824933 + 0.4892467856 0.4756763875 0.4756763875 + 0.4903483987 0.4767695963 0.4767695963 + 0.4914352894 0.4778566062 0.4778566062 + 0.4925222099 0.4789434969 0.4789434969 + 0.4936090112 0.4800305068 0.4800305068 + 0.4946955144 0.4811173975 0.4811173975 + 0.4957770109 0.4822036028 0.4822036028 + 0.4968583882 0.4832898080 0.4832898080 + 0.4979399145 0.4843761027 0.4843761027 + 0.4990214109 0.4854621887 0.4854621887 + 0.5000975728 0.4865370989 0.4865370989 + 0.5011737943 0.4876120090 0.4876120090 + 0.5022500157 0.4886868894 0.4886868894 + 0.5033261776 0.4897617996 0.4897617996 + 0.5043833256 0.4908238053 0.4908238053 + 0.5054367781 0.4918834865 0.4918834865 + 0.5064904094 0.4929431975 0.4929431975 + 0.5075439811 0.4940029085 0.4940029085 + 0.5085870028 0.4950586855 0.4950586855 + 0.5096237063 0.4961124063 0.4961124063 + 0.5106604099 0.4971660078 0.4971660078 + 0.5116971135 0.4982196093 0.4982196093 + 0.5127326250 0.4992741942 0.4992741942 + 0.5137655139 0.5003306270 0.5003306270 + 0.5147984028 0.5013868809 0.5013868809 + 0.5158312917 0.5024433136 0.5024433136 + 0.5168641806 0.5034996271 0.5034996271 + 0.5178936124 0.5045477748 0.5045477748 + 0.5189229250 0.5055958033 0.5055958033 + 0.5199521780 0.5066437721 0.5066437721 + 0.5209816098 0.5076918006 0.5076918006 + 0.5220068097 0.5087348819 0.5087348819 + 0.5230284929 0.5097740889 0.5097740889 + 0.5240502954 0.5108131766 0.5108131766 + 0.5250719786 0.5118523240 0.5118523240 + 0.5260933042 0.5128911138 0.5128911138 + 0.5271025896 0.5139240026 0.5139240026 + 0.5281118751 0.5149567723 0.5149567723 + 0.5291212201 0.5159897208 0.5159897208 + 0.5301305056 0.5170226097 0.5170226097 + 0.5311338902 0.5180504918 0.5180504918 + 0.5321304202 0.5190727711 0.5190727711 + 0.5331268907 0.5200952291 0.5200952291 + 0.5341234207 0.5211176276 0.5211176276 + 0.5351197720 0.5221399069 0.5221399069 + 0.5361112952 0.5231561065 0.5231561065 + 0.5371016860 0.5241708755 0.5241708755 + 0.5380920172 0.5251858234 0.5251858234 + 0.5390822887 0.5262005925 0.5262005925 + 0.5400725007 0.5272145271 0.5272145271 + 0.5410608053 0.5282195807 0.5282195807 + 0.5420491099 0.5292246938 0.5292246938 + 0.5430374742 0.5302299261 0.5302299261 + 0.5440257788 0.5312349796 0.5312349796 + 0.5450109243 0.5322359800 0.5322359800 + 0.5459877849 0.5332267880 0.5332267880 + 0.5469647050 0.5342177153 0.5342177153 + 0.5479416251 0.5352085233 0.5352085233 + 0.5489184856 0.5361993909 0.5361993909 + 0.5498880744 0.5371838212 0.5371838212 + 0.5508465767 0.5381588936 0.5381588936 + 0.5518051982 0.5391340256 0.5391340256 + 0.5527637005 0.5401090980 0.5401090980 + 0.5537223220 0.5410841703 0.5410841703 + 0.5546782017 0.5420532823 0.5420532823 + 0.5556306839 0.5430148244 0.5430148244 + 0.5565832853 0.5439764261 0.5439764261 + 0.5575358272 0.5449379086 0.5449379086 + 0.5584883094 0.5458995104 0.5458995104 + 0.5594409704 0.5468540192 0.5468540192 + 0.5603938103 0.5477982163 0.5477982163 + 0.5613465905 0.5487424135 0.5487424135 + 0.5622994900 0.5496866107 0.5496866107 + 0.5632522702 0.5506308079 0.5506308079 + 0.5642018914 0.5515701175 0.5515701175 + 0.5651431084 0.5524966717 0.5524966717 + 0.5660842061 0.5534232855 0.5534232855 + 0.5670254230 0.5543497801 0.5543497801 + 0.5679665804 0.5552763939 0.5552763939 + 0.5689064860 0.5562021732 0.5562021732 + 0.5698277950 0.5571172237 0.5571172237 + 0.5707491040 0.5580322146 0.5580322146 + 0.5716704130 0.5589473248 0.5589473248 + 0.5725917220 0.5598623157 0.5598623157 + 0.5735129714 0.5607773066 0.5607773066 + 0.5744280815 0.5616865754 0.5616865754 + 0.5753415227 0.5625941753 0.5625941753 + 0.5762547851 0.5635017753 0.5635017753 + 0.5771682262 0.5644093752 0.5644093752 + 0.5780814886 0.5653169751 0.5653169751 + 0.5789892077 0.5662230849 0.5662230849 + 0.5798879862 0.5671266913 0.5671266913 + 0.5807867050 0.5680304170 0.5680304170 + 0.5816854835 0.5689340234 0.5689340234 + 0.5825843215 0.5698376894 0.5698376894 + 0.5834829807 0.5707412958 0.5707412958 + 0.5843644738 0.5716376901 0.5716376901 + 0.5852444768 0.5725334883 0.5725334883 + 0.5861244798 0.5734294057 0.5734294057 + 0.5870044827 0.5743252039 0.5743252039 + 0.5878844857 0.5752210021 0.5752210021 + 0.5887588263 0.5761132240 0.5761132240 + 0.5896230936 0.5769993067 0.5769993067 + 0.5904874802 0.5778853893 0.5778853893 + 0.5913518071 0.5787714124 0.5787714124 + 0.5922161937 0.5796574950 0.5796574950 + 0.5930805206 0.5805435777 0.5805435777 + 0.5939381719 0.5814265013 0.5814265013 + 0.5947932005 0.5823081732 0.5823081732 + 0.5956482291 0.5831899047 0.5831899047 + 0.5965033174 0.5840715170 0.5840715170 + 0.5973582864 0.5849531889 0.5849531889 + 0.5982133150 0.5858349204 0.5858349204 + 0.5990638733 0.5867123008 0.5867123008 + 0.5999143124 0.5875896811 0.5875896811 + 0.6007646918 0.5884671211 0.5884671211 + 0.6016150713 0.5893443823 0.5893443823 + 0.6024655104 0.5902218223 0.5902218223 + 0.6033152938 0.5910989046 0.5910989046 + 0.6041615009 0.5919741988 0.5919741988 + 0.6050077081 0.5928496122 0.5928496122 + 0.6058537960 0.5937249064 0.5937249064 + 0.6067000031 0.5946002007 0.5946002007 + 0.6075462103 0.5954756141 0.5954756141 + 0.6083909273 0.5963500142 0.5963500142 + 0.6092299223 0.5972210169 0.5972210169 + 0.6100689769 0.5980920792 0.5980920792 + 0.6109080911 0.5989630818 0.5989630818 + 0.6117472053 0.5998342037 0.5998342037 + 0.6125863194 0.6007053256 0.6007053256 + 0.6134225726 0.6015741229 0.6015741229 + 0.6142470241 0.6024342179 0.6024342179 + 0.6150714755 0.6032943130 0.6032943130 + 0.6158959866 0.6041544080 0.6041544080 + 0.6167204976 0.6050143838 0.6050143838 + 0.6175450087 0.6058744788 0.6058744788 + 0.6183692813 0.6067342162 0.6067342162 + 0.6191921234 0.6075887084 0.6075887084 + 0.6200149059 0.6084432006 0.6084432006 + 0.6208376884 0.6092978120 0.6092978120 + 0.6216604710 0.6101523042 0.6101523042 + 0.6224833131 0.6110067964 0.6110067964 + 0.6233062148 0.6118612885 0.6118612885 + 0.6241316199 0.6127145290 0.6127145290 + 0.6249575019 0.6135674119 0.6135674119 + 0.6257833242 0.6144202948 0.6144202948 + 0.6266092062 0.6152731776 0.6152731776 + 0.6274350882 0.6161261201 0.6161261201 + 0.6282610297 0.6169791222 0.6169791222 + 0.6290842295 0.6178271174 0.6178271174 + 0.6299049258 0.6186708808 0.6186708808 + 0.6307256222 0.6195145845 0.6195145845 + 0.6315463781 0.6203582883 0.6203582883 + 0.6323670745 0.6212021112 0.6212021112 + 0.6331877708 0.6220458150 0.6220458150 + 0.6340078712 0.6228886247 0.6228886247 + 0.6348218918 0.6237223148 0.6237223148 + 0.6356359124 0.6245561242 0.6245561242 + 0.6364498734 0.6253898740 0.6253898740 + 0.6372638941 0.6262236238 0.6262236238 + 0.6380779147 0.6270573735 0.6270573735 + 0.6388918757 0.6278911829 0.6278911829 + 0.6397082210 0.6287242174 0.6287242174 + 0.6405261755 0.6295565963 0.6295565963 + 0.6413441896 0.6303889751 0.6303889751 + 0.6421622038 0.6312214136 0.6312214136 + 0.6429802775 0.6320537925 0.6320537925 + 0.6437982917 0.6328861713 0.6328861713 + 0.6446163058 0.6337186098 0.6337186098 + 0.6454324722 0.6345450282 0.6345450282 + 0.6462485194 0.6353709102 0.6353709102 + 0.6470645070 0.6361969113 0.6361969113 + 0.6478806138 0.6370227933 0.6370227933 + 0.6486966014 0.6378486753 0.6378486753 + 0.6495125890 0.6386746168 0.6386746168 + 0.6503264904 0.6394987106 0.6394987106 + 0.6511304975 0.6403145790 0.6403145790 + 0.6519343853 0.6411305070 0.6411305070 + 0.6527382731 0.6419463754 0.6419463754 + 0.6535422206 0.6427623034 0.6427623034 + 0.6543462276 0.6435781717 0.6435781717 + 0.6551501155 0.6443940997 0.6443940997 + 0.6559516191 0.6452056170 0.6452056170 + 0.6567478776 0.6460080147 0.6460080147 + 0.6575443149 0.6468102932 0.6468102932 + 0.6583405733 0.6476125717 0.6476125717 + 0.6591368914 0.6484150290 0.6484150290 + 0.6599332094 0.6492173076 0.6492173076 + 0.6607295871 0.6500195861 0.6500195861 + 0.6615231037 0.6508170962 0.6508170962 + 0.6623113751 0.6516057849 0.6516057849 + 0.6630997062 0.6523944736 0.6523944736 + 0.6638879776 0.6531832218 0.6531832218 + 0.6646761894 0.6539719105 0.6539719105 + 0.6654645205 0.6547605991 0.6547605991 + 0.6662527919 0.6555492878 0.6555492878 + 0.6670367718 0.6563370228 0.6563370228 + 0.6678087711 0.6571220756 0.6571220756 + 0.6685808897 0.6579073071 0.6579073071 + 0.6693528891 0.6586924195 0.6586924195 + 0.6701248884 0.6594774723 0.6594774723 + 0.6708970070 0.6602627039 0.6602627039 + 0.6716690063 0.6610478163 0.6610478163 + 0.6724401712 0.6618329883 0.6618329883 + 0.6731992960 0.6626194119 0.6626194119 + 0.6739584208 0.6634057760 0.6634057760 + 0.6747174859 0.6641921997 0.6641921997 + 0.6754766703 0.6649786234 0.6649786234 + 0.6762357950 0.6657649875 0.6657649875 + 0.6769949198 0.6665514112 0.6665514112 + 0.6777541041 0.6673377752 0.6673377752 + 0.6785085201 0.6681154966 0.6681154966 + 0.6792613268 0.6688904762 0.6688904762 + 0.6800141931 0.6696655154 0.6696655154 + 0.6807669997 0.6704404950 0.6704404950 + 0.6815198064 0.6712154746 0.6712154746 + 0.6822726727 0.6719905138 0.6719905138 + 0.6830254793 0.6727654934 0.6727654934 + 0.6837748289 0.6735368967 0.6735368967 + 0.6845164895 0.6743007898 0.6743007898 + 0.6852582097 0.6750648022 0.6750648022 + 0.6859998703 0.6758286953 0.6758286953 + 0.6867415905 0.6765927076 0.6765927076 + 0.6874831915 0.6773566008 0.6773566008 + 0.6882249117 0.6781204939 0.6781204939 + 0.6889665723 0.6788845062 0.6788845062 + 0.6897013187 0.6796460152 0.6796460152 + 0.6904339194 0.6804066896 0.6804066896 + 0.6911664009 0.6811674833 0.6811674833 + 0.6918990016 0.6819282770 0.6819282770 + 0.6926314831 0.6826890111 0.6826890111 + 0.6933640242 0.6834498048 0.6834498048 + 0.6940966249 0.6842104793 0.6842104793 + 0.6948286295 0.6849713922 0.6849713922 + 0.6955537796 0.6857334971 0.6857334971 + 0.6962791085 0.6864956021 0.6864956021 + 0.6970043778 0.6872575879 0.6872575879 + 0.6977297068 0.6880196929 0.6880196929 + 0.6984549761 0.6887817979 0.6887817979 + 0.6991803050 0.6895439029 0.6895439029 + 0.6999055743 0.6903060079 0.6903060079 + 0.7006272078 0.6910654902 0.6910654902 + 0.7013388276 0.6918187141 0.6918187141 + 0.7020503879 0.6925718188 0.6925718188 + 0.7027621269 0.6933249235 0.6933249235 + 0.7034736872 0.6940780282 0.6940780282 + 0.7041853070 0.6948311925 0.6948311925 + 0.7048969865 0.6955842972 0.6955842972 + 0.7056086063 0.6963374019 0.6963374019 + 0.7063143849 0.6970837116 0.6970837116 + 0.7070090175 0.6978172064 0.6978172064 + 0.7077037096 0.6985507011 0.6985507011 + 0.7083982825 0.6992840767 0.6992840767 + 0.7090929151 0.7000175714 0.7000175714 + 0.7097874880 0.7007511258 0.7007511258 + 0.7104821205 0.7014846206 0.7014846206 + 0.7111766934 0.7022181153 0.7022181153 + 0.7118694186 0.7029485703 0.7029485703 + 0.7125568986 0.7036715150 0.7036715150 + 0.7132444978 0.7043945193 0.7043945193 + 0.7139320970 0.7051174045 0.7051174045 + 0.7146195769 0.7058404088 0.7058404088 + 0.7153071761 0.7065634131 0.7065634131 + 0.7159947753 0.7072862983 0.7072862983 + 0.7166823745 0.7080093026 0.7080093026 + 0.7173694968 0.7087321281 0.7087321281 + 0.7180529237 0.7094535828 0.7094535828 + 0.7187362909 0.7101749778 0.7101749778 + 0.7194197178 0.7108964920 0.7108964920 + 0.7201030254 0.7116180062 0.7116180062 + 0.7207863927 0.7123395205 0.7123395205 + 0.7214698195 0.7130609155 0.7130609155 + 0.7221531272 0.7137824297 0.7137824297 + 0.7228364944 0.7145038843 0.7145038843 + 0.7235093117 0.7152239084 0.7152239084 + 0.7241787910 0.7159435153 0.7159435153 + 0.7248482704 0.7166631222 0.7166631222 + 0.7255179286 0.7173827291 0.7173827291 + 0.7261874080 0.7181022763 0.7181022763 + 0.7268568873 0.7188218832 0.7188218832 + 0.7275264263 0.7195414901 0.7195414901 + 0.7281959057 0.7202610970 0.7202610970 + 0.7288634181 0.7209777236 0.7209777236 + 0.7295259833 0.7216871977 0.7216871977 + 0.7301887274 0.7223966718 0.7223966718 + 0.7308512926 0.7231062055 0.7231062055 + 0.7315139771 0.7238156796 0.7238156796 + 0.7321766019 0.7245252132 0.7245252132 + 0.7328392863 0.7252346873 0.7252346873 + 0.7335019112 0.7259442210 0.7259442210 + 0.7341645956 0.7266536951 0.7266536951 + 0.7348304987 0.7273570895 0.7273570895 + 0.7354977727 0.7280579209 0.7280579209 + 0.7361652255 0.7287588120 0.7287588120 + 0.7368324995 0.7294595838 0.7294595838 + 0.7374997735 0.7301604152 0.7301604152 + 0.7381672263 0.7308611870 0.7308611870 + 0.7388345003 0.7315620184 0.7315620184 + 0.7395017743 0.7322629094 0.7322629094 + 0.7401691079 0.7329636812 0.7329636812 + 0.7408332229 0.7336601019 0.7336601019 + 0.7414970994 0.7343564034 0.7343564034 + 0.7421609163 0.7350527048 0.7350527048 + 0.7428247929 0.7357490063 0.7357490063 + 0.7434887290 0.7364453077 0.7364453077 + 0.7441526055 0.7371416092 0.7371416092 + 0.7448164225 0.7378379107 0.7378379107 + 0.7454802990 0.7385342121 0.7385342121 + 0.7461434007 0.7392303944 0.7392303944 + 0.7467958927 0.7399262190 0.7399262190 + 0.7474485040 0.7406219244 0.7406219244 + 0.7481011152 0.7413176894 0.7413176894 + 0.7487536073 0.7420133948 0.7420133948 + 0.7494062185 0.7427091002 0.7427091002 + 0.7500588298 0.7434049249 0.7434049249 + 0.7507113218 0.7441005707 0.7441005707 + 0.7513638735 0.7447963953 0.7447963953 + 0.7520164847 0.7454916835 0.7454916835 + 0.7526692152 0.7461783290 0.7461783290 + 0.7533218861 0.7468649745 0.7468649745 + 0.7539746165 0.7475516796 0.7475516796 + 0.7546272874 0.7482383251 0.7482383251 + 0.7552800179 0.7489249706 0.7489249706 + 0.7559326887 0.7496116757 0.7496116757 + 0.7565854192 0.7502983212 0.7502983212 + 0.7572380900 0.7509850264 0.7509850264 + 0.7578908205 0.7516716719 0.7516716719 + 0.7585409880 0.7523459196 0.7523459196 + 0.7591909766 0.7530183792 0.7530183792 + 0.7598409057 0.7536908984 0.7536908984 + 0.7604907751 0.7543634176 0.7543634176 + 0.7611407042 0.7550358772 0.7550358772 + 0.7617905736 0.7557083964 0.7557083964 + 0.7624406219 0.7563807964 0.7563807964 + 0.7630904913 0.7570533156 0.7570533156 + 0.7637404203 0.7577257752 0.7577257752 + 0.7643836737 0.7583953738 0.7583953738 + 0.7650216222 0.7590625286 0.7590625286 + 0.7656595111 0.7597296238 0.7597296238 + 0.7662972808 0.7603967190 0.7603967190 + 0.7669352293 0.7610638738 0.7610638738 + 0.7675729990 0.7617310286 0.7617310286 + 0.7682108879 0.7623981237 0.7623981237 + 0.7688487768 0.7630652785 0.7630652785 + 0.7694866061 0.7637323737 0.7637323737 + 0.7701240778 0.7643994093 0.7643994093 + 0.7707566023 0.7650648952 0.7650648952 + 0.7713890076 0.7657303810 0.7657303810 + 0.7720214725 0.7663959265 0.7663959265 + 0.7726539969 0.7670614123 0.7670614123 + 0.7732864022 0.7677268982 0.7677268982 + 0.7739189267 0.7683923841 0.7683923841 + 0.7745512724 0.7690579295 0.7690579295 + 0.7751837969 0.7697234154 0.7697234154 + 0.7758163214 0.7703889012 0.7703889012 + 0.7764492035 0.7710499763 0.7710499763 + 0.7770828009 0.7717056870 0.7717056870 + 0.7777163982 0.7723612785 0.7723612785 + 0.7783499956 0.7730169892 0.7730169892 + 0.7789835930 0.7736726999 0.7736726999 + 0.7796171904 0.7743282914 0.7743282914 + 0.7802507877 0.7749840021 0.7749840021 + 0.7808843851 0.7756395936 0.7756395936 + 0.7815179825 0.7762953043 0.7762953043 + 0.7821515799 0.7769508958 0.7769508958 + 0.7827799916 0.7775998712 0.7775998712 + 0.7834056020 0.7782453895 0.7782453895 + 0.7840312719 0.7788907886 0.7788907886 + 0.7846568823 0.7795363069 0.7795363069 + 0.7852826118 0.7801818252 0.7801818252 + 0.7859082222 0.7808272243 0.7808272243 + 0.7865338922 0.7814726830 0.7814726830 + 0.7871595025 0.7821182013 0.7821182013 + 0.7877851725 0.7827636003 0.7827636003 + 0.7884107828 0.7834091187 0.7834091187 + 0.7890290022 0.7840545177 0.7840545177 + 0.7896440029 0.7846997976 0.7846997976 + 0.7902588844 0.7853450775 0.7853450775 + 0.7908738852 0.7859904170 0.7859904170 + 0.7914888859 0.7866356969 0.7866356969 + 0.7921038866 0.7872809768 0.7872809768 + 0.7927188873 0.7879263163 0.7879263163 + 0.7933338881 0.7885715961 0.7885715961 + 0.7939488888 0.7892168760 0.7892168760 + 0.7945638895 0.7898622155 0.7898622155 + 0.7951788902 0.7905039191 0.7905039191 + 0.7957940102 0.7911430001 0.7911430001 + 0.7964090705 0.7917820811 0.7917820811 + 0.7970241904 0.7924212813 0.7924212813 + 0.7976393104 0.7930604219 0.7930604219 + 0.7982543707 0.7936995029 0.7936995029 + 0.7988696098 0.7943387032 0.7943387032 + 0.7994847298 0.7949777842 0.7949777842 + 0.8000997901 0.7956169248 0.7956169248 + 0.8007149100 0.7962561250 0.7962561250 + 0.8013291955 0.7968928814 0.7968928814 + 0.8019415736 0.7975248098 0.7975248098 + 0.8025540709 0.7981566787 0.7981566787 + 0.8031666279 0.7987886071 0.7987886071 + 0.8037791252 0.7994204760 0.7994204760 + 0.8043916225 0.8000524044 0.8000524044 + 0.8050041199 0.8006842732 0.8006842732 + 0.8056166172 0.8013160825 0.8013160825 + 0.8062291145 0.8019480109 0.8019480109 + 0.8068416119 0.8025798798 0.8025798798 + 0.8074541092 0.8032118082 0.8032118082 + 0.8080565929 0.8038352728 0.8038352728 + 0.8086578250 0.8044574857 0.8044574857 + 0.8092588782 0.8050796986 0.8050796986 + 0.8098599911 0.8057019114 0.8057019114 + 0.8104611039 0.8063241839 0.8063241839 + 0.8110622764 0.8069463968 0.8069463968 + 0.8116633892 0.8075686097 0.8075686097 + 0.8122645020 0.8081908226 0.8081908226 + 0.8128656745 0.8088130951 0.8088130951 + 0.8134667873 0.8094353080 0.8094353080 + 0.8140665889 0.8100557923 0.8100557923 + 0.8146625757 0.8106715083 0.8106715083 + 0.8152586818 0.8112871051 0.8112871051 + 0.8158547282 0.8119028211 0.8119028211 + 0.8164507151 0.8125184178 0.8125184178 + 0.8170468211 0.8131340742 0.8131340742 + 0.8176428080 0.8137496710 0.8137496710 + 0.8182387948 0.8143653870 0.8143653870 + 0.8188349009 0.8149809837 0.8149809837 + 0.8194308877 0.8155966997 0.8155966997 + 0.8200268745 0.8162122965 0.8162122965 + 0.8206235170 0.8168265820 0.8168265820 + 0.8212205768 0.8174393773 0.8174393773 + 0.8218176961 0.8180521131 0.8180521131 + 0.8224148154 0.8186649084 0.8186649084 + 0.8230118752 0.8192775846 0.8192775846 + 0.8236089945 0.8198903799 0.8198903799 + 0.8242061138 0.8205031157 0.8205031157 + 0.8248031735 0.8211159110 0.8211159110 + 0.8254002929 0.8217287064 0.8217287064 + 0.8259974122 0.8223413825 0.8223413825 + 0.8265944719 0.8229541779 0.8229541779 + 0.8271877766 0.8235660791 0.8235660791 + 0.8277773857 0.8241772056 0.8241772056 + 0.8283669949 0.8247882724 0.8247882724 + 0.8289566040 0.8253993988 0.8253993988 + 0.8295462728 0.8260105252 0.8260105252 + 0.8301358819 0.8266214728 0.8266214728 + 0.8307254910 0.8272325993 0.8272325993 + 0.8313151002 0.8278437257 0.8278437257 + 0.8319047093 0.8284547925 0.8284547925 + 0.8324943185 0.8290659189 0.8290659189 + 0.8330839276 0.8296769857 0.8296769857 + 0.8336697817 0.8302866220 0.8302866220 + 0.8342493773 0.8308938146 0.8308938146 + 0.8348289728 0.8315008879 0.8315008879 + 0.8354085088 0.8321080208 0.8321080208 + 0.8359881043 0.8327152133 0.8327152133 + 0.8365676999 0.8333222866 0.8333222866 + 0.8371472955 0.8339294195 0.8339294195 + 0.8377267718 0.8345366120 0.8345366120 + 0.8383064270 0.8351436853 0.8351436853 + 0.8388860226 0.8357508183 0.8357508183 + 0.8394654989 0.8363580108 0.8363580108 + 0.8400450945 0.8369646072 0.8369646072 + 0.8406248093 0.8375620246 0.8375620246 + 0.8412045240 0.8381593823 0.8381593823 + 0.8417841196 0.8387567997 0.8387567997 + 0.8423637748 0.8393542171 0.8393542171 + 0.8429434896 0.8399515748 0.8399515748 + 0.8435232043 0.8405489922 0.8405489922 + 0.8441029191 0.8411465287 0.8411465287 + 0.8446825743 0.8417438865 0.8417438865 + 0.8452622294 0.8423413038 0.8423413038 + 0.8458418846 0.8429387212 0.8429387212 + 0.8464215994 0.8435360789 0.8435360789 + 0.8469976187 0.8441309929 0.8441309929 + 0.8475704789 0.8447238207 0.8447238207 + 0.8481433988 0.8453165889 0.8453165889 + 0.8487163186 0.8459094167 0.8459094167 + 0.8492891788 0.8465021849 0.8465021849 + 0.8498620987 0.8470950127 0.8470950127 + 0.8504350185 0.8476877809 0.8476877809 + 0.8510079980 0.8482806087 0.8482806087 + 0.8515809178 0.8488733768 0.8488733768 + 0.8521537781 0.8494662046 0.8494662046 + 0.8527266979 0.8500589728 0.8500589728 + 0.8532996178 0.8506518006 0.8506518006 + 0.8538609147 0.8512412906 0.8512412906 + 0.8544201851 0.8518301845 0.8518301845 + 0.8549793959 0.8524190784 0.8524190784 + 0.8555387259 0.8530079126 0.8530079126 + 0.8560978770 0.8535968065 0.8535968065 + 0.8566572070 0.8541857004 0.8541857004 + 0.8572164178 0.8547745943 0.8547745943 + 0.8577756882 0.8553634882 0.8553634882 + 0.8583348989 0.8559523821 0.8559523821 + 0.8588942289 0.8565412760 0.8565412760 + 0.8594533801 0.8571302295 0.8571302295 + 0.8600127101 0.8577190042 0.8577190042 + 0.8605682254 0.8583009243 0.8583009243 + 0.8611236215 0.8588824272 0.8588824272 + 0.8616790771 0.8594639897 0.8594639897 + 0.8622344732 0.8600456119 0.8600456119 + 0.8627899289 0.8606271148 0.8606271148 + 0.8633453250 0.8612086773 0.8612086773 + 0.8639007211 0.8617901802 0.8617901802 + 0.8644561172 0.8623718023 0.8623718023 + 0.8650115132 0.8629534245 0.8629534245 + 0.8655669093 0.8635349274 0.8635349274 + 0.8661223054 0.8641164899 0.8641164899 + 0.8666777015 0.8646979928 0.8646979928 + 0.8672348261 0.8652762175 0.8652762175 + 0.8677921295 0.8658539057 0.8658539057 + 0.8683493733 0.8664317131 0.8664317131 + 0.8689066768 0.8670094013 0.8670094013 + 0.8694639206 0.8675870895 0.8675870895 + 0.8700212240 0.8681647778 0.8681647778 + 0.8705785275 0.8687425852 0.8687425852 + 0.8711357713 0.8693202734 0.8693202734 + 0.8716930747 0.8698980212 0.8698980212 + 0.8722503781 0.8704758286 0.8704758286 + 0.8728076816 0.8710535169 0.8710535169 + 0.8733649850 0.8716312051 0.8716312051 + 0.8739185929 0.8722062111 0.8722062111 + 0.8744698763 0.8727794290 0.8727794290 + 0.8750212193 0.8733525276 0.8733525276 + 0.8755723834 0.8739256859 0.8739256859 + 0.8761237264 0.8744989038 0.8744989038 + 0.8766748905 0.8750720024 0.8750720024 + 0.8772261739 0.8756452203 0.8756452203 + 0.8777773976 0.8762183785 0.8762183785 + 0.8783286810 0.8767915964 0.8767915964 + 0.8788799047 0.8773646951 0.8773646951 + 0.8794311881 0.8779379129 0.8779379129 + 0.8799824119 0.8785110712 0.8785110712 + 0.8805326223 0.8790833950 0.8790833950 + 0.8810753822 0.8796498775 0.8796498775 + 0.8816182017 0.8802164197 0.8802164197 + 0.8821610212 0.8807829022 0.8807829022 + 0.8827037811 0.8813493252 0.8813493252 + 0.8832466006 0.8819158077 0.8819158077 + 0.8837893009 0.8824822903 0.8824822903 + 0.8843321204 0.8830487728 0.8830487728 + 0.8848748803 0.8836153150 0.8836153150 + 0.8854176998 0.8841817975 0.8841817975 + 0.8859605193 0.8847482204 0.8847482204 + 0.8865032792 0.8853147030 0.8853147030 + 0.8870459795 0.8858811855 0.8858811855 + 0.8875892162 0.8864449859 0.8864449859 + 0.8881329894 0.8870056272 0.8870056272 + 0.8886767030 0.8875662088 0.8875662088 + 0.8892204762 0.8881267905 0.8881267905 + 0.8897641897 0.8886873126 0.8886873126 + 0.8903079033 0.8892478943 0.8892478943 + 0.8908516765 0.8898084760 0.8898084760 + 0.8913953900 0.8903689981 0.8903689981 + 0.8919392228 0.8909295797 0.8909295797 + 0.8924828768 0.8914902210 0.8914902210 + 0.8930265903 0.8920506835 0.8920506835 + 0.8935704231 0.8926113248 0.8926113248 + 0.8941140771 0.8931719065 0.8931719065 + 0.8946548104 0.8937309980 0.8937309980 + 0.8951931000 0.8942890167 0.8942890167 + 0.8957313895 0.8948469162 0.8948469162 + 0.8962696791 0.8954048753 0.8954048753 + 0.8968080282 0.8959628940 0.8959628940 + 0.8973463774 0.8965209126 0.8965209126 + 0.8978847265 0.8970788121 0.8970788121 + 0.8984230161 0.8976367712 0.8976367712 + 0.8989613056 0.8981947899 0.8981947899 + 0.8994995952 0.8987526894 0.8987526894 + 0.9000378847 0.8993107080 0.8993107080 + 0.9005761743 0.8998687267 0.8998687267 + 0.9011145234 0.9004266262 0.9004266262 + 0.9016473293 0.9009829760 0.9009829760 + 0.9021736979 0.9015374184 0.9015374184 + 0.9027001858 0.9020918012 0.9020918012 + 0.9032266140 0.9026463032 0.9026463032 + 0.9037529826 0.9032006860 0.9032006860 + 0.9042794108 0.9037551284 0.9037551284 + 0.9048057795 0.9043095112 0.9043095112 + 0.9053322077 0.9048638940 0.9048638940 + 0.9058586955 0.9054183960 0.9054183960 + 0.9063851237 0.9059727788 0.9059727788 + 0.9069114923 0.9065272212 0.9065272212 + 0.9074379206 0.9070816040 0.9070816040 + 0.9079642892 0.9076361060 0.9076361060 + 0.9084903002 0.9081891179 0.9081891179 + 0.9090139866 0.9087343812 0.9087343812 + 0.9095376730 0.9092797041 0.9092797041 + 0.9100614190 0.9098249078 0.9098249078 + 0.9105851054 0.9103701711 0.9103701711 + 0.9111087918 0.9109154940 0.9109154940 + 0.9116324782 0.9114606977 0.9114606977 + 0.9121562243 0.9120060205 0.9120060205 + 0.9126799107 0.9125512838 0.9125512838 + 0.9132035971 0.9130964875 0.9130964875 + 0.9137272835 0.9136418104 0.9136418104 + 0.9142510295 0.9141870737 0.9141870737 + 0.9147747755 0.9147322774 0.9147322774 + 0.9152985215 0.9152776003 0.9152776003 + 0.9158238173 0.9158192277 0.9158192277 + 0.9163501263 0.9163584709 0.9163584709 + 0.9168763757 0.9168977737 0.9168977737 + 0.9174026847 0.9174370766 0.9174370766 + 0.9179289937 0.9179763794 0.9179763794 + 0.9184553027 0.9185156226 0.9185156226 + 0.9189816117 0.9190549254 0.9190549254 + 0.9195079207 0.9195942283 0.9195942283 + 0.9200342298 0.9201334715 0.9201334715 + 0.9205604792 0.9206727743 0.9206727743 + 0.9210867882 0.9212120771 0.9212120771 + 0.9216129780 0.9217513800 0.9217513800 + 0.9221392870 0.9222906828 0.9222906828 + 0.9226655960 0.9228299856 0.9228299856 + 0.9231876731 0.9233682752 0.9233682752 + 0.9237092137 0.9239063859 0.9239063859 + 0.9242306948 0.9244444966 0.9244444966 + 0.9247521162 0.9249826074 0.9249826074 + 0.9252735972 0.9255207777 0.9255207777 + 0.9257950783 0.9260588884 0.9260588884 + 0.9263164997 0.9265969992 0.9265969992 + 0.9268379807 0.9271351099 0.9271351099 + 0.9273594022 0.9276732206 0.9276732206 + 0.9278808832 0.9282112718 0.9282112718 + 0.9284024239 0.9287495017 0.9287495017 + 0.9289237857 0.9292876124 0.9292876124 + 0.9294453263 0.9298257232 0.9298257232 + 0.9299668074 0.9303637743 0.9303637743 + 0.9304789901 0.9308947921 0.9308947921 + 0.9309902191 0.9314250946 0.9314250946 + 0.9315013885 0.9319552779 0.9319552779 + 0.9320126176 0.9324855804 0.9324855804 + 0.9325237274 0.9330158234 0.9330158234 + 0.9330348969 0.9335461259 0.9335461259 + 0.9335461259 0.9340763092 0.9340763092 + 0.9340572953 0.9346066117 0.9346066117 + 0.9345685244 0.9351367950 0.9351367950 + 0.9350796938 0.9356669784 0.9356669784 + 0.9355909228 0.9361972809 0.9361972809 + 0.9361019731 0.9367275238 0.9367275238 + 0.9366132021 0.9372578263 0.9372578263 + 0.9371243715 0.9377880096 0.9377880096 + 0.9376301169 0.9383096099 0.9383096099 + 0.9381334186 0.9388273954 0.9388273954 + 0.9386367202 0.9393453002 0.9393453002 + 0.9391400218 0.9398630857 0.9398630857 + 0.9396432042 0.9403809905 0.9403809905 + 0.9401465058 0.9408987761 0.9408987761 + 0.9406498075 0.9414166808 0.9414166808 + 0.9411531091 0.9419345260 0.9419345260 + 0.9416564107 0.9424523115 0.9424523115 + 0.9421597123 0.9429702163 0.9429702163 + 0.9426630139 0.9434880018 0.9434880018 + 0.9431663156 0.9440059066 0.9440059066 + 0.9436694980 0.9445236921 0.9445236921 + 0.9441727996 0.9450414777 0.9450414777 + 0.9446740746 0.9455562234 0.9455562234 + 0.9451695085 0.9460619092 0.9460619092 + 0.9456648827 0.9465677142 0.9465677142 + 0.9461603761 0.9470734000 0.9470734000 + 0.9466558099 0.9475792050 0.9475792050 + 0.9471513033 0.9480848908 0.9480848908 + 0.9476466775 0.9485906959 0.9485906959 + 0.9481421709 0.9490963817 0.9490963817 + 0.9486376047 0.9496021867 0.9496021867 + 0.9491330981 0.9501078725 0.9501078725 + 0.9496284723 0.9506136775 0.9506136775 + 0.9501240253 0.9511194229 0.9511194229 + 0.9506193995 0.9516252279 0.9516252279 + 0.9511148930 0.9521309137 0.9521309137 + 0.9516103268 0.9526367188 0.9526367188 + 0.9520999789 0.9531362057 0.9531362057 + 0.9525858164 0.9536315799 0.9536315799 + 0.9530715942 0.9541268945 0.9541268945 + 0.9535574913 0.9546223283 0.9546223283 + 0.9540433288 0.9551175833 0.9551175833 + 0.9545291066 0.9556128979 0.9556128979 + 0.9550148845 0.9561082721 0.9561082721 + 0.9555007219 0.9566035867 0.9566035867 + 0.9559866190 0.9570990205 0.9570990205 + 0.9564723969 0.9575942755 0.9575942755 + 0.9569581747 0.9580897093 0.9580897093 + 0.9574440122 0.9585850239 0.9585850239 + 0.9579297900 0.9590802789 0.9590802789 + 0.9584156871 0.9595757127 0.9595757127 + 0.9589015245 0.9600710273 0.9600710273 + 0.9593812823 0.9605569243 0.9605569243 + 0.9598584771 0.9610384107 0.9610384107 + 0.9603356123 0.9615200162 0.9615200162 + 0.9608128071 0.9620016217 0.9620016217 + 0.9612900019 0.9624832273 0.9624832273 + 0.9617670774 0.9629647136 0.9629647136 + 0.9622442722 0.9634463191 0.9634463191 + 0.9627214074 0.9639279246 0.9639279246 + 0.9631986022 0.9644094706 0.9644094706 + 0.9636756778 0.9648910165 0.9648910165 + 0.9641528726 0.9653726220 0.9653726220 + 0.9646300077 0.9658542275 0.9658542275 + 0.9651072025 0.9663357735 0.9663357735 + 0.9655842781 0.9668173194 0.9668173194 + 0.9660614729 0.9672989249 0.9672989249 + 0.9665307999 0.9677714705 0.9677714705 + 0.9669935107 0.9682365060 0.9682365060 + 0.9674562216 0.9687014818 0.9687014818 + 0.9679188728 0.9691665173 0.9691665173 + 0.9683815837 0.9696314931 0.9696314931 + 0.9688442945 0.9700965285 0.9700965285 + 0.9693070054 0.9705615044 0.9705615044 + 0.9697697163 0.9710264802 0.9710264802 + 0.9702324271 0.9714915156 0.9714915156 + 0.9706950188 0.9719564915 0.9719564915 + 0.9711577296 0.9724215269 0.9724215269 + 0.9716203809 0.9728865027 0.9728865027 + 0.9720830917 0.9733514786 0.9733514786 + 0.9725458026 0.9738165140 0.9738165140 + 0.9730085135 0.9742814898 0.9742814898 + 0.9734690189 0.9747437239 0.9747437239 + 0.9739159942 0.9751892090 0.9751892090 + 0.9743630886 0.9756346941 0.9756346941 + 0.9748101830 0.9760801792 0.9760801792 + 0.9752572775 0.9765257835 0.9765257835 + 0.9757043719 0.9769713283 0.9769713283 + 0.9761515260 0.9774168134 0.9774168134 + 0.9765985012 0.9778622985 0.9778622985 + 0.9770455956 0.9783079028 0.9783079028 + 0.9774926901 0.9787533879 0.9787533879 + 0.9779397845 0.9791988730 0.9791988730 + 0.9783868790 0.9796444178 0.9796444178 + 0.9788339734 0.9800899029 0.9800899029 + 0.9792810082 0.9805355072 0.9805355072 + 0.9797281027 0.9809809923 0.9809809923 + 0.9801751971 0.9814264774 0.9814264774 + 0.9806160927 0.9818611741 0.9818611741 + 0.9810506105 0.9822847247 0.9822847247 + 0.9814851284 0.9827082753 0.9827082753 + 0.9819195271 0.9831318855 0.9831318855 + 0.9823539853 0.9835553765 0.9835553765 + 0.9827885032 0.9839789867 0.9839789867 + 0.9832230210 0.9844024777 0.9844024777 + 0.9836574793 0.9848260880 0.9848260880 + 0.9840919971 0.9852495790 0.9852495790 + 0.9845265150 0.9856731892 0.9856731892 + 0.9849609733 0.9860966802 0.9860966802 + 0.9853954911 0.9865202904 0.9865202904 + 0.9858298898 0.9869437814 0.9869437814 + 0.9862644076 0.9873673916 0.9873673916 + 0.9866989255 0.9877910018 0.9877910018 + 0.9871333838 0.9882144928 0.9882144928 + 0.9875543714 0.9886164069 0.9886164069 + 0.9879658818 0.9890031219 0.9890031219 + 0.9883775115 0.9893897772 0.9893897772 + 0.9887890220 0.9897766113 0.9897766113 + 0.9892005920 0.9901633263 0.9901633263 + 0.9896121025 0.9905501008 0.9905501008 + 0.9900236726 0.9909368157 0.9909368157 + 0.9904351830 0.9913235903 0.9913235903 + 0.9908468127 0.9917103052 0.9917103052 + 0.9912583232 0.9920970201 0.9920970201 + 0.9916698933 0.9924837947 0.9924837947 + 0.9920814037 0.9928705096 0.9928705096 + 0.9924929738 0.9932572842 0.9932572842 + 0.9929044843 0.9936439991 0.9936439991 + 0.9933161139 0.9940307736 0.9940307736 + 0.9937276244 0.9944174886 0.9944174886 + 0.9941204190 0.9947785139 0.9947785139 + 0.9944878221 0.9951047897 0.9951047897 + 0.9948552847 0.9954311848 0.9954311848 + 0.9952228069 0.9957575202 0.9957575202 + 0.9955903292 0.9960837960 0.9960837960 + 0.9959577918 0.9964101911 0.9964101911 + 0.9963251948 0.9967365265 0.9967365265 + 0.9966927171 0.9970629215 0.9970629215 + 0.9970601797 0.9973891973 0.9973891973 + 0.9974277020 0.9977155924 0.9977155924 + 0.9977951050 0.9980419278 0.9980419278 + 0.9981626272 0.9983683228 0.9983683228 + 0.9985300899 0.9986945987 0.9986945987 + 0.9988976121 0.9990209937 0.9990209937 + 0.9992650151 0.9993473291 0.9993473291 + 0.9996324778 0.9996737242 0.9996737242 + 1.0000000000 1.0000000000 1.0000000000 +} diff --git a/rpplugins/color_correction/resources/generate_default_lut.py b/rpplugins/color_correction/resources/generate_default_lut.py new file mode 100644 index 0000000..67b3cff --- /dev/null +++ b/rpplugins/color_correction/resources/generate_default_lut.py @@ -0,0 +1,52 @@ +""" + +RenderPipeline + +Copyright (c) 2014-2016 tobspr + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. + +""" +from __future__ import division, print_function + +from panda3d.core import PNMImage + +lut_size = 64 +lut_cols = 8 +lut_rows = (lut_size + lut_cols - 1) // lut_cols + +img = PNMImage(lut_size * lut_cols, lut_size * lut_rows, 3, 2**16 - 1) + + +def to_linear(v): + return float(v) / float(lut_size - 1) + + +def to_linear_inv(v): + return 1 - to_linear(v) + +for r in range(lut_size): + for g in range(lut_size): + for b in range(lut_size): + slice_offset_x = (b % lut_cols) * lut_size + slice_offset_y = (b // lut_cols) * lut_size + img.set_xel(r + slice_offset_x, g + slice_offset_y, + to_linear(r), to_linear_inv(g), to_linear(b)) + +img.write("default_lut.png") diff --git a/rpplugins/color_correction/resources/generate_film_luts.py b/rpplugins/color_correction/resources/generate_film_luts.py new file mode 100644 index 0000000..96159a3 --- /dev/null +++ b/rpplugins/color_correction/resources/generate_film_luts.py @@ -0,0 +1,79 @@ +""" + +Script to convert spi1d files to luts + +""" + +from __future__ import print_function + +import os +from panda3d.core import PNMImage + +for f in os.listdir("film_luts_raw"): + if not f.endswith(".spi1d"): + continue + + input_file = "film_luts_raw/" + f + + print("Processing", input_file) + output_name = input_file.replace("\\", "/").split("/")[-1].replace(".spi1d", "") + + with open(input_file, "r") as handle: + content = [i.strip() for i in handle.readlines()] + + header = [ + "Version 1", + "From 0.0 1.0", + "Length 1024", + "Components 3", + "{", + ] + + for i, line in enumerate(header): + if content[i] != line: + print("Invalid header! Expected", line, "but got", content[i]) + break + else: + + content = content[len(header):-1] + + values = [[], [], []] + + def srgb_to_linear(channel): + if channel <= 0.04045: + return channel / 12.92 + else: + return pow((channel + 0.055) / (1.0 + 0.055), 2.4) + + for i in xrange(1024): + line = [float(k) for k in content[i].split()] + + for k in xrange(3): + values[k].append(srgb_to_linear(line[k])) + + def to_linear(v): + return float(v) / float(64 - 1) + + def to_linear_inv(v): + return 1 - to_linear(v) + + def lookup_value(v, values): + return values[int(v * (len(values) - 1))] + + # Generate lut + img = PNMImage(64 * 8, 64 * 8, 3, 2**16 - 1) + for r in xrange(64): + for g in xrange(64): + for b in xrange(64): + slice_offset_x = (b % 8) * 64 + slice_offset_y = (b // 8) * 64 + + fr, fg, fb = to_linear(r), to_linear_inv(g), to_linear(b) + + fr = lookup_value(fr, values[0]) + fg = lookup_value(fg, values[1]) + fb = lookup_value(fb, values[2]) + + img.set_xel(r + slice_offset_x, g + slice_offset_y, fr, fg, fb) + + img.write("film_luts/" + output_name + ".png") diff --git a/rpplugins/color_correction/shader/analyze_brightness.frag.glsl b/rpplugins/color_correction/shader/analyze_brightness.frag.glsl new file mode 100644 index 0000000..04cc79f --- /dev/null +++ b/rpplugins/color_correction/shader/analyze_brightness.frag.glsl @@ -0,0 +1,85 @@ +/** + * + * RenderPipeline + * + * Copyright (c) 2014-2016 tobspr + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + */ + +#version 430 + +#define USE_TIME_OF_DAY 1 +#pragma include "render_pipeline_base.inc.glsl" +#pragma include "includes/tonemapping.inc.glsl" + +layout(r16f) uniform imageBuffer RESTRICT ExposureStorage; +uniform sampler2D DownscaledTex; + +void main() { + + // Manually do the last downscale step + ivec2 texsize = textureSize(DownscaledTex, 0).xy; + float avg_luminance = 0.0; + for (int x = 0; x < texsize.x; ++x) { + for (int y = 0; y < texsize.y; ++y) { + avg_luminance += texelFetch(DownscaledTex, ivec2(x, y), 0).x; + } + } + + avg_luminance /= float(texsize.x * texsize.y); + avg_luminance = avg_luminance / (1 - avg_luminance); + + #if 0 + float exposure_val = computeEV100FromAvgLuminance(avg_luminance); + float exposure = convertEV100ToExposure(exposure_val); + #else + // Same as a above - just factored out. + float exposure = 0.1041666 * (1.0 / avg_luminance); + #endif + + float min_ev = GET_SETTING(color_correction, min_exposure_value); + float max_ev = GET_SETTING(color_correction, max_exposure_value); + float exposure_scale = GET_SETTING(color_correction, exposure_scale); + + // XXX: Without a multiplier of two, the image gets way too dark - not sure + // why, but most likely an issue in the exposure calculation. However, + // this is not physically correct. + exposure *= exposure_scale * 2.0; + + // Clamp to min and max exposure value + exposure = clamp(exposure, min_ev, max_ev); + + // Transition between the last and current value smoothly + float curr_exposure = imageLoad(ExposureStorage, 0).x; + float adaption_rate = GET_SETTING(color_correction, brightness_adaption_rate); + + if (curr_exposure < exposure) { + adaption_rate = GET_SETTING(color_correction, darkness_adaption_rate); + } + + const float adaption_speed = 0.8; + adaption_rate *= adaption_speed; + + float adjustment = saturate(MainSceneData.smooth_frame_delta * adaption_rate); + float new_luminance = mix(curr_exposure, exposure, adjustment); + new_luminance = clamp(new_luminance, 0.0, 1e4); + imageStore(ExposureStorage, 0, vec4(new_luminance)); +} diff --git a/rpplugins/color_correction/shader/apply_exposure.frag.glsl b/rpplugins/color_correction/shader/apply_exposure.frag.glsl new file mode 100644 index 0000000..b0be751 --- /dev/null +++ b/rpplugins/color_correction/shader/apply_exposure.frag.glsl @@ -0,0 +1,46 @@ +/** + * + * RenderPipeline + * + * Copyright (c) 2014-2016 tobspr + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + */ + +#version 430 + +#pragma include "render_pipeline_base.inc.glsl" + +uniform sampler2D ShadedScene; +uniform samplerBuffer Exposure; + +out vec3 result; + +void main() { + ivec2 coord = ivec2(gl_FragCoord.xy); + vec3 scene_color = texelFetch(ShadedScene, coord, 0).xyz; + + #if !DEBUG_MODE + float exposure = texelFetch(Exposure, 0).x; + scene_color *= exposure; + #endif + + result = scene_color; +} diff --git a/rpplugins/color_correction/shader/apply_tonemap.frag.glsl b/rpplugins/color_correction/shader/apply_tonemap.frag.glsl new file mode 100644 index 0000000..6f2332b --- /dev/null +++ b/rpplugins/color_correction/shader/apply_tonemap.frag.glsl @@ -0,0 +1,61 @@ +/** + * + * RenderPipeline + * + * Copyright (c) 2014-2016 tobspr + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + */ + +#version 430 + +#define USE_TIME_OF_DAY 1 +#pragma include "render_pipeline_base.inc.glsl" +#pragma include "includes/tonemapping.inc.glsl" + +uniform sampler2D ShadedScene; +uniform sampler3D ColorLUT; + +out vec4 result; + +vec3 apply_lut(vec3 color) { + // We have a gradient from 0.5 / lut_size to 1 - 0.5 / lut_size + // so we need to transform from 0 .. 1 to that gradient (hardcoded lut size for now) + const float lut_start = 0.5 / 64.0; + const float lut_end = 1.0 - lut_start; + color = color * (lut_end - lut_start) + lut_start; + return textureLod(ColorLUT, color, 0).xyz; +} + +void main() { + vec2 texcoord = get_texcoord(); + + #if !DEBUG_MODE + vec3 scene_color = textureLod(ShadedScene, texcoord, 0).xyz; + scene_color = do_tonemapping(scene_color); + scene_color = apply_lut(scene_color); + #else + vec3 scene_color = textureLod(ShadedScene, texcoord, 0).xyz; + #endif // !DEBUG_MODE + + scene_color = saturate(scene_color); + + result = vec4(scene_color, 1); +} diff --git a/rpplugins/color_correction/shader/chromatic_aberration.inc.glsl b/rpplugins/color_correction/shader/chromatic_aberration.inc.glsl new file mode 100644 index 0000000..52627ae --- /dev/null +++ b/rpplugins/color_correction/shader/chromatic_aberration.inc.glsl @@ -0,0 +1,60 @@ +/** + * + * RenderPipeline + * + * Copyright (c) 2014-2016 tobspr + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + */ + +#pragma once + +#pragma optionNV (unroll all) + +vec3 do_chromatic_aberration(sampler2D colortex, vec2 texcoord, float factor) { + + vec2 mid_coord = texcoord * 2.0 - 1.0; + vec3 blurred = vec3(0); + const int num_samples = GET_SETTING(color_correction, chromatic_aberration_samples); + + float factor_base = saturate(factor) * + GET_SETTING(color_correction, chromatic_aberration_strength); + float factor_strength = 25.0; + + vec2 mid_coord_r = mid_coord; + vec2 mid_coord_g = mid_coord * (1 - factor_base / factor_strength * 0.5); + vec2 mid_coord_b = mid_coord * (1 - factor_base / factor_strength); + + vec2 blur_dir = normalize(mid_coord + 1e-5) / SCREEN_SIZE * factor_strength * factor_base; + + for (int i = -num_samples; i <= num_samples; ++i) { + vec2 offset = float(i) / num_samples * blur_dir; + vec2 offcord_r = mid_coord_r + offset; + vec2 offcord_g = mid_coord_g + offset; + vec2 offcord_b = mid_coord_b + offset; + blurred.r += textureLod(colortex, offcord_r * 0.5 + 0.5, 0).r; + blurred.g += textureLod(colortex, offcord_g * 0.5 + 0.5, 0).g; + blurred.b += textureLod(colortex, offcord_b * 0.5 + 0.5, 0).b; + } + + blurred /= fma(float(num_samples), 2.0, 1.0); + + return blurred; +} diff --git a/rpplugins/color_correction/shader/downscale_luminance.frag.glsl b/rpplugins/color_correction/shader/downscale_luminance.frag.glsl new file mode 100644 index 0000000..087aff7 --- /dev/null +++ b/rpplugins/color_correction/shader/downscale_luminance.frag.glsl @@ -0,0 +1,44 @@ +/** + * + * RenderPipeline + * + * Copyright (c) 2014-2016 tobspr + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + */ + +#version 430 + +uniform sampler2D SourceTex; +out vec4 result; + +void main() { + vec2 texsize = vec2(textureSize(SourceTex, 0).xy); + ivec2 coord_screen = ivec2(gl_FragCoord.xy) * 4; + vec2 local_coord = (coord_screen + 1.0) / texsize; + vec2 pixel_offset = 2.0 / texsize; + + float lum = textureLod(SourceTex, local_coord, 0).x; + lum += textureLod(SourceTex, local_coord + vec2(pixel_offset.x, 0), 0).x; + lum += textureLod(SourceTex, local_coord + vec2(0, pixel_offset.y), 0).x; + lum += textureLod(SourceTex, local_coord + pixel_offset.xy, 0).x; + + result = vec4(lum * 0.25); +} diff --git a/rpplugins/color_correction/shader/generate_luminance.frag.glsl b/rpplugins/color_correction/shader/generate_luminance.frag.glsl new file mode 100644 index 0000000..17f3353 --- /dev/null +++ b/rpplugins/color_correction/shader/generate_luminance.frag.glsl @@ -0,0 +1,62 @@ +/** + * + * RenderPipeline + * + * Copyright (c) 2014-2016 tobspr + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + */ + +#version 430 +#pragma include "render_pipeline_base.inc.glsl" +#pragma include "includes/color_spaces.inc.glsl" + +// Converts the scene color to a luminance + +uniform sampler2D ShadedScene; +out float result; + +float get_log_luminance(vec3 color) { + float lum = get_luminance(color); + return lum / (1 + lum); +} + +void main() { + ivec2 coord_screen = ivec2(gl_FragCoord.xy) * 4; + vec2 local_coord = (coord_screen + 1.0) / SCREEN_SIZE; + vec2 pixel_offset = 2.0 / SCREEN_SIZE; + + // Weight luminance based on distance to the borders - this is because + // pixels in the center of the screen are more visually important + float weight = 1.05 - 0.2 * distance(local_coord, vec2(0.5, 0.5)); + + vec4 luminances = vec4( + get_log_luminance(weight * + textureLod(ShadedScene, local_coord, 0).xyz), + get_log_luminance(weight * + textureLod(ShadedScene, local_coord + vec2(pixel_offset.x, 0), 0).xyz), + get_log_luminance(weight * + textureLod(ShadedScene, local_coord + vec2(0, pixel_offset.y), 0).xyz), + get_log_luminance(weight * + textureLod(ShadedScene, local_coord + pixel_offset.xy, 0).xyz) + ); + + result = dot(luminances, vec4(0.25)); +} diff --git a/rpplugins/color_correction/shader/manual_exposure.frag.glsl b/rpplugins/color_correction/shader/manual_exposure.frag.glsl new file mode 100644 index 0000000..33de3f0 --- /dev/null +++ b/rpplugins/color_correction/shader/manual_exposure.frag.glsl @@ -0,0 +1,49 @@ +/** + * + * RenderPipeline + * + * Copyright (c) 2014-2016 tobspr + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + */ + +#version 430 + +#define USE_TIME_OF_DAY 1 +#pragma include "render_pipeline_base.inc.glsl" +#pragma include "includes/tonemapping.inc.glsl" + +uniform sampler2D ShadedScene; + +out vec3 result; + +// Applies manual camera parameters + +void main() { + vec2 texcoord = get_texcoord(); + + float exposure_val = computeEV100( + TimeOfDay.color_correction.camera_aperture, + TimeOfDay.color_correction.camera_shutter, + TimeOfDay.color_correction.camera_iso); + + float exposure = convertEV100ToExposure(exposure_val); + result = textureLod(ShadedScene, texcoord, 0).xyz * exposure; +} diff --git a/rpplugins/color_correction/shader/post_fx.frag.glsl b/rpplugins/color_correction/shader/post_fx.frag.glsl new file mode 100644 index 0000000..e220101 --- /dev/null +++ b/rpplugins/color_correction/shader/post_fx.frag.glsl @@ -0,0 +1,79 @@ +/** + * + * RenderPipeline + * + * Copyright (c) 2014-2016 tobspr + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + */ + +#version 430 + +#define USE_TIME_OF_DAY 1 +#pragma include "render_pipeline_base.inc.glsl" +#pragma include "includes/transforms.inc.glsl" +#pragma include "includes/noise.inc.glsl" + +#pragma include "chromatic_aberration.inc.glsl" + +uniform sampler2D ShadedScene; + +out vec4 result; + + +void main() { + + vec2 texcoord = get_texcoord(); + + #if !DEBUG_MODE + + + vec2 ccord = (texcoord - 0.5) * vec2(1.0, ASPECT_RATIO); + float vignette = 1 - saturate(length(ccord)); + + // Chromatic abberation + #if GET_SETTING(color_correction, use_chromatic_aberration) + vec3 scene_color = do_chromatic_aberration(ShadedScene, texcoord, 1-vignette); + #else + vec3 scene_color = textureLod(ShadedScene, texcoord, 0).xyz; + #endif + + // Compute film grain + float film_grain = grain(MainSceneData.frame_time); + vec3 blended_color = blend_soft_light(scene_color, vec3(film_grain)); + + // Blend film grain + float grain_factor = GET_SETTING(color_correction, film_grain_strength); + scene_color = mix(scene_color, blended_color, grain_factor); + + // const float saturation = 0.00; + // scene_color = max(vec3(0), (scene_color - saturation) / (1 - saturation)); + + // Apply the vignette based on the vignette strength + scene_color *= mix(1.0, vignette, GET_SETTING(color_correction, vignette_strength)); + + + #else + vec3 scene_color = textureLod(ShadedScene, texcoord, 0).xyz; + #endif // !DEBUG_MODE + + + result = vec4(scene_color, 1); +} diff --git a/rpplugins/color_correction/shader/sharpen.frag.glsl b/rpplugins/color_correction/shader/sharpen.frag.glsl new file mode 100644 index 0000000..1aea9d5 --- /dev/null +++ b/rpplugins/color_correction/shader/sharpen.frag.glsl @@ -0,0 +1,60 @@ +/** + * + * RenderPipeline + * + * Copyright (c) 2014-2016 tobspr + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + */ + +#version 430 + +#pragma include "render_pipeline_base.inc.glsl" +#pragma include "includes/color_spaces.inc.glsl" + +uniform sampler2D ShadedScene; +out vec3 result; + +void main() { + + vec2 texcoord = (ivec2(gl_FragCoord.xy) + 0.5) / NATIVE_SCREEN_SIZE; + vec3 scene_color = textureLod(ShadedScene, texcoord, 0).xyz; + + // Compute the sharpen strength for each individual channel + const float sharpen_strength = GET_SETTING(color_correction, sharpen_strength); + + vec2 pixel_size = 1.0 / NATIVE_SCREEN_SIZE; + const float r = 0.8; + + // Blur arround the current pixel + vec3 blur_sum = vec3(0); + blur_sum += textureLod(ShadedScene, texcoord + vec2(r, -r) * pixel_size, 0).rgb; + blur_sum += textureLod(ShadedScene, texcoord + vec2(-r, -r) * pixel_size, 0).rgb; + blur_sum += textureLod(ShadedScene, texcoord + vec2(r, r) * pixel_size, 0).rgb; + blur_sum += textureLod(ShadedScene, texcoord + vec2(-r, r) * pixel_size, 0).rgb; + + vec3 pixel_diff = scene_color - blur_sum * 0.25; + + // Apply the sharpening + #if !DEBUG_MODE + scene_color += dot(pixel_diff, LUMA_COEFFS * sharpen_strength); + #endif + result = scene_color; +} diff --git a/rpplugins/color_correction/sharpen_stage.py b/rpplugins/color_correction/sharpen_stage.py new file mode 100644 index 0000000..553ad60 --- /dev/null +++ b/rpplugins/color_correction/sharpen_stage.py @@ -0,0 +1,73 @@ +""" + +RenderPipeline + +Copyright (c) 2014-2016 tobspr + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. + +""" + +from __future__ import division + +from rplibs.six import itervalues + +from rpcore.globals import Globals +from rpcore.render_stage import RenderStage + + +class SharpenStage(RenderStage): + + required_inputs = [] + required_pipes = ["ShadedScene"] + + def __init__(self, pipeline): + RenderStage.__init__(self, pipeline) + self.sharpen_twice = True + + @property + def produced_pipes(self): + if self.sharpen_twice: + return {"ShadedScene": self.target2.color_tex} + else: + return {"ShadedScene": self.target.color_tex} + + def create(self): + native_size = Globals.native_resolution.x, Globals.native_resolution.y + self.target = self.create_target("Sharpen") + self.target.size = native_size + self.target.add_color_attachment(bits=16) + self.target.prepare_buffer() + + if self.sharpen_twice: + self.target2 = self.create_target("Sharpen2") + self.target2.size = native_size + self.target2.add_color_attachment(bits=16) + self.target2.prepare_buffer() + self.target2.set_shader_input("ShadedScene", self.target.color_tex) + + def set_dimensions(self): + self.target.size = Globals.native_resolution.x, Globals.native_resolution.y + if self.sharpen_twice: + self.target2.size = Globals.native_resolution.x, Globals.native_resolution.y + + def reload_shaders(self): + sharpen_shader = self.load_plugin_shader("sharpen.frag.glsl") + for target in itervalues(self._targets): + target.shader = sharpen_shader diff --git a/rpplugins/color_correction/tonemapping_stage.py b/rpplugins/color_correction/tonemapping_stage.py new file mode 100644 index 0000000..f2f54a4 --- /dev/null +++ b/rpplugins/color_correction/tonemapping_stage.py @@ -0,0 +1,45 @@ +""" + +RenderPipeline + +Copyright (c) 2014-2016 tobspr + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. + +""" + +from rpcore.render_stage import RenderStage + + +class TonemappingStage(RenderStage): + + required_inputs = [] + required_pipes = ["ShadedScene"] + + @property + def produced_pipes(self): + return {"ShadedScene": self.target.color_tex} + + def create(self): + self.target = self.create_target("Tonemap") + self.target.add_color_attachment(bits=16) + self.target.prepare_buffer() + + def reload_shaders(self): + self.target.shader = self.load_plugin_shader("apply_tonemap.frag.glsl") diff --git a/rpplugins/dof/__init__.py b/rpplugins/dof/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/rpplugins/dof/config.yaml b/rpplugins/dof/config.yaml new file mode 100644 index 0000000..adb4ee9 --- /dev/null +++ b/rpplugins/dof/config.yaml @@ -0,0 +1,42 @@ + +settings: !!omap + + - focal_point: + type: float + range: [0.0, 10000.0] + default: 10.0 + shader_runtime: true + label: Focal point + description: > + The focal point distance to the camera. + + - focal_size: + type: float + range: [0.0, 5000.0] + default: 2.5 + label: Focal size + shader_runtime: true + description: > + Size of the focal region. + + - blur_strength: + type: float + range: [0.0, 1.0] + default: 0.5 + label: Blur strength + shader_runtime: true + description: > + Strength of the blur - Will get replaced by a physically based + parameter soon! + + - near_blur_strength: + type: float + range: [0.0, 1.0] + default: 0.5 + label: Near Blur strength + shader_runtime: true + description: > + Strength of the near-field blur - Will get replaced by a physically based + parameter soon! + +daytime_settings: diff --git a/rpplugins/dof/dof_stage.py b/rpplugins/dof/dof_stage.py new file mode 100644 index 0000000..b88da33 --- /dev/null +++ b/rpplugins/dof/dof_stage.py @@ -0,0 +1,101 @@ +""" + +RenderPipeline + +Copyright (c) 2014-2016 tobspr + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. + +""" + +from rpcore.render_stage import RenderStage + + +class DoFStage(RenderStage): + + """ This stage does the DoF pass """ + + required_inputs = [] + required_pipes = ["ShadedScene", "GBuffer", "DownscaledDepth"] + + @property + def produced_pipes(self): + return {"ShadedScene": self.target_merge.color_tex} + + def create(self): + + self.target_prefilter = self.create_target("PrefilterDoF") + # self.target_prefilter.size = -2 + self.target_prefilter.add_color_attachment(bits=16, alpha=True) + self.target_prefilter.prepare_buffer() + + self.tile_size = 32 + self.tile_target = self.create_target("FetchVertDOF") + self.tile_target.size = -1, -self.tile_size + self.tile_target.add_color_attachment(bits=(16, 16, 0)) + self.tile_target.prepare_buffer() + + self.tile_target.set_shader_input("PrecomputedCoC", self.target_prefilter.color_tex) + + self.tile_target_horiz = self.create_target("FetchHorizDOF") + self.tile_target_horiz.size = -self.tile_size + self.tile_target_horiz.add_color_attachment(bits=(16, 16, 0)) + self.tile_target_horiz.prepare_buffer() + self.tile_target_horiz.set_shader_input("SourceTex", self.tile_target.color_tex) + + self.minmax_target = self.create_target("DoFNeighborMinMax") + self.minmax_target.size = -self.tile_size + self.minmax_target.add_color_attachment(bits=(16, 16, 0)) + self.minmax_target.prepare_buffer() + self.minmax_target.set_shader_input("TileMinMax", self.tile_target_horiz.color_tex) + + self.presort_target = self.create_target("DoFPresort") + self.presort_target.add_color_attachment(bits=(11, 11, 10)) + self.presort_target.prepare_buffer() + self.presort_target.set_shader_inputs( + TileMinMax=self.minmax_target.color_tex, + PrecomputedCoC=self.target_prefilter.color_tex) + + self.target = self.create_target("ComputeDoF") + # self.target.size = -2 + self.target.add_color_attachment(bits=16, alpha=True) + self.target.prepare_buffer() + self.target.set_shader_inputs( + PresortResult=self.presort_target.color_tex, + PrecomputedCoC=self.target_prefilter.color_tex, + TileMinMax=self.minmax_target.color_tex) + + self.target_merge = self.create_target("MergeDoF") + self.target_merge.add_color_attachment(bits=16) + self.target_merge.prepare_buffer() + self.target_merge.set_shader_input("SourceTex", self.target.color_tex) + + # self.target_upscale.set_shader_input("SourceTex", self.target.color_tex) + # self.target_upscale.set_shader_input("upscaleWeights", Vec2(0.001, 0.001)) + + def reload_shaders(self): + self.tile_target.shader = self.load_plugin_shader("fetch_dof_minmax.frag.glsl") + self.tile_target_horiz.shader = self.load_plugin_shader("fetch_dof_minmax_horiz.frag.glsl") + self.minmax_target.shader = self.load_plugin_shader("fetch_dof_tile_neighbors.frag.glsl") + self.presort_target.shader = self.load_plugin_shader("dof_presort.frag.glsl") + self.target_prefilter.shader = self.load_plugin_shader("prefilter_dof.frag.glsl") + self.target.shader = self.load_plugin_shader("compute_dof.frag.glsl") + self.target_merge.shader = self.load_plugin_shader("merge_dof.frag.glsl") + # self.target_upscale.shader = self.load_plugin_shader( + # "/$$rp/shader/bilateral_upscale.frag.glsl") diff --git a/rpplugins/dof/plugin.py b/rpplugins/dof/plugin.py new file mode 100644 index 0000000..6c3b3e4 --- /dev/null +++ b/rpplugins/dof/plugin.py @@ -0,0 +1,48 @@ +""" + +RenderPipeline + +Copyright (c) 2014-2016 tobspr + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. + +""" + +from rpcore.pluginbase.base_plugin import BasePlugin + +from .dof_stage import DoFStage + + +class Plugin(BasePlugin): + + name = "Depth of Field" + author = "tobspr " + description = ("Adds support for depth of field") + version = "alpha (!)" + + def on_stage_setup(self): + self._stage = self.create_stage(DoFStage) + + def on_pipeline_created(self): + pass + + def update_some_setting(self): + """ This method gets called when the setting "some_setting" + of your plugin gets called. You should do all work to update required + inputs etc. yourself. """ diff --git a/rpplugins/dof/shader/compute_dof.frag.glsl b/rpplugins/dof/shader/compute_dof.frag.glsl new file mode 100644 index 0000000..e7f25c2 --- /dev/null +++ b/rpplugins/dof/shader/compute_dof.frag.glsl @@ -0,0 +1,124 @@ +/** + * + * RenderPipeline + * + * Copyright (c) 2014-2016 tobspr + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + */ + +#version 430 + +#pragma include "render_pipeline_base.inc.glsl" +#pragma include "dof.inc.glsl" +#pragma include "includes/noise.inc.glsl" + +uniform sampler2D ShadedScene; +uniform sampler2D PresortResult; +uniform sampler2D PrecomputedCoC; +uniform sampler2D TileMinMax; +out vec4 result; + +/* + +WORK IN PROGRESS + +This code is code in progress and such not formatted very nicely nor commented! + +*/ + +float intersect_circle(vec2 d, float radius) { + float latt = saturate(length(d * vec2(1, 1)) / radius); + latt = pow(latt, 10.0); + latt = 1 - latt; + return latt; + + if (length(d) <= radius) { + return 1.0; + } + return 0.0; +} + +void main() { + + vec2 texcoord = get_texcoord(); + ivec2 tile_coord = ivec2(ivec2(gl_FragCoord.xy) / vec2(tile_size)); + vec2 tile_data = texelFetch(TileMinMax, tile_coord, 0).xy; + float tile_max_depth = tile_data.x; + float tile_max_coc = tile_data.y; + + vec3 presort_result = textureLod(PresortResult, texcoord, 0).xyz; + float mid_coc = presort_result.x; + + if (tile_max_coc <= 1e-4) { + result = textureLod(ShadedScene, texcoord, 0); + result.w = 0; + } + + vec2 max_radius = 16.0 / SCREEN_SIZE; + + vec3 jitter = rand_rgb(texcoord); + + const int num_ring_samples = 4; + float max_length = length(max_radius * vec2(1, 1)); + + int num_samples = 0; + + vec3 scene_color = textureLod(ShadedScene, texcoord, 0).xyz; + + float alpha = 0.0; + vec4 foreground = vec4(scene_color, 1) * 1e-4; + vec4 background = vec4(scene_color, 1) * 1e-4; + + for (int ring = 0; ring <= num_ring_samples; ++ring) { + int n_samples = max(1, 8 * ring); + vec2 r = max_radius * ring / float(num_ring_samples) * (tile_max_coc); + // vec2 r = max_radius * ring / float(num_ring_samples); + + for (int i = 0; i < n_samples; ++i) { + ++num_samples; + float phi = i / float(n_samples) * TWO_PI; + float x_offs = sin(phi); + float y_offs = cos(phi); + + vec2 tcoord = texcoord + vec2(x_offs, y_offs) * r; + // tcoord += jitter.xy * 0.1 * r; + + // XXX: Instead of manual clamping, use a near filtered texture + tcoord = truncate_coordinate(tcoord); + + vec3 sample_data = textureLod(PresortResult, tcoord, 0).xyz; + vec3 color_data = textureLod(PrecomputedCoC, tcoord, 0).xyz; + + float coc_weight = intersect_circle(r, sample_data.x * max_length); + coc_weight *= 1.0 / max(1e-9, sample_data.x * sample_data.x); + foreground += vec4(color_data, 1) * coc_weight; + // foreground += vec4(color_data, 1) * coc_weight * sample_data.y; + // background += vec4(color_data, 1) * coc_weight * sample_data.z; + } + } + + foreground.xyz /= max(1e-5, foreground.w); + // background.xyz /= max(1e-5, background.w); + + // result = mix(background, foreground, saturate(2 * foreground.w / num_samples)); + result = foreground; + result.w = mid_coc; +} diff --git a/rpplugins/dof/shader/dof.inc.glsl b/rpplugins/dof/shader/dof.inc.glsl new file mode 100644 index 0000000..5900462 --- /dev/null +++ b/rpplugins/dof/shader/dof.inc.glsl @@ -0,0 +1,48 @@ +/** + * + * RenderPipeline + * + * Copyright (c) 2014-2016 tobspr + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + */ + +const int tile_size = 32; + +#define DOF_DEPTH_SCALE_FOREGROUND 250.0 +#define DOF_SINGLE_PIXEL_RADIUS 1.0 +// #define DOF_SINGLE_PIXEL_RADIUS 1.0 + +vec2 compare_depth(float depth, float tile_max_depth) +{ + float d = DOF_DEPTH_SCALE_FOREGROUND * (tile_max_depth - depth); + d -= 0.7; + vec2 depth_cmp = vec2(0); + depth_cmp.x = smoothstep(0.0, 1.0, saturate(d)); + // depth_cmp.x = step(0.01, d); + depth_cmp.y = 1.0 - depth_cmp.x; + return depth_cmp; +} + +float sample_alpha(float sampleCoc) +{ + return min(1.0 / (M_PI * sampleCoc * sampleCoc), M_PI * + DOF_SINGLE_PIXEL_RADIUS * DOF_SINGLE_PIXEL_RADIUS); +} diff --git a/rpplugins/dof/shader/dof_presort.frag.glsl b/rpplugins/dof/shader/dof_presort.frag.glsl new file mode 100644 index 0000000..40f7e7e --- /dev/null +++ b/rpplugins/dof/shader/dof_presort.frag.glsl @@ -0,0 +1,66 @@ +/** + * + * RenderPipeline + * + * Copyright (c) 2014-2016 tobspr + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + */ + +#version 430 + +#define USE_GBUFFER_EXTENSIONS +#pragma include "render_pipeline_base.inc.glsl" +#pragma include "includes/gbuffer.inc.glsl" +#pragma include "dof.inc.glsl" + +uniform sampler2D PrecomputedCoC; +uniform sampler2D TileMinMax; +out vec3 result; + + +/* + +WORK IN PROGRESS + +This code is code in progress and such not formatted very nicely nor commented! + +*/ + +void main() { + + vec2 texcoord = get_texcoord(); + ivec2 tile_coord = ivec2(ivec2(gl_FragCoord.xy) / vec2(tile_size)); + vec2 tile_data = texelFetch(TileMinMax, tile_coord, 0).xy; + float tile_min_depth = tile_data.x; + float tile_max_coc = tile_data.y; + + float pixel_depth = get_depth_at(texcoord); + float pixel_coc = textureLod(PrecomputedCoC, texcoord, 0).w; + + float alpha = sample_alpha(pixel_coc); // XXX: Returns just strange values + // float alpha = sample_alpha(tile_max_coc * 24.0); // XXX: Returns just strange values + alpha = 1.0; + vec2 depth_weights = compare_depth(pixel_depth, tile_min_depth); + // Depth weights.x = Foreground + // Depth weights.y = Background + result = vec3(pixel_coc, depth_weights.xy * alpha); + // result = vec3(pow(tile_min_depth, 100.0)); +} diff --git a/rpplugins/dof/shader/fetch_dof_minmax.frag.glsl b/rpplugins/dof/shader/fetch_dof_minmax.frag.glsl new file mode 100644 index 0000000..0343cb7 --- /dev/null +++ b/rpplugins/dof/shader/fetch_dof_minmax.frag.glsl @@ -0,0 +1,60 @@ +/** + * + * RenderPipeline + * + * Copyright (c) 2014-2016 tobspr + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + */ + +#version 430 + +#pragma optionNV (unroll all) + +#define USE_GBUFFER_EXTENSIONS +#pragma include "render_pipeline_base.inc.glsl" +#pragma include "includes/gbuffer.inc.glsl" +#pragma include "dof.inc.glsl" + + +uniform sampler2D PrecomputedCoC; + +out vec2 result; + +void main() { + ivec2 coord = ivec2(gl_FragCoord.xy); + ivec2 screen_coord = ivec2(coord.x, coord.y * tile_size); + + float max_depth = 0; + float max_coc = 0; + + for (int y = 0; y <= tile_size; y += 1) { + float coc = texelFetch(PrecomputedCoC, screen_coord + ivec2(0, y), 0).w; + float depth = texelFetch(GBuffer.Depth, screen_coord, 0).x; + + if (screen_coord.y + y >= WINDOW_HEIGHT) continue; + + max_depth = max(max_depth, depth); + max_coc = max(max_coc, coc); + + } + + result = vec2(max_depth, max_coc); +} diff --git a/rpplugins/dof/shader/fetch_dof_minmax_horiz.frag.glsl b/rpplugins/dof/shader/fetch_dof_minmax_horiz.frag.glsl new file mode 100644 index 0000000..34706fa --- /dev/null +++ b/rpplugins/dof/shader/fetch_dof_minmax_horiz.frag.glsl @@ -0,0 +1,57 @@ +/** + * + * RenderPipeline + * + * Copyright (c) 2014-2016 tobspr + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + */ + +#version 430 + +#pragma optionNV (unroll all) + +#define USE_GBUFFER_EXTENSIONS +#pragma include "render_pipeline_base.inc.glsl" +#pragma include "includes/gbuffer.inc.glsl" +#pragma include "dof.inc.glsl" + +uniform sampler2D SourceTex; + +out vec2 result; + +void main() { + ivec2 coord = ivec2(gl_FragCoord.xy); + ivec2 source_coord = ivec2(coord.x * tile_size, coord.y); + + float max_depth = 0; + float max_coc = 0; + + for (int x = 0; x <= tile_size; x += 1) { + int x_coord = clamp(source_coord.x + x, 0, WINDOW_WIDTH - 1); + vec2 data = texelFetch(SourceTex, ivec2(x_coord, source_coord.y), 0).xy; + + max_depth = max(max_depth, data.x); + max_coc = max(max_coc, data.y); + + } + + result = vec2(max_depth, max_coc); +} diff --git a/rpplugins/dof/shader/fetch_dof_tile_neighbors.frag.glsl b/rpplugins/dof/shader/fetch_dof_tile_neighbors.frag.glsl new file mode 100644 index 0000000..290d995 --- /dev/null +++ b/rpplugins/dof/shader/fetch_dof_tile_neighbors.frag.glsl @@ -0,0 +1,57 @@ +/** + * + * RenderPipeline + * + * Copyright (c) 2014-2016 tobspr + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + */ + +#version 430 + +#pragma include "render_pipeline_base.inc.glsl" +#pragma include "includes/gbuffer.inc.glsl" +#pragma include "dof.inc.glsl" + +uniform sampler2D TileMinMax; +out vec2 result; + +void main() { + + ivec2 tile = ivec2(gl_FragCoord.xy); + ivec2 screen_coord = tile * tile_size; + ivec2 max_tiles = textureSize(TileMinMax, 0) - 1; + + float max_depth = 0; + float max_coc = 0; + + const int filter_size = 1; + + for (int x = -filter_size; x <= filter_size; ++x) { + for (int y = -filter_size; y <= filter_size; ++y) { + ivec2 neighbor_coord = clamp(tile + ivec2(x, y), ivec2(0), ivec2(max_tiles)); + vec2 neighbor_data = texelFetch(TileMinMax, neighbor_coord, 0).xy; + max_depth = max(max_depth, neighbor_data.x); + max_coc = max(max_coc, neighbor_data.y); + } + } + + result = vec2(max_depth, max_coc); +} diff --git a/rpplugins/dof/shader/merge_dof.frag.glsl b/rpplugins/dof/shader/merge_dof.frag.glsl new file mode 100644 index 0000000..a8168a8 --- /dev/null +++ b/rpplugins/dof/shader/merge_dof.frag.glsl @@ -0,0 +1,56 @@ +/** + * + * RenderPipeline + * + * Copyright (c) 2014-2016 tobspr + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + */ + +#version 430 + +#pragma include "render_pipeline_base.inc.glsl" +#pragma include "includes/color_spaces.inc.glsl" + +uniform sampler2D ShadedScene; +uniform sampler2D SourceTex; +out vec3 result; + +void main() { + const float sharpness = 0.5; + + vec2 texcoord = get_texcoord(); + vec4 dof_result = textureLod(SourceTex, texcoord, 0); + vec3 scene_color = textureLod(ShadedScene, texcoord, 0).xyz; + + // Reconstruct original color + // dof_result.xyz = dof_result.xyz / (1 - (1 - sharpness) * get_luminance(dof_result.xyz)); + float dof_weight = saturate(dof_result.w * 10.0); + + #if DEBUG_MODE + dof_weight = 0; + #endif + + // result = mix(scene_color * 0, dof_result.xyz, dof_weight); + // result = mix(vec3(1, 0, 0), dof_result.xyz, dof_weight); + // result.xyz = vec3(dof_result.w); + result.xyz = dof_result.xyz; + // result.xyz = scene_color; +} diff --git a/rpplugins/dof/shader/prefilter_dof.frag.glsl b/rpplugins/dof/shader/prefilter_dof.frag.glsl new file mode 100644 index 0000000..27c0f27 --- /dev/null +++ b/rpplugins/dof/shader/prefilter_dof.frag.glsl @@ -0,0 +1,108 @@ +/** + * + * RenderPipeline + * + * Copyright (c) 2014-2016 tobspr + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + */ + +#version 430 + +#define USE_GBUFFER_EXTENSIONS +#pragma include "render_pipeline_base.inc.glsl" +#pragma include "includes/gbuffer.inc.glsl" +#pragma include "includes/transforms.inc.glsl" +#pragma include "includes/color_spaces.inc.glsl" + +uniform sampler2D ShadedScene; + +out vec4 result; + +/* + +WORK IN PROGRESS + +This code is code in progress and such not formatted very nicely nor commented! + +*/ + + +vec3 karis_average(vec3 color) { + const float sharpness = 0.0; + return color / (1 + (1 - sharpness) * get_luminance(color)); +} + +void main() { + vec2 texcoord = get_texcoord(); + float mid_depth = textureLod(GBuffer.Depth, texcoord, 0).x; + + vec3 mid_color = textureLod(ShadedScene, texcoord, 0).xyz; + + vec3 accum = karis_average(mid_color.xyz) * 0; + float weights = 1.0 * 0.0; + + const float scale = 0.1 * GET_SETTING(dof, blur_strength); // XXX: Todo, make it physically based + const float focus_plane = GET_SETTING(dof, focal_point); + const float focus_size = GET_SETTING(dof, focal_size); + const float near_scale = GET_SETTING(dof, near_blur_strength) / + max(0.0, focus_plane - focus_size - CAMERA_NEAR); + float dist = get_linear_z_from_z(mid_depth); + + float coc = (dist - focus_plane); + + if (coc >= 0) { + coc -= focus_size; + coc *= scale; + } else { + coc += focus_size; + coc *= -near_scale; + } + + coc = clamp(coc, 0.0001, 1.0); + + const int kernel_size = 2; + for (int x = -kernel_size; x <= kernel_size; ++x) { + for (int y = -kernel_size; y <= kernel_size; ++y) { + // skip center sample + // if (x == 0 && y == 0) continue; + vec2 offcoord = texcoord + vec2(x, y) / SCREEN_SIZE; + vec3 sample_data = textureLod(ShadedScene, offcoord, 0).xyz; + float sample_depth = textureLod(GBuffer.Depth, offcoord, 0).x; + sample_data = karis_average(sample_data); + + float weight = 1 - saturate(abs(mid_depth - sample_depth) / 0.005); + // float weight = 1; + accum += sample_data * weight; + weights += weight; + + } + } + accum /= max(0.001, weights); + + accum = mid_color; + + if (coc < 0.01) { + // accum = karis_average(mid_color); + } + // accum = karis_average(mid_color); + + result = vec4(accum, coc); +} diff --git a/rpplugins/env_probes/__init__.py b/rpplugins/env_probes/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/rpplugins/env_probes/apply_envprobes_stage.py b/rpplugins/env_probes/apply_envprobes_stage.py new file mode 100644 index 0000000..149c798 --- /dev/null +++ b/rpplugins/env_probes/apply_envprobes_stage.py @@ -0,0 +1,53 @@ +""" + +RenderPipeline + +Copyright (c) 2014-2016 tobspr + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. + +""" + +from rpcore.render_stage import RenderStage +from rpcore.stages.ambient_stage import AmbientStage + + +class ApplyEnvprobesStage(RenderStage): + + """ This stage takes the per-cell environment probes and samples them """ + + required_inputs = ["EnvProbes"] + required_pipes = ["GBuffer", "PerCellProbes", "CellIndices"] + + @property + def produced_pipes(self): + return { + "EnvmapAmbientSpec": self.target.color_tex, + "EnvmapAmbientDiff": self.target.aux_tex[0] + } + + def create(self): + self.target = self.create_target("ApplyEnvmap") + self.target.add_color_attachment(bits=16, alpha=True) + self.target.add_aux_attachment(bits=16) + self.target.prepare_buffer() + AmbientStage.required_pipes += ["EnvmapAmbientSpec", "EnvmapAmbientDiff"] + + def reload_shaders(self): + self.target.shader = self.load_plugin_shader("apply_envprobes.frag.glsl") diff --git a/rpplugins/env_probes/config.yaml b/rpplugins/env_probes/config.yaml new file mode 100644 index 0000000..6cc36ca --- /dev/null +++ b/rpplugins/env_probes/config.yaml @@ -0,0 +1,72 @@ + +settings: !!omap + + - probe_resolution: + type: power_of_two + range: [16, 512] + default: 128 + label: Specular cubemap resolution + description: > + Resolution of the specular cubemaps in pixels. This heavily impacts + the VRAM usage, so you shouldn't set it too high. + + - diffuse_probe_resolution: + type: power_of_two + range: [1, 32] + default: 2 + label: Diffuse cubemap resolution + description: > + Resolution of the diffuse cubemap in pixels, this can usually be quite low. + + - max_probes: + type: int + range: [1, 341] + default: 16 + label: Maximum probe count + description: > + Maximum amount of enviroment probes, try to set this as low + as possible, since it affects VRAM usage by a lot. The maximum + limit of this setting is caused by hardware. + + - max_probes_per_cell: + type: int + range: [1, 16] + default: 3 + label: Max overlapping probes + description: > + Controlls how many probes can overlay at a given location. + If you get artifacts at probe transitions, try increasing this. + +daytime_settings: !!omap + + - ambient_scale: + type: scalar + range: [0.0, 2.0] + default: 0.2 + label: Ambient scale + description: > + Controls the ambient scale for the enviroment probes, since no + full rendering is performed, this is an approximation + + - sky_ambient_scale: + type: scalar + range: [0.0, 2.0] + default: 0.1 + label: Sky Ambient scale + description: > + Controls the sky ambient scale for the enviroment probes, since no + full rendering is performed, this is an approximation + + - sun_ambient_scale: + type: scalar + range: [0.0, 2.0] + default: 0.1 + label: Sun Ambient scale + description: > + Controls the sun ambient scale for the enviroment probes, since no + full rendering is performed, this is an approximation + + + + + diff --git a/rpplugins/env_probes/cull_probes_stage.py b/rpplugins/env_probes/cull_probes_stage.py new file mode 100644 index 0000000..403d38a --- /dev/null +++ b/rpplugins/env_probes/cull_probes_stage.py @@ -0,0 +1,74 @@ +""" + +RenderPipeline + +Copyright (c) 2014-2016 tobspr + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. + +""" + +import math + +from rpcore.render_stage import RenderStage +from rpcore.image import Image + + +class CullProbesStage(RenderStage): + + """ This stage takes the list of used cells and creates a list of environment + probes for each cell """ + + required_inputs = ["EnvProbes"] + required_pipes = ["CellListBuffer"] + + def __init__(self, pipeline): + RenderStage.__init__(self, pipeline) + self.max_probes_per_cell = 4 + self.slice_width = pipeline.settings["lighting.culling_slice_width"] + + @property + def produced_pipes(self): + return {"PerCellProbes": self.per_cell_probes} + + @property + def produced_defines(self): + return {"MAX_PROBES_PER_CELL": self.max_probes_per_cell} + + def create(self): + # TODO: Use no oversized triangle in this stage + self.target = self.create_target("CullProbes") + self.target.size = 0, 0 + self.target.prepare_buffer() + + self.per_cell_probes = Image.create_buffer("PerCellProbes", 0, "R32I") + self.per_cell_probes.clear_image() + self.target.set_shader_inputs( + PerCellProbes=self.per_cell_probes, + threadCount=1) + + def set_dimensions(self): + max_cells = self._pipeline.light_mgr.total_tiles + num_rows = int(math.ceil(max_cells / float(self.slice_width))) + self.per_cell_probes.set_x_size(max_cells * self.max_probes_per_cell) + self.target.size = self.slice_width, num_rows + + def reload_shaders(self): + self.target.shader = self.load_plugin_shader( + "/$$rp/shader/tiled_culling.vert.glsl", "cull_probes.frag.glsl") diff --git a/rpplugins/env_probes/environment_capture_stage.py b/rpplugins/env_probes/environment_capture_stage.py new file mode 100644 index 0000000..b4f40f2 --- /dev/null +++ b/rpplugins/env_probes/environment_capture_stage.py @@ -0,0 +1,193 @@ +""" + +RenderPipeline + +Copyright (c) 2014-2016 tobspr + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. + +""" + +from __future__ import division +from rplibs.six.moves import range # pylint: disable=import-error +from rplibs.six import itervalues + +from panda3d.core import Camera, PerspectiveLens, Vec4, Vec3, PTAInt + +from rpcore.globals import Globals +from rpcore.image import Image +from rpcore.render_stage import RenderStage + + +class EnvironmentCaptureStage(RenderStage): + + """ This stage renders the scene to a cubemap """ + + required_inputs = ["DefaultEnvmap", "AllLightsData", "maxLightIndex", "IESDatasetTex"] + required_pipes = [] + + def __init__(self, pipeline): + RenderStage.__init__(self, pipeline) + self.resolution = 128 + self.diffuse_resolution = 4 + self.regions = [] + self.cameras = [] + self.rig_node = Globals.render.attach_new_node("EnvmapCamRig") + self.pta_index = PTAInt.empty_array(1) + self.storage_tex = None + self.storage_tex_diffuse = None + + def create(self): + self.target = self.create_target("CaptureScene") + self.target.size = self.resolution * 6, self.resolution + self.target.add_depth_attachment(bits=16) + self.target.add_color_attachment(bits=16, alpha=True) + self.target.prepare_render(None) + + # Remove all unused display regions + internal_buffer = self.target.internal_buffer + internal_buffer.remove_all_display_regions() + internal_buffer.disable_clears() + internal_buffer.get_overlay_display_region().disable_clears() + + self._setup_camera_rig() + self._create_store_targets() + self._create_filter_targets() + + def _setup_camera_rig(self): + """ Setups the cameras to render a cubemap """ + directions = (Vec3(1, 0, 0), Vec3(-1, 0, 0), Vec3(0, 1, 0), + Vec3(0, -1, 0), Vec3(0, 0, 1), Vec3(0, 0, -1)) + + # Prepare the display regions + for i in range(6): + region = self.target.internal_buffer.make_display_region( + i / 6, i / 6 + 1 / 6, 0, 1) + region.set_sort(25 + i) + region.set_active(True) + region.disable_clears() + + # Set the correct clears + region.set_clear_depth_active(True) + region.set_clear_depth(1.0) + region.set_clear_color_active(True) + region.set_clear_color(Vec4(0)) + + lens = PerspectiveLens() + lens.set_fov(90) + lens.set_near_far(0.001, 1.0) + camera = Camera("EnvmapCam-" + str(i), lens) + camera_np = self.rig_node.attach_new_node(camera) + camera_np.look_at(camera_np, directions[i]) + region.set_camera(camera_np) + self.regions.append(region) + self.cameras.append(camera_np) + + self.cameras[0].set_r(90) + self.cameras[1].set_r(-90) + self.cameras[3].set_r(180) + self.cameras[5].set_r(180) + + # Register cameras + for camera_np in self.cameras: + self._pipeline.tag_mgr.register_camera("envmap", camera_np.node()) + + def _create_store_targets(self): + """ Creates the targets which copy the result texture into the actual storage """ + self.target_store = self.create_target("StoreCubemap") + self.target_store.size = self.resolution * 6, self.resolution + self.target_store.prepare_buffer() + self.target_store.set_shader_inputs( + SourceTex=self.target.color_tex, + DestTex=self.storage_tex, + currentIndex=self.pta_index) + + self.temporary_diffuse_map = Image.create_cube("DiffuseTemp", self.resolution, "RGBA16") + self.target_store_diff = self.create_target("StoreCubemapDiffuse") + self.target_store_diff.size = self.resolution * 6, self.resolution + self.target_store_diff.prepare_buffer() + self.target_store_diff.set_shader_inputs( + SourceTex=self.target.color_tex, + DestTex=self.temporary_diffuse_map, + currentIndex=self.pta_index) + + def _create_filter_targets(self): + """ Generates the targets which filter the specular cubemap """ + self.filter_targets = [] + mip = 0 + size = self.resolution + while size > 1: + size = size // 2 + mip += 1 + target = self.create_target("FilterCubemap:{0}-{1}x{1}".format(mip, size)) + target.size = size * 6, size + target.prepare_buffer() + target.set_shader_inputs( + currentIndex=self.pta_index, + currentMip=mip, + SourceTex=self.storage_tex) + target.set_shader_input("DestTex", self.storage_tex, False, True, -1, mip, 0) + self.filter_targets.append(target) + + # Target to filter the diffuse cubemap + self.filter_diffuse_target = self.create_target("FilterCubemapDiffuse") + self.filter_diffuse_target.size = self.diffuse_resolution * 6, self.diffuse_resolution + self.filter_diffuse_target.prepare_buffer() + self.filter_diffuse_target.set_shader_inputs( + SourceTex=self.temporary_diffuse_map, + DestTex=self.storage_tex_diffuse, + currentIndex=self.pta_index) + + def set_probe(self, probe): + self.rig_node.set_mat(probe.matrix) + self.pta_index[0] = probe.index + + def update(self): + # First, disable all targets + for target in itervalues(self._targets): + target.active = False + + # Check for updated faces + for i in range(6): + if self._pipeline.task_scheduler.is_scheduled("envprobes_capture_envmap_face" + str(i)): + self.regions[i].set_active(True) + + # Check for filtering + if self._pipeline.task_scheduler.is_scheduled("envprobes_filter_and_store_envmap"): + self.target_store.active = True + self.target_store_diff.active = True + self.filter_diffuse_target.active = True + for target in self.filter_targets: + target.active = True + + def set_shader_input(self, *args): + Globals.render.set_shader_input(*args) + + def set_shader_inputs(self, **kwargs): + Globals.render.set_shader_inputs(**kwargs) + + def reload_shaders(self): + self.target_store.shader = self.load_plugin_shader( + "store_cubemap.frag.glsl") + self.target_store_diff.shader = self.load_plugin_shader( + "store_cubemap_diffuse.frag.glsl") + self.filter_diffuse_target.shader = self.load_plugin_shader( + "filter_cubemap_diffuse.frag.glsl") + for i, target in enumerate(self.filter_targets): + target.shader = self.load_plugin_shader("mips/{}.autogen.glsl".format(i)) diff --git a/rpplugins/env_probes/environment_probe.py b/rpplugins/env_probes/environment_probe.py new file mode 100644 index 0000000..4643f2e --- /dev/null +++ b/rpplugins/env_probes/environment_probe.py @@ -0,0 +1,133 @@ +""" + +RenderPipeline + +Copyright (c) 2014-2016 tobspr + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. + +""" + +import struct +from panda3d.core import TransformState, Vec3, Mat4, BoundingSphere + +from rpcore.rpobject import RPObject + + +class EnvironmentProbe(RPObject): + """ Simple class, representing an environment probe """ + + def __init__(self): + """ Inits a new environment probe """ + RPObject.__init__(self) + self.index = -1 + self.last_update = -1 + self._transform = TransformState.make_identity() + self._bounds = BoundingSphere(Vec3(0), 1.0) + self._modified = True + self._parallax_correction = True + self._border_smoothness = 0.1 + + @property + def modified(self): + """ Returns whether the probe was modified since the last write """ + return self._modified + + @property + def bounds(self): + """ Returns the probes worldspace bounds """ + return self._bounds + + @property + def parallax_correction(self): + """ Returns whether parallax correction is enabled for this probe """ + return self._parallax_correction + + @parallax_correction.setter + def parallax_correction(self, value): + """ Sets whether parallax correction is enabled for this probe """ + self._parallax_correction = value + self._modified = True + + @property + def border_smoothness(self): + """ Returns the border smoothness factor """ + return self._border_smoothness + + @border_smoothness.setter + def border_smoothness(self, value): + """ Sets the border smoothness factor """ + self._border_smoothness = value + self._modified = True + + def set_pos(self, *args): + """ Sets the probe position """ + self._transform = self._transform.set_pos(Vec3(*args)) + self.update_bounds() + + def set_hpr(self, *args): + """ Sets the probe rotation """ + self._transform = self._transform.set_hpr(Vec3(*args)) + self.update_bounds() + + def set_scale(self, *args): + """ Sets the probe scale """ + self._transform = self._transform.set_scale(Vec3(*args)) + self.update_bounds() + + def set_mat(self, matrix): + """ Sets the probes matrix, overrides all other transforms """ + self._transform = TransformState.make_mat(matrix) + self.update_bounds() + + def update_bounds(self): + """ Updates the spheres bounds """ + mat = self._transform.get_mat() + mid_point = mat.xform_point(Vec3(0, 0, 0)) + max_point = mat.xform_point(Vec3(1, 1, 1)) + radius = (mid_point - max_point).length() + self._bounds = BoundingSphere(mid_point, radius) + self._modified = True + + @property + def matrix(self): + """ Returns the matrix of the probe """ + return self._transform.get_mat() + + def write_to_buffer(self, buffer_ptr): + """ Writes the probe to a given byte buffer """ + data, mat = [], Mat4(self._transform.get_mat()) + mat.invert_in_place() + for i in range(4): + for j in range(3): + data.append(mat.get_cell(i, j)) + data += (float(self.index), + 1.0 if self._parallax_correction else 0.0, + self._border_smoothness, 0) + data.append(self._bounds.get_center().x) + data.append(self._bounds.get_center().y) + data.append(self._bounds.get_center().z) + data.append(self._bounds.get_radius()) + byte_data = struct.pack("f" * 20, *data) + + # 4 = sizeof float, 20 = floats per cubemap + bytes_per_probe = 4 * 20 + buffer_ptr.set_subdata(self.index * bytes_per_probe, bytes_per_probe, byte_data) + + self._modified = False diff --git a/rpplugins/env_probes/plugin.py b/rpplugins/env_probes/plugin.py new file mode 100644 index 0000000..7205158 --- /dev/null +++ b/rpplugins/env_probes/plugin.py @@ -0,0 +1,111 @@ +""" + +RenderPipeline + +Copyright (c) 2014-2016 tobspr + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. + +""" + +from panda3d.core import PTAInt + +from rpcore.globals import Globals +from rpcore.util.shader_input_blocks import SimpleInputBlock +from rpcore.pluginbase.base_plugin import BasePlugin +from rpcore.stages.cull_lights_stage import CullLightsStage + +from .probe_manager import ProbeManager +from .environment_capture_stage import EnvironmentCaptureStage +from .apply_envprobes_stage import ApplyEnvprobesStage +from .cull_probes_stage import CullProbesStage + + +class Plugin(BasePlugin): + + name = "Environment Probes" + author = "tobspr " + description = ("This plugin adds support for environment probes, containing " + "diffuse and specular information. This enables accurate " + "reflections, and can also be used to simulate GI.") + version = "beta (!)" + + def on_stage_setup(self): + self.probe_mgr = ProbeManager() + self.probe_mgr.resolution = self.get_setting("probe_resolution") + self.probe_mgr.diffuse_resolution = self.get_setting("diffuse_probe_resolution") + self.probe_mgr.max_probes = self.get_setting("max_probes") + self.probe_mgr.init() + self._setup_stages() + + def _setup_stages(self): + """ Setups all stages """ + # Create the stage to generate and update the cubemaps + self.capture_stage = self.create_stage(EnvironmentCaptureStage) + self.capture_stage.resolution = self.probe_mgr.resolution + self.capture_stage.diffuse_resolution = self.probe_mgr.diffuse_resolution + self.capture_stage.storage_tex = self.probe_mgr.cubemap_storage + self.capture_stage.storage_tex_diffuse = self.probe_mgr.diffuse_storage + + # Create the stage to cull the cubemaps + self.cull_stage = self.create_stage(CullProbesStage) + + # Create the stage to apply the cubemaps + self.apply_stage = self.create_stage(ApplyEnvprobesStage) + + if self.is_plugin_enabled("scattering"): + self.capture_stage.required_pipes += ["ScatteringIBLSpecular", "ScatteringIBLDiffuse"] + + if self.is_plugin_enabled("pssm"): + self.capture_stage.required_pipes += ["PSSMSceneSunShadowMapPCF"] + self.capture_stage.required_inputs += ["PSSMSceneSunShadowMVP"] + + self._setup_inputs() + + def _setup_inputs(self): + """ Sets all required inputs """ + self.pta_probes = PTAInt.empty_array(1) + + # Construct the UBO which stores all environment probe data + self.data_ubo = SimpleInputBlock("EnvProbes") + self.data_ubo.add_input("num_probes", self.pta_probes) + self.data_ubo.add_input("cubemaps", self.probe_mgr.cubemap_storage) + self.data_ubo.add_input("diffuse_cubemaps", self.probe_mgr.diffuse_storage) + self.data_ubo.add_input("dataset", self.probe_mgr.dataset_storage) + self._pipeline.stage_mgr.input_blocks.append(self.data_ubo) + + # Use the UBO in light culling + CullLightsStage.required_inputs.append("EnvProbes") + + def on_pre_render_update(self): + if self._pipeline.task_scheduler.is_scheduled("envprobes_select_and_cull"): + self.probe_mgr.update() + self.pta_probes[0] = self.probe_mgr.num_probes + probe = self.probe_mgr.find_probe_to_update() + if probe: + probe.last_update = Globals.clock.get_frame_count() + self.capture_stage.active = True + self.capture_stage.set_probe(probe) + + if self.is_plugin_enabled("pssm"): + self.get_plugin_instance("pssm").scene_shadow_stage.request_focus( + probe.bounds.get_center(), probe.bounds.get_radius() + ) + else: + self.capture_stage.active = False diff --git a/rpplugins/env_probes/probe_manager.py b/rpplugins/env_probes/probe_manager.py new file mode 100644 index 0000000..d48583b --- /dev/null +++ b/rpplugins/env_probes/probe_manager.py @@ -0,0 +1,103 @@ +""" + +RenderPipeline + +Copyright (c) 2014-2016 tobspr + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. + +""" + +from panda3d.core import Vec4, SamplerState, BoundingVolume + +from rpcore.globals import Globals +from rpcore.rpobject import RPObject +from rpcore.image import Image + + +class ProbeManager(RPObject): + """ Manages all environment probes """ + + def __init__(self): + """ Initializes a new probe manager """ + RPObject.__init__(self) + self.probes = [] + self.max_probes = 3 + self.resolution = 128 + self.diffuse_resolution = 4 + + def init(self): + """ Creates the cubemap storage """ + + # Storage for the specular components (with mipmaps) + self.cubemap_storage = Image.create_cube_array( + "EnvmapStorage", self.resolution, self.max_probes, "RGBA16") + self.cubemap_storage.set_minfilter(SamplerState.FT_linear_mipmap_linear) + self.cubemap_storage.set_magfilter(SamplerState.FT_linear) + self.cubemap_storage.set_clear_color(Vec4(1.0, 0.0, 0.1, 1.0)) + self.cubemap_storage.clear_image() + + # Storage for the diffuse component + self.diffuse_storage = Image.create_cube_array( + "EnvmapDiffStorage", self.diffuse_resolution, self.max_probes, "RGBA16") + self.diffuse_storage.set_clear_color(Vec4(1, 0, 0.2, 1.0)) + self.diffuse_storage.clear_image() + + # Data-storage to store all cubemap properties + self.dataset_storage = Image.create_buffer( + "EnvmapData", self.max_probes * 5, "RGBA32") + self.dataset_storage.set_clear_color(Vec4(0)) + self.dataset_storage.clear_image() + + def add_probe(self, probe): + """ Adds a new probe """ + if len(self.probes) >= self.max_probes: + self.error("Cannot attach probe, out of slots!") + return False + probe.last_update = -1 + probe.index = len(self.probes) + self.probes.append(probe) + return True + + def update(self): + """ Updates the manager, updating all probes """ + ptr = self.dataset_storage.modify_ram_image() + for probe in self.probes: + if probe.modified: + probe.write_to_buffer(ptr) + + @property + def num_probes(self): + return len(self.probes) + + def find_probe_to_update(self): + """ Finds the next probe which requires an update, or returns None """ + if not self.probes: + return None + + view_frustum = Globals.base.camLens.make_bounds() + view_frustum.xform(Globals.base.cam.get_transform(Globals.base.render).get_mat()) + + def rating(probe): + return probe.last_update + for candidate in sorted(self.probes, key=rating): + if view_frustum.contains(candidate.bounds) == BoundingVolume.IF_no_intersection: + continue + return candidate + return None diff --git a/rpplugins/env_probes/shader/apply_envprobes.frag.glsl b/rpplugins/env_probes/shader/apply_envprobes.frag.glsl new file mode 100644 index 0000000..43b0c2d --- /dev/null +++ b/rpplugins/env_probes/shader/apply_envprobes.frag.glsl @@ -0,0 +1,43 @@ +/** + * + * RenderPipeline + * + * Copyright (c) 2014-2016 tobspr + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + */ + +#version 430 + +#define USE_GBUFFER_EXTENSIONS +#pragma include "render_pipeline_base.inc.glsl" +#pragma include "includes/gbuffer.inc.glsl" + +#define APPLY_ENVPROBES_PASS 1 +#pragma include "includes/envprobes.inc.glsl" + +layout(location = 0) out vec4 result_spec; +layout(location = 1) out vec4 result_diff; + +void main() { + vec2 texcoord = get_texcoord(); + Material m = unpack_material(GBuffer, texcoord); + apply_all_probes(m, result_spec, result_diff); +} diff --git a/rpplugins/env_probes/shader/cull_probes.frag.glsl b/rpplugins/env_probes/shader/cull_probes.frag.glsl new file mode 100644 index 0000000..a9e9c26 --- /dev/null +++ b/rpplugins/env_probes/shader/cull_probes.frag.glsl @@ -0,0 +1,103 @@ +/** + * + * RenderPipeline + * + * Copyright (c) 2014-2016 tobspr + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + */ + +#version 430 + +#pragma include "render_pipeline_base.inc.glsl" +#pragma include "includes/envprobes.inc.glsl" +#pragma include "includes/transforms.inc.glsl" +#pragma include "includes/light_culling.inc.glsl" + +out vec4 result; + +uniform isamplerBuffer CellListBuffer; +uniform writeonly iimageBuffer RESTRICT PerCellProbes; + +void main() { + ivec2 coord = ivec2(gl_FragCoord.xy); + + // Find the index of the cell we are about to process + int idx = 1 + coord.x + coord.y * LC_CULLING_SLICE_WIDTH; + int num_total_cells = texelFetch(CellListBuffer, 0).x; + ivec2 precompute_size = MainSceneData.lc_tile_count; + + // If we found no remaining cell, we are done, so just return and hope for + // good coherency. + if (idx > num_total_cells) { + discard; + } + + // Fetch the cell data, this contains the cells position + int packed_cell_data = texelFetch(CellListBuffer, idx).x; + int cell_x, cell_y, cell_slice; + unpack_cell_data(packed_cell_data, cell_x, cell_y, cell_slice); + + float distance_bias = 0.01; + float bsphere_bias = 0.05; + // Find the tiles minimum and maximum distance + float min_distance = get_distance_from_slice(cell_slice) - distance_bias; + float max_distance = get_distance_from_slice(cell_slice + 1) + distance_bias; + + // Compute sample directions + vec3 local_ray_dirs[num_raydirs] = get_raydirs(cell_x, cell_y, precompute_size); + + int storage_offset = idx * MAX_PROBES_PER_CELL; + int probes_written = 0; + + // Iterate over all probes + for(int i = 0; i < EnvProbes.num_probes && probes_written < MAX_PROBES_PER_CELL; ++i) { + Cubemap map = get_cubemap(i); + vec4 pos_view = MainSceneData.view_mat_z_up * vec4(map.bounding_sphere_center, 1); + + bool visible = false; + + Sphere sphere; + sphere.pos = pos_view.xyz; + sphere.radius = map.bounding_sphere_radius + bsphere_bias; + + // Check for visibility + for (int k = 0; k < num_raydirs; ++k) { + visible = visible || viewspace_ray_sphere_distance_intersection( + sphere, local_ray_dirs[k], min_distance, max_distance); + } + + if (visible) { + imageStore(PerCellProbes, storage_offset + probes_written, ivec4(1 + i)); + ++probes_written; + } + } + + // Append zero byte + // if (probes_written < MAX_PROBES_PER_CELL) { + // imageStore(PerCellProbes, storage_offset + probes_written, ivec4(0)); + // } + + for (int i = probes_written; i < MAX_PROBES_PER_CELL; ++i) { + imageStore(PerCellProbes, storage_offset + i, ivec4(0)); + } + + result = vec4(cell_x % 2, 0.6, 1.0, 1.0); +} diff --git a/rpplugins/env_probes/shader/filter_cubemap.frag.glsl b/rpplugins/env_probes/shader/filter_cubemap.frag.glsl new file mode 100644 index 0000000..f12ee5d --- /dev/null +++ b/rpplugins/env_probes/shader/filter_cubemap.frag.glsl @@ -0,0 +1,75 @@ +/** + * + * RenderPipeline + * + * Copyright (c) 2014-2016 tobspr + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + */ + + +#pragma include "render_pipeline_base.inc.glsl" +#pragma include "includes/importance_sampling.inc.glsl" +#pragma include "includes/poisson_disk.inc.glsl" +#pragma include "includes/brdf.inc.glsl" +#pragma include "includes/noise.inc.glsl" + +// #pragma optionNV (unroll all) + +uniform samplerCubeArray SourceTex; +uniform writeonly imageCubeArray RESTRICT DestTex; +uniform int currentMip; +uniform int currentIndex; +out vec4 result; + +void main() { + const uint num_samples = SHADER_NUM_SAMPLES; + + // Get cubemap coordinate + int texsize = textureSize(SourceTex, currentMip).x; + ivec2 coord = ivec2(gl_FragCoord.xy); + ivec2 clamped_coord; int face; + vec3 n = texcoord_to_cubemap(texsize, coord, clamped_coord, face); + + // Determine target roughenss + float sample_roughness = 1e-10 + (currentMip + 1) / 12.0 - 0.04; + + // Get tangent and binormal + vec3 tangent, binormal; + find_arbitrary_tangent(n, tangent, binormal); + + vec4 accum = vec4(0.0); + for (uint i = 0; i < num_samples; ++i) { + vec2 Xi = hammersley(i, num_samples); + vec3 h = importance_sample_ggx(Xi, sample_roughness); + h = normalize(h.x * tangent + h.y * binormal + h.z * n); + accum += textureLod(SourceTex, vec4(h, currentIndex), currentMip - 1); + } + + accum /= num_samples; + + // It seems we are having some precision issues here. To make sure that + // no sky-cubemap leaks in, increase the weight by a small amount. + accum *= 1 + 1e-7; + accum.w = saturate(accum.w); + + imageStore(DestTex, ivec3(clamped_coord, currentIndex * 6 + face), accum); + result = accum; +} diff --git a/rpplugins/env_probes/shader/filter_cubemap_diffuse.frag.glsl b/rpplugins/env_probes/shader/filter_cubemap_diffuse.frag.glsl new file mode 100644 index 0000000..b966751 --- /dev/null +++ b/rpplugins/env_probes/shader/filter_cubemap_diffuse.frag.glsl @@ -0,0 +1,61 @@ +/** + * + * RenderPipeline + * + * Copyright (c) 2014-2016 tobspr + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + */ + +#version 430 + +#pragma include "render_pipeline_base.inc.glsl" +#pragma include "includes/importance_sampling.inc.glsl" + +// #pragma optionNV (unroll all) + +uniform samplerCube SourceTex; +uniform writeonly imageCubeArray RESTRICT DestTex; +uniform int currentIndex; +out vec4 result; + +void main() { + // Get cubemap coordinate + const int texsize = GET_SETTING(env_probes, diffuse_probe_resolution); + ivec2 coord = ivec2(gl_FragCoord.xy); + ivec2 clamped_coord; int face; + vec3 n = texcoord_to_cubemap(texsize, coord, clamped_coord, face); + + // Get tangent and binormal + vec3 tangent, binormal; + find_arbitrary_tangent(n, tangent, binormal); + + const int num_samples = 256; + vec4 accum = vec4(0.0); + for (uint i = 0; i < num_samples; ++i) { + vec2 Xi = hammersley(i, num_samples); + vec3 h = importance_sample_lambert(Xi); + h = normalize(h.x * tangent + h.y * binormal + h.z * n); + accum += textureLod(SourceTex, h, 0); + } + accum /= num_samples; + imageStore(DestTex, ivec3(clamped_coord, currentIndex * 6 + face), accum); + result = accum; +} diff --git a/rpplugins/env_probes/shader/generate_mip_shaders.py b/rpplugins/env_probes/shader/generate_mip_shaders.py new file mode 100644 index 0000000..5c7a6af --- /dev/null +++ b/rpplugins/env_probes/shader/generate_mip_shaders.py @@ -0,0 +1,17 @@ + +import os +from os.path import dirname, realpath, isdir +os.chdir(dirname(realpath(__file__))) + +if not isdir("mips"): + os.makedirs("mips") + +for i in range(12): + num_samples = 256 + i * 12 + if i == 0: + num_samples = 128 + with open('mips/{}.autogen.glsl'.format(i), 'w') as handle: + handle.write('// Autogenerated, do not edit\n') + handle.write('#version 430\n') + handle.write('#define SHADER_NUM_SAMPLES {}\n'.format(num_samples)) + handle.write('#pragma include "../filter_cubemap.frag.glsl"\n') diff --git a/rpplugins/env_probes/shader/store_cubemap.frag.glsl b/rpplugins/env_probes/shader/store_cubemap.frag.glsl new file mode 100644 index 0000000..761343f --- /dev/null +++ b/rpplugins/env_probes/shader/store_cubemap.frag.glsl @@ -0,0 +1,46 @@ +/** + * + * RenderPipeline + * + * Copyright (c) 2014-2016 tobspr + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + */ + +#version 430 + +#pragma include "render_pipeline_base.inc.glsl" + +uniform sampler2D SourceTex; +uniform writeonly imageCubeArray RESTRICT DestTex; +uniform int currentIndex; + +void main() { + ivec2 coord = ivec2(gl_FragCoord.xy); + int size = textureSize(SourceTex, 0).y; + vec4 source_data = texelFetch(SourceTex, coord, 0); + + // Convert to local cubemap coordinate + int offset = coord.x / size; + coord.x = coord.x % size; + + // Store color in cubemap array + imageStore(DestTex, ivec3(coord.x, coord.y, currentIndex * 6 + offset), source_data); +} diff --git a/rpplugins/env_probes/shader/store_cubemap_diffuse.frag.glsl b/rpplugins/env_probes/shader/store_cubemap_diffuse.frag.glsl new file mode 100644 index 0000000..006f0f9 --- /dev/null +++ b/rpplugins/env_probes/shader/store_cubemap_diffuse.frag.glsl @@ -0,0 +1,45 @@ +/** + * + * RenderPipeline + * + * Copyright (c) 2014-2016 tobspr + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + */ + +#version 430 + +#pragma include "render_pipeline_base.inc.glsl" + +uniform sampler2D SourceTex; +uniform writeonly imageCube RESTRICT DestTex; + +void main() { + ivec2 coord = ivec2(gl_FragCoord.xy); + int size = textureSize(SourceTex, 0).y; + vec4 source_data = texelFetch(SourceTex, coord, 0); + + // Convert to local cubemap coordinate + int offset = coord.x / size; + coord.x = coord.x % size; + + // Store color in diffuse cubemap array + imageStore(DestTex, ivec3(coord.x, coord.y, offset), source_data); +} diff --git a/rpplugins/forward_shading/__init__.py b/rpplugins/forward_shading/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/rpplugins/forward_shading/config.yaml b/rpplugins/forward_shading/config.yaml new file mode 100644 index 0000000..87e3f9e --- /dev/null +++ b/rpplugins/forward_shading/config.yaml @@ -0,0 +1,3 @@ + +settings: +daytime_settings: diff --git a/rpplugins/forward_shading/forward_stage.py b/rpplugins/forward_shading/forward_stage.py new file mode 100644 index 0000000..c79477e --- /dev/null +++ b/rpplugins/forward_shading/forward_stage.py @@ -0,0 +1,74 @@ +""" + +RenderPipeline + +Copyright (c) 2014-2016 tobspr + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. + +""" + +from panda3d.core import Camera + +from rpcore.globals import Globals +from rpcore.render_stage import RenderStage + + +class ForwardStage(RenderStage): + + """ Forward shading stage, which first renders all forward objects, + and then merges them with the scene """ + + required_inputs = ["DefaultEnvmap", "PrefilteredBRDF", "PrefilteredCoatBRDF"] + required_pipes = ["SceneDepth", "ShadedScene", "CellIndices"] + + @property + def produced_pipes(self): + return {"ShadedScene": self.target_merge.color_tex} + + def create(self): + self.forward_cam = Camera("ForwardShadingCam") + self.forward_cam.set_lens(Globals.base.camLens) + self.forward_cam_np = Globals.base.camera.attach_new_node(self.forward_cam) + + self.target = self.create_target("ForwardShading") + self.target.add_color_attachment(bits=16, alpha=True) + self.target.add_depth_attachment(bits=32) + self.target.prepare_render(self.forward_cam_np) + self.target.set_clear_color(0, 0, 0, 0) + + self._pipeline.tag_mgr.register_camera("forward", self.forward_cam) + + self.target_merge = self.create_target("MergeWithDeferred") + self.target_merge.add_color_attachment(bits=16) + self.target_merge.prepare_buffer() + self.target_merge.set_shader_inputs( + ForwardDepth=self.target.depth_tex, + ForwardColor=self.target.color_tex) + + def set_shader_input(self, *args): + Globals.base.render.set_shader_input(*args) + RenderStage.set_shader_input(self, *args) + + def set_shader_inputs(self, **kwargs): + Globals.base.render.set_shader_inputs(**kwargs) + RenderStage.set_shader_inputs(self, **kwargs) + + def reload_shaders(self): + self.target_merge.shader = self.load_plugin_shader("merge_with_deferred.frag.glsl") diff --git a/rpplugins/forward_shading/plugin.py b/rpplugins/forward_shading/plugin.py new file mode 100644 index 0000000..ef50452 --- /dev/null +++ b/rpplugins/forward_shading/plugin.py @@ -0,0 +1,55 @@ +""" + +RenderPipeline + +Copyright (c) 2014-2016 tobspr + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. + +""" + +from rpcore.pluginbase.base_plugin import BasePlugin + +from .forward_stage import ForwardStage + + +class Plugin(BasePlugin): + + name = "Forward Rendering" + author = "tobspr " + description = ("This plugin adds support for an additional forward rendering " + "pass. This is mainly useful for transparency.") + version = "0.1 alpha (!)" + + def on_stage_setup(self): + self.stage = self.create_stage(ForwardStage) + + if self.is_plugin_enabled("scattering"): + self.stage.required_pipes += ["ScatteringIBLSpecular", "ScatteringIBLDiffuse"] + + if self.is_plugin_enabled("pssm"): + self.stage.required_pipes += ["PSSMSceneSunShadowMapPCF"] + self.stage.required_inputs += ["PSSMSceneSunShadowMVP"] + + if self.is_plugin_enabled("env_probes"): + self.stage.required_pipes += ["PerCellProbes"] + self.stage.required_inputs += ["EnvProbes"] + + def on_pipeline_created(self): + pass diff --git a/rpplugins/forward_shading/shader/merge_with_deferred.frag.glsl b/rpplugins/forward_shading/shader/merge_with_deferred.frag.glsl new file mode 100644 index 0000000..e747536 --- /dev/null +++ b/rpplugins/forward_shading/shader/merge_with_deferred.frag.glsl @@ -0,0 +1,49 @@ +/** + * + * RenderPipeline + * + * Copyright (c) 2014-2016 tobspr + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + */ + +#version 430 + +#pragma include "render_pipeline_base.inc.glsl" + +uniform sampler2D ShadedScene; +uniform sampler2D SceneDepth; +uniform sampler2D ForwardDepth; +uniform sampler2D ForwardColor; + +out vec3 result; + +void main() { + vec2 texcoord = get_texcoord(); + + vec3 deferred_result = textureLod(ShadedScene, texcoord, 0).xyz; + vec4 forward_result = textureLod(ForwardColor, texcoord, 0); + + float deferred_depth = textureLod(ForwardDepth, texcoord, 0).x; + float forward_depth = textureLod(SceneDepth, texcoord, 0).x; + forward_result.xyz = forward_result.xyz * forward_result.w + + deferred_result * (1 - forward_result.w); + result = deferred_depth > forward_depth ? deferred_result : forward_result.xyz; +} diff --git a/rpplugins/fxaa/__init__.py b/rpplugins/fxaa/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/rpplugins/fxaa/config.yaml b/rpplugins/fxaa/config.yaml new file mode 100644 index 0000000..10f030b --- /dev/null +++ b/rpplugins/fxaa/config.yaml @@ -0,0 +1,41 @@ + +settings: !!omap + + - quality: + type: enum + values: ["low", "medium", "high", "ultra"] + default: "ultra" + label: FXAA Quality + shader_runtime: true + description: > + This controls the quality of the FXAA algorithm, higher presets + produce better antialiasing but also consume more performance. + + - subpixel_quality: + type: float + range: [0, 1] + default: 0.5 + label: Subpixel quality + description: This controls the subpixel quality. + shader_runtime: true + + - edge_threshold: + type: float + range: [0.063, 0.333] + default: 0.166 + label: Edge threshold + shader_runtime: true + description: > + This controls the edge detection. Lower values lead to a better + detection, but also require more performace. + + - min_threshold: + type: float + range: [0.312, 0.833] + default: 0.833 + shader_runtime: true + label: Minimum threshold + description: > + Minimum edge threshold, improves detection in dark scenes. + +daytime_settings: diff --git a/rpplugins/fxaa/fxaa_stage.py b/rpplugins/fxaa/fxaa_stage.py new file mode 100644 index 0000000..48aed42 --- /dev/null +++ b/rpplugins/fxaa/fxaa_stage.py @@ -0,0 +1,53 @@ +""" + +RenderPipeline + +Copyright (c) 2014-2016 tobspr + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. + +""" + +from rpcore.render_stage import RenderStage + + +class FXAAStage(RenderStage): + + """ This is the main stage used by the FXAA plugin """ + + required_pipes = ["ShadedScene", "GBuffer"] + required_inputs = [] + + @property + def produced_pipes(self): + return {"ShadedScene": self.target.color_tex} + + def create(self): + self.luma_target = self.create_target("FXAAWriteLuma") + self.luma_target.add_color_attachment(bits=16, alpha=True) + self.luma_target.prepare_buffer() + + self.target = self.create_target("FXAA") + self.target.add_color_attachment(bits=16) + self.target.prepare_buffer() + self.target.set_shader_input("SourceTex", self.luma_target.color_tex) + + def reload_shaders(self): + self.target.shader = self.load_plugin_shader("fxaa_stage.frag.glsl") + self.luma_target.shader = self.load_plugin_shader("write_luma.frag.glsl") diff --git a/rpplugins/fxaa/plugin.py b/rpplugins/fxaa/plugin.py new file mode 100644 index 0000000..f56abc3 --- /dev/null +++ b/rpplugins/fxaa/plugin.py @@ -0,0 +1,42 @@ +""" + +RenderPipeline + +Copyright (c) 2014-2016 tobspr + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. + +""" + +from rpcore.pluginbase.base_plugin import BasePlugin + +from .fxaa_stage import FXAAStage + + +class Plugin(BasePlugin): + + name = "FXAA (Antialiasing)" + author = "tobspr " + description = ("This plugin adds support for the FXAA Antialiasing technique. " + "However, Please use SMAA! This plugin is just here for completeness, " + "but FXAA is really inferior to SMAA.") + version = "1.0" + + def on_stage_setup(self): + self._stage = self.create_stage(FXAAStage) diff --git a/rpplugins/fxaa/shader/FXAA.inc.glsl b/rpplugins/fxaa/shader/FXAA.inc.glsl new file mode 100644 index 0000000..d48e829 --- /dev/null +++ b/rpplugins/fxaa/shader/FXAA.inc.glsl @@ -0,0 +1,1248 @@ +#pragma once + +/*============================================================================ + + + NVIDIA FXAA 3.11 by TIMOTHY LOTTES + + +------------------------------------------------------------------------------ +COPYRIGHT (C) 2010, 2011 NVIDIA CORPORATION. ALL RIGHTS RESERVED. +------------------------------------------------------------------------------ +TO THE MAXIMUM EXTENT PERMITTED BY APPLICABLE LAW, THIS SOFTWARE IS PROVIDED +*AS IS* AND NVIDIA AND ITS SUPPLIERS DISCLAIM ALL WARRANTIES, EITHER EXPRESS +OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, IMPLIED WARRANTIES OF +MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL NVIDIA +OR ITS SUPPLIERS BE LIABLE FOR ANY SPECIAL, INCIDENTAL, INDIRECT, OR +CONSEQUENTIAL DAMAGES WHATSOEVER (INCLUDING, WITHOUT LIMITATION, DAMAGES FOR +LOSS OF BUSINESS PROFITS, BUSINESS INTERRUPTION, LOSS OF BUSINESS INFORMATION, +OR ANY OTHER PECUNIARY LOSS) ARISING OUT OF THE USE OF OR INABILITY TO USE +THIS SOFTWARE, EVEN IF NVIDIA HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH +DAMAGES. + +------------------------------------------------------------------------------ + INTEGRATION CHECKLIST +------------------------------------------------------------------------------ +(1.) +In the shader source, setup defines for the desired configuration. +When providing multiple shaders (for different presets), +simply setup the defines differently in multiple files. +Example, + + #define FXAA_PC 1 + #define FXAA_HLSL_5 1 + #define FXAA_QUALITY__PRESET 12 + +Or, + + #define FXAA_360 1 + +Or, + + #define FXAA_PS3 1 + +Etc. + +(2.) +Then include this file, + + #include "Fxaa3_11.h" + +(3.) +Then call the FXAA pixel shader from within your desired shader. +Look at the FXAA Quality FxaaPixelShader() for docs on inputs. +As for FXAA 3.11 all inputs for all shaders are the same +to enable easy porting between platforms. + + return FxaaPixelShader(...); + +(4.) +Insure pass prior to FXAA outputs RGBL (see next section). +Or use, + + #define FXAA_GREEN_AS_LUMA 1 + +(5.) +Setup engine to provide the following constants +which are used in the FxaaPixelShader() inputs, + + FxaaFloat2 fxaaQualityRcpFrame, + FxaaFloat4 fxaaConsoleRcpFrameOpt, + FxaaFloat4 fxaaConsoleRcpFrameOpt2, + FxaaFloat4 fxaaConsole360RcpFrameOpt2, + FxaaFloat fxaaQualitySubpix, + FxaaFloat fxaaQualityEdgeThreshold, + FxaaFloat fxaaQualityEdgeThresholdMin, + FxaaFloat fxaaConsoleEdgeSharpness, + FxaaFloat fxaaConsoleEdgeThreshold, + FxaaFloat fxaaConsoleEdgeThresholdMin, + FxaaFloat4 fxaaConsole360ConstDir + +Look at the FXAA Quality FxaaPixelShader() for docs on inputs. + +(6.) +Have FXAA vertex shader run as a full screen triangle, +and output "pos" and "fxaaConsolePosPos" +such that inputs in the pixel shader provide, + + // {xy} = center of pixel + FxaaFloat2 pos, + + // {xy__} = upper left of pixel + // {__zw} = lower right of pixel + FxaaFloat4 fxaaConsolePosPos, + +(7.) +Insure the texture sampler(s) used by FXAA are set to bilinear filtering. + + +------------------------------------------------------------------------------ + INTEGRATION - RGBL AND COLORSPACE +------------------------------------------------------------------------------ +FXAA3 requires RGBL as input unless the following is set, + + #define FXAA_GREEN_AS_LUMA 1 + +In which case the engine uses green in place of luma, +and requires RGB input is in a non-linear colorspace. + +RGB should be LDR (low dynamic range). +Specifically do FXAA after tonemapping. + +RGB data as returned by a texture fetch can be non-linear, +or linear when FXAA_GREEN_AS_LUMA is not set. +Note an "sRGB format" texture counts as linear, +because the result of a texture fetch is linear data. +Regular "RGBA8" textures in the sRGB colorspace are non-linear. + +If FXAA_GREEN_AS_LUMA is not set, +luma must be stored in the alpha channel prior to running FXAA. +This luma should be in a perceptual space (could be gamma 2.0). +Example pass before FXAA where output is gamma 2.0 encoded, + + color.rgb = ToneMap(color.rgb); // linear color output + color.rgb = sqrt(color.rgb); // gamma 2.0 color output + return color; + +To use FXAA, + + color.rgb = ToneMap(color.rgb); // linear color output + color.rgb = sqrt(color.rgb); // gamma 2.0 color output + color.a = dot(color.rgb, FxaaFloat3(0.299, 0.587, 0.114)); // compute luma + return color; + +Another example where output is linear encoded, +say for instance writing to an sRGB formated render target, +where the render target does the conversion back to sRGB after blending, + + color.rgb = ToneMap(color.rgb); // linear color output + return color; + +To use FXAA, + + color.rgb = ToneMap(color.rgb); // linear color output + color.a = sqrt(dot(color.rgb, FxaaFloat3(0.299, 0.587, 0.114))); // compute luma + return color; + +Getting luma correct is required for the algorithm to work correctly. + + +------------------------------------------------------------------------------ + BEING LINEARLY CORRECT? +------------------------------------------------------------------------------ +Applying FXAA to a framebuffer with linear RGB color will look worse. +This is very counter intuitive, but happends to be true in this case. +The reason is because dithering artifacts will be more visiable +in a linear colorspace. + + +------------------------------------------------------------------------------ + COMPLEX INTEGRATION +------------------------------------------------------------------------------ +Q. What if the engine is blending into RGB before wanting to run FXAA? + +A. In the last opaque pass prior to FXAA, + have the pass write out luma into alpha. + Then blend into RGB only. + FXAA should be able to run ok + assuming the blending pass did not any add aliasing. + This should be the common case for particles and common blending passes. + +A. Or use FXAA_GREEN_AS_LUMA. + +============================================================================*/ + +/*============================================================================ + + INTEGRATION KNOBS + +============================================================================*/ +// +// FXAA_PS3 and FXAA_360 choose the console algorithm (FXAA3 CONSOLE). +// FXAA_360_OPT is a prototype for the new optimized 360 version. +// +// 1 = Use API. +// 0 = Don't use API. +// +/*--------------------------------------------------------------------------*/ +#ifndef FXAA_PS3 + #define FXAA_PS3 0 +#endif +/*--------------------------------------------------------------------------*/ +#ifndef FXAA_360 + #define FXAA_360 0 +#endif +/*--------------------------------------------------------------------------*/ +#ifndef FXAA_360_OPT + #define FXAA_360_OPT 0 +#endif +/*==========================================================================*/ +#ifndef FXAA_PC + // + // FXAA Quality + // The high quality PC algorithm. + // + #define FXAA_PC 0 +#endif +/*--------------------------------------------------------------------------*/ +#ifndef FXAA_PC_CONSOLE + // + // The console algorithm for PC is included + // for developers targeting really low spec machines. + // Likely better to just run FXAA_PC, and use a really low preset. + // + #define FXAA_PC_CONSOLE 0 +#endif +/*--------------------------------------------------------------------------*/ +#ifndef FXAA_GLSL_120 + #define FXAA_GLSL_120 0 +#endif +/*--------------------------------------------------------------------------*/ +#ifndef FXAA_GLSL_130 + #define FXAA_GLSL_130 0 +#endif +/*--------------------------------------------------------------------------*/ +#ifndef FXAA_HLSL_3 + #define FXAA_HLSL_3 0 +#endif +/*--------------------------------------------------------------------------*/ +#ifndef FXAA_HLSL_4 + #define FXAA_HLSL_4 0 +#endif +/*--------------------------------------------------------------------------*/ +#ifndef FXAA_HLSL_5 + #define FXAA_HLSL_5 0 +#endif +/*==========================================================================*/ +#ifndef FXAA_GREEN_AS_LUMA + // + // For those using non-linear color, + // and either not able to get luma in alpha, or not wanting to, + // this enables FXAA to run using green as a proxy for luma. + // So with this enabled, no need to pack luma in alpha. + // + // This will turn off AA on anything which lacks some amount of green. + // Pure red and blue or combination of only R and B, will get no AA. + // + // Might want to lower the settings for both, + // fxaaConsoleEdgeThresholdMin + // fxaaQualityEdgeThresholdMin + // In order to insure AA does not get turned off on colors + // which contain a minor amount of green. + // + // 1 = On. + // 0 = Off. + // + #define FXAA_GREEN_AS_LUMA 0 +#endif +/*--------------------------------------------------------------------------*/ +#ifndef FXAA_EARLY_EXIT + // + // Controls algorithm's early exit path. + // On PS3 turning this ON adds 2 cycles to the shader. + // On 360 turning this OFF adds 10ths of a millisecond to the shader. + // Turning this off on console will result in a more blurry image. + // So this defaults to on. + // + // 1 = On. + // 0 = Off. + // + #define FXAA_EARLY_EXIT 1 +#endif +/*--------------------------------------------------------------------------*/ +#ifndef FXAA_DISCARD + // + // Only valid for PC OpenGL currently. + // Probably will not work when FXAA_GREEN_AS_LUMA = 1. + // + // 1 = Use discard on pixels which don't need AA. + // For APIs which enable concurrent TEX+ROP from same surface. + // 0 = Return unchanged color on pixels which don't need AA. + // + #define FXAA_DISCARD 0 +#endif +/*--------------------------------------------------------------------------*/ +#ifndef FXAA_FAST_PIXEL_OFFSET + // + // Used for GLSL 120 only. + // + // 1 = GL API supports fast pixel offsets + // 0 = do not use fast pixel offsets + // + #ifdef GL_EXT_gpu_shader4 + #define FXAA_FAST_PIXEL_OFFSET 1 + #endif + #ifdef GL_NV_gpu_shader5 + #define FXAA_FAST_PIXEL_OFFSET 1 + #endif + #ifdef GL_ARB_gpu_shader5 + #define FXAA_FAST_PIXEL_OFFSET 1 + #endif + #ifndef FXAA_FAST_PIXEL_OFFSET + #define FXAA_FAST_PIXEL_OFFSET 0 + #endif +#endif +/*--------------------------------------------------------------------------*/ +#ifndef FXAA_GATHER4_ALPHA + // + // 1 = API supports gather4 on alpha channel. + // 0 = API does not support gather4 on alpha channel. + // + #if (FXAA_HLSL_5 == 1) + #define FXAA_GATHER4_ALPHA 1 + #endif + #ifdef GL_ARB_gpu_shader5 + #define FXAA_GATHER4_ALPHA 1 + #endif + #ifdef GL_NV_gpu_shader5 + #define FXAA_GATHER4_ALPHA 1 + #endif + #ifndef FXAA_GATHER4_ALPHA + #define FXAA_GATHER4_ALPHA 0 + #endif +#endif + +/*============================================================================ + FXAA CONSOLE PS3 - TUNING KNOBS +============================================================================*/ +#ifndef FXAA_CONSOLE__PS3_EDGE_SHARPNESS + // + // Consoles the sharpness of edges on PS3 only. + // Non-PS3 tuning is done with shader input. + // + // Due to the PS3 being ALU bound, + // there are only two safe values here: 4 and 8. + // These options use the shaders ability to a free *|/ by 2|4|8. + // + // 8.0 is sharper + // 4.0 is softer + // 2.0 is really soft (good for vector graphics inputs) + // + #if 1 + #define FXAA_CONSOLE__PS3_EDGE_SHARPNESS 8.0 + #endif + #if 0 + #define FXAA_CONSOLE__PS3_EDGE_SHARPNESS 4.0 + #endif + #if 0 + #define FXAA_CONSOLE__PS3_EDGE_SHARPNESS 2.0 + #endif +#endif +/*--------------------------------------------------------------------------*/ +#ifndef FXAA_CONSOLE__PS3_EDGE_THRESHOLD + // + // Only effects PS3. + // Non-PS3 tuning is done with shader input. + // + // The minimum amount of local contrast required to apply algorithm. + // The console setting has a different mapping than the quality setting. + // + // This only applies when FXAA_EARLY_EXIT is 1. + // + // Due to the PS3 being ALU bound, + // there are only two safe values here: 0.25 and 0.125. + // These options use the shaders ability to a free *|/ by 2|4|8. + // + // 0.125 leaves less aliasing, but is softer + // 0.25 leaves more aliasing, and is sharper + // + #if 1 + #define FXAA_CONSOLE__PS3_EDGE_THRESHOLD 0.125 + #else + #define FXAA_CONSOLE__PS3_EDGE_THRESHOLD 0.25 + #endif +#endif + +/*============================================================================ + FXAA QUALITY - TUNING KNOBS +------------------------------------------------------------------------------ +NOTE the other tuning knobs are now in the shader function inputs! +============================================================================*/ +#ifndef FXAA_QUALITY__PRESET + // + // Choose the quality preset. + // This needs to be compiled into the shader as it effects code. + // Best option to include multiple presets is to + // in each shader define the preset, then include this file. + // + // OPTIONS + // ----------------------------------------------------------------------- + // 10 to 15 - default medium dither (10=fastest, 15=highest quality) + // 20 to 29 - less dither, more expensive (20=fastest, 29=highest quality) + // 39 - no dither, very expensive + // + // NOTES + // ----------------------------------------------------------------------- + // 12 = slightly faster then FXAA 3.9 and higher edge quality (default) + // 13 = about same speed as FXAA 3.9 and better than 12 + // 23 = closest to FXAA 3.9 visually and performance wise + // _ = the lowest digit is directly related to performance + // _ = the highest digit is directly related to style + // + #define FXAA_QUALITY__PRESET 12 +#endif + + +/*============================================================================ + + FXAA QUALITY - PRESETS + +============================================================================*/ + +/*============================================================================ + FXAA QUALITY - MEDIUM DITHER PRESETS +============================================================================*/ +#if (FXAA_QUALITY__PRESET == 10) + #define FXAA_QUALITY__PS 3 + #define FXAA_QUALITY__P0 1.5 + #define FXAA_QUALITY__P1 3.0 + #define FXAA_QUALITY__P2 12.0 +#endif +/*--------------------------------------------------------------------------*/ +#if (FXAA_QUALITY__PRESET == 11) + #define FXAA_QUALITY__PS 4 + #define FXAA_QUALITY__P0 1.0 + #define FXAA_QUALITY__P1 1.5 + #define FXAA_QUALITY__P2 3.0 + #define FXAA_QUALITY__P3 12.0 +#endif +/*--------------------------------------------------------------------------*/ +#if (FXAA_QUALITY__PRESET == 12) + #define FXAA_QUALITY__PS 5 + #define FXAA_QUALITY__P0 1.0 + #define FXAA_QUALITY__P1 1.5 + #define FXAA_QUALITY__P2 2.0 + #define FXAA_QUALITY__P3 4.0 + #define FXAA_QUALITY__P4 12.0 +#endif +/*--------------------------------------------------------------------------*/ +#if (FXAA_QUALITY__PRESET == 13) + #define FXAA_QUALITY__PS 6 + #define FXAA_QUALITY__P0 1.0 + #define FXAA_QUALITY__P1 1.5 + #define FXAA_QUALITY__P2 2.0 + #define FXAA_QUALITY__P3 2.0 + #define FXAA_QUALITY__P4 4.0 + #define FXAA_QUALITY__P5 12.0 +#endif +/*--------------------------------------------------------------------------*/ +#if (FXAA_QUALITY__PRESET == 14) + #define FXAA_QUALITY__PS 7 + #define FXAA_QUALITY__P0 1.0 + #define FXAA_QUALITY__P1 1.5 + #define FXAA_QUALITY__P2 2.0 + #define FXAA_QUALITY__P3 2.0 + #define FXAA_QUALITY__P4 2.0 + #define FXAA_QUALITY__P5 4.0 + #define FXAA_QUALITY__P6 12.0 +#endif +/*--------------------------------------------------------------------------*/ +#if (FXAA_QUALITY__PRESET == 15) + #define FXAA_QUALITY__PS 8 + #define FXAA_QUALITY__P0 1.0 + #define FXAA_QUALITY__P1 1.5 + #define FXAA_QUALITY__P2 2.0 + #define FXAA_QUALITY__P3 2.0 + #define FXAA_QUALITY__P4 2.0 + #define FXAA_QUALITY__P5 2.0 + #define FXAA_QUALITY__P6 4.0 + #define FXAA_QUALITY__P7 12.0 +#endif + +/*============================================================================ + FXAA QUALITY - LOW DITHER PRESETS +============================================================================*/ +#if (FXAA_QUALITY__PRESET == 20) + #define FXAA_QUALITY__PS 3 + #define FXAA_QUALITY__P0 1.5 + #define FXAA_QUALITY__P1 2.0 + #define FXAA_QUALITY__P2 8.0 +#endif +/*--------------------------------------------------------------------------*/ +#if (FXAA_QUALITY__PRESET == 21) + #define FXAA_QUALITY__PS 4 + #define FXAA_QUALITY__P0 1.0 + #define FXAA_QUALITY__P1 1.5 + #define FXAA_QUALITY__P2 2.0 + #define FXAA_QUALITY__P3 8.0 +#endif +/*--------------------------------------------------------------------------*/ +#if (FXAA_QUALITY__PRESET == 22) + #define FXAA_QUALITY__PS 5 + #define FXAA_QUALITY__P0 1.0 + #define FXAA_QUALITY__P1 1.5 + #define FXAA_QUALITY__P2 2.0 + #define FXAA_QUALITY__P3 2.0 + #define FXAA_QUALITY__P4 8.0 +#endif +/*--------------------------------------------------------------------------*/ +#if (FXAA_QUALITY__PRESET == 23) + #define FXAA_QUALITY__PS 6 + #define FXAA_QUALITY__P0 1.0 + #define FXAA_QUALITY__P1 1.5 + #define FXAA_QUALITY__P2 2.0 + #define FXAA_QUALITY__P3 2.0 + #define FXAA_QUALITY__P4 2.0 + #define FXAA_QUALITY__P5 8.0 +#endif +/*--------------------------------------------------------------------------*/ +#if (FXAA_QUALITY__PRESET == 24) + #define FXAA_QUALITY__PS 7 + #define FXAA_QUALITY__P0 1.0 + #define FXAA_QUALITY__P1 1.5 + #define FXAA_QUALITY__P2 2.0 + #define FXAA_QUALITY__P3 2.0 + #define FXAA_QUALITY__P4 2.0 + #define FXAA_QUALITY__P5 3.0 + #define FXAA_QUALITY__P6 8.0 +#endif +/*--------------------------------------------------------------------------*/ +#if (FXAA_QUALITY__PRESET == 25) + #define FXAA_QUALITY__PS 8 + #define FXAA_QUALITY__P0 1.0 + #define FXAA_QUALITY__P1 1.5 + #define FXAA_QUALITY__P2 2.0 + #define FXAA_QUALITY__P3 2.0 + #define FXAA_QUALITY__P4 2.0 + #define FXAA_QUALITY__P5 2.0 + #define FXAA_QUALITY__P6 4.0 + #define FXAA_QUALITY__P7 8.0 +#endif +/*--------------------------------------------------------------------------*/ +#if (FXAA_QUALITY__PRESET == 26) + #define FXAA_QUALITY__PS 9 + #define FXAA_QUALITY__P0 1.0 + #define FXAA_QUALITY__P1 1.5 + #define FXAA_QUALITY__P2 2.0 + #define FXAA_QUALITY__P3 2.0 + #define FXAA_QUALITY__P4 2.0 + #define FXAA_QUALITY__P5 2.0 + #define FXAA_QUALITY__P6 2.0 + #define FXAA_QUALITY__P7 4.0 + #define FXAA_QUALITY__P8 8.0 +#endif +/*--------------------------------------------------------------------------*/ +#if (FXAA_QUALITY__PRESET == 27) + #define FXAA_QUALITY__PS 10 + #define FXAA_QUALITY__P0 1.0 + #define FXAA_QUALITY__P1 1.5 + #define FXAA_QUALITY__P2 2.0 + #define FXAA_QUALITY__P3 2.0 + #define FXAA_QUALITY__P4 2.0 + #define FXAA_QUALITY__P5 2.0 + #define FXAA_QUALITY__P6 2.0 + #define FXAA_QUALITY__P7 2.0 + #define FXAA_QUALITY__P8 4.0 + #define FXAA_QUALITY__P9 8.0 +#endif +/*--------------------------------------------------------------------------*/ +#if (FXAA_QUALITY__PRESET == 28) + #define FXAA_QUALITY__PS 11 + #define FXAA_QUALITY__P0 1.0 + #define FXAA_QUALITY__P1 1.5 + #define FXAA_QUALITY__P2 2.0 + #define FXAA_QUALITY__P3 2.0 + #define FXAA_QUALITY__P4 2.0 + #define FXAA_QUALITY__P5 2.0 + #define FXAA_QUALITY__P6 2.0 + #define FXAA_QUALITY__P7 2.0 + #define FXAA_QUALITY__P8 2.0 + #define FXAA_QUALITY__P9 4.0 + #define FXAA_QUALITY__P10 8.0 +#endif +/*--------------------------------------------------------------------------*/ +#if (FXAA_QUALITY__PRESET == 29) + #define FXAA_QUALITY__PS 12 + #define FXAA_QUALITY__P0 1.0 + #define FXAA_QUALITY__P1 1.5 + #define FXAA_QUALITY__P2 2.0 + #define FXAA_QUALITY__P3 2.0 + #define FXAA_QUALITY__P4 2.0 + #define FXAA_QUALITY__P5 2.0 + #define FXAA_QUALITY__P6 2.0 + #define FXAA_QUALITY__P7 2.0 + #define FXAA_QUALITY__P8 2.0 + #define FXAA_QUALITY__P9 2.0 + #define FXAA_QUALITY__P10 4.0 + #define FXAA_QUALITY__P11 8.0 +#endif + +/*============================================================================ + FXAA QUALITY - EXTREME QUALITY +============================================================================*/ +#if (FXAA_QUALITY__PRESET == 39) + #define FXAA_QUALITY__PS 12 + #define FXAA_QUALITY__P0 1.0 + #define FXAA_QUALITY__P1 1.0 + #define FXAA_QUALITY__P2 1.0 + #define FXAA_QUALITY__P3 1.0 + #define FXAA_QUALITY__P4 1.0 + #define FXAA_QUALITY__P5 1.5 + #define FXAA_QUALITY__P6 2.0 + #define FXAA_QUALITY__P7 2.0 + #define FXAA_QUALITY__P8 2.0 + #define FXAA_QUALITY__P9 2.0 + #define FXAA_QUALITY__P10 4.0 + #define FXAA_QUALITY__P11 8.0 +#endif + + + +/*============================================================================ + + API PORTING + +============================================================================*/ +#if (FXAA_GLSL_120 == 1) || (FXAA_GLSL_130 == 1) + #define FxaaBool bool + #define FxaaDiscard discard + #define FxaaFloat float + #define FxaaFloat2 vec2 + #define FxaaFloat3 vec3 + #define FxaaFloat4 vec4 + #define FxaaHalf float + #define FxaaHalf2 vec2 + #define FxaaHalf3 vec3 + #define FxaaHalf4 vec4 + #define FxaaInt2 ivec2 + #define FxaaSat(x) clamp(x, 0.0, 1.0) + #define FxaaTex sampler2D +#else + #define FxaaBool bool + #define FxaaDiscard clip(-1) + #define FxaaFloat float + #define FxaaFloat2 float2 + #define FxaaFloat3 float3 + #define FxaaFloat4 float4 + #define FxaaHalf half + #define FxaaHalf2 half2 + #define FxaaHalf3 half3 + #define FxaaHalf4 half4 + #define FxaaSat(x) saturate(x) +#endif +/*--------------------------------------------------------------------------*/ +#if (FXAA_GLSL_120 == 1) + // Requires, + // #version 120 + // And at least, + // #extension GL_EXT_gpu_shader4 : enable + // (or set FXAA_FAST_PIXEL_OFFSET 1 to work like DX9) + #define FxaaTexTop(t, p) texture2DLod(t, p, 0.0) + #if (FXAA_FAST_PIXEL_OFFSET == 1) + #define FxaaTexOff(t, p, o, r) texture2DLodOffset(t, p, 0.0, o) + #else + #define FxaaTexOff(t, p, o, r) texture2DLod(t, p + (o * r), 0.0) + #endif + #if (FXAA_GATHER4_ALPHA == 1) + // use #extension GL_ARB_gpu_shader5 : enable + #define FxaaTexAlpha4(t, p) textureGather(t, p, 3) + #define FxaaTexOffAlpha4(t, p, o) textureGatherOffset(t, p, o, 3) + #define FxaaTexGreen4(t, p) textureGather(t, p, 1) + #define FxaaTexOffGreen4(t, p, o) textureGatherOffset(t, p, o, 1) + #endif +#endif +/*--------------------------------------------------------------------------*/ +#if (FXAA_GLSL_130 == 1) + // Requires "#version 130" or better + #define FxaaTexTop(t, p) textureLod(t, p, 0.0) + #define FxaaTexOff(t, p, o, r) textureLodOffset(t, p, 0.0, o) + #if (FXAA_GATHER4_ALPHA == 1) + // use #extension GL_ARB_gpu_shader5 : enable + #define FxaaTexAlpha4(t, p) textureGather(t, p, 3) + #define FxaaTexOffAlpha4(t, p, o) textureGatherOffset(t, p, o, 3) + #define FxaaTexGreen4(t, p) textureGather(t, p, 1) + #define FxaaTexOffGreen4(t, p, o) textureGatherOffset(t, p, o, 1) + #endif +#endif +/*--------------------------------------------------------------------------*/ +#if (FXAA_HLSL_3 == 1) || (FXAA_360 == 1) || (FXAA_PS3 == 1) + #define FxaaInt2 float2 + #define FxaaTex sampler2D + #define FxaaTexTop(t, p) tex2Dlod(t, float4(p, 0.0, 0.0)) + #define FxaaTexOff(t, p, o, r) tex2Dlod(t, float4(p + (o * r), 0, 0)) +#endif +/*--------------------------------------------------------------------------*/ +#if (FXAA_HLSL_4 == 1) + #define FxaaInt2 int2 + struct FxaaTex { SamplerState smpl; Texture2D tex; }; + #define FxaaTexTop(t, p) t.tex.SampleLevel(t.smpl, p, 0.0) + #define FxaaTexOff(t, p, o, r) t.tex.SampleLevel(t.smpl, p, 0.0, o) +#endif +/*--------------------------------------------------------------------------*/ +#if (FXAA_HLSL_5 == 1) + #define FxaaInt2 int2 + struct FxaaTex { SamplerState smpl; Texture2D tex; }; + #define FxaaTexTop(t, p) t.tex.SampleLevel(t.smpl, p, 0.0) + #define FxaaTexOff(t, p, o, r) t.tex.SampleLevel(t.smpl, p, 0.0, o) + #define FxaaTexAlpha4(t, p) t.tex.GatherAlpha(t.smpl, p) + #define FxaaTexOffAlpha4(t, p, o) t.tex.GatherAlpha(t.smpl, p, o) + #define FxaaTexGreen4(t, p) t.tex.GatherGreen(t.smpl, p) + #define FxaaTexOffGreen4(t, p, o) t.tex.GatherGreen(t.smpl, p, o) +#endif + + +/*============================================================================ + GREEN AS LUMA OPTION SUPPORT FUNCTION +============================================================================*/ +#if (FXAA_GREEN_AS_LUMA == 0) + FxaaFloat FxaaLuma(FxaaFloat4 rgba) { return rgba.w; } +#else + FxaaFloat FxaaLuma(FxaaFloat4 rgba) { return rgba.y; } +#endif + + + + +/*============================================================================ + + FXAA3 QUALITY - PC + +============================================================================*/ +#if (FXAA_PC == 1) +/*--------------------------------------------------------------------------*/ +FxaaFloat4 FxaaPixelShader( + // + // Use noperspective interpolation here (turn off perspective interpolation). + // {xy} = center of pixel + FxaaFloat2 pos, + // + // Used only for FXAA Console, and not used on the 360 version. + // Use noperspective interpolation here (turn off perspective interpolation). + // {xy__} = upper left of pixel + // {__zw} = lower right of pixel + FxaaFloat4 fxaaConsolePosPos, + // + // Input color texture. + // {rgb_} = color in linear or perceptual color space + // if (FXAA_GREEN_AS_LUMA == 0) + // {___a} = luma in perceptual color space (not linear) + FxaaTex tex, + // + // Only used on the optimized 360 version of FXAA Console. + // For everything but 360, just use the same input here as for "tex". + // For 360, same texture, just alias with a 2nd sampler. + // This sampler needs to have an exponent bias of -1. + FxaaTex fxaaConsole360TexExpBiasNegOne, + // + // Only used on the optimized 360 version of FXAA Console. + // For everything but 360, just use the same input here as for "tex". + // For 360, same texture, just alias with a 3nd sampler. + // This sampler needs to have an exponent bias of -2. + FxaaTex fxaaConsole360TexExpBiasNegTwo, + // + // Only used on FXAA Quality. + // This must be from a constant/uniform. + // {x_} = 1.0/screenWidthInPixels + // {_y} = 1.0/screenHeightInPixels + FxaaFloat2 fxaaQualityRcpFrame, + // + // Only used on FXAA Console. + // This must be from a constant/uniform. + // This effects sub-pixel AA quality and inversely sharpness. + // Where N ranges between, + // N = 0.50 (default) + // N = 0.33 (sharper) + // {x___} = -N/screenWidthInPixels + // {_y__} = -N/screenHeightInPixels + // {__z_} = N/screenWidthInPixels + // {___w} = N/screenHeightInPixels + FxaaFloat4 fxaaConsoleRcpFrameOpt, + // + // Only used on FXAA Console. + // Not used on 360, but used on PS3 and PC. + // This must be from a constant/uniform. + // {x___} = -2.0/screenWidthInPixels + // {_y__} = -2.0/screenHeightInPixels + // {__z_} = 2.0/screenWidthInPixels + // {___w} = 2.0/screenHeightInPixels + FxaaFloat4 fxaaConsoleRcpFrameOpt2, + // + // Only used on FXAA Console. + // Only used on 360 in place of fxaaConsoleRcpFrameOpt2. + // This must be from a constant/uniform. + // {x___} = 8.0/screenWidthInPixels + // {_y__} = 8.0/screenHeightInPixels + // {__z_} = -4.0/screenWidthInPixels + // {___w} = -4.0/screenHeightInPixels + FxaaFloat4 fxaaConsole360RcpFrameOpt2, + // + // Only used on FXAA Quality. + // This used to be the FXAA_QUALITY__SUBPIX define. + // It is here now to allow easier tuning. + // Choose the amount of sub-pixel aliasing removal. + // This can effect sharpness. + // 1.00 - upper limit (softer) + // 0.75 - default amount of filtering + // 0.50 - lower limit (sharper, less sub-pixel aliasing removal) + // 0.25 - almost off + // 0.00 - completely off + FxaaFloat fxaaQualitySubpix, + // + // Only used on FXAA Quality. + // This used to be the FXAA_QUALITY__EDGE_THRESHOLD define. + // It is here now to allow easier tuning. + // The minimum amount of local contrast required to apply algorithm. + // 0.333 - too little (faster) + // 0.250 - low quality + // 0.166 - default + // 0.125 - high quality + // 0.063 - overkill (slower) + FxaaFloat fxaaQualityEdgeThreshold, + // + // Only used on FXAA Quality. + // This used to be the FXAA_QUALITY__EDGE_THRESHOLD_MIN define. + // It is here now to allow easier tuning. + // Trims the algorithm from processing darks. + // 0.0833 - upper limit (default, the start of visible unfiltered edges) + // 0.0625 - high quality (faster) + // 0.0312 - visible limit (slower) + // Special notes when using FXAA_GREEN_AS_LUMA, + // Likely want to set this to zero. + // As colors that are mostly not-green + // will appear very dark in the green channel! + // Tune by looking at mostly non-green content, + // then start at zero and increase until aliasing is a problem. + FxaaFloat fxaaQualityEdgeThresholdMin, + // + // Only used on FXAA Console. + // This used to be the FXAA_CONSOLE__EDGE_SHARPNESS define. + // It is here now to allow easier tuning. + // This does not effect PS3, as this needs to be compiled in. + // Use FXAA_CONSOLE__PS3_EDGE_SHARPNESS for PS3. + // Due to the PS3 being ALU bound, + // there are only three safe values here: 2 and 4 and 8. + // These options use the shaders ability to a free *|/ by 2|4|8. + // For all other platforms can be a non-power of two. + // 8.0 is sharper (default!!!) + // 4.0 is softer + // 2.0 is really soft (good only for vector graphics inputs) + FxaaFloat fxaaConsoleEdgeSharpness, + // + // Only used on FXAA Console. + // This used to be the FXAA_CONSOLE__EDGE_THRESHOLD define. + // It is here now to allow easier tuning. + // This does not effect PS3, as this needs to be compiled in. + // Use FXAA_CONSOLE__PS3_EDGE_THRESHOLD for PS3. + // Due to the PS3 being ALU bound, + // there are only two safe values here: 1/4 and 1/8. + // These options use the shaders ability to a free *|/ by 2|4|8. + // The console setting has a different mapping than the quality setting. + // Other platforms can use other values. + // 0.125 leaves less aliasing, but is softer (default!!!) + // 0.25 leaves more aliasing, and is sharper + FxaaFloat fxaaConsoleEdgeThreshold, + // + // Only used on FXAA Console. + // This used to be the FXAA_CONSOLE__EDGE_THRESHOLD_MIN define. + // It is here now to allow easier tuning. + // Trims the algorithm from processing darks. + // The console setting has a different mapping than the quality setting. + // This only applies when FXAA_EARLY_EXIT is 1. + // This does not apply to PS3, + // PS3 was simplified to avoid more shader instructions. + // 0.06 - faster but more aliasing in darks + // 0.05 - default + // 0.04 - slower and less aliasing in darks + // Special notes when using FXAA_GREEN_AS_LUMA, + // Likely want to set this to zero. + // As colors that are mostly not-green + // will appear very dark in the green channel! + // Tune by looking at mostly non-green content, + // then start at zero and increase until aliasing is a problem. + FxaaFloat fxaaConsoleEdgeThresholdMin, + // + // Extra constants for 360 FXAA Console only. + // Use zeros or anything else for other platforms. + // These must be in physical constant registers and NOT immedates. + // Immedates will result in compiler un-optimizing. + // {xyzw} = float4(1.0, -1.0, 0.25, -0.25) + FxaaFloat4 fxaaConsole360ConstDir +) { +/*--------------------------------------------------------------------------*/ + FxaaFloat2 posM; + posM.x = pos.x; + posM.y = pos.y; + #if (FXAA_GATHER4_ALPHA == 1) + #if (FXAA_DISCARD == 0) + FxaaFloat4 rgbyM = FxaaTexTop(tex, posM); + #if (FXAA_GREEN_AS_LUMA == 0) + #define lumaM rgbyM.w + #else + #define lumaM rgbyM.y + #endif + #endif + #if (FXAA_GREEN_AS_LUMA == 0) + FxaaFloat4 luma4A = FxaaTexAlpha4(tex, posM); + FxaaFloat4 luma4B = FxaaTexOffAlpha4(tex, posM, FxaaInt2(-1, -1)); + #else + FxaaFloat4 luma4A = FxaaTexGreen4(tex, posM); + FxaaFloat4 luma4B = FxaaTexOffGreen4(tex, posM, FxaaInt2(-1, -1)); + #endif + #if (FXAA_DISCARD == 1) + #define lumaM luma4A.w + #endif + #define lumaE luma4A.z + #define lumaS luma4A.x + #define lumaSE luma4A.y + #define lumaNW luma4B.w + #define lumaN luma4B.z + #define lumaW luma4B.x + #else + FxaaFloat4 rgbyM = FxaaTexTop(tex, posM); + #if (FXAA_GREEN_AS_LUMA == 0) + #define lumaM rgbyM.w + #else + #define lumaM rgbyM.y + #endif + FxaaFloat lumaS = FxaaLuma(FxaaTexOff(tex, posM, FxaaInt2(0, 1), fxaaQualityRcpFrame.xy)); + FxaaFloat lumaE = FxaaLuma(FxaaTexOff(tex, posM, FxaaInt2(1, 0), fxaaQualityRcpFrame.xy)); + FxaaFloat lumaN = FxaaLuma(FxaaTexOff(tex, posM, FxaaInt2(0, -1), fxaaQualityRcpFrame.xy)); + FxaaFloat lumaW = FxaaLuma(FxaaTexOff(tex, posM, FxaaInt2(-1, 0), fxaaQualityRcpFrame.xy)); + #endif +/*--------------------------------------------------------------------------*/ + FxaaFloat maxSM = max(lumaS, lumaM); + FxaaFloat minSM = min(lumaS, lumaM); + FxaaFloat maxESM = max(lumaE, maxSM); + FxaaFloat minESM = min(lumaE, minSM); + FxaaFloat maxWN = max(lumaN, lumaW); + FxaaFloat minWN = min(lumaN, lumaW); + FxaaFloat rangeMax = max(maxWN, maxESM); + FxaaFloat rangeMin = min(minWN, minESM); + FxaaFloat rangeMaxScaled = rangeMax * fxaaQualityEdgeThreshold; + FxaaFloat range = rangeMax - rangeMin; + FxaaFloat rangeMaxClamped = max(fxaaQualityEdgeThresholdMin, rangeMaxScaled); + FxaaBool earlyExit = range < rangeMaxClamped; +/*--------------------------------------------------------------------------*/ + if(earlyExit) + #if (FXAA_DISCARD == 1) + FxaaDiscard; + #else + return rgbyM; + #endif +/*--------------------------------------------------------------------------*/ + #if (FXAA_GATHER4_ALPHA == 0) + FxaaFloat lumaNW = FxaaLuma( + FxaaTexOff(tex, posM, FxaaInt2(-1, -1), fxaaQualityRcpFrame.xy)); + FxaaFloat lumaSE = FxaaLuma( + FxaaTexOff(tex, posM, FxaaInt2(1, 1), fxaaQualityRcpFrame.xy)); + FxaaFloat lumaNE = FxaaLuma( + FxaaTexOff(tex, posM, FxaaInt2(1, -1), fxaaQualityRcpFrame.xy)); + FxaaFloat lumaSW = FxaaLuma( + FxaaTexOff(tex, posM, FxaaInt2(-1, 1), fxaaQualityRcpFrame.xy)); + #else + FxaaFloat lumaNE = FxaaLuma( + FxaaTexOff(tex, posM, FxaaInt2(1, -1), fxaaQualityRcpFrame.xy)); + FxaaFloat lumaSW = FxaaLuma( + FxaaTexOff(tex, posM, FxaaInt2(-1, 1), fxaaQualityRcpFrame.xy)); + #endif +/*--------------------------------------------------------------------------*/ + FxaaFloat lumaNS = lumaN + lumaS; + FxaaFloat lumaWE = lumaW + lumaE; + FxaaFloat subpixRcpRange = 1.0 / range; + FxaaFloat subpixNSWE = lumaNS + lumaWE; + FxaaFloat edgeHorz1 = (-2.0 * lumaM) + lumaNS; + FxaaFloat edgeVert1 = (-2.0 * lumaM) + lumaWE; +/*--------------------------------------------------------------------------*/ + FxaaFloat lumaNESE = lumaNE + lumaSE; + FxaaFloat lumaNWNE = lumaNW + lumaNE; + FxaaFloat edgeHorz2 = (-2.0 * lumaE) + lumaNESE; + FxaaFloat edgeVert2 = (-2.0 * lumaN) + lumaNWNE; +/*--------------------------------------------------------------------------*/ + FxaaFloat lumaNWSW = lumaNW + lumaSW; + FxaaFloat lumaSWSE = lumaSW + lumaSE; + FxaaFloat edgeHorz4 = (abs(edgeHorz1) * 2.0) + abs(edgeHorz2); + FxaaFloat edgeVert4 = (abs(edgeVert1) * 2.0) + abs(edgeVert2); + FxaaFloat edgeHorz3 = (-2.0 * lumaW) + lumaNWSW; + FxaaFloat edgeVert3 = (-2.0 * lumaS) + lumaSWSE; + FxaaFloat edgeHorz = abs(edgeHorz3) + edgeHorz4; + FxaaFloat edgeVert = abs(edgeVert3) + edgeVert4; +/*--------------------------------------------------------------------------*/ + FxaaFloat subpixNWSWNESE = lumaNWSW + lumaNESE; + FxaaFloat lengthSign = fxaaQualityRcpFrame.x; + FxaaBool horzSpan = edgeHorz >= edgeVert; + FxaaFloat subpixA = subpixNSWE * 2.0 + subpixNWSWNESE; +/*--------------------------------------------------------------------------*/ + if (!horzSpan) lumaN = lumaW; + if (!horzSpan) lumaS = lumaE; + if (horzSpan) lengthSign = fxaaQualityRcpFrame.y; + FxaaFloat subpixB = (subpixA * (1.0 / 12.0)) - lumaM; +/*--------------------------------------------------------------------------*/ + FxaaFloat gradientN = lumaN - lumaM; + FxaaFloat gradientS = lumaS - lumaM; + FxaaFloat lumaNN = lumaN + lumaM; + FxaaFloat lumaSS = lumaS + lumaM; + FxaaBool pairN = abs(gradientN) >= abs(gradientS); + FxaaFloat gradient = max(abs(gradientN), abs(gradientS)); + if (pairN) lengthSign = -lengthSign; + FxaaFloat subpixC = FxaaSat(abs(subpixB) * subpixRcpRange); +/*--------------------------------------------------------------------------*/ + FxaaFloat2 posB; + posB.x = posM.x; + posB.y = posM.y; + FxaaFloat2 offNP; + offNP.x = (!horzSpan) ? 0.0 : fxaaQualityRcpFrame.x; + offNP.y = (horzSpan) ? 0.0 : fxaaQualityRcpFrame.y; + if (!horzSpan) posB.x += lengthSign * 0.5; + if (horzSpan) posB.y += lengthSign * 0.5; +/*--------------------------------------------------------------------------*/ + FxaaFloat2 posN; + posN.x = posB.x - offNP.x * FXAA_QUALITY__P0; + posN.y = posB.y - offNP.y * FXAA_QUALITY__P0; + FxaaFloat2 posP; + posP.x = posB.x + offNP.x * FXAA_QUALITY__P0; + posP.y = posB.y + offNP.y * FXAA_QUALITY__P0; + FxaaFloat subpixD = (-2.0 * subpixC) + 3.0; + FxaaFloat lumaEndN = FxaaLuma(FxaaTexTop(tex, posN)); + FxaaFloat subpixE = subpixC * subpixC; + FxaaFloat lumaEndP = FxaaLuma(FxaaTexTop(tex, posP)); +/*--------------------------------------------------------------------------*/ + if(!pairN) lumaNN = lumaSS; + FxaaFloat gradientScaled = gradient * 1.0 / 4.0; + FxaaFloat lumaMM = lumaM - lumaNN * 0.5; + FxaaFloat subpixF = subpixD * subpixE; + FxaaBool lumaMLTZero = lumaMM < 0.0; +/*--------------------------------------------------------------------------*/ + lumaEndN -= lumaNN * 0.5; + lumaEndP -= lumaNN * 0.5; + FxaaBool doneN = abs(lumaEndN) >= gradientScaled; + FxaaBool doneP = abs(lumaEndP) >= gradientScaled; + if(!doneN) posN.x -= offNP.x * FXAA_QUALITY__P1; + if(!doneN) posN.y -= offNP.y * FXAA_QUALITY__P1; + FxaaBool doneNP = (!doneN) || (!doneP); + if(!doneP) posP.x += offNP.x * FXAA_QUALITY__P1; + if(!doneP) posP.y += offNP.y * FXAA_QUALITY__P1; +/*--------------------------------------------------------------------------*/ + if(doneNP) { + if(!doneN) lumaEndN = FxaaLuma(FxaaTexTop(tex, posN.xy)); + if(!doneP) lumaEndP = FxaaLuma(FxaaTexTop(tex, posP.xy)); + if(!doneN) lumaEndN = lumaEndN - lumaNN * 0.5; + if(!doneP) lumaEndP = lumaEndP - lumaNN * 0.5; + doneN = abs(lumaEndN) >= gradientScaled; + doneP = abs(lumaEndP) >= gradientScaled; + if(!doneN) posN.x -= offNP.x * FXAA_QUALITY__P2; + if(!doneN) posN.y -= offNP.y * FXAA_QUALITY__P2; + doneNP = (!doneN) || (!doneP); + if(!doneP) posP.x += offNP.x * FXAA_QUALITY__P2; + if(!doneP) posP.y += offNP.y * FXAA_QUALITY__P2; +/*--------------------------------------------------------------------------*/ + #if (FXAA_QUALITY__PS > 3) + if(doneNP) { + if(!doneN) lumaEndN = FxaaLuma(FxaaTexTop(tex, posN.xy)); + if(!doneP) lumaEndP = FxaaLuma(FxaaTexTop(tex, posP.xy)); + if(!doneN) lumaEndN = lumaEndN - lumaNN * 0.5; + if(!doneP) lumaEndP = lumaEndP - lumaNN * 0.5; + doneN = abs(lumaEndN) >= gradientScaled; + doneP = abs(lumaEndP) >= gradientScaled; + if(!doneN) posN.x -= offNP.x * FXAA_QUALITY__P3; + if(!doneN) posN.y -= offNP.y * FXAA_QUALITY__P3; + doneNP = (!doneN) || (!doneP); + if(!doneP) posP.x += offNP.x * FXAA_QUALITY__P3; + if(!doneP) posP.y += offNP.y * FXAA_QUALITY__P3; +/*--------------------------------------------------------------------------*/ + #if (FXAA_QUALITY__PS > 4) + if(doneNP) { + if(!doneN) lumaEndN = FxaaLuma(FxaaTexTop(tex, posN.xy)); + if(!doneP) lumaEndP = FxaaLuma(FxaaTexTop(tex, posP.xy)); + if(!doneN) lumaEndN = lumaEndN - lumaNN * 0.5; + if(!doneP) lumaEndP = lumaEndP - lumaNN * 0.5; + doneN = abs(lumaEndN) >= gradientScaled; + doneP = abs(lumaEndP) >= gradientScaled; + if(!doneN) posN.x -= offNP.x * FXAA_QUALITY__P4; + if(!doneN) posN.y -= offNP.y * FXAA_QUALITY__P4; + doneNP = (!doneN) || (!doneP); + if(!doneP) posP.x += offNP.x * FXAA_QUALITY__P4; + if(!doneP) posP.y += offNP.y * FXAA_QUALITY__P4; +/*--------------------------------------------------------------------------*/ + #if (FXAA_QUALITY__PS > 5) + if(doneNP) { + if(!doneN) lumaEndN = FxaaLuma(FxaaTexTop(tex, posN.xy)); + if(!doneP) lumaEndP = FxaaLuma(FxaaTexTop(tex, posP.xy)); + if(!doneN) lumaEndN = lumaEndN - lumaNN * 0.5; + if(!doneP) lumaEndP = lumaEndP - lumaNN * 0.5; + doneN = abs(lumaEndN) >= gradientScaled; + doneP = abs(lumaEndP) >= gradientScaled; + if(!doneN) posN.x -= offNP.x * FXAA_QUALITY__P5; + if(!doneN) posN.y -= offNP.y * FXAA_QUALITY__P5; + doneNP = (!doneN) || (!doneP); + if(!doneP) posP.x += offNP.x * FXAA_QUALITY__P5; + if(!doneP) posP.y += offNP.y * FXAA_QUALITY__P5; +/*--------------------------------------------------------------------------*/ + #if (FXAA_QUALITY__PS > 6) + if(doneNP) { + if(!doneN) lumaEndN = FxaaLuma(FxaaTexTop(tex, posN.xy)); + if(!doneP) lumaEndP = FxaaLuma(FxaaTexTop(tex, posP.xy)); + if(!doneN) lumaEndN = lumaEndN - lumaNN * 0.5; + if(!doneP) lumaEndP = lumaEndP - lumaNN * 0.5; + doneN = abs(lumaEndN) >= gradientScaled; + doneP = abs(lumaEndP) >= gradientScaled; + if(!doneN) posN.x -= offNP.x * FXAA_QUALITY__P6; + if(!doneN) posN.y -= offNP.y * FXAA_QUALITY__P6; + doneNP = (!doneN) || (!doneP); + if(!doneP) posP.x += offNP.x * FXAA_QUALITY__P6; + if(!doneP) posP.y += offNP.y * FXAA_QUALITY__P6; +/*--------------------------------------------------------------------------*/ + #if (FXAA_QUALITY__PS > 7) + if(doneNP) { + if(!doneN) lumaEndN = FxaaLuma(FxaaTexTop(tex, posN.xy)); + if(!doneP) lumaEndP = FxaaLuma(FxaaTexTop(tex, posP.xy)); + if(!doneN) lumaEndN = lumaEndN - lumaNN * 0.5; + if(!doneP) lumaEndP = lumaEndP - lumaNN * 0.5; + doneN = abs(lumaEndN) >= gradientScaled; + doneP = abs(lumaEndP) >= gradientScaled; + if(!doneN) posN.x -= offNP.x * FXAA_QUALITY__P7; + if(!doneN) posN.y -= offNP.y * FXAA_QUALITY__P7; + doneNP = (!doneN) || (!doneP); + if(!doneP) posP.x += offNP.x * FXAA_QUALITY__P7; + if(!doneP) posP.y += offNP.y * FXAA_QUALITY__P7; +/*--------------------------------------------------------------------------*/ + #if (FXAA_QUALITY__PS > 8) + if(doneNP) { + if(!doneN) lumaEndN = FxaaLuma(FxaaTexTop(tex, posN.xy)); + if(!doneP) lumaEndP = FxaaLuma(FxaaTexTop(tex, posP.xy)); + if(!doneN) lumaEndN = lumaEndN - lumaNN * 0.5; + if(!doneP) lumaEndP = lumaEndP - lumaNN * 0.5; + doneN = abs(lumaEndN) >= gradientScaled; + doneP = abs(lumaEndP) >= gradientScaled; + if(!doneN) posN.x -= offNP.x * FXAA_QUALITY__P8; + if(!doneN) posN.y -= offNP.y * FXAA_QUALITY__P8; + doneNP = (!doneN) || (!doneP); + if(!doneP) posP.x += offNP.x * FXAA_QUALITY__P8; + if(!doneP) posP.y += offNP.y * FXAA_QUALITY__P8; +/*--------------------------------------------------------------------------*/ + #if (FXAA_QUALITY__PS > 9) + if(doneNP) { + if(!doneN) lumaEndN = FxaaLuma(FxaaTexTop(tex, posN.xy)); + if(!doneP) lumaEndP = FxaaLuma(FxaaTexTop(tex, posP.xy)); + if(!doneN) lumaEndN = lumaEndN - lumaNN * 0.5; + if(!doneP) lumaEndP = lumaEndP - lumaNN * 0.5; + doneN = abs(lumaEndN) >= gradientScaled; + doneP = abs(lumaEndP) >= gradientScaled; + if(!doneN) posN.x -= offNP.x * FXAA_QUALITY__P9; + if(!doneN) posN.y -= offNP.y * FXAA_QUALITY__P9; + doneNP = (!doneN) || (!doneP); + if(!doneP) posP.x += offNP.x * FXAA_QUALITY__P9; + if(!doneP) posP.y += offNP.y * FXAA_QUALITY__P9; +/*--------------------------------------------------------------------------*/ + #if (FXAA_QUALITY__PS > 10) + if(doneNP) { + if(!doneN) lumaEndN = FxaaLuma(FxaaTexTop(tex, posN.xy)); + if(!doneP) lumaEndP = FxaaLuma(FxaaTexTop(tex, posP.xy)); + if(!doneN) lumaEndN = lumaEndN - lumaNN * 0.5; + if(!doneP) lumaEndP = lumaEndP - lumaNN * 0.5; + doneN = abs(lumaEndN) >= gradientScaled; + doneP = abs(lumaEndP) >= gradientScaled; + if(!doneN) posN.x -= offNP.x * FXAA_QUALITY__P10; + if(!doneN) posN.y -= offNP.y * FXAA_QUALITY__P10; + doneNP = (!doneN) || (!doneP); + if(!doneP) posP.x += offNP.x * FXAA_QUALITY__P10; + if(!doneP) posP.y += offNP.y * FXAA_QUALITY__P10; +/*--------------------------------------------------------------------------*/ + #if (FXAA_QUALITY__PS > 11) + if(doneNP) { + if(!doneN) lumaEndN = FxaaLuma(FxaaTexTop(tex, posN.xy)); + if(!doneP) lumaEndP = FxaaLuma(FxaaTexTop(tex, posP.xy)); + if(!doneN) lumaEndN = lumaEndN - lumaNN * 0.5; + if(!doneP) lumaEndP = lumaEndP - lumaNN * 0.5; + doneN = abs(lumaEndN) >= gradientScaled; + doneP = abs(lumaEndP) >= gradientScaled; + if(!doneN) posN.x -= offNP.x * FXAA_QUALITY__P11; + if(!doneN) posN.y -= offNP.y * FXAA_QUALITY__P11; + doneNP = (!doneN) || (!doneP); + if(!doneP) posP.x += offNP.x * FXAA_QUALITY__P11; + if(!doneP) posP.y += offNP.y * FXAA_QUALITY__P11; +/*--------------------------------------------------------------------------*/ + #if (FXAA_QUALITY__PS > 12) + if(doneNP) { + if(!doneN) lumaEndN = FxaaLuma(FxaaTexTop(tex, posN.xy)); + if(!doneP) lumaEndP = FxaaLuma(FxaaTexTop(tex, posP.xy)); + if(!doneN) lumaEndN = lumaEndN - lumaNN * 0.5; + if(!doneP) lumaEndP = lumaEndP - lumaNN * 0.5; + doneN = abs(lumaEndN) >= gradientScaled; + doneP = abs(lumaEndP) >= gradientScaled; + if(!doneN) posN.x -= offNP.x * FXAA_QUALITY__P12; + if(!doneN) posN.y -= offNP.y * FXAA_QUALITY__P12; + doneNP = (!doneN) || (!doneP); + if(!doneP) posP.x += offNP.x * FXAA_QUALITY__P12; + if(!doneP) posP.y += offNP.y * FXAA_QUALITY__P12; +/*--------------------------------------------------------------------------*/ + } + #endif +/*--------------------------------------------------------------------------*/ + } + #endif +/*--------------------------------------------------------------------------*/ + } + #endif +/*--------------------------------------------------------------------------*/ + } + #endif +/*--------------------------------------------------------------------------*/ + } + #endif +/*--------------------------------------------------------------------------*/ + } + #endif +/*--------------------------------------------------------------------------*/ + } + #endif +/*--------------------------------------------------------------------------*/ + } + #endif +/*--------------------------------------------------------------------------*/ + } + #endif +/*--------------------------------------------------------------------------*/ + } + #endif +/*--------------------------------------------------------------------------*/ + } +/*--------------------------------------------------------------------------*/ + FxaaFloat dstN = posM.x - posN.x; + FxaaFloat dstP = posP.x - posM.x; + if(!horzSpan) dstN = posM.y - posN.y; + if(!horzSpan) dstP = posP.y - posM.y; +/*--------------------------------------------------------------------------*/ + FxaaBool goodSpanN = (lumaEndN < 0.0) != lumaMLTZero; + FxaaFloat spanLength = (dstP + dstN); + FxaaBool goodSpanP = (lumaEndP < 0.0) != lumaMLTZero; + FxaaFloat spanLengthRcp = 1.0 / spanLength; +/*--------------------------------------------------------------------------*/ + FxaaBool directionN = dstN < dstP; + FxaaFloat dst = min(dstN, dstP); + FxaaBool goodSpan = directionN ? goodSpanN : goodSpanP; + FxaaFloat subpixG = subpixF * subpixF; + FxaaFloat pixelOffset = (dst * (-spanLengthRcp)) + 0.5; + FxaaFloat subpixH = subpixG * fxaaQualitySubpix; +/*--------------------------------------------------------------------------*/ + FxaaFloat pixelOffsetGood = goodSpan ? pixelOffset : 0.0; + FxaaFloat pixelOffsetSubpix = max(pixelOffsetGood, subpixH); + if(!horzSpan) posM.x += pixelOffsetSubpix * lengthSign; + if(horzSpan) posM.y += pixelOffsetSubpix * lengthSign; + #if (FXAA_DISCARD == 1) + return FxaaTexTop(tex, posM); + #else + return FxaaFloat4(FxaaTexTop(tex, posM).xyz, lumaM); + #endif +} +/*==========================================================================*/ +#endif diff --git a/rpplugins/fxaa/shader/fxaa_stage.frag.glsl b/rpplugins/fxaa/shader/fxaa_stage.frag.glsl new file mode 100644 index 0000000..e2b764e --- /dev/null +++ b/rpplugins/fxaa/shader/fxaa_stage.frag.glsl @@ -0,0 +1,86 @@ +/** + * + * RenderPipeline + * + * Copyright (c) 2014-2016 tobspr + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + */ + +#version 430 + +#pragma include "render_pipeline_base.inc.glsl" + +#define FXAA_PC 1 +#define FXAA_GLSL_130 1 + +// Define quality level +#if ENUM_V_ACTIVE(fxaa, quality, low) + #define FXAA_QUALITY_PRESET 12 +#elif ENUM_V_ACTIVE(fxaa, quality, medium) + #define FXAA_QUALITY_PRESET 20 +#elif ENUM_V_ACTIVE(fxaa, quality, high) + #define FXAA_QUALITY_PRESET 29 +#elif ENUM_V_ACTIVE(fxaa, quality, ultra) + #define FXAA_QUALITY_PRESET 39 +#else + #error Unkown fxaa quality +#endif + +#pragma include "FXAA.inc.glsl" + +uniform sampler2D SourceTex; +out vec4 color; + +void main() { + + vec2 texcoord = get_texcoord(); + vec2 pixel_size = vec2(1.0) / SCREEN_SIZE; + + vec2 upper_left = texcoord + vec2(-0.5, 0.5) * pixel_size; + vec2 lower_right = texcoord + vec2(0.5, -0.5) * pixel_size; + + const float sharp = 0.5; // unused in the pc version + const float edge_threshold = GET_SETTING(fxaa, edge_threshold); + const float edge_min_threshold = 0.1 * GET_SETTING(fxaa, min_threshold); + const float edge_sharpness = 8.0; // power of two, unused in the pc version + vec4 size_twice = vec4(WINDOW_WIDTH, WINDOW_HEIGHT, WINDOW_WIDTH, WINDOW_HEIGHT); + + vec4 result = FxaaPixelShader( + texcoord, // pos + vec4(upper_left, lower_right), // fxaaConsolePosPos + SourceTex, // tex + SourceTex, // fxaaConsole360TexExpBiasNegOne + SourceTex, // fxaaConsole360TexExpBiasNegTwo + vec2(1.0) / SCREEN_SIZE, // fxaaQualityRcpFrame + vec4(-sharp, -sharp, sharp, sharp) / size_twice, // fxaaConsoleRcpFrameOpt + vec4(-2, -2, 2, 2) / size_twice, // fxaaConsoleRcpFrameOpt2 + vec4(8, 8, -4, -4) / size_twice, // fxaaConsole360RcpFrameOpt2 + GET_SETTING(fxaa, subpixel_quality), // fxaaQualitySubpix + edge_threshold, // fxaaQualityEdgeThreshold + edge_min_threshold, // fxaaQualityEdgeThresholdMin + edge_sharpness, // fxaaConsoleEdgeSharpness + edge_threshold, // fxaaConsoleEdgeThreshold + edge_min_threshold, // fxaaConsoleEdgeThresholdMin + vec4(1.0, -1.0, 0.25, -0.25) // fxaaConsole360ConstDir + ); + + color = result; +} diff --git a/rpplugins/fxaa/shader/write_luma.frag.glsl b/rpplugins/fxaa/shader/write_luma.frag.glsl new file mode 100644 index 0000000..21f4dfd --- /dev/null +++ b/rpplugins/fxaa/shader/write_luma.frag.glsl @@ -0,0 +1,37 @@ +/** + * + * RenderPipeline + * + * Copyright (c) 2014-2016 tobspr + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + */ + +#version 430 + +#pragma include "render_pipeline_base.inc.glsl" +uniform sampler2D ShadedScene; +out vec4 color; + +void main() { + vec2 texcoord = get_texcoord(); + color.xyz = textureLod(ShadedScene, texcoord, 0).xyz; + color.w = dot(color.xyz, vec3(0.299, 0.587, 0.114)); +} diff --git a/rpplugins/motion_blur/__init__.py b/rpplugins/motion_blur/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/rpplugins/motion_blur/config.yaml b/rpplugins/motion_blur/config.yaml new file mode 100644 index 0000000..a722921 --- /dev/null +++ b/rpplugins/motion_blur/config.yaml @@ -0,0 +1,80 @@ + +settings: !!omap + + - num_camera_samples: + type: int + range: [2, 16] + default: 6 + label: Camera Blur sample count + shader_runtime: true + description: > + Controls the amount of samples for camera motion blur, more samples + mean a smoother blur but also require more performance. + + - camera_blur_factor: + type: float + range: [0.0, 2.0] + default: 0.4 + label: Camera Blur factor + shader_runtime: true + description: > + Controls the camera blur factor, a factor of 1 means the full blur + is applied, a factor of 0 means no blur at all. You should adjust + this so the blur is not too strong, otherwise motion sickness can happen. + + - enable_object_blur: + type: bool + default: false + label: Enable object blur + description: > + Whether to enable per object blur, this only works when the per + object velocity vector patch was applied. Otherwise, this just + costs more performance. + + - blur_factor: + display_if: {enable_object_blur: true} + type: float + range: [0.0, 1.0] + default: 0.5 + label: Object Blur factor + shader_runtime: true + description: > + Controls the blur factor of moving objects, a factor of 1 means the + full blur is applied, a factor of 0 means no blur at all. + + - tile_size: + display_if: {enable_object_blur: true} + type: int + range: [8, 64] + default: 32 + label: Object Blur Tile Size + description: > + Size of the blur tiles, this also has influence on the maximum + blur radius. Setting this too high will cause artifacts when objects + with different motion vectors overlap. + + + - max_blur_radius: + display_if: {enable_object_blur: true} + type: float + range: [1.0, 64.0] + default: 10.0 + label: Object Blur limit + shader_runtime: true + description: > + Controls the maximum possible blur size. Try to set this as low as + possible without getting artifacts. + + - num_samples: + display_if: {enable_object_blur: true} + type: int + range: [2, 64] + default: 12 + label: Object Blur sample count + shader_runtime: true + description: > + Controls the amount of samples, more samples mean a smoother blur + but also require more performance. + + +daytime_settings: diff --git a/rpplugins/motion_blur/motion_blur_stage.py b/rpplugins/motion_blur/motion_blur_stage.py new file mode 100644 index 0000000..b8fcb1f --- /dev/null +++ b/rpplugins/motion_blur/motion_blur_stage.py @@ -0,0 +1,97 @@ +""" + +RenderPipeline + +Copyright (c) 2014-2016 tobspr + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. + +""" + +from panda3d.core import SamplerState + +from rpcore.render_stage import RenderStage + + +class MotionBlurStage(RenderStage): + + """ This stage applies the motion blur, using the screen space velocity vectors """ + + required_inputs = [] + required_pipes = ["ShadedScene", "GBuffer", "DownscaledDepth", "CombinedVelocity"] + + @property + def produced_pipes(self): + return {"ShadedScene": self.target_cam_blur.color_tex} + + def create(self): + + if self.per_object_blur: + self.tile_target = self.create_target("FetchVertDominantVelocity") + self.tile_target.size = -1, -self.tile_size + self.tile_target.add_color_attachment(bits=(16, 16, 0)) + self.tile_target.prepare_buffer() + + self.tile_target_horiz = self.create_target("FetchHorizDominantVelocity") + self.tile_target_horiz.size = -self.tile_size + self.tile_target_horiz.add_color_attachment(bits=(16, 16, 0)) + self.tile_target_horiz.prepare_buffer() + self.tile_target_horiz.set_shader_input("SourceTex", self.tile_target.color_tex) + + self.minmax_target = self.create_target("NeighborMinMax") + self.minmax_target.size = -self.tile_size + self.minmax_target.add_color_attachment(bits=(16, 16, 0)) + self.minmax_target.prepare_buffer() + self.minmax_target.set_shader_input("TileMinMax", self.tile_target_horiz.color_tex) + + self.pack_target = self.create_target("PackBlurData") + self.pack_target.add_color_attachment(bits=(16, 16, 0)) + self.pack_target.prepare_buffer() + + self.target = self.create_target("ObjectMotionBlur") + self.target.add_color_attachment(bits=16) + self.target.prepare_buffer() + self.target.set_shader_inputs( + NeighborMinMax=self.minmax_target.color_tex, + PackedSceneData=self.pack_target.color_tex) + + self.target.color_tex.set_wrap_u(SamplerState.WM_clamp) + self.target.color_tex.set_wrap_v(SamplerState.WM_clamp) + + self.target_cam_blur = self.create_target("CameraMotionBlur") + self.target_cam_blur.add_color_attachment(bits=16) + self.target_cam_blur.prepare_buffer() + + if self.per_object_blur: + self.target_cam_blur.set_shader_input("SourceTex", self.target.color_tex) + + def reload_shaders(self): + if self.per_object_blur: + self.tile_target.shader = self.load_plugin_shader( + "fetch_dominant_velocity.frag.glsl") + self.tile_target_horiz.shader = self.load_plugin_shader( + "fetch_dominant_velocity_horiz.frag.glsl") + self.minmax_target.shader = self.load_plugin_shader( + "neighbor_minmax.frag.glsl") + self.pack_target.shader = self.load_plugin_shader( + "pack_blur_data.frag.glsl") + self.target.shader = self.load_plugin_shader( + "apply_motion_blur.frag.glsl") + self.target_cam_blur.shader = self.load_plugin_shader( + "camera_motion_blur.frag.glsl") diff --git a/rpplugins/motion_blur/plugin.py b/rpplugins/motion_blur/plugin.py new file mode 100644 index 0000000..551eb68 --- /dev/null +++ b/rpplugins/motion_blur/plugin.py @@ -0,0 +1,43 @@ +""" + +RenderPipeline + +Copyright (c) 2014-2016 tobspr + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. + +""" + +from rpcore.pluginbase.base_plugin import BasePlugin + +from .motion_blur_stage import MotionBlurStage + + +class Plugin(BasePlugin): + + name = "Motion blur" + author = "tobspr " + description = ("This plugin adds support for motion blur. This includes " + "per-object motion blur aswell as camera-motion blur.") + version = "1.0" + + def on_stage_setup(self): + self.stage = self.create_stage(MotionBlurStage) + self.stage.tile_size = self.get_setting("tile_size") + self.stage.per_object_blur = self.get_setting("enable_object_blur") diff --git a/rpplugins/motion_blur/shader/apply_motion_blur.frag.glsl b/rpplugins/motion_blur/shader/apply_motion_blur.frag.glsl new file mode 100644 index 0000000..46514e6 --- /dev/null +++ b/rpplugins/motion_blur/shader/apply_motion_blur.frag.glsl @@ -0,0 +1,93 @@ +/** + * + * RenderPipeline + * + * Copyright (c) 2014-2016 tobspr + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + */ + +#version 430 + +#define USE_GBUFFER_EXTENSIONS +#pragma include "render_pipeline_base.inc.glsl" +#pragma include "includes/gbuffer.inc.glsl" +#pragma include "includes/noise.inc.glsl" + +#pragma include "motion_blur.inc.glsl" + +uniform sampler2D ShadedScene; +uniform sampler2D PackedSceneData; +uniform sampler2D NeighborMinMax; + +out vec3 result; + +const int num_samples = GET_SETTING(motion_blur, num_samples); + + +void main() { + + vec2 texcoord = get_texcoord(); + ivec2 coord = ivec2(gl_FragCoord.xy); + ivec2 tile = coord / tile_size; + vec3 center_color = texelFetch(ShadedScene, coord, 0).xyz; + + vec2 tile_velocity = texelFetch(NeighborMinMax, tile, 0).xy; // max_v + const float weight_step = 1.0 / float(num_samples - 1); + + // Early out + if (length(tile_velocity) < 0.5 / WINDOW_WIDTH) { + result = max(vec3(0.0), center_color); + return; + } + + // Get current pixel offset + vec2 vx = texelFetch(PackedSceneData, coord, 0).xy; + vec2 blur_step = tile_velocity * weight_step * 2.0; + vec2 start_tc = texcoord - tile_velocity; + + float min_len_xy = -length(tile_velocity.xy); + float len_xy_step = (-min_len_xy) * weight_step * 2.0; + + float initial_weight = saturate(float(num_samples / 40.0)); + initial_weight *= 1.0 / (max(1.0, vx.x)); + + float jitter = rand(vec2(coord)); + + float weight_accum = initial_weight; + vec3 accum = center_color * initial_weight; + + for (int i = 0; i < num_samples; ++i) { + + vec2 tc = start_tc + blur_step * (i + jitter); + vec2 vy = textureLod(PackedSceneData, tc, 0).xy; + float len_xy = abs(min_len_xy + len_xy_step * (i + jitter)); + + vec2 cmp_softz = soft_depth_cmp(vec2(vx.y, vy.y), vec2(vy.y, vx.y)); + vec4 cmp_batch = batch_cmp(len_xy, max(vec2(1e-6), vec2(vy.x, vx.x))); + float w = dot(cmp_softz, cmp_batch.xy) + (cmp_batch.z * cmp_batch.w) * 2.0; + + accum += saturate(textureLod(ShadedScene, tc, 0).xyz) * w; + weight_accum += w; + + } + + result = max(vec3(0.0), accum / max(0.001, weight_accum)); +} diff --git a/rpplugins/motion_blur/shader/camera_motion_blur.frag.glsl b/rpplugins/motion_blur/shader/camera_motion_blur.frag.glsl new file mode 100644 index 0000000..23ace79 --- /dev/null +++ b/rpplugins/motion_blur/shader/camera_motion_blur.frag.glsl @@ -0,0 +1,111 @@ +/** + * + * RenderPipeline + * + * Copyright (c) 2014-2016 tobspr + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + */ + +#version 430 + +#define USE_GBUFFER_EXTENSIONS +#pragma include "render_pipeline_base.inc.glsl" +#pragma include "includes/gbuffer.inc.glsl" +#pragma include "includes/noise.inc.glsl" + +#pragma optionNV (unroll all) + +#if GET_SETTING(motion_blur, enable_object_blur) +uniform sampler2D SourceTex; +#define SOURCE SourceTex +#else +uniform sampler2D ShadedScene; +#define SOURCE ShadedScene +#endif + + +uniform sampler2D CombinedVelocity; +out vec3 result; + +const int num_samples = GET_SETTING(motion_blur, num_camera_samples) * 2; +float max_velocity = 70.0 / WINDOW_WIDTH; +float min_velocity = 0.5 / WINDOW_WIDTH; + +void main() { + + vec2 texcoord = get_texcoord(); + ivec2 coord = ivec2(gl_FragCoord.xy); + + #if DEBUG_MODE + result = textureLod(SOURCE, texcoord, 0).xyz; + return; + #endif + + // Reconstruct last frame texcoord + vec2 film_offset_bias = MainSceneData.current_film_offset * vec2(1.0, 1.0 / ASPECT_RATIO); + vec3 pos = get_world_pos_at(texcoord - film_offset_bias); + vec4 last_proj = MainSceneData.last_view_proj_mat_no_jitter * vec4(pos, 1); + vec2 last_coord = fma(last_proj.xy / last_proj.w, vec2(0.5), vec2(0.5)); + + // Compute velocity in screen space + vec2 velocity = last_coord - texcoord; + + // Make sure that when we have low-fps, we reduce motion blur, and when we + // have higher fps, we increase it - this way it perceptually always stays + // the same (otherwise it feels really laggy at low FPS) + const float target_fps = 60.0; + velocity *= (1.0 / target_fps) / MainSceneData.frame_delta; + velocity *= GET_SETTING(motion_blur, camera_blur_factor); + + float velocity_len = length(velocity); + + // We can abort early when no velocity is present + if (velocity_len < min_velocity) { + result = textureLod(SOURCE, texcoord, 0).xyz; + return; + } + + if (velocity_len > max_velocity) { + float scale_factor = max_velocity / velocity_len; + velocity *= scale_factor; + velocity_len *= scale_factor; + } + + // Weight the center sample by a small bit to make sure we always have a weight. + // However, we don't weight it too much to make the blur not look weird. + float weights = 1e-3; + vec3 accum = textureLod(SOURCE, texcoord, 0).xyz * weights; + float jitter = rand(texcoord); + + // Blur in both directions + for (int i = -num_samples + 1; i < num_samples; ++i) { + vec2 offs = (i + 0.5 * jitter) / float(num_samples) * velocity; + + // Prevent bleeding when rotating - that is, objects moving into different directions + vec2 sample_velocity = textureLod(CombinedVelocity, texcoord + offs, 0).xy; + float weight = saturate(dot(sample_velocity, velocity) * WINDOW_WIDTH * 3); + accum += textureLod(SOURCE, texcoord + offs, 0).xyz * weight; + weights += weight; + } + + accum /= weights; + result = max(vec3(0.0), accum); +} diff --git a/rpplugins/motion_blur/shader/fetch_dominant_velocity.frag.glsl b/rpplugins/motion_blur/shader/fetch_dominant_velocity.frag.glsl new file mode 100644 index 0000000..c322142 --- /dev/null +++ b/rpplugins/motion_blur/shader/fetch_dominant_velocity.frag.glsl @@ -0,0 +1,58 @@ +/** + * + * RenderPipeline + * + * Copyright (c) 2014-2016 tobspr + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + */ + +#version 430 + +#pragma optionNV (unroll all) + +#define USE_GBUFFER_EXTENSIONS +#pragma include "render_pipeline_base.inc.glsl" +#pragma include "includes/gbuffer.inc.glsl" +#pragma include "motion_blur.inc.glsl" + +out vec2 result; + +void main() { + ivec2 coord = ivec2(gl_FragCoord.xy); + ivec2 screen_coord = ivec2(coord.x, coord.y * tile_size); + + vec2 max_velocity = vec2(0); + float max_velocity_len_sq = 0.0; + + // Find the longest vector in the tile + for (int y = 0; y <= tile_size; y += 4) { + vec2 velocity = get_gbuffer_object_velocity(GBuffer, ivec2(coord.x, screen_coord.y + y)); + float len_sq = dot(velocity, velocity); + + // Check if the vector is longer than the current longest vector + if (len_sq > max_velocity_len_sq) { + max_velocity_len_sq = len_sq; + max_velocity = velocity; + } + } + + result = adjust_velocity(max_velocity); +} diff --git a/rpplugins/motion_blur/shader/fetch_dominant_velocity_horiz.frag.glsl b/rpplugins/motion_blur/shader/fetch_dominant_velocity_horiz.frag.glsl new file mode 100644 index 0000000..cab721a --- /dev/null +++ b/rpplugins/motion_blur/shader/fetch_dominant_velocity_horiz.frag.glsl @@ -0,0 +1,60 @@ +/** + * + * RenderPipeline + * + * Copyright (c) 2014-2016 tobspr + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + */ + +#version 430 + +#pragma optionNV (unroll all) + +#define USE_GBUFFER_EXTENSIONS +#pragma include "render_pipeline_base.inc.glsl" +#pragma include "includes/gbuffer.inc.glsl" +#pragma include "motion_blur.inc.glsl" + +uniform sampler2D SourceTex; +out vec2 result; + +void main() { + ivec2 coord = ivec2(gl_FragCoord.xy); + ivec2 source_coord = ivec2(coord.x * tile_size, coord.y); + + vec2 max_velocity = vec2(0); + float max_velocity_len_sq = 0.0; + + // Find the longest vector in the tile + for (int x = 0; x <= tile_size; x += 4) { + int x_coord = clamp(source_coord.x + x, 0, WINDOW_WIDTH - 1); + vec2 velocity = texelFetch(SourceTex, ivec2(x_coord, source_coord.y), 0).xy; + float len_sq = dot(velocity, velocity); + + // Check if the vector is longer than the current longest vector + if (len_sq > max_velocity_len_sq) { + max_velocity_len_sq = len_sq; + max_velocity = velocity; + } + } + + result = max_velocity; +} diff --git a/rpplugins/motion_blur/shader/motion_blur.inc.glsl b/rpplugins/motion_blur/shader/motion_blur.inc.glsl new file mode 100644 index 0000000..6f47d12 --- /dev/null +++ b/rpplugins/motion_blur/shader/motion_blur.inc.glsl @@ -0,0 +1,55 @@ +/** + * + * RenderPipeline + * + * Copyright (c) 2014-2016 tobspr + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + */ + +#pragma once + +const int tile_size = GET_SETTING(motion_blur, tile_size); +float blur_factor = GET_SETTING(motion_blur, blur_factor) * 0.5; +float max_velocity_len = GET_SETTING(motion_blur, max_blur_radius) * + tile_size / WINDOW_WIDTH * 0.2; +const vec2 soft_depth_factor = vec2(10.0); + +vec2 adjust_velocity(vec2 velocity) { + velocity *= blur_factor; + + // Make sure the velocity does not exceed the maximum length + float vel_len = length(velocity); + if (vel_len > max_velocity_len) { + velocity *= max_velocity_len / vel_len; + } + return velocity; +} + + +vec2 soft_depth_cmp(vec2 z0, vec2 z1) +{ + return saturate(fma(z0, soft_depth_factor, vec2(1.0)) - z1 * soft_depth_factor); +} + +vec4 batch_cmp(float len_xy_sq, vec2 velocities) +{ + return saturate(vec4((1 - len_xy_sq / (velocities.xyxy)) + vec4(0.0, 0.0, 0.95, 0.95))); +} diff --git a/rpplugins/motion_blur/shader/neighbor_minmax.frag.glsl b/rpplugins/motion_blur/shader/neighbor_minmax.frag.glsl new file mode 100644 index 0000000..59ae2a0 --- /dev/null +++ b/rpplugins/motion_blur/shader/neighbor_minmax.frag.glsl @@ -0,0 +1,71 @@ +/** + * + * RenderPipeline + * + * Copyright (c) 2014-2016 tobspr + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + */ + +#version 430 + +#pragma include "render_pipeline_base.inc.glsl" +#pragma include "includes/gbuffer.inc.glsl" +#pragma include "motion_blur.inc.glsl" + +uniform sampler2D TileMinMax; +out vec2 result; + +// Based on: +// http://graphics.cs.williams.edu/papers/MotionBlurI3D12/ + +void main() { + + ivec2 tile = ivec2(gl_FragCoord.xy); + ivec2 screen_coord = tile * tile_size; + ivec2 max_tiles = textureSize(TileMinMax, 0) - 1; + + vec2 max_velocity = vec2(0.0); + float largest_magnitude = -1.0; + + const int filter_size = 2; + + for (int x = -filter_size; x <= filter_size; ++x) { + for (int y = -filter_size; y <= filter_size; ++y) { + ivec2 neighbor_coord = clamp(tile + ivec2(x, y), ivec2(0), ivec2(max_tiles)); + vec2 vmax_neighbor = texelFetch(TileMinMax, neighbor_coord, 0).xy; + + float magnitude_neighbor = dot(vmax_neighbor, vmax_neighbor); + + if (magnitude_neighbor > largest_magnitude) { + vec2 direction_of_velocity = vmax_neighbor; + int displacement = abs(x) + abs(y); + ivec2 point = ivec2(sign(vec2(x, y) * direction_of_velocity)); + float dist = point.x + point.y; + if (abs(dist) == displacement) { + max_velocity = vmax_neighbor; + largest_magnitude = magnitude_neighbor; + } + } + } + } + + result = max_velocity; +} diff --git a/rpplugins/motion_blur/shader/pack_blur_data.frag.glsl b/rpplugins/motion_blur/shader/pack_blur_data.frag.glsl new file mode 100644 index 0000000..a260bdf --- /dev/null +++ b/rpplugins/motion_blur/shader/pack_blur_data.frag.glsl @@ -0,0 +1,44 @@ +/** + * + * RenderPipeline + * + * Copyright (c) 2014-2016 tobspr + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + */ + +#version 430 + +// Packs the velocity length and scene depth into a RG16 target + +#define USE_GBUFFER_EXTENSIONS +#pragma include "render_pipeline_base.inc.glsl" +#pragma include "includes/gbuffer.inc.glsl" +#pragma include "motion_blur.inc.glsl" + +out vec2 result; + +void main() { + vec2 texcoord = get_texcoord(); + float depth = get_depth_at(texcoord); + vec2 velocity = get_object_velocity_at(texcoord); + velocity = adjust_velocity(velocity); + result = vec2(length(velocity), depth); +} diff --git a/rpplugins/plugin_prefab/__init__.py b/rpplugins/plugin_prefab/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/rpplugins/plugin_prefab/config.yaml b/rpplugins/plugin_prefab/config.yaml new file mode 100644 index 0000000..2d71d0b --- /dev/null +++ b/rpplugins/plugin_prefab/config.yaml @@ -0,0 +1,48 @@ + +settings: !!omap + + - some_int_setting: + type: int + range: [0, 10] + default: 5 + label: Some integer setting + description: Description of the setting. + + - some_resolution_setting: + type: power_of_two + range: [4, 8192] + default: 32 + label: Some resolution setting, must be power of two. + description: Description of the setting. + + - some_float_setting: + type: float + range: [-5.3, 2.9] + default: 2.5 + label: Some float setting + description: Description of the setting. + runtime: true + + - some_enum: + type: enum + values: [value1, value2, value3] + default: value2 + label: Some enum setting + description: Description of the setting. + + - some_bool: + type: bool + default: false + label: Some boolean setting + description: Description of the setting. + +daytime_settings: !!omap + + - some_scalar: + type: scalar + unit: percent + range: [0, 1] + default: 0.5 + label: Some Scalar + description: Description of the scalar. + diff --git a/rpplugins/plugin_prefab/demo_stage.py b/rpplugins/plugin_prefab/demo_stage.py new file mode 100644 index 0000000..8faa32a --- /dev/null +++ b/rpplugins/plugin_prefab/demo_stage.py @@ -0,0 +1,47 @@ +""" + +RenderPipeline + +Copyright (c) 2014-2016 tobspr + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. + +""" + +from rpcore.render_stage import RenderStage + + +class DemoStage(RenderStage): + + """ This is a demo stage which does .. nothing """ + + required_inputs = [] + required_pipes = ["ShadedScene"] + + @property + def produced_pipes(self): + return {"ShadedScene": self.target.color_tex} + + def create(self): + self.target = self.create_target("FancyEffect") + self.target.add_color_texture(bits=16) + self.target.prepare_buffer() + + def reload_shaders(self): + self.target.shader = self.load_plugin_shader("fancy_effect.frag.glsl") diff --git a/rpplugins/plugin_prefab/plugin.py b/rpplugins/plugin_prefab/plugin.py new file mode 100644 index 0000000..d288548 --- /dev/null +++ b/rpplugins/plugin_prefab/plugin.py @@ -0,0 +1,55 @@ +""" + +RenderPipeline + +Copyright (c) 2014-2016 tobspr + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. + +""" +# Load the base plugin class +from rpcore.pluginbase.base_plugin import BasePlugin + +# Load your additional plugin classes here, if required +from .demo_stage import DemoStage + + +class Plugin(BasePlugin): + + name = "Plugin Prefab" + author = "tobspr " + description = ("This is the most basic structure of a plugin. You can copy " + "it to produce your own plugins") + version = "1.0" + + def on_stage_setup(self): + """ This method gets called when the pipeline setups the render + stages. You should create your custom stages here """ + + # Setup a demo stage + self.stage = self.create_stage(DemoStage) + + def on_pipeline_created(self): + """ This method gets called after the pipeline finished the setup, + and is about to start rendering """ + + def update_some_setting(self): + """ This method gets called when the setting "some_setting" + of your plugin gets called. You should do all work to update required + inputs etc. yourself. """ diff --git a/rpplugins/plugin_prefab/resources/README.txt b/rpplugins/plugin_prefab/resources/README.txt new file mode 100644 index 0000000..df8455e --- /dev/null +++ b/rpplugins/plugin_prefab/resources/README.txt @@ -0,0 +1,4 @@ +Put your textures / models and other resources into this folder. + +You can access them with get_resource("resource_name.ext") + diff --git a/rpplugins/plugin_prefab/shader/README.txt b/rpplugins/plugin_prefab/shader/README.txt new file mode 100644 index 0000000..4a0dc3a --- /dev/null +++ b/rpplugins/plugin_prefab/shader/README.txt @@ -0,0 +1,12 @@ +Put your shaders into this directory. + +-- + +You can access shader files with self.get_shader_resource("shader_name.frag.glsl") + +-- + +You can access load shader files inside of a RenderStage with: + +self.load_plugin_shader("shader_name.frag.glsl") + diff --git a/rpplugins/pssm/__init__.py b/rpplugins/pssm/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/rpplugins/pssm/config.yaml b/rpplugins/pssm/config.yaml new file mode 100644 index 0000000..f84901d --- /dev/null +++ b/rpplugins/pssm/config.yaml @@ -0,0 +1,254 @@ + +settings: !!omap + + - max_distance: + type: float + range: [2.0, 6000.0] + default: 100.0 + runtime: true + shader_runtime: true + label: Maximum shadow distance + description: > + This controls the maximum distance up to where shadows + are rendered. A higher distance means further shadows, + but also a worse shadow quality. + + - logarithmic_factor: + type: float + range: [0.01, 3.0] + default: 2.4 + runtime: true + shader_runtime: true + label: Logarithmic Factor + description: > + Controls the logarithmic factor of the splitting scheme. Lower + values mean a more linear distribution, while higher values will + move the splits closer to the camera. + + - sun_distance: + type: float + range: [100.0, 10000.0] + default: 100.0 + label: Sun distance + runtime: true + description: > + This controls how far the sun is away from the scene, to avoid + clipping objects outside of the frustum which still cast shadows. + Basically you don't need to adjust this setting, but in + case you get artifacts, try increasing this setting. + + - split_count: + type: int + range: [1, 20] + default: 5 + label: Amount of PSSM Splits / Cascades + description: > + This controls how many splits are used for the PSSM. + A higher amount of splits increases the shadow map + detail and quality, but also increases the performance + cost by a lot. For every split, the scene has to get + rendered again, so be careful when choosing high amount + of splits. + + - resolution: + type: power_of_two + range: [128, 4096] + default: 1024 + label: Shadowmap resolution + description: > + This controls the resolution of the individual shadowmaps + of the splits. If you choose a resolution of 512 for example, + and you have 10 splits, then that makes a total resolution + of 5120 * 512 for the shadow map. Be careful when choosing high + defaults, the shadow map will soon take a huge amount of VRam. + + - border_bias: + type: float + range: [0.0, 0.35] + default: 0.058 + label: Border Padding + runtime: true + shader_runtime: true + description: > + Increases the shadow map size of each cascade by a small factor, to + ensure seamless filtering between cascades. If you encounter artifacts + between cascades, increase this value. + + - use_pcf: + type: bool + default: true + label: Use hardware filtering (PCF) + description: > + This setting turns Percentage Closer Filtering on or off (A simple + 2x2 bilinear filter provided by the GPU). + It provides a better shadow quality, and theoretically a better + performance. However, not all GPU's seem to support it. + + - filter_sequence: + type: sample_sequence + dimension: 2 + default: halton_2D_16 + shader_runtime: true + label: Filtering sequence + description: > + Amount and Type of samples to take for filtering the shadow. Higher + values provide a better shadow quality, but also are more expensive. + + - filter_radius: + type: float + range: [0.05, 10.0] + default: 0.55 + shader_runtime: true + label: Filtering radius + description: > + This setting controls the filter size, higher values mean a more + smooth penumbra. Too high values might (and will) produce artifacts. + This setting has almost no measureable impact on performance. + + - fixed_bias: + type: float + range: [0.0, 2.0] + default: 0.48 + shader_runtime: true + label: Depth Bias + description: > + Depth-Based bias. This avoids self-shadowing issues (also known) + as Shadow-Acne. Too high values will produce gaps in the shadows, + so try to find the lowest possible value. + + - slope_bias: + type: float + range: [0.0, 5.0] + default: 0.11 + shader_runtime: true + label: Slope Bias + description: > + Slope-Based bias. This avoid self-shadowing issues as well, but instead + of the fixed bias it adds bias based on the angle between the light + and the surface. + + - normal_bias: + type: float + range: [0.0, 5.0] + default: 0.39 + shader_runtime: true + label: Normal Bias + description: > + Normal-Based bias. This moves the sample position by a small amount + into the direction of the surface normal, to avoid self shadowing. + + # PCSS settings + + - use_pcss: + type: bool + default: false + shader_runtime: true + label: Use PCSS + description: > + PCSS adds support for variable penumbra size shadows. Without PCSS, + all shadows have the same penumbra size at all places. With PCSS, + the shadow penumbra size increases based on the distance. However, + PCSS requires additionally computations, and thus is slower than + regular filtering. + + - pcss_sequence: + display_if: {use_pcss: true} + type: sample_sequence + dimension: 2 + default: halton_2D_16 + shader_runtime: true + label: PCSS Penumbra Samples + description: > + Amount and Type of samples to take for finding the penumbra size. + Higher values might produce better results at the cost of performance. + + - pcss_penumbra_size: + display_if: {use_pcss: true} + type: float + range: [0.1, 300.0] + default: 11.0 + shader_runtime: true + label: PCSS Penumbra scale + description: > + Scales the penumbra by a fixed factor. This is an artistic setting, + and does not affect performance much. Lower settings will cause a + smaller penumbra, while higher settings produce a bigger one. Too + high values might cause artifacts in the filtering. + + - pcss_min_penumbra_size: + display_if: {use_pcss: true} + type: float + range: [0.1, 20.0] + default: 5.0 + shader_runtime: true + label: PCSS Min. Penumbra scale + description: > + Specifies the minimum penumbra/filter size to avoid blocky shadows. + + - use_distant_shadows: + type: bool + default: true + label: Render distant shadows + description: > + When this setting is enabled, an additional shadow map is generated + to render distant shadows, e.g. for terrain. This makes it possible + to set the pssm distance very small, but still recieve shadows from + big objects. If your scene is not big, this may not be required. + + - dist_shadow_resolution: + display_if: {use_distant_shadows: true} + type: power_of_two + range: [128, 8192] + default: 1024 + label: Distant Shadow Resolution + description: > + Controls the size of distant shadow map in pixels. + + - dist_shadow_clipsize: + display_if: {use_distant_shadows: true} + type: float + range: [100.0, 20000.0] + default: 1000.0 + runtime: true + label: Distant Shadow Range + description: > + Controls the range of the distant shadow map. Bigger values cover + a bigger part of the scene, but also decrease the effective resolution. + + - dist_shadow_sundist: + display_if: {use_distant_shadows: true} + type: float + range: [100.0, 20000.0] + default: 500.0 + label: Distant Shadow Sun Distance + runtime: true + description: > + Same as the Sun Distance, but for the distant shadow map. + + - scene_shadow_resolution: + type: power_of_two + range: [128, 4096] + default: 512 + label: Scene shadow Resolution + description: > + Controls the size of the shadow map which is used when rendering + environment probes. + + - scene_shadow_sundist: + type: float + range: [100.0, 20000.0] + default: 100.0 + label: Scene Shadow Sun Distance + runtime: true + description: > + Same as the Sun Distance, but for the scene shadow map. + +daytime_settings: + + + + + + + + diff --git a/rpplugins/pssm/plugin.py b/rpplugins/pssm/plugin.py new file mode 100644 index 0000000..0ea16c2 --- /dev/null +++ b/rpplugins/pssm/plugin.py @@ -0,0 +1,182 @@ +""" + +RenderPipeline + +Copyright (c) 2014-2016 tobspr + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. + +""" +from __future__ import print_function + +from rplibs.six.moves import range # pylint: disable=import-error +from panda3d.core import PTAVecBase3f + +from rpcore.globals import Globals +from rpcore.pluginbase.base_plugin import BasePlugin +from rpcore.native import PSSMCameraRig, NATIVE_CXX_LOADED + +from .pssm_stage import PSSMStage +from .pssm_shadow_stage import PSSMShadowStage +from .pssm_scene_shadow_stage import PSSMSceneShadowStage +from .pssm_dist_shadow_stage import PSSMDistShadowStage + + +class Plugin(BasePlugin): + + name = "Sun Shadows" + author = "tobspr " + description = ("This plugin adds support for Parallel Split Shadow Maps " + "(PSSM), and also sun lighting.") + version = "1.2" + required_plugins = ("scattering",) + + def on_stage_setup(self): + + if not NATIVE_CXX_LOADED: + self.debug("Setting max splits to 1 since python is used") + self._pipeline.plugin_mgr.settings["pssm"]["split_count"].set_value(1) + + self.update_enabled = True + self.pta_sun_vector = PTAVecBase3f.empty_array(1) + self.last_cache_reset = 0 + + self.shadow_stage = self.create_stage(PSSMShadowStage) + self.pssm_stage = self.create_stage(PSSMStage) + + self.shadow_stage.num_splits = self.get_setting("split_count") + self.shadow_stage.split_resolution = self.get_setting("resolution") + + self.scene_shadow_stage = self.create_stage(PSSMSceneShadowStage) + self.scene_shadow_stage.resolution = self.get_setting("scene_shadow_resolution") + self.scene_shadow_stage.sun_distance = self.get_setting("scene_shadow_sundist") + + # Enable distant shadow map if specified + if self.get_setting("use_distant_shadows"): + self.dist_shadow_stage = self.create_stage(PSSMDistShadowStage) + self.dist_shadow_stage.resolution = self.get_setting("dist_shadow_resolution") + self.dist_shadow_stage.clip_size = self.get_setting("dist_shadow_clipsize") + self.dist_shadow_stage.sun_distance = self.get_setting("dist_shadow_sundist") + + self.pssm_stage.required_pipes.append("PSSMDistSunShadowMap") + self.pssm_stage.required_inputs.append("PSSMDistSunShadowMapMVP") + + def on_pipeline_created(self): + self.debug("Initializing pssm ..") + # Construct a dummy node to parent the rig to + self.node = Globals.base.render.attach_new_node("PSSMCameraRig") + self.node.hide() + + # Construct the actual PSSM rig + self.camera_rig = PSSMCameraRig(self.get_setting("split_count")) # noqa # pylint: disable=undefined-variable + self.camera_rig.set_sun_distance(self.get_setting("sun_distance")) + self.camera_rig.set_pssm_distance(self.get_setting("max_distance")) + self.camera_rig.set_logarithmic_factor(self.get_setting("logarithmic_factor")) + self.camera_rig.set_border_bias(self.get_setting("border_bias")) + self.camera_rig.set_use_stable_csm(True) + self.camera_rig.set_use_fixed_film_size(True) + self.camera_rig.set_resolution(self.get_setting("resolution")) + self.camera_rig.reparent_to(self.node) + + # Attach the cameras to the shadow stage + for i in range(self.get_setting("split_count")): + camera_np = self.camera_rig.get_camera(i) + camera_np.node().set_scene(Globals.base.render) + region = self.shadow_stage.split_regions[i] + region.set_camera(camera_np) + # camera_np.node().show_frustum() + + # Make sure the pipeline knows about our camera, so it can apply + # the correct bitmasks + self._pipeline.tag_mgr.register_camera("shadow", camera_np.node()) + + # Accept a shortcut to enable / disable the update of PSSM + Globals.base.accept("u", self.toggle_update_enabled) + + # Set inputs + self.pssm_stage.set_shader_inputs( + pssm_mvps=self.camera_rig.get_mvp_array(), + pssm_nearfar=self.camera_rig.get_nearfar_array()) + + if self.is_plugin_enabled("volumetrics"): + handle = self.get_plugin_instance("volumetrics") + handle.stage.set_shader_inputs( + pssm_mvps=self.camera_rig.get_mvp_array(), + pssm_nearfar=self.camera_rig.get_nearfar_array()) + + + def on_pre_render_update(self): + sun_vector = self.get_plugin_instance("scattering").sun_vector + + if sun_vector.z < 0.0: + self.shadow_stage.active = False + self.scene_shadow_stage.active = False + self.pssm_stage.set_render_shadows(False) + + if self.get_setting("use_distant_shadows"): + self.dist_shadow_stage.active = False + + # Return, no need to update the pssm splits + return + else: + self.shadow_stage.active = True + self.scene_shadow_stage.active = True + self.pssm_stage.set_render_shadows(True) + + if self.get_setting("use_distant_shadows"): + self.dist_shadow_stage.active = True + + if self.update_enabled: + self.camera_rig.update(Globals.base.camera, sun_vector) + + # Eventually reset cache + cache_diff = Globals.clock.get_frame_time() - self.last_cache_reset + if cache_diff > 5.0: + self.last_cache_reset = Globals.clock.get_frame_time() + self.camera_rig.reset_film_size_cache() + + self.scene_shadow_stage.sun_vector = sun_vector + + if self.get_setting("use_distant_shadows"): + self.dist_shadow_stage.sun_vector = sun_vector + + def update_max_distance(self): + self.camera_rig.set_pssm_distance(self.get_setting("max_distance")) + + def update_logarithmic_factor(self): + self.camera_rig.set_logarithmic_factor(self.get_setting("logarithmic_factor")) + + def update_border_bias(self): + self.camera_rig.set_border_bias(self.get_setting("border_bias")) + + def update_sun_distance(self): + self.camera_rig.set_sun_distance(self.get_setting("sun_distance")) + + def update_dist_shadow_clipsize(self): + self.dist_shadow_stage.clip_size = self.get_setting("dist_shadow_clipsize") + + def update_dist_shadow_sundist(self): + self.dist_shadow_stage.sun_distance = self.get_setting("dist_shadow_sundist") + + def update_scene_shadow_sundist(self): + self.scene_shadow_stage.sun_distance = self.get_setting("scene_shadow_sundist") + + def toggle_update_enabled(self): + self.update_enabled = not self.update_enabled + self.debug("Update enabled:", self.update_enabled) diff --git a/rpplugins/pssm/pssm_dist_shadow_stage.py b/rpplugins/pssm/pssm_dist_shadow_stage.py new file mode 100644 index 0000000..5a59c5a --- /dev/null +++ b/rpplugins/pssm/pssm_dist_shadow_stage.py @@ -0,0 +1,140 @@ +""" + +RenderPipeline + +Copyright (c) 2014-2016 tobspr + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. + +""" +from __future__ import division + +from panda3d.core import Vec3, Camera, OrthographicLens, PTAMat4 +from panda3d.core import LVecBase2i + +from rpcore.globals import Globals +from rpcore.render_stage import RenderStage +from rpcore.util.generic import snap_shadow_map + + +class PSSMDistShadowStage(RenderStage): + + """ This stage generates a depth map using Variance Shadow Maps for very + distant objects. """ + + required_inputs = [] + + def __init__(self, pipeline): + RenderStage.__init__(self, pipeline) + self.resolution = 2048 + self.clip_size = 500 + self.sun_distance = 8000 + self.sun_vector = Vec3(0, 0, 1) + self.pta_mvp = PTAMat4.empty_array(1) + + @property + def produced_inputs(self): + return {"PSSMDistSunShadowMapMVP": self.pta_mvp} + + @property + def produced_pipes(self): + return {"PSSMDistSunShadowMap": self.target_blur_h.color_tex} + + @property + def mvp(self): + return Globals.base.render.get_transform(self.cam_node).get_mat() * \ + self.cam_lens.get_projection_mat() + + def update(self): + self.target.active = False + self.target_convert.active = False + self.target_blur_v.active = False + self.target_blur_h.active = False + + # Query scheduled tasks + if self._pipeline.task_scheduler.is_scheduled("pssm_distant_shadows"): + + self.target.active = True + + # Reposition camera before we capture the scene + cam_pos = Globals.base.cam.get_pos(Globals.base.render) + self.cam_node.set_pos(cam_pos + self.sun_vector * self.sun_distance) + self.cam_node.look_at(cam_pos) + self.cam_lens.set_film_size(self.clip_size, self.clip_size) + + snap_shadow_map(self.mvp, self.cam_node, self.resolution) + + if self._pipeline.task_scheduler.is_scheduled("pssm_convert_distant_to_esm"): + self.target_convert.active = True + if self._pipeline.task_scheduler.is_scheduled("pssm_blur_distant_vert"): + self.target_blur_v.active = True + if self._pipeline.task_scheduler.is_scheduled("pssm_blur_distant_horiz"): + self.target_blur_h.active = True + + # Only update the MVP as soon as the shadow map is available + self.pta_mvp[0] = self.mvp + + def create(self): + self.camera = Camera("PSSMDistShadowsESM") + self.cam_lens = OrthographicLens() + self.cam_lens.set_film_size(12000, 12000) + self.cam_lens.set_near_far(10.0, self.sun_distance * 2) + self.camera.set_lens(self.cam_lens) + self.cam_node = Globals.base.render.attach_new_node(self.camera) + + self.target = self.create_target("ShadowMap") + self.target.size = self.resolution + self.target.add_depth_attachment(bits=32) + self.target.prepare_render(self.cam_node) + + self.target_convert = self.create_target("ConvertToESM") + self.target_convert.size = self.resolution + self.target_convert.add_color_attachment(bits=(32, 0, 0, 0)) + self.target_convert.prepare_buffer() + self.target_convert.set_shader_input("SourceTex", self.target.depth_tex) + + self.target_blur_v = self.create_target("BlurVert") + self.target_blur_v.size = self.resolution + self.target_blur_v.add_color_attachment(bits=(32, 0, 0, 0)) + self.target_blur_v.prepare_buffer() + self.target_blur_v.set_shader_inputs( + SourceTex=self.target_convert.color_tex, + direction=LVecBase2i(1, 0)) + + self.target_blur_h = self.create_target("BlurHoriz") + self.target_blur_h.size = self.resolution + self.target_blur_h.add_color_attachment(bits=(32, 0, 0, 0)) + self.target_blur_h.prepare_buffer() + self.target_blur_h.set_shader_inputs( + SourceTex=self.target_blur_v.color_tex, + direction=LVecBase2i(0, 1)) + + # Register shadow camera + self._pipeline.tag_mgr.register_camera("shadow", self.camera) + + def reload_shaders(self): + self.target_convert.shader = self.load_plugin_shader("convert_to_esm.frag.glsl") + self.target_blur_v.shader = self.load_plugin_shader("blur_esm.frag.glsl") + self.target_blur_h.shader = self.load_plugin_shader("blur_esm.frag.glsl") + + def set_shader_input(self, *args): + Globals.render.set_shader_input(*args) + + def set_shader_inputs(self, **kwargs): + Globals.render.set_shader_inputs(**kwargs) diff --git a/rpplugins/pssm/pssm_scene_shadow_stage.py b/rpplugins/pssm/pssm_scene_shadow_stage.py new file mode 100644 index 0000000..6bfde17 --- /dev/null +++ b/rpplugins/pssm/pssm_scene_shadow_stage.py @@ -0,0 +1,121 @@ +""" + +RenderPipeline + +Copyright (c) 2014-2016 tobspr + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. + +""" +from __future__ import division + +from panda3d.core import Vec3, Camera, OrthographicLens, PTAMat4, SamplerState + +from rpcore.globals import Globals +from rpcore.render_stage import RenderStage +from rpcore.util.generic import snap_shadow_map + + +class PSSMSceneShadowStage(RenderStage): + + """ This stage creates the shadow map which covers the whole important part + of the scene. This is required because the shadow cascades only cover the + view frustum, but many plugins (VXGI, EnvMaps) require a shadow map. """ + + required_inputs = [] + required_pipes = [] + + def __init__(self, pipeline): + RenderStage.__init__(self, pipeline) + self.resolution = 2048 + self.sun_vector = Vec3(0, 0, 1) + self.sun_distance = 10.0 + self.pta_mvp = PTAMat4.empty_array(1) + self.focus = None + + # Store last focus entirely for the purpose of being able to see + # it in the debugger + self.last_focus = None + + @property + def produced_inputs(self): + return {"PSSMSceneSunShadowMVP": self.pta_mvp} + + @property + def produced_pipes(self): + return {"PSSMSceneSunShadowMapPCF": (self.target.depth_tex, self.make_pcf_state())} + + def make_pcf_state(self): + state = SamplerState() + state.set_minfilter(SamplerState.FT_shadow) + state.set_magfilter(SamplerState.FT_shadow) + return state + + def request_focus(self, focus_point, focus_size): + self.focus = (focus_point, focus_size) + self.last_focus = self.focus + + @property + def mvp(self): + return Globals.base.render.get_transform(self.cam_node).get_mat() * \ + self.cam_lens.get_projection_mat() + + def update(self): + if self._pipeline.task_scheduler.is_scheduled("pssm_scene_shadows"): + if self.focus is None: + # When no focus is set, there is no point in rendering the shadow map + self.target.active = False + else: + focus_point, focus_size = self.focus + + self.cam_lens.set_near_far(0.0, 2 * (focus_size + self.sun_distance)) + self.cam_lens.set_film_size(2 * focus_size, 2 * focus_size) + self.cam_node.set_pos( + focus_point + self.sun_vector * (self.sun_distance + focus_size)) + self.cam_node.look_at(focus_point) + + snap_shadow_map(self.mvp, self.cam_node, self.resolution) + self.target.active = True + self.pta_mvp[0] = self.mvp + + self.focus = None + else: + self.target.active = False + + def create(self): + self.camera = Camera("PSSMSceneSunShadowCam") + self.cam_lens = OrthographicLens() + self.cam_lens.set_film_size(400, 400) + self.cam_lens.set_near_far(100.0, 1800.0) + self.camera.set_lens(self.cam_lens) + self.cam_node = Globals.base.render.attach_new_node(self.camera) + + self.target = self.create_target("ShadowMap") + self.target.size = self.resolution + self.target.add_depth_attachment(bits=32) + self.target.prepare_render(self.cam_node) + + # Register shadow camera + self._pipeline.tag_mgr.register_camera("shadow", self.camera) + + def set_shader_input(self, *args): + Globals.render.set_shader_input(*args) + + def set_shader_inputs(self, **kwargs): + Globals.render.set_shader_inputs(**kwargs) diff --git a/rpplugins/pssm/pssm_shadow_stage.py b/rpplugins/pssm/pssm_shadow_stage.py new file mode 100644 index 0000000..e904533 --- /dev/null +++ b/rpplugins/pssm/pssm_shadow_stage.py @@ -0,0 +1,93 @@ +""" + +RenderPipeline + +Copyright (c) 2014-2016 tobspr + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. + +""" +from __future__ import division +from rplibs.six.moves import range # pylint: disable=import-error + +from panda3d.core import SamplerState + +from rpcore.globals import Globals +from rpcore.render_stage import RenderStage + + +class PSSMShadowStage(RenderStage): + + """ This stage generates the depth-maps used for rendering PSSM """ + + required_inputs = [] + + def __init__(self, pipeline): + RenderStage.__init__(self, pipeline) + self.num_splits = 3 + self.split_resolution = 512 + self.split_regions = [] + + @property + def produced_pipes(self): + return { + "PSSMShadowAtlas": self.target.depth_tex, + "PSSMShadowAtlasPCF": (self.target.depth_tex, self.make_pcf_state()), + } + + def make_pcf_state(self): + state = SamplerState() + state.set_minfilter(SamplerState.FT_shadow) + state.set_magfilter(SamplerState.FT_shadow) + return state + + def get_shadow_tex(self): + return self.target["depth"] + + def create(self): + self.target = self.create_target("ShadowMap") + self.target.size = self.split_resolution * self.num_splits, self.split_resolution + self.target.add_depth_attachment(bits=32) + self.target.prepare_render(None) + + # Remove all unused display regions + internal_buffer = self.target.internal_buffer + internal_buffer.remove_all_display_regions() + internal_buffer.get_display_region(0).set_active(False) + internal_buffer.disable_clears() + + # Set a clear on the buffer instead on all regions + internal_buffer.set_clear_depth(1) + internal_buffer.set_clear_depth_active(True) + + # Prepare the display regions + for i in range(self.num_splits): + region = internal_buffer.make_display_region( + i / self.num_splits, + i / self.num_splits + 1 / self.num_splits, 0, 1) + region.set_sort(25 + i) + region.disable_clears() + region.set_active(True) + self.split_regions.append(region) + + def set_shader_input(self, *args): + Globals.render.set_shader_input(*args) + + def set_shader_inputs(self, **kwargs): + Globals.render.set_shader_inputs(**kwargs) diff --git a/rpplugins/pssm/pssm_stage.py b/rpplugins/pssm/pssm_stage.py new file mode 100644 index 0000000..4f63747 --- /dev/null +++ b/rpplugins/pssm/pssm_stage.py @@ -0,0 +1,65 @@ +""" + +RenderPipeline + +Copyright (c) 2014-2016 tobspr + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. + +""" + +from panda3d.core import Vec4 +from rpcore.render_stage import RenderStage + + +class PSSMStage(RenderStage): + + """ This stage uses the PSSM Shadow map to render the shadows """ + + required_inputs = [] + required_pipes = ["ShadedScene", "PSSMShadowAtlas", "GBuffer", "PSSMShadowAtlasPCF"] + + @property + def produced_pipes(self): + return {"ShadedScene": self.target.color_tex} + + def create(self): + self.enabled = True + self.target_shadows = self.create_target("FilterPSSM") + self.target_shadows.add_color_attachment(bits=(8, 0, 0, 0)) + self.target_shadows.prepare_buffer() + self.target_shadows.color_tex.set_clear_color(Vec4(0)) + + self.target = self.create_target("ApplyPSSMShadows") + self.target.add_color_attachment(bits=16) + self.target.prepare_buffer() + + self.target.set_shader_input("PrefilteredShadows", self.target_shadows.color_tex) + + def set_render_shadows(self, enabled): + """ Toggle whether to render shadows or whether to just pass through + the scene color """ + self.target_shadows.active = enabled + if enabled != self.enabled: + self.target_shadows.color_tex.clear_image() + self.enabled = enabled + + def reload_shaders(self): + self.target_shadows.shader = self.load_plugin_shader("filter_pssm_shadows.frag.glsl") + self.target.shader = self.load_plugin_shader("apply_sun_shading.frag.glsl") diff --git a/rpplugins/pssm/shader/apply_sun_shading.frag.glsl b/rpplugins/pssm/shader/apply_sun_shading.frag.glsl new file mode 100644 index 0000000..de0a866 --- /dev/null +++ b/rpplugins/pssm/shader/apply_sun_shading.frag.glsl @@ -0,0 +1,103 @@ +/** + * + * RenderPipeline + * + * Copyright (c) 2014-2016 tobspr + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + */ + +#version 430 + +#pragma optionNV (unroll all) + +#define USE_TIME_OF_DAY 1 +#pragma include "render_pipeline_base.inc.glsl" +#pragma include "includes/transforms.inc.glsl" +#pragma include "includes/gbuffer.inc.glsl" +#pragma include "includes/lighting_pipeline.inc.glsl" +#pragma include "includes/lights.inc.glsl" +#pragma include "includes/poisson_disk.inc.glsl" +#pragma include "includes/shadows.inc.glsl" +#pragma include "includes/noise.inc.glsl" +#pragma include "includes/skin_shading.inc.glsl" + +out vec4 result; + +uniform GBufferData GBuffer; +uniform sampler2D PrefilteredShadows; +uniform sampler2D ShadedScene; + +void main() { + + vec3 sun_vector = get_sun_vector(); + + // Get current scene color + vec2 texcoord = get_texcoord(); + ivec2 coord = ivec2(gl_FragCoord.xy); + vec4 scene_color = textureLod(ShadedScene, texcoord, 0); + + float prefiltered_shadow = textureLod(PrefilteredShadows, texcoord, 0).x; + + // Early out + if (prefiltered_shadow < 1e-5) { + result = scene_color; + return; + } + + // Get the material data + Material m = unpack_material(GBuffer); + vec3 transmittance = vec3(1); + + // Compute the sun lighting + vec3 v = normalize(MainSceneData.camera_pos - m.position); + vec3 l = sun_vector; + vec3 sun_color = get_sun_color() * get_sun_color_scale(sun_vector); + + { + vec3 reflected_dir = reflect(-v, m.normal); + const float sun_angular_radius = degree_to_radians(0.54); + const float r = sin(sun_angular_radius); // Disk radius + const float d = cos(sun_angular_radius); // Distance to disk + + // Closest point to a disk (since the radius is small, this is + // a good approximation) + float DdotR = dot(sun_vector, reflected_dir); + vec3 S = reflected_dir - DdotR * sun_vector; + l = DdotR < d ? normalize(d * sun_vector + normalize(S) * r) : reflected_dir; + } + + vec3 lighting_result = apply_light(m, v, l, sun_color, 1.0, prefiltered_shadow, transmittance); + + // Backface shading for foliage, not physically correct but a nice + // approximation + float foliage_factor = m.shading_model == SHADING_MODEL_FOLIAGE ? 1.0 : 0.0; + lighting_result += foliage_factor * prefiltered_shadow * sun_color * m.basecolor * 0.12 * saturate(3.0 * dot(v, -sun_vector)); + + #if DEBUG_MODE + lighting_result *= 0; + #endif + + #if MODE_ACTIVE(PSSM_SPLITS) + lighting_result = vec3(prefiltered_shadow); + #endif + + result = max(vec4(0), scene_color) * 1 + vec4(lighting_result, 0); +} diff --git a/rpplugins/pssm/shader/blur_esm.frag.glsl b/rpplugins/pssm/shader/blur_esm.frag.glsl new file mode 100644 index 0000000..7738af6 --- /dev/null +++ b/rpplugins/pssm/shader/blur_esm.frag.glsl @@ -0,0 +1,57 @@ +/** + * + * RenderPipeline + * + * Copyright (c) 2014-2016 tobspr + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + */ + +#version 430 + +#pragma optionNV (unroll all) + +// Blurs the ESM + +#pragma include "render_pipeline_base.inc.glsl" +#pragma include "includes/gaussian_weights.inc.glsl" + +uniform sampler2D SourceTex; +uniform ivec2 direction; + +out float result; + +void main() { + vec2 texsize = textureSize(SourceTex, 0).xy; + vec2 texcoord = gl_FragCoord.xy / texsize; + + float accum = 0; + + // Make sure you also adjust the offsets and weight arrays when you change the + // amount of samples + const int num_steps = 2; + + for (int i = 0; i < num_steps; ++i) { + vec2 offcoord = texcoord + vec2(opt_gaussian_offsets_2[i]) * direction / texsize; + accum += textureLod(SourceTex, offcoord, 0).x * opt_gaussian_weights_2[i]; + } + + result = accum; +} diff --git a/rpplugins/pssm/shader/convert_to_esm.frag.glsl b/rpplugins/pssm/shader/convert_to_esm.frag.glsl new file mode 100644 index 0000000..e0ad044 --- /dev/null +++ b/rpplugins/pssm/shader/convert_to_esm.frag.glsl @@ -0,0 +1,41 @@ +/** + * + * RenderPipeline + * + * Copyright (c) 2014-2016 tobspr + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + */ + +#version 430 + +// Converts a depth texture to a ESM + +uniform sampler2D SourceTex; + +out float result; + +void main() { + ivec2 coord = ivec2(gl_FragCoord.xy); + float depth = texelFetch(SourceTex, coord, 0).x; + + const float esm_factor = 5.0; + result = exp(esm_factor * depth); +} diff --git a/rpplugins/pssm/shader/filter_pssm.inc.glsl b/rpplugins/pssm/shader/filter_pssm.inc.glsl new file mode 100644 index 0000000..1f569a7 --- /dev/null +++ b/rpplugins/pssm/shader/filter_pssm.inc.glsl @@ -0,0 +1,63 @@ +/** + * + * RenderPipeline + * + * Copyright (c) 2014-2016 tobspr + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + */ + + +#pragma once + + +vec2 get_split_coord(vec2 local_coord, int split_index) { + local_coord.x = (local_coord.x + split_index) / float(GET_SETTING(pssm, split_count)); + return local_coord; +} + +float get_shadow(vec2 coord, float refz) { + #if GET_SETTING(pssm, use_pcf) + return textureLod(PSSMShadowAtlasPCF, vec3(coord, refz), 0); + #else + float depth_sample = textureLod(PSSMShadowAtlas, coord, 0).x; + return step(refz, depth_sample); + #endif +} + +float get_fixed_bias(int split) { + return GET_SETTING(pssm, fixed_bias) * 0.001 * (1 + 1.5 * split); +} + +vec3 get_pssm_split_biased_position(vec3 pos, vec3 normal, vec3 sun_vector, int split) { + + // Compute the biased position based on the normal and slope scaled + // bias. + float slope_bias = GET_SETTING(pssm, slope_bias) * 0.1 * (1 + 0.2 * split); + const float normal_bias = GET_SETTING(pssm, normal_bias) * 0.1; + + // Compute the biased position based on the normal and slope scaled + // bias. + vec3 biased_pos = get_biased_position(pos, slope_bias, normal_bias, normal, sun_vector); + + return biased_pos; +} + + diff --git a/rpplugins/pssm/shader/filter_pssm_shadows.frag.glsl b/rpplugins/pssm/shader/filter_pssm_shadows.frag.glsl new file mode 100644 index 0000000..88c54e8 --- /dev/null +++ b/rpplugins/pssm/shader/filter_pssm_shadows.frag.glsl @@ -0,0 +1,291 @@ +/** + * + * RenderPipeline + * + * Copyright (c) 2014-2016 tobspr + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + */ + +#version 430 + +#pragma optionNV (unroll all) + +#define USE_TIME_OF_DAY 1 +#pragma include "render_pipeline_base.inc.glsl" +#pragma include "includes/transforms.inc.glsl" +#pragma include "includes/gbuffer.inc.glsl" +#pragma include "includes/sampling_sequences.inc.glsl" +#pragma include "includes/shadows.inc.glsl" +#pragma include "includes/noise.inc.glsl" + +out float result; + +uniform GBufferData GBuffer; + +#if GET_SETTING(pssm, use_pcf) + uniform sampler2DShadow PSSMShadowAtlasPCF; +#endif + +uniform sampler2D PSSMShadowAtlas; + +uniform mat4 pssm_mvps[GET_SETTING(pssm, split_count)]; +uniform vec2 pssm_nearfar[GET_SETTING(pssm, split_count)]; + +#if GET_SETTING(pssm, use_distant_shadows) + uniform mat4 PSSMDistSunShadowMapMVP; + uniform sampler2D PSSMDistSunShadowMap; +#endif + +#pragma include "filter_pssm.inc.glsl" + + +void main() { + vec3 sun_vector = get_sun_vector(); + + // Get current scene color + vec2 texcoord = get_texcoord(); + ivec2 coord = ivec2(gl_FragCoord.xy); + + // Get the material data + Material m = unpack_material(GBuffer); + + // Early out, different optimizations + bool early_out = is_skybox(m) || sun_vector.z < SUN_VECTOR_HORIZON; + early_out = early_out || + (m.shading_model != SHADING_MODEL_FOLIAGE && dot(m.normal, sun_vector) <= 1e-7); + + if (early_out) { + result = 0.0; + return; + } + + // Variables to accumulate the shadows + float shadow_factor = 1.0; + + // Compute distant shadows + #if GET_SETTING(pssm, use_distant_shadows) + // #if 0 + { + // Compute the biased position based on the normal and slope scaled + // bias. + const float slope_bias = GET_SETTING(pssm, slope_bias) * 0.1 * 2; + const float normal_bias = GET_SETTING(pssm, normal_bias) * 0.1; + const float fixed_bias = 0.0005; + vec3 biased_pos = get_biased_position(m.position, + slope_bias, normal_bias, m.normal, sun_vector); + vec3 proj = project(PSSMDistSunShadowMapMVP, biased_pos); + proj.z -= fixed_bias; + + if (!out_of_unit_box(proj)) { + const float esm_factor = 5.0; + float depth_sample = textureLod(PSSMDistSunShadowMap, proj.xy, 0).x; + shadow_factor = saturate(exp(-esm_factor * proj.z) * depth_sample); + shadow_factor = pow(shadow_factor, 1e2); + } + } + #endif + + // Find lowest split in range + const int split_count = GET_SETTING(pssm, split_count); + int split = 99; + float border_bias = 0.5 - (0.5 / (1.0 + GET_SETTING(pssm, border_bias))); + + // Find the first matching split + for (int i = 0; i < split_count; ++i) { + vec3 coord = project(pssm_mvps[i], m.position); + if (coord.x >= border_bias && coord.x <= 1-border_bias && + coord.y >= border_bias && coord.y <= 1-border_bias && + coord.z >= 0.0 && coord.z <= 1.0) { + split = i; + break; + } + } + + // Compute the shadowing factor + if (split < GET_SETTING(pssm, split_count)) { + + // Get the MVP for the current split + mat4 mvp = pssm_mvps[split]; + + + float rotation = interleaved_gradient_noise( + gl_FragCoord.xy + (MainSceneData.frame_index % 4) / 3.0 ); + + // XXX: Pretty noisy + // mat2 rotation_mat = make_rotation_mat(rotation); + mat2 rotation_mat = mat2(1, 0, 0, 1); + + const float filter_radius = GET_SETTING(pssm, filter_radius) / + GET_SETTING(pssm, resolution); + + vec3 biased_pos = get_pssm_split_biased_position(m.position, m.normal, sun_vector, split); + + // Project the current pixel to the view of the light + vec3 projected = project(mvp, biased_pos); + vec2 projected_coord = get_split_coord(projected.xy, split); + + // Compute the fixed bias + float ref_depth = projected.z - get_fixed_bias(split); + + // Find filter size + vec2 filter_size = find_filter_size(mvp, sun_vector, filter_radius); + + // Increase filter size in the distance, to get better cache usage + filter_size *= (1.0 + 10.5 * distance(m.position, MainSceneData.camera_pos) / 100.0); + // vec2 filter_size = vec2(0.5 * filter_radius) * (1 / (1 + 0.7 * split)); + + #if GET_SETTING(pssm, use_pcss) + + { + /* + + PCSS Kernel + + Scan the region of the pixel for blockers, penumbra size is + amount of blockers compared to non-blockers. + + */ + + float num_blockers = 0.0; + float sum_blockers = 0.0; + + START_ITERATE_SEQUENCE(pssm, pcss_sequence, vec2 offset) + + offset = rotation_mat * offset; + + // Find depth at sample location + float sampled_depth = textureLod(PSSMShadowAtlas, + projected_coord + offset * filter_size * 4.0, 0).x; + + // Compare the depth with the pixel depth, in case its smaller, + // we found a blocker + float factor = step(sampled_depth, ref_depth); + num_blockers += factor; + sum_blockers += sampled_depth * factor; + + END_ITERATE_SEQUENCE(); + + // Examine ratio between blockers and non-blockers + float avg_blocker_depth = sum_blockers / num_blockers; + + // Penumbra size also takes average blocker depth into account + float penumbra_size = max(GET_SETTING(pssm, pcss_min_penumbra_size) * 0.03, ref_depth - avg_blocker_depth) / + ref_depth * GET_SETTING(pssm, pcss_penumbra_size); + + // Apply penumbra size + filter_size *= penumbra_size; + } + + #endif + + float local_shadow_factor = 0.0; + + + // Do the actual shadow map filtering + START_ITERATE_SEQUENCE(pssm, filter_sequence, vec2 offset) + + local_shadow_factor += get_shadow( + projected_coord + (rotation_mat * offset) * filter_size, ref_depth); + + END_ITERATE_SEQUENCE(); + NORMALIZE_SEQUENCE(pssm, filter_sequence, local_shadow_factor); + + + if (split >= GET_SETTING(pssm, split_count) - 1) { + // Smoothly fade in distant shadows + const float fade_size = 0.09; + const float depth_fade = 0.01; + float cascade_factor = 1; + cascade_factor *= saturate(projected.x / fade_size); + cascade_factor *= saturate(projected.y / fade_size); + cascade_factor *= saturate((1 - projected.x) / fade_size); + cascade_factor *= saturate((1 - projected.y) / fade_size); + cascade_factor *= saturate(projected.z / depth_fade); + cascade_factor *= saturate((1 - projected.z) / depth_fade); + shadow_factor = mix(shadow_factor, local_shadow_factor, cascade_factor); + } else { + shadow_factor = local_shadow_factor; + } + + // OPTIONAL: Transmittance - however this looks a bit buggy right now - + // might look better on surfaces like ice and so on + + // #if HAVE_PLUGIN(skin_shading) + // // Get the current split near and far planes + // vec2 split_near_far = pssm_nearfar[split]; + + // // Bias to move the position "into" the object, prevents artifacts + // float skin_border_factor = 0.025; + + // // Project the biased position to light space + // vec3 projected_skin = project(mvp, m.position - m.normal * skin_border_factor); + // vec2 projected_skin_coord = get_split_coord(projected_skin.xy, split); + // float skin_ref_depth = projected_skin.z; + + // // Get the shadow sample + // float shadow_sample = textureLod(PSSMShadowAtlas, projected_skin_coord, 0).x; + + // // Reconstruct intersection position + // // TODO: This is totally slow! Pass it as input + // mat4 inverse_mvp = inverse(mvp); + // vec3 intersection_pos = calculate_surface_pos_ortho(shadow_sample, projected_skin.xy, split_near_far.x, split_near_far.y, inverse_mvp); + + // // Get the distance the light traveled through the medium + // float distance_through_medium = distance(m.position, intersection_pos.xyz); + + // // TODO: Maybe we can remove this branch + // if (skin_ref_depth < shadow_sample) distance_through_medium = 0.0; + + // // Fetch the skin transmittance + // // transmittance = skin_transmittance(distance_through_medium); + // transmittance = vec3(1); + + // #endif + + } + + // Raymarch clouds + // CloudVoxels + #if HAVE_PLUGIN(clouds) + { + // vec3 start_coord = vec3(m.position.xy / 800.0, 0); + // vec3 end_coord = start_coord + vec3(0, 0, 1); + // const int num_steps = 32; + // vec3 step_dir = (end_coord - start_coord) / num_steps; + // float cloud_factor = 0.0; + // for (int i = 0; i < num_steps; ++i) { + // float cloud_sample = textureLod(CloudVoxels, start_coord, 0).w; + // cloud_factor += cloud_sample; + // start_coord += step_dir; + // } + // cloud_factor /= num_steps; + // cloud_factor *= 10.0; + // shadow_factor *= saturate(1.0 - cloud_factor); + } + #endif + + #if MODE_ACTIVE(PSSM_SPLITS) + float factor = float(split) / GET_SETTING(pssm, split_count); + shadow_factor = saturate(shadow_factor+0.5) * factor; + #endif + + result = shadow_factor; +} diff --git a/rpplugins/scattering/__init__.py b/rpplugins/scattering/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/rpplugins/scattering/config.yaml b/rpplugins/scattering/config.yaml new file mode 100644 index 0000000..88358b1 --- /dev/null +++ b/rpplugins/scattering/config.yaml @@ -0,0 +1,142 @@ + +settings: !!omap + + - scattering_method: + type: enum + values: ["eric_bruneton", "hosek_wilkie"] + default: "eric_bruneton" + label: Scattering Method + description: > + Chooses the scattering algorithm. eric_bruneton is the Precomputed + Atmospheric Scattering method proposed by Eric Bruneton. hosek_wilkie + denotes the sky model proposed by Lukas Hosek and Alexander Wilkie. + + - ground_reflectance: + display_if: {scattering_method: "eric_bruneton"} + type: float + range: [0.01, 1.0] + default: 0.1 + shader_runtime: true + label: Ground Reflectance + description: > + Average ground reflectance, controls how much light the earth reflects. + + - rayleigh_factor: + display_if: {scattering_method: "eric_bruneton"} + type: float + range: [0.05, 1.0] + default: 0.5 + shader_runtime: true + label: Rayleigh factor + description: > + Controls the the rayleigh factor, lower values cause a more bluish sky. + + - rayleigh_height_scale: + display_if: {scattering_method: "eric_bruneton"} + type: float + range: [1.0, 16.0] + default: 8.0 + shader_runtime: true + label: Rayleigh height scale + description: > + Rayleigh height scale, higher values cause a more bluish sky. + + - mie_height_scale: + display_if: {scattering_method: "eric_bruneton"} + type: float + range: [0.5, 5.0] + default: 1.3 + shader_runtime: true + label: Mie height scale + description: > + Mie height scale, higher values cause a more reddish sky. + + - mie_phase_factor: + display_if: {scattering_method: "eric_bruneton"} + type: float + range: [0.1, 0.9999] + default: 0.3 + shader_runtime: true + label: Mie Phase + description: > + Mie phase factor, this controls the apperance of the sun highlight + in the sky, higher values produce a smaller (but brighter) sun-shape. + + - beta_mie_scattering: + display_if: {scattering_method: "eric_bruneton"} + type: float + range: [1, 30] + default: 4 + shader_runtime: true + label: Beta Mie Scattering + description: > + Beta Mie Scattering factor + + - enable_godrays: + type: bool + default: false + label: Enable Godrays (experimental!) + description: > + This enables the experimental support for godrays. + + - atmosphere_start: + type: float + range: [25.0, 2000.0] + default: 100 + label: Atmosphere Start + shader_runtime: true + description: > + Start of the the atmosphere, this controls where + z = 0 lies inside the atmosphere. A value of 0 would mean + sea level for example. + + +daytime_settings: !!omap + + - sun_intensity: + type: scalar + unit: klux + range: [0.0, 150.0] + default: 100.0 + label: Sun Intensity + description: > + Controls the intensity of the sun in K-LUX (1000 lux) + + - sun_color: + type: color + default: [126, 255, 100] + label: Sun Color + description: > + Color of the sun, only affects direct lighting, has no impact on scattering. + + - sun_azimuth: + type: scalar + unit: degree + range: [0.0, 360.0] + default: 180 + label: Sun Azimuth + description: > + Horizontal angle of the sun, this basically controls from which + direction the sun comes + + - sun_altitude: + type: scalar + unit: degree + range: [-60, 60.0] + default: 30 + label: Sun Altidude + description: > + Vertical angle of the sun, this controls the height of the sun. + + - extinction: + type: scalar + unit: meter + range: [0.5, 50000.0] + default: 2000 + label: Extinction + logarithmic_factor: 2.0 + description: > + Extinction factor, this controls how much the fog darkens the + objects in the distance. + + diff --git a/rpplugins/scattering/godray_stage.py b/rpplugins/scattering/godray_stage.py new file mode 100644 index 0000000..82797ba --- /dev/null +++ b/rpplugins/scattering/godray_stage.py @@ -0,0 +1,49 @@ +""" + +RenderPipeline + +Copyright (c) 2014-2016 tobspr + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. + +""" + +from __future__ import division + +from rpcore.render_stage import RenderStage + + +class GodrayStage(RenderStage): + + """ This stage renders the suns godrays """ + + required_inputs = [] + required_pipes = ["ShadedScene", "GBuffer"] + + @property + def produced_pipes(self): + return {"ShadedScene": self._target.color_tex} + + def create(self): + self._target = self.create_target("ComputeGodrays") + self._target.add_color_attachment(bits=16) + self._target.prepare_buffer() + + def reload_shaders(self): + self._target.shader = self.load_plugin_shader("compute_godrays.frag.glsl") diff --git a/rpplugins/scattering/plugin.py b/rpplugins/scattering/plugin.py new file mode 100644 index 0000000..e864f1a --- /dev/null +++ b/rpplugins/scattering/plugin.py @@ -0,0 +1,89 @@ +""" + +RenderPipeline + +Copyright (c) 2014-2016 tobspr + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. + +""" + +import math + +from panda3d.core import Vec3 + +from rpcore.pluginbase.base_plugin import BasePlugin + +from .scattering_stage import ScatteringStage +from .scattering_envmap_stage import ScatteringEnvmapStage +from .godray_stage import GodrayStage + + +class Plugin(BasePlugin): + name = "Atmospheric Scattering" + author = "tobspr " + description = ("This plugin adds support for Atmospheric Scattering, and a " + "single sun, based on the work from Eric Bruneton. It also " + "adds support for atmospheric fog.") + version = "1.2" + + def on_pipeline_created(self): + self.scattering_model.load() + self.scattering_model.compute() + + def on_stage_setup(self): + self.display_stage = self.create_stage(ScatteringStage) + self.envmap_stage = self.create_stage(ScatteringEnvmapStage) + + if self.get_setting("enable_godrays"): + self.godray_stage = self.create_stage(GodrayStage) + + # Load scattering method + method = self.get_setting("scattering_method") + + self.debug("Loading scattering method for '" + method + "'") + + if method == "eric_bruneton": + from .scattering_methods import ScatteringMethodEricBruneton + self.scattering_model = ScatteringMethodEricBruneton(self) + elif method == "hosek_wilkie": + from .scattering_methods import ScatteringMethodHosekWilkie + self.scattering_model = ScatteringMethodHosekWilkie(self) # noqa # pylint: disable=redefined-variable-type + else: + self.error("Unrecognized scattering method!") + + @property + def sun_vector(self): + """ Returns the sun vector """ + sun_altitude = self.get_daytime_setting("sun_altitude") + sun_azimuth = self.get_daytime_setting("sun_azimuth") + theta = (90 - sun_altitude) / 180.0 * math.pi + phi = sun_azimuth / 180.0 * math.pi + sun_vector = Vec3( + math.sin(theta) * math.cos(phi), + math.sin(theta) * math.sin(phi), + math.cos(theta)) + return sun_vector + + def on_pre_render_update(self): + self.envmap_stage.active = self._pipeline.task_scheduler.is_scheduled( + "scattering_update_envmap") + + def on_shader_reload(self): + self.scattering_model.compute() diff --git a/rpplugins/scattering/resources/hosek_wilkie_scattering/.gitignore b/rpplugins/scattering/resources/hosek_wilkie_scattering/.gitignore new file mode 100644 index 0000000..a2c9784 --- /dev/null +++ b/rpplugins/scattering/resources/hosek_wilkie_scattering/.gitignore @@ -0,0 +1,19 @@ + +# Prefab gitignore which can be used by the user to ignore the files generated +# by the module builder + +*.pyd +*.pyc +*.so +*.pdb + +# Various output names +win_*/ +linux_*/ +source/interrogate* + +# Source and script files +scripts/ +CMakeLists.txt +build.py +LICENSE diff --git a/rpplugins/scattering/resources/hosek_wilkie_scattering/README.md b/rpplugins/scattering/resources/hosek_wilkie_scattering/README.md new file mode 100644 index 0000000..638ea42 --- /dev/null +++ b/rpplugins/scattering/resources/hosek_wilkie_scattering/README.md @@ -0,0 +1,70 @@ + +# Hosek & Wilkie Skylight Model + +This uses the precomputed scattering model proposed by: + +http://cgg.mff.cuni.cz/projects/SkylightModelling/ + +It generates a LUT evaluating the model offline, which then +will be used in the scattering shader later on. + +### Usage + +In case you want to generate the lookup texture yourself, you need to first +compile the code (see below), and then run the program. +The program will ask you for a turbidity and ground albedo, using +`turbidity=3.0` and `groundAlbedo=0.1` is a good starting point. + +### Compilation + +Just run `python update_module_builder.py`, after that you should see a `build.py`, +run it with `python build.py` to generate the module. When the compilation succeeded, +run `python generate_table.py` to generate the LUT. After that you can use the +scattering method in the pipeline. + + +### License + +``` + + "An Analytic Model for Full Spectral Sky-Dome Radiance" + "Adding a Solar Radiance Function to the Hosek Skylight Model" + + both by + + Lukas Hosek and Alexander Wilkie + Charles University in Prague, Czech Republic + + Version: 1.4a, February 22nd, 2013 + + +This source is published under the following 3-clause BSD license. + +Copyright (c) 2012, Lukas Hosek and Alexander Wilkie +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + + * Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + * None of the names of the contributors may be used to endorse or promote + products derived from this software without specific prior written + permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY +DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND +ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +``` + diff --git a/rpplugins/scattering/resources/hosek_wilkie_scattering/config.ini b/rpplugins/scattering/resources/hosek_wilkie_scattering/config.ini new file mode 100644 index 0000000..e31ca54 --- /dev/null +++ b/rpplugins/scattering/resources/hosek_wilkie_scattering/config.ini @@ -0,0 +1,4 @@ +generate_pdb=0 +module_name=HSWKScattering +use_lib_eigen=1 +vc_version=Visual Studio 10 2010 diff --git a/rpplugins/scattering/resources/hosek_wilkie_scattering/generate_table.py b/rpplugins/scattering/resources/hosek_wilkie_scattering/generate_table.py new file mode 100644 index 0000000..16aac24 --- /dev/null +++ b/rpplugins/scattering/resources/hosek_wilkie_scattering/generate_table.py @@ -0,0 +1,27 @@ +""" + +RenderPipeline + +Copyright (c) 2014-2016 tobspr + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. + +""" +import HSWKScattering +HSWKScattering.generate_table() diff --git a/rpplugins/scattering/resources/hosek_wilkie_scattering/source/ArHosekSkyModel.cpp b/rpplugins/scattering/resources/hosek_wilkie_scattering/source/ArHosekSkyModel.cpp new file mode 100644 index 0000000..7aa517b --- /dev/null +++ b/rpplugins/scattering/resources/hosek_wilkie_scattering/source/ArHosekSkyModel.cpp @@ -0,0 +1,503 @@ +/* +This source is published under the following 3-clause BSD license. + +Copyright (c) 2012 - 2013, Lukas Hosek and Alexander Wilkie +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + + * Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + * None of the names of the contributors may be used to endorse or promote + products derived from this software without specific prior written + permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY +DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND +ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +*/ + +/* ============================================================================ + +This file is part of a sample implementation of the analytical skylight and +solar radiance models presented in the SIGGRAPH 2012 paper + + + "An Analytic Model for Full Spectral Sky-Dome Radiance" + +and the 2013 IEEE CG&A paper + + "Adding a Solar Radiance Function to the Hosek Skylight Model" + + both by + + Lukas Hosek and Alexander Wilkie + Charles University in Prague, Czech Republic + + + Version: 1.4a, February 22nd, 2013 + +Version history: + +1.4a February 22nd, 2013 + Removed unnecessary and counter-intuitive solar radius parameters + from the interface of the colourspace sky dome initialisation functions. + +1.4 February 11th, 2013 + Fixed a bug which caused the relative brightness of the solar disc + and the sky dome to be off by a factor of about 6. The sun was too + bright: this affected both normal and alien sun scenarios. The + coefficients of the solar radiance function were changed to fix this. + +1.3 January 21st, 2013 (not released to the public) + Added support for solar discs that are not exactly the same size as + the terrestrial sun. Also added support for suns with a different + emission spectrum ("Alien World" functionality). + +1.2a December 18th, 2012 + Fixed a mistake and some inaccuracies in the solar radiance function + explanations found in ArHosekSkyModel.h. The actual source code is + unchanged compared to version 1.2. + +1.2 December 17th, 2012 + Native RGB data and a solar radiance function that matches the turbidity + conditions were added. + +1.1 September 2012 + The coefficients of the spectral model are now scaled so that the output + is given in physical units: W / (m^-2 * sr * nm). Also, the output of the + XYZ model is now no longer scaled to the range [0...1]. Instead, it is + the result of a simple conversion from spectral data via the CIE 2 degree + standard observer matching functions. Therefore, after multiplication + with 683 lm / W, the Y channel now corresponds to luminance in lm. + +1.0 May 11th, 2012 + Initial release. + + +Please visit http://cgg.mff.cuni.cz/projects/SkylightModelling/ to check if +an updated version of this code has been published! + +============================================================================ */ + +/* + +All instructions on how to use this code are in the accompanying header file. + +*/ + +#include "ArHosekSkyModel.h" +#include "ArHosekSkyModelData_CIEXYZ.data" +#include "ArHosekSkyModelData_RGB.data" +#include +#include +#include +#include + +// Some macro definitions that occur elsewhere in ART, and that have to be +// replicated to make this a stand-alone module. + +#ifndef NIL +#define NIL 0 +#endif + +#ifndef MATH_PI +#define MATH_PI 3.141592653589793 +#endif + +#ifndef MATH_DEG_TO_RAD +#define MATH_DEG_TO_RAD ( MATH_PI / 180.0 ) +#endif + +#ifndef MATH_RAD_TO_DEG +#define MATH_RAD_TO_DEG ( 180.0 / MATH_PI ) +#endif + +#ifndef DEGREES +#define DEGREES * MATH_DEG_TO_RAD +#endif + +#ifndef TERRESTRIAL_SOLAR_RADIUS +#define TERRESTRIAL_SOLAR_RADIUS ( ( 0.51 DEGREES ) / 2.0 ) +#endif + +#ifndef ALLOC +#define ALLOC(_struct) ((_struct *)malloc(sizeof(_struct))) +#endif + +// internal definitions + +typedef double *ArHosekSkyModel_Dataset; +typedef double *ArHosekSkyModel_Radiance_Dataset; + +// internal functions + +void ArHosekSkyModel_CookConfiguration( + ArHosekSkyModel_Dataset dataset, + ArHosekSkyModelConfiguration config, + double turbidity, + double albedo, + double solar_elevation + ) +{ + double * elev_matrix; + + int int_turbidity = (int)turbidity; + double turbidity_rem = turbidity - (double)int_turbidity; + + solar_elevation = pow(solar_elevation / (MATH_PI / 2.0), (1.0 / 3.0)); + + // alb 0 low turb + + elev_matrix = dataset + ( 9 * 6 * (int_turbidity-1) ); + + + for( unsigned int i = 0; i < 9; ++i ) + { + //(1-t).^3* A1 + 3*(1-t).^2.*t * A2 + 3*(1-t) .* t .^ 2 * A3 + t.^3 * A4; + config[i] = + (1.0-albedo) * (1.0 - turbidity_rem) + * ( pow(1.0-solar_elevation, 5.0) * elev_matrix[i] + + 5.0 * pow(1.0-solar_elevation, 4.0) * solar_elevation * elev_matrix[i+9] + + 10.0*pow(1.0-solar_elevation, 3.0)*pow(solar_elevation, 2.0) * elev_matrix[i+18] + + 10.0*pow(1.0-solar_elevation, 2.0)*pow(solar_elevation, 3.0) * elev_matrix[i+27] + + 5.0*(1.0-solar_elevation)*pow(solar_elevation, 4.0) * elev_matrix[i+36] + + pow(solar_elevation, 5.0) * elev_matrix[i+45]); + } + + // alb 1 low turb + elev_matrix = dataset + (9*6*10 + 9*6*(int_turbidity-1)); + for(unsigned int i = 0; i < 9; ++i) + { + //(1-t).^3* A1 + 3*(1-t).^2.*t * A2 + 3*(1-t) .* t .^ 2 * A3 + t.^3 * A4; + config[i] += + (albedo) * (1.0 - turbidity_rem) + * ( pow(1.0-solar_elevation, 5.0) * elev_matrix[i] + + 5.0 * pow(1.0-solar_elevation, 4.0) * solar_elevation * elev_matrix[i+9] + + 10.0*pow(1.0-solar_elevation, 3.0)*pow(solar_elevation, 2.0) * elev_matrix[i+18] + + 10.0*pow(1.0-solar_elevation, 2.0)*pow(solar_elevation, 3.0) * elev_matrix[i+27] + + 5.0*(1.0-solar_elevation)*pow(solar_elevation, 4.0) * elev_matrix[i+36] + + pow(solar_elevation, 5.0) * elev_matrix[i+45]); + } + + if(int_turbidity == 10) + return; + + // alb 0 high turb + elev_matrix = dataset + (9*6*(int_turbidity)); + for(unsigned int i = 0; i < 9; ++i) + { + //(1-t).^3* A1 + 3*(1-t).^2.*t * A2 + 3*(1-t) .* t .^ 2 * A3 + t.^3 * A4; + config[i] += + (1.0-albedo) * (turbidity_rem) + * ( pow(1.0-solar_elevation, 5.0) * elev_matrix[i] + + 5.0 * pow(1.0-solar_elevation, 4.0) * solar_elevation * elev_matrix[i+9] + + 10.0*pow(1.0-solar_elevation, 3.0)*pow(solar_elevation, 2.0) * elev_matrix[i+18] + + 10.0*pow(1.0-solar_elevation, 2.0)*pow(solar_elevation, 3.0) * elev_matrix[i+27] + + 5.0*(1.0-solar_elevation)*pow(solar_elevation, 4.0) * elev_matrix[i+36] + + pow(solar_elevation, 5.0) * elev_matrix[i+45]); + } + + // alb 1 high turb + elev_matrix = dataset + (9*6*10 + 9*6*(int_turbidity)); + for(unsigned int i = 0; i < 9; ++i) + { + //(1-t).^3* A1 + 3*(1-t).^2.*t * A2 + 3*(1-t) .* t .^ 2 * A3 + t.^3 * A4; + config[i] += + (albedo) * (turbidity_rem) + * ( pow(1.0-solar_elevation, 5.0) * elev_matrix[i] + + 5.0 * pow(1.0-solar_elevation, 4.0) * solar_elevation * elev_matrix[i+9] + + 10.0*pow(1.0-solar_elevation, 3.0)*pow(solar_elevation, 2.0) * elev_matrix[i+18] + + 10.0*pow(1.0-solar_elevation, 2.0)*pow(solar_elevation, 3.0) * elev_matrix[i+27] + + 5.0*(1.0-solar_elevation)*pow(solar_elevation, 4.0) * elev_matrix[i+36] + + pow(solar_elevation, 5.0) * elev_matrix[i+45]); + } +} + +double ArHosekSkyModel_CookRadianceConfiguration( + ArHosekSkyModel_Radiance_Dataset dataset, + double turbidity, + double albedo, + double solar_elevation + ) +{ + double* elev_matrix; + + int int_turbidity = (int)turbidity; + double turbidity_rem = turbidity - (double)int_turbidity; + double res; + solar_elevation = pow(solar_elevation / (MATH_PI / 2.0), (1.0 / 3.0)); + + // alb 0 low turb + elev_matrix = dataset + (6*(int_turbidity-1)); + //(1-t).^3* A1 + 3*(1-t).^2.*t * A2 + 3*(1-t) .* t .^ 2 * A3 + t.^3 * A4; + res = (1.0-albedo) * (1.0 - turbidity_rem) * + ( pow(1.0-solar_elevation, 5.0) * elev_matrix[0] + + 5.0*pow(1.0-solar_elevation, 4.0)*solar_elevation * elev_matrix[1] + + 10.0*pow(1.0-solar_elevation, 3.0)*pow(solar_elevation, 2.0) * elev_matrix[2] + + 10.0*pow(1.0-solar_elevation, 2.0)*pow(solar_elevation, 3.0) * elev_matrix[3] + + 5.0*(1.0-solar_elevation)*pow(solar_elevation, 4.0) * elev_matrix[4] + + pow(solar_elevation, 5.0) * elev_matrix[5]); + + // alb 1 low turb + elev_matrix = dataset + (6*10 + 6*(int_turbidity-1)); + //(1-t).^3* A1 + 3*(1-t).^2.*t * A2 + 3*(1-t) .* t .^ 2 * A3 + t.^3 * A4; + res += (albedo) * (1.0 - turbidity_rem) * + ( pow(1.0-solar_elevation, 5.0) * elev_matrix[0] + + 5.0*pow(1.0-solar_elevation, 4.0)*solar_elevation * elev_matrix[1] + + 10.0*pow(1.0-solar_elevation, 3.0)*pow(solar_elevation, 2.0) * elev_matrix[2] + + 10.0*pow(1.0-solar_elevation, 2.0)*pow(solar_elevation, 3.0) * elev_matrix[3] + + 5.0*(1.0-solar_elevation)*pow(solar_elevation, 4.0) * elev_matrix[4] + + pow(solar_elevation, 5.0) * elev_matrix[5]); + if(int_turbidity == 10) + return res; + + // alb 0 high turb + elev_matrix = dataset + (6*(int_turbidity)); + //(1-t).^3* A1 + 3*(1-t).^2.*t * A2 + 3*(1-t) .* t .^ 2 * A3 + t.^3 * A4; + res += (1.0-albedo) * (turbidity_rem) * + ( pow(1.0-solar_elevation, 5.0) * elev_matrix[0] + + 5.0*pow(1.0-solar_elevation, 4.0)*solar_elevation * elev_matrix[1] + + 10.0*pow(1.0-solar_elevation, 3.0)*pow(solar_elevation, 2.0) * elev_matrix[2] + + 10.0*pow(1.0-solar_elevation, 2.0)*pow(solar_elevation, 3.0) * elev_matrix[3] + + 5.0*(1.0-solar_elevation)*pow(solar_elevation, 4.0) * elev_matrix[4] + + pow(solar_elevation, 5.0) * elev_matrix[5]); + + // alb 1 high turb + elev_matrix = dataset + (6*10 + 6*(int_turbidity)); + //(1-t).^3* A1 + 3*(1-t).^2.*t * A2 + 3*(1-t) .* t .^ 2 * A3 + t.^3 * A4; + res += (albedo) * (turbidity_rem) * + ( pow(1.0-solar_elevation, 5.0) * elev_matrix[0] + + 5.0*pow(1.0-solar_elevation, 4.0)*solar_elevation * elev_matrix[1] + + 10.0*pow(1.0-solar_elevation, 3.0)*pow(solar_elevation, 2.0) * elev_matrix[2] + + 10.0*pow(1.0-solar_elevation, 2.0)*pow(solar_elevation, 3.0) * elev_matrix[3] + + 5.0*(1.0-solar_elevation)*pow(solar_elevation, 4.0) * elev_matrix[4] + + pow(solar_elevation, 5.0) * elev_matrix[5]); + return res; +} + +double ArHosekSkyModel_GetRadianceInternal( + ArHosekSkyModelConfiguration configuration, + double theta, + double gamma + ) +{ + const double expM = exp(configuration[4] * gamma); + const double rayM = cos(gamma)*cos(gamma); + const double mieM = (1.0 + cos(gamma)*cos(gamma)) / pow((1.0 + configuration[8]*configuration[8] - 2.0*configuration[8]*cos(gamma)), 1.5); + const double zenith = sqrt(cos(theta)); + + return (1.0 + configuration[0] * exp(configuration[1] / (cos(theta) + 0.01))) * + (configuration[2] + configuration[3] * expM + configuration[5] * rayM + configuration[6] * mieM + configuration[7] * zenith); +} + + +// 'blackbody_scaling_factor' +// +// Fudge factor, computed in Mathematica, to scale the results of the +// following function to match the solar radiance spectrum used in the +// original simulation. The scaling is done so their integrals over the +// range from 380.0 to 720.0 nanometers match for a blackbody temperature +// of 5800 K. +// Which leaves the original spectrum being less bright overall than the 5.8k +// blackbody radiation curve if the ultra-violet part of the spectrum is +// also considered. But the visible brightness should be very similar. + +const double blackbody_scaling_factor = 3.19992 * 10E-11; + +// 'art_blackbody_dd_value()' function +// +// Blackbody radiance, Planck's formula + +double art_blackbody_dd_value( + const double temperature, + const double lambda + ) +{ + double c1 = 3.74177 * 10E-17; + double c2 = 0.0143878; + double value; + + value = ( c1 / ( pow( lambda, 5.0 ) ) ) + * ( 1.0 / ( exp( c2 / ( lambda * temperature ) ) - 1.0 ) ); + + return value; +} + +// 'originalSolarRadianceTable[]' +// +// The solar spectrum incident at the top of the atmosphere, as it was used +// in the brute force path tracer that generated the reference results the +// model was fitted to. We need this as the yardstick to compare any altered +// Blackbody emission spectra for alien world stars to. + +// This is just the data from the Preetham paper, extended into the UV range. + +const double originalSolarRadianceTable[] = +{ + 7500.0, + 12500.0, + 21127.5, + 26760.5, + 30663.7, + 27825.0, + 25503.8, + 25134.2, + 23212.1, + 21526.7, + 19870.8 +}; + + +void arhosekskymodelstate_free( + ArHosekSkyModelState * state + ) +{ + free(state); +} + +double arhosekskymodel_radiance( + ArHosekSkyModelState * state, + double theta, + double gamma, + double wavelength + ) +{ + /// @@@ Added explicit cast to int to avoid warning + int low_wl = (int)((wavelength - 320.0 ) / 40.0); + + if ( low_wl < 0 || low_wl >= 11 ) + return 0.0f; + + double interp = fmod((wavelength - 320.0 ) / 40.0, 1.0); + + double val_low = + ArHosekSkyModel_GetRadianceInternal( + state->configs[low_wl], + theta, + gamma + ) + * state->radiances[low_wl] + * state->emission_correction_factor_sky[low_wl]; + + if ( interp < 1e-6 ) + return val_low; + + double result = ( 1.0 - interp ) * val_low; + + if ( low_wl+1 < 11 ) + { + result += + interp + * ArHosekSkyModel_GetRadianceInternal( + state->configs[low_wl+1], + theta, + gamma + ) + * state->radiances[low_wl+1] + * state->emission_correction_factor_sky[low_wl+1]; + } + + return result; +} + + +// xyz and rgb versions + +ArHosekSkyModelState * arhosek_xyz_skymodelstate_alloc_init( + const double turbidity, + const double albedo, + const double elevation + ) +{ + ArHosekSkyModelState * state = ALLOC(ArHosekSkyModelState); + + state->solar_radius = TERRESTRIAL_SOLAR_RADIUS; + state->turbidity = turbidity; + state->albedo = albedo; + state->elevation = elevation; + + for( unsigned int channel = 0; channel < 3; ++channel ) + { + ArHosekSkyModel_CookConfiguration( + datasetsXYZ[channel], + state->configs[channel], + turbidity, + albedo, + elevation + ); + + state->radiances[channel] = + ArHosekSkyModel_CookRadianceConfiguration( + datasetsXYZRad[channel], + turbidity, + albedo, + elevation + ); + } + + return state; +} + + +ArHosekSkyModelState * arhosek_rgb_skymodelstate_alloc_init( + const double turbidity, + const double albedo, + const double elevation + ) +{ + ArHosekSkyModelState* state = ALLOC(ArHosekSkyModelState); + + state->solar_radius = TERRESTRIAL_SOLAR_RADIUS; + state->turbidity = turbidity; + state->albedo = albedo; + state->elevation = elevation; + + for( unsigned int channel = 0; channel < 3; ++channel ) + { + ArHosekSkyModel_CookConfiguration( + datasetsRGB[channel], + state->configs[channel], + turbidity, + albedo, + elevation + ); + + state->radiances[channel] = + ArHosekSkyModel_CookRadianceConfiguration( + datasetsRGBRad[channel], + turbidity, + albedo, + elevation + ); + } + + return state; +} + +double arhosek_tristim_skymodel_radiance( + ArHosekSkyModelState * state, + double theta, + double gamma, + int channel + ) +{ + return + ArHosekSkyModel_GetRadianceInternal( + state->configs[channel], + theta, + gamma + ) + * state->radiances[channel]; +} diff --git a/rpplugins/scattering/resources/hosek_wilkie_scattering/source/ArHosekSkyModel.h b/rpplugins/scattering/resources/hosek_wilkie_scattering/source/ArHosekSkyModel.h new file mode 100644 index 0000000..e1c3e2d --- /dev/null +++ b/rpplugins/scattering/resources/hosek_wilkie_scattering/source/ArHosekSkyModel.h @@ -0,0 +1,451 @@ +/* +This source is published under the following 3-clause BSD license. + +Copyright (c) 2012 - 2013, Lukas Hosek and Alexander Wilkie +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + + * Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + * None of the names of the contributors may be used to endorse or promote + products derived from this software without specific prior written + permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY +DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND +ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +*/ + + +/* ============================================================================ + +This file is part of a sample implementation of the analytical skylight and +solar radiance models presented in the SIGGRAPH 2012 paper + + + "An Analytic Model for Full Spectral Sky-Dome Radiance" + +and the 2013 IEEE CG&A paper + + "Adding a Solar Radiance Function to the Hosek Skylight Model" + + both by + + Lukas Hosek and Alexander Wilkie + Charles University in Prague, Czech Republic + + + Version: 1.4a, February 22nd, 2013 + +Version history: + +1.4a February 22nd, 2013 + Removed unnecessary and counter-intuitive solar radius parameters + from the interface of the colourspace sky dome initialisation functions. + +1.4 February 11th, 2013 + Fixed a bug which caused the relative brightness of the solar disc + and the sky dome to be off by a factor of about 6. The sun was too + bright: this affected both normal and alien sun scenarios. The + coefficients of the solar radiance function were changed to fix this. + +1.3 January 21st, 2013 (not released to the public) + Added support for solar discs that are not exactly the same size as + the terrestrial sun. Also added support for suns with a different + emission spectrum ("Alien World" functionality). + +1.2a December 18th, 2012 + Fixed a mistake and some inaccuracies in the solar radiance function + explanations found in ArHosekSkyModel.h. The actual source code is + unchanged compared to version 1.2. + +1.2 December 17th, 2012 + Native RGB data and a solar radiance function that matches the turbidity + conditions were added. + +1.1 September 2012 + The coefficients of the spectral model are now scaled so that the output + is given in physical units: W / (m^-2 * sr * nm). Also, the output of the + XYZ model is now no longer scaled to the range [0...1]. Instead, it is + the result of a simple conversion from spectral data via the CIE 2 degree + standard observer matching functions. Therefore, after multiplication + with 683 lm / W, the Y channel now corresponds to luminance in lm. + +1.0 May 11th, 2012 + Initial release. + + +Please visit http://cgg.mff.cuni.cz/projects/SkylightModelling/ to check if +an updated version of this code has been published! + +============================================================================ */ + + +/* + +This code is taken from ART, a rendering research system written in a +mix of C99 / Objective C. Since ART is not a small system and is intended to +be inter-operable with other libraries, and since C does not have namespaces, +the structures and functions in ART all have to have somewhat wordy +canonical names that begin with Ar.../ar..., like those seen in this example. + +Usage information: +================== + + +Model initialisation +-------------------- + +A separate ArHosekSkyModelState has to be maintained for each spectral +band you want to use the model for. So in a renderer with 'num_channels' +bands, you would need something like + + ArHosekSkyModelState * skymodel_state[num_channels]; + +You then have to allocate and initialise these states. In the following code +snippet, we assume that 'albedo' is defined as + + double albedo[num_channels]; + +with a ground albedo value between [0,1] for each channel. The solar elevation +is given in radians. + + for ( unsigned int i = 0; i < num_channels; i++ ) + skymodel_state[i] = + arhosekskymodelstate_alloc_init( + turbidity, + albedo[i], + solarElevation + ); + +Note that starting with version 1.3, there is also a second initialisation +function which generates skydome states for different solar emission spectra +and solar radii: 'arhosekskymodelstate_alienworld_alloc_init()'. + +See the notes about the "Alien World" functionality provided further down for a +discussion of the usefulness and limits of that second initalisation function. +Sky model states that have been initialised with either function behave in a +completely identical fashion during use and cleanup. + +Using the model to generate skydome samples +------------------------------------------- + +Generating a skydome radiance spectrum "skydome_result" for a given location +on the skydome determined via the angles theta and gamma works as follows: + + double skydome_result[num_channels]; + + for ( unsigned int i = 0; i < num_channels; i++ ) + skydome_result[i] = + arhosekskymodel_radiance( + skymodel_state[i], + theta, + gamma, + channel_center[i] + ); + +The variable "channel_center" is assumed to hold the channel center wavelengths +for each of the num_channels samples of the spectrum we are building. + + +Cleanup after use +----------------- + +After rendering is complete, the content of the sky model states should be +disposed of via + + for ( unsigned int i = 0; i < num_channels; i++ ) + arhosekskymodelstate_free( skymodel_state[i] ); + + +CIE XYZ Version of the Model +---------------------------- + +Usage of the CIE XYZ version of the model is exactly the same, except that +num_channels is of course always 3, and that ArHosekTristimSkyModelState and +arhosek_tristim_skymodel_radiance() have to be used instead of their spectral +counterparts. + +RGB Version of the Model +------------------------ + +The RGB version uses sRGB primaries with a linear gamma ramp. The same set of +functions as with the XYZ data is used, except the model is initialized +by calling arhosek_rgb_skymodelstate_alloc_init. + +Solar Radiance Function +----------------------- + +For each position on the solar disc, this function returns the entire radiance +one sees - direct emission, as well as in-scattered light in the area of the +solar disc. The latter is important for low solar elevations - nice images of +the setting sun would not be possible without this. This is also the reason why +this function, just like the regular sky dome model evaluation function, needs +access to the sky dome data structures, as these provide information on +in-scattered radiance. + +CAVEAT #1: in this release, this function is only provided in spectral form! + RGB/XYZ versions to follow at a later date. + +CAVEAT #2: (fixed from release 1.3 onwards) + +CAVEAT #3: limb darkening renders the brightness of the solar disc + inhomogeneous even for high solar elevations - only taking a single + sample at the centre of the sun will yield an incorrect power + estimate for the solar disc! Always take multiple random samples + across the entire solar disc to estimate its power! + +CAVEAT #4: in this version, the limb darkening calculations still use a fairly + computationally expensive 5th order polynomial that was directly + taken from astronomical literature. For the purposes of Computer + Graphics, this is needlessly accurate, though, and will be replaced + by a cheaper approximation in a future release. + +"Alien World" functionality +--------------------------- + +The Hosek sky model can be used to roughly (!) predict the appearance of +outdoor scenes on earth-like planets, i.e. planets of a similar size and +atmospheric make-up. Since the spectral version of our model predicts sky dome +luminance patterns and solar radiance independently for each waveband, and +since the intensity of each waveband is solely dependent on the input radiance +from the star that the world in question is orbiting, it is trivial to re-scale +the wavebands to match a different star radiance. + +At least in theory, the spectral version of the model has always been capable +of this sort of thing, and the actual sky dome and solar radiance models were +actually not altered at all in this release. All we did was to add some support +functionality for doing this more easily with the existing data and functions, +and to add some explanations. + +Just use 'arhosekskymodelstate_alienworld_alloc_init()' to initialise the sky +model states (you will have to provide values for star temperature and solar +intensity compared to the terrestrial sun), and do everything else as you +did before. + +CAVEAT #1: we assume the emission of the star that illuminates the alien world + to be a perfect blackbody emission spectrum. This is never entirely + realistic - real star emission spectra are considerably more complex + than this, mainly due to absorption effects in the outer layers of + stars. However, blackbody spectra are a reasonable first assumption + in a usage scenario like this, where 100% accuracy is simply not + necessary: for rendering purposes, there are likely no visible + differences between a highly accurate solution based on a more + involved simulation, and this approximation. + +CAVEAT #2: we always use limb darkening data from our own sun to provide this + "appearance feature", even for suns of strongly different + temperature. Which is presumably not very realistic, but (as with + the unaltered blackbody spectrum from caveat #1) probably not a bad + first guess, either. If you need more accuracy than we provide here, + please make inquiries with a friendly astro-physicst of your choice. + +CAVEAT #3: you have to provide a value for the solar intensity of the star + which illuminates the alien world. For this, please bear in mind + that there is very likely a comparatively tight range of absolute + solar irradiance values for which an earth-like planet with an + atmosphere like the one we assume in our model can exist in the + first place! + + Too much irradiance, and the atmosphere probably boils off into + space, too little, it freezes. Which means that stars of + considerably different emission colour than our sun will have to be + fairly different in size from it, to still provide a reasonable and + inhabitable amount of irradiance. Red stars will need to be much + larger than our sun, while white or blue stars will have to be + comparatively tiny. The initialisation function handles this and + computes a plausible solar radius for a given emission spectrum. In + terms of absolute radiometric values, you should probably not stray + all too far from a solar intensity value of 1.0. + +CAVEAT #4: although we now support different solar radii for the actual solar + disc, the sky dome luminance patterns are *not* parameterised by + this value - i.e. the patterns stay exactly the same for different + solar radii! Which is of course not correct. But in our experience, + solar discs up to several degrees in diameter (! - our own sun is + half a degree across) do not cause the luminance patterns on the sky + to change perceptibly. The reason we know this is that we initially + used unrealistically large suns in our brute force path tracer, in + order to improve convergence speeds (which in the beginning were + abysmal). Later, we managed to do the reference renderings much + faster even with realistically small suns, and found that there was + no real difference in skydome appearance anyway. + Conclusion: changing the solar radius should not be over-done, so + close orbits around red supergiants are a no-no. But for the + purposes of getting a fairly credible first impression of what an + alien world with a reasonably sized sun would look like, what we are + doing here is probably still o.k. + +HINT #1: if you want to model the sky of an earth-like planet that orbits + a binary star, just super-impose two of these models with solar + intensity of ~0.5 each, and closely spaced solar positions. Light is + additive, after all. Tattooine, here we come... :-) + + P.S. according to Star Wars canon, Tattooine orbits a binary + that is made up of a G and K class star, respectively. + So ~5500K and ~4200K should be good first guesses for their + temperature. Just in case you were wondering, after reading the + previous paragraph. +*/ + + +#ifndef _ARHOSEK_SKYMODEL_H_ +#define _ARHOSEK_SKYMODEL_H_ + +typedef double ArHosekSkyModelConfiguration[9]; + + +// Spectral version of the model + +/* ---------------------------------------------------------------------------- + + ArHosekSkyModelState struct + --------------------------- + + This struct holds the pre-computation data for one particular albedo value. + Most fields are self-explanatory, but users should never directly + manipulate any of them anyway. The only consistent way to manipulate such + structs is via the functions 'arhosekskymodelstate_alloc_init' and + 'arhosekskymodelstate_free'. + + 'emission_correction_factor_sky' + 'emission_correction_factor_sun' + + The original model coefficients were fitted against the emission of + our local sun. If a different solar emission is desired (i.e. if the + model is being used to predict skydome appearance for an earth-like + planet that orbits a different star), these correction factors, which + are determined during the alloc_init step, are applied to each waveband + separately (they default to 1.0 in normal usage). This is the simplest + way to retrofit this sort of capability to the existing model. The + different factors for sky and sun are needed since the solar disc may + be of a different size compared to the terrestrial sun. + +---------------------------------------------------------------------------- */ + +typedef struct ArHosekSkyModelState +{ + ArHosekSkyModelConfiguration configs[11]; + double radiances[11]; + double turbidity; + double solar_radius; + double emission_correction_factor_sky[11]; + double emission_correction_factor_sun[11]; + double albedo; + double elevation; +} +ArHosekSkyModelState; + +/* ---------------------------------------------------------------------------- + + arhosekskymodelstate_alloc_init() function + ------------------------------------------ + + Initialises an ArHosekSkyModelState struct for a terrestrial setting. + +---------------------------------------------------------------------------- */ + +ArHosekSkyModelState * arhosekskymodelstate_alloc_init( + const double solar_elevation, + const double atmospheric_turbidity, + const double ground_albedo + ); + + +/* ---------------------------------------------------------------------------- + + arhosekskymodelstate_alienworld_alloc_init() function + ----------------------------------------------------- + + Initialises an ArHosekSkyModelState struct for an "alien world" setting + with a sun of a surface temperature given in 'kelvin'. The parameter + 'solar_intensity' controls the overall brightness of the sky, relative + to the solar irradiance on Earth. A value of 1.0 yields a sky dome that + is, on average over the wavelenghts covered in the model (!), as bright + as the terrestrial sky in radiometric terms. + + Which means that the solar radius has to be adjusted, since the + emissivity of a solar surface with a given temperature is more or less + fixed. So hotter suns have to be smaller to be equally bright as the + terrestrial sun, while cooler suns have to be larger. Note that there are + limits to the validity of the luminance patterns of the underlying model: + see the discussion above for more on this. In particular, an alien sun with + a surface temperature of only 2000 Kelvin has to be very large if it is + to be as bright as the terrestrial sun - so large that the luminance + patterns are no longer a really good fit in that case. + + If you need information about the solar radius that the model computes + for a given temperature (say, for light source sampling purposes), you + have to query the 'solar_radius' variable of the sky model state returned + *after* running this function. + +---------------------------------------------------------------------------- */ + +ArHosekSkyModelState * arhosekskymodelstate_alienworld_alloc_init( + const double solar_elevation, + const double solar_intensity, + const double solar_surface_temperature_kelvin, + const double atmospheric_turbidity, + const double ground_albedo + ); + +void arhosekskymodelstate_free( + ArHosekSkyModelState * state + ); + +double arhosekskymodel_radiance( + ArHosekSkyModelState * state, + double theta, + double gamma, + double wavelength + ); + +// CIE XYZ and RGB versions + + +ArHosekSkyModelState * arhosek_xyz_skymodelstate_alloc_init( + const double turbidity, + const double albedo, + const double elevation + ); + + +ArHosekSkyModelState * arhosek_rgb_skymodelstate_alloc_init( + const double turbidity, + const double albedo, + const double elevation + ); + + +double arhosek_tristim_skymodel_radiance( + ArHosekSkyModelState * state, + double theta, + double gamma, + int channel + ); + +// Delivers the complete function: sky + sun, including limb darkening. +// Please read the above description before using this - there are several +// caveats! + +double arhosekskymodel_solar_radiance( + ArHosekSkyModelState * state, + double theta, + double gamma, + double wavelength + ); + + +#endif // _ARHOSEK_SKYMODEL_H_ diff --git a/rpplugins/scattering/resources/hosek_wilkie_scattering/source/ArHosekSkyModelData_CIEXYZ.data b/rpplugins/scattering/resources/hosek_wilkie_scattering/source/ArHosekSkyModelData_CIEXYZ.data new file mode 100644 index 0000000..a5f3ce4 --- /dev/null +++ b/rpplugins/scattering/resources/hosek_wilkie_scattering/source/ArHosekSkyModelData_CIEXYZ.data @@ -0,0 +1,3863 @@ +/* +This source is published under the following 3-clause BSD license. + +Copyright (c) 2012 - 2013, Lukas Hosek and Alexander Wilkie +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + + * Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + * None of the names of the contributors may be used to endorse or promote + products derived from this software without specific prior written + permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY +DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND +ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +*/ + + +/* ============================================================================ + +This file is part of a sample implementation of the analytical skylight and +solar radiance models presented in the SIGGRAPH 2012 paper + + + "An Analytic Model for Full Spectral Sky-Dome Radiance" + +and the 2013 IEEE CG&A paper + + "Adding a Solar Radiance Function to the Hosek Skylight Model" + + both by + + Lukas Hosek and Alexander Wilkie + Charles University in Prague, Czech Republic + + + Version: 1.4a, February 22nd, 2013 + +Version history: + +1.4a February 22nd, 2013 + Removed unnecessary and counter-intuitive solar radius parameters + from the interface of the colourspace sky dome initialisation functions. + +1.4 February 11th, 2013 + Fixed a bug which caused the relative brightness of the solar disc + and the sky dome to be off by a factor of about 6. The sun was too + bright: this affected both normal and alien sun scenarios. The + coefficients of the solar radiance function were changed to fix this. + +1.3 January 21st, 2013 (not released to the public) + Added support for solar discs that are not exactly the same size as + the terrestrial sun. Also added support for suns with a different + emission spectrum ("Alien World" functionality). + +1.2a December 18th, 2012 + Fixed a mistake and some inaccuracies in the solar radiance function + explanations found in ArHosekSkyModel.h. The actual source code is + unchanged compared to version 1.2. + +1.2 December 17th, 2012 + Native RGB data and a solar radiance function that matches the turbidity + conditions were added. + +1.1 September 2012 + The coefficients of the spectral model are now scaled so that the output + is given in physical units: W / (m^-2 * sr * nm). Also, the output of the + XYZ model is now no longer scaled to the range [0...1]. Instead, it is + the result of a simple conversion from spectral data via the CIE 2 degree + standard observer matching functions. Therefore, after multiplication + with 683 lm / W, the Y channel now corresponds to luminance in lm. + +1.0 May 11th, 2012 + Initial release. + + +Please visit http://cgg.mff.cuni.cz/projects/SkylightModelling/ to check if +an updated version of this code has been published! + +============================================================================ */ + + +/* + +This file contains the coefficient data for the XYZ colour space version of +the model. + +*/ + +// Uses Sep 9 pattern / Aug 23 mean dataset + +double datasetXYZ1[] = +{ + // albedo 0, turbidity 1 + -1.117001e+000, + -1.867262e-001, + -1.113505e+001, + 1.259865e+001, + -3.937339e-002, + 1.167571e+000, + 7.100686e-003, + 3.592678e+000, + 6.083296e-001, + -1.152006e+000, + -1.926669e-001, + 6.152049e+000, + -4.770802e+000, + -8.704701e-002, + 7.483626e-001, + 3.372718e-002, + 4.464592e+000, + 4.036546e-001, + -1.072371e+000, + -2.696632e-001, + 2.816168e-001, + 1.820571e+000, + -3.742666e-001, + 2.080607e+000, + -7.675295e-002, + -2.835366e+000, + 1.129329e+000, + -1.109935e+000, + -1.532764e-001, + 1.198787e+000, + -9.015183e-001, + 5.173015e-003, + 5.749178e-001, + 1.075633e-001, + 4.387949e+000, + 2.650413e-001, + -1.052297e+000, + -2.229452e-001, + 1.952347e+000, + 5.727205e-001, + -4.885070e+000, + 1.984016e+000, + -1.106197e-001, + -4.898361e-001, + 8.907873e-001, + -1.070108e+000, + -1.600465e-001, + 1.593886e+000, + -4.479251e-005, + -3.306541e+000, + 9.390193e-001, + 9.513168e-002, + 2.343583e+000, + 5.335404e-001, + // albedo 0, turbidity 2 + -1.113253e+000, + -1.699600e-001, + -1.038822e+001, + 1.137513e+001, + -4.040911e-002, + 1.037455e+000, + 4.991792e-002, + 4.801919e+000, + 6.302710e-001, + -1.135747e+000, + -1.678594e-001, + 4.970755e+000, + -4.430230e+000, + -6.657408e-002, + 3.636161e-001, + 1.558009e-001, + 6.013370e+000, + 3.959601e-001, + -1.095892e+000, + -2.732595e-001, + 7.666496e-001, + 1.350731e+000, + -4.401401e-001, + 2.470135e+000, + -1.707929e-001, + -3.260793e+000, + 1.170337e+000, + -1.073668e+000, + -2.603929e-002, + -1.944589e-001, + 4.575207e-001, + 6.878164e-001, + -1.390770e-001, + 3.690299e-001, + 7.885781e+000, + 1.877694e-001, + -1.070091e+000, + -2.798957e-001, + 2.338478e+000, + -2.647221e+000, + -7.387808e+000, + 2.329210e+000, + -1.644639e-001, + -2.003710e+000, + 9.874527e-001, + -1.067120e+000, + -1.418866e-001, + 1.254090e+000, + 6.053048e+000, + -2.918892e+000, + 5.322812e-001, + 1.613053e-001, + 3.018161e+000, + 5.274090e-001, + // albedo 0, turbidity 3 + -1.129483e+000, + -1.890619e-001, + -9.065101e+000, + 9.659923e+000, + -3.607819e-002, + 8.314359e-001, + 8.181661e-002, + 4.768868e+000, + 6.339777e-001, + -1.146420e+000, + -1.883579e-001, + 3.309173e+000, + -3.127882e+000, + -6.938176e-002, + 3.987113e-001, + 1.400581e-001, + 6.283042e+000, + 5.267076e-001, + -1.128348e+000, + -2.641305e-001, + 1.223176e+000, + 5.514952e-002, + -3.490649e-001, + 1.997784e+000, + -4.123709e-002, + -2.251251e+000, + 9.483466e-001, + -1.025820e+000, + 1.404690e-002, + -1.187406e+000, + 2.729900e+000, + 5.877588e-001, + -2.761140e-001, + 4.602633e-001, + 8.305125e+000, + 3.945001e-001, + -1.083957e+000, + -2.606679e-001, + 2.207108e+000, + -7.202803e+000, + -5.968103e+000, + 2.129455e+000, + -7.789512e-002, + -1.137688e+000, + 8.871769e-001, + -1.062465e+000, + -1.512189e-001, + 1.042881e+000, + 1.427839e+001, + -4.242214e+000, + 4.038100e-001, + 1.997780e-001, + 2.814449e+000, + 5.803196e-001, + // albedo 0, turbidity 4 + -1.175099e+000, + -2.410789e-001, + -1.108587e+001, + 1.133404e+001, + -1.819300e-002, + 6.772942e-001, + 9.605043e-002, + 4.231166e+000, + 6.239972e-001, + -1.224207e+000, + -2.883527e-001, + 3.002206e+000, + -2.649612e+000, + -4.795418e-002, + 4.984398e-001, + 3.251434e-002, + 4.851611e+000, + 6.551019e-001, + -1.136955e+000, + -2.423048e-001, + 1.058823e+000, + -2.489236e-001, + -2.462179e-001, + 1.933140e+000, + 9.106828e-002, + -1.905869e-001, + 8.171065e-001, + -1.014535e+000, + -8.262500e-003, + -1.448017e+000, + 2.295788e+000, + 3.510334e-001, + -1.477418e+000, + 5.432449e-001, + 5.762796e+000, + 4.908751e-001, + -1.070666e+000, + -2.379780e-001, + 1.844589e+000, + -5.442448e+000, + -4.012768e+000, + 2.945275e+000, + 9.854725e-003, + 8.455959e-002, + 8.145030e-001, + -1.071525e+000, + -1.777132e-001, + 8.076590e-001, + 9.925865e+000, + -3.324623e+000, + -6.367437e-001, + 2.844581e-001, + 2.248384e+000, + 6.544022e-001, + // albedo 0, turbidity 5 + -1.218818e+000, + -2.952382e-001, + -1.345975e+001, + 1.347153e+001, + -6.814585e-003, + 5.079068e-001, + 1.197230e-001, + 3.776949e+000, + 5.836961e-001, + -1.409868e+000, + -5.114330e-001, + 2.776539e+000, + -2.039001e+000, + -2.673769e-002, + 4.145288e-001, + 7.829342e-004, + 2.275883e+000, + 6.629691e-001, + -1.069151e+000, + -9.434247e-002, + 7.293972e-001, + -1.222473e+000, + -1.533461e-001, + 2.160357e+000, + 4.626837e-002, + 3.852415e+000, + 8.593570e-001, + -1.021306e+000, + -1.149551e-001, + -1.108414e+000, + 4.178343e+000, + 4.013665e-001, + -2.222814e+000, + 6.929462e-001, + 1.392652e+000, + 4.401662e-001, + -1.074251e+000, + -2.224002e-001, + 1.372356e+000, + -8.858704e+000, + -3.922660e+000, + 3.020018e+000, + -1.458724e-002, + 1.511186e+000, + 8.288064e-001, + -1.062048e+000, + -1.526582e-001, + 4.921067e-001, + 1.485522e+001, + -3.229936e+000, + -8.426604e-001, + 3.916243e-001, + 2.678994e+000, + 6.689264e-001, + // albedo 0, turbidity 6 + -1.257023e+000, + -3.364700e-001, + -1.527795e+001, + 1.504223e+001, + 2.717715e-003, + 3.029910e-001, + 1.636851e-001, + 3.561663e+000, + 5.283161e-001, + -1.635124e+000, + -7.329993e-001, + 3.523939e+000, + -2.566337e+000, + -1.902543e-002, + 5.505483e-001, + -6.242176e-002, + 1.065992e+000, + 6.654236e-001, + -9.295823e-001, + 4.845834e-002, + -2.992990e-001, + -2.001327e-001, + -8.019339e-002, + 1.807806e+000, + 9.020277e-002, + 5.095372e+000, + 8.639936e-001, + -1.093740e+000, + -2.148608e-001, + -5.216240e-001, + 2.119777e+000, + 9.506454e-002, + -1.831439e+000, + 6.961204e-001, + 1.102084e-001, + 4.384319e-001, + -1.044181e+000, + -1.849257e-001, + 9.071246e-001, + -4.648901e+000, + -2.279385e+000, + 2.356502e+000, + -4.169147e-002, + 1.932557e+000, + 8.296550e-001, + -1.061451e+000, + -1.458745e-001, + 2.952267e-001, + 8.967214e+000, + -3.726228e+000, + -5.022316e-001, + 5.684877e-001, + 3.102347e+000, + 6.658443e-001, + // albedo 0, turbidity 7 + -1.332391e+000, + -4.127769e-001, + -9.328643e+000, + 9.046194e+000, + 3.457775e-003, + 3.377425e-001, + 1.530909e-001, + 3.301209e+000, + 4.997917e-001, + -1.932002e+000, + -9.947777e-001, + -2.042329e+000, + 3.586940e+000, + -5.642182e-002, + 8.130478e-001, + -8.195988e-002, + 1.118294e-001, + 5.617231e-001, + -8.707374e-001, + 1.286999e-001, + 1.820054e+000, + -4.674706e+000, + 3.317471e-003, + 5.919018e-001, + 1.975278e-001, + 6.686519e+000, + 9.631727e-001, + -1.070378e+000, + -3.030579e-001, + -9.041938e-001, + 6.200201e+000, + 1.232207e-001, + -3.650628e-001, + 5.029403e-001, + -2.903162e+000, + 3.811408e-001, + -1.063035e+000, + -1.637545e-001, + 5.853072e-001, + -7.889906e+000, + -1.200641e+000, + 1.035018e+000, + 1.192093e-001, + 3.267054e+000, + 8.416151e-001, + -1.053655e+000, + -1.562286e-001, + 2.423683e-001, + 1.128575e+001, + -4.363262e+000, + -7.314160e-002, + 5.642088e-001, + 2.514023e+000, + 6.670457e-001, + // albedo 0, turbidity 8 + -1.366112e+000, + -4.718287e-001, + -7.876222e+000, + 7.746900e+000, + -9.182309e-003, + 4.716076e-001, + 8.320252e-002, + 3.165603e+000, + 5.392334e-001, + -2.468204e+000, + -1.336340e+000, + -5.386723e+000, + 7.072672e+000, + -8.329266e-002, + 8.636876e-001, + -1.978177e-002, + -1.326218e-001, + 2.979222e-001, + -9.653522e-001, + -2.373416e-002, + 1.810250e+000, + -6.467262e+000, + 1.410706e-001, + -4.753717e-001, + 3.003095e-001, + 6.551163e+000, + 1.151083e+000, + -8.943186e-001, + -2.487152e-001, + -2.308960e-001, + 8.512648e+000, + 1.298402e-001, + 1.034705e+000, + 2.303509e-001, + -3.924095e+000, + 2.982717e-001, + -1.146999e+000, + -2.318784e-001, + 8.992419e-002, + -9.933614e+000, + -8.860920e-001, + -3.071656e-002, + 2.852012e-001, + 3.046199e+000, + 8.599001e-001, + -1.032399e+000, + -1.645145e-001, + 2.683599e-001, + 1.327701e+001, + -4.407670e+000, + 7.709869e-002, + 4.951727e-001, + 1.957277e+000, + 6.630943e-001, + // albedo 0, turbidity 9 + -1.469070e+000, + -6.135092e-001, + -6.506263e+000, + 6.661315e+000, + -3.835383e-002, + 7.150413e-001, + 7.784318e-003, + 2.820577e+000, + 6.756784e-001, + -2.501583e+000, + -1.247404e+000, + -1.523462e+001, + 1.633191e+001, + -1.204803e-002, + 5.896471e-001, + -2.002023e-002, + 1.144647e+000, + 6.177874e-002, + -2.438672e+000, + -1.127291e+000, + 5.731172e+000, + -1.021350e+001, + 6.165610e-002, + -7.752641e-001, + 4.708254e-001, + 4.176847e+000, + 1.200881e+000, + -1.513427e-001, + 9.792731e-002, + -1.612349e+000, + 9.814289e+000, + 5.188921e-002, + 1.716403e+000, + -7.039255e-002, + -2.815115e+000, + 3.291874e-001, + -1.318511e+000, + -3.650554e-001, + 4.221268e-001, + -9.294529e+000, + -4.397520e-002, + -8.100625e-001, + 3.742719e-001, + 1.834166e+000, + 8.223450e-001, + -1.016009e+000, + -1.820264e-001, + 1.278426e-001, + 1.182696e+001, + -4.801528e+000, + 4.947899e-001, + 4.660378e-001, + 1.601254e+000, + 6.702359e-001, + // albedo 0, turbidity 10 + -1.841310e+000, + -9.781779e-001, + -4.610903e+000, + 4.824662e+000, + -5.100806e-002, + 6.463776e-001, + -6.377724e-006, + 2.216875e+000, + 8.618530e-001, + -2.376373e+000, + -1.108657e+000, + -1.489799e+001, + 1.546458e+001, + 4.091025e-002, + 9.761780e-002, + -1.048958e-002, + 2.165834e+000, + -1.609171e-001, + -4.710318e+000, + -2.261963e+000, + 6.947327e+000, + -1.034828e+001, + -1.325542e-001, + 7.508674e-001, + 2.247553e-001, + 2.873142e+000, + 1.297100e+000, + 2.163750e-001, + -1.944345e-001, + -2.437860e+000, + 1.011314e+001, + 4.450500e-001, + 3.111492e-001, + 2.751323e-001, + -1.627906e+000, + 2.531213e-001, + -1.258794e+000, + -3.524641e-001, + 8.425444e-001, + -1.085313e+001, + -1.154381e+000, + -4.638014e-001, + -2.781115e-003, + 4.344498e-001, + 8.507091e-001, + -1.018938e+000, + -1.804153e-001, + -6.354054e-002, + 1.573150e+001, + -4.386999e+000, + 6.211115e-001, + 5.294648e-001, + 1.580749e+000, + 6.586655e-001, + // albedo 1, turbidity 1 + -1.116416e+000, + -1.917524e-001, + -1.068233e+001, + 1.222221e+001, + -3.668978e-002, + 1.054022e+000, + 1.592132e-002, + 3.180583e+000, + 5.627370e-001, + -1.132341e+000, + -1.671286e-001, + 5.976499e+000, + -4.227366e+000, + -9.542489e-002, + 8.664938e-001, + 8.351793e-003, + 4.876068e+000, + 4.492779e-001, + -1.087635e+000, + -3.173679e-001, + 4.314407e-001, + 1.100555e+000, + -4.410057e-001, + 1.677253e+000, + -3.005925e-002, + -4.201249e+000, + 1.070902e+000, + -1.083031e+000, + -8.847705e-002, + 1.291773e+000, + 4.546776e-001, + 3.091894e-001, + 7.261760e-001, + 4.203659e-002, + 5.990615e+000, + 3.704756e-001, + -1.057899e+000, + -2.246706e-001, + 2.329563e+000, + -1.219656e+000, + -5.335260e+000, + 8.545378e-001, + -3.906209e-002, + -9.025499e-001, + 7.797348e-001, + -1.073305e+000, + -1.522553e-001, + 1.767063e+000, + 1.904280e+000, + -3.101673e+000, + 3.995856e-001, + 2.905192e-002, + 2.563977e+000, + 5.753067e-001, + // albedo 1, turbidity 2 + -1.113674e+000, + -1.759694e-001, + -9.754125e+000, + 1.087391e+001, + -3.841093e-002, + 9.524272e-001, + 5.680219e-002, + 4.227034e+000, + 6.029571e-001, + -1.126496e+000, + -1.680281e-001, + 5.332352e+000, + -4.575579e+000, + -6.761755e-002, + 3.295335e-001, + 1.194896e-001, + 5.570901e+000, + 4.536185e-001, + -1.103074e+000, + -2.681801e-001, + 6.571479e-002, + 2.396522e+000, + -4.551280e-001, + 2.466331e+000, + -1.232022e-001, + -3.023201e+000, + 1.086379e+000, + -1.053299e+000, + -2.697173e-002, + 8.379121e-001, + -9.681458e-001, + 5.890692e-001, + -4.872027e-001, + 2.936929e-001, + 7.510139e+000, + 3.079122e-001, + -1.079553e+000, + -2.710448e-001, + 2.462379e+000, + -3.713554e-001, + -8.534512e+000, + 1.828242e+000, + -1.686398e-001, + -1.961340e+000, + 8.941077e-001, + -1.069741e+000, + -1.396394e-001, + 1.657868e+000, + 3.236313e+000, + -2.706344e+000, + -2.948122e-001, + 1.314816e-001, + 2.868457e+000, + 5.413403e-001, + // albedo 1, turbidity 3 + -1.131649e+000, + -1.954455e-001, + -7.751595e+000, + 8.685861e+000, + -4.910871e-002, + 8.992952e-001, + 4.710143e-002, + 4.254818e+000, + 6.821116e-001, + -1.156689e+000, + -1.884324e-001, + 3.163519e+000, + -3.091522e+000, + -6.613927e-002, + -2.575883e-002, + 1.640065e-001, + 6.073643e+000, + 4.453468e-001, + -1.079224e+000, + -2.621389e-001, + 9.446437e-001, + 1.448479e+000, + -3.969384e-001, + 2.626638e+000, + -8.101186e-002, + -3.016355e+000, + 1.076295e+000, + -1.080832e+000, + 1.033057e-002, + -3.500156e-001, + -3.281419e-002, + 5.655512e-001, + -1.156742e+000, + 4.534710e-001, + 8.774122e+000, + 2.772869e-001, + -1.051202e+000, + -2.679975e-001, + 2.719109e+000, + -2.190316e+000, + -6.878798e+000, + 2.250481e+000, + -2.030252e-001, + -2.026527e+000, + 9.701096e-001, + -1.089849e+000, + -1.598589e-001, + 1.564748e+000, + 6.869187e+000, + -3.053670e+000, + -6.110435e-001, + 1.644472e-001, + 2.370452e+000, + 5.511770e-001, + // albedo 1, turbidity 4 + -1.171419e+000, + -2.429746e-001, + -8.991334e+000, + 9.571216e+000, + -2.772861e-002, + 6.688262e-001, + 7.683478e-002, + 3.785611e+000, + 6.347635e-001, + -1.228554e+000, + -2.917562e-001, + 2.753986e+000, + -2.491780e+000, + -4.663434e-002, + 3.118303e-001, + 7.546506e-002, + 4.463096e+000, + 5.955071e-001, + -1.093124e+000, + -2.447767e-001, + 9.097406e-001, + 5.448296e-001, + -2.957824e-001, + 2.024167e+000, + -5.152333e-004, + -1.069081e+000, + 9.369565e-001, + -1.056994e+000, + 1.569507e-002, + -8.217491e-001, + 1.870818e+000, + 7.061930e-001, + -1.483928e+000, + 5.978206e-001, + 6.864902e+000, + 3.673332e-001, + -1.054871e+000, + -2.758129e-001, + 2.712807e+000, + -5.950110e+000, + -6.554039e+000, + 2.447523e+000, + -1.895171e-001, + -1.454292e+000, + 9.131738e-001, + -1.100218e+000, + -1.746241e-001, + 1.438505e+000, + 1.115481e+001, + -3.266076e+000, + -8.837357e-001, + 1.970100e-001, + 1.991595e+000, + 5.907821e-001, + // albedo 1, turbidity 5 + -1.207267e+000, + -2.913610e-001, + -1.103767e+001, + 1.140724e+001, + -1.416800e-002, + 5.564047e-001, + 8.476262e-002, + 3.371255e+000, + 6.221335e-001, + -1.429698e+000, + -5.374218e-001, + 2.837524e+000, + -2.221936e+000, + -2.422337e-002, + 9.313758e-002, + 7.190250e-002, + 1.869022e+000, + 5.609035e-001, + -1.002274e+000, + -6.972810e-002, + 4.031308e-001, + -3.932997e-001, + -1.521923e-001, + 2.390646e+000, + -6.893990e-002, + 2.999661e+000, + 1.017843e+000, + -1.081168e+000, + -1.178666e-001, + -4.968080e-001, + 3.919299e+000, + 6.046866e-001, + -2.440615e+000, + 7.891538e-001, + 2.140835e+000, + 2.740470e-001, + -1.050727e+000, + -2.307688e-001, + 2.276396e+000, + -9.454407e+000, + -5.505176e+000, + 2.992620e+000, + -2.450942e-001, + 6.078372e-001, + 9.606765e-001, + -1.103752e+000, + -1.810202e-001, + 1.375044e+000, + 1.589095e+001, + -3.438954e+000, + -1.265669e+000, + 2.475172e-001, + 1.680768e+000, + 5.978056e-001, + // albedo 1, turbidity 6 + -1.244324e+000, + -3.378542e-001, + -1.111001e+001, + 1.137784e+001, + -7.896794e-003, + 4.808023e-001, + 9.249904e-002, + 3.025816e+000, + 5.880239e-001, + -1.593165e+000, + -7.027621e-001, + 2.220896e+000, + -1.437709e+000, + -1.534738e-002, + 6.286958e-002, + 6.644555e-002, + 1.091727e+000, + 5.470080e-001, + -9.136506e-001, + 1.344874e-002, + 7.772636e-001, + -1.209396e+000, + -1.408978e-001, + 2.433718e+000, + -1.041938e-001, + 3.791244e+000, + 1.037916e+000, + -1.134968e+000, + -1.803315e-001, + -9.267335e-001, + 4.576670e+000, + 6.851928e-001, + -2.805000e+000, + 8.687208e-001, + 1.161483e+000, + 2.571688e-001, + -1.017037e+000, + -2.053943e-001, + 2.361640e+000, + -9.887818e+000, + -5.122889e+000, + 3.287088e+000, + -2.594102e-001, + 8.578927e-001, + 9.592340e-001, + -1.118723e+000, + -1.934942e-001, + 1.226023e+000, + 1.674140e+001, + -3.277335e+000, + -1.629809e+000, + 2.765232e-001, + 1.637713e+000, + 6.113963e-001, + // albedo 1, turbidity 7 + -1.314779e+000, + -4.119915e-001, + -1.241150e+001, + 1.241578e+001, + 2.344284e-003, + 2.980837e-001, + 1.414613e-001, + 2.781731e+000, + 4.998556e-001, + -1.926199e+000, + -1.020038e+000, + 2.569200e+000, + -1.081159e+000, + -2.266833e-002, + 3.588668e-001, + 8.750078e-003, + -2.452171e-001, + 4.796758e-001, + -7.780002e-001, + 1.850647e-001, + 4.445456e-002, + -2.409297e+000, + -7.816346e-002, + 1.546790e+000, + -2.807227e-002, + 5.998176e+000, + 1.132396e+000, + -1.179326e+000, + -3.578330e-001, + -2.392933e-001, + 6.467883e+000, + 5.904596e-001, + -1.869975e+000, + 8.045839e-001, + -2.498121e+000, + 1.610633e-001, + -1.009956e+000, + -1.311896e-001, + 1.726577e+000, + -1.219356e+001, + -3.466239e+000, + 2.343602e+000, + -2.252205e-001, + 2.573681e+000, + 1.027109e+000, + -1.112460e+000, + -2.063093e-001, + 1.233051e+000, + 2.058946e+001, + -4.578074e+000, + -1.145643e+000, + 3.160192e-001, + 1.420159e+000, + 5.860212e-001, + // albedo 1, turbidity 8 + -1.371689e+000, + -4.914196e-001, + -1.076610e+001, + 1.107405e+001, + -1.485077e-002, + 5.936218e-001, + 3.685482e-002, + 2.599968e+000, + 6.002204e-001, + -2.436997e+000, + -1.377939e+000, + 2.130141e-002, + 1.079593e+000, + -1.796232e-002, + -3.933248e-002, + 1.610711e-001, + -6.901181e-001, + 1.206416e-001, + -8.743368e-001, + 7.331370e-002, + 8.734259e-001, + -3.743126e+000, + -3.151167e-002, + 1.297596e+000, + -7.634926e-002, + 6.532873e+000, + 1.435737e+000, + -9.810197e-001, + -3.521634e-001, + -2.855205e-001, + 7.134674e+000, + 6.839748e-001, + -1.394841e+000, + 6.952036e-001, + -4.633104e+000, + -2.173401e-002, + -1.122958e+000, + -1.691536e-001, + 1.382360e+000, + -1.102913e+001, + -2.608171e+000, + 1.865111e+000, + -1.345154e-001, + 3.112342e+000, + 1.094134e+000, + -1.075586e+000, + -2.077415e-001, + 1.171477e+000, + 1.793270e+001, + -4.656858e+000, + -1.036839e+000, + 3.338295e-001, + 1.042793e+000, + 5.739374e-001, + // albedo 1, turbidity 9 + -1.465871e+000, + -6.364486e-001, + -8.833718e+000, + 9.343650e+000, + -3.223600e-002, + 7.552848e-001, + -3.121341e-006, + 2.249164e+000, + 8.094662e-001, + -2.448924e+000, + -1.270878e+000, + -4.823703e+000, + 5.853058e+000, + -2.149127e-002, + 3.581132e-002, + -1.230276e-003, + 4.892553e-001, + -1.597657e-001, + -2.419809e+000, + -1.071337e+000, + 1.575648e+000, + -4.983580e+000, + 9.545185e-003, + 5.032615e-001, + 4.186266e-001, + 4.634147e+000, + 1.433517e+000, + -1.383278e-001, + -2.797095e-002, + -1.943067e-001, + 6.679623e+000, + 4.118280e-001, + -2.744289e-001, + -2.118722e-002, + -4.337025e+000, + 1.505072e-001, + -1.341872e+000, + -2.518572e-001, + 1.027009e+000, + -6.527103e+000, + -1.081271e+000, + 1.015465e+000, + 2.845789e-001, + 2.470371e+000, + 9.278120e-001, + -1.040640e+000, + -2.367454e-001, + 1.100744e+000, + 8.827253e+000, + -4.560794e+000, + -7.287017e-001, + 2.842503e-001, + 6.336593e-001, + 6.327335e-001, + // albedo 1, turbidity 10 + -1.877993e+000, + -1.025135e+000, + -4.311037e+000, + 4.715016e+000, + -4.711631e-002, + 6.335844e-001, + -7.665398e-006, + 1.788017e+000, + 9.001409e-001, + -2.281540e+000, + -1.137668e+000, + -1.036869e+001, + 1.136254e+001, + 1.961739e-002, + -9.836174e-002, + -6.734567e-003, + 1.320918e+000, + -2.400807e-001, + -4.904054e+000, + -2.315781e+000, + 5.735999e+000, + -8.626257e+000, + -1.255643e-001, + 1.545446e+000, + 1.396860e-001, + 2.972897e+000, + 1.429934e+000, + 4.077067e-001, + -1.833688e-001, + -2.450939e+000, + 9.119433e+000, + 4.505361e-001, + -1.340828e+000, + 3.973690e-001, + -1.785370e+000, + 9.628711e-002, + -1.296052e+000, + -3.250526e-001, + 1.813294e+000, + -1.031485e+001, + -1.388690e+000, + 1.239733e+000, + -8.989196e-002, + -3.389637e-001, + 9.639560e-001, + -1.062181e+000, + -2.423444e-001, + 7.577592e-001, + 1.566938e+001, + -4.462264e+000, + -5.742810e-001, + 3.262259e-001, + 9.461672e-001, + 6.232887e-001, +}; + +double datasetXYZRad1[] = +{ + // albedo 0, turbidity 1 + 1.560219e+000, + 1.417388e+000, + 1.206927e+000, + 1.091949e+001, + 5.931416e+000, + 7.304788e+000, + // albedo 0, turbidity 2 + 1.533049e+000, + 1.560532e+000, + 3.685059e-001, + 1.355040e+001, + 5.543711e+000, + 7.792189e+000, + // albedo 0, turbidity 3 + 1.471043e+000, + 1.746088e+000, + -9.299697e-001, + 1.720362e+001, + 5.473384e+000, + 8.336416e+000, + // albedo 0, turbidity 4 + 1.355991e+000, + 2.109348e+000, + -3.295855e+000, + 2.264843e+001, + 5.454607e+000, + 9.304656e+000, + // albedo 0, turbidity 5 + 1.244963e+000, + 2.547533e+000, + -5.841485e+000, + 2.756879e+001, + 5.576104e+000, + 1.043287e+001, + // albedo 0, turbidity 6 + 1.175532e+000, + 2.784634e+000, + -7.212225e+000, + 2.975347e+001, + 6.472980e+000, + 1.092331e+001, + // albedo 0, turbidity 7 + 1.082973e+000, + 3.118094e+000, + -8.934293e+000, + 3.186879e+001, + 8.473885e+000, + 1.174019e+001, + // albedo 0, turbidity 8 + 9.692500e-001, + 3.349574e+000, + -1.003810e+001, + 3.147654e+001, + 1.338931e+001, + 1.272547e+001, + // albedo 0, turbidity 9 + 8.547044e-001, + 3.151538e+000, + -9.095567e+000, + 2.554995e+001, + 2.273219e+001, + 1.410398e+001, + // albedo 0, turbidity 10 + 7.580340e-001, + 2.311153e+000, + -5.170814e+000, + 1.229669e+001, + 3.686529e+001, + 1.598882e+001, + // albedo 1, turbidity 1 + 1.664273e+000, + 1.574468e+000, + 1.422078e+000, + 9.768247e+000, + 1.447338e+001, + 1.644988e+001, + // albedo 1, turbidity 2 + 1.638295e+000, + 1.719586e+000, + 5.786675e-001, + 1.239846e+001, + 1.415419e+001, + 1.728605e+001, + // albedo 1, turbidity 3 + 1.572623e+000, + 1.921559e+000, + -7.714802e-001, + 1.609246e+001, + 1.420954e+001, + 1.825908e+001, + // albedo 1, turbidity 4 + 1.468395e+000, + 2.211970e+000, + -2.845869e+000, + 2.075027e+001, + 1.524822e+001, + 1.937622e+001, + // albedo 1, turbidity 5 + 1.355047e+000, + 2.556469e+000, + -4.960920e+000, + 2.460237e+001, + 1.648360e+001, + 2.065648e+001, + // albedo 1, turbidity 6 + 1.291642e+000, + 2.742036e+000, + -6.061967e+000, + 2.602002e+001, + 1.819144e+001, + 2.116712e+001, + // albedo 1, turbidity 7 + 1.194565e+000, + 2.972120e+000, + -7.295779e+000, + 2.691805e+001, + 2.124880e+001, + 2.201819e+001, + // albedo 1, turbidity 8 + 1.083631e+000, + 3.047021e+000, + -7.766096e+000, + 2.496261e+001, + 2.744264e+001, + 2.291875e+001, + // albedo 1, turbidity 9 + 9.707994e-001, + 2.736459e+000, + -6.308284e+000, + 1.760860e+001, + 3.776291e+001, + 2.392150e+001, + // albedo 1, turbidity 10 + 8.574294e-001, + 1.865155e+000, + -2.364707e+000, + 4.337793e+000, + 5.092831e+001, + 2.523432e+001, +}; + +double datasetXYZ2[] = +{ + // albedo 0, turbidity 1 + -1.127942e+000, + -1.905548e-001, + -1.252356e+001, + 1.375799e+001, + -3.624732e-002, + 1.055453e+000, + 1.385036e-002, + 4.176970e+000, + 5.928345e-001, + -1.155260e+000, + -1.778135e-001, + 6.216056e+000, + -5.254116e+000, + -8.787445e-002, + 8.434621e-001, + 4.025734e-002, + 6.195322e+000, + 3.111856e-001, + -1.125624e+000, + -3.217593e-001, + 5.043919e-001, + 1.686284e+000, + -3.536071e-001, + 1.476321e+000, + -7.899019e-002, + -4.522531e+000, + 1.271691e+000, + -1.081801e+000, + -1.033234e-001, + 9.995550e-001, + 7.482946e-003, + -6.776018e-002, + 1.463141e+000, + 9.492021e-002, + 5.612723e+000, + 1.298846e-001, + -1.075320e+000, + -2.402711e-001, + 2.141284e+000, + -1.203359e+000, + -4.945188e+000, + 1.437221e+000, + -8.096750e-002, + -1.028378e+000, + 1.004164e+000, + -1.073337e+000, + -1.516517e-001, + 1.639379e+000, + 2.304669e+000, + -3.214244e+000, + 1.286245e+000, + 5.613957e-002, + 2.480902e+000, + 4.999363e-001, + // albedo 0, turbidity 2 + -1.128399e+000, + -1.857793e-001, + -1.089863e+001, + 1.172984e+001, + -3.768099e-002, + 9.439285e-001, + 4.869335e-002, + 4.845114e+000, + 6.119211e-001, + -1.114002e+000, + -1.399280e-001, + 4.963800e+000, + -4.685500e+000, + -7.780879e-002, + 4.049736e-001, + 1.586297e-001, + 7.770264e+000, + 3.449006e-001, + -1.185472e+000, + -3.403543e-001, + 6.588322e-001, + 1.133713e+000, + -4.118674e-001, + 2.061191e+000, + -1.882768e-001, + -4.372586e+000, + 1.223530e+000, + -1.002272e+000, + 2.000703e-002, + 7.073269e-002, + 1.485075e+000, + 5.005589e-001, + 4.301494e-001, + 3.626541e-001, + 7.921098e+000, + 1.574766e-001, + -1.121006e+000, + -3.007777e-001, + 2.242051e+000, + -4.571561e+000, + -7.761071e+000, + 2.053404e+000, + -1.524018e-001, + -1.886162e+000, + 1.018208e+000, + -1.058864e+000, + -1.358673e-001, + 1.389667e+000, + 8.633409e+000, + -3.437249e+000, + 7.295429e-001, + 1.514700e-001, + 2.842513e+000, + 5.014325e-001, + // albedo 0, turbidity 3 + -1.144464e+000, + -2.043799e-001, + -1.020188e+001, + 1.071247e+001, + -3.256693e-002, + 7.860205e-001, + 6.872719e-002, + 4.824771e+000, + 6.259836e-001, + -1.170104e+000, + -2.118626e-001, + 4.391405e+000, + -4.198900e+000, + -7.111559e-002, + 3.890442e-001, + 1.024831e-001, + 6.282535e+000, + 5.365688e-001, + -1.129171e+000, + -2.552880e-001, + 2.238298e-001, + 7.314295e-001, + -3.562730e-001, + 1.881931e+000, + -3.078716e-002, + -1.039120e+000, + 9.096301e-001, + -1.042294e+000, + 4.450203e-003, + -5.116033e-001, + 2.627589e+000, + 6.098996e-001, + -1.264638e-001, + 4.325281e-001, + 7.080503e+000, + 4.583646e-001, + -1.082293e+000, + -2.723056e-001, + 2.065076e+000, + -8.143133e+000, + -7.892212e+000, + 2.142231e+000, + -7.106240e-002, + -1.122398e+000, + 8.338505e-001, + -1.071715e+000, + -1.426568e-001, + 1.095351e+000, + 1.729783e+001, + -3.851931e+000, + 4.360514e-001, + 2.114440e-001, + 2.970832e+000, + 5.944389e-001, + // albedo 0, turbidity 4 + -1.195909e+000, + -2.590449e-001, + -1.191037e+001, + 1.207947e+001, + -1.589842e-002, + 6.297846e-001, + 9.054772e-002, + 4.285959e+000, + 5.933752e-001, + -1.245763e+000, + -3.316637e-001, + 4.293660e+000, + -3.694011e+000, + -4.699947e-002, + 4.843684e-001, + 2.130425e-002, + 4.097549e+000, + 6.530809e-001, + -1.148742e+000, + -1.902509e-001, + -2.393233e-001, + -2.441254e-001, + -2.610918e-001, + 1.846988e+000, + 3.532866e-002, + 2.660106e+000, + 8.358294e-001, + -1.016080e+000, + -7.444960e-002, + -5.053436e-001, + 4.388855e+000, + 6.054987e-001, + -1.208300e+000, + 5.817215e-001, + 2.543570e+000, + 4.726568e-001, + -1.072027e+000, + -2.101440e-001, + 1.518378e+000, + -1.060119e+001, + -6.016546e+000, + 2.649475e+000, + -5.166992e-002, + 1.571269e+000, + 8.344622e-001, + -1.072365e+000, + -1.511201e-001, + 7.478010e-001, + 1.900732e+001, + -3.950387e+000, + -3.473907e-001, + 3.797211e-001, + 2.782949e+000, + 6.296808e-001, + // albedo 0, turbidity 5 + -1.239423e+000, + -3.136289e-001, + -1.351100e+001, + 1.349468e+001, + -7.070423e-003, + 5.012315e-001, + 1.106008e-001, + 3.803619e+000, + 5.577948e-001, + -1.452524e+000, + -5.676944e-001, + 2.993153e+000, + -2.277288e+000, + -2.168954e-002, + 3.056720e-001, + 1.152338e-002, + 1.852697e+000, + 6.427228e-001, + -1.061421e+000, + -4.590521e-002, + 6.057022e-001, + -1.096835e+000, + -1.504952e-001, + 2.344921e+000, + -5.491832e-002, + 5.268322e+000, + 9.082253e-001, + -1.042373e+000, + -1.769498e-001, + -1.075388e+000, + 3.831712e+000, + 3.154140e-001, + -2.416458e+000, + 7.909032e-001, + -1.492892e-002, + 3.854049e-001, + -1.064159e+000, + -1.892684e-001, + 1.438685e+000, + -8.166362e+000, + -3.616364e+000, + 3.275206e+000, + -1.203825e-001, + 2.039491e+000, + 8.688057e-001, + -1.070120e+000, + -1.569508e-001, + 4.124760e-001, + 1.399683e+001, + -3.547085e+000, + -1.046326e+000, + 4.973825e-001, + 2.791231e+000, + 6.503286e-001, + // albedo 0, turbidity 6 + -1.283579e+000, + -3.609518e-001, + -1.335397e+001, + 1.315248e+001, + -4.431938e-004, + 3.769526e-001, + 1.429824e-001, + 3.573613e+000, + 4.998696e-001, + -1.657952e+000, + -7.627948e-001, + 1.958222e+000, + -7.949816e-001, + -2.882837e-002, + 5.356149e-001, + -5.191946e-002, + 8.869955e-001, + 6.263320e-001, + -9.527600e-001, + 6.494189e-002, + 5.361303e-001, + -2.129590e+000, + -9.258630e-002, + 1.604776e+000, + 5.067770e-002, + 6.376055e+000, + 9.138052e-001, + -1.080827e+000, + -2.523120e-001, + -7.154262e-001, + 4.120085e+000, + 1.878228e-001, + -1.492158e+000, + 6.881655e-001, + -1.446611e+000, + 4.040631e-001, + -1.054075e+000, + -1.665498e-001, + 9.191052e-001, + -6.636943e+000, + -1.894826e+000, + 2.107810e+000, + -3.680499e-002, + 2.655452e+000, + 8.413840e-001, + -1.061127e+000, + -1.448849e-001, + 2.667493e-001, + 1.034103e+001, + -4.285769e+000, + -3.874504e-001, + 5.998752e-001, + 3.132426e+000, + 6.652753e-001, + // albedo 0, turbidity 7 + -1.347345e+000, + -4.287832e-001, + -9.305553e+000, + 9.133813e+000, + -3.173527e-003, + 3.977564e-001, + 1.151420e-001, + 3.320564e+000, + 4.998134e-001, + -1.927296e+000, + -9.901372e-001, + -2.593499e+000, + 4.087421e+000, + -5.833993e-002, + 8.158929e-001, + -4.681279e-002, + 2.423716e-001, + 4.938052e-001, + -9.470092e-001, + 7.325237e-002, + 2.064735e+000, + -5.167540e+000, + -1.313751e-002, + 4.832169e-001, + 1.126295e-001, + 6.970522e+000, + 1.035022e+000, + -1.022557e+000, + -2.762616e-001, + -9.375748e-001, + 6.696739e+000, + 2.200765e-001, + -1.133253e-001, + 5.492505e-001, + -3.109391e+000, + 3.321914e-001, + -1.087444e+000, + -1.836263e-001, + 6.225024e-001, + -8.576765e+000, + -1.107637e+000, + 7.859427e-001, + 9.910909e-002, + 3.112938e+000, + 8.596261e-001, + -1.051544e+000, + -1.546262e-001, + 2.371731e-001, + 1.200502e+001, + -4.527291e+000, + 7.268862e-002, + 5.571478e-001, + 2.532873e+000, + 6.662000e-001, + // albedo 0, turbidity 8 + -1.375576e+000, + -4.840019e-001, + -8.121290e+000, + 8.058140e+000, + -1.445661e-002, + 5.123314e-001, + 5.813321e-002, + 3.203219e+000, + 5.442318e-001, + -2.325221e+000, + -1.241463e+000, + -7.063430e+000, + 8.741369e+000, + -7.829950e-002, + 8.844273e-001, + -3.471106e-002, + 1.740583e-001, + 2.814079e-001, + -1.228700e+000, + -2.013412e-001, + 2.949042e+000, + -7.371945e+000, + 1.071753e-001, + -2.491970e-001, + 2.265223e-001, + 6.391504e+000, + 1.172389e+000, + -7.601786e-001, + -1.680631e-001, + -7.584444e-001, + 8.541356e+000, + 8.222291e-002, + 6.729633e-001, + 3.206615e-001, + -3.700940e+000, + 2.710054e-001, + -1.191166e+000, + -2.672347e-001, + 2.927498e-001, + -9.713613e+000, + -4.783721e-001, + 2.352803e-001, + 2.161949e-001, + 2.691481e+000, + 8.745447e-001, + -1.030135e+000, + -1.653301e-001, + 2.263443e-001, + 1.296157e+001, + -4.650644e+000, + 7.055709e-003, + 5.091975e-001, + 2.000370e+000, + 6.603839e-001, + // albedo 0, turbidity 9 + -1.508018e+000, + -6.460933e-001, + -6.402745e+000, + 6.545995e+000, + -3.750320e-002, + 6.921803e-001, + 3.309819e-003, + 2.797527e+000, + 6.978446e-001, + -2.333308e+000, + -1.167837e+000, + -1.746787e+001, + 1.868630e+001, + -8.948229e-003, + 5.621946e-001, + -3.402626e-002, + 1.217943e+000, + 1.149865e-002, + -2.665953e+000, + -1.226307e+000, + 7.169725e+000, + -1.159434e+001, + 3.583420e-002, + -3.074378e-001, + 3.412248e-001, + 4.422122e+000, + 1.283791e+000, + -9.705116e-002, + 8.312991e-002, + -2.160462e+000, + 1.028235e+001, + 3.543357e-002, + 1.032049e+000, + 1.058310e-001, + -2.972898e+000, + 2.418628e-001, + -1.329617e+000, + -3.699557e-001, + 5.560117e-001, + -9.730113e+000, + 9.938865e-002, + -3.071488e-001, + 2.510691e-001, + 1.777111e+000, + 8.705142e-001, + -1.019387e+000, + -1.893247e-001, + 1.194079e-001, + 1.239436e+001, + -4.799224e+000, + 2.940213e-001, + 4.841268e-001, + 1.529724e+000, + 6.582615e-001, + // albedo 0, turbidity 10 + -1.896737e+000, + -1.005442e+000, + -6.411032e+000, + 6.548220e+000, + -3.227596e-002, + 5.717262e-001, + -8.115192e-006, + 2.296704e+000, + 9.000749e-001, + -2.411116e+000, + -1.225587e+000, + -1.753629e+001, + 1.829393e+001, + 1.247555e-002, + 2.364616e-001, + -5.114637e-003, + 1.603778e+000, + -2.224156e-001, + -4.707121e+000, + -2.074977e+000, + 7.942300e+000, + -1.132407e+001, + -5.415654e-002, + 5.446811e-001, + 1.032493e-001, + 4.010235e+000, + 1.369802e+000, + 1.010482e-001, + -4.013305e-001, + -2.674579e+000, + 9.779409e+000, + 1.782506e-001, + 7.053045e-001, + 4.200002e-001, + -2.400671e+000, + 1.953165e-001, + -1.243526e+000, + -3.391255e-001, + 8.848882e-001, + -9.789025e+000, + -3.997324e-001, + -9.546227e-001, + -1.044017e-001, + 6.010593e-001, + 8.714462e-001, + -1.014633e+000, + -1.730009e-001, + -7.738934e-002, + 1.390903e+001, + -4.847307e+000, + 1.076059e+000, + 5.685743e-001, + 1.572992e+000, + 6.561432e-001, + // albedo 1, turbidity 1 + -1.122998e+000, + -1.881183e-001, + -1.030709e+001, + 1.158932e+001, + -4.079495e-002, + 9.603774e-001, + 3.079436e-002, + 4.009235e+000, + 5.060745e-001, + -1.134790e+000, + -1.539688e-001, + 5.478405e+000, + -4.217270e+000, + -1.043858e-001, + 7.165008e-001, + 1.524765e-002, + 6.473623e+000, + 4.207882e-001, + -1.134957e+000, + -3.513318e-001, + 7.393837e-001, + 1.354415e+000, + -4.764078e-001, + 1.690441e+000, + -5.492640e-002, + -5.563523e+000, + 1.145743e+000, + -1.058344e+000, + -5.758503e-002, + 1.168230e+000, + 3.269824e-001, + 1.795193e-001, + 7.849011e-001, + 7.441853e-002, + 6.904804e+000, + 2.818790e-001, + -1.075194e+000, + -2.355813e-001, + 2.463685e+000, + -1.536505e+000, + -7.505771e+000, + 9.619712e-001, + -6.465851e-002, + -1.355492e+000, + 8.489847e-001, + -1.079030e+000, + -1.465328e-001, + 1.773838e+000, + 2.310131e+000, + -3.136065e+000, + 3.507952e-001, + 4.435014e-002, + 2.819225e+000, + 5.689008e-001, + // albedo 1, turbidity 2 + -1.125833e+000, + -1.870849e-001, + -9.555833e+000, + 1.059713e+001, + -4.225402e-002, + 9.164663e-001, + 4.338796e-002, + 4.400980e+000, + 6.056119e-001, + -1.127440e+000, + -1.551891e-001, + 4.755621e+000, + -4.408806e+000, + -7.851763e-002, + 2.268284e-001, + 1.460070e-001, + 7.048003e+000, + 3.525997e-001, + -1.143788e+000, + -3.170178e-001, + 5.480669e-001, + 2.041830e+000, + -4.532139e-001, + 2.302233e+000, + -1.887419e-001, + -4.489221e+000, + 1.250967e+000, + -1.032849e+000, + 7.376031e-003, + 5.666073e-001, + -2.312203e-001, + 4.862894e-001, + -1.748294e-001, + 3.572870e-001, + 8.380522e+000, + 1.302333e-001, + -1.093728e+000, + -2.786977e-001, + 2.641272e+000, + -1.507494e+000, + -8.731243e+000, + 1.684055e+000, + -2.023377e-001, + -2.176398e+000, + 1.013249e+000, + -1.076578e+000, + -1.456205e-001, + 1.693935e+000, + 2.945003e+000, + -2.822673e+000, + -2.520033e-001, + 1.517034e-001, + 2.649109e+000, + 5.179094e-001, + // albedo 1, turbidity 3 + -1.146417e+000, + -2.119353e-001, + -7.187525e+000, + 8.058599e+000, + -5.256438e-002, + 8.375733e-001, + 3.887093e-002, + 4.222111e+000, + 6.695347e-001, + -1.173674e+000, + -2.067025e-001, + 2.899359e+000, + -2.804918e+000, + -8.473899e-002, + 3.944225e-003, + 1.340641e-001, + 6.160887e+000, + 4.527141e-001, + -1.090098e+000, + -2.599633e-001, + 9.180856e-001, + 1.092710e+000, + -4.215019e-001, + 2.427660e+000, + -9.277667e-002, + -2.123523e+000, + 1.058159e+000, + -1.084460e+000, + 8.056181e-003, + -2.453510e-001, + 6.619567e-001, + 4.668118e-001, + -9.526719e-001, + 4.648454e-001, + 8.001572e+000, + 3.054194e-001, + -1.053728e+000, + -2.765784e-001, + 2.792388e+000, + -3.489517e+000, + -8.150535e+000, + 2.195757e+000, + -2.017234e-001, + -2.128017e+000, + 9.326589e-001, + -1.099348e+000, + -1.593939e-001, + 1.568292e+000, + 7.247853e+000, + -2.933000e+000, + -5.890481e-001, + 1.724440e-001, + 2.433484e+000, + 5.736558e-001, + // albedo 1, turbidity 4 + -1.185983e+000, + -2.581184e-001, + -7.761056e+000, + 8.317053e+000, + -3.351773e-002, + 6.676667e-001, + 5.941733e-002, + 3.820727e+000, + 6.324032e-001, + -1.268591e+000, + -3.398067e-001, + 2.348503e+000, + -2.023779e+000, + -5.368458e-002, + 1.083282e-001, + 8.402858e-002, + 3.910254e+000, + 5.577481e-001, + -1.071353e+000, + -1.992459e-001, + 7.878387e-001, + 1.974702e-001, + -3.033058e-001, + 2.335298e+000, + -8.205259e-002, + 7.954454e-001, + 9.972312e-001, + -1.089513e+000, + -3.104364e-002, + -5.995746e-001, + 2.330281e+000, + 6.581939e-001, + -1.821467e+000, + 6.679973e-001, + 5.090195e+000, + 3.125161e-001, + -1.040214e+000, + -2.570934e-001, + 2.660489e+000, + -6.506045e+000, + -7.053586e+000, + 2.763153e+000, + -2.433632e-001, + -7.648176e-001, + 9.452937e-001, + -1.116052e+000, + -1.831993e-001, + 1.457694e+000, + 1.163608e+001, + -3.216426e+000, + -1.045594e+000, + 2.285002e-001, + 1.817407e+000, + 5.810396e-001, + // albedo 1, turbidity 5 + -1.230134e+000, + -3.136264e-001, + -8.909301e+000, + 9.145006e+000, + -1.055387e-002, + 4.467317e-001, + 1.016826e-001, + 3.342964e+000, + 5.633840e-001, + -1.442907e+000, + -5.593147e-001, + 2.156447e+000, + -1.241657e+000, + -3.512130e-002, + 3.050274e-001, + 1.797175e-002, + 1.742358e+000, + 5.977153e-001, + -1.027627e+000, + -6.481539e-002, + 4.351975e-001, + -1.051677e+000, + -2.030672e-001, + 1.942684e+000, + -3.615993e-002, + 4.050266e+000, + 9.801624e-001, + -1.082110e+000, + -1.578209e-001, + -3.397511e-001, + 4.163851e+000, + 6.650368e-001, + -1.841730e+000, + 7.062544e-001, + 6.789881e-001, + 3.172623e-001, + -1.047447e+000, + -1.977560e-001, + 2.183364e+000, + -8.805249e+000, + -5.483962e+000, + 2.551309e+000, + -1.779640e-001, + 1.519501e+000, + 9.212536e-001, + -1.111853e+000, + -1.935736e-001, + 1.394408e+000, + 1.392405e+001, + -3.465430e+000, + -1.068432e+000, + 2.388671e-001, + 1.455336e+000, + 6.233425e-001, + // albedo 1, turbidity 6 + -1.262238e+000, + -3.546341e-001, + -1.008703e+001, + 1.020084e+001, + -1.852187e-003, + 3.537580e-001, + 1.239199e-001, + 3.056093e+000, + 5.132052e-001, + -1.613810e+000, + -7.355585e-001, + 2.760123e+000, + -1.685253e+000, + -2.517552e-002, + 2.914258e-001, + 4.743448e-003, + 8.689596e-001, + 5.674192e-001, + -9.462336e-001, + 2.950767e-002, + -2.613816e-001, + -7.398653e-001, + -1.315558e-001, + 1.901042e+000, + -6.447844e-002, + 4.969341e+000, + 1.027342e+000, + -1.111481e+000, + -2.194054e-001, + -9.004538e-002, + 3.983442e+000, + 4.871278e-001, + -1.965315e+000, + 7.956121e-001, + -2.363225e-001, + 2.718037e-001, + -1.036397e+000, + -1.827106e-001, + 1.964747e+000, + -8.870759e+000, + -4.208011e+000, + 2.461215e+000, + -2.158905e-001, + 1.561676e+000, + 9.436866e-001, + -1.113769e+000, + -1.947819e-001, + 1.300720e+000, + 1.516476e+001, + -4.088732e+000, + -1.069384e+000, + 2.836434e-001, + 1.671451e+000, + 6.229612e-001, + // albedo 1, turbidity 7 + -1.328069e+000, + -4.244047e-001, + -8.417040e+000, + 8.552244e+000, + -6.813504e-003, + 4.127422e-001, + 9.619897e-002, + 2.854227e+000, + 5.059880e-001, + -1.927552e+000, + -1.025290e+000, + 9.529576e-001, + 4.255950e-001, + -3.738779e-002, + 2.584586e-001, + 4.911004e-002, + -2.640913e-001, + 4.138626e-001, + -8.488094e-001, + 1.435988e-001, + 6.356807e-001, + -2.895732e+000, + -8.473961e-002, + 1.701305e+000, + -1.323908e-001, + 6.499338e+000, + 1.210928e+000, + -1.128313e+000, + -3.397048e-001, + -4.043140e-001, + 6.265097e+000, + 5.482395e-001, + -2.057614e+000, + 8.884087e-001, + -2.943879e+000, + 9.760301e-002, + -1.039764e+000, + -1.494772e-001, + 1.781915e+000, + -1.153012e+001, + -3.379232e+000, + 2.517231e+000, + -2.764393e-001, + 2.588849e+000, + 1.052120e+000, + -1.108447e+000, + -2.012251e-001, + 1.198640e+000, + 1.925331e+001, + -4.423892e+000, + -1.257122e+000, + 3.395690e-001, + 1.481220e+000, + 5.880175e-001, + // albedo 1, turbidity 8 + -1.374185e+000, + -4.967434e-001, + -7.401318e+000, + 7.724021e+000, + -2.345723e-002, + 5.979653e-001, + 2.436346e-002, + 2.658970e+000, + 6.014891e-001, + -2.310933e+000, + -1.290290e+000, + -1.301909e+000, + 2.557806e+000, + -3.744449e-002, + 8.982861e-002, + 1.090613e-001, + -4.398363e-001, + 1.184329e-001, + -1.124730e+000, + -9.921830e-002, + 1.366902e+000, + -4.172489e+000, + -5.078016e-002, + 1.393597e+000, + -9.323843e-002, + 6.452721e+000, + 1.435913e+000, + -8.468477e-001, + -2.744819e-001, + -4.347200e-001, + 6.713362e+000, + 6.127133e-001, + -1.685634e+000, + 7.360941e-001, + -4.535502e+000, + -2.920866e-002, + -1.165242e+000, + -2.008697e-001, + 1.438778e+000, + -1.008936e+001, + -2.214771e+000, + 2.102909e+000, + -1.763085e-001, + 2.859075e+000, + 1.093470e+000, + -1.074614e+000, + -2.066374e-001, + 1.131891e+000, + 1.630063e+001, + -4.801441e+000, + -1.112590e+000, + 3.595785e-001, + 1.122227e+000, + 5.794610e-001, + // albedo 1, turbidity 9 + -1.521515e+000, + -6.835604e-001, + -5.571044e+000, + 6.028774e+000, + -4.253715e-002, + 6.875746e-001, + -5.279456e-006, + 2.180150e+000, + 8.487705e-001, + -2.240415e+000, + -1.171166e+000, + -7.182771e+000, + 8.417068e+000, + -1.932866e-002, + 1.101887e-001, + -1.098862e-002, + 6.242195e-001, + -2.393875e-001, + -2.712354e+000, + -1.198830e+000, + 3.180200e+000, + -6.768130e+000, + -2.563386e-003, + 7.984607e-001, + 2.764376e-001, + 4.695358e+000, + 1.557045e+000, + -3.655172e-002, + -2.142321e-002, + -9.138120e-001, + 7.932786e+000, + 3.516542e-001, + -7.994343e-001, + 1.786761e-001, + -4.208399e+000, + 1.820576e-002, + -1.368610e+000, + -2.656212e-001, + 1.249397e+000, + -8.317818e+000, + -8.962772e-001, + 1.423249e+000, + 1.478381e-001, + 2.191660e+000, + 1.007748e+000, + -1.041753e+000, + -2.453366e-001, + 1.061102e+000, + 1.130172e+001, + -4.739312e+000, + -9.223334e-001, + 2.982776e-001, + 6.162931e-001, + 6.080302e-001, + // albedo 1, turbidity 10 + -1.989159e+000, + -1.095160e+000, + -2.915550e+000, + 3.275339e+000, + -5.735765e-002, + 5.742174e-001, + -7.683288e-006, + 1.763400e+000, + 9.001342e-001, + -2.070020e+000, + -1.086338e+000, + -1.095898e+001, + 1.206960e+001, + 3.780123e-002, + -1.774699e-002, + -5.881348e-004, + 1.333819e+000, + -2.605423e-001, + -5.249653e+000, + -2.383040e+000, + 6.160406e+000, + -9.097138e+000, + -1.955319e-001, + 1.651785e+000, + 6.016463e-004, + 3.021824e+000, + 1.493574e+000, + 4.685432e-001, + -2.358662e-001, + -2.666433e+000, + 9.685763e+000, + 5.804928e-001, + -1.521875e+000, + 5.668989e-001, + -1.548136e+000, + 1.688642e-002, + -1.296891e+000, + -3.449031e-001, + 1.928548e+000, + -1.167560e+001, + -1.627615e+000, + 1.355603e+000, + -1.929074e-001, + -6.568952e-001, + 1.009774e+000, + -1.067288e+000, + -2.410392e-001, + 7.147961e-001, + 1.783840e+001, + -4.374399e+000, + -6.588777e-001, + 3.329831e-001, + 1.012066e+000, + 6.118645e-001, +}; + +double datasetXYZRad2[] = +{ + // albedo 0, turbidity 1 + 1.632341e+000, + 1.395230e+000, + 1.375634e+000, + 1.238193e+001, + 5.921102e+000, + 7.766508e+000, + // albedo 0, turbidity 2 + 1.597115e+000, + 1.554617e+000, + 3.932382e-001, + 1.505284e+001, + 5.725234e+000, + 8.158155e+000, + // albedo 0, turbidity 3 + 1.522034e+000, + 1.844545e+000, + -1.322862e+000, + 1.918382e+001, + 5.440769e+000, + 8.837119e+000, + // albedo 0, turbidity 4 + 1.403048e+000, + 2.290852e+000, + -4.013792e+000, + 2.485100e+001, + 5.521888e+000, + 9.845547e+000, + // albedo 0, turbidity 5 + 1.286364e+000, + 2.774498e+000, + -6.648221e+000, + 2.964151e+001, + 5.923777e+000, + 1.097075e+001, + // albedo 0, turbidity 6 + 1.213544e+000, + 3.040195e+000, + -8.092676e+000, + 3.186082e+001, + 6.789782e+000, + 1.158899e+001, + // albedo 0, turbidity 7 + 1.122622e+000, + 3.347465e+000, + -9.649016e+000, + 3.343824e+001, + 9.347715e+000, + 1.231374e+001, + // albedo 0, turbidity 8 + 1.007356e+000, + 3.543858e+000, + -1.053520e+001, + 3.239842e+001, + 1.483962e+001, + 1.331718e+001, + // albedo 0, turbidity 9 + 8.956642e-001, + 3.278700e+000, + -9.254933e+000, + 2.557923e+001, + 2.489677e+001, + 1.476166e+001, + // albedo 0, turbidity 10 + 7.985143e-001, + 2.340404e+000, + -4.928274e+000, + 1.141787e+001, + 3.961501e+001, + 1.682448e+001, + // albedo 1, turbidity 1 + 1.745162e+000, + 1.639467e+000, + 1.342721e+000, + 1.166033e+001, + 1.490124e+001, + 1.774031e+001, + // albedo 1, turbidity 2 + 1.708439e+000, + 1.819144e+000, + 2.834399e-001, + 1.448066e+001, + 1.459214e+001, + 1.858679e+001, + // albedo 1, turbidity 3 + 1.631720e+000, + 2.094799e+000, + -1.378825e+000, + 1.843198e+001, + 1.463173e+001, + 1.962881e+001, + // albedo 1, turbidity 4 + 1.516536e+000, + 2.438729e+000, + -3.624121e+000, + 2.298621e+001, + 1.599782e+001, + 2.070027e+001, + // albedo 1, turbidity 5 + 1.405863e+000, + 2.785191e+000, + -5.705236e+000, + 2.645121e+001, + 1.768330e+001, + 2.191903e+001, + // albedo 1, turbidity 6 + 1.344052e+000, + 2.951807e+000, + -6.683851e+000, + 2.744271e+001, + 1.985706e+001, + 2.229452e+001, + // albedo 1, turbidity 7 + 1.245827e+000, + 3.182923e+000, + -7.822960e+000, + 2.791395e+001, + 2.327254e+001, + 2.315910e+001, + // albedo 1, turbidity 8 + 1.132305e+000, + 3.202593e+000, + -8.008429e+000, + 2.521093e+001, + 3.000014e+001, + 2.405306e+001, + // albedo 1, turbidity 9 + 1.020330e+000, + 2.820556e+000, + -6.238704e+000, + 1.709276e+001, + 4.077916e+001, + 2.509949e+001, + // albedo 1, turbidity 10 + 9.031570e-001, + 1.863917e+000, + -1.955738e+000, + 3.032665e+000, + 5.434290e+001, + 2.641780e+001, +}; + +double datasetXYZ3[] = +{ + // albedo 0, turbidity 1 + -1.310023e+000, + -4.407658e-001, + -3.640340e+001, + 3.683292e+001, + -8.124762e-003, + 5.297961e-001, + 1.188633e-002, + 3.138320e+000, + 5.134778e-001, + -1.424100e+000, + -5.501606e-001, + -1.753510e+001, + 1.822769e+001, + -1.539272e-002, + 6.366826e-001, + 2.661996e-003, + 2.659915e+000, + 4.071138e-001, + -1.103436e+000, + -1.884105e-001, + 6.425322e+000, + -6.910579e+000, + -2.019861e-002, + 3.553271e-001, + -1.589061e-002, + 5.345985e+000, + 8.790218e-001, + -1.186200e+000, + -4.307514e-001, + -3.957947e+000, + 5.979352e+000, + -5.348869e-002, + 1.736117e+000, + 3.491346e-002, + -2.692261e+000, + 5.610506e-001, + -1.006038e+000, + -1.305995e-001, + 4.473513e+000, + -3.806719e+000, + 1.419407e-001, + -2.148238e-002, + -5.081185e-002, + 3.735362e+000, + 5.358280e-001, + -1.078507e+000, + -1.633754e-001, + -3.812368e+000, + 4.381700e+000, + 2.988122e-002, + 1.754224e+000, + 1.472376e-001, + 3.722798e+000, + 4.999157e-001, + // albedo 0, turbidity 2 + -1.333582e+000, + -4.649908e-001, + -3.359528e+001, + 3.404375e+001, + -9.384242e-003, + 5.587511e-001, + 5.726310e-003, + 3.073145e+000, + 5.425529e-001, + -1.562624e+000, + -7.107068e-001, + -1.478170e+001, + 1.559839e+001, + -1.462375e-002, + 5.050133e-001, + 2.516017e-002, + 1.604696e+000, + 2.902403e-001, + -8.930158e-001, + 4.068077e-002, + 1.373481e+000, + -2.342752e+000, + -2.098058e-002, + 6.248686e-001, + -5.258363e-002, + 7.058214e+000, + 1.150373e+000, + -1.262823e+000, + -4.818353e-001, + 8.892610e-004, + 1.923120e+000, + -4.979718e-002, + 1.040693e+000, + 1.558103e-001, + -2.852480e+000, + 2.420691e-001, + -9.968383e-001, + -1.200648e-001, + 1.324342e+000, + -9.430889e-001, + 1.931098e-001, + 4.436916e-001, + -7.320456e-002, + 4.215931e+000, + 7.898019e-001, + -1.078185e+000, + -1.718192e-001, + -1.720191e+000, + 2.358918e+000, + 2.765637e-002, + 1.260245e+000, + 2.021941e-001, + 3.395483e+000, + 5.173628e-001, + // albedo 0, turbidity 3 + -1.353023e+000, + -4.813523e-001, + -3.104920e+001, + 3.140156e+001, + -9.510741e-003, + 5.542030e-001, + 8.135471e-003, + 3.136646e+000, + 5.215989e-001, + -1.624704e+000, + -7.990201e-001, + -2.167125e+001, + 2.246341e+001, + -1.163533e-002, + 5.415746e-001, + 2.618378e-002, + 1.139214e+000, + 3.444357e-001, + -7.983610e-001, + 1.417476e-001, + 9.914841e+000, + -1.081503e+001, + -1.218845e-002, + 3.411392e-001, + -6.137698e-002, + 7.445848e+000, + 1.180080e+000, + -1.266679e+000, + -4.288977e-001, + -5.818701e+000, + 6.986437e+000, + -8.180711e-002, + 1.397403e+000, + 2.016916e-001, + -1.275731e+000, + 2.592773e-001, + -1.009707e+000, + -1.537754e-001, + 3.496378e+000, + -3.013726e+000, + 2.421150e-001, + -2.831925e-001, + 3.003395e-002, + 3.702862e+000, + 7.746320e-001, + -1.075646e+000, + -1.768747e-001, + -1.347762e+000, + 1.989004e+000, + 1.375836e-002, + 1.764810e+000, + 1.330018e-001, + 3.230864e+000, + 6.626210e-001, + // albedo 0, turbidity 4 + -1.375269e+000, + -5.103569e-001, + -3.442661e+001, + 3.478703e+001, + -8.460009e-003, + 5.408643e-001, + 4.813323e-003, + 3.016078e+000, + 5.062069e-001, + -1.821679e+000, + -9.766461e-001, + -1.926488e+001, + 1.997912e+001, + -9.822567e-003, + 3.649556e-001, + 4.316092e-002, + 8.930190e-001, + 4.166527e-001, + -6.633542e-001, + 1.997841e-001, + 2.395592e+000, + -3.117175e+000, + -1.080884e-002, + 8.983814e-001, + -1.375825e-001, + 6.673463e+000, + 1.115663e+000, + -1.303240e+000, + -3.612712e-001, + 8.292959e-002, + 3.381364e-001, + -6.078648e-002, + 3.229247e-001, + 3.680987e-001, + 7.046755e-001, + 3.144924e-001, + -9.952598e-001, + -2.039076e-001, + 4.026851e-001, + 2.686684e-001, + 1.640712e-001, + 5.186341e-001, + -1.205520e-002, + 2.659613e+000, + 8.030394e-001, + -1.098579e+000, + -2.151992e-001, + 6.558198e-001, + -7.436900e-004, + -1.421817e-003, + 1.073701e+000, + 1.886875e-001, + 2.536857e+000, + 6.673923e-001, + // albedo 0, turbidity 5 + -1.457986e+000, + -5.906842e-001, + -3.812464e+001, + 3.838539e+001, + -6.024357e-003, + 4.741484e-001, + 1.209223e-002, + 2.818432e+000, + 5.012433e-001, + -1.835728e+000, + -1.003405e+000, + -6.848129e+000, + 7.601943e+000, + -1.277375e-002, + 4.785598e-001, + 3.366853e-002, + 1.097701e+000, + 4.636635e-001, + -8.491348e-001, + 9.466365e-003, + -2.685226e+000, + 2.004060e+000, + -1.168708e-002, + 6.752316e-001, + -1.543371e-001, + 5.674759e+000, + 1.039534e+000, + -1.083379e+000, + -1.506790e-001, + 7.328236e-001, + -5.095568e-001, + -8.609153e-002, + 4.448820e-001, + 4.174662e-001, + 1.481556e+000, + 3.942551e-001, + -1.117089e+000, + -3.337605e-001, + 2.502281e-001, + 4.036323e-001, + 2.673899e-001, + 2.829817e-001, + 2.242450e-002, + 2.043207e+000, + 7.706902e-001, + -1.071648e+000, + -2.126200e-001, + 6.069466e-001, + -1.456290e-003, + -5.515960e-001, + 1.046755e+000, + 1.985021e-001, + 2.290245e+000, + 6.876058e-001, + // albedo 0, turbidity 6 + -1.483903e+000, + -6.309647e-001, + -4.380213e+001, + 4.410537e+001, + -5.712161e-003, + 5.195992e-001, + 2.028428e-003, + 2.687114e+000, + 5.098321e-001, + -2.053976e+000, + -1.141473e+000, + 5.109183e-001, + 8.060391e-002, + -1.033983e-002, + 4.066532e-001, + 4.869627e-002, + 1.161722e+000, + 4.039525e-001, + -6.348185e-001, + 7.651292e-002, + -1.031327e+001, + 1.007598e+001, + -2.083688e-002, + 7.359516e-001, + -2.029459e-001, + 5.013257e+000, + 1.077649e+000, + -1.228630e+000, + -1.650496e-001, + 4.077157e-002, + -7.189167e-001, + -5.092220e-002, + 2.959814e-001, + 5.111496e-001, + 2.540433e+000, + 3.615330e-001, + -1.041883e+000, + -3.278413e-001, + -6.691911e-002, + 1.307364e+000, + 2.166663e-001, + 3.000595e-001, + -3.157136e-003, + 1.389208e+000, + 7.999026e-001, + -1.103556e+000, + -2.443602e-001, + 4.705347e-001, + -9.296482e-004, + -5.309920e-001, + 9.654511e-001, + 2.142587e-001, + 2.244723e+000, + 6.839976e-001, + // albedo 0, turbidity 7 + -1.555684e+000, + -6.962113e-001, + -4.647983e+001, + 4.674270e+001, + -5.034895e-003, + 4.755090e-001, + -9.502561e-007, + 2.626569e+000, + 5.056194e-001, + -1.998288e+000, + -1.124720e+000, + -1.629586e+000, + 2.187993e+000, + -8.284384e-003, + 3.845258e-001, + 5.726240e-002, + 1.185644e+000, + 4.255812e-001, + -1.032570e+000, + -2.513850e-001, + -3.721112e+000, + 3.506967e+000, + -2.186561e-002, + 9.436049e-001, + -2.451412e-001, + 4.725724e+000, + 1.039256e+000, + -8.597532e-001, + 9.073332e-002, + -2.553741e+000, + 1.993237e+000, + -4.390891e-002, + -2.046928e-001, + 5.515623e-001, + 1.909127e+000, + 3.948212e-001, + -1.210482e+000, + -4.477622e-001, + -2.267805e-001, + 1.219488e+000, + 1.336186e-001, + 6.866897e-001, + 2.808997e-002, + 1.600403e+000, + 7.816409e-001, + -1.078168e+000, + -2.699261e-001, + 2.537282e-001, + 3.820684e-001, + -4.425103e-001, + 5.298235e-001, + 2.185217e-001, + 1.728679e+000, + 6.882743e-001, + // albedo 0, turbidity 8 + -1.697968e+000, + -8.391488e-001, + -5.790105e+001, + 5.814120e+001, + -3.404760e-003, + 4.265140e-001, + -1.796301e-006, + 2.368442e+000, + 5.324429e-001, + -2.141552e+000, + -1.172230e+000, + 1.677872e+001, + -1.641470e+001, + -5.732425e-003, + 2.002199e-001, + 6.841834e-002, + 1.485338e+000, + 3.215763e-001, + -1.442946e+000, + -7.264245e-001, + -9.503706e+000, + 9.650462e+000, + -2.120995e-002, + 1.419263e+000, + -2.893098e-001, + 3.860731e+000, + 1.120857e+000, + -5.696752e-001, + 3.411279e-001, + -2.931035e-001, + -6.512552e-001, + -1.068437e-001, + -1.085661e+000, + 6.107549e-001, + 1.459503e+000, + 3.210336e-001, + -1.313839e+000, + -5.921371e-001, + -2.332222e-001, + 1.648196e+000, + 2.492787e-001, + 1.381033e+000, + -1.993392e-002, + 9.812560e-001, + 8.316329e-001, + -1.087464e+000, + -3.195534e-001, + 2.902095e-001, + 3.383709e-001, + -8.798482e-001, + 1.494668e-002, + 2.529703e-001, + 1.452644e+000, + 6.693870e-001, + // albedo 0, turbidity 9 + -2.068582e+000, + -1.118605e+000, + -5.081598e+001, + 5.097486e+001, + -3.280669e-003, + 4.067371e-001, + -2.544951e-006, + 2.179497e+000, + 5.778017e-001, + -1.744693e+000, + -8.537207e-001, + 2.234361e+001, + -2.208318e+001, + -5.932616e-003, + 1.035049e-001, + 5.742772e-002, + 1.977880e+000, + 2.124846e-001, + -3.287515e+000, + -2.140268e+000, + -1.249566e+001, + 1.240091e+001, + -2.409349e-002, + 1.397821e+000, + -2.371627e-001, + 2.771192e+000, + 1.170496e+000, + 5.502311e-001, + 1.046630e+000, + 2.193517e+000, + -2.220400e+000, + -1.064394e-001, + -1.017926e+000, + 4.795457e-001, + 1.030644e+000, + 3.177516e-001, + -1.719734e+000, + -9.536198e-001, + -6.586821e-001, + 1.386361e+000, + -2.513065e-002, + 1.187011e+000, + 6.542539e-002, + 5.296055e-001, + 8.082660e-001, + -1.005700e+000, + -3.028096e-001, + 4.470957e-002, + 1.007760e+000, + -8.119016e-001, + 3.153338e-002, + 2.311321e-001, + 1.182208e+000, + 6.824758e-001, + // albedo 0, turbidity 10 + -2.728867e+000, + -1.580388e+000, + -3.079627e+001, + 3.092586e+001, + -4.197673e-003, + 3.154759e-001, + -3.897675e-006, + 1.920567e+000, + 6.664791e-001, + -1.322495e+000, + -7.249275e-001, + 1.477660e+001, + -1.468154e+001, + -9.044857e-003, + 5.624314e-002, + 6.498392e-002, + 2.047389e+000, + 6.367540e-002, + -6.102376e+000, + -3.473018e+000, + -9.926071e+000, + 9.637797e+000, + -1.097909e-002, + 1.103498e+000, + -2.424521e-001, + 2.520748e+000, + 1.240260e+000, + 1.351796e+000, + 1.018588e+000, + 2.009081e+000, + -1.333394e+000, + -1.979125e-001, + -3.318292e-001, + 4.476624e-001, + 9.095235e-001, + 2.955611e-001, + -1.774467e+000, + -1.079880e+000, + -8.084680e-002, + 2.577697e-001, + -1.149295e-001, + 4.975303e-001, + 2.931611e-003, + -3.803171e-001, + 8.002794e-001, + -9.898401e-001, + -2.542513e-001, + -7.530911e-002, + 1.870355e+000, + -1.521918e+000, + 2.405164e-001, + 2.964615e-001, + 1.334800e+000, + 6.789053e-001, + // albedo 1, turbidity 1 + -1.279730e+000, + -4.290674e-001, + -4.277972e+001, + 4.343305e+001, + -6.541826e-003, + 4.945086e-001, + 1.425338e-002, + 2.685244e+000, + 5.011313e-001, + -1.449506e+000, + -5.766374e-001, + -1.688496e+001, + 1.781118e+001, + -1.121649e-002, + 3.545020e-001, + 2.287338e-002, + 1.904281e+000, + 4.936998e-001, + -1.021980e+000, + -1.897574e-001, + 2.482462e+000, + -2.941725e+000, + -1.570448e-002, + 7.532578e-001, + -4.256800e-002, + 5.239660e+000, + 4.983116e-001, + -1.162608e+000, + -3.428049e-001, + 3.974358e+000, + -1.527935e+000, + -3.919201e-002, + 8.758593e-001, + 7.291363e-002, + -3.455257e+000, + 8.007426e-001, + -9.929985e-001, + -8.712006e-002, + -7.397313e-001, + 1.348372e+000, + 9.511685e-002, + 3.233584e-001, + -7.549148e-002, + 5.806452e+000, + 4.990042e-001, + -1.084996e+000, + -1.739767e-001, + 1.580475e-001, + 9.088180e-001, + 6.871433e-002, + 5.933079e-001, + 1.188921e-001, + 3.074079e+000, + 4.999327e-001, + // albedo 1, turbidity 2 + -1.317009e+000, + -4.661946e-001, + -4.255347e+001, + 4.312782e+001, + -5.727235e-003, + 4.285447e-001, + 2.189854e-002, + 2.608310e+000, + 5.190700e-001, + -1.469236e+000, + -6.282139e-001, + -1.241404e+001, + 1.348765e+001, + -1.204770e-002, + 5.070285e-001, + -7.280216e-004, + 1.491533e+000, + 3.635064e-001, + -9.713808e-001, + -8.138038e-002, + 3.709854e-001, + -1.041174e+000, + -1.814075e-002, + 5.060860e-001, + -2.053756e-002, + 6.161431e+000, + 1.093736e+000, + -1.159057e+000, + -3.698074e-001, + 2.711209e+000, + -6.006479e-001, + -4.896926e-002, + 9.273957e-001, + 1.137712e-001, + -3.496828e+000, + 2.867109e-001, + -1.011601e+000, + -8.201890e-002, + 2.105725e-001, + 4.597520e-001, + 1.478925e-001, + 2.138940e-001, + -5.660670e-002, + 6.057755e+000, + 7.859121e-001, + -1.078020e+000, + -1.811580e-001, + 1.646622e-001, + 8.348426e-001, + 1.149064e-001, + 4.985738e-001, + 1.376605e-001, + 2.746607e+000, + 4.999626e-001, + // albedo 1, turbidity 3 + -1.325672e+000, + -4.769313e-001, + -4.111215e+001, + 4.168293e+001, + -6.274997e-003, + 4.649469e-001, + 1.119411e-002, + 2.631267e+000, + 5.234546e-001, + -1.619391e+000, + -8.000253e-001, + -1.534098e+001, + 1.632706e+001, + -1.012023e-002, + 4.242255e-001, + 2.931597e-002, + 8.925807e-001, + 3.314765e-001, + -7.356979e-001, + 1.368406e-001, + 2.972579e+000, + -3.535359e+000, + -1.318948e-002, + 4.607620e-001, + -7.182778e-002, + 6.254100e+000, + 1.236299e+000, + -1.316217e+000, + -4.194427e-001, + 3.489902e-002, + 1.289849e+000, + -4.755960e-002, + 1.138222e+000, + 1.975992e-001, + -8.991542e-001, + 2.290572e-001, + -9.502188e-001, + -1.172703e-001, + 1.405202e+000, + -3.061919e-001, + 1.058772e-001, + -3.760592e-001, + -1.983179e-002, + 3.562353e+000, + 7.895959e-001, + -1.100117e+000, + -1.900567e-001, + 4.925030e-001, + 5.250225e-001, + 1.576804e-001, + 1.042701e+000, + 7.330743e-002, + 2.796064e+000, + 6.749783e-001, + // albedo 1, turbidity 4 + -1.354183e+000, + -5.130625e-001, + -4.219268e+001, + 4.271772e+001, + -5.365373e-003, + 4.136743e-001, + 1.235172e-002, + 2.520122e+000, + 5.187269e-001, + -1.741434e+000, + -9.589761e-001, + -8.230339e+000, + 9.296799e+000, + -9.600162e-003, + 4.994969e-001, + 2.955452e-002, + 3.667099e-001, + 3.526999e-001, + -6.917347e-001, + 2.154887e-001, + -8.760264e-001, + 2.334121e-001, + -1.909621e-002, + 4.748033e-001, + -1.138514e-001, + 6.515360e+000, + 1.225097e+000, + -1.293189e+000, + -4.218700e-001, + 1.620952e+000, + -7.858597e-001, + -3.769410e-002, + 6.636786e-001, + 3.364945e-001, + -5.341017e-001, + 2.128347e-001, + -9.735521e-001, + -1.325495e-001, + 1.007517e+000, + 2.598258e-001, + 6.762169e-002, + 1.421018e-003, + -6.915987e-002, + 3.185897e+000, + 8.641956e-001, + -1.094800e+000, + -1.962062e-001, + 5.755591e-001, + 2.906259e-001, + 2.625748e-001, + 7.644049e-001, + 1.347492e-001, + 2.677126e+000, + 6.465460e-001, + // albedo 1, turbidity 5 + -1.393063e+000, + -5.578338e-001, + -4.185249e+001, + 4.233504e+001, + -5.435640e-003, + 4.743765e-001, + 7.422477e-003, + 2.442801e+000, + 5.211707e-001, + -1.939487e+000, + -1.128509e+000, + -8.974257e+000, + 9.978383e+000, + -7.965597e-003, + 2.948830e-001, + 4.436763e-002, + 2.839868e-001, + 3.440424e-001, + -6.011562e-001, + 2.354877e-001, + -3.079820e+000, + 2.585094e+000, + -2.002701e-002, + 7.793909e-001, + -1.598414e-001, + 5.834678e+000, + 1.202856e+000, + -1.315676e+000, + -3.903446e-001, + 1.701900e+000, + -1.304609e+000, + -1.045121e-002, + 2.747707e-001, + 4.143967e-001, + 3.197102e-001, + 2.637580e-001, + -9.618628e-001, + -1.625841e-001, + 1.187138e+000, + 1.497802e-001, + -5.590954e-006, + 3.178475e-002, + -4.153145e-002, + 2.496096e+000, + 8.195082e-001, + -1.111554e+000, + -2.365546e-001, + 7.831875e-001, + 2.018684e-001, + 2.074369e-001, + 7.395978e-001, + 1.225730e-001, + 1.876478e+000, + 6.821167e-001, + // albedo 1, turbidity 6 + -1.427879e+000, + -5.994879e-001, + -3.531016e+001, + 3.581581e+001, + -6.431497e-003, + 4.554192e-001, + 7.348731e-004, + 2.334619e+000, + 5.233377e-001, + -1.998177e+000, + -1.206633e+000, + -2.146510e+001, + 2.242237e+001, + -5.857596e-003, + 2.755663e-001, + 6.384795e-002, + 1.358244e-001, + 3.328437e-001, + -6.440630e-001, + 2.058571e-001, + 2.155499e+000, + -2.587968e+000, + -1.840023e-002, + 8.826555e-001, + -2.222452e-001, + 5.847073e+000, + 1.228387e+000, + -1.229071e+000, + -3.360441e-001, + -3.429599e-001, + 6.179469e-001, + 2.029610e-003, + 8.899319e-002, + 5.041624e-001, + 1.882964e-001, + 2.252040e-001, + -1.022905e+000, + -2.101621e-001, + 1.915689e+000, + -6.498794e-001, + -3.463651e-002, + 8.954605e-002, + -6.797854e-002, + 2.417705e+000, + 8.568618e-001, + -1.082538e+000, + -2.007723e-001, + 4.731009e-001, + 4.077267e-001, + 1.324289e-001, + 6.514880e-001, + 1.702912e-001, + 2.309383e+000, + 6.600895e-001, + // albedo 1, turbidity 7 + -1.472139e+000, + -6.499815e-001, + -3.428465e+001, + 3.469659e+001, + -5.747023e-003, + 4.174167e-001, + 1.688597e-003, + 2.323046e+000, + 5.395191e-001, + -2.161176e+000, + -1.353089e+000, + -2.226827e+001, + 2.329138e+001, + -5.583808e-003, + 2.364793e-001, + 6.096656e-002, + 1.944666e-003, + 2.861624e-001, + -6.593044e-001, + 1.393558e-001, + 4.698373e+000, + -5.193883e+000, + -1.998390e-002, + 1.095635e+000, + -2.391254e-001, + 5.598103e+000, + 1.236193e+000, + -1.195717e+000, + -2.972715e-001, + 4.648953e-002, + 3.024588e-001, + 5.003313e-003, + -3.754741e-001, + 5.247265e-001, + -1.381312e-001, + 2.493896e-001, + -1.020139e+000, + -2.253524e-001, + 3.548437e-001, + 7.030485e-001, + -2.107076e-002, + 4.581395e-001, + -3.243757e-002, + 2.453259e+000, + 8.323623e-001, + -1.098770e+000, + -2.435780e-001, + 8.761614e-001, + 1.941613e-001, + -1.990692e-001, + 3.761139e-001, + 1.657412e-001, + 1.590503e+000, + 6.741417e-001, + // albedo 1, turbidity 8 + -1.648007e+000, + -8.205121e-001, + -4.435106e+001, + 4.479801e+001, + -4.181353e-003, + 3.854830e-001, + -1.842385e-006, + 2.000281e+000, + 5.518363e-001, + -2.140986e+000, + -1.282239e+000, + -3.979213e+000, + 4.672459e+000, + -5.008582e-003, + 2.421920e-001, + 6.253602e-002, + 6.612713e-001, + 2.555851e-001, + -1.300502e+000, + -5.137898e-001, + 5.179821e-001, + -4.032341e-001, + -2.066785e-002, + 1.087929e+000, + -2.615309e-001, + 4.225887e+000, + 1.229237e+000, + -6.963340e-001, + 9.241060e-002, + 6.936356e-002, + -3.588571e-001, + -5.461843e-002, + -5.616643e-001, + 5.484166e-001, + -4.776267e-002, + 2.414935e-001, + -1.233179e+000, + -4.325498e-001, + 6.479813e-001, + 8.368356e-001, + 2.458875e-001, + 6.464752e-001, + -2.897097e-002, + 1.561773e+000, + 8.518598e-001, + -1.051023e+000, + -2.533690e-001, + 1.004294e+000, + 3.028083e-001, + -1.520108e+000, + 1.607013e-001, + 1.619975e-001, + 1.131094e+000, + 6.706655e-001, + // albedo 1, turbidity 9 + -1.948249e+000, + -1.097383e+000, + -4.453697e+001, + 4.494902e+001, + -3.579939e-003, + 3.491605e-001, + -2.500253e-006, + 1.740442e+000, + 6.188022e-001, + -2.154253e+000, + -1.209559e+000, + 4.144894e+000, + -3.562411e+000, + -5.638843e-003, + 1.067169e-001, + 7.594858e-002, + 1.005280e+000, + 1.072543e-001, + -2.513259e+000, + -1.507208e+000, + -1.602979e+000, + 1.404154e+000, + -5.560750e-003, + 1.240490e+000, + -2.852117e-001, + 3.485252e+000, + 1.349321e+000, + -7.832214e-002, + 3.655626e-001, + 3.856288e-001, + 6.867894e-001, + -1.609523e-001, + -6.704306e-001, + 5.357301e-001, + -6.457935e-001, + 1.479503e-001, + -1.354784e+000, + -5.454375e-001, + 8.797469e-001, + -1.466514e+000, + 7.134420e-001, + 5.934903e-001, + -2.911178e-002, + 8.643737e-001, + 9.030724e-001, + -1.048324e+000, + -2.738736e-001, + 8.783074e-001, + 3.246188e+000, + -4.435369e+000, + 1.251791e-001, + 1.783486e-001, + 1.064657e+000, + 6.522878e-001, + // albedo 1, turbidity 10 + -2.770408e+000, + -1.618911e+000, + -2.504031e+001, + 2.531674e+001, + -4.239279e-003, + 3.241013e-001, + -3.764484e-006, + 1.586843e+000, + 7.035906e-001, + -1.913500e+000, + -1.144014e+000, + -1.080587e+001, + 1.153677e+001, + -1.003197e-002, + 1.577515e-001, + 5.217789e-002, + 1.225278e+000, + 5.172771e-003, + -5.293208e+000, + -2.876463e+000, + 2.087053e+000, + -3.201552e+000, + 3.892964e-003, + 5.323930e-001, + -2.034512e-001, + 2.617760e+000, + 1.273597e+000, + 9.060340e-001, + 3.773409e-001, + -6.399945e-001, + 3.213979e+000, + -9.112172e-002, + 6.494055e-001, + 3.953280e-001, + 5.047796e-001, + 2.998695e-001, + -1.482179e+000, + -6.778310e-001, + 1.161775e+000, + -3.004872e+000, + 4.774797e-001, + -4.969248e-001, + -3.512074e-003, + -1.307190e+000, + 7.927378e-001, + -9.863181e-001, + -1.803364e-001, + 5.810824e-001, + 4.580570e+000, + -3.863454e+000, + 5.328174e-001, + 2.272821e-001, + 1.771114e+000, + 6.791814e-001, +}; + +double datasetXYZRad3[] = +{ + // albedo 0, turbidity 1 + 1.168084e+000, + 2.156455e+000, + -3.980314e+000, + 1.989302e+001, + 1.328335e+001, + 1.435621e+001, + // albedo 0, turbidity 2 + 1.135488e+000, + 2.294701e+000, + -4.585886e+000, + 2.090208e+001, + 1.347840e+001, + 1.467658e+001, + // albedo 0, turbidity 3 + 1.107408e+000, + 2.382765e+000, + -5.112357e+000, + 2.147823e+001, + 1.493128e+001, + 1.460882e+001, + // albedo 0, turbidity 4 + 1.054193e+000, + 2.592891e+000, + -6.115000e+000, + 2.268967e+001, + 1.635672e+001, + 1.518999e+001, + // albedo 0, turbidity 5 + 1.006946e+000, + 2.705420e+000, + -6.698930e+000, + 2.291830e+001, + 1.834324e+001, + 1.570651e+001, + // albedo 0, turbidity 6 + 9.794044e-001, + 2.742440e+000, + -6.805283e+000, + 2.225271e+001, + 2.050797e+001, + 1.563130e+001, + // albedo 0, turbidity 7 + 9.413577e-001, + 2.722009e+000, + -6.760707e+000, + 2.098242e+001, + 2.342588e+001, + 1.605011e+001, + // albedo 0, turbidity 8 + 8.917923e-001, + 2.592780e+000, + -6.152635e+000, + 1.774141e+001, + 2.858324e+001, + 1.657910e+001, + // albedo 0, turbidity 9 + 8.288391e-001, + 2.153434e+000, + -4.118327e+000, + 1.078118e+001, + 3.681710e+001, + 1.738139e+001, + // albedo 0, turbidity 10 + 7.623528e-001, + 1.418187e+000, + -8.845235e-001, + 7.590129e-001, + 4.629859e+001, + 1.921657e+001, + // albedo 1, turbidity 1 + 1.352858e+000, + 2.048862e+000, + -2.053393e+000, + 1.405874e+001, + 3.045344e+001, + 3.044430e+001, + // albedo 1, turbidity 2 + 1.330497e+000, + 2.126497e+000, + -2.466296e+000, + 1.467559e+001, + 3.090738e+001, + 3.069707e+001, + // albedo 1, turbidity 3 + 1.286344e+000, + 2.200436e+000, + -2.877228e+000, + 1.492701e+001, + 3.236288e+001, + 3.077223e+001, + // albedo 1, turbidity 4 + 1.234428e+000, + 2.289628e+000, + -3.404699e+000, + 1.499436e+001, + 3.468390e+001, + 3.084842e+001, + // albedo 1, turbidity 5 + 1.178660e+000, + 2.306071e+000, + -3.549159e+000, + 1.411006e+001, + 3.754188e+001, + 3.079730e+001, + // albedo 1, turbidity 6 + 1.151366e+000, + 2.333005e+000, + -3.728627e+000, + 1.363374e+001, + 3.905894e+001, + 3.092599e+001, + // albedo 1, turbidity 7 + 1.101593e+000, + 2.299422e+000, + -3.565787e+000, + 1.196745e+001, + 4.188472e+001, + 3.102755e+001, + // albedo 1, turbidity 8 + 1.038322e+000, + 2.083539e+000, + -2.649585e+000, + 8.037389e+000, + 4.700869e+001, + 3.065948e+001, + // albedo 1, turbidity 9 + 9.596146e-001, + 1.671470e+000, + -8.751538e-001, + 1.679772e+000, + 5.345784e+001, + 3.054520e+001, + // albedo 1, turbidity 10 + 8.640731e-001, + 9.858301e-001, + 1.854956e+000, + -6.798097e+000, + 5.936468e+001, + 3.110255e+001, +}; + + + +double* datasetsXYZ[] = +{ + datasetXYZ1, + datasetXYZ2, + datasetXYZ3 +}; + +double* datasetsXYZRad[] = +{ + datasetXYZRad1, + datasetXYZRad2, + datasetXYZRad3 +}; diff --git a/rpplugins/scattering/resources/hosek_wilkie_scattering/source/ArHosekSkyModelData_RGB.data b/rpplugins/scattering/resources/hosek_wilkie_scattering/source/ArHosekSkyModelData_RGB.data new file mode 100644 index 0000000..3cd1b90 --- /dev/null +++ b/rpplugins/scattering/resources/hosek_wilkie_scattering/source/ArHosekSkyModelData_RGB.data @@ -0,0 +1,3861 @@ +/* +This source is published under the following 3-clause BSD license. + +Copyright (c) 2012 - 2013, Lukas Hosek and Alexander Wilkie +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + + * Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + * None of the names of the contributors may be used to endorse or promote + products derived from this software without specific prior written + permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY +DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND +ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +*/ + + +/* ============================================================================ + +This file is part of a sample implementation of the analytical skylight and +solar radiance models presented in the SIGGRAPH 2012 paper + + + "An Analytic Model for Full Spectral Sky-Dome Radiance" + +and the 2013 IEEE CG&A paper + + "Adding a Solar Radiance Function to the Hosek Skylight Model" + + both by + + Lukas Hosek and Alexander Wilkie + Charles University in Prague, Czech Republic + + + Version: 1.4a, February 22nd, 2013 + +Version history: + +1.4a February 22nd, 2013 + Removed unnecessary and counter-intuitive solar radius parameters + from the interface of the colourspace sky dome initialisation functions. + +1.4 February 11th, 2013 + Fixed a bug which caused the relative brightness of the solar disc + and the sky dome to be off by a factor of about 6. The sun was too + bright: this affected both normal and alien sun scenarios. The + coefficients of the solar radiance function were changed to fix this. + +1.3 January 21st, 2013 (not released to the public) + Added support for solar discs that are not exactly the same size as + the terrestrial sun. Also added support for suns with a different + emission spectrum ("Alien World" functionality). + +1.2a December 18th, 2012 + Fixed a mistake and some inaccuracies in the solar radiance function + explanations found in ArHosekSkyModel.h. The actual source code is + unchanged compared to version 1.2. + +1.2 December 17th, 2012 + Native RGB data and a solar radiance function that matches the turbidity + conditions were added. + +1.1 September 2012 + The coefficients of the spectral model are now scaled so that the output + is given in physical units: W / (m^-2 * sr * nm). Also, the output of the + XYZ model is now no longer scaled to the range [0...1]. Instead, it is + the result of a simple conversion from spectral data via the CIE 2 degree + standard observer matching functions. Therefore, after multiplication + with 683 lm / W, the Y channel now corresponds to luminance in lm. + +1.0 May 11th, 2012 + Initial release. + + +Please visit http://cgg.mff.cuni.cz/projects/SkylightModelling/ to check if +an updated version of this code has been published! + +============================================================================ */ + + +/* + +This file contains the coefficient data for the RGB colour space version of +the model. + +*/ + +// uses Aug 23 dataset + +double datasetRGB1[] = +{ + // albedo 0, turbidity 1 + -1.099459e+000, + -1.335146e-001, + -4.083223e+000, + 5.919603e+000, + -1.104166e-001, + 1.600158e+000, + -1.326538e-006, + 4.917807e+000, + 5.127716e-001, + -1.169858e+000, + -1.832793e-001, + 9.694744e-001, + 9.495762e-002, + -4.738918e-002, + 2.194171e-001, + 1.095749e-001, + 3.603604e+000, + 3.815119e-001, + -9.665225e-001, + -1.403888e-001, + 5.194457e+000, + -1.107607e+000, + -8.135181e-001, + 4.969661e+000, + -2.300508e-001, + -2.489350e+000, + 1.279158e+000, + -1.292508e+000, + -1.299552e-001, + -2.071404e+000, + -4.752482e-002, + 1.215598e+000, + -1.904179e+000, + 3.027985e-001, + 8.707768e+000, + 6.332446e-002, + -9.264666e-001, + -1.696780e-001, + 4.574070e+000, + -4.232936e-001, + -7.575833e+000, + 5.079755e+000, + -2.576343e-001, + -4.506805e+000, + 6.908129e-001, + -1.139072e+000, + -1.796056e-001, + 1.923311e+000, + 6.788529e+000, + -2.364389e+000, + -1.064041e+000, + 1.717010e-001, + 1.534681e+000, + 5.015810e-001, + // albedo 0, turbidity 2 + -1.107257e+000, + -1.384411e-001, + -4.285744e+000, + 5.713157e+000, + -1.015992e-001, + 1.372638e+000, + 6.555893e-002, + 5.127514e+000, + 6.550471e-001, + -1.187337e+000, + -1.969013e-001, + 8.551048e-001, + 5.289708e-002, + -7.626406e-002, + 1.733153e-002, + 1.779454e-001, + 3.801038e+000, + 4.742709e-001, + -9.685321e-001, + -1.553308e-001, + 4.732492e+000, + -1.178935e+000, + -7.852791e-001, + 4.604492e+000, + -2.666518e-001, + -2.367663e+000, + 1.177527e+000, + -1.252817e+000, + -5.129949e-002, + -2.800433e+000, + -1.295992e-002, + 1.308964e+000, + -2.204331e+000, + 7.276011e-001, + 8.699265e+000, + 1.188388e-001, + -9.459509e-001, + -2.322133e-001, + 4.375041e+000, + -1.712018e-001, + -7.451681e+000, + 5.078019e+000, + -4.223538e-001, + -4.595561e+000, + 1.074719e+000, + -1.125092e+000, + -1.796750e-001, + 1.626399e+000, + 6.989743e+000, + -2.406382e+000, + -9.060383e-001, + 2.961611e-001, + 1.337715e+000, + 5.438140e-001, + // albedo 0, turbidity 3 + -1.135338e+000, + -1.716160e-001, + -1.499253e+000, + 2.373491e+000, + -1.654023e-001, + 9.566404e-001, + 1.113453e-001, + 4.528473e+000, + 6.579439e-001, + -1.132780e+000, + -1.456214e-001, + -1.736672e+000, + 1.756589e+000, + -1.087003e-001, + 3.757927e-001, + 2.525070e-001, + 7.178513e+000, + 5.003814e-001, + -1.167176e+000, + -2.927225e-001, + 5.727667e+000, + -3.139244e+000, + -6.425204e-001, + 2.822634e+000, + -1.457812e-001, + -6.787080e+000, + 1.017072e+000, + -1.042529e+000, + 4.110823e-002, + -4.000629e+000, + 4.362364e+000, + 1.090540e+000, + -1.338674e+000, + 8.246964e-001, + 1.095249e+001, + 2.912211e-001, + -1.061598e+000, + -2.096143e-001, + 3.803155e+000, + -7.977069e+000, + -3.637880e+000, + 3.707671e+000, + -1.903128e-001, + -3.397953e+000, + 9.971500e-001, + -1.073560e+000, + -2.077964e-001, + 1.492052e+000, + 1.626322e+001, + -5.015304e+000, + -4.059889e-001, + 2.659782e-001, + 6.395380e-001, + 5.634436e-001, + // albedo 0, turbidity 4 + -1.172794e+000, + -2.111186e-001, + -1.360013e+000, + 1.604080e+000, + -8.473723e-002, + 7.217312e-001, + 1.548030e-001, + 4.257010e+000, + 6.328974e-001, + -1.238374e+000, + -2.670827e-001, + 3.247678e-001, + 5.466311e-001, + -7.425952e-001, + 5.276440e-001, + 2.678026e-002, + 5.484169e+000, + 6.814734e-001, + -1.176923e+000, + -2.574586e-001, + 2.304045e+000, + -2.797678e+000, + 1.464405e+000, + 1.998552e+000, + 2.550559e-001, + -4.199772e+000, + 7.544892e-001, + -1.003284e+000, + 1.943984e-002, + -2.145066e+000, + 1.030924e+001, + -1.525413e+001, + -2.023010e+000, + 5.448699e-001, + 8.159497e+000, + 5.539148e-001, + -1.060017e+000, + -2.037206e-001, + 2.483018e+000, + -4.595459e+000, + 6.526991e+000, + 4.031804e+000, + 1.206513e-001, + -2.586527e+000, + 7.875752e-001, + -1.081141e+000, + -2.123302e-001, + 1.092275e+000, + 2.683841e+000, + -4.166938e+000, + -1.396582e+000, + 4.371205e-001, + 1.030233e+000, + 6.664862e-001, + // albedo 0, turbidity 5 + -1.222392e+000, + -2.651924e-001, + -4.625037e-001, + 3.521964e-001, + 2.148855e-002, + 5.078494e-001, + 1.791590e-001, + 3.852516e+000, + 5.998216e-001, + -1.424610e+000, + -4.710155e-001, + -1.826815e-001, + 1.786277e+000, + -1.952442e+000, + 5.277612e-001, + -1.773629e-002, + 2.415874e+000, + 6.701272e-001, + -1.130655e+000, + -1.358609e-001, + 9.171203e-001, + -4.660394e+000, + 6.251162e+000, + 1.904529e+000, + 2.639668e-001, + 1.856130e+000, + 8.228440e-001, + -9.739015e-001, + -6.674749e-002, + -4.768897e-001, + 1.248589e+001, + -1.994688e+001, + -2.353043e+000, + 5.885575e-001, + 1.287251e+000, + 4.830135e-001, + -1.082178e+000, + -1.974495e-001, + 1.050245e+000, + -4.792855e+000, + 8.663406e+000, + 3.246969e+000, + 1.556731e-001, + 8.117442e-001, + 8.050376e-001, + -1.063354e+000, + -1.727108e-001, + 9.681592e-001, + 2.736077e+000, + -4.969269e+000, + -8.360570e-001, + 5.994612e-001, + 1.024039e+000, + 6.786935e-001, + // albedo 0, turbidity 6 + -1.261936e+000, + -3.053676e-001, + -4.262222e-001, + 4.000196e-001, + -2.059388e-002, + 4.721802e-001, + 1.480028e-001, + 3.505343e+000, + 6.121337e-001, + -1.681088e+000, + -6.971919e-001, + -1.105652e-001, + 7.437426e-001, + -6.594399e-001, + 2.254221e-001, + 8.710195e-002, + 1.263913e+000, + 5.681865e-001, + -9.453001e-001, + 3.460388e-002, + 6.067038e-001, + -1.985128e+000, + 3.457236e+000, + 2.655483e+000, + -1.162354e-002, + 3.304716e+000, + 1.001950e+000, + -1.086609e+000, + -2.029011e-001, + -6.399170e-001, + 6.926885e+000, + -1.512189e+001, + -3.793051e+000, + 9.456120e-001, + 2.222222e-001, + 2.893725e-001, + -1.041259e+000, + -1.388790e-001, + 1.147331e+000, + 6.282086e+000, + 3.679836e+000, + 4.398314e+000, + -1.355232e-001, + 1.031134e+000, + 9.273509e-001, + -1.063473e+000, + -1.916051e-001, + 6.556979e-001, + -3.371891e-003, + -3.699664e+000, + -1.926783e+000, + 7.371154e-001, + 1.179975e+000, + 6.367068e-001, + // albedo 0, turbidity 7 + -1.336390e+000, + -3.778927e-001, + -7.259477e-001, + 2.270247e-001, + 4.627513e-001, + 1.366459e-001, + 2.637347e-001, + 3.292059e+000, + 4.998211e-001, + -2.119878e+000, + -1.055472e+000, + 5.422052e-001, + 7.826648e-001, + -1.286065e+000, + 9.517905e-001, + -1.432358e-001, + -2.379816e-001, + 5.910513e-001, + -7.761432e-001, + 2.124336e-001, + -6.845184e-001, + -9.812342e-001, + 4.347257e+000, + 9.671980e-001, + 3.773150e-001, + 5.789529e+000, + 9.646598e-001, + -1.118734e+000, + -3.513815e-001, + 5.500918e-001, + 9.449627e-001, + -1.262070e+001, + -1.825280e+000, + 4.731260e-001, + -3.326892e+000, + 3.568768e-001, + -1.026437e+000, + -8.257946e-002, + 3.221701e-001, + 1.198372e+001, + 1.555130e+000, + 2.560304e+000, + 1.406465e-001, + 2.912858e+000, + 8.643181e-001, + -1.069949e+000, + -2.029607e-001, + 5.825042e-001, + -2.398595e-003, + -3.278335e+000, + -1.349882e+000, + 7.208433e-001, + 8.505164e-001, + 6.625391e-001, + // albedo 0, turbidity 8 + -1.392309e+000, + -4.454945e-001, + -5.664000e-001, + 6.283393e-001, + -3.761727e-001, + 6.949802e-001, + 7.748178e-002, + 3.192797e+000, + 5.968661e-001, + -2.713405e+000, + -1.395112e+000, + 2.029230e-001, + 1.877272e-001, + -3.715859e-001, + -1.652929e-001, + 2.385861e-001, + -4.150768e-001, + 1.375467e-001, + -9.588644e-001, + 2.433900e-002, + -1.527493e+000, + -9.632874e-001, + 5.496269e+000, + 1.094931e+000, + 2.004044e-001, + 6.084554e+000, + 1.369604e+000, + -8.028546e-001, + -2.473563e-001, + 1.617898e+000, + 2.073591e+000, + -1.149446e+001, + -8.394131e-001, + 2.726847e-001, + -4.634538e+000, + 1.367293e-001, + -1.198326e+000, + -1.804865e-001, + -3.565414e-001, + 4.073200e+000, + 1.662086e+000, + 1.239770e+000, + 3.367978e-001, + 2.997402e+000, + 9.360383e-001, + -1.013531e+000, + -1.859060e-001, + 5.799857e-001, + 1.331883e+001, + -4.346873e+000, + -1.113820e+000, + 5.275714e-001, + 8.045177e-001, + 6.496373e-001, + // albedo 0, turbidity 9 + -1.530103e+000, + -6.107468e-001, + -3.841771e-001, + 1.881508e+000, + -1.464807e+000, + 6.654690e-001, + -5.950797e-006, + 2.738912e+000, + 8.101012e-001, + -2.415469e+000, + -1.057499e+000, + -4.161968e-001, + -2.357548e+000, + 6.300296e-001, + 6.224915e-001, + 1.545048e-002, + 2.038561e+000, + -1.339415e-001, + -3.096796e+000, + -1.465688e+000, + -1.199232e+000, + 4.567061e+000, + 3.260980e+000, + -9.794907e-001, + 8.950491e-001, + 2.049235e+000, + 1.331015e+000, + 2.713904e-001, + 2.852852e-001, + 1.202090e+000, + -8.206784e+000, + -5.805762e+000, + 1.804431e+000, + -6.090648e-001, + -1.990902e+000, + 3.288858e-001, + -1.456580e+000, + -3.455960e-001, + -6.409257e-002, + 1.667697e+001, + -2.311094e+000, + -9.771104e-001, + 6.759863e-001, + 1.245136e+000, + 7.911932e-001, + -9.860389e-001, + -2.099564e-001, + 2.946650e-001, + -3.547800e-003, + -2.268313e+000, + -6.205647e-002, + 4.705185e-001, + 8.657995e-001, + 6.856284e-001, + // albedo 0, turbidity 10 + -1.971736e+000, + -9.414047e-001, + -3.400557e-001, + 1.468763e+000, + -1.474284e+000, + 5.501062e-001, + -1.109750e-005, + 2.356370e+000, + 9.001702e-001, + -1.589845e+000, + -7.797079e-001, + -5.582240e-001, + -8.137376e-001, + 5.846617e-001, + 1.129459e-001, + -2.658005e-002, + 2.707248e+000, + -2.112486e-001, + -6.940173e+000, + -2.823963e+000, + -1.620848e+000, + 1.090696e+000, + 2.391730e+000, + 1.370047e+000, + 5.890462e-001, + 1.728400e+000, + 1.331253e+000, + 1.293144e+000, + -1.919778e-003, + 1.644206e+000, + -8.666967e-001, + -7.161953e+000, + -1.385018e+000, + -1.505374e-001, + -1.388643e+000, + 2.530122e-001, + -1.488880e+000, + -2.495496e-001, + -2.377137e-001, + 1.167714e+001, + -8.617124e-001, + 1.053828e+000, + 1.992744e-001, + 3.633564e-001, + 8.553304e-001, + -1.060891e+000, + -4.035829e-001, + 2.823207e-001, + -2.369798e-003, + -1.876577e+000, + -5.950265e-001, + 4.241017e-001, + 3.140802e-001, + 6.631669e-001, + // albedo 1, turbidity 1 + -1.101204e+000, + -1.351353e-001, + -4.030882e+000, + 6.096353e+000, + -1.148599e-001, + 1.606507e+000, + -1.555474e-006, + 4.436084e+000, + 5.973715e-001, + -1.154597e+000, + -1.923378e-001, + 8.512132e-001, + 2.934895e-001, + -6.522777e-002, + 1.389077e-001, + 9.091469e-002, + 3.133307e+000, + 2.108541e-001, + -1.031588e+000, + -1.546804e-001, + 5.266214e+000, + -9.491390e-001, + -7.184867e-001, + 4.875626e+000, + -1.911907e-001, + -2.865642e+000, + 1.087895e+000, + -1.159454e+000, + -9.546699e-002, + -1.508146e+000, + -2.031411e-002, + 1.040653e+000, + -2.333508e+000, + 2.540592e-001, + 8.594981e+000, + 9.316770e-002, + -1.035940e+000, + -2.021151e-001, + 4.719343e+000, + -9.019318e-001, + -7.858046e+000, + 3.901234e+000, + -2.233137e-001, + -4.344739e+000, + 6.550733e-001, + -1.096669e+000, + -1.558196e-001, + 2.057553e+000, + 6.274495e+000, + -2.678352e+000, + -1.814927e+000, + 1.550676e-001, + 1.903276e+000, + 4.998989e-001, + // albedo 1, turbidity 2 + -1.114209e+000, + -1.473531e-001, + -7.602914e+000, + 8.973685e+000, + -4.980074e-002, + 1.289198e+000, + 8.366906e-002, + 4.557987e+000, + 6.118757e-001, + -1.149397e+000, + -1.981628e-001, + 4.914096e+000, + -3.498986e+000, + -6.257090e-002, + 1.667401e-001, + 1.048980e-001, + 2.284689e+000, + 5.935965e-001, + -1.056121e+000, + -1.456172e-001, + 4.272656e-001, + 2.912649e+000, + -5.501745e-001, + 4.406542e+000, + -1.387680e-001, + 1.245555e+000, + 9.733011e-001, + -1.125047e+000, + -4.003662e-002, + 1.058457e+000, + -3.462236e+000, + 4.395278e-001, + -2.395805e+000, + 5.177589e-001, + 4.866247e+000, + 4.253189e-001, + -1.051444e+000, + -2.804541e-001, + 3.364668e+000, + 3.293787e+000, + -1.015741e+001, + 3.807407e+000, + -3.592377e-001, + -3.367415e+000, + 7.900825e-001, + -1.093847e+000, + -1.436965e-001, + 2.384780e+000, + 5.787070e+000, + -2.445987e+000, + -1.311171e+000, + 2.326563e-001, + 1.158439e+000, + 5.555416e-001, + // albedo 1, turbidity 3 + -1.134824e+000, + -1.680468e-001, + -3.325620e+000, + 4.458596e+000, + -1.135063e-001, + 1.104500e+000, + 7.794544e-002, + 4.609952e+000, + 6.854854e-001, + -1.143017e+000, + -1.565926e-001, + 3.014687e-001, + -1.763027e-001, + -3.557925e-002, + -2.342406e-001, + 2.528705e-001, + 5.884085e+000, + 4.750602e-001, + -1.136801e+000, + -2.907502e-001, + 3.682423e+000, + -4.061202e-001, + -8.728159e-001, + 4.001510e+000, + -1.522202e-001, + -5.528713e+000, + 1.044847e+000, + -1.063652e+000, + 7.808107e-002, + -1.983678e+000, + 3.648078e-001, + 2.102276e+000, + -3.065050e+000, + 8.431951e-001, + 1.038830e+001, + 2.662834e-001, + -1.061015e+000, + -2.859814e-001, + 4.223615e+000, + -2.290138e+000, + -8.314010e+000, + 4.405718e+000, + -4.613627e-001, + -4.502910e+000, + 1.008383e+000, + -1.106302e+000, + -1.697123e-001, + 2.087196e+000, + 8.238929e+000, + -2.992416e+000, + -1.821776e+000, + 3.434859e-001, + 7.755179e-001, + 5.341190e-001, + // albedo 1, turbidity 4 + -1.171110e+000, + -2.106304e-001, + -1.614361e+000, + 2.378103e+000, + -1.625969e-001, + 8.504483e-001, + 1.059312e-001, + 4.046256e+000, + 6.618227e-001, + -1.200480e+000, + -2.235733e-001, + 1.014390e+000, + -1.174074e+000, + -4.440180e-001, + 2.262406e-001, + 1.665868e-001, + 5.461829e+000, + 5.676310e-001, + -1.223587e+000, + -3.502622e-001, + 1.699106e+000, + 6.724266e-001, + 1.268567e+000, + 2.135102e+000, + 8.039374e-004, + -5.221111e+000, + 9.445690e-001, + -9.452673e-001, + 1.468459e-001, + -1.335034e+000, + 4.346628e+000, + -1.285652e+001, + -1.807046e+000, + 8.175243e-001, + 9.301065e+000, + 3.656798e-001, + -1.134681e+000, + -3.310951e-001, + 3.571244e+000, + -2.208948e+000, + 6.041580e+000, + 3.107577e+000, + -3.112127e-001, + -4.186351e+000, + 9.188333e-001, + -1.083237e+000, + -1.831394e-001, + 2.062654e+000, + 1.385424e+000, + -5.004950e+000, + -1.332669e+000, + 3.627352e-001, + 3.323150e-001, + 6.191181e-001, + // albedo 1, turbidity 5 + -1.211527e+000, + -2.590617e-001, + -1.660874e-001, + 3.627905e-001, + -1.039258e-001, + 4.697924e-001, + 1.671653e-001, + 3.507497e+000, + 6.022506e-001, + -1.433017e+000, + -4.733592e-001, + 1.724445e-001, + 9.953236e-001, + -1.874457e+000, + 4.432099e-001, + 1.715810e-002, + 2.339272e+000, + 6.441470e-001, + -1.084920e+000, + -1.587903e-001, + 8.999585e-001, + -2.537516e+000, + 5.877859e+000, + 2.014554e+000, + 9.689141e-002, + 3.177242e-001, + 9.030399e-001, + -1.008242e+000, + 2.793030e-003, + -3.507469e-001, + 1.028300e+001, + -2.080454e+001, + -2.781026e+000, + 8.995090e-001, + 3.366951e+000, + 3.473867e-001, + -1.103151e+000, + -2.799598e-001, + 2.525791e+000, + -4.255704e+000, + 9.903388e+000, + 3.722668e+000, + -3.603941e-001, + -1.303292e+000, + 9.369454e-001, + -1.102235e+000, + -2.025061e-001, + 2.085660e+000, + 1.686787e+000, + -5.010957e+000, + -1.656458e+000, + 4.584029e-001, + -2.751759e-001, + 6.184162e-001, + // albedo 1, turbidity 6 + -1.256130e+000, + -3.104904e-001, + 1.639350e-001, + 1.315502e-001, + -7.297583e-001, + 4.778480e-001, + 1.259265e-001, + 3.012108e+000, + 6.202728e-001, + -1.620114e+000, + -6.552670e-001, + -2.877157e-001, + 1.094371e+000, + 2.818914e-001, + 3.696830e-001, + 9.428521e-002, + 1.450951e+000, + 5.681308e-001, + -9.686204e-001, + -3.755647e-002, + 1.469980e+000, + -3.103414e+000, + 2.856583e+000, + 1.883209e+000, + -5.746099e-002, + 1.286383e+000, + 1.001751e+000, + -1.089377e+000, + -1.023062e-001, + -1.498891e+000, + 1.066455e+001, + -1.720184e+001, + -2.759314e+000, + 1.061258e+000, + 2.910211e+000, + 2.624701e-001, + -1.044681e+000, + -2.156857e-001, + 3.230136e+000, + -5.863862e-001, + 6.096640e+000, + 3.550019e+000, + -4.255773e-001, + -1.500033e+000, + 9.687696e-001, + -1.133658e+000, + -2.505101e-001, + 1.717840e+000, + 8.480428e-003, + -5.011789e+000, + -1.740989e+000, + 4.983430e-001, + -2.081829e-001, + 6.088641e-001, + // albedo 1, turbidity 7 + -1.335366e+000, + -3.863319e-001, + -5.279971e-001, + 3.638324e-001, + 3.230699e-001, + 8.339707e-002, + 2.483293e-001, + 2.678646e+000, + 4.998346e-001, + -2.004511e+000, + -9.957121e-001, + 1.250807e+000, + 1.625025e-002, + -3.410754e-001, + 7.858244e-001, + -9.506757e-002, + 2.651876e-002, + 5.788643e-001, + -8.714157e-001, + 1.192051e-001, + -8.486879e-001, + -3.702497e-001, + 1.818277e+000, + 1.103427e+000, + 2.454866e-001, + 3.841575e+000, + 9.847350e-001, + -1.042618e+000, + -2.285793e-001, + 3.620175e-001, + 2.983368e+000, + -9.776844e+000, + -1.971587e+000, + 6.691674e-001, + -7.901947e-001, + 3.213200e-001, + -1.099112e+000, + -1.869868e-001, + 2.044065e+000, + 2.062964e+000, + 1.265668e+000, + 2.710130e+000, + -1.099443e-001, + 2.179353e-001, + 9.024108e-001, + -1.106985e+000, + -2.396881e-001, + 1.809807e+000, + 8.523319e+000, + -5.011788e+000, + -1.590086e+000, + 3.248449e-001, + -1.003187e-001, + 6.550606e-001, + // albedo 1, turbidity 8 + -1.421285e+000, + -4.767024e-001, + -3.885004e-001, + 8.274590e-001, + -3.644229e-001, + 6.999513e-001, + 5.196710e-002, + 2.578431e+000, + 6.246310e-001, + -2.611217e+000, + -1.398846e+000, + 4.527425e-001, + -5.932142e-001, + 2.224617e-001, + -5.593581e-001, + 3.389633e-001, + -7.767112e-001, + 6.536004e-002, + -9.881543e-001, + 4.684782e-002, + -8.616613e-001, + 8.799807e-001, + 4.003130e+000, + 1.739543e+000, + -8.098378e-002, + 5.524802e+000, + 1.499673e+000, + -7.544759e-001, + -2.314808e-001, + 8.125770e-001, + -7.724135e-001, + -9.577645e+000, + -1.629433e+000, + 6.790832e-001, + -4.193895e+000, + -2.526624e-002, + -1.273719e+000, + -2.187030e-001, + 1.401798e+000, + 5.231832e+000, + 7.405093e-001, + 1.775166e+000, + -7.269476e-002, + 1.996087e+000, + 1.057450e+000, + -1.046864e+000, + -2.247559e-001, + 1.679449e+000, + 1.140057e+001, + -4.948829e+000, + -1.182664e+000, + 3.241038e-001, + -2.470012e-001, + 6.115900e-001, + // albedo 1, turbidity 9 + -1.514607e+000, + -5.985430e-001, + -1.877610e-001, + 1.756930e+000, + -1.314206e+000, + 6.115810e-001, + -5.970460e-006, + 2.412975e+000, + 8.124304e-001, + -2.308414e+000, + -1.083797e+000, + -1.179959e-001, + -1.728246e+000, + 7.784742e-001, + 5.494505e-001, + 6.203168e-003, + 9.326251e-001, + -1.419518e-001, + -3.230837e+000, + -1.438670e+000, + -9.868286e-001, + 2.974393e+000, + 1.949339e+000, + -6.337857e-001, + 8.160271e-001, + 3.278606e+000, + 1.354373e+000, + 5.149378e-001, + 2.754789e-001, + 1.040965e+000, + -4.501186e+000, + -3.399057e+000, + 9.661861e-001, + -4.736173e-001, + -4.037574e+000, + 2.794847e-001, + -1.621870e+000, + -3.192763e-001, + 8.786242e-001, + 9.785565e+000, + -2.727652e+000, + 1.903691e-002, + 5.521261e-001, + 2.138764e+000, + 8.419871e-001, + -9.951701e-001, + -2.550607e-001, + 1.498952e+000, + -2.737197e-003, + -3.101832e+000, + -5.921329e-001, + 2.864422e-001, + -4.405218e-001, + 6.631410e-001, + // albedo 1, turbidity 10 + -1.902954e+000, + -9.056918e-001, + -2.069570e-001, + 1.191499e+000, + -1.092577e+000, + 5.849556e-001, + -9.649602e-006, + 2.048407e+000, + 9.001527e-001, + -1.271627e+000, + -7.193923e-001, + -1.136606e-002, + -1.167951e-001, + 3.286175e-003, + -5.262827e-002, + -2.473874e-002, + 1.716125e+000, + -2.187133e-001, + -7.647175e+000, + -3.114129e+000, + -1.490128e+000, + -5.266488e-001, + 3.063090e+000, + 1.474262e+000, + 5.481458e-001, + 2.052174e+000, + 1.353089e+000, + 2.191403e+000, + 3.421120e-001, + 1.446510e+000, + 2.170943e+000, + -7.768187e+000, + -1.471207e+000, + -1.456708e-001, + -1.753574e+000, + 2.310576e-001, + -1.932296e+000, + -3.814739e-001, + 6.245422e-001, + 6.748294e+000, + -3.060171e-001, + 1.067747e+000, + 2.500671e-001, + -1.252596e-001, + 8.614611e-001, + -9.471101e-001, + -4.052640e-001, + 1.300174e+000, + -3.951536e-003, + -1.908284e+000, + -5.385721e-001, + 2.133578e-001, + -6.250292e-001, + 6.658012e-001, +}; + +double datasetRGBRad1[] = +{ + // albedo 0, turbidity 1 + 1.962684e+000, + 1.159831e+000, + 4.450588e+000, + 5.079633e+000, + 4.437388e+000, + 4.324573e+000, + // albedo 0, turbidity 2 + 1.946487e+000, + 1.287515e+000, + 3.703696e+000, + 8.782833e+000, + 3.440437e+000, + 5.160333e+000, + // albedo 0, turbidity 3 + 1.882170e+000, + 1.335878e+000, + 2.648641e+000, + 1.358368e+001, + 3.105473e+000, + 5.907387e+000, + // albedo 0, turbidity 4 + 1.738159e+000, + 1.624289e+000, + -8.786695e-003, + 2.118253e+001, + 2.770255e+000, + 7.055672e+000, + // albedo 0, turbidity 5 + 1.571896e+000, + 2.301786e+000, + -4.028545e+000, + 2.966806e+001, + 1.630876e+000, + 8.711031e+000, + // albedo 0, turbidity 6 + 1.475048e+000, + 2.679086e+000, + -6.311315e+000, + 3.377896e+001, + 2.140975e+000, + 9.385283e+000, + // albedo 0, turbidity 7 + 1.326174e+000, + 3.378759e+000, + -9.831444e+000, + 3.942061e+001, + 2.852702e+000, + 1.082542e+001, + // albedo 0, turbidity 8 + 1.153344e+000, + 3.967771e+000, + -1.265181e+001, + 4.195016e+001, + 7.468239e+000, + 1.221350e+001, + // albedo 0, turbidity 9 + 9.746081e-001, + 4.051626e+000, + -1.298454e+001, + 3.754964e+001, + 1.749232e+001, + 1.420619e+001, + // albedo 0, turbidity 10 + 8.448016e-001, + 3.181809e+000, + -8.757338e+000, + 2.197962e+001, + 3.524033e+001, + 1.639549e+001, + // albedo 1, turbidity 1 + 2.029623e+000, + 1.364434e+000, + 4.201529e+000, + 5.415099e+000, + 9.825839e+000, + 1.063328e+001, + // albedo 1, turbidity 2 + 2.023126e+000, + 1.494728e+000, + 3.420413e+000, + 9.072178e+000, + 9.205157e+000, + 1.186639e+001, + // albedo 1, turbidity 3 + 1.956307e+000, + 1.648665e+000, + 2.039712e+000, + 1.430239e+001, + 9.039526e+000, + 1.330453e+001, + // albedo 1, turbidity 4 + 1.825053e+000, + 1.985022e+000, + -8.036307e-001, + 2.202493e+001, + 9.415361e+000, + 1.517659e+001, + // albedo 1, turbidity 5 + 1.650367e+000, + 2.593201e+000, + -4.469328e+000, + 2.969817e+001, + 9.410977e+000, + 1.744850e+001, + // albedo 1, turbidity 6 + 1.555202e+000, + 2.962925e+000, + -6.608170e+000, + 3.329887e+001, + 1.064559e+001, + 1.850816e+001, + // albedo 1, turbidity 7 + 1.412478e+000, + 3.439403e+000, + -9.196616e+000, + 3.685077e+001, + 1.345341e+001, + 2.003128e+001, + // albedo 1, turbidity 8 + 1.252990e+000, + 3.820805e+000, + -1.115338e+001, + 3.721593e+001, + 2.014916e+001, + 2.182320e+001, + // albedo 1, turbidity 9 + 1.091952e+000, + 3.663027e+000, + -1.031330e+001, + 2.978985e+001, + 3.296835e+001, + 2.375450e+001, + // albedo 1, turbidity 10 + 9.501691e-001, + 2.664579e+000, + -5.545167e+000, + 1.281159e+001, + 5.154768e+001, + 2.574284e+001, +}; + +double datasetRGB2[] = +{ + // albedo 0, turbidity 1 + -1.140530e+000, + -1.982747e-001, + -7.512730e+000, + 8.403899e+000, + -5.699038e-002, + 9.015907e-001, + 3.392161e-002, + 4.772522e+000, + 5.111184e-001, + -1.165117e+000, + -1.852955e-001, + 2.963684e+000, + -2.262274e+000, + -1.571683e-001, + 6.339974e-001, + 4.977879e-002, + 7.243307e+000, + 4.220053e-001, + -1.169936e+000, + -3.357429e-001, + 1.911291e+000, + -2.391074e-001, + -4.791643e-001, + 1.446113e+000, + -9.178108e-002, + -4.700239e+000, + 8.096219e-001, + -1.060246e+000, + -1.051633e-001, + 5.013829e-001, + 2.832309e+000, + -3.707855e-001, + 1.523131e+000, + 9.163749e-002, + 5.604183e+000, + 7.208566e-001, + -1.089753e+000, + -2.382167e-001, + 2.360312e+000, + -5.902562e+000, + -8.799894e+000, + 1.377692e+000, + -6.131633e-002, + -1.415472e+000, + 6.124057e-001, + -1.075481e+000, + -1.242391e-001, + 1.425781e+000, + 8.810319e+000, + -2.922646e+000, + 1.486520e+000, + 3.270580e-002, + 3.889783e+000, + 4.999482e-001, + // albedo 0, turbidity 2 + -1.149342e+000, + -2.076337e-001, + -7.446587e+000, + 8.014559e+000, + -4.866227e-002, + 8.203043e-001, + 6.386483e-002, + 4.894198e+000, + 5.452051e-001, + -1.120531e+000, + -1.513311e-001, + 2.735504e+000, + -2.417591e+000, + -1.361114e-001, + 4.296342e-001, + 9.427488e-002, + 8.171403e+000, + 4.102448e-001, + -1.226964e+000, + -3.516378e-001, + 1.308298e+000, + -5.097487e-002, + -4.846783e-001, + 1.654619e+000, + -1.134940e-001, + -3.347854e+000, + 1.131147e+000, + -9.664377e-001, + 2.767589e-002, + 1.658235e-001, + 2.407439e+000, + -1.300304e-001, + 9.170958e-001, + 2.742895e-001, + 6.642633e+000, + 2.550064e-001, + -1.153358e+000, + -3.126223e-001, + 2.078934e+000, + -5.857733e+000, + -8.659848e+000, + 1.758505e+000, + -9.616094e-002, + -1.230863e+000, + 9.663832e-001, + -1.053850e+000, + -1.330743e-001, + 1.481738e+000, + 1.049485e+001, + -3.528854e+000, + 9.142363e-001, + 1.244880e-001, + 2.644615e+000, + 5.001048e-001, + // albedo 0, turbidity 3 + -1.173687e+000, + -2.360362e-001, + -3.741454e+000, + 4.088507e+000, + -7.528205e-002, + 6.645237e-001, + 7.718265e-002, + 4.651220e+000, + 5.586318e-001, + -1.213757e+000, + -2.589561e-001, + 7.132551e-001, + -4.259327e-001, + -1.980821e-001, + 3.627815e-001, + 4.666560e-002, + 5.807984e+000, + 5.847377e-001, + -1.108794e+000, + -2.259870e-001, + 1.574179e+000, + -3.753731e-001, + -5.984743e-001, + 1.659414e+000, + -1.681021e-002, + 6.785219e-001, + 8.647325e-001, + -1.060896e+000, + -1.346690e-002, + -7.529656e-001, + 1.711319e+000, + -9.792435e-001, + 2.022433e-001, + 3.826487e-001, + 5.725157e+000, + 5.290714e-001, + -1.085145e+000, + -2.840715e-001, + 2.088029e+000, + -4.935097e+000, + -9.056542e+000, + 1.976149e+000, + -3.912485e-002, + -8.636064e-001, + 7.452125e-001, + -1.077983e+000, + -1.416633e-001, + 1.100848e+000, + 1.015875e+001, + -2.943712e+000, + 5.255135e-001, + 2.164224e-001, + 2.941143e+000, + 6.699937e-001, + // albedo 0, turbidity 4 + -1.223293e+000, + -2.867444e-001, + -1.624136e+000, + 1.668299e+000, + -9.537589e-002, + 5.015947e-001, + 1.130741e-001, + 4.244812e+000, + 5.082152e-001, + -1.325342e+000, + -4.280991e-001, + 4.705490e-001, + 6.926592e-002, + -4.572587e-001, + 5.344144e-001, + -2.554192e-002, + 3.093939e+000, + 6.639401e-001, + -1.113581e+000, + -1.192133e-001, + 4.011536e-001, + 7.011889e-001, + 2.052842e-001, + 9.880724e-001, + 1.807533e-002, + 4.690160e+000, + 8.576240e-001, + -1.016063e+000, + -1.038138e-001, + -2.280391e-001, + 7.898918e-001, + -1.127333e+001, + 2.074545e-001, + 5.388182e-001, + 1.364263e+000, + 4.660455e-001, + -1.099582e+000, + -2.228607e-001, + 1.332648e+000, + 5.135188e+000, + 1.653152e+000, + 1.417020e+000, + -1.087532e-001, + 1.809275e+000, + 8.080874e-001, + -1.064357e+000, + -1.520775e-001, + 8.207368e-001, + -1.323565e-003, + -5.009523e+000, + 3.946298e-001, + 4.337902e-001, + 2.593198e+000, + 6.719172e-001, + // albedo 0, turbidity 5 + -1.278702e+000, + -3.512866e-001, + -4.511055e-001, + 3.895760e-001, + -2.429672e-001, + 4.270577e-001, + 1.135348e-001, + 3.719130e+000, + 4.998867e-001, + -1.580069e+000, + -7.095475e-001, + -3.198904e-001, + 1.715748e+000, + -1.185915e+000, + 4.523161e-001, + -1.026159e-002, + 7.927188e-001, + 5.538350e-001, + -9.474023e-001, + 1.173703e-001, + 4.881381e-001, + -2.618684e+000, + 3.251661e+000, + 1.213931e+000, + -1.736274e-002, + 8.000768e+000, + 1.025998e+000, + -1.129091e+000, + -3.287694e-001, + -3.524077e-001, + 3.352892e+000, + -1.416073e+001, + -8.485617e-001, + 6.560766e-001, + -2.820937e+000, + 3.111303e-001, + -1.030884e+000, + -1.137581e-001, + 1.109855e+000, + 8.082276e+000, + 1.519214e+000, + 2.112433e+000, + -1.592299e-001, + 3.675905e+000, + 8.703367e-001, + -1.075192e+000, + -1.627166e-001, + 3.514910e-001, + 1.168164e+000, + -4.255822e+000, + -6.015348e-001, + 6.265776e-001, + 2.884818e+000, + 6.548384e-001, + // albedo 0, turbidity 6 + -1.316017e+000, + -3.889652e-001, + -5.030854e-001, + 4.488704e-001, + -3.186800e-001, + 4.570763e-001, + 8.909201e-002, + 3.659274e+000, + 5.011746e-001, + -1.731876e+000, + -8.493806e-001, + 1.194871e-001, + 2.002781e+000, + -2.006547e+000, + 4.872233e-001, + -2.854606e-002, + 2.662137e-001, + 4.611629e-001, + -9.273680e-001, + 1.380954e-001, + -3.302179e-001, + -3.553265e+000, + 4.633345e+000, + 9.696729e-001, + 8.799775e-002, + 8.291129e+000, + 1.094451e+000, + -1.099377e+000, + -3.325392e-001, + 2.501063e-001, + 2.613712e+000, + -1.328142e+001, + -5.579527e-001, + 4.992081e-001, + -3.504402e+000, + 3.022924e-001, + -1.048420e+000, + -1.227773e-001, + 5.845373e-001, + 1.105869e+001, + 3.813151e-002, + 1.330409e+000, + 1.978131e-002, + 3.959430e+000, + 8.396439e-001, + -1.063233e+000, + -1.560639e-001, + 2.840033e-001, + 8.751565e-001, + -3.411820e+000, + -1.436564e-001, + 5.846580e-001, + 2.899292e+000, + 6.799095e-001, + // albedo 0, turbidity 7 + -1.376715e+000, + -4.541567e-001, + -1.445491e+000, + 1.569898e+000, + -1.390627e-001, + 5.558270e-001, + 4.109877e-002, + 3.349451e+000, + 5.516123e-001, + -1.953391e+000, + -1.035869e+000, + 1.690563e+000, + -1.964690e-001, + -7.787096e-001, + 5.799605e-001, + 2.945626e-002, + 4.217906e-002, + 2.451373e-001, + -1.012422e+000, + 7.136451e-002, + -1.862534e+000, + -7.228653e-001, + 1.947997e-001, + 2.091805e-001, + 6.399233e-002, + 7.928994e+000, + 1.290733e+000, + -9.706708e-001, + -2.880950e-001, + 1.107797e+000, + -2.731734e+000, + -8.445995e+000, + 4.296774e-001, + 5.117648e-001, + -3.824277e+000, + 1.761207e-001, + -1.110611e+000, + -1.789409e-001, + 2.108488e-001, + 2.071430e+001, + -1.763174e+000, + 9.554695e-002, + -2.943103e-002, + 3.422079e+000, + 8.815496e-001, + -1.048334e+000, + -1.614087e-001, + 2.475184e-001, + 2.146938e-002, + -2.983901e+000, + 2.538224e-001, + 5.601370e-001, + 2.461925e+000, + 6.777394e-001, + // albedo 0, turbidity 8 + -1.393719e+000, + -5.002724e-001, + -2.408940e+000, + 2.680983e+000, + -1.362825e-001, + 7.395067e-001, + -3.300343e-006, + 3.260889e+000, + 8.132057e-001, + -2.128663e+000, + -1.151182e+000, + 2.923026e+000, + -1.931838e+000, + -4.426170e-001, + 2.309983e-001, + -5.485890e-003, + 3.279529e-001, + -2.229467e-001, + -1.618022e+000, + -3.766490e-001, + -3.163544e+000, + 1.611608e+000, + -3.967476e-001, + 3.933680e-001, + 3.006742e-001, + 6.835177e+000, + 1.613765e+000, + -5.669064e-001, + -1.481749e-001, + 2.071817e+000, + -8.157422e+000, + -5.988088e+000, + 2.387202e-001, + 1.447191e-001, + -4.296385e+000, + 5.011258e-002, + -1.241724e+000, + -2.519348e-001, + -1.908609e-001, + 2.952235e+001, + -3.333660e+000, + -1.837651e-002, + 1.022249e-001, + 2.929320e+000, + 8.867262e-001, + -1.021670e+000, + -1.667327e-001, + 1.789771e-001, + -2.178108e-003, + -2.641572e+000, + -5.641484e-002, + 5.303758e-001, + 2.138196e+000, + 6.780350e-001, + // albedo 0, turbidity 9 + -1.669332e+000, + -7.588708e-001, + -2.993557e+000, + 3.178760e+000, + -8.066442e-002, + 6.544672e-001, + -8.089880e-006, + 2.628924e+000, + 9.001272e-001, + -1.755806e+000, + -8.735348e-001, + 3.258881e+000, + -2.504785e+000, + -3.300791e-001, + 1.180565e-001, + -9.315982e-003, + 1.785154e+000, + -3.205824e-001, + -3.720277e+000, + -1.733350e+000, + -3.332272e+000, + 1.515869e+000, + 1.734218e-001, + 8.011956e-001, + 1.995440e-001, + 3.817666e+000, + 1.638502e+000, + 4.724641e-001, + 3.209828e-001, + 2.051443e+000, + -5.105574e+000, + -6.509139e+000, + -4.232041e-001, + 2.598931e-001, + -2.151756e+000, + -3.493910e-003, + -1.525600e+000, + -4.897606e-001, + -9.891121e-002, + 2.346818e+001, + -2.278152e+000, + 1.681219e-001, + -4.469389e-002, + 1.051000e+000, + 9.294666e-001, + -9.908649e-001, + -2.008182e-001, + 1.605143e-001, + -2.463113e-003, + -2.477349e+000, + -1.218647e-001, + 4.750121e-001, + 1.460813e+000, + 6.661364e-001, + // albedo 0, turbidity 10 + -2.122119e+000, + -1.125475e+000, + -3.066599e+000, + 3.145078e+000, + -5.411593e-002, + 5.133628e-001, + -7.823408e-006, + 2.268448e+000, + 9.001416e-001, + -1.528158e+000, + -9.370249e-001, + 2.567559e+000, + -1.591439e+000, + -3.634460e-001, + 1.763256e-001, + 1.119624e-003, + 1.811848e+000, + -2.637929e-001, + -6.524387e+000, + -2.673507e+000, + -2.940472e+000, + -6.025609e-001, + 7.852067e-001, + 1.073499e+000, + -3.540435e-002, + 3.517416e+000, + 1.490466e+000, + 8.886026e-001, + -9.681828e-002, + 1.430554e+000, + 4.993717e+000, + -6.071355e+000, + -6.053986e-001, + 5.092997e-001, + -1.273010e+000, + 7.491329e-002, + -1.481997e+000, + -5.897282e-001, + 2.659264e-001, + 1.267239e+000, + -5.741291e-001, + 5.983011e-002, + -2.217312e-001, + -3.016452e-001, + 9.260830e-001, + -1.010943e+000, + -2.075134e-001, + 5.066749e-002, + 1.470708e+001, + -3.780501e+000, + 7.253223e-002, + 4.045458e-001, + 1.320164e+000, + 6.559925e-001, + // albedo 1, turbidity 1 + -1.129907e+000, + -1.884011e-001, + -8.047670e+000, + 9.035776e+000, + -5.539419e-002, + 8.823349e-001, + 3.197135e-002, + 4.839388e+000, + 5.042822e-001, + -1.133821e+000, + -1.510781e-001, + 3.362822e+000, + -2.453381e+000, + -1.463925e-001, + 4.728708e-001, + 5.958140e-002, + 7.636300e+000, + 4.805162e-001, + -1.176518e+000, + -3.549902e-001, + 1.729044e+000, + -2.160966e-001, + -5.075865e-001, + 1.675584e+000, + -8.906902e-002, + -5.386842e+000, + 5.452218e-001, + -1.043563e+000, + -7.520975e-002, + 8.750644e-001, + 2.510518e+000, + 7.584882e-003, + 9.361250e-001, + 7.889083e-002, + 6.066644e+000, + 5.813108e-001, + -1.081304e+000, + -2.222253e-001, + 2.517638e+000, + -4.453820e+000, + -8.663691e+000, + 8.662558e-001, + -4.802657e-002, + -8.965449e-001, + 4.886656e-001, + -1.083774e+000, + -1.375469e-001, + 1.685818e+000, + 5.631120e+000, + -3.100752e+000, + 4.045941e-001, + 2.346895e-002, + 3.390321e+000, + 5.008309e-001, + // albedo 1, turbidity 2 + -1.143158e+000, + -2.058334e-001, + -9.660198e+000, + 1.062394e+001, + -4.434119e-002, + 8.607615e-001, + 3.177325e-002, + 4.416481e+000, + 5.918162e-001, + -1.146773e+000, + -1.727385e-001, + 4.626048e+000, + -4.684602e+000, + -8.307137e-002, + 1.619616e-001, + 1.484866e-001, + 7.572868e+000, + 2.681126e-001, + -1.151324e+000, + -3.099303e-001, + 4.125596e-001, + 2.340752e+000, + -4.214444e-001, + 1.987375e+000, + -1.913410e-001, + -3.845978e+000, + 1.337311e+000, + -1.034258e+000, + -7.778759e-003, + 7.050094e-001, + -8.036369e-001, + 3.138570e-001, + 2.469452e-001, + 3.559970e-001, + 7.485917e+000, + 4.790329e-002, + -1.096568e+000, + -2.673169e-001, + 2.575654e+000, + -8.057121e-001, + -8.884928e+000, + 1.416170e+000, + -2.091315e-001, + -1.543494e+000, + 1.065445e+000, + -1.083304e+000, + -1.528265e-001, + 1.697727e+000, + 2.503702e+000, + -2.885296e+000, + -1.298500e-001, + 1.548870e-001, + 2.479652e+000, + 5.066496e-001, + // albedo 1, turbidity 3 + -1.165736e+000, + -2.329945e-001, + -5.967964e+000, + 6.705959e+000, + -5.931355e-002, + 7.485638e-001, + 3.913878e-002, + 4.221591e+000, + 6.183926e-001, + -1.212422e+000, + -2.545910e-001, + 2.418626e+000, + -2.266104e+000, + -1.102014e-001, + 1.363887e-002, + 1.055411e-001, + 5.648062e+000, + 4.557412e-001, + -1.070436e+000, + -2.163341e-001, + 7.098718e-001, + 7.843075e-001, + -4.323930e-001, + 2.109823e+000, + -9.589700e-002, + -1.985193e-001, + 1.060428e+000, + -1.104879e+000, + -3.013622e-002, + 2.976276e-002, + 1.069707e+000, + 1.410000e-001, + -4.880020e-001, + 4.452288e-001, + 6.418590e+000, + 3.195986e-001, + -1.048969e+000, + -2.655317e-001, + 2.689426e+000, + -3.941038e+000, + -9.506461e+000, + 1.837119e+000, + -1.892124e-001, + -1.562146e+000, + 9.043414e-001, + -1.106145e+000, + -1.601642e-001, + 1.544544e+000, + 7.388492e+000, + -2.924600e+000, + -4.328453e-001, + 1.763161e-001, + 2.523111e+000, + 5.851902e-001, + // albedo 1, turbidity 4 + -1.203666e+000, + -2.776587e-001, + -2.084286e+000, + 2.450840e+000, + -8.746613e-002, + 5.258507e-001, + 7.983316e-002, + 3.860055e+000, + 5.486167e-001, + -1.340448e+000, + -4.230590e-001, + 3.462849e-001, + 4.707607e-001, + -2.512626e-001, + 1.530746e-001, + 2.724218e-002, + 3.035216e+000, + 5.876133e-001, + -1.014554e+000, + -1.168790e-001, + 9.477794e-001, + -1.061218e+000, + -4.196730e-001, + 2.058832e+000, + -5.989624e-002, + 3.058168e+000, + 9.763861e-001, + -1.137388e+000, + -9.854030e-002, + -2.984893e-001, + 3.647820e+000, + -6.585571e-001, + -1.479180e+000, + 6.102932e-001, + 3.265914e+000, + 3.480333e-001, + -1.021816e+000, + -2.344957e-001, + 2.463671e+000, + -7.240685e+000, + -8.862697e+000, + 2.514058e+000, + -2.122768e-001, + -3.313968e-002, + 9.028136e-001, + -1.126581e+000, + -1.874347e-001, + 1.454154e+000, + 1.034398e+001, + -3.237393e+000, + -8.654927e-001, + 2.457248e-001, + 1.845769e+000, + 6.002482e-001, + // albedo 1, turbidity 5 + -1.263727e+000, + -3.439354e-001, + -1.786388e-001, + 3.980166e-001, + -3.349517e-001, + 3.825166e-001, + 1.029225e-001, + 3.331096e+000, + 4.998955e-001, + -1.530010e+000, + -6.879698e-001, + 2.380415e-001, + 1.608216e+000, + -1.682679e+000, + 3.546360e-001, + -3.915220e-003, + 4.517655e-001, + 5.128605e-001, + -9.685659e-001, + 9.480403e-002, + 6.076844e-002, + -3.217561e+000, + 4.568074e+000, + 1.069299e+000, + 2.083638e-002, + 7.301088e+000, + 1.072165e+000, + -1.113925e+000, + -3.112382e-001, + 3.954133e-001, + 5.105907e+000, + -1.456866e+001, + -4.917378e-001, + 5.289909e-001, + -2.678374e+000, + 3.014709e-001, + -1.046864e+000, + -1.215754e-001, + 1.778308e+000, + 4.661489e+000, + 2.565583e-001, + 1.353680e+000, + -1.175767e-001, + 3.415972e+000, + 8.457746e-001, + -1.104480e+000, + -1.940913e-001, + 1.343668e+000, + -1.759206e-003, + -5.009204e+000, + -4.186951e-001, + 3.125710e-001, + 1.628183e+000, + 6.720408e-001, + // albedo 1, turbidity 6 + -1.286902e+000, + -3.781238e-001, + -8.977253e-002, + 3.545393e-001, + -4.866515e-001, + 3.843664e-001, + 8.281675e-002, + 3.122231e+000, + 5.046991e-001, + -1.712597e+000, + -8.549112e-001, + 4.809286e-001, + 1.515398e+000, + -2.212211e+000, + 2.539029e-001, + 2.335997e-002, + -6.089466e-002, + 4.268444e-001, + -8.807283e-001, + 1.646097e-001, + -4.437898e-001, + -3.188247e+000, + 5.984417e+000, + 1.334779e+000, + -4.026975e-002, + 7.546431e+000, + 1.175751e+000, + -1.147253e+000, + -3.538199e-001, + 6.101836e-001, + 4.437780e+000, + -1.559813e+001, + -1.103222e+000, + 6.242039e-001, + -3.091472e+000, + 2.174290e-001, + -1.038230e+000, + -1.213475e-001, + 1.547505e+000, + 5.893176e+000, + 1.368738e+000, + 1.663127e+000, + -1.377130e-001, + 3.185279e+000, + 8.736453e-001, + -1.101026e+000, + -1.874907e-001, + 1.272667e+000, + 3.596524e+000, + -5.007243e+000, + -6.352483e-001, + 3.048985e-001, + 1.931613e+000, + 6.788844e-001, + // albedo 1, turbidity 7 + -1.342753e+000, + -4.384971e-001, + -1.213491e+000, + 1.621399e+000, + -1.551441e-001, + 5.614218e-001, + 2.591739e-002, + 2.958967e+000, + 5.782132e-001, + -1.937684e+000, + -1.066019e+000, + 1.913336e+000, + -7.347719e-001, + -5.916167e-001, + 1.587590e-001, + 1.092568e-001, + -6.275002e-001, + 1.599071e-001, + -9.302391e-001, + 1.486187e-001, + -1.603835e+000, + 1.783713e-001, + 1.100461e+000, + 1.174181e+000, + -1.602361e-001, + 7.868331e+000, + 1.468971e+000, + -1.053631e+000, + -3.727050e-001, + 1.114117e+000, + -9.603286e-001, + -1.062469e+001, + -1.162140e+000, + 7.952797e-001, + -4.478765e+000, + -4.440862e-002, + -1.083629e+000, + -1.261405e-001, + 1.229344e+000, + 1.127825e+001, + 1.319010e-001, + 1.624729e+000, + -2.825898e-001, + 3.661082e+000, + 1.036911e+000, + -1.093950e+000, + -2.067455e-001, + 1.258035e+000, + 7.548645e+000, + -4.598387e+000, + -8.944932e-001, + 3.292634e-001, + 1.311304e+000, + 6.291871e-001, + // albedo 1, turbidity 8 + -1.385867e+000, + -5.068139e-001, + -1.486490e+000, + 1.969049e+000, + -1.698025e-001, + 6.629167e-001, + -5.289365e-006, + 2.760315e+000, + 8.644368e-001, + -2.107367e+000, + -1.175639e+000, + 2.313241e+000, + -1.001653e+000, + -4.843139e-001, + 1.124485e-001, + 3.901494e-005, + -3.502469e-001, + -3.204780e-001, + -1.475244e+000, + -2.833055e-001, + -2.085824e+000, + 1.192563e+000, + -7.645200e-001, + 8.380081e-001, + 2.203580e-001, + 7.157885e+000, + 1.753702e+000, + -6.644372e-001, + -2.549735e-001, + 1.600273e+000, + -8.589034e+000, + -6.144718e+000, + -7.599731e-001, + 2.898370e-001, + -5.770923e+000, + -9.656242e-002, + -1.211687e+000, + -1.653494e-001, + 8.393400e-001, + 2.792988e+001, + -3.395461e+000, + 9.933752e-001, + -3.976877e-002, + 3.776659e+000, + 9.546526e-001, + -1.063757e+000, + -2.037563e-001, + 1.117207e+000, + -1.252806e-003, + -3.332330e+000, + -6.971409e-001, + 3.388719e-001, + 1.311398e+000, + 6.635171e-001, + // albedo 1, turbidity 9 + -1.678889e+000, + -7.992295e-001, + -2.421687e+000, + 2.871029e+000, + -7.662842e-002, + 6.046208e-001, + -7.598099e-006, + 2.002314e+000, + 9.001307e-001, + -1.692144e+000, + -8.804250e-001, + 3.060895e+000, + -2.000009e+000, + -3.183563e-001, + 8.385862e-002, + -6.326713e-003, + 1.206639e+000, + -3.369967e-001, + -3.676795e+000, + -1.719207e+000, + -2.534697e+000, + 1.005285e+000, + 1.550407e-001, + 1.072910e+000, + 1.318094e-001, + 3.717018e+000, + 1.689191e+000, + 5.424542e-001, + 3.263528e-001, + 1.551055e+000, + -3.841058e+000, + -6.598996e+000, + -1.201779e+000, + 3.530669e-001, + -2.542945e+000, + -6.482523e-002, + -1.553849e+000, + -4.576860e-001, + 9.324676e-001, + 1.950982e+001, + -2.344516e+000, + 1.121020e+000, + -1.221537e-001, + 7.285496e-001, + 9.582816e-001, + -1.020650e+000, + -2.215797e-001, + 1.009774e+000, + -2.056855e-003, + -2.740338e+000, + -8.122355e-001, + 3.328967e-001, + 8.982766e-001, + 6.594676e-001, + // albedo 1, turbidity 10 + -2.247360e+000, + -1.221267e+000, + -3.072346e+000, + 3.385139e+000, + -4.387559e-002, + 5.084887e-001, + -7.418833e-006, + 1.750107e+000, + 9.001401e-001, + -1.248499e+000, + -8.442718e-001, + 3.062611e+000, + -2.020314e+000, + -2.815341e-001, + 5.254745e-002, + 3.345008e-003, + 1.433225e+000, + -2.835911e-001, + -7.004119e+000, + -2.927978e+000, + -2.649852e+000, + 7.971894e-001, + 5.466893e-001, + 1.442667e+000, + -6.063912e-002, + 2.806194e+000, + 1.547429e+000, + 1.434882e+000, + 9.114639e-002, + 1.170089e+000, + 3.512808e-002, + -5.861915e+000, + -1.411843e+000, + 5.400486e-001, + -7.746522e-001, + 2.386984e-002, + -1.559053e+000, + -5.502302e-001, + 1.200396e+000, + 1.347741e+001, + -2.344397e+000, + 8.868907e-001, + -3.292661e-001, + -1.362105e+000, + 9.217826e-001, + -1.044436e+000, + -2.360719e-001, + 7.054471e-001, + -2.904518e-003, + -2.092829e+000, + -5.119668e-001, + 4.174861e-001, + 9.687435e-001, + 6.588427e-001, +}; + +double datasetRGBRad2[] = +{ + // albedo 0, turbidity 1 + 1.590330e+000, + 1.355401e+000, + 1.151412e+000, + 1.359116e+001, + 5.857714e+000, + 8.090833e+000, + // albedo 0, turbidity 2 + 1.552540e+000, + 1.510040e+000, + 1.276413e-001, + 1.604643e+001, + 5.912162e+000, + 8.350009e+000, + // albedo 0, turbidity 3 + 1.470871e+000, + 1.880464e+000, + -1.865398e+000, + 2.030808e+001, + 5.471461e+000, + 9.109834e+000, + // albedo 0, turbidity 4 + 1.356563e+000, + 2.373866e+000, + -4.653245e+000, + 2.570922e+001, + 5.686009e+000, + 1.009480e+001, + // albedo 0, turbidity 5 + 1.244232e+000, + 2.851519e+000, + -7.130942e+000, + 2.993449e+001, + 6.382120e+000, + 1.114578e+001, + // albedo 0, turbidity 6 + 1.173693e+000, + 3.120604e+000, + -8.491886e+000, + 3.187393e+001, + 7.290615e+000, + 1.180066e+001, + // albedo 0, turbidity 7 + 1.091845e+000, + 3.368888e+000, + -9.722083e+000, + 3.268508e+001, + 1.032424e+001, + 1.236508e+001, + // albedo 0, turbidity 8 + 9.858985e-001, + 3.500541e+000, + -1.026328e+001, + 3.092956e+001, + 1.610881e+001, + 1.331222e+001, + // albedo 0, turbidity 9 + 8.864993e-001, + 3.172888e+000, + -8.687550e+000, + 2.362161e+001, + 2.621851e+001, + 1.474967e+001, + // albedo 0, turbidity 10 + 7.946973e-001, + 2.189355e+000, + -4.207953e+000, + 9.399091e+000, + 4.062849e+001, + 1.681753e+001, + // albedo 1, turbidity 1 + 1.711696e+000, + 1.657311e+000, + 9.328021e-001, + 1.317880e+001, + 1.506751e+001, + 1.863556e+001, + // albedo 1, turbidity 2 + 1.666968e+000, + 1.849993e+000, + -2.088601e-001, + 1.586653e+001, + 1.486880e+001, + 1.940719e+001, + // albedo 1, turbidity 3 + 1.584846e+000, + 2.170022e+000, + -2.019597e+000, + 1.970826e+001, + 1.490684e+001, + 2.045055e+001, + // albedo 1, turbidity 4 + 1.469412e+000, + 2.524017e+000, + -4.197267e+000, + 2.365249e+001, + 1.664588e+001, + 2.134477e+001, + // albedo 1, turbidity 5 + 1.369714e+000, + 2.843548e+000, + -6.059031e+000, + 2.634993e+001, + 1.881361e+001, + 2.232186e+001, + // albedo 1, turbidity 6 + 1.310477e+000, + 2.984444e+000, + -6.831686e+000, + 2.682340e+001, + 2.123267e+001, + 2.259755e+001, + // albedo 1, turbidity 7 + 1.222552e+000, + 3.176523e+000, + -7.731496e+000, + 2.671760e+001, + 2.484358e+001, + 2.336863e+001, + // albedo 1, turbidity 8 + 1.115781e+000, + 3.130635e+000, + -7.581744e+000, + 2.336531e+001, + 3.171048e+001, + 2.413859e+001, + // albedo 1, turbidity 9 + 1.013181e+000, + 2.699342e+000, + -5.602709e+000, + 1.500158e+001, + 4.217613e+001, + 2.515957e+001, + // albedo 1, turbidity 10 + 8.976323e-001, + 1.726948e+000, + -1.296120e+000, + 1.183675e+000, + 5.503215e+001, + 2.643066e+001, +}; + +double datasetRGB3[] = +{ + // albedo 0, turbidity 1 + -1.372629e+000, + -4.905585e-001, + -4.100789e+001, + 4.122169e+001, + -7.389360e-003, + 4.839359e-001, + 6.474757e-003, + 3.471755e+000, + 5.092936e-001, + -1.523025e+000, + -6.497084e-001, + 6.249857e+000, + -5.662543e+000, + -1.908402e-002, + 5.512810e-001, + -2.181049e-005, + 2.507663e+000, + 4.339598e-001, + -1.035567e+000, + -7.478740e-002, + 9.221030e-001, + -2.140047e+000, + -2.374146e-002, + 3.795517e-001, + -1.769134e-002, + 7.479831e+000, + 7.729303e-001, + -1.271086e+000, + -5.588190e-001, + 6.908023e-001, + 2.096832e+000, + -2.453967e-001, + 1.410648e+000, + 4.475036e-002, + -4.719115e+000, + 5.741186e-001, + -9.712598e-001, + -7.033926e-002, + 9.167274e-001, + -9.502097e-001, + 3.004684e-001, + 4.547054e-001, + -5.929017e-002, + 5.266196e+000, + 7.204135e-001, + -1.087457e+000, + -1.888896e-001, + 8.156686e-001, + 3.101712e-001, + -2.155419e+000, + 1.422205e+000, + 9.692261e-002, + 3.122404e+000, + 4.999430e-001, + // albedo 0, turbidity 2 + -1.425280e+000, + -5.413508e-001, + -3.454883e+001, + 3.481142e+001, + -8.686975e-003, + 4.914268e-001, + -2.479243e-006, + 3.239879e+000, + 6.094201e-001, + -1.688557e+000, + -8.070865e-001, + 7.018459e+000, + -6.244574e+000, + -2.149341e-002, + 3.993971e-001, + 1.252502e-002, + 1.630662e+000, + 1.097860e-001, + -8.664152e-001, + 7.869125e-002, + -5.236535e-001, + -1.218960e+000, + -2.059093e-002, + 6.684898e-001, + -5.584112e-002, + 8.602299e+000, + 1.410496e+000, + -1.319763e+000, + -5.985323e-001, + 1.253918e+000, + 1.914706e+000, + -3.216739e-001, + 9.011213e-001, + 1.324845e-001, + -5.252749e+000, + 6.231252e-002, + -9.706008e-001, + -5.914059e-002, + 5.693150e-001, + -1.175362e+000, + 5.221644e-001, + 7.518213e-001, + -8.247655e-002, + 5.875635e+000, + 9.850863e-001, + -1.085330e+000, + -1.956105e-001, + 8.019605e-001, + 5.338101e-001, + -3.423464e+000, + 1.110444e+000, + 1.507923e-001, + 2.864942e+000, + 4.999481e-001, + // albedo 0, turbidity 3 + -1.431967e+000, + -5.478935e-001, + -3.286288e+001, + 3.305288e+001, + -8.380797e-003, + 4.772050e-001, + -3.044274e-006, + 3.289973e+000, + 5.976303e-001, + -1.801361e+000, + -9.315889e-001, + 5.391756e+000, + -4.588592e+000, + -2.040076e-002, + 4.144684e-001, + 1.814534e-002, + 1.051795e+000, + 1.145651e-001, + -7.905357e-001, + 1.451332e-001, + -1.605661e-001, + -1.592174e+000, + 4.561348e-004, + 3.380323e-001, + -7.770275e-002, + 8.775384e+000, + 1.489512e+000, + -1.308575e+000, + -5.539232e-001, + 9.184133e-001, + 2.011479e+000, + -3.842472e-001, + 1.432274e+000, + 1.637153e-001, + -4.408856e+000, + 5.272957e-002, + -9.829872e-001, + -8.183048e-002, + 4.464556e-001, + -1.442716e+000, + 1.029641e+000, + -6.991617e-002, + 8.702356e-003, + 5.706417e+000, + 9.116452e-001, + -1.087130e+000, + -2.038013e-001, + 7.260801e-001, + 9.164376e-001, + -5.006183e+000, + 1.511271e+000, + 1.257134e-001, + 2.715439e+000, + 6.201652e-001, + // albedo 0, turbidity 4 + -1.448662e+000, + -5.799075e-001, + -2.833268e+001, + 2.858023e+001, + -9.134061e-003, + 4.404783e-001, + -2.709026e-006, + 3.029357e+000, + 5.540071e-001, + -2.061772e+000, + -1.145190e+000, + 7.918478e+000, + -7.212525e+000, + -2.020760e-002, + 2.962715e-001, + 4.689670e-002, + 8.517209e-001, + 2.334587e-001, + -6.413755e-001, + 1.780425e-001, + -2.412919e+000, + 1.064484e+000, + -1.949986e-002, + 6.769741e-001, + -1.752760e-001, + 7.262714e+000, + 1.325869e+000, + -1.304871e+000, + -3.975581e-001, + 1.219002e+000, + 7.285178e-001, + -2.710105e-001, + 7.779727e-001, + 3.247139e-001, + -8.818168e-001, + 1.839517e-001, + -1.001104e+000, + -1.994801e-001, + 3.676742e-001, + -1.409737e+000, + 2.901555e-001, + 2.506940e-001, + 2.468899e-003, + 3.398923e+000, + 8.584645e-001, + -1.111552e+000, + -2.487204e-001, + 7.410842e-001, + 1.703749e+000, + -5.007855e+000, + 1.057763e+000, + 1.354511e-001, + 2.088715e+000, + 6.600013e-001, + // albedo 0, turbidity 5 + -1.547227e+000, + -6.679466e-001, + -1.861465e+001, + 1.884045e+001, + -1.242210e-002, + 4.157339e-001, + -2.432805e-006, + 2.812423e+000, + 5.446957e-001, + -2.043890e+000, + -1.149081e+000, + 2.304118e+000, + -1.715757e+000, + -2.433628e-002, + 2.816836e-001, + 7.185458e-002, + 1.064860e+000, + 2.706789e-001, + -9.040720e-001, + -8.274472e-002, + -2.555676e-001, + -6.326215e-001, + -2.770880e-002, + 6.676024e-001, + -2.513532e-001, + 5.903839e+000, + 1.241452e+000, + -1.000013e+000, + -1.010774e-001, + 3.699166e-001, + 8.774526e-001, + -3.042007e-001, + 6.951053e-001, + 4.361813e-001, + 6.793421e-001, + 2.573892e-001, + -1.171332e+000, + -3.768188e-001, + 3.701377e-001, + -1.470757e+000, + 5.525942e-001, + 2.991456e-002, + 1.581823e-002, + 2.365233e+000, + 8.214514e-001, + -1.068667e+000, + -2.326330e-001, + 6.725059e-001, + 2.243733e+000, + -4.614370e+000, + 1.033677e+000, + 1.376291e-001, + 2.013334e+000, + 6.865304e-001, + // albedo 0, turbidity 6 + -1.592991e+000, + -7.246948e-001, + -2.598204e+001, + 2.621960e+001, + -8.365176e-003, + 4.207571e-001, + -2.742772e-006, + 2.623735e+000, + 5.873190e-001, + -2.271349e+000, + -1.280884e+000, + 6.308739e+000, + -5.758350e+000, + -1.977049e-002, + 3.671835e-001, + 6.698038e-002, + 1.150597e+000, + 1.759218e-001, + -6.368620e-001, + -7.436052e-003, + -2.230026e+000, + 1.640997e+000, + -1.548497e-002, + 3.145331e-001, + -2.492644e-001, + 5.083843e+000, + 1.260215e+000, + -1.177925e+000, + -9.628114e-002, + 3.051152e-001, + -3.749544e-002, + -2.713209e-001, + 1.164226e+000, + 4.559969e-001, + 2.175429e+000, + 2.874284e-001, + -1.078500e+000, + -3.801779e-001, + 4.788906e-001, + -4.795969e-001, + 5.977621e-001, + -4.488535e-001, + 3.386874e-002, + 1.538143e+000, + 8.062054e-001, + -1.108028e+000, + -2.596892e-001, + 5.162202e-001, + 1.557081e+000, + -4.265039e+000, + 1.182535e+000, + 1.563762e-001, + 2.095084e+000, + 6.883383e-001, + // albedo 0, turbidity 7 + -1.668427e+000, + -7.908511e-001, + -2.779690e+001, + 2.799746e+001, + -7.186935e-003, + 3.757766e-001, + -3.326858e-006, + 2.563421e+000, + 5.439687e-001, + -2.156175e+000, + -1.220004e+000, + 3.585732e+000, + -3.235988e+000, + -1.086239e-002, + 1.846143e-001, + 1.046017e-001, + 1.234427e+000, + 2.842191e-001, + -1.117051e+000, + -4.101627e-001, + -8.463730e-001, + 7.671472e-001, + -2.226609e-002, + 8.574943e-001, + -3.434124e-001, + 4.475715e+000, + 1.154824e+000, + -7.444840e-001, + 2.312078e-001, + -5.393724e-001, + 1.574213e-001, + -1.763914e-001, + 2.751692e-001, + 5.564200e-001, + 2.217672e+000, + 3.483932e-001, + -1.273036e+000, + -5.275562e-001, + 4.902512e-001, + -4.498436e-002, + 4.339366e-001, + 2.386682e-001, + 2.380879e-002, + 1.413444e+000, + 7.855923e-001, + -1.084192e+000, + -2.936753e-001, + 4.719432e-001, + 1.384436e+000, + -3.257789e+000, + 6.119543e-001, + 1.681884e-001, + 1.650441e+000, + 6.936631e-001, + // albedo 0, turbidity 8 + -1.848490e+000, + -9.512670e-001, + -3.005251e+001, + 3.024315e+001, + -5.635304e-003, + 3.447780e-001, + -2.782999e-006, + 2.309422e+000, + 5.643559e-001, + -2.300008e+000, + -1.252335e+000, + -1.218876e+000, + 1.493730e+000, + -6.107100e-003, + 7.974860e-002, + 1.023449e-001, + 1.505934e+000, + 2.360948e-001, + -1.483705e+000, + -8.547575e-001, + -7.797146e-001, + 6.447971e-001, + -2.678052e-002, + 1.091263e+000, + -3.344889e-001, + 3.830416e+000, + 1.189425e+000, + -5.348005e-001, + 3.982733e-001, + -4.071573e-001, + 3.265569e-001, + -8.658789e-002, + -2.370892e-001, + 5.369097e-001, + 1.478279e+000, + 3.143303e-001, + -1.320401e+000, + -6.043247e-001, + 3.019196e-001, + -7.732911e-002, + 4.768381e-001, + 6.745764e-001, + 3.694098e-002, + 1.158234e+000, + 8.169056e-001, + -1.101040e+000, + -3.420019e-001, + 3.775661e-001, + 1.769338e+000, + -2.990515e+000, + 1.649529e-001, + 1.970125e-001, + 1.453355e+000, + 6.759757e-001, + // albedo 0, turbidity 9 + -2.251946e+000, + -1.229349e+000, + -3.271808e+001, + 3.283114e+001, + -4.252027e-003, + 3.372289e-001, + -3.001937e-006, + 2.154046e+000, + 5.842674e-001, + -1.867834e+000, + -9.531252e-001, + -1.229365e+001, + 1.269149e+001, + -6.844772e-003, + 1.185107e-001, + 7.539587e-002, + 1.846381e+000, + 1.899412e-001, + -3.398629e+000, + -2.180862e+000, + 2.335213e+000, + -3.382823e+000, + -8.613985e-003, + 8.431602e-001, + -2.393567e-001, + 3.112460e+000, + 1.218556e+000, + 5.708381e-001, + 9.406030e-001, + -6.890113e-001, + 2.746233e+000, + -5.772068e-002, + 1.096005e-001, + 3.491978e-001, + 7.281453e-001, + 3.212049e-001, + -1.705909e+000, + -8.517224e-001, + 1.131160e-001, + -2.141434e+000, + 4.274043e-001, + 3.397600e-001, + 1.786490e-001, + 9.026101e-001, + 7.882800e-001, + -1.012865e+000, + -3.495551e-001, + 3.369038e-001, + 3.724205e+000, + -3.089586e+000, + 1.266964e-001, + 1.461790e-001, + 1.170199e+000, + 6.931052e-001, + // albedo 0, turbidity 10 + -2.890318e+000, + -1.665573e+000, + -3.493756e+001, + 3.500369e+001, + -2.984251e-003, + 2.622419e-001, + -4.259360e-006, + 1.947681e+000, + 6.905752e-001, + -1.956022e+000, + -1.062900e+000, + -1.919714e+001, + 1.975164e+001, + -8.865396e-003, + 2.165540e-001, + 5.475637e-002, + 1.761134e+000, + 3.164249e-003, + -5.612198e+000, + -3.101371e+000, + 4.098034e+000, + -6.144001e+000, + 9.944958e-003, + 2.905472e-001, + -1.707110e-001, + 3.199107e+000, + 1.337660e+000, + 8.353756e-001, + 4.855943e-001, + -1.243589e+000, + 5.147385e+000, + -7.013963e-002, + 9.380410e-001, + 2.335714e-001, + 1.727744e-001, + 2.802696e-001, + -1.524329e+000, + -7.388547e-001, + 3.259025e-001, + -4.050634e+000, + 4.058549e-001, + -2.591384e-001, + 1.898299e-001, + 3.556071e-001, + 7.884126e-001, + -1.070371e+000, + -4.207858e-001, + 1.739862e-001, + 5.293410e+000, + -3.136757e+000, + 2.323856e-001, + 1.673706e-001, + 1.007227e+000, + 6.844287e-001, + // albedo 1, turbidity 1 + -1.341720e+000, + -4.834889e-001, + -4.633447e+001, + 4.682148e+001, + -6.137296e-003, + 4.599216e-001, + 7.047323e-003, + 2.895798e+000, + 4.999398e-001, + -1.529104e+000, + -6.498631e-001, + 1.534103e+001, + -1.450675e+001, + -1.531439e-002, + 3.280082e-001, + 1.682926e-002, + 1.901587e+000, + 5.013227e-001, + -1.014776e+000, + -1.454495e-001, + -4.071085e+000, + 2.954982e+000, + -2.630348e-002, + 5.681531e-001, + -3.016505e-002, + 6.773854e+000, + 5.003504e-001, + -1.172413e+000, + -4.026320e-001, + 2.960428e+000, + 2.020710e-001, + -2.004947e-001, + 9.375572e-001, + 5.998168e-002, + -4.945934e+000, + 4.502898e-001, + -9.898161e-001, + -5.772814e-002, + 4.470024e-001, + -5.786656e-001, + 1.158168e-001, + 3.468040e-001, + -5.043360e-002, + 6.867947e+000, + 8.012363e-001, + -1.085111e+000, + -1.882675e-001, + 1.223748e+000, + 3.565495e-001, + -3.688357e+000, + 5.653723e-001, + 6.727646e-002, + 2.690130e+000, + 4.999400e-001, + // albedo 1, turbidity 2 + -1.389119e+000, + -5.290250e-001, + -4.055774e+001, + 4.105972e+001, + -7.062577e-003, + 4.560060e-001, + -1.736334e-006, + 2.775512e+000, + 6.671455e-001, + -1.584641e+000, + -7.200619e-001, + 1.248067e+001, + -1.156028e+001, + -1.659568e-002, + 3.050029e-001, + 1.099895e-002, + 1.438927e+000, + -2.138015e-002, + -9.826068e-001, + -8.887254e-002, + -2.960031e+000, + 1.808816e+000, + -2.478159e-002, + 6.035733e-001, + -4.868441e-002, + 7.347705e+000, + 1.584739e+000, + -1.150423e+000, + -4.073793e-001, + 2.412991e+000, + 4.870840e-001, + -2.337902e-001, + 8.295114e-001, + 1.129914e-001, + -5.150045e+000, + -9.016643e-002, + -1.016933e+000, + -6.311501e-002, + 5.218937e-001, + -5.716430e-001, + 1.250993e-001, + 3.601524e-001, + -5.497586e-002, + 7.060139e+000, + 1.018333e+000, + -1.073151e+000, + -1.845444e-001, + 1.155394e+000, + 3.004486e-001, + -3.431711e+000, + 4.657031e-001, + 9.401223e-002, + 2.688620e+000, + 4.999544e-001, + // albedo 1, turbidity 3 + -1.391257e+000, + -5.365815e-001, + -4.255881e+001, + 4.299132e+001, + -5.838466e-003, + 4.229134e-001, + -2.760038e-006, + 2.775531e+000, + 6.234597e-001, + -1.780062e+000, + -9.228880e-001, + 1.376172e+001, + -1.260946e+001, + -1.507526e-002, + 3.117435e-001, + 2.205045e-002, + 6.093731e-001, + 3.463446e-002, + -7.388169e-001, + 1.275670e-001, + -3.999528e+000, + 2.223993e+000, + -1.856853e-002, + 5.439310e-001, + -8.834054e-002, + 8.037139e+000, + 1.645951e+000, + -1.322387e+000, + -5.320143e-001, + 2.659359e+000, + 1.086712e+000, + -2.129712e-001, + 8.704649e-001, + 1.800315e-001, + -4.967241e+000, + -1.383720e-001, + -9.378288e-001, + -1.599895e-002, + 3.607555e-001, + -1.980561e+000, + 3.791456e-001, + 1.212268e-001, + -2.845992e-002, + 6.825542e+000, + 1.059139e+000, + -1.100832e+000, + -2.172313e-001, + 1.211561e+000, + 2.002721e+000, + -5.010011e+000, + 5.717583e-001, + 6.777702e-002, + 2.160006e+000, + 5.676392e-001, + // albedo 1, turbidity 4 + -1.409373e+000, + -5.708751e-001, + -3.034974e+001, + 3.079809e+001, + -7.280715e-003, + 3.723304e-001, + -2.436279e-006, + 2.577348e+000, + 5.913377e-001, + -1.954312e+000, + -1.116510e+000, + 5.399148e+000, + -4.299553e+000, + -1.724739e-002, + 3.742824e-001, + 4.187077e-002, + 1.044883e-001, + 1.232727e-001, + -6.772215e-001, + 2.001396e-001, + -3.670523e-001, + -1.014628e+000, + -3.497152e-003, + 4.099858e-001, + -1.584633e-001, + 7.750400e+000, + 1.514559e+000, + -1.291600e+000, + -4.977437e-001, + 9.641914e-001, + 1.562420e+000, + -3.227782e-001, + 9.055427e-001, + 3.046444e-001, + -3.385619e+000, + 9.546291e-003, + -9.750857e-001, + -8.770560e-002, + 9.054256e-001, + -1.429236e+000, + 8.974777e-001, + -1.217961e-001, + -5.194608e-002, + 4.909409e+000, + 9.589153e-001, + -1.088007e+000, + -1.959301e-001, + 9.745799e-001, + 1.260761e+000, + -5.008864e+000, + 7.271248e-001, + 1.096661e-001, + 2.717295e+000, + 6.340731e-001, + // albedo 1, turbidity 5 + -1.456050e+000, + -6.223072e-001, + -2.228088e+001, + 2.269604e+001, + -9.340812e-003, + 4.118308e-001, + -2.418083e-006, + 2.442117e+000, + 5.589638e-001, + -2.176449e+000, + -1.302416e+000, + 2.222836e+000, + -1.222730e+000, + -1.728051e-002, + 1.323513e-001, + 7.027731e-002, + 4.835745e-002, + 2.093351e-001, + -5.789641e-001, + 2.215407e-001, + 2.142291e-001, + -1.201725e+000, + -1.185728e-002, + 8.122982e-001, + -2.380420e-001, + 6.706841e+000, + 1.404146e+000, + -1.307463e+000, + -4.515174e-001, + 6.447827e-001, + 1.223841e+000, + -2.902391e-001, + 4.986588e-001, + 4.073652e-001, + -1.706696e+000, + 1.060885e-001, + -9.698678e-001, + -1.307094e-001, + 9.389347e-001, + -1.522852e+000, + 7.768797e-001, + -1.368595e-001, + -3.857426e-002, + 3.676935e+000, + 8.980966e-001, + -1.104349e+000, + -2.380323e-001, + 1.047043e+000, + 1.865421e+000, + -5.011664e+000, + 7.014954e-001, + 9.622701e-002, + 1.891360e+000, + 6.687354e-001, + // albedo 1, turbidity 6 + -1.502249e+000, + -6.724523e-001, + -2.888092e+001, + 2.930360e+001, + -6.685766e-003, + 3.685464e-001, + -2.469442e-006, + 2.310797e+000, + 5.566754e-001, + -2.217125e+000, + -1.364924e+000, + 4.048243e+000, + -3.111333e+000, + -1.317747e-002, + 1.921948e-001, + 8.627702e-002, + 1.981769e-003, + 2.213689e-001, + -6.215757e-001, + 1.687995e-001, + -5.949131e-001, + -1.551293e-001, + 3.356129e-004, + 6.897657e-001, + -2.855053e-001, + 6.271042e+000, + 1.363084e+000, + -1.216317e+000, + -3.489429e-001, + 7.566226e-001, + 5.409809e-001, + -2.830843e-001, + 6.191825e-001, + 4.755163e-001, + -9.131387e-001, + 1.383909e-001, + -1.030437e+000, + -2.034064e-001, + 8.335995e-001, + -1.050947e+000, + 8.689093e-001, + -3.672310e-001, + -4.056183e-002, + 3.111269e+000, + 8.856842e-001, + -1.078984e+000, + -2.070549e-001, + 9.683145e-001, + 1.497022e+000, + -5.007653e+000, + 7.702541e-001, + 1.285822e-001, + 2.225188e+000, + 6.587911e-001, + // albedo 1, turbidity 7 + -1.559291e+000, + -7.374039e-001, + -3.596311e+001, + 3.634470e+001, + -4.667132e-003, + 3.277964e-001, + -2.487945e-006, + 2.215652e+000, + 5.764681e-001, + -2.356929e+000, + -1.444755e+000, + 6.244526e+000, + -5.540162e+000, + -8.794510e-003, + 1.792100e-001, + 9.578517e-002, + 3.737676e-001, + 1.922194e-001, + -6.589752e-001, + -2.926910e-002, + -1.831779e+000, + 1.869962e+000, + -2.030095e-003, + 7.552089e-001, + -3.168157e-001, + 4.632196e+000, + 1.294054e+000, + -1.161046e+000, + -1.472506e-001, + 6.494138e-001, + -8.327174e-001, + -2.320724e-001, + 3.391212e-001, + 5.269637e-001, + 9.376341e-001, + 2.458573e-001, + -1.034427e+000, + -3.062504e-001, + 8.975634e-001, + 3.203531e-001, + 8.565142e-001, + -1.250162e-001, + -4.094017e-002, + 1.861304e+000, + 8.223468e-001, + -1.109954e+000, + -2.740277e-001, + 1.063811e+000, + 7.077398e-001, + -4.695734e+000, + 5.621696e-001, + 1.248956e-001, + 1.297723e+000, + 6.789720e-001, + // albedo 1, turbidity 8 + -1.788293e+000, + -9.368751e-001, + -4.382980e+001, + 4.424963e+001, + -3.652530e-003, + 3.094331e-001, + -2.810503e-006, + 1.904402e+000, + 5.861599e-001, + -2.268206e+000, + -1.312676e+000, + 2.863082e+000, + -2.373727e+000, + -5.144980e-003, + 1.711072e-001, + 9.316041e-002, + 9.309598e-001, + 1.791683e-001, + -1.376966e+000, + -7.418582e-001, + -1.349589e+000, + 1.563419e+000, + -3.124219e-003, + 6.967139e-001, + -3.061887e-001, + 3.602731e+000, + 1.255669e+000, + -6.017540e-001, + 2.815928e-001, + 5.424052e-001, + -6.885450e-001, + -1.620001e-001, + 2.980046e-001, + 4.995571e-001, + 7.371203e-001, + 2.812466e-001, + -1.278853e+000, + -5.245326e-001, + 7.870520e-001, + 3.125067e-001, + 7.748105e-001, + -7.788581e-002, + 3.490956e-003, + 1.283748e+000, + 8.130190e-001, + -1.050930e+000, + -2.786331e-001, + 1.056344e+000, + 1.053002e+000, + -4.047789e+000, + 4.432174e-001, + 1.169077e-001, + 9.532621e-001, + 6.806764e-001, + // albedo 1, turbidity 9 + -2.084927e+000, + -1.203954e+000, + -4.881638e+001, + 4.920160e+001, + -2.896045e-003, + 2.882977e-001, + -3.073517e-006, + 1.702211e+000, + 6.374180e-001, + -2.328567e+000, + -1.238023e+000, + -1.891019e+000, + 2.451520e+000, + -5.847581e-003, + 2.084702e-001, + 7.848130e-002, + 1.211048e+000, + 8.095008e-002, + -2.634632e+000, + -1.789460e+000, + -1.370558e-001, + -3.326435e-001, + 2.783737e-003, + 5.239451e-001, + -2.548881e-001, + 2.896327e+000, + 1.324116e+000, + 6.882616e-002, + 5.997821e-001, + 1.535398e-001, + 1.375209e+000, + -1.267285e-001, + 4.239743e-001, + 4.013122e-001, + 1.794675e-001, + 2.395382e-001, + -1.430918e+000, + -6.439041e-001, + 8.325980e-001, + -1.705612e+000, + 7.236426e-001, + -5.567593e-002, + 6.408718e-002, + 6.836524e-001, + 8.388887e-001, + -1.037956e+000, + -3.215402e-001, + 9.457349e-001, + 3.178114e+000, + -4.152156e+000, + 2.230992e-001, + 1.156198e-001, + 7.606223e-001, + 6.656923e-001, + // albedo 1, turbidity 10 + -2.967314e+000, + -1.728778e+000, + -3.730988e+001, + 3.755578e+001, + -2.588835e-003, + 2.927966e-001, + -3.935038e-006, + 1.592161e+000, + 6.868694e-001, + -2.123311e+000, + -1.175148e+000, + -1.314988e+001, + 1.386882e+001, + -7.828537e-003, + 1.852026e-001, + 5.481038e-002, + 1.294309e+000, + 2.428177e-002, + -5.443597e+000, + -3.156344e+000, + 2.110838e+000, + -3.421556e+000, + 1.181890e-002, + 1.196951e-001, + -1.742902e-001, + 2.404353e+000, + 1.272805e+000, + 1.029898e+000, + 5.912521e-001, + -3.983531e-001, + 3.286069e+000, + -9.252065e-002, + 1.331381e+000, + 2.560642e-001, + 8.001754e-001, + 3.624178e-001, + -1.547574e+000, + -7.881604e-001, + 1.020902e+000, + -2.897069e+000, + 5.213470e-001, + -9.242315e-001, + 1.185594e-001, + -1.150721e+000, + 7.317211e-001, + -9.621043e-001, + -1.991406e-001, + 6.531287e-001, + 3.925839e+000, + -3.596904e+000, + 6.317332e-001, + 1.531334e-001, + 1.457846e+000, + 6.966285e-001, +}; + +double datasetRGBRad3[] = +{ + // albedo 0, turbidity 1 + 9.926518e-001, + 1.999494e+000, + -4.136109e+000, + 1.856270e+001, + 1.351028e+001, + 1.390238e+001, + // albedo 0, turbidity 2 + 9.634366e-001, + 2.119694e+000, + -4.614523e+000, + 1.919701e+001, + 1.376644e+001, + 1.418731e+001, + // albedo 0, turbidity 3 + 9.446537e-001, + 2.171610e+000, + -4.915556e+000, + 1.918240e+001, + 1.537135e+001, + 1.400530e+001, + // albedo 0, turbidity 4 + 9.073074e-001, + 2.330536e+000, + -5.577596e+000, + 1.961615e+001, + 1.688365e+001, + 1.446955e+001, + // albedo 0, turbidity 5 + 8.739124e-001, + 2.388682e+000, + -5.842995e+000, + 1.923265e+001, + 1.887735e+001, + 1.485698e+001, + // albedo 0, turbidity 6 + 8.563688e-001, + 2.391534e+000, + -5.769133e+000, + 1.828709e+001, + 2.097209e+001, + 1.469587e+001, + // albedo 0, turbidity 7 + 8.270533e-001, + 2.342790e+000, + -5.558071e+000, + 1.684993e+001, + 2.356498e+001, + 1.505975e+001, + // albedo 0, turbidity 8 + 7.908339e-001, + 2.190341e+000, + -4.852571e+000, + 1.374862e+001, + 2.806846e+001, + 1.548444e+001, + // albedo 0, turbidity 9 + 7.403619e-001, + 1.783998e+000, + -2.983854e+000, + 7.622563e+000, + 3.507610e+001, + 1.615805e+001, + // albedo 0, turbidity 10 + 6.840111e-001, + 1.154457e+000, + -2.393830e-001, + -7.896893e-001, + 4.282765e+001, + 1.779469e+001, + // albedo 1, turbidity 1 + 1.168300e+000, + 1.860993e+000, + -2.129074e+000, + 1.251952e+001, + 3.032499e+001, + 2.938716e+001, + // albedo 1, turbidity 2 + 1.150338e+000, + 1.918813e+000, + -2.413527e+000, + 1.274862e+001, + 3.087134e+001, + 2.951432e+001, + // albedo 1, turbidity 3 + 1.114719e+000, + 1.964689e+000, + -2.625423e+000, + 1.247837e+001, + 3.237949e+001, + 2.943596e+001, + // albedo 1, turbidity 4 + 1.077948e+000, + 2.006292e+000, + -2.846934e+000, + 1.190195e+001, + 3.459293e+001, + 2.937492e+001, + // albedo 1, turbidity 5 + 1.035143e+000, + 1.986681e+000, + -2.752584e+000, + 1.060972e+001, + 3.722185e+001, + 2.918594e+001, + // albedo 1, turbidity 6 + 1.015992e+000, + 1.992054e+000, + -2.812626e+000, + 1.001416e+001, + 3.847300e+001, + 2.924624e+001, + // albedo 1, turbidity 7 + 9.756887e-001, + 1.939897e+000, + -2.533281e+000, + 8.319176e+000, + 4.083907e+001, + 2.925586e+001, + // albedo 1, turbidity 8 + 9.264164e-001, + 1.716454e+000, + -1.597044e+000, + 4.739725e+000, + 4.507683e+001, + 2.878915e+001, + // albedo 1, turbidity 9 + 8.595191e-001, + 1.346034e+000, + -2.801895e-002, + -6.582906e-001, + 5.017523e+001, + 2.852953e+001, + // albedo 1, turbidity 10 + 7.754116e-001, + 7.709245e-001, + 2.200201e+000, + -7.487661e+000, + 5.436622e+001, + 2.893432e+001, +}; + +double* datasetsRGB[] = +{ + datasetRGB1, + datasetRGB2, + datasetRGB3 +}; + +double* datasetsRGBRad[] = +{ + datasetRGBRad1, + datasetRGBRad2, + datasetRGBRad3 +}; diff --git a/rpplugins/scattering/resources/hosek_wilkie_scattering/source/config_module.cpp b/rpplugins/scattering/resources/hosek_wilkie_scattering/source/config_module.cpp new file mode 100644 index 0000000..1597710 --- /dev/null +++ b/rpplugins/scattering/resources/hosek_wilkie_scattering/source/config_module.cpp @@ -0,0 +1,34 @@ + +#include "config_module.h" + +/* + +Include all your dynamically typed classes here, e.g. +#include "my_dynamic_class.h" + +*/ + +#include "dconfig.h" + + +Configure( config_mymodule ); +NotifyCategoryDef( mymodule , ""); + +ConfigureFn( config_mymodule ) { + init_libmymodule(); +} + +void +init_libmymodule() { + static bool initialized = false; + if (initialized) { + return; + } + initialized = true; + + // Init your dynamic types here, e.g.: + // MyDynamicClass::init_type(); + + return; +} + diff --git a/rpplugins/scattering/resources/hosek_wilkie_scattering/source/config_module.h b/rpplugins/scattering/resources/hosek_wilkie_scattering/source/config_module.h new file mode 100644 index 0000000..b0aa4e5 --- /dev/null +++ b/rpplugins/scattering/resources/hosek_wilkie_scattering/source/config_module.h @@ -0,0 +1,12 @@ +#pragma once + +#include "pandabase.h" +#include "notifyCategoryProxy.h" +#include "configVariableDouble.h" +#include "configVariableString.h" +#include "configVariableInt.h" + + +NotifyCategoryDecl(mymodule, EXPORT_CLASS, EXPORT_TEMPL); + +extern void init_libmymodule(); diff --git a/rpplugins/scattering/resources/hosek_wilkie_scattering/source/main.h b/rpplugins/scattering/resources/hosek_wilkie_scattering/source/main.h new file mode 100644 index 0000000..3ace461 --- /dev/null +++ b/rpplugins/scattering/resources/hosek_wilkie_scattering/source/main.h @@ -0,0 +1,101 @@ + + +#include "ArHosekSkyModel.h" +#include "PNMImage.h" +#include "Texture.h" + +#include +using namespace std; + +#define ONE_PI 3.14159265359 +#define TWO_PI 6.28318530718 + +double srgb_clamp(double v) { + v = max(0.0, min(1.0, v / 255.0)); + return v; +} + + +BEGIN_PUBLISH +INLINE void generate_table() +{ + + const double min_elevation = 0.0; // degree + const double max_elevation = 40.0; // degree + double turbidity = 3.0; + double albedo = 0.2; + + cout << "Scattering Precomputation v0.1" << endl; + cout << "Turbidity (double from 0 to 10): "; + cin >> turbidity; + cout << "Ground Albedo (double from 0 to 1): "; + cin >> albedo; + + const double sun_azimuth = ONE_PI * 0.25; + + PNMImage img(512 * 10, 128 * 10, 3, 65535); + + for (size_t elev = 0; elev < 100; ++elev) { + if (elev % 10 == 0) + cout << elev << " percent" << endl; + + double factor = ((double)elev) / 99.0; + double angle = factor * (max_elevation - min_elevation) + min_elevation; + + const double sun_elevation = angle / 360.0 * TWO_PI; + const int num_channels = 3; + + ArHosekSkyModelState* skymodel_state = arhosek_rgb_skymodelstate_alloc_init( + turbidity, albedo, sun_elevation); + + double skydome_result[num_channels]; + + for (size_t i = 0; i < 512; ++i) { + for (size_t k = 0; k < 128; ++k) { + + double factor_x = ((double)i) / 512.0; + double factor_y = ((double)k) / 128.0; + + double theta = 0, gamma = 0; + + if (true) { + // write out raw angles + gamma = factor_x * 2.0 * ONE_PI; + theta = factor_y * 0.5 * ONE_PI; + } + else { + // Write out transformed angles + double coord_azimuth = factor_x * TWO_PI; + theta = factor_y * ONE_PI * 0.5; + double neg_solar_elevation = 0.5 * ONE_PI - sun_elevation; + + double cosGamma = cos(theta) * cos(neg_solar_elevation) + + sin(theta) * sin(neg_solar_elevation) + * cos(coord_azimuth - sun_azimuth); + + gamma = acos(cosGamma); + } + + for (size_t r = 0; r < num_channels; r++) { + skydome_result[r] = srgb_clamp(arhosek_tristim_skymodel_radiance( + skymodel_state, theta, gamma, r)); + } + + img.set_xel(i + (elev % 10) * 512, k + (elev / 10) * 128, + skydome_result[0], skydome_result[1], skydome_result[2]); + } + } + + arhosekskymodelstate_free(skymodel_state); + } + + cout << "Writing data ..." << endl; + // img.write("scattering_lut.png"); + + Texture t; + t.setup_2d_texture(img.get_x_size(), img.get_y_size(), Texture::T_float, Texture::F_rgb16); + t.load(img); + t.write("scattering_lut.txo.pz"); +} + +END_PUBLISH diff --git a/rpplugins/scattering/resources/hosek_wilkie_scattering/update_module_builder.py b/rpplugins/scattering/resources/hosek_wilkie_scattering/update_module_builder.py new file mode 100644 index 0000000..ab2d79e --- /dev/null +++ b/rpplugins/scattering/resources/hosek_wilkie_scattering/update_module_builder.py @@ -0,0 +1,57 @@ +""" + +RenderPipeline + +Copyright (c) 2014-2016 tobspr + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. + +""" + +# This script downloads and updates the module builder. + +# pylint: skip-file + +if __name__ == "__main__": + import os + import sys + from os.path import dirname, realpath, join, isfile + + # Files which are skipped from the downloaded zip + files_to_ignore = "__init__.py LICENSE README.md config.ini config_module".split() + + current_dir = dirname(realpath(__file__)) + os.chdir(current_dir) + + # Import thirdparty packages + sys.path.insert(0, "../" * 4 + "rpcore/util") + sys.path.insert(0, "../" * 4) + + # Download the module + from submodule_downloader import download_submodule + download_submodule("tobspr", "P3DModuleBuilder", current_dir, files_to_ignore) + + # Make an init script so we can import the code + with open("scripts/__init__.py", "w") as handle: + handle.write("# empty file to be able to import the scripts") + + # Update the gitignore using the suggested version from the module builder + if isfile(".gitignore"): + os.remove(".gitignore") + os.rename("prefab.gitignore", ".gitignore") diff --git a/rpplugins/scattering/scattering_envmap_stage.py b/rpplugins/scattering/scattering_envmap_stage.py new file mode 100644 index 0000000..26a0c83 --- /dev/null +++ b/rpplugins/scattering/scattering_envmap_stage.py @@ -0,0 +1,68 @@ +""" + +RenderPipeline + +Copyright (c) 2014-2016 tobspr + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. + +""" + +from __future__ import division + +from rpcore.render_stage import RenderStage +from rpcore.util.cubemap_filter import CubemapFilter + +from rpcore.stages.ambient_stage import AmbientStage +from rpcore.stages.gbuffer_stage import GBufferStage + + +class ScatteringEnvmapStage(RenderStage): + + """ This stage uses the precomputed data to make a cubemap containing the + scattering """ + + required_pipes = [] + required_inputs = ["DefaultSkydome", "DefaultEnvmap"] + + @property + def produced_pipes(self): + return { + "ScatteringIBLDiffuse": self.cubemap_filter.diffuse_cubemap, + "ScatteringIBLSpecular": self.cubemap_filter.specular_cubemap, + } + + def create(self): + self.cubemap_filter = CubemapFilter(self, "ScatEnvCub") + + self.target_cube = self.create_target("ComputeScattering") + self.target_cube.size = self.cubemap_filter.size * 6, self.cubemap_filter.size + self.target_cube.prepare_buffer() + self.target_cube.set_shader_input("DestCubemap", self.cubemap_filter.target_cubemap) + + self.cubemap_filter.create() + + # Make the stages use our cubemap textures + for stage in (AmbientStage, GBufferStage): + stage.required_pipes.append("ScatteringIBLDiffuse") + stage.required_pipes.append("ScatteringIBLSpecular") + + def reload_shaders(self): + self.target_cube.shader = self.load_plugin_shader("scattering_envmap.frag.glsl") + self.cubemap_filter.reload_shaders() diff --git a/rpplugins/scattering/scattering_methods.py b/rpplugins/scattering/scattering_methods.py new file mode 100644 index 0000000..8b19809 --- /dev/null +++ b/rpplugins/scattering/scattering_methods.py @@ -0,0 +1,254 @@ +""" + +RenderPipeline + +Copyright (c) 2014-2016 tobspr + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. + +""" + +import math + +from rplibs.six.moves import range # pylint: disable=import-error +from rplibs.six import iteritems, itervalues + +from direct.stdpy.file import listdir, isfile, join +from panda3d.core import SamplerState, ShaderAttrib, NodePath + +from rpcore.globals import Globals +from rpcore.rpobject import RPObject +from rpcore.image import Image +from rpcore.loader import RPLoader + + +class ScatteringMethod(RPObject): + + """ Base class for all scattering methods """ + + def __init__(self, plugin_handle): + RPObject.__init__(self) + self.handle = plugin_handle + + def load(self): + """ Should load all required resources here """ + raise NotImplementedError() + + def compute(self): + """ Should compute the model here if necessary """ + raise NotImplementedError() + + +class ScatteringMethodHosekWilkie(ScatteringMethod): + + """ Scattering as suggested by Hosek and Wilkie """ + + def load(self): + """ Loads the scattering method """ + lut_src = self.handle.get_resource( + "hosek_wilkie_scattering/scattering_lut.txo") + + if not isfile(lut_src): + self.error("Could not find precompiled LUT for the Hosek Wilkie " + "Scattering! Make sure you compiled the algorithm code!") + return + + lut_tex = RPLoader.load_sliced_3d_texture(lut_src, 512, 128, 100) + lut_tex.set_wrap_u(SamplerState.WM_repeat) + lut_tex.set_wrap_v(SamplerState.WM_clamp) + lut_tex.set_wrap_w(SamplerState.WM_clamp) + lut_tex.set_minfilter(SamplerState.FT_linear) + lut_tex.set_magfilter(SamplerState.FT_linear) + + # Setting the format explicitely shouldn't be necessary + # lut_tex.set_format(Image.F_rgb16) + + self.handle.display_stage.set_shader_input("ScatteringLUT", lut_tex) + self.handle.envmap_stage.set_shader_input("ScatteringLUT", lut_tex) + + def compute(self): + """ Computes the scattering method, not required since we use a precomputed + LUT """ + pass + + +class ScatteringMethodEricBruneton(ScatteringMethod): + + """ Precomputed atmospheric scattering by Eric Bruneton """ + + def load(self): + """ Inits parameters, those should match with the ones specified in common.glsl """ + self.use_32_bit = False + self.trans_w, self.trans_h = 256 * 4, 64 * 4 + self.sky_w, self.sky_h = 64 * 4, 16 * 4 + self.res_r, self.res_mu, self.res_mu_s, self.res_nu = 32, 128, 32, 8 + self.res_mu_s_nu = self.res_mu_s * self.res_nu + + self.create_shaders() + self.create_textures() + + def create_textures(self): + """ Creates all textures required for the scattering """ + + tex_format = "RGBA32" if self.use_32_bit else "RGBA16" + img_2d, img_3d = Image.create_2d, Image.create_3d + + self.textures = { + "transmittance": img_2d("scat-trans", self.trans_w, self.trans_h, tex_format), + "irradiance": img_2d("scat-irrad", self.sky_w, self.sky_h, tex_format), + "inscatter": img_3d("scat-inscat", self.res_mu_s_nu, self.res_mu, self.res_r, tex_format), # noqa # pylint: disable=line-too-long + "delta_e": img_2d("scat-dx-e", self.sky_w, self.sky_h, tex_format), + "delta_sr": img_3d("scat-dx-sr", self.res_mu_s_nu, self.res_mu, self.res_r, tex_format), + "delta_sm": img_3d("scat-dx-sm", self.res_mu_s_nu, self.res_mu, self.res_r, tex_format), + "delta_j": img_3d("scat-dx-j", self.res_mu_s_nu, self.res_mu, self.res_r, tex_format), + } + + for img in itervalues(self.textures): + img.set_minfilter(SamplerState.FT_linear) + img.set_magfilter(SamplerState.FT_linear) + img.set_wrap_u(SamplerState.WM_clamp) + img.set_wrap_v(SamplerState.WM_clamp) + img.set_wrap_w(SamplerState.WM_clamp) + + def create_shaders(self): + """ Creates all the shaders used for precomputing """ + self.shaders = {} + resource_path = self.handle.get_shader_resource("eric_bruneton") + for fname in listdir(resource_path): + fpath = join(resource_path, fname) + if isfile(fpath) and fname.endswith(".compute.glsl"): + shader_name = fname.split(".")[0] + shader_obj = RPLoader.load_shader(fpath) + self.shaders[shader_name] = shader_obj + + def exec_compute_shader(self, shader_obj, shader_inputs, exec_size, + workgroup_size=(16, 16, 1)): + """ Executes a compute shader. The shader object should be a shader + loaded with Shader.load_compute, the shader inputs should be a dict where + the keys are the names of the shader inputs and the values are the + inputs. The workgroup_size has to match the size defined in the + compute shader """ + ntx = int(math.ceil(exec_size[0] / workgroup_size[0])) + nty = int(math.ceil(exec_size[1] / workgroup_size[1])) + ntz = int(math.ceil(exec_size[2] / workgroup_size[2])) + + nodepath = NodePath("shader") + nodepath.set_shader(shader_obj) + nodepath.set_shader_inputs(**shader_inputs) + + attr = nodepath.get_attrib(ShaderAttrib) + Globals.base.graphicsEngine.dispatch_compute( + (ntx, nty, ntz), attr, Globals.base.win.gsg) + + def compute(self): + """ Precomputes the scattering """ + + self.debug("Precomputing ...") + exec_cshader = self.exec_compute_shader + + # Transmittance + exec_cshader( + self.shaders["transmittance"], { + "dest": self.textures["transmittance"] + }, (self.trans_w, self.trans_h, 1)) + + # Delta E + exec_cshader( + self.shaders["delta_e"], { + "transmittanceSampler": self.textures["transmittance"], + "dest": self.textures["delta_e"] + }, (self.sky_w, self.sky_h, 1)) + + # Delta S + exec_cshader( + self.shaders["delta_sm_sr"], { + "transmittanceSampler": self.textures["transmittance"], + "destDeltaSR": self.textures["delta_sr"], + "destDeltaSM": self.textures["delta_sm"] + }, (self.res_mu_s_nu, self.res_mu, self.res_r), (8, 8, 8)) + + # Copy deltaE to irradiance texture + exec_cshader( + self.shaders["copy_irradiance"], { + "k": 0.0, + "deltaESampler": self.textures["delta_e"], + "dest": self.textures["irradiance"] + }, (self.sky_w, self.sky_h, 1)) + + # Copy delta s into inscatter texture + exec_cshader( + self.shaders["copy_inscatter"], { + "deltaSRSampler": self.textures["delta_sr"], + "deltaSMSampler": self.textures["delta_sm"], + "dest": self.textures["inscatter"] + }, (self.res_mu_s_nu, self.res_mu, self.res_r), (8, 8, 8)) + + for order in range(2, 5): + first = order == 2 + + # Delta J + exec_cshader( + self.shaders["delta_j"], { + "transmittanceSampler": self.textures["transmittance"], + "deltaSRSampler": self.textures["delta_sr"], + "deltaSMSampler": self.textures["delta_sm"], + "deltaESampler": self.textures["delta_e"], + "dest": self.textures["delta_j"], + "first": first + }, (self.res_mu_s_nu, self.res_mu, self.res_r), (8, 8, 8)) + + # Delta E + exec_cshader( + self.shaders["irradiance_n"], { + "transmittanceSampler": self.textures["transmittance"], + "deltaSRSampler": self.textures["delta_sr"], + "deltaSMSampler": self.textures["delta_sm"], + "dest": self.textures["delta_e"], + "first": first + }, (self.sky_w, self.sky_h, 1)) + + # Delta Sr + exec_cshader( + self.shaders["delta_sr"], { + "transmittanceSampler": self.textures["transmittance"], + "deltaJSampler": self.textures["delta_j"], + "dest": self.textures["delta_sr"], + "first": first + }, (self.res_mu_s_nu, self.res_mu, self.res_r), (8, 8, 8)) + + # Add delta E to irradiance + exec_cshader( + self.shaders["add_delta_e"], { + "deltaESampler": self.textures["delta_e"], + "dest": self.textures["irradiance"], + }, (self.sky_w, self.sky_h, 1)) + + # Add deltaSr to inscatter texture + exec_cshader( + self.shaders["add_delta_sr"], { + "deltaSSampler": self.textures["delta_sr"], + "dest": self.textures["inscatter"] + }, (self.res_mu_s_nu, self.res_mu, self.res_r), (8, 8, 8)) + + # Make stages available + for stage in [self.handle.display_stage, self.handle.envmap_stage]: + stage.set_shader_inputs( + InscatterSampler=self.textures["inscatter"], + transmittanceSampler=self.textures["transmittance"], + IrradianceSampler=self.textures["irradiance"]) diff --git a/rpplugins/scattering/scattering_stage.py b/rpplugins/scattering/scattering_stage.py new file mode 100644 index 0000000..908e5b3 --- /dev/null +++ b/rpplugins/scattering/scattering_stage.py @@ -0,0 +1,49 @@ +""" + +RenderPipeline + +Copyright (c) 2014-2016 tobspr + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. + +""" + +from __future__ import division + +from rpcore.render_stage import RenderStage + + +class ScatteringStage(RenderStage): + + """ This stage uses the precomputed data to display the scattering """ + + required_pipes = ["ShadedScene", "GBuffer"] + required_inputs = ["DefaultSkydome"] + + @property + def produced_pipes(self): + return {"ShadedScene": self.target.color_tex} + + def create(self): + self.target = self.create_target("ApplyScattering") + self.target.add_color_attachment(bits=16, alpha=True) + self.target.prepare_buffer() + + def reload_shaders(self): + self.target.shader = self.load_plugin_shader("apply_scattering.frag.glsl") diff --git a/rpplugins/scattering/shader/LICENSE.txt b/rpplugins/scattering/shader/LICENSE.txt new file mode 100644 index 0000000..2e6526e --- /dev/null +++ b/rpplugins/scattering/shader/LICENSE.txt @@ -0,0 +1,37 @@ + +Some parts of the shaders in the plugin contain code from a +publication from Eric Bruneton: + +https://hal.inria.fr/inria-00288758/document + +Below is the license for this code: + + +Precomputed Atmospheric Scattering +Copyright (c) 2008 INRIA +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions +are met: +1. Redistributions of source code must retain the above copyright +notice, this list of conditions and the following disclaimer. +2. Redistributions in binary form must reproduce the above copyright +notice, this list of conditions and the following disclaimer in the +documentation and/or other materials provided with the distribution. +3. Neither the name of the copyright holders nor the names of its +contributors may be used to endorse or promote products derived from +this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE +LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF +THE POSSIBILITY OF SUCH DAMAGE. + diff --git a/rpplugins/scattering/shader/apply_scattering.frag.glsl b/rpplugins/scattering/shader/apply_scattering.frag.glsl new file mode 100644 index 0000000..63d802b --- /dev/null +++ b/rpplugins/scattering/shader/apply_scattering.frag.glsl @@ -0,0 +1,101 @@ +/** + * + * RenderPipeline + * + * Copyright (c) 2014-2016 tobspr + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + */ + +#version 430 + +#define USE_TIME_OF_DAY 1 +#pragma include "render_pipeline_base.inc.glsl" +#pragma include "includes/gbuffer.inc.glsl" + +uniform sampler2D ShadedScene; +uniform sampler2D DefaultSkydome; + +uniform GBufferData GBuffer; + +out vec4 result; + +#pragma include "scattering_method.inc.glsl" + +void main() { + + vec2 texcoord = get_texcoord(); + + // Get material data + Material m = unpack_material(GBuffer); + vec3 view_vector = normalize(m.position - MainSceneData.camera_pos); + vec3 orig_view_vector = view_vector; + + // Fetch scattering + float sky_clip = 0.0; + + // Prevent a way too dark horizon by clamping the view vector + if (is_skybox(m)) { + view_vector.z = max(view_vector.z, 0.05); + } + + vec3 inscattered_light = DoScattering(m.position, view_vector, sky_clip) + * TimeOfDay.scattering.sun_intensity; + + result.xyz = textureLod(ShadedScene, texcoord, 0).xyz; + result.w = 1; + + // Cloud color + if (is_skybox(m)) { + + inscattered_light *= M_PI; // XXX: This makes it look better, but has no physical background. + + #if !HAVE_PLUGIN(clouds) + vec3 cloud_color = textureLod(DefaultSkydome, get_skydome_coord(orig_view_vector), 0).xyz; + // inscattered_light = 15 * cloud_color * M_PI; + cloud_color = mix(vec3(0.5), cloud_color, saturate(orig_view_vector.z / 0.05)); + inscattered_light *= 0.5 + 1 * cloud_color; + #endif + + // Sun disk + vec3 silhouette_col = vec3(TimeOfDay.scattering.sun_intensity) * + inscattered_light * sky_clip; + silhouette_col *= 2.0; + float disk_factor = pow(saturate(dot(orig_view_vector, sun_vector) + 0.000069), 23.0 * 1e5); + float upper_disk_factor = smoothstep(0, 1, (orig_view_vector.z + 0.045) * 1.0); + inscattered_light += vec3(1, 0.3, 0.1) * disk_factor * upper_disk_factor * + silhouette_col * 3.0 * 1e3; + + } else { + inscattered_light *= 70.0; + float dist = distance(m.position, MainSceneData.camera_pos); + float extinction = saturate(dist / TimeOfDay.scattering.extinction * 10.0); + inscattered_light *= extinction; + } + + #if !DEBUG_MODE + result.xyz += inscattered_light; + #endif + + #if MODE_ACTIVE(SCATTERING) + result.xyz = inscattered_light / (1 + inscattered_light); + #endif + +} diff --git a/rpplugins/scattering/shader/compute_godrays.frag.glsl b/rpplugins/scattering/shader/compute_godrays.frag.glsl new file mode 100644 index 0000000..0cc58cf --- /dev/null +++ b/rpplugins/scattering/shader/compute_godrays.frag.glsl @@ -0,0 +1,80 @@ +/** + * + * RenderPipeline + * + * Copyright (c) 2014-2016 tobspr + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + */ + +#version 430 + +#define USE_TIME_OF_DAY 1 +#define USE_GBUFFER_EXTENSIONS +#pragma include "render_pipeline_base.inc.glsl" +#pragma include "includes/gbuffer.inc.glsl" +#pragma include "includes/color_spaces.inc.glsl" +#pragma include "includes/noise.inc.glsl" + +uniform sampler2D ShadedScene; +out vec3 result; + + +void main() { + vec2 texcoord = get_texcoord(); + Material m = unpack_material(GBuffer); + + // compute sun position on screen + // TODO: could move to vertex shader + vec3 sun_vector = get_sun_vector(); + vec3 sun_pos = sun_vector * 1e5; + vec4 sun_proj = MainSceneData.view_proj_mat_no_jitter * vec4(sun_pos, 1); + sun_proj.xyz /= sun_proj.w; + if (sun_proj.w < 0.0) { + result = textureLod(ShadedScene, texcoord, 0).xyz; + return; + } + sun_proj.xy = sun_proj.xy * 0.5 + 0.5; + + // raymarch to sun and collect .. whatever + float jitter = rand(texcoord) * 0.9; + + const int num_samples = 32; + vec3 accum = vec3(0); + for (int i = 0; i < num_samples; ++i) { + float t = (i + jitter) / float(num_samples - 1); + + vec2 sample_coord = mix(texcoord, sun_proj.xy, pow(t, 1.0)); + vec3 sample_data = textureLod(ShadedScene, sample_coord, 0).xyz; + + // float weight = step(get_luminance(sample_data), 1.0); + float weight = step(1.0, get_luminance(sample_data)); + // float weight = 1.0; + accum += sample_data * weight * saturate(5 * (1 - t)) * 1; + // accum += sample_data * weight; + } + + accum /= num_samples; + accum *= 0.001; + + accum += textureLod(ShadedScene, texcoord, 0).xyz; + result = vec3(accum); + +} diff --git a/rpplugins/scattering/shader/eric_bruneton/add_delta_e.compute.glsl b/rpplugins/scattering/shader/eric_bruneton/add_delta_e.compute.glsl new file mode 100644 index 0000000..7b5229d --- /dev/null +++ b/rpplugins/scattering/shader/eric_bruneton/add_delta_e.compute.glsl @@ -0,0 +1,46 @@ +/** + * + * RenderPipeline + * + * Copyright (c) 2014-2016 tobspr + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + */ + +#version 430 + +#pragma include "scattering_common.glsl" + +layout(local_size_x = 16, local_size_y = 16) in; + +uniform sampler2D deltaESampler; + +#if SCATTERING_USE_32_BIT +layout(rgba32f) uniform image2D RESTRICT dest; +#else +layout(rgba16f) uniform image2D RESTRICT dest; +#endif + +void main() { + ivec2 coord = ivec2(gl_GlobalInvocationID.xy); + vec3 delta_e_val = texelFetch(deltaESampler, coord, 0).xyz; + vec4 irradiance_val = imageLoad(dest, coord); + imageStore(dest, coord, vec4(delta_e_val + irradiance_val.xyz, irradiance_val.w)); +} diff --git a/rpplugins/scattering/shader/eric_bruneton/add_delta_sr.compute.glsl b/rpplugins/scattering/shader/eric_bruneton/add_delta_sr.compute.glsl new file mode 100644 index 0000000..2d95e28 --- /dev/null +++ b/rpplugins/scattering/shader/eric_bruneton/add_delta_sr.compute.glsl @@ -0,0 +1,56 @@ +/** + * + * RenderPipeline + * + * Copyright (c) 2014-2016 tobspr + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + */ + +#version 430 + +#pragma include "scattering_common.glsl" + +layout(local_size_x = 8, local_size_y = 8, local_size_z = 8) in; + +uniform sampler3D deltaSSampler; + +#if SCATTERING_USE_32_BIT +layout(rgba32f) uniform image3D RESTRICT dest; +#else +layout(rgba16f) uniform image3D RESTRICT dest; +#endif + +void main() { + + ivec3 coord = ivec3(gl_GlobalInvocationID.xyz); + + float r; + vec4 dhdH; + get_r_dhdh(coord.z, r, dhdH); + + float mu, muS, nu; + getMuMuSNu(r, dhdH, mu, muS, nu); + + vec4 orig_val = imageLoad(dest, coord); + vec4 new_val = texelFetch(deltaSSampler, coord, 0) / phaseFunctionR(nu); + imageStore(dest, coord, vec4(orig_val + new_val)); + +} diff --git a/rpplugins/scattering/shader/eric_bruneton/compute_scattering.inc.glsl b/rpplugins/scattering/shader/eric_bruneton/compute_scattering.inc.glsl new file mode 100644 index 0000000..ba182c0 --- /dev/null +++ b/rpplugins/scattering/shader/eric_bruneton/compute_scattering.inc.glsl @@ -0,0 +1,237 @@ +/** + * + * RenderPipeline + * + * Copyright (c) 2014-2016 tobspr + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + */ + + + +// Include local scattering code +#define NO_COMPUTE_SHADER 1 +#pragma include "scattering_common.glsl" +#pragma include "includes/gbuffer.inc.glsl" + +uniform sampler3D InscatterSampler; +uniform sampler2D IrradianceSampler; + +vec3 sun_vector = get_sun_vector(); +/* + + +Some parts of this code are taken from the master thesis of Stefan Sperlhofer, +which unfortunately does not seem to be online anymore, so I can't link to it. + + +*/ + +const float EPSILON_ATMOSPHERE = 0.002f; +const float EPSILON_INSCATTER = 0.01f; + + +// input - d: view ray in world space +// output - offset: distance to atmosphere or 0 if within atmosphere +// output - max_path_length: distance traversed within atmosphere +// output - return value: intersection occurred true/false +bool intersect_atmosphere(vec3 cam_pos, vec3 d, out float offset, out float max_path_length) +{ + offset = 0.0f; + max_path_length = 0.0f; + + // vector from ray origin to center of the sphere + vec3 l = -cam_pos; + float l2 = dot(l, l); + float s = dot(l, d); + + // adjust top atmosphere boundary by small epsilon to prevent artifacts + float r = Rt - EPSILON_ATMOSPHERE; + float r2 = r * r; + if(l2 <= r2) + { + // ray origin inside sphere, hit is ensured + float m2 = l2 - (s * s); + float q = sqrt(r2 - m2); + max_path_length = s + q; + return true; + } + else if(s >= 0) + { + // ray starts outside in front of sphere, hit is possible + float m2 = l2 - (s * s); + if(m2 <= r2) + { + // ray hits atmosphere definitely + float q = sqrt(r2 - m2); + offset = s - q; + max_path_length = (s + q) - offset; + return true; + } + } + return false; +} + + +// Transforms a point from world-space to atmospheric-space. +// This is required because we use different coordinate systems for normal +// rendering and atmospheric scattering. +vec3 worldspace_to_atmosphere(vec3 pos) { + pos.z += GET_SETTING(scattering, atmosphere_start); + pos /= 1000.0; + pos.z = max(0, pos.z); + pos.z += Rg; + return pos; +} + +vec3 get_inscattered_light(vec3 surface_pos, vec3 view_dir, inout vec3 attenuation, + inout float irradiance_factor) +{ + vec3 inscattered_light = vec3(0); + float offset; + float max_path_length; + + vec3 cam_pos = MainSceneData.camera_pos; + // cam_pos.z = max(cam_pos.z, surface_pos.z); + cam_pos = worldspace_to_atmosphere(cam_pos); + + if (is_skybox(surface_pos)) { + surface_pos = worldspace_to_atmosphere(surface_pos * 1e10); + } else { + surface_pos = worldspace_to_atmosphere(surface_pos); + } + + if (intersect_atmosphere(cam_pos, view_dir, offset, max_path_length)) { + float path_length = distance(cam_pos, surface_pos); + + // check if object occludes atmosphere + if (path_length > offset) { + + // offsetting camera + vec3 start_pos = cam_pos + offset * view_dir; + float start_pos_height = length(start_pos); + path_length -= offset; + + // starting position of path is now ensured to be inside atmosphere + // was either originally there or has been moved to top boundary + float mustart_pos = dot(start_pos, view_dir) / start_pos_height; + float nustart_pos = dot(view_dir, sun_vector); + float musstart_pos = dot(start_pos, sun_vector) / start_pos_height; + + // in-scattering for infinite ray (light in-scattered when + // no surface hit or object behind atmosphere) + vec4 inscatter = max(texture4D(InscatterSampler, start_pos_height, + mustart_pos, musstart_pos, nustart_pos), 0.0f); + float surface_pos_height = length(surface_pos); + float musEndPos = dot(surface_pos, sun_vector) / surface_pos_height; + + // check if object hit is inside atmosphere + if (path_length < max_path_length) { + + // reduce total in-scattered light when surface hit + // within atmosphere + // fíx described in chapter 5.1.1 + attenuation = analyticTransmittance(start_pos_height, mustart_pos, path_length); + float muEndPos = dot(surface_pos, view_dir) / surface_pos_height; + vec4 inscatterSurface = texture4D(InscatterSampler, surface_pos_height, + muEndPos, musEndPos, nustart_pos); + inscatter = max(inscatter - attenuation.rgbr * inscatterSurface, 0.0f); + irradiance_factor = 1.0f; + } else { + // retrieve extinction factor for infinite ray + // fíx described in chapter 5.1.1 + attenuation = analyticTransmittance(start_pos_height, mustart_pos, path_length); + } + + // avoids imprecision problems near horizon by interpolating between + // two points above and below horizon + // fíx described in chapter 5.1.2 + + #if 0 + float muHorizon = -sqrt(1.0 - (Rg / start_pos_height) * (Rg / start_pos_height)); + if (abs(mustart_pos - muHorizon) < EPSILON_INSCATTER) + { + float mu = muHorizon - EPSILON_INSCATTER; + float samplePosHeight = sqrt(start_pos_height * start_pos_height + + path_length * path_length + 2.0f * start_pos_height * + path_length * mu); + float muSamplePos = (start_pos_height * mu + path_length) / samplePosHeight; + vec4 inScatter0 = texture4D(InscatterSampler, start_pos_height, mu, + musstart_pos, nustart_pos); + vec4 inScatter1 = texture4D(InscatterSampler, samplePosHeight, + muSamplePos, musEndPos, nustart_pos); + vec4 inScatterA = max(inScatter0 - attenuation.rgbr * inScatter1, 0.0); + mu = muHorizon + EPSILON_INSCATTER; + samplePosHeight = sqrt(start_pos_height * start_pos_height + + path_length * path_length + 2.0f * + start_pos_height * path_length * mu); + muSamplePos = (start_pos_height * mu + path_length) / samplePosHeight; + inScatter0 = texture4D(InscatterSampler, start_pos_height, mu, + musstart_pos, nustart_pos); + inScatter1 = texture4D(InscatterSampler, samplePosHeight, muSamplePos, + musEndPos, nustart_pos); + vec4 inScatterB = max(inScatter0 - attenuation.rgbr * inScatter1, + 0.0f); + float t = ((mustart_pos - muHorizon) + EPSILON_INSCATTER) / + (2.0 * EPSILON_INSCATTER); + inscatter = mix(inScatterA, inScatterB, t); + } + #endif + + // avoids imprecision problems in Mie scattering when sun is below + //horizon + // fíx described in chapter 5.1.3 + inscatter.w *= smoothstep(0.00, 0.02, musstart_pos); + float phaseR = phaseFunctionR(nustart_pos); + float phaseM = phaseFunctionM(nustart_pos); + + phaseR *= GET_SETTING(scattering, rayleigh_factor); + + inscattered_light = max(inscatter.rgb * phaseR + getMie(inscatter) * phaseM, 0.0f); + + } + } + + + + #if !HAVE_PLUGIN(color_correction) + // Reduce scattering, otherwise its way too bright without automatic + // exposure + // inscattered_light /= 7.0; + #endif + + return inscattered_light; +} + + + +vec3 DoScattering(vec3 surface_pos, vec3 view_dir, out float sky_clip) +{ + vec3 attenuation = vec3(0); + float irradiance_factor = 0.0; + vec3 scattering = get_inscattered_light(surface_pos, view_dir, attenuation, irradiance_factor); + + sky_clip = is_skybox(surface_pos) ? 1.0 : 0.0; + + // Reduce scattering in the near to avoid artifacts due to low precision + scattering *= saturate(distance(surface_pos, MainSceneData.camera_pos) / 500.0 - 0.0); + + return scattering; +} diff --git a/rpplugins/scattering/shader/eric_bruneton/copy_inscatter.compute.glsl b/rpplugins/scattering/shader/eric_bruneton/copy_inscatter.compute.glsl new file mode 100644 index 0000000..4672bbd --- /dev/null +++ b/rpplugins/scattering/shader/eric_bruneton/copy_inscatter.compute.glsl @@ -0,0 +1,44 @@ +/** + * + * RenderPipeline + * + * Copyright (c) 2014-2016 tobspr + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + */ + +#version 430 + +#pragma include "scattering_common.glsl" + +layout(local_size_x = 8, local_size_y = 8, local_size_z = 8) in; + +uniform sampler3D deltaSRSampler; +uniform sampler3D deltaSMSampler; +uniform writeonly image3D RESTRICT dest; + +void main() { + ivec2 coord = ivec2(gl_GlobalInvocationID.xy); + int layer = int(gl_GlobalInvocationID.z); + + vec3 ray = texelFetch(deltaSRSampler, ivec3(coord, layer), 0).xyz; + vec3 mie = texelFetch(deltaSMSampler, ivec3(coord, layer), 0).xyz; + imageStore(dest, ivec3(coord, layer), vec4(ray.xyz, mie.x)); +} diff --git a/rpplugins/scattering/shader/eric_bruneton/copy_irradiance.compute.glsl b/rpplugins/scattering/shader/eric_bruneton/copy_irradiance.compute.glsl new file mode 100644 index 0000000..89a8b5c --- /dev/null +++ b/rpplugins/scattering/shader/eric_bruneton/copy_irradiance.compute.glsl @@ -0,0 +1,42 @@ +/** + * + * RenderPipeline + * + * Copyright (c) 2014-2016 tobspr + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + */ + +#version 430 + +#pragma include "scattering_common.glsl" + +layout(local_size_x = 16, local_size_y = 16) in; + +uniform float k; +uniform sampler2D deltaESampler; + +uniform writeonly image2D RESTRICT dest; + +void main() { + ivec2 coord = ivec2(gl_GlobalInvocationID.xy); + vec4 delta_e_val = texelFetch(deltaESampler, coord, 0); + imageStore(dest, coord, vec4(k * delta_e_val)); +} diff --git a/rpplugins/scattering/shader/eric_bruneton/delta_e.compute.glsl b/rpplugins/scattering/shader/eric_bruneton/delta_e.compute.glsl new file mode 100644 index 0000000..967288a --- /dev/null +++ b/rpplugins/scattering/shader/eric_bruneton/delta_e.compute.glsl @@ -0,0 +1,39 @@ +/** + * + * RenderPipeline + * + * Copyright (c) 2014-2016 tobspr + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + */ + +#version 430 + +#pragma include "scattering_common.glsl" + +layout(local_size_x = 16, local_size_y = 16) in; +uniform writeonly image2D RESTRICT dest; + +void main() { + ivec2 coord = ivec2(gl_GlobalInvocationID.xy); + float r, muS; + getIrradianceRMuS(r, muS); + imageStore(dest, coord, vec4(transmittance(r, muS) * max(muS, 0.0), SCAT_DEBUG_ALPHA)); +} diff --git a/rpplugins/scattering/shader/eric_bruneton/delta_j.compute.glsl b/rpplugins/scattering/shader/eric_bruneton/delta_j.compute.glsl new file mode 100644 index 0000000..5fb6d1e --- /dev/null +++ b/rpplugins/scattering/shader/eric_bruneton/delta_j.compute.glsl @@ -0,0 +1,130 @@ +/** + * + * RenderPipeline + * + * Copyright (c) 2014-2016 tobspr + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + */ + +#version 430 + +#pragma include "scattering_common.glsl" + +layout(local_size_x = 8, local_size_y = 8, local_size_z = 8) in; + +uniform sampler2D deltaESampler; +uniform sampler3D deltaSRSampler; +uniform sampler3D deltaSMSampler; +uniform bool first; + +uniform writeonly image3D RESTRICT dest; + +const float dphi = M_PI / float(INSCATTER_SPHERICAL_INTEGRAL_SAMPLES); +const float dtheta = M_PI / float(INSCATTER_SPHERICAL_INTEGRAL_SAMPLES); + +void inscatter(float r, float mu, float muS, float nu, out vec3 raymie) { + r = clamp(r, Rg, Rt); + mu = clamp(mu, -1.0, 1.0); + muS = clamp(muS, -1.0, 1.0); + float var = sqrt(1.0 - mu * mu) * sqrt(1.0 - muS * muS); + nu = clamp(nu, muS * mu - var, muS * mu + var); + + float cthetamin = -sqrt(1.0 - (Rg / r) * (Rg / r)); + + vec3 v = vec3(sqrt(1.0 - mu * mu), 0.0, mu); + float sx = v.x == 0.0 ? 0.0 : (nu - muS * mu) / v.x; + vec3 s = vec3(sx, sqrt(max(0.0, 1.0 - sx * sx - muS * muS)), muS); + + raymie = vec3(0.0); + + // integral over 4.PI around x with two nested loops over w directions (theta,phi) -- Eq (7) + for (int itheta = 0; itheta < INSCATTER_SPHERICAL_INTEGRAL_SAMPLES; ++itheta) { + float theta = (float(itheta) + 0.5) * dtheta; + float ctheta = cos(theta); + + float greflectance = 0.0; + float dground = 0.0; + vec3 gtransp = vec3(0.0); + if (ctheta < cthetamin) { // if ground visible in direction w + // compute transparency gtransp between x and ground + greflectance = AVERAGE_GROUND_REFLECTANCE / M_PI; + dground = -r * ctheta - sqrt(r * r * (ctheta * ctheta - 1.0) + Rg * Rg); + gtransp = transmittance(Rg, -(r * ctheta + dground) / Rg, dground); + } + + for (int iphi = 0; iphi < 2 * INSCATTER_SPHERICAL_INTEGRAL_SAMPLES; ++iphi) { + float phi = (float(iphi) + 0.5) * dphi; + float dw = dtheta * dphi * sin(theta); + vec3 w = vec3(cos(phi) * sin(theta), sin(phi) * sin(theta), ctheta); + + float nu1 = dot(s, w); + float nu2 = dot(v, w); + float pr2 = phaseFunctionR(nu2); + float pm2 = phaseFunctionM(nu2); + + // compute irradiance received at ground in direction w (if ground visible) =deltaE + vec3 gnormal = (vec3(0.0, 0.0, r) + dground * w) / Rg; + vec3 girradiance = irradiance(deltaESampler, Rg, dot(gnormal, s)); + + vec3 raymie1; // light arriving at x from direction w + + // first term = light reflected from the ground and attenuated before reaching x, =T.alpha/PI.deltaE + raymie1 = greflectance * girradiance * gtransp; + + // second term = inscattered light, =deltaS + if (first) { + // first iteration is special because Rayleigh and Mie were stored separately, + // without the phase functions factors; they must be reintroduced here + float pr1 = phaseFunctionR(nu1); + float pm1 = phaseFunctionM(nu1); + vec3 ray1 = texture4D(deltaSRSampler, r, w.z, muS, nu1).rgb; + vec3 mie1 = texture4D(deltaSMSampler, r, w.z, muS, nu1).rgb; + raymie1 += ray1 * pr1 + mie1 * pm1; + } else { + raymie1 += texture4D(deltaSRSampler, r, w.z, muS, nu1).rgb; + } + + // light coming from direction w and scattered in direction v + // = light arriving at x from direction w (raymie1) * SUM(scattering coefficient * phaseFunction) + // see Eq (7) + raymie += raymie1 * (betaR * exp(-(r - Rg) / HR) * pr2 + betaMSca * + exp(-(r - Rg) / HM) * pm2) * dw; + } + } + + // output raymie = J[T.alpha/PI.deltaE + deltaS] (line 7 in algorithm 4.1) +} + +void main() { + ivec2 coord = ivec2(gl_GlobalInvocationID.xy); + int layer = int(gl_GlobalInvocationID.z); + + float r; + vec4 dhdH; + get_r_dhdh(layer, r, dhdH); + + vec3 raymie; + float mu, muS, nu; + getMuMuSNu(r, dhdH, mu, muS, nu); + inscatter(r, mu, muS, nu, raymie); + + imageStore(dest, ivec3(coord, layer), vec4(raymie, SCAT_DEBUG_ALPHA)); +} diff --git a/rpplugins/scattering/shader/eric_bruneton/delta_sm_sr.compute.glsl b/rpplugins/scattering/shader/eric_bruneton/delta_sm_sr.compute.glsl new file mode 100644 index 0000000..84da095 --- /dev/null +++ b/rpplugins/scattering/shader/eric_bruneton/delta_sm_sr.compute.glsl @@ -0,0 +1,93 @@ +/** + * + * RenderPipeline + * + * Copyright (c) 2014-2016 tobspr + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + */ + +#version 430 + +#pragma include "scattering_common.glsl" + +layout(local_size_x = 8, local_size_y = 8, local_size_z = 8) in; + +uniform writeonly image3D RESTRICT destDeltaSR; +uniform writeonly image3D RESTRICT destDeltaSM; + +void integrand(float r, float mu, float muS, float nu, float t, out vec3 ray, out vec3 mie) { + ray = vec3(0.0); + mie = vec3(0.0); + float ri = sqrt(r * r + t * t + 2.0 * r * mu * t); + float muSi = (nu * t + muS * r) / ri; + ri = max(Rg, ri); + if (muSi >= -sqrt(1.0 - Rg * Rg / (ri * ri))) { + vec3 ti = transmittance(r, mu, t) * transmittance(ri, muSi); + ray = exp(-(ri - Rg) / HR) * ti; + mie = exp(-(ri - Rg) / HM) * ti; + } +} + + +void inscatter(float r, float mu, float muS, float nu, out vec3 ray, out vec3 mie) { + ray = vec3(0.0); + mie = vec3(0.0); + float dx = limit(r, mu) / float(INSCATTER_INTEGRAL_SAMPLES); + float xi = 0.0; + vec3 rayi; + vec3 miei; + integrand(r, mu, muS, nu, 0.0, rayi, miei); + for (int i = 1; i <= INSCATTER_INTEGRAL_SAMPLES; ++i) { + float xj = float(i) * dx; + vec3 rayj; + vec3 miej; + integrand(r, mu, muS, nu, xj, rayj, miej); + ray += (rayi + rayj) / 2.0 * dx; + mie += (miei + miej) / 2.0 * dx; + xi = xj; + rayi = rayj; + miei = miej; + } + ray *= betaR; + mie *= betaMSca; +} + + +void main() { + ivec2 coord = ivec2(gl_GlobalInvocationID.xy); + int layer = int(gl_GlobalInvocationID.z); + + float r; + vec4 dhdH; + get_r_dhdh(layer, r, dhdH); + + vec3 ray; + vec3 mie; + float mu, muS, nu; + getMuMuSNu(r, dhdH, mu, muS, nu); + inscatter(r, mu, muS, nu, ray, mie); + // store separately Rayleigh and Mie contributions, WITHOUT the phase function factor + // (cf "Angular precision") + + imageStore(destDeltaSR, ivec3(coord, layer), vec4(ray, SCAT_DEBUG_ALPHA)); + imageStore(destDeltaSM, ivec3(coord, layer), vec4(mie, SCAT_DEBUG_ALPHA)); + +} diff --git a/rpplugins/scattering/shader/eric_bruneton/delta_sr.compute.glsl b/rpplugins/scattering/shader/eric_bruneton/delta_sr.compute.glsl new file mode 100644 index 0000000..dcd21db --- /dev/null +++ b/rpplugins/scattering/shader/eric_bruneton/delta_sr.compute.glsl @@ -0,0 +1,70 @@ +/** + * + * RenderPipeline + * + * Copyright (c) 2014-2016 tobspr + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + */ + +#version 430 + +#pragma include "scattering_common.glsl" + +layout(local_size_x = 8, local_size_y = 8, local_size_z = 8) in; + +uniform sampler3D deltaJSampler; +uniform writeonly image3D RESTRICT dest; + +vec3 integrand(float r, float mu, float muS, float nu, float t) { + float ri = sqrt(r * r + t * t + 2.0 * r * mu * t); + float mui = (r * mu + t) / ri; + float muSi = (nu * t + muS * r) / ri; + return texture4D(deltaJSampler, ri, mui, muSi, nu).rgb * transmittance(r, mu, t); +} + +vec3 inscatter(float r, float mu, float muS, float nu) { + vec3 raymie = vec3(0.0); + float dx = limit(r, mu) / float(INSCATTER_INTEGRAL_SAMPLES); + float xi = 0.0; + vec3 raymiei = integrand(r, mu, muS, nu, 0.0); + for (int i = 1; i <= INSCATTER_INTEGRAL_SAMPLES; ++i) { + float xj = float(i) * dx; + vec3 raymiej = integrand(r, mu, muS, nu, xj); + raymie += (raymiei + raymiej) / 2.0 * dx; + xi = xj; + raymiei = raymiej; + } + return raymie; +} + +void main() { + ivec2 coord = ivec2(gl_GlobalInvocationID.xy); + int layer = int(gl_GlobalInvocationID.z); + + float r; + vec4 dhdH; + get_r_dhdh(layer, r, dhdH); + + float mu, muS, nu; + getMuMuSNu(r, dhdH, mu, muS, nu); + vec3 result = inscatter(r, mu, muS, nu); + imageStore(dest, ivec3(coord, layer), vec4(result, SCAT_DEBUG_ALPHA)); +} diff --git a/rpplugins/scattering/shader/eric_bruneton/irradiance_n.compute.glsl b/rpplugins/scattering/shader/eric_bruneton/irradiance_n.compute.glsl new file mode 100644 index 0000000..db4f56b --- /dev/null +++ b/rpplugins/scattering/shader/eric_bruneton/irradiance_n.compute.glsl @@ -0,0 +1,72 @@ +/** + * + * RenderPipeline + * + * Copyright (c) 2014-2016 tobspr + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + */ + +#version 430 + +#pragma include "scattering_common.glsl" + +layout(local_size_x = 16, local_size_y = 16) in; + +uniform sampler3D deltaSRSampler; +uniform sampler3D deltaSMSampler; +uniform bool first; + +uniform writeonly image2D RESTRICT dest; + +const float dphi = M_PI / float(IRRADIANCE_INTEGRAL_SAMPLES); +const float dtheta = M_PI / float(IRRADIANCE_INTEGRAL_SAMPLES); + +void main() { + ivec2 coord = ivec2(gl_GlobalInvocationID.xy); + + float r, muS; + getIrradianceRMuS(r, muS); + vec3 s = vec3(max(sqrt(1.0 - muS * muS), 0.0), 0.0, muS); + + vec3 result = vec3(0.0); + // integral over 2.PI around x with two nested loops over w directions (theta,phi) -- Eq (15) + for (int iphi = 0; iphi < 2 * IRRADIANCE_INTEGRAL_SAMPLES; ++iphi) { + float phi = (float(iphi) + 0.5) * dphi; + for (int itheta = 0; itheta < IRRADIANCE_INTEGRAL_SAMPLES / 2; ++itheta) { + float theta = (float(itheta) + 0.5) * dtheta; + float dw = dtheta * dphi * sin(theta); + vec3 w = vec3(cos(phi) * sin(theta), sin(phi) * sin(theta), cos(theta)); + float nu = dot(s, w); + if (first) { + // first iteration is special because Rayleigh and Mie were stored separately, + // without the phase functions factors; they must be reintroduced here + float pr1 = phaseFunctionR(nu); + float pm1 = phaseFunctionM(nu); + vec3 ray1 = texture4D(deltaSRSampler, r, w.z, muS, nu).rgb; + vec3 mie1 = texture4D(deltaSMSampler, r, w.z, muS, nu).rgb; + result += (ray1 * pr1 + mie1 * pm1) * w.z * dw; + } else { + result += texture4D(deltaSRSampler, r, w.z, muS, nu).rgb * w.z * dw; + } + } + } + imageStore(dest, coord, vec4(result, SCAT_DEBUG_ALPHA)); +} diff --git a/rpplugins/scattering/shader/eric_bruneton/scattering_common.glsl b/rpplugins/scattering/shader/eric_bruneton/scattering_common.glsl new file mode 100644 index 0000000..01de7b2 --- /dev/null +++ b/rpplugins/scattering/shader/eric_bruneton/scattering_common.glsl @@ -0,0 +1,343 @@ +#pragma once + +#extension GL_ARB_shading_language_420pack : enable + +// This file includes defines and functions used for the scattering + + +// #define SCATTERING_USE_32_BIT 1 + +#pragma include "render_pipeline_base.inc.glsl" + + +// These can be overridden depending on if the shader is a compute shader +// or a regular fragment shader +#ifndef NO_COMPUTE_SHADER +#define PIXEL_X gl_GlobalInvocationID.x +#define PIXEL_Y gl_GlobalInvocationID.y +#else +#define PIXEL_X gl_FragCoord.x +#define PIXEL_Y gl_FragCoord.x +#endif + + +// This define can be set to 1.0 when writing out the scattering textures, so +// the alpha channel is not 0.0 and the texture cannot get displayed +#define SCAT_DEBUG_ALPHA 0.0 + + +// Actual include: + +/** + * Precomputed Atmospheric Scattering + * Copyright (c) 2008 INRIA + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the copyright holders nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF + * THE POSSIBILITY OF SUCH DAMAGE. + + * Author: Eric Bruneton + */ + +// Constants +const float Rg = 6360.0; +const float Rt = 6420.0; +const float RL = 6421.0; +const int TRANSMITTANCE_W = 256 * 4; +const int TRANSMITTANCE_H = 64 * 4; +const int SKY_W = 64 * 4; +const int SKY_H = 16 * 4; + +const int RES_R = 32; +const int RES_MU = 128; +const int RES_MU_S = 32; +const int RES_NU = 8; + + + +// ---------------------------------------------------------------------------- +// PHYSICAL MODEL PARAMETERS +// ---------------------------------------------------------------------------- + +const float AVERAGE_GROUND_REFLECTANCE = GET_SETTING(scattering, ground_reflectance); + +// Rayleigh +const float HR = GET_SETTING(scattering, rayleigh_height_scale); +const vec3 betaR = vec3(5.8e-3, 1.35e-2, 3.31e-2); + +// Mie + +const float HM = GET_SETTING(scattering, mie_height_scale); +const vec3 betaMSca = vec3(GET_SETTING(scattering, beta_mie_scattering) * 1e-3); +const float mieG = GET_SETTING(scattering, mie_phase_factor); +// CLEAR SKY +// const float HM = 1.2; +// const vec3 betaMSca = vec3(20e-3); +// const float mieG = 0.76; +// PARTLY CLOUDY +/*const float HM = 3.0; +const vec3 betaMSca = vec3(3e-3); +const float mieG = 0.65;*/ + +// Beta Mie Extinction +const vec3 betaMEx = betaMSca / 0.9; + +// ---------------------------------------------------------------------------- +// NUMERICAL INTEGRATION PARAMETERS +// ---------------------------------------------------------------------------- + +const int TRANSMITTANCE_INTEGRAL_SAMPLES = 500; +const int INSCATTER_INTEGRAL_SAMPLES = 50; +const int IRRADIANCE_INTEGRAL_SAMPLES = 32; + +// Needs to be a low value, leads to driver crashes otherwise +const int INSCATTER_SPHERICAL_INTEGRAL_SAMPLES = 8; + +// ---------------------------------------------------------------------------- +// PARAMETERIZATION OPTIONS +// ---------------------------------------------------------------------------- + +#define TRANSMITTANCE_NON_LINEAR +#define INSCATTER_NON_LINEAR + +// ---------------------------------------------------------------------------- +// PARAMETERIZATION FUNCTIONS +// ---------------------------------------------------------------------------- + +uniform sampler2D transmittanceSampler; + + +void get_r_dhdh(int layer, out float r, out vec4 dhdh) { + r = float(layer) / float(RES_R - 1.0); + r = r * r; + r = sqrt(Rg * Rg + r * (Rt * Rt - Rg * Rg)) + + (layer == 0 ? 0.01 : (layer == RES_R - 1 ? -0.001 : 0.0)); + float dmin = Rt - r; + float dmax = sqrt(r * r - Rg * Rg) + sqrt(Rt * Rt - Rg * Rg); + float dminp = r - Rg; + float dmaxp = sqrt(r * r - Rg * Rg); + dhdh = vec4(dmin, dmax, dminp, dmaxp); +} + + + + +vec2 getTransmittanceUV(float r, float mu) { + float uR, uMu; +#ifdef TRANSMITTANCE_NON_LINEAR + uR = sqrt((r - Rg) / (Rt - Rg)); + uMu = atan((mu + 0.15) / (1.0 + 0.15) * tan(1.5)) / 1.5; +#else + uR = (r - Rg) / (Rt - Rg); + uMu = (mu + 0.15) / (1.0 + 0.15); +#endif + return vec2(uMu, uR); +} + +void getTransmittanceRMu(out float r, out float muS) { + r = PIXEL_Y / float(TRANSMITTANCE_H); + muS = PIXEL_X / float(TRANSMITTANCE_W); +#ifdef TRANSMITTANCE_NON_LINEAR + r = Rg + (r * r) * (Rt - Rg); + muS = -0.15 + tan(1.5 * muS) / tan(1.5) * (1.0 + 0.15); +#else + r = Rg + r * (Rt - Rg); + muS = -0.15 + muS * (1.0 + 0.15); +#endif +} + +vec2 getIrradianceUV(float r, float muS) { + float uR = (r - Rg) / (Rt - Rg); + float uMuS = (muS + 0.2) / (1.0 + 0.2); + return vec2(uMuS, uR); +} + +void getIrradianceRMuS(out float r, out float muS) { + // POSSIBLE PROBLEMS int(coord) does not match gl_FragCoord ? + r = Rg + int(PIXEL_Y) / (float(SKY_H) - 1.0) * (Rt - Rg); + muS = -0.2 + int(PIXEL_X) / (float(SKY_W) - 1.0) * (1.0 + 0.2); +} + +vec4 texture4D(sampler3D table, float r, float mu, float muS, float nu) +{ + float Rg_sq = Rg * Rg; + float H = sqrt(Rt * Rt - Rg_sq); + float rho = sqrt(r * r - Rg_sq); +#ifdef INSCATTER_NON_LINEAR + float rmu = r * mu; + float delta = rmu * rmu - r * r + Rg_sq; + vec4 cst = rmu < 0.0 && delta > 0.0 ? + vec4(1.0, 0.0, 0.0, 0.5 - 0.5 / float(RES_MU)) : + vec4(-1.0, H * H, H, 0.5 + 0.5 / float(RES_MU)); + float uR = 0.5 / float(RES_R) + rho / H * (1.0 - 1.0 / float(RES_R)); + float uMu = cst.w + (rmu * cst.x + sqrt(delta + cst.y)) / (rho + cst.z) * + (0.5 - 1.0 / float(RES_MU)); + // paper formula + // float uMuS = 0.5 / float(RES_MU_S) + max((1.0 - exp(-3.0 * muS - 0.6)) / (1.0 - exp(-3.6)), 0.0) * (1.0 - 1.0 / float(RES_MU_S)); + // better formula + float uMuS = 0.5 / float(RES_MU_S) + (atan(max(muS, -0.1975) * tan(1.26 * 1.1)) / 1.1 + + (1.0 - 0.26)) * 0.5 * (1.0 - 1.0 / float(RES_MU_S)); +#else + float uR = 0.5 / float(RES_R) + rho / H * (1.0 - 1.0 / float(RES_R)); + float uMu = 0.5 / float(RES_MU) + (mu + 1.0) / 2.0 * (1.0 - 1.0 / float(RES_MU)); + float uMuS = 0.5 / float(RES_MU_S) + max(muS + 0.2, 0.0) / 1.2 * (1.0 - 1.0 / float(RES_MU_S)); +#endif + float lerp = (nu + 1.0) / 2.0 * (float(RES_NU) - 1.0); + float uNu = floor(lerp); + lerp = lerp - uNu; + return textureLod(table, vec3((uNu + uMuS) / float(RES_NU), uMu, uR), 0) * (1.0 - lerp) + + textureLod(table, vec3((uNu + uMuS + 1.0) / float(RES_NU), uMu, uR), 0) * lerp; +} + +void getMuMuSNu(float r, vec4 dhdH, out float mu, out float muS, out float nu) { + float x = int(PIXEL_X); + float y = int(PIXEL_Y); +#ifdef INSCATTER_NON_LINEAR + if (y < float(RES_MU) / 2.0) { + float d = 1.0 - y / (float(RES_MU) / 2.0 - 1.0); + d = min(max(dhdH.z, d * dhdH.w), dhdH.w * 0.999); + mu = (Rg * Rg - r * r - d * d) / (2.0 * r * d); + mu = min(mu, -sqrt(1.0 - (Rg / r) * (Rg / r)) - 0.001); + } else { + float d = (y - float(RES_MU) / 2.0) / (float(RES_MU) / 2.0 - 1.0); + d = min(max(dhdH.x, d * dhdH.y), dhdH.y * 0.999); + mu = (Rt * Rt - r * r - d * d) / (2.0 * r * d); + } + muS = mod(x, float(RES_MU_S)) / (float(RES_MU_S) - 1.0); + // paper formula + //muS = -(0.6 + log(1.0 - muS * (1.0 - exp(-3.6)))) / 3.0; + // better formula + muS = tan((2.0 * muS - 1.0 + 0.26) * 1.1) / tan(1.26 * 1.1); + nu = -1.0 + floor(x / float(RES_MU_S)) / (float(RES_NU) - 1.0) * 2.0; +#else + mu = -1.0 + 2.0 * y / (float(RES_MU) - 1.0); + muS = mod(x, float(RES_MU_S)) / (float(RES_MU_S) - 1.0); + muS = -0.2 + muS * 1.2; + nu = -1.0 + floor(x / float(RES_MU_S)) / (float(RES_NU) - 1.0) * 2.0; +#endif +} + +// ---------------------------------------------------------------------------- +// UTILITY FUNCTIONS +// ---------------------------------------------------------------------------- + +// nearest intersection of ray r,mu with ground or top atmosphere boundary +// mu=cos(ray zenith angle at ray origin) +float limit(float r, float mu) { + float dout = -r * mu + sqrt(r * r * (mu * mu - 1.0) + RL * RL); + float delta2 = r * r * (mu * mu - 1.0) + Rg * Rg; + if (delta2 >= 0.0) { + float din = -r * mu - sqrt(delta2); + if (din >= 0.0) { + dout = min(dout, din); + } + } + return dout; +} + +// transmittance(=transparency) of atmosphere for infinite ray (r,mu) +// (mu=cos(view zenith angle)), intersections with ground ignored +vec3 transmittance(float r, float mu) { + vec2 uv = getTransmittanceUV(r, mu); + return textureLod(transmittanceSampler, uv, 0).rgb; +} + +// transmittance(=transparency) of atmosphere for infinite ray (r,mu) +// (mu=cos(view zenith angle)), or zero if ray intersects ground +vec3 transmittanceWithShadow(float r, float mu) { + return mu < -sqrt(1.0 - (Rg / r) * (Rg / r)) ? vec3(0.0) : transmittance(r, mu); +} + +// transmittance(=transparency) of atmosphere between x and x0 +// assume segment x,x0 not intersecting ground +// r=||x||, mu=cos(zenith angle of [x,x0) ray at x), v=unit direction vector of [x,x0) ray +vec3 transmittance(float r, float mu, vec3 v, vec3 x0) { + vec3 result; + float r1 = length(x0); + float mu1 = dot(x0, v) / r; + if (mu > 0.0) { + result = min(transmittance(r, mu) / transmittance(r1, mu1), 1.0); + } else { + result = min(transmittance(r1, -mu1) / transmittance(r, -mu), 1.0); + } + return result; +} + +// optical depth for ray (r,mu) of length d, using analytic formula +// (mu=cos(view zenith angle)), intersections with ground ignored +// H=height scale of exponential density function +float opticalDepth(float H, float r, float mu, float d) { + float a = sqrt((0.5 / H) * r); + vec2 a01 = a * vec2(mu, mu + d / r); + vec2 a01s = sign(a01); + vec2 a01sq = a01 * a01; + float x = a01s.y > a01s.x ? exp(a01sq.x) : 0.0; + vec2 y = a01s / (2.3193 * abs(a01) + sqrt(1.52 * a01sq + 4.0)) * + vec2(1.0, exp(-d / H * (d / (2.0 * r) + mu))); + return sqrt((6.2831 * H) * r) * exp((Rg - r) / H) * (x + dot(y, vec2(1.0, -1.0))); +} + +// transmittance(=transparency) of atmosphere for ray (r,mu) of length d +// (mu=cos(view zenith angle)), intersections with ground ignored +// uses analytic formula instead of transmittance texture +vec3 analyticTransmittance(float r, float mu, float d) { + return exp(- betaR * opticalDepth(HR, r, mu, d) - betaMEx * opticalDepth(HM, r, mu, d)); +} + +// transmittance(=transparency) of atmosphere between x and x0 +// assume segment x,x0 not intersecting ground +// d = distance between x and x0, mu=cos(zenith angle of [x,x0) ray at x) +vec3 transmittance(float r, float mu, float d) { + vec3 result; + float r1 = sqrt(r * r + d * d + 2.0 * r * mu * d); + float mu1 = (r * mu + d) / r1; + if (mu > 0.0) { + result = min(transmittance(r, mu) / transmittance(r1, mu1), 1.0); + } else { + result = min(transmittance(r1, -mu1) / transmittance(r, -mu), 1.0); + } + return result; +} + +vec3 irradiance(sampler2D sampler, float r, float muS) { + vec2 uv = getIrradianceUV(r, muS); + return textureLod(sampler, uv, 0).rgb; +} + +// Rayleigh phase function +float phaseFunctionR(float mu) { + return (3.0 / (16.0 * M_PI)) * (1.0 + mu * mu); +} + +// Mie phase function +float phaseFunctionM(float mu) { + return 1.5 * 1.0 / (4.0 * M_PI) * (1.0 - mieG * mieG) * + pow(1.0 + (mieG * mieG) - 2.0 * mieG * mu, -3.0 / 2.0) * + (1.0 + mu * mu) / (2.0 + mieG * mieG); +} + +// approximated single Mie scattering (cf. approximate Cm in paragraph "Angular precision") +vec3 getMie(vec4 rayMie) { // rayMie.rgb=C*, rayMie.w=Cm,r + return rayMie.rgb * rayMie.w / max(rayMie.r, 1e-4) * (betaR.r / betaR); +} diff --git a/rpplugins/scattering/shader/eric_bruneton/transmittance.compute.glsl b/rpplugins/scattering/shader/eric_bruneton/transmittance.compute.glsl new file mode 100644 index 0000000..c5cf63d --- /dev/null +++ b/rpplugins/scattering/shader/eric_bruneton/transmittance.compute.glsl @@ -0,0 +1,58 @@ +/** + * + * RenderPipeline + * + * Copyright (c) 2014-2016 tobspr + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + */ + +#version 430 + +#pragma include "scattering_common.glsl" + + +layout(local_size_x = 16, local_size_y = 16) in; + +uniform writeonly image2D RESTRICT dest; + +float opticalDepth(float H, float r, float mu) { + float result = 0.0; + float dx = limit(r, mu) / float(TRANSMITTANCE_INTEGRAL_SAMPLES); + float xi = 0.0; + float yi = exp(-(r - Rg) / H); + for (int i = 1; i <= TRANSMITTANCE_INTEGRAL_SAMPLES; ++i) { + float xj = float(i) * dx; + float yj = exp(-(sqrt(r * r + xj * xj + 2.0 * xj * r * mu) - Rg) / H); + result += (yi + yj) / 2.0 * dx; + xi = xj; + yi = yj; + } + return mu < -sqrt(1.0 - (Rg / r) * (Rg / r)) ? 1e9 : result; +} + + +void main() { + ivec2 coord = ivec2(gl_GlobalInvocationID.xy); + float r, muS; + getTransmittanceRMu(r, muS); + vec3 depth = betaR * opticalDepth(HR, r, muS) + betaMEx * opticalDepth(HM, r, muS); + imageStore(dest, coord, vec4(exp(-depth), SCAT_DEBUG_ALPHA)); +} diff --git a/rpplugins/scattering/shader/hosek_wilkie/compute_scattering.inc.glsl b/rpplugins/scattering/shader/hosek_wilkie/compute_scattering.inc.glsl new file mode 100644 index 0000000..08591a4 --- /dev/null +++ b/rpplugins/scattering/shader/hosek_wilkie/compute_scattering.inc.glsl @@ -0,0 +1,125 @@ +/** + * + * RenderPipeline + * + * Copyright (c) 2014-2016 tobspr + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + */ + +#pragma once + + +vec3 sun_vector = get_sun_vector(); + +uniform sampler3D ScatteringLUT; + + +// Fetches the scattering value from the LUT +vec3 get_scattering(vec3 surface_pos) { + surface_pos = normalize(surface_pos); + + float elevation, theta, radius; + vector_to_spherical(surface_pos, theta, elevation, radius); + + float sun_elevation = TimeOfDay.scattering.sun_altitude / 180.0 * M_PI; + float sun_azimuth = TimeOfDay.scattering.sun_azimuth / 180.0 * M_PI; + + float night_factor = saturate(sun_elevation * 30.0); + + float max_angle_factor = 40.0 / 180.0 * M_PI; + float elevation_factor = sun_elevation / max_angle_factor; + + float slice_index = 0.5 / 100.0 + elevation_factor; + + float factor_x = theta; + float factor_y = elevation; + + float neg_solar_elevation = HALF_PI - sun_elevation; + + float cos_gamma = cos(elevation) * cos(neg_solar_elevation) + + sin(elevation) * sin(neg_solar_elevation) + * cos(theta - sun_azimuth + M_PI); + + float gamma = acos(cos_gamma); + + elevation *= 0.95; + + vec2 lut_coord = vec2(gamma / TWO_PI, 1 - (elevation / HALF_PI)); + vec3 value = textureLod(ScatteringLUT, vec3(lut_coord, slice_index), 0).xyz ; + value *= 25.0; + value *= night_factor; + return vec3(value); + +} + +// Fetches the scattering value at a given surface position +vec3 get_scattering_at_surface(vec3 surface_pos) { + vec3 vec_to_cam = vec3(surface_pos - MainSceneData.camera_pos); + surface_pos.xy = vec2(vec_to_cam.xy * 0.6); + return get_scattering(surface_pos); +} + +vec3 DoScattering(vec3 surface_pos, vec3 view_dir, out float fog_factor) +{ + + // Move surface pos above ocean level + if (surface_pos.z < -0.01) { + vec3 v2s = surface_pos - MainSceneData.camera_pos; + float z_factor = abs(MainSceneData.camera_pos.z) / abs(v2s.z); + surface_pos = MainSceneData.camera_pos + v2s * z_factor; + view_dir = normalize(surface_pos - MainSceneData.camera_pos); + } + + float path_length = distance(surface_pos, MainSceneData.camera_pos); + vec3 inscatter = get_scattering(surface_pos); + fog_factor = 1.0; + + + // Check if the ray is finite + if (path_length < 20000.0) { + + // Integrate scattering + const int num_steps = 6; + float curr_h = MainSceneData.camera_pos.z; + + curr_h *= 1.0 - saturate(path_length / 30000.0); + + float h_step = (surface_pos.z - MainSceneData.camera_pos.z) / num_steps; + vec3 accum = vec3(0); + for (int i = 0; i < num_steps; ++i) { + curr_h += h_step; + accum += get_scattering_at_surface(vec3(surface_pos.xy, curr_h)); + } + + accum /= float(num_steps); + + // Exponential fog + float fog_ramp = TimeOfDay.scattering.fog_ramp_size; + fog_factor = saturate(1.0 - exp(-path_length / (0.6 * fog_ramp))); + + // Exponential height fog + fog_factor *= exp(-pow(max(0, surface_pos.z), 1.2) / (5.0 * 4000.0)); + inscatter = accum * 0.8; + fog_factor = saturate(1.1 * fog_factor); + } + + return inscatter; +} diff --git a/rpplugins/scattering/shader/scattering_envmap.frag.glsl b/rpplugins/scattering/shader/scattering_envmap.frag.glsl new file mode 100644 index 0000000..eefe1bb --- /dev/null +++ b/rpplugins/scattering/shader/scattering_envmap.frag.glsl @@ -0,0 +1,75 @@ +/** + * + * RenderPipeline + * + * Copyright (c) 2014-2016 tobspr + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + */ + +#version 430 + +#define USE_TIME_OF_DAY 1 +#pragma include "render_pipeline_base.inc.glsl" + +layout(r11f_g11f_b10f) uniform imageCube RESTRICT DestCubemap; +uniform sampler2D DefaultSkydome; +uniform samplerCube DefaultEnvmap; + +#pragma include "scattering_method.inc.glsl" + +void main() { + + // Get cubemap coordinate + int texsize = imageSize(DestCubemap).x; + ivec2 coord = ivec2(gl_FragCoord.xy); + + // Get cubemap view_vector + ivec2 clamped_coord; int face; + vec3 view_vector = texcoord_to_cubemap(texsize, coord, clamped_coord, face); + + // Store horizon + float horizon = view_vector.z; + float sky_clip = 0.0; + + // Get inscattered light + vec3 inscattered_light = DoScattering(view_vector * 1e10, view_vector, sky_clip) + * TimeOfDay.scattering.sun_intensity; + + if (horizon > 0.0) { + inscattered_light *= 2.0; // XXX: This makes it look better, but has no physical background. + + // Render clouds to provide more variance for the cubemap + vec3 cloud_color = textureLod(DefaultSkydome, get_skydome_coord(view_vector), 0).xyz; + // inscattered_light = cloud_color * 15; + } else { + // Blend ambient cubemap at the bottom + vec3 sun_vector = get_sun_vector(); + vec3 color_scale = get_sun_color_scale(sun_vector) * TimeOfDay.scattering.sun_color; + inscattered_light = textureLod(DefaultEnvmap, fix_cubemap_coord(view_vector), 0).xyz + * TimeOfDay.scattering.sun_intensity / M_PI * color_scale; + + #if !HAVE_PLUGIN(color_correction) + // inscattered_light *= 0.1; + #endif + } + + imageStore(DestCubemap, ivec3(clamped_coord, face), vec4(inscattered_light, 1.0)); +} diff --git a/rpplugins/scattering/shader/scattering_method.inc.glsl b/rpplugins/scattering/shader/scattering_method.inc.glsl new file mode 100644 index 0000000..4767eb5 --- /dev/null +++ b/rpplugins/scattering/shader/scattering_method.inc.glsl @@ -0,0 +1,39 @@ +/** + * + * RenderPipeline + * + * Copyright (c) 2014-2016 tobspr + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + */ + +#pragma once + +// This file just includes the scattering kernel based on the selected scattering +// method + + +#if ENUM_V_ACTIVE(scattering, scattering_method, eric_bruneton) + #pragma include "eric_bruneton/compute_scattering.inc.glsl" +#elif ENUM_V_ACTIVE(scattering, scattering_method, hosek_wilkie) + #pragma include "hosek_wilkie/compute_scattering.inc.glsl" +#else + #error Unkown Scattering Method! +#endif diff --git a/rpplugins/skin_shading/__init__.py b/rpplugins/skin_shading/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/rpplugins/skin_shading/config.yaml b/rpplugins/skin_shading/config.yaml new file mode 100644 index 0000000..01deba1 --- /dev/null +++ b/rpplugins/skin_shading/config.yaml @@ -0,0 +1,23 @@ + +settings: !!omap + + - quality: + type: enum + values: ["low", "medium", "high"] + default: "medium" + label: Quality + shader_runtime: true + description: > + Controls the quality of the subsurface scattering, higher + values provide smoother results but also consume more performance. + + - blur_scale: + type: float + range: [0.1, 3.0] + default: 0.43 + shader_runtime: true + label: Filter Radius + description: Radius of the subsurface scattering filter, higher values + produce smoother results but might also produce artifacts. + +daytime_settings: diff --git a/rpplugins/skin_shading/plugin.py b/rpplugins/skin_shading/plugin.py new file mode 100644 index 0000000..b56cefa --- /dev/null +++ b/rpplugins/skin_shading/plugin.py @@ -0,0 +1,41 @@ +""" + +RenderPipeline + +Copyright (c) 2014-2016 tobspr + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. + +""" + +from rpcore.pluginbase.base_plugin import BasePlugin + +from .skin_shading_stage import SkinShadingStage + + +class Plugin(BasePlugin): + + name = "Skin Shading" + author = "tobspr " + description = ("This plugin adds support for Seperable Screen Space Subsurface " + "Scattering (SSSSS). This improves skin rendering.") + version = "1.0" + + def on_stage_setup(self): + self.stage = self.create_stage(SkinShadingStage) diff --git a/rpplugins/skin_shading/shader/SeperableSSS.inc.glsl b/rpplugins/skin_shading/shader/SeperableSSS.inc.glsl new file mode 100644 index 0000000..94f3f8f --- /dev/null +++ b/rpplugins/skin_shading/shader/SeperableSSS.inc.glsl @@ -0,0 +1,173 @@ +/** + * + * NOTICE: Modified by tobspr for GLSL 4.0, removed all unnecessary stuff. + * Original copyright below. + * + * + * Copyright (C) 2012 Jorge Jimenez (jorge@iryoku.com) + * Copyright (C) 2012 Diego Gutierrez (diegog@unizar.es) + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the following disclaimer + * in the documentation and/or other materials provided with the + * distribution: + * + * "Uses Separable SSS. Copyright (C) 2012 by Jorge Jimenez and Diego + * Gutierrez." + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS + * IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL COPYRIGHT HOLDERS OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + * The views and conclusions contained in the software and documentation are + * those of the authors and should not be interpreted as representing official + * policies, either expressed or implied, of the copyright holders. + */ + +#pragma optionNV (unroll all) + +#if ENUM_V_ACTIVE(skin_shading, quality, low) + #define SSSS_QUALITY 0 +#elif ENUM_V_ACTIVE(skin_shading, quality, medium) + #define SSSS_QUALITY 1 +#elif ENUM_V_ACTIVE(skin_shading, quality, high) + #define SSSS_QUALITY 2 +#else + #error Invalid skin shading quality level +#endif + +#define SSSS_FOLLOW_SURFACE 1 + + +#if SSSS_QUALITY == 2 +#define SSSS_N_SAMPLES 25 +vec4 kernel[] = { + vec4(0.530605, 0.613514, 0.739601, 0), + vec4(0.000973794, 1.11862e-005, 9.43437e-007, -3), + vec4(0.00333804, 7.85443e-005, 1.2945e-005, -2.52083), + vec4(0.00500364, 0.00020094, 5.28848e-005, -2.08333), + vec4(0.00700976, 0.00049366, 0.000151938, -1.6875), + vec4(0.0094389, 0.00139119, 0.000416598, -1.33333), + vec4(0.0128496, 0.00356329, 0.00132016, -1.02083), + vec4(0.017924, 0.00711691, 0.00347194, -0.75), + vec4(0.0263642, 0.0119715, 0.00684598, -0.520833), + vec4(0.0410172, 0.0199899, 0.0118481, -0.333333), + vec4(0.0493588, 0.0367726, 0.0219485, -0.1875), + vec4(0.0402784, 0.0657244, 0.04631, -0.0833333), + vec4(0.0211412, 0.0459286, 0.0378196, -0.0208333), + vec4(0.0211412, 0.0459286, 0.0378196, 0.0208333), + vec4(0.0402784, 0.0657244, 0.04631, 0.0833333), + vec4(0.0493588, 0.0367726, 0.0219485, 0.1875), + vec4(0.0410172, 0.0199899, 0.0118481, 0.333333), + vec4(0.0263642, 0.0119715, 0.00684598, 0.520833), + vec4(0.017924, 0.00711691, 0.00347194, 0.75), + vec4(0.0128496, 0.00356329, 0.00132016, 1.02083), + vec4(0.0094389, 0.00139119, 0.000416598, 1.33333), + vec4(0.00700976, 0.00049366, 0.000151938, 1.6875), + vec4(0.00500364, 0.00020094, 5.28848e-005, 2.08333), + vec4(0.00333804, 7.85443e-005, 1.2945e-005, 2.52083), + vec4(0.000973794, 1.11862e-005, 9.43437e-007, 3), +}; +#elif SSSS_QUALITY == 1 +#define SSSS_N_SAMPLES 17 +vec4 kernel[] = { + vec4(0.536343, 0.624624, 0.748867, 0), + vec4(0.00317394, 0.000134823, 3.77269e-005, -2), + vec4(0.0100386, 0.000914679, 0.000275702, -1.53125), + vec4(0.0144609, 0.00317269, 0.00106399, -1.125), + vec4(0.0216301, 0.00794618, 0.00376991, -0.78125), + vec4(0.0347317, 0.0151085, 0.00871983, -0.5), + vec4(0.0571056, 0.0287432, 0.0172844, -0.28125), + vec4(0.0582416, 0.0659959, 0.0411329, -0.125), + vec4(0.0324462, 0.0656718, 0.0532821, -0.03125), + vec4(0.0324462, 0.0656718, 0.0532821, 0.03125), + vec4(0.0582416, 0.0659959, 0.0411329, 0.125), + vec4(0.0571056, 0.0287432, 0.0172844, 0.28125), + vec4(0.0347317, 0.0151085, 0.00871983, 0.5), + vec4(0.0216301, 0.00794618, 0.00376991, 0.78125), + vec4(0.0144609, 0.00317269, 0.00106399, 1.125), + vec4(0.0100386, 0.000914679, 0.000275702, 1.53125), + vec4(0.00317394, 0.000134823, 3.77269e-005, 2), +}; +#elif SSSS_QUALITY == 0 +#define SSSS_N_SAMPLES 11 +vec4 kernel[] = { + vec4(0.560479, 0.669086, 0.784728, 0), + vec4(0.00471691, 0.000184771, 5.07566e-005, -2), + vec4(0.0192831, 0.00282018, 0.00084214, -1.28), + vec4(0.03639, 0.0130999, 0.00643685, -0.72), + vec4(0.0821904, 0.0358608, 0.0209261, -0.32), + vec4(0.0771802, 0.113491, 0.0793803, -0.08), + vec4(0.0771802, 0.113491, 0.0793803, 0.08), + vec4(0.0821904, 0.0358608, 0.0209261, 0.32), + vec4(0.03639, 0.0130999, 0.00643685, 0.72), + vec4(0.0192831, 0.00282018, 0.00084214, 1.28), + vec4(0.00471691, 0.000184771, 5.07565e-005, 2), +}; +#else +#error Quality must be one of {0, 1, 2} +#endif + + +vec4 SSSSBlurPS( + vec2 texcoord, + sampler2D colorTex, + sampler2D depthTex, + float sssWidth, + float sssScale, + vec2 dir) { + + // Fetch color of current pixel: + vec4 colorM = textureLod(colorTex, texcoord, 0); + + // Fetch linear depth of current pixel: + float depthM = textureLod(depthTex, texcoord, 0).r; + + // Calculate the sssWidth scale (1.0 for a unit plane sitting on the + // projection window): + float distanceToProjectionWindow = 10.0; + float scale = distanceToProjectionWindow / depthM; + + // Calculate the final step to fetch the surrounding pixels: + vec2 finalStep = sssWidth * scale * dir; + finalStep *= sssScale; + finalStep *= 1.0 / 3.0; // Divide by 3 as the kernels range from -3 to 3. + + // Accumulate the center sample: + vec4 colorBlurred = colorM; + colorBlurred.rgb *= kernel[0].rgb; + + // Accumulate the other samples: + for (int i = 1; i < SSSS_N_SAMPLES; i++) { + // Fetch color and depth for current sample: + vec2 offset = texcoord + kernel[i].a * finalStep; + vec4 color = textureLod(colorTex, offset, 0); + + #if SSSS_FOLLOW_SURFACE == 1 + // If the difference in depth is huge, we lerp color back to "colorM": + float depth = textureLod(depthTex, offset, 0).r; + float s = saturate(1000.0f * distanceToProjectionWindow * + sssWidth * abs(depthM - depth)); + color.rgb = mix(color.rgb, colorM.rgb, s); + #endif + + // Accumulate: + colorBlurred.rgb += kernel[i].rgb * color.rgb; + } + + return colorBlurred; +} diff --git a/rpplugins/skin_shading/shader/sssss_blur.frag.glsl b/rpplugins/skin_shading/shader/sssss_blur.frag.glsl new file mode 100644 index 0000000..101c89b --- /dev/null +++ b/rpplugins/skin_shading/shader/sssss_blur.frag.glsl @@ -0,0 +1,63 @@ +/** + * + * RenderPipeline + * + * Copyright (c) 2014-2016 tobspr + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + */ + +#version 430 + +#pragma optionNV (unroll all) + +#define USE_GBUFFER_EXTENSIONS +#pragma include "render_pipeline_base.inc.glsl" +#pragma include "includes/gbuffer.inc.glsl" + +#pragma include "SeperableSSS.inc.glsl" + +uniform sampler2D ShadedScene; +uniform ivec2 direction; + +out vec3 color; + +// Performs the subsurface scattering blur + +void main() { + vec2 texcoord = get_texcoord(); + int shading_model = get_gbuffer_shading_model(GBuffer, texcoord); + + // Early out + if (shading_model != SHADING_MODEL_SKIN) { + color = textureLod(ShadedScene, texcoord, 0).xyz; + return; + } + + const float sss_width = 0.01 * GET_SETTING(skin_shading, blur_scale); + vec4 blur_result = SSSSBlurPS(texcoord, ShadedScene, GBuffer.Depth, sss_width, + 1, vec2(direction)); + color = blur_result.xyz; + + #if DEBUG_MODE + color = textureLod(ShadedScene, texcoord, 0).xyz; + #endif + +} diff --git a/rpplugins/skin_shading/skin_shading_stage.py b/rpplugins/skin_shading/skin_shading_stage.py new file mode 100644 index 0000000..945ce06 --- /dev/null +++ b/rpplugins/skin_shading/skin_shading_stage.py @@ -0,0 +1,66 @@ +""" + +RenderPipeline + +Copyright (c) 2014-2016 tobspr + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. + +""" + +from panda3d.core import LVecBase2i + +from rplibs.six.moves import range # pylint: disable=import-error +from rpcore.render_stage import RenderStage + + +class SkinShadingStage(RenderStage): + + """ This is the main stage used by the SkinShadingStage plugin """ + + required_pipes = ["ShadedScene", "GBuffer"] + + @property + def produced_pipes(self): + return {"ShadedScene": self.final_tex} + + def create(self): + current_tex = None + self.blur_targets = [] + for i in range(3): + target_h = self.create_target("BlurH-" + str(i)) + target_h.add_color_attachment(bits=16) + target_h.prepare_buffer() + target_h.set_shader_input("direction", LVecBase2i(1, 0)) + if current_tex is not None: + target_h.set_shader_input("ShadedScene", current_tex, override=True) + current_tex = target_h.color_tex + target_v = self.create_target("BlurV-" + str(i)) + target_v.add_color_attachment(bits=16) + target_v.prepare_buffer() + target_v.set_shader_input("ShadedScene", current_tex, override=True) + target_v.set_shader_input("direction", LVecBase2i(0, 1)) + current_tex = target_v.color_tex + self.blur_targets += [target_h, target_v] + self.final_tex = current_tex + + def reload_shaders(self): + blur_shader = self.load_plugin_shader("sssss_blur.frag.glsl") + for target in self.blur_targets: + target.shader = blur_shader diff --git a/rpplugins/sky_ao/__init__.py b/rpplugins/sky_ao/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/rpplugins/sky_ao/ao_stage.py b/rpplugins/sky_ao/ao_stage.py new file mode 100644 index 0000000..a1ff37f --- /dev/null +++ b/rpplugins/sky_ao/ao_stage.py @@ -0,0 +1,62 @@ +""" + +RenderPipeline + +Copyright (c) 2014-2016 tobspr + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. + +""" + +from panda3d.core import Vec2 + +from rpcore.render_stage import RenderStage + + +class SkyAOStage(RenderStage): + + """ This is the main stage used by the Sky AO plugin, and computes + the sky occlusion term """ + + required_inputs = ["SkyAOCapturePosition"] + required_pipes = ["SkyAOHeight", "GBuffer"] + + @property + def produced_pipes(self): + return {"SkyAO": self.target_upscale.color_tex} + + def create(self): + self.target = self.create_target("ComputeSkyAO") + self.target.size = -2 + self.target.add_color_attachment(bits=(16, 0, 0, 0)) + self.target.prepare_buffer() + + self.target_upscale = self.create_target("UpscaleSkyAO") + self.target_upscale.add_color_attachment(bits=(16, 0, 0, 0)) + self.target_upscale.prepare_buffer() + + self.target_upscale.set_shader_inputs( + SourceTex=self.target.color_tex, + upscaleWeights=Vec2(0.001, 0.001)) + + def reload_shaders(self): + self.target.shader = self.load_plugin_shader( + "compute_sky_ao.frag.glsl") + self.target_upscale.shader = self.load_plugin_shader( + "/$$rp/shader/bilateral_upscale.frag.glsl") diff --git a/rpplugins/sky_ao/capture_stage.py b/rpplugins/sky_ao/capture_stage.py new file mode 100644 index 0000000..314f18e --- /dev/null +++ b/rpplugins/sky_ao/capture_stage.py @@ -0,0 +1,94 @@ +""" + +RenderPipeline + +Copyright (c) 2014-2016 tobspr + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. + +""" + +from __future__ import division + +from panda3d.core import Camera, OrthographicLens, PTALVecBase3f + +from rpcore.globals import Globals +from rpcore.render_stage import RenderStage + + +class SkyAOCaptureStage(RenderStage): + + """ This stage captures the sky ao by rendering the scene from above """ + + required_inputs = [] + required_pipes = [] + + @property + def produced_pipes(self): + return {"SkyAOHeight": self.target_convert.color_tex} + + @property + def produced_inputs(self): + return {"SkyAOCapturePosition": self.pta_position} + + def __init__(self, pipeline): + RenderStage.__init__(self, pipeline) + self.pta_position = PTALVecBase3f.empty_array(1) + self.resolution = 512 + self.capture_height = 100.0 + self.max_radius = 100.0 + + def create(self): + self.camera = Camera("SkyAOCaptureCam") + self.cam_lens = OrthographicLens() + self.cam_lens.set_film_size(self.max_radius, self.max_radius) + self.cam_lens.set_near_far(0, self.capture_height) + self.camera.set_lens(self.cam_lens) + self.cam_node = Globals.base.render.attach_new_node(self.camera) + self.cam_node.look_at(0, 0, -1) + self.cam_node.set_r(0) + + self.target = self.create_target("SkyAOCapture") + self.target.size = self.resolution + self.target.add_depth_attachment(bits=16) + self.target.prepare_render(self.cam_node) + + self.target_convert = self.create_target("ConvertDepth") + self.target_convert.size = self.resolution + self.target_convert.add_color_attachment(bits=(16, 0, 0, 0)) + self.target_convert.prepare_buffer() + + self.target_convert.set_shader_inputs( + DepthTex=self.target.depth_tex, + position=self.pta_position) + + # Register camera + self._pipeline.tag_mgr.register_camera("shadow", self.camera) + + def update(self): + snap_size = self.max_radius / self.resolution + cam_pos = Globals.base.camera.get_pos(Globals.base.render) + self.cam_node.set_pos( + cam_pos.x - cam_pos.x % snap_size, + cam_pos.y - cam_pos.y % snap_size, + self.capture_height / 2.0) + self.pta_position[0] = self.cam_node.get_pos() + + def reload_shaders(self): + self.target_convert.shader = self.load_plugin_shader("convert_depth.frag.glsl") diff --git a/rpplugins/sky_ao/config.yaml b/rpplugins/sky_ao/config.yaml new file mode 100644 index 0000000..1f0f272 --- /dev/null +++ b/rpplugins/sky_ao/config.yaml @@ -0,0 +1,79 @@ + +settings: !!omap + + - sample_radius: + type: float + range: [0.1, 50.0] + default: 6.0 + shader_runtime: true + label: Sample radius + description: > + Controls the ao sample radius, higher values produce blurrier results, + but might cost more performance, and cause more jittering. + + - max_radius: + type: float + range: [10, 2000.0] + default: 200.0 + label: Maximum Radius + description: > + Controls how far the sky ao is computed, in world space. The higher + the maximum radius is, the further sky ao reaches, but it also reduces + the precision. + + - resolution: + type: power_of_two + range: [32, 8192] + default: 1024 + label: Resolution + description: > + A higher resolution provides more details, but also costs more + performance and memory. + + - sample_sequence: + type: sample_sequence + shader_runtime: true + dimension: 2 + default: poisson_2D_32 + label: Sample Sequence + description: > + Amout and Type of samples, higher values cost more performance + but provide smoother results. + + - ao_multiplier: + type: float + shader_runtime: true + range: [0.05, 5.0] + default: 0.25 + label: AO Multiplier + description: > + Controls the ao strength, higher values produce a darker ao. + + - ao_bias: + shader_runtime: true + type: float + range: [0.0, 1.0] + default: 0.3 + label: AO Bias + description: > + Miminum ambient occlusion term, to prevent total dark spots. + + - blend_factor: + type: float + shader_runtime: true + range: [0.01, 0.5] + default: 0.05 + label: Border Blending + description: > + Controls how smooth the sky ao fades out at distance (the maximum radius) + + - capture_height: + type: float + range: [10, 1500.0] + default: 250.0 + label: Capture height + description: > + Controls from which height the sky ao is captured. This should be the + height of your highest object, e.g. maximum terrain height. + +daytime_settings: diff --git a/rpplugins/sky_ao/plugin.py b/rpplugins/sky_ao/plugin.py new file mode 100644 index 0000000..5ddf96b --- /dev/null +++ b/rpplugins/sky_ao/plugin.py @@ -0,0 +1,60 @@ +""" + +RenderPipeline + +Copyright (c) 2014-2016 tobspr + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. + +""" + +from rpcore.pluginbase.base_plugin import BasePlugin +from rpcore.stages.ambient_stage import AmbientStage + +from .capture_stage import SkyAOCaptureStage +from .ao_stage import SkyAOStage + + +class Plugin(BasePlugin): + + name = "Sky Occlusion" + author = "tobspr " + description = ("This plugin adds support for sky occlusion, computing " + "occlusion based on the sky visibility.") + version = "0.2 beta" + + def on_stage_setup(self): + self.capture_stage = self.create_stage(SkyAOCaptureStage) + self.ao_stage = self.create_stage(SkyAOStage) + + self.capture_stage.resolution = self.get_setting("resolution") + self.capture_stage.max_radius = self.get_setting("max_radius") + self.capture_stage.capture_height = self.get_setting("capture_height") + + # Make the stages use our output + AmbientStage.required_pipes.append("SkyAO") + + def on_post_stage_setup(self): + if self.is_plugin_enabled("env_probes"): + self.get_plugin_instance("env_probes").capture_stage.required_inputs.append("SkyAOCapturePosition") + self.get_plugin_instance("env_probes").capture_stage.required_pipes.append("SkyAOHeight") + + + def on_pipeline_created(self): + pass diff --git a/rpplugins/sky_ao/shader/compute_sky_ao.frag.glsl b/rpplugins/sky_ao/shader/compute_sky_ao.frag.glsl new file mode 100644 index 0000000..4847467 --- /dev/null +++ b/rpplugins/sky_ao/shader/compute_sky_ao.frag.glsl @@ -0,0 +1,42 @@ +/** + * + * RenderPipeline + * + * Copyright (c) 2014-2016 tobspr + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + */ + +#version 430 + +#define USE_GBUFFER_EXTENSIONS +#pragma include "render_pipeline_base.inc.glsl" +#pragma include "includes/gbuffer.inc.glsl" + +#pragma include "sky_ao.inc.glsl" + +out vec4 result; + +void main() { + + vec2 texcoord = get_half_texcoord(); + Material m = unpack_material(GBuffer, texcoord); + result = vec4(compute_sky_ao(m.position, m.normal)); +} diff --git a/rpplugins/sky_ao/shader/convert_depth.frag.glsl b/rpplugins/sky_ao/shader/convert_depth.frag.glsl new file mode 100644 index 0000000..8fa983b --- /dev/null +++ b/rpplugins/sky_ao/shader/convert_depth.frag.glsl @@ -0,0 +1,47 @@ +/** + * + * RenderPipeline + * + * Copyright (c) 2014-2016 tobspr + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + */ + +#version 430 + +#pragma include "render_pipeline_base.inc.glsl" +#pragma include "includes/transforms.inc.glsl" + +uniform sampler2D DepthTex; +uniform vec3 position; + +out vec4 result; + +void main() { + ivec2 coord = ivec2(gl_FragCoord.xy); + + float depth_val = texelFetch(DepthTex, coord, 0).x; + + const float far_plane = GET_SETTING(sky_ao, capture_height); + + float linear_depth = depth_val * far_plane; + float z_pos = position.z - linear_depth; + result = vec4(z_pos); +} diff --git a/rpplugins/sky_ao/shader/sky_ao.inc.glsl b/rpplugins/sky_ao/shader/sky_ao.inc.glsl new file mode 100644 index 0000000..673e21a --- /dev/null +++ b/rpplugins/sky_ao/shader/sky_ao.inc.glsl @@ -0,0 +1,98 @@ +/** + * + * RenderPipeline + * + * Copyright (c) 2014-2016 tobspr + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + */ +#pragma once + +#pragma include "includes/sampling_sequences.inc.glsl" +#pragma include "includes/noise.inc.glsl" + +uniform sampler2D SkyAOHeight; +uniform vec3 SkyAOCapturePosition; + +float compute_sky_ao(vec3 ws_position, vec3 ws_normal) { + + // Constants + const int ao_map_resolution = GET_SETTING(sky_ao, resolution); + const float radius = GET_SETTING(sky_ao, sample_radius); + const float ao_multiplier = GET_SETTING(sky_ao, ao_multiplier); + const float ao_bias = GET_SETTING(sky_ao, ao_bias); + const float fade_scale = GET_SETTING(sky_ao, blend_factor); + const float ao_map_scale = GET_SETTING(sky_ao, max_radius); // world space + const float film_size = ao_map_scale * 0.5; + + + vec2 local_coord = (ws_position.xy - SkyAOCapturePosition.xy) / film_size * 0.5 + 0.5; + + if (out_of_screen(local_coord)) { + return 1.0; + } + + float blend = 1.0; + blend *= saturate(min(local_coord.x, local_coord.y) / fade_scale); + blend *= saturate(min(1 - local_coord.x, 1 - local_coord.y) / fade_scale); + + + // Factor to convert from tex-space to world-space + const float tc_to_ws = ao_map_scale; + + + float accum = 0.0; + vec2 jitter = rand_rgb(ivec2(gl_FragCoord.xy) % 2).xy; + + // Capture samples + + // vec3 avg_unoccluded_normal = vec3(0); + + START_ITERATE_SEQUENCE(sky_ao, sample_sequence, vec2 offset) + + offset = (offset * 0.9 + 0.1 * jitter) / ao_map_resolution * radius; + vec2 offcoord = local_coord + offset; + + float sample_z = textureLod(SkyAOHeight, offcoord, 0).x; + + + accum += saturate(1.0 * (sample_z - ws_position.z)); + // if (sample_z > ws_position.z) + // accum += 1.0; + // Project sample in normal direction + // float dist = length(offset) * tc_to_ws; + // float proj_z = ws_position.z + dist * ws_normal.z; + + + // accum += saturate((sample_z - proj_z) * 2.0); + // if (proj_z >= sample_z) { + // accum += 1.0; + // } + + END_ITERATE_SEQUENCE() + + NORMALIZE_SEQUENCE(sky_ao, sample_sequence, accum); + + accum = saturate(1 - accum + ao_bias); + accum = pow(accum, 0.25 * ao_multiplier); + accum = mix(1, accum, blend); + + return accum; +} diff --git a/rpplugins/smaa/LICENSE.txt b/rpplugins/smaa/LICENSE.txt new file mode 100644 index 0000000..fa50989 --- /dev/null +++ b/rpplugins/smaa/LICENSE.txt @@ -0,0 +1,34 @@ + +This plugin uses the SMAA code from: + +https://github.com/iryoku/smaa + +You can find the license below: + +---- + +Copyright (C) 2013 Jorge Jimenez (jorge@iryoku.com) +Copyright (C) 2013 Jose I. Echevarria (joseignacioechevarria@gmail.com) +Copyright (C) 2013 Belen Masia (bmasia@unizar.es) +Copyright (C) 2013 Fernando Navarro (fernandn@microsoft.com) +Copyright (C) 2013 Diego Gutierrez (diegog@unizar.es) + +Permission is hereby granted, free of charge, to any person obtaining a copy +this software and associated documentation files (the "Software"), to deal in +the Software without restriction, including without limitation the rights to +use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of +the Software, and to permit persons to whom the Software is furnished to do so, +subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. As clarification, there is no +requirement that the copyright notice and permission be included in binary +distributions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS +FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR +COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER +IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + diff --git a/rpplugins/smaa/__init__.py b/rpplugins/smaa/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/rpplugins/smaa/config.yaml b/rpplugins/smaa/config.yaml new file mode 100644 index 0000000..b5ae3a0 --- /dev/null +++ b/rpplugins/smaa/config.yaml @@ -0,0 +1,61 @@ + +settings: !!omap + + - use_reprojection: + type: bool + default: true + label: Use temporal antialiasing (SMAA T2) + description: > + This setting enables temporal antialiasing, which increases the + antialiasing quality a lot. Basically the scene gets rendered a + little different every frame, and the results of the current and + the last frame get merged. This way, flickering is reduced by a lot, + and the image becomes more smooth. + + - smaa_quality: + type: enum + default: ultra + values: ["low", "medium", "high", "ultra"] + label: SMAA Quality Preset + shader_runtime: true + description: > + The quality of the smaa algorithm. Usually you should choose "ultra", + since it does not have a significant higher cost, but provides way + better quality. However, on low-end systems, it might be desireable + to turn this value down. + + - jitter_pattern: + type: enum + default: halton8 + values: ["halton8", "skew_butterly", "uniform4", "halton256", "rotated4_helix2", "uniform2", + "halton16", "still", "rotated4", "rotated4_helix", "poisson10", "halton32", + "uniform4_helix", "uniform4_double_helix", "pentagram"] + runtime: true + label: Jitter sequence + description: > + Controls the jitter pattern to use + + - history_length: + display_if: { use_reprojection: True } + type: int + range: [1, 16] + default: 8 + shader_runtime: true + label: History Length + description: > + History buffer size. This controls how long pixels will stay + in the history buffer, greater values lead to smoother results + but also might produce more artifacts. + + - jitter_amount: + display_if: { use_reprojection: True } + type: float + range: [0.05, 2.0] + default: 0.3 + runtime: true + label: Jitter Amount + description: > + Controls how much each pixel is jittered, higher values might + preserve better details but also introduce flickering. + +daytime_settings: diff --git a/rpplugins/smaa/jitters.py b/rpplugins/smaa/jitters.py new file mode 100644 index 0000000..32be2c8 --- /dev/null +++ b/rpplugins/smaa/jitters.py @@ -0,0 +1,140 @@ +""" + +RenderPipeline + +Copyright (c) 2014-2016 tobspr + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. + +""" + +# pylint: skip-file +# flake8: noqa + +# Jitters from +# https://github.com/playdeadgames/temporal/blob/master/Assets/Scripts/FrustumJitter.cs + +from __future__ import division +from panda3d.core import Vec2 + +__all__ = ("JITTERS",) + +JITTERS = { + + "still": [ + Vec2(0.0, 0.0), + ], + + "uniform2": [ + Vec2(-0.25, -0.25), # ll + Vec2( 0.25, 0.25), # ur + ], + + "uniform4": [ + Vec2(-0.25, -0.25), # ll + Vec2( 0.25, -0.25), # lr + Vec2( 0.25, 0.25), # ur + Vec2(-0.25, 0.25), # ul + ], + + "uniform4_helix": [ + Vec2(-0.25, -0.25), # ll 3 1 + Vec2( 0.25, 0.25), # ur \/| + Vec2( 0.25, -0.25), # lr /\| + Vec2(-0.25, 0.25), # ul 0 2 + ], + + "uniform4_double_helix": [ + Vec2(-0.25, -0.25), # ll 3 1 + Vec2( 0.25, 0.25), # ur \/| + Vec2( 0.25, -0.25), # lr /\| + Vec2(-0.25, 0.25), # ul 0 2 + Vec2(-0.25, -0.25), # ll 6--7 + Vec2( 0.25, -0.25), # lr \ + Vec2(-0.25, 0.25), # ul \ + Vec2( 0.25, 0.25), # ur 4--5 + ], + + "skew_butterly": [ + Vec2(-0.250, -0.250), + Vec2( 0.250, 0.250), + Vec2( 0.125, -0.125), + Vec2(-0.125, 0.125), + ], + + "rotated4": [ + Vec2(-0.125, -0.375), # ll + Vec2( 0.375, -0.125), # lr + Vec2( 0.125, 0.375), # ur + Vec2(-0.375, 0.125), # ul + ], + + "rotated4_helix": [ + Vec2(-0.125, -0.375), # ll 3 1 + Vec2( 0.125, 0.375), # ur \/| + Vec2( 0.375, -0.125), # lr /\| + Vec2(-0.375, 0.125), # ul 0 2 + ], + + "rotated4_helix2": [ + Vec2(-0.125, -0.375), # ll 2--1 + Vec2( 0.125, 0.375), # ur \/ + Vec2(-0.375, 0.125), # ul /\ + Vec2( 0.375, -0.125), # lr 0 3 + ], + + "poisson10": [ + Vec2(-0.16795960 * 0.25, 0.65544910 * 0.25), + Vec2(-0.69096030 * 0.25, 0.59015970 * 0.25), + Vec2( 0.49843820 * 0.25, 0.83099720 * 0.25), + Vec2( 0.17230150 * 0.25, -0.03882703 * 0.25), + Vec2(-0.60772670 * 0.25, -0.06013587 * 0.25), + Vec2( 0.65606390 * 0.25, 0.24007600 * 0.25), + Vec2( 0.80348370 * 0.25, -0.48096900 * 0.25), + Vec2( 0.33436540 * 0.25, -0.73007030 * 0.25), + Vec2(-0.47839520 * 0.25, -0.56005300 * 0.25), + Vec2(-0.12388120 * 0.25, -0.96633990 * 0.25), + ], + + "pentagram": [ + Vec2( 0.000000 * 0.5, 0.525731 * 0.5), # head + Vec2(-0.309017 * 0.5, -0.425325 * 0.5), # lleg + Vec2( 0.500000 * 0.5, 0.162460 * 0.5), # rarm + Vec2(-0.500000 * 0.5, 0.162460 * 0.5), # larm + Vec2( 0.309017 * 0.5, -0.425325 * 0.5), # rleg + ], +} + + +def halton_seq(prime, index=1): + """ Low discrepancy halton sequence with a given prime """ + r, f, i = 0.0, 1.0, index + while i > 0: + f /= prime + r += f * (i % prime) + i = int(i / float(prime)) + return r + +# Initialize halton sequences +for seq_num in [8, 16, 32, 256]: + sequence = [] + for seq_iter in range(seq_num): + point = Vec2(halton_seq(2, seq_iter + 1) - 0.5, halton_seq(3, seq_iter + 1) - 0.5) + sequence.append(point) + JITTERS["halton" + str(seq_num)] = sequence diff --git a/rpplugins/smaa/plugin.py b/rpplugins/smaa/plugin.py new file mode 100644 index 0000000..466ef01 --- /dev/null +++ b/rpplugins/smaa/plugin.py @@ -0,0 +1,108 @@ +""" + +RenderPipeline + +Copyright (c) 2014-2016 tobspr + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. + +""" + +from panda3d.core import SamplerState + +from rpcore.globals import Globals +from rpcore.loader import RPLoader +from rpcore.pluginbase.base_plugin import BasePlugin + +from .smaa_stage import SMAAStage +from .jitters import JITTERS + + +class Plugin(BasePlugin): + + name = "SMAA (Antialiasing)" + author = "tobspr " + description = ("This plugin adds support for SMAA, a post process " + "antialiasing technique.") + version = "1.5" + + def on_stage_setup(self): + if self.get_setting("use_reprojection"): + self._compute_jitters() + + self._smaa_stage = self.create_stage(SMAAStage) + self._smaa_stage.use_reprojection = self.get_setting("use_reprojection") + self._load_textures() + + def on_pre_render_update(self): + # Apply jitter for temporal aa + if self.get_setting("use_reprojection"): + jitter_scale = self.get_setting("jitter_amount") + jitter = self._jitters[self._jitter_index] + jitter = jitter[0] * jitter_scale, jitter[1] * jitter_scale + + Globals.base.camLens.set_film_offset(jitter) + self._smaa_stage.set_jitter_index(self._jitter_index) + + # Increase jitter index + self._jitter_index += 1 + if self._jitter_index >= len(self._jitters): + self._jitter_index = 0 + + def _compute_jitters(self): + """ Internal method to compute the SMAA sub-pixel frame offsets """ + self._jitters = [] + self._jitter_index = 0 + scale = 1.0 / float(Globals.native_resolution.x) + + # Reduce jittering to 35% to avoid flickering + scale *= 0.35 + + for x, y in JITTERS[self.get_setting("jitter_pattern")]: + jitter_x = (x * 2 - 1) * scale * 0.5 + jitter_y = (y * 2 - 1) * scale * 0.5 + self._jitters.append((jitter_x, jitter_y)) + + @property + def history_length(self): + if self.get_setting("use_reprojection"): + return len(self._jitters) + return 1 + + def update_jitter_pattern(self): + """ Updates the jitter pattern when the setting was changed """ + self._compute_jitters() + + def on_window_resized(self): + """ Updates the jitter pattern when the window size was changed """ + self._compute_jitters() + + def _load_textures(self): + """ Loads all required textures """ + search_tex = RPLoader.load_texture(self.get_resource("search_tex.png")) + area_tex = RPLoader.load_texture(self.get_resource("area_tex.png")) + + for tex in [search_tex, area_tex]: + tex.set_minfilter(SamplerState.FT_linear) + tex.set_magfilter(SamplerState.FT_linear) + tex.set_wrap_u(SamplerState.WM_clamp) + tex.set_wrap_v(SamplerState.WM_clamp) + + self._smaa_stage.area_tex = area_tex + self._smaa_stage.search_tex = search_tex diff --git a/rpplugins/smaa/resources/area_tex.png b/rpplugins/smaa/resources/area_tex.png new file mode 100644 index 0000000..7b73de6 Binary files /dev/null and b/rpplugins/smaa/resources/area_tex.png differ diff --git a/rpplugins/smaa/resources/search_tex.png b/rpplugins/smaa/resources/search_tex.png new file mode 100644 index 0000000..97d22e4 Binary files /dev/null and b/rpplugins/smaa/resources/search_tex.png differ diff --git a/rpplugins/smaa/shader/SMAA.inc.glsl b/rpplugins/smaa/shader/SMAA.inc.glsl new file mode 100644 index 0000000..c5ed9d3 --- /dev/null +++ b/rpplugins/smaa/shader/SMAA.inc.glsl @@ -0,0 +1,1309 @@ + +// lint: skip-file + + +/** + * Copyright (C) 2013 Jorge Jimenez (jorge@iryoku.com) + * Copyright (C) 2013 Jose I. Echevarria (joseignacioechevarria@gmail.com) + * Copyright (C) 2013 Belen Masia (bmasia@unizar.es) + * Copyright (C) 2013 Fernando Navarro (fernandn@microsoft.com) + * Copyright (C) 2013 Diego Gutierrez (diegog@unizar.es) + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * this software and associated documentation files (the "Software"), to deal in + * the Software without restriction, including without limitation the rights to + * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies + * of the Software, and to permit persons to whom the Software is furnished to + * do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. As clarification, there + * is no requirement that the copyright notice and permission be included in + * binary distributions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + + +/** + * _______ ___ ___ ___ ___ + * / || \/ | / \ / \ + * | (---- | \ / | / ^ \ / ^ \ + * \ \ | |\/| | / /_\ \ / /_\ \ + * ----) | | | | | / _____ \ / _____ \ + * |_______/ |__| |__| /__/ \__\ /__/ \__\ + * + * E N H A N C E D + * S U B P I X E L M O R P H O L O G I C A L A N T I A L I A S I N G + * + * http://www.iryoku.com/smaa/ + * + * Hi, welcome aboard! + * + * Here you'll find instructions to get the shader up and running as fast as + * possible. + * + * IMPORTANTE NOTICE: when updating, remember to update both this file and the + * precomputed textures! They may change from version to version. + * + * The shader has three passes, chained together as follows: + * + * |input|------------------ + * v | + * [ SMAA*EdgeDetection ] | + * v | + * |edgesTex| | + * v | + * [ SMAABlendingWeightCalculation ] | + * v | + * |blendTex| | + * v | + * [ SMAANeighborhoodBlending ] <------ + * v + * |output| + * + * Note that each [pass] has its own vertex and pixel shader. Remember to use + * oversized triangles instead of quads to avoid overshading along the + * diagonal. + * + * You've three edge detection methods to choose from: luma, color or depth. + * They represent different quality/performance and anti-aliasing/sharpness + * tradeoffs, so our recommendation is for you to choose the one that best + * suits your particular scenario: + * + * - Depth edge detection is usually the fastest but it may miss some edges. + * + * - Luma edge detection is usually more expensive than depth edge detection, + * but catches visible edges that depth edge detection can miss. + * + * - Color edge detection is usually the most expensive one but catches + * chroma-only edges. + * + * For quickstarters: just use luma edge detection. + * + * The general advice is to not rush the integration process and ensure each + * step is done correctly (don't try to integrate SMAA T2x with predicated edge + * detection from the start!). Ok then, let's go! + * + * 1. The first step is to create two RGBA temporal render targets for holding + * |edgesTex| and |blendTex|. + * + * In DX10 or DX11, you can use a RG render target for the edges texture. + * In the case of NVIDIA GPUs, using RG render targets seems to actually be + * slower. + * + * On the Xbox 360, you can use the same render target for resolving both + * |edgesTex| and |blendTex|, as they aren't needed simultaneously. + * + * 2. Both temporal render targets |edgesTex| and |blendTex| must be cleared + * each frame. Do not forget to clear the alpha channel! + * + * 3. The next step is loading the two supporting precalculated textures, + * 'areaTex' and 'searchTex'. You'll find them in the 'Textures' folder as + * C++ headers, and also as regular DDS files. They'll be needed for the + * 'SMAABlendingWeightCalculation' pass. + * + * If you use the C++ headers, be sure to load them in the format specified + * inside of them. + * + * You can also compress 'areaTex' and 'searchTex' using BC5 and BC4 + * respectively, if you have that option in your content processor pipeline. + * When compressing then, you get a non-perceptible quality decrease, and a + * marginal performance increase. + * + * 4. All samplers must be set to linear filtering and clamp. + * + * After you get the technique working, remember that 64-bit inputs have + * half-rate linear filtering on GCN. + * + * If SMAA is applied to 64-bit color buffers, switching to point filtering + * when accesing them will increase the performance. Search for + * 'SMAASamplePoint' to see which textures may benefit from point + * filtering, and where (which is basically the color input in the edge + * detection and resolve passes). + * + * 5. All texture reads and buffer writes must be non-sRGB, with the exception + * of the input read and the output write in + * 'SMAANeighborhoodBlending' (and only in this pass!). If sRGB reads in + * this last pass are not possible, the technique will work anyway, but + * will perform antialiasing in gamma space. + * + * IMPORTANT: for best results the input read for the color/luma edge + * detection should *NOT* be sRGB. + * + * 6. Before including SMAA.h you'll have to setup the render target metrics, + * the target and any optional configuration defines. Optionally you can + * use a preset. + * + * You have the following targets available: + * SMAA_HLSL_3 + * SMAA_HLSL_4 + * SMAA_HLSL_4_1 + * SMAA_GLSL_3 * + * SMAA_GLSL_4 * + * + * * (See SMAA_INCLUDE_VS and SMAA_INCLUDE_PS below). + * + * And four presets: + * SMAA_PRESET_LOW (%60 of the quality) + * SMAA_PRESET_MEDIUM (%80 of the quality) + * SMAA_PRESET_HIGH (%95 of the quality) + * SMAA_PRESET_ULTRA (%99 of the quality) + * + * For example: + * #define SMAA_RT_METRICS float4(1.0 / 1280.0, 1.0 / 720.0, 1280.0, 720.0) + * #define SMAA_HLSL_4 + * #define SMAA_PRESET_HIGH + * #include "SMAA.h" + * + * Note that SMAA_RT_METRICS doesn't need to be a macro, it can be a + * uniform variable. The code is designed to minimize the impact of not + * using a constant value, but it is still better to hardcode it. + * + * Depending on how you encoded 'areaTex' and 'searchTex', you may have to + * add (and customize) the following defines before including SMAA.h: + * #define SMAA_AREATEX_SELECT(sample) sample.rg + * #define SMAA_SEARCHTEX_SELECT(sample) sample.r + * + * If your engine is already using porting macros, you can define + * SMAA_CUSTOM_SL, and define the porting functions by yourself. + * + * 7. Then, you'll have to setup the passes as indicated in the scheme above. + * You can take a look into SMAA.fx, to see how we did it for our demo. + * Checkout the function wrappers, you may want to copy-paste them! + * + * 8. It's recommended to validate the produced |edgesTex| and |blendTex|. + * You can use a screenshot from your engine to compare the |edgesTex| + * and |blendTex| produced inside of the engine with the results obtained + * with the reference demo. + * + * 9. After you get the last pass to work, it's time to optimize. You'll have + * to initialize a stencil buffer in the first pass (discard is already in + * the code), then mask execution by using it the second pass. The last + * pass should be executed in all pixels. + * + * + * After this point you can choose to enable predicated thresholding, + * temporal supersampling and motion blur integration: + * + * a) If you want to use predicated thresholding, take a look into + * SMAA_PREDICATION; you'll need to pass an extra texture in the edge + * detection pass. + * + * b) If you want to enable temporal supersampling (SMAA T2x): + * + * 1. The first step is to render using subpixel jitters. I won't go into + * detail, but it's as simple as moving each vertex position in the + * vertex shader, you can check how we do it in our DX10 demo. + * + * 2. Then, you must setup the temporal resolve. You may want to take a look + * into SMAAResolve for resolving 2x modes. After you get it working, you'll + * probably see ghosting everywhere. But fear not, you can enable the + * CryENGINE temporal reprojection by setting the SMAA_REPROJECTION macro. + * Check out SMAA_DECODE_VELOCITY if your velocity buffer is encoded. + * + * 3. The next step is to apply SMAA to each subpixel jittered frame, just as + * done for 1x. + * + * 4. At this point you should already have something usable, but for best + * results the proper area textures must be set depending on current jitter. + * For this, the parameter 'subsampleIndices' of + * 'SMAABlendingWeightCalculationPS' must be set as follows, for our T2x + * mode: + * + * @SUBSAMPLE_INDICES + * + * | S# | Camera Jitter | subsampleIndices | + * +----+------------------+---------------------+ + * | 0 | ( 0.25, -0.25) | float4(1, 1, 1, 0) | + * | 1 | (-0.25, 0.25) | float4(2, 2, 2, 0) | + * + * These jitter positions assume a bottom-to-top y axis. S# stands for the + * sample number. + * + * More information about temporal supersampling here: + * http://iryoku.com/aacourse/downloads/13-Anti-Aliasing-Methods-in-CryENGINE-3.pdf + * + * c) If you want to enable spatial multisampling (SMAA S2x): + * + * 1. The scene must be rendered using MSAA 2x. The MSAA 2x buffer must be + * created with: + * - DX10: see below (*) + * - DX10.1: D3D10_STANDARD_MULTISAMPLE_PATTERN or + * - DX11: D3D11_STANDARD_MULTISAMPLE_PATTERN + * + * This allows to ensure that the subsample order matches the table in + * @SUBSAMPLE_INDICES. + * + * (*) In the case of DX10, we refer the reader to: + * - SMAA::detectMSAAOrder and + * - SMAA::msaaReorder + * + * These functions allow to match the standard multisample patterns by + * detecting the subsample order for a specific GPU, and reordering + * them appropriately. + * + * 2. A shader must be run to output each subsample into a separate buffer + * (DX10 is required). You can use SMAASeparate for this purpose, or just do + * it in an existing pass (for example, in the tone mapping pass, which has + * the advantage of feeding tone mapped subsamples to SMAA, which will yield + * better results). + * + * 3. The full SMAA 1x pipeline must be run for each separated buffer, storing + * the results in the final buffer. The second run should alpha blend with + * the existing final buffer using a blending factor of 0.5. + * 'subsampleIndices' must be adjusted as in the SMAA T2x case (see point + * b). + * + * d) If you want to enable temporal supersampling on top of SMAA S2x + * (which actually is SMAA 4x): + * + * 1. SMAA 4x consists on temporally jittering SMAA S2x, so the first step is + * to calculate SMAA S2x for current frame. In this case, 'subsampleIndices' + * must be set as follows: + * + * | F# | S# | Camera Jitter | Net Jitter | subsampleIndices | + * +----+----+--------------------+-------------------+----------------------+ + * | 0 | 0 | ( 0.125, 0.125) | ( 0.375, -0.125) | float4(5, 3, 1, 3) | + * | 0 | 1 | ( 0.125, 0.125) | (-0.125, 0.375) | float4(4, 6, 2, 3) | + * +----+----+--------------------+-------------------+----------------------+ + * | 1 | 2 | (-0.125, -0.125) | ( 0.125, -0.375) | float4(3, 5, 1, 4) | + * | 1 | 3 | (-0.125, -0.125) | (-0.375, 0.125) | float4(6, 4, 2, 4) | + * + * These jitter positions assume a bottom-to-top y axis. F# stands for the + * frame number. S# stands for the sample number. + * + * 2. After calculating SMAA S2x for current frame (with the new subsample + * indices), previous frame must be reprojected as in SMAA T2x mode (see + * point b). + * + * e) If motion blur is used, you may want to do the edge detection pass + * together with motion blur. This has two advantages: + * + * 1. Pixels under heavy motion can be omitted from the edge detection process. + * For these pixels we can just store "no edge", as motion blur will take + * care of them. + * 2. The center pixel tap is reused. + * + * Note that in this case depth testing should be used instead of stenciling, + * as we have to write all the pixels in the motion blur pass. + * + * That's it! + */ + +//----------------------------------------------------------------------------- +// SMAA Presets + +/** + * Note that if you use one of these presets, the following configuration + * macros will be ignored if set in the "Configurable Defines" section. + */ + +#if defined(SMAA_PRESET_LOW) +#define SMAA_THRESHOLD 0.15 +#define SMAA_MAX_SEARCH_STEPS 4 +#define SMAA_DISABLE_DIAG_DETECTION +#define SMAA_DISABLE_CORNER_DETECTION +#elif defined(SMAA_PRESET_MEDIUM) +#define SMAA_THRESHOLD 0.1 +#define SMAA_MAX_SEARCH_STEPS 8 +#define SMAA_DISABLE_DIAG_DETECTION +#define SMAA_DISABLE_CORNER_DETECTION +#elif defined(SMAA_PRESET_HIGH) +#define SMAA_THRESHOLD 0.1 +#define SMAA_MAX_SEARCH_STEPS 16 +#define SMAA_MAX_SEARCH_STEPS_DIAG 8 +#define SMAA_CORNER_ROUNDING 25 +#elif defined(SMAA_PRESET_ULTRA) +#define SMAA_THRESHOLD 0.05 +#define SMAA_MAX_SEARCH_STEPS 32 +#define SMAA_MAX_SEARCH_STEPS_DIAG 16 +#define SMAA_CORNER_ROUNDING 25 +#endif + +//----------------------------------------------------------------------------- +// Configurable Defines + +/** + * SMAA_THRESHOLD specifies the threshold or sensitivity to edges. + * Lowering this value you will be able to detect more edges at the expense of + * performance. + * + * Range: [0, 0.5] + * 0.1 is a reasonable value, and allows to catch most visible edges. + * 0.05 is a rather overkill value, that allows to catch 'em all. + * + * If temporal supersampling is used, 0.2 could be a reasonable value, as low + * contrast edges are properly filtered by just 2x. + */ +#ifndef SMAA_THRESHOLD +#define SMAA_THRESHOLD 0.1 +#endif + +/** + * SMAA_DEPTH_THRESHOLD specifies the threshold for depth edge detection. + * + * Range: depends on the depth range of the scene. + */ +#ifndef SMAA_DEPTH_THRESHOLD +#define SMAA_DEPTH_THRESHOLD (0.1 * SMAA_THRESHOLD) +#endif + +/** + * SMAA_MAX_SEARCH_STEPS specifies the maximum steps performed in the + * horizontal/vertical pattern searches, at each side of the pixel. + * + * In number of pixels, it's actually the double. So the maximum line length + * perfectly handled by, for example 16, is 64 (by perfectly, we meant that + * longer lines won't look as good, but still antialiased). + * + * Range: [0, 112] + */ +#ifndef SMAA_MAX_SEARCH_STEPS +#define SMAA_MAX_SEARCH_STEPS 16 +#endif + +/** + * SMAA_MAX_SEARCH_STEPS_DIAG specifies the maximum steps performed in the + * diagonal pattern searches, at each side of the pixel. In this case we jump + * one pixel at time, instead of two. + * + * Range: [0, 20] + * + * On high-end machines it is cheap (between a 0.8x and 0.9x slower for 16 + * steps), but it can have a significant impact on older machines. + * + * Define SMAA_DISABLE_DIAG_DETECTION to disable diagonal processing. + */ +#ifndef SMAA_MAX_SEARCH_STEPS_DIAG +#define SMAA_MAX_SEARCH_STEPS_DIAG 8 +#endif + +/** + * SMAA_CORNER_ROUNDING specifies how much sharp corners will be rounded. + * + * Range: [0, 100] + * + * Define SMAA_DISABLE_CORNER_DETECTION to disable corner processing. + */ +#ifndef SMAA_CORNER_ROUNDING +#define SMAA_CORNER_ROUNDING 25 +#endif + +/** + * If there is an neighbor edge that has SMAA_LOCAL_CONTRAST_FACTOR times + * bigger contrast than current edge, current edge will be discarded. + * + * This allows to eliminate spurious crossing edges, and is based on the fact + * that, if there is too much contrast in a direction, that will hide + * perceptually contrast in the other neighbors. + */ +#ifndef SMAA_LOCAL_CONTRAST_ADAPTATION_FACTOR +#define SMAA_LOCAL_CONTRAST_ADAPTATION_FACTOR 2.0 +#endif + +/** + * Predicated thresholding allows to better preserve texture details and to + * improve performance, by decreasing the number of detected edges using an + * additional buffer like the light accumulation buffer, object ids or even the + * depth buffer (the depth buffer usage may be limited to indoor or short range + * scenes). + * + * It locally decreases the luma or color threshold if an edge is found in an + * additional buffer (so the global threshold can be higher). + * + * This method was developed by Playstation EDGE MLAA team, and used in + * Killzone 3, by using the light accumulation buffer. More information here: + * http://iryoku.com/aacourse/downloads/06-MLAA-on-PS3.pptx + */ +#ifndef SMAA_PREDICATION +#define SMAA_PREDICATION 0 +#endif + +/** + * Threshold to be used in the additional predication buffer. + * + * Range: depends on the input, so you'll have to find the magic number that + * works for you. + */ +#ifndef SMAA_PREDICATION_THRESHOLD +#define SMAA_PREDICATION_THRESHOLD 0.01 +#endif + +/** + * How much to scale the global threshold used for luma or color edge + * detection when using predication. + * + * Range: [1, 5] + */ +#ifndef SMAA_PREDICATION_SCALE +#define SMAA_PREDICATION_SCALE 2.0 +#endif + +/** + * How much to locally decrease the threshold. + * + * Range: [0, 1] + */ +#ifndef SMAA_PREDICATION_STRENGTH +#define SMAA_PREDICATION_STRENGTH 0.4 +#endif + +/** + * Temporal reprojection allows to remove ghosting artifacts when using + * temporal supersampling. We use the CryEngine 3 method which also introduces + * velocity weighting. This feature is of extreme importance for totally + * removing ghosting. More information here: + * http://iryoku.com/aacourse/downloads/13-Anti-Aliasing-Methods-in-CryENGINE-3.pdf + * + * Note that you'll need to setup a velocity buffer for enabling reprojection. + * For static geometry, saving the previous depth buffer is a viable + * alternative. + */ +#ifndef SMAA_REPROJECTION +#define SMAA_REPROJECTION 0 +#endif + +/** + * SMAA_REPROJECTION_WEIGHT_SCALE controls the velocity weighting. It allows to + * remove ghosting trails behind the moving object, which are not removed by + * just using reprojection. Using low values will exhibit ghosting, while using + * high values will disable temporal supersampling under motion. + * + * Behind the scenes, velocity weighting removes temporal supersampling when + * the velocity of the subsamples differs (meaning they are different objects). + * + * Range: [0, 80] + */ +#ifndef SMAA_REPROJECTION_WEIGHT_SCALE +#define SMAA_REPROJECTION_WEIGHT_SCALE 30.0 +#endif + +/** + * On some compilers, discard cannot be used in vertex shaders. Thus, they need + * to be compiled separately. + */ +#ifndef SMAA_INCLUDE_VS +#define SMAA_INCLUDE_VS 1 +#endif +#ifndef SMAA_INCLUDE_PS +#define SMAA_INCLUDE_PS 1 +#endif + +//----------------------------------------------------------------------------- +// Texture Access Defines + +#ifndef SMAA_AREATEX_SELECT +#if defined(SMAA_HLSL_3) +#define SMAA_AREATEX_SELECT(sample) sample.ra +#else +#define SMAA_AREATEX_SELECT(sample) sample.rg +#endif +#endif + +#ifndef SMAA_SEARCHTEX_SELECT +#define SMAA_SEARCHTEX_SELECT(sample) sample.r +#endif + +#ifndef SMAA_DECODE_VELOCITY +#define SMAA_DECODE_VELOCITY(sample) sample.rg +#endif + +//----------------------------------------------------------------------------- +// Non-Configurable Defines + +#define SMAA_AREATEX_MAX_DISTANCE 16 +#define SMAA_AREATEX_MAX_DISTANCE_DIAG 20 +#define SMAA_AREATEX_PIXEL_SIZE (1.0 / float2(160.0, 560.0)) +#define SMAA_AREATEX_SUBTEX_SIZE (1.0 / 7.0) +#define SMAA_SEARCHTEX_SIZE float2(66.0, 33.0) +#define SMAA_SEARCHTEX_PACKED_SIZE float2(64.0, 16.0) +#define SMAA_CORNER_ROUNDING_NORM (float(SMAA_CORNER_ROUNDING) / 100.0) + +//----------------------------------------------------------------------------- +// Porting Functions + +#if defined(SMAA_HLSL_3) +#define SMAATexture2D(tex) sampler2D tex +#define SMAATexturePass2D(tex) tex +#define SMAASampleLevelZero(tex, coord) tex2Dlod(tex, float4(coord, 0.0, 0.0)) +#define SMAASampleLevelZeroPoint(tex, coord) tex2Dlod(tex, float4(coord, 0.0, 0.0)) +#define SMAASampleLevelZeroOffset(tex, coord, offset) tex2Dlod(tex, float4(coord + offset * SMAA_RT_METRICS.xy, 0.0, 0.0)) +#define SMAASample(tex, coord) tex2D(tex, coord) +#define SMAASamplePoint(tex, coord) tex2D(tex, coord) +#define SMAASampleOffset(tex, coord, offset) tex2D(tex, coord + offset * SMAA_RT_METRICS.xy) +#define SMAA_FLATTEN [flatten] +#define SMAA_BRANCH [branch] +#endif +#if defined(SMAA_HLSL_4) || defined(SMAA_HLSL_4_1) +SamplerState LinearSampler { Filter = MIN_MAG_LINEAR_MIP_POINT; AddressU = Clamp; AddressV = Clamp; }; +SamplerState PointSampler { Filter = MIN_MAG_MIP_POINT; AddressU = Clamp; AddressV = Clamp; }; +#define SMAATexture2D(tex) Texture2D tex +#define SMAATexturePass2D(tex) tex +#define SMAASampleLevelZero(tex, coord) tex.SampleLevel(LinearSampler, coord, 0) +#define SMAASampleLevelZeroPoint(tex, coord) tex.SampleLevel(PointSampler, coord, 0) +#define SMAASampleLevelZeroOffset(tex, coord, offset) tex.SampleLevel(LinearSampler, coord, 0, offset) +#define SMAASample(tex, coord) tex.Sample(LinearSampler, coord) +#define SMAASamplePoint(tex, coord) tex.Sample(PointSampler, coord) +#define SMAASampleOffset(tex, coord, offset) tex.Sample(LinearSampler, coord, offset) +#define SMAA_FLATTEN [flatten] +#define SMAA_BRANCH [branch] +#define SMAATexture2DMS2(tex) Texture2DMS tex +#define SMAALoad(tex, pos, sample) tex.Load(pos, sample) +#if defined(SMAA_HLSL_4_1) +#define SMAAGather(tex, coord) tex.Gather(LinearSampler, coord, 0) +#endif +#endif +#if defined(SMAA_GLSL_3) || defined(SMAA_GLSL_4) +#define SMAATexture2D(tex) sampler2D tex +#define SMAATexturePass2D(tex) tex +#define SMAASampleLevelZero(tex, coord) textureLod(tex, coord, 0.0) +#define SMAASampleLevelZeroPoint(tex, coord) textureLod(tex, coord, 0.0) +#define SMAASampleLevelZeroOffset(tex, coord, offset) textureLodOffset(tex, coord, 0.0, offset) +#define SMAASample(tex, coord) textureLod(tex, coord, 0) +#define SMAASamplePoint(tex, coord) textureLod(tex, coord, 0) +#define SMAASampleOffset(tex, coord, offset) texture(tex, coord, offset) +#define SMAA_FLATTEN +#define SMAA_BRANCH +#define lerp(a, b, t) mix(a, b, t) +#define saturate(a) clamp(a, 0.0, 1.0) +#if defined(SMAA_GLSL_4) +#define mad(a, b, c) fma(a, b, c) +#define SMAAGather(tex, coord) textureGather(tex, coord) +#else +#define mad(a, b, c) (a * b + c) +#endif +#define float2 vec2 +#define float3 vec3 +#define float4 vec4 +#define int2 ivec2 +#define int3 ivec3 +#define int4 ivec4 +#define bool2 bvec2 +#define bool3 bvec3 +#define bool4 bvec4 +#endif + +#if !defined(SMAA_HLSL_3) && !defined(SMAA_HLSL_4) && !defined(SMAA_HLSL_4_1) && !defined(SMAA_GLSL_3) && !defined(SMAA_GLSL_4) && !defined(SMAA_CUSTOM_SL) +#error you must define the shading language: SMAA_HLSL_*, SMAA_GLSL_* or SMAA_CUSTOM_SL +#endif + +//----------------------------------------------------------------------------- +// Misc functions + +/** + * Gathers current pixel, and the top-left neighbors. + */ +float3 SMAAGatherNeighbours(float2 texcoord, + float4 offset[3], + SMAATexture2D(tex)) { + #ifdef SMAAGather + return SMAAGather(tex, texcoord + SMAA_RT_METRICS.xy * float2(-0.5, -0.5)).grb; + #else + float P = SMAASamplePoint(tex, texcoord).r; + float Pleft = SMAASamplePoint(tex, offset[0].xy).r; + float Ptop = SMAASamplePoint(tex, offset[0].zw).r; + return float3(P, Pleft, Ptop); + #endif +} + +/** + * Adjusts the threshold by means of predication. + */ +float2 SMAACalculatePredicatedThreshold(float2 texcoord, + float4 offset[3], + SMAATexture2D(predicationTex)) { + float3 neighbours = SMAAGatherNeighbours(texcoord, offset, SMAATexturePass2D(predicationTex)); + float2 delta = abs(neighbours.xx - neighbours.yz); + float2 edges = step(SMAA_PREDICATION_THRESHOLD, delta); + return SMAA_PREDICATION_SCALE * SMAA_THRESHOLD * (1.0 - SMAA_PREDICATION_STRENGTH * edges); +} + +/** + * Conditional move: + */ +void SMAAMovc(bool2 cond, inout float2 variable, float2 value) { + SMAA_FLATTEN if (cond.x) variable.x = value.x; + SMAA_FLATTEN if (cond.y) variable.y = value.y; +} + +void SMAAMovc(bool4 cond, inout float4 variable, float4 value) { + SMAAMovc(cond.xy, variable.xy, value.xy); + SMAAMovc(cond.zw, variable.zw, value.zw); +} + + +#if SMAA_INCLUDE_VS +//----------------------------------------------------------------------------- +// Vertex Shaders + +/** + * Edge Detection Vertex Shader + */ +void SMAAEdgeDetectionVS(float2 texcoord, + out float4 offset[3]) { + offset[0] = mad(SMAA_RT_METRICS.xyxy, float4(-1.0, 0.0, 0.0, -1.0), texcoord.xyxy); + offset[1] = mad(SMAA_RT_METRICS.xyxy, float4( 1.0, 0.0, 0.0, 1.0), texcoord.xyxy); + offset[2] = mad(SMAA_RT_METRICS.xyxy, float4(-2.0, 0.0, 0.0, -2.0), texcoord.xyxy); +} + +/** + * Blend Weight Calculation Vertex Shader + */ +void SMAABlendingWeightCalculationVS(float2 texcoord, + out float2 pixcoord, + out float4 offset[3]) { + pixcoord = texcoord * SMAA_RT_METRICS.zw; + + // We will use these offsets for the searches later on (see @PSEUDO_GATHER4): + offset[0] = mad(SMAA_RT_METRICS.xyxy, float4(-0.25, -0.125, 1.25, -0.125), texcoord.xyxy); + offset[1] = mad(SMAA_RT_METRICS.xyxy, float4(-0.125, -0.25, -0.125, 1.25), texcoord.xyxy); + + // And these for the searches, they indicate the ends of the loops: + offset[2] = mad(SMAA_RT_METRICS.xxyy, + float4(-2.0, 2.0, -2.0, 2.0) * float(SMAA_MAX_SEARCH_STEPS), + float4(offset[0].xz, offset[1].yw)); +} + +/** + * Neighborhood Blending Vertex Shader + */ +void SMAANeighborhoodBlendingVS(float2 texcoord, + out float4 offset) { + offset = mad(SMAA_RT_METRICS.xyxy, float4( 1.0, 0.0, 0.0, 1.0), texcoord.xyxy); +} +#endif // SMAA_INCLUDE_VS + +#if SMAA_INCLUDE_PS +//----------------------------------------------------------------------------- +// Edge Detection Pixel Shaders (First Pass) + +/** + * Luma Edge Detection + * + * IMPORTANT NOTICE: luma edge detection requires gamma-corrected colors, and + * thus 'colorTex' should be a non-sRGB texture. + */ +float2 SMAALumaEdgeDetectionPS(float2 texcoord, + float4 offset[3], + SMAATexture2D(colorTex) + #if SMAA_PREDICATION + , SMAATexture2D(predicationTex) + #endif + ) { + // Calculate the threshold: + #if SMAA_PREDICATION + float2 threshold = SMAACalculatePredicatedThreshold(texcoord, offset, SMAATexturePass2D(predicationTex)); + #else + float2 threshold = float2(SMAA_THRESHOLD, SMAA_THRESHOLD); + #endif + + // Calculate lumas: + float3 weights = float3(0.2126, 0.7152, 0.0722); + float L = dot(SMAASamplePoint(colorTex, texcoord).rgb, weights); + + float Lleft = dot(SMAASamplePoint(colorTex, offset[0].xy).rgb, weights); + float Ltop = dot(SMAASamplePoint(colorTex, offset[0].zw).rgb, weights); + + // We do the usual threshold: + float4 delta; + delta.xy = abs(L - float2(Lleft, Ltop)); + float2 edges = step(threshold, delta.xy); + + // Then discard if there is no edge: + if (dot(edges, float2(1.0, 1.0)) == 0.0) + discard; + + // Calculate right and bottom deltas: + float Lright = dot(SMAASamplePoint(colorTex, offset[1].xy).rgb, weights); + float Lbottom = dot(SMAASamplePoint(colorTex, offset[1].zw).rgb, weights); + delta.zw = abs(L - float2(Lright, Lbottom)); + + // Calculate the maximum delta in the direct neighborhood: + float2 maxDelta = max(delta.xy, delta.zw); + + // Calculate left-left and top-top deltas: + float Lleftleft = dot(SMAASamplePoint(colorTex, offset[2].xy).rgb, weights); + float Ltoptop = dot(SMAASamplePoint(colorTex, offset[2].zw).rgb, weights); + delta.zw = abs(float2(Lleft, Ltop) - float2(Lleftleft, Ltoptop)); + + // Calculate the final maximum delta: + maxDelta = max(maxDelta.xy, delta.zw); + float finalDelta = max(maxDelta.x, maxDelta.y); + + // Local contrast adaptation: + edges.xy *= step(finalDelta, SMAA_LOCAL_CONTRAST_ADAPTATION_FACTOR * delta.xy); + + return edges; +} + +/** + * Color Edge Detection + * + * IMPORTANT NOTICE: color edge detection requires gamma-corrected colors, and + * thus 'colorTex' should be a non-sRGB texture. + */ +float2 SMAAColorEdgeDetectionPS(float2 texcoord, + float4 offset[3], + SMAATexture2D(colorTex) + #if SMAA_PREDICATION + , SMAATexture2D(predicationTex) + #endif + ) { + // Calculate the threshold: + #if SMAA_PREDICATION + float2 threshold = SMAACalculatePredicatedThreshold(texcoord, offset, predicationTex); + #else + float2 threshold = float2(SMAA_THRESHOLD, SMAA_THRESHOLD); + #endif + + // Calculate color deltas: + float4 delta; + float3 C = SMAA_GET_COLOR(SMAASamplePoint(colorTex, texcoord).rgb); + + float3 Cleft = SMAA_GET_COLOR(SMAASamplePoint(colorTex, offset[0].xy).rgb); + float3 t = abs(C - Cleft); + delta.x = max(max(t.r, t.g), t.b); + + float3 Ctop = SMAA_GET_COLOR(SMAASamplePoint(colorTex, offset[0].zw).rgb); + t = abs(C - Ctop); + delta.y = max(max(t.r, t.g), t.b); + + // We do the usual threshold: + float2 edges = step(threshold, delta.xy); + + // Then discard if there is no edge: + if (dot(edges, float2(1.0, 1.0)) == 0.0) + discard; + + // Calculate right and bottom deltas: + float3 Cright = SMAA_GET_COLOR(SMAASamplePoint(colorTex, offset[1].xy).rgb); + t = abs(C - Cright); + delta.z = max(max(t.r, t.g), t.b); + + float3 Cbottom = SMAA_GET_COLOR(SMAASamplePoint(colorTex, offset[1].zw).rgb); + t = abs(C - Cbottom); + delta.w = max(max(t.r, t.g), t.b); + + // Calculate the maximum delta in the direct neighborhood: + float2 maxDelta = max(delta.xy, delta.zw); + + // Calculate left-left and top-top deltas: + float3 Cleftleft = SMAA_GET_COLOR(SMAASamplePoint(colorTex, offset[2].xy).rgb); + t = abs(C - Cleftleft); + delta.z = max(max(t.r, t.g), t.b); + + float3 Ctoptop = SMAA_GET_COLOR(SMAASamplePoint(colorTex, offset[2].zw).rgb); + t = abs(C - Ctoptop); + delta.w = max(max(t.r, t.g), t.b); + + // Calculate the final maximum delta: + maxDelta = max(maxDelta.xy, delta.zw); + float finalDelta = max(maxDelta.x, maxDelta.y); + + // Local contrast adaptation: + edges.xy *= step(finalDelta, SMAA_LOCAL_CONTRAST_ADAPTATION_FACTOR * delta.xy); + + return edges; +} + +/** + * Depth Edge Detection + */ +float2 SMAADepthEdgeDetectionPS(float2 texcoord, + float4 offset[3], + SMAATexture2D(depthTex)) { + float3 neighbours = SMAAGatherNeighbours(texcoord, offset, SMAATexturePass2D(depthTex)); + float2 delta = abs(neighbours.xx - float2(neighbours.y, neighbours.z)); + float2 edges = step(SMAA_DEPTH_THRESHOLD, delta); + + if (dot(edges, float2(1.0, 1.0)) == 0.0) + discard; + + return edges; +} + +//----------------------------------------------------------------------------- +// Diagonal Search Functions + +#if !defined(SMAA_DISABLE_DIAG_DETECTION) + +/** + * Allows to decode two binary values from a bilinear-filtered access. + */ +float2 SMAADecodeDiagBilinearAccess(float2 e) { + // Bilinear access for fetching 'e' have a 0.25 offset, and we are + // interested in the R and G edges: + // + // +---G---+-------+ + // | x o R x | + // +-------+-------+ + // + // Then, if one of these edge is enabled: + // Red: (0.75 * X + 0.25 * 1) => 0.25 or 1.0 + // Green: (0.75 * 1 + 0.25 * X) => 0.75 or 1.0 + // + // This function will unpack the values (mad + mul + round): + // wolframalpha.com: round(x * abs(5 * x - 5 * 0.75)) plot 0 to 1 + e.r = e.r * abs(5.0 * e.r - 5.0 * 0.75); + return round(e); +} + +float4 SMAADecodeDiagBilinearAccess(float4 e) { + e.rb = e.rb * abs(5.0 * e.rb - 5.0 * 0.75); + return round(e); +} + +/** + * These functions allows to perform diagonal pattern searches. + */ +float2 SMAASearchDiag1(SMAATexture2D(edgesTex), float2 texcoord, float2 dir, out float2 e) { + float4 coord = float4(texcoord, -1.0, 1.0); + float3 t = float3(SMAA_RT_METRICS.xy, 1.0); + while (coord.z < float(SMAA_MAX_SEARCH_STEPS_DIAG - 1) && + coord.w > 0.9) { + coord.xyz = mad(t, float3(dir, 1.0), coord.xyz); + e = SMAASampleLevelZero(edgesTex, coord.xy).rg; + coord.w = dot(e, float2(0.5, 0.5)); + } + return coord.zw; +} + +float2 SMAASearchDiag2(SMAATexture2D(edgesTex), float2 texcoord, float2 dir, out float2 e) { + float4 coord = float4(texcoord, -1.0, 1.0); + coord.x += 0.25 * SMAA_RT_METRICS.x; // See @SearchDiag2Optimization + float3 t = float3(SMAA_RT_METRICS.xy, 1.0); + while (coord.z < float(SMAA_MAX_SEARCH_STEPS_DIAG - 1) && + coord.w > 0.9) { + coord.xyz = mad(t, float3(dir, 1.0), coord.xyz); + + // @SearchDiag2Optimization + // Fetch both edges at once using bilinear filtering: + e = SMAASampleLevelZero(edgesTex, coord.xy).rg; + e = SMAADecodeDiagBilinearAccess(e); + + // Non-optimized version: + // e.g = SMAASampleLevelZero(edgesTex, coord.xy).g; + // e.r = SMAASampleLevelZeroOffset(edgesTex, coord.xy, int2(1, 0)).r; + + coord.w = dot(e, float2(0.5, 0.5)); + } + return coord.zw; +} + +/** + * Similar to SMAAArea, this calculates the area corresponding to a certain + * diagonal distance and crossing edges 'e'. + */ +float2 SMAAAreaDiag(SMAATexture2D(areaTex), float2 dist, float2 e, float offset) { + float2 texcoord = mad(float2(SMAA_AREATEX_MAX_DISTANCE_DIAG, SMAA_AREATEX_MAX_DISTANCE_DIAG), e, dist); + + // We do a scale and bias for mapping to texel space: + texcoord = mad(SMAA_AREATEX_PIXEL_SIZE, texcoord, 0.5 * SMAA_AREATEX_PIXEL_SIZE); + + // Diagonal areas are on the second half of the texture: + texcoord.x += 0.5; + + // Move to proper place, according to the subpixel offset: + texcoord.y += SMAA_AREATEX_SUBTEX_SIZE * offset; + + // Do it! + return SMAA_AREATEX_SELECT(SMAASampleLevelZero(areaTex, texcoord)); +} + +/** + * This searches for diagonal patterns and returns the corresponding weights. + */ +float2 SMAACalculateDiagWeights(SMAATexture2D(edgesTex), SMAATexture2D(areaTex), float2 texcoord, float2 e, float4 subsampleIndices) { + float2 weights = float2(0.0, 0.0); + + // Search for the line ends: + float4 d; + float2 end; + if (e.r > 0.0) { + d.xz = SMAASearchDiag1(SMAATexturePass2D(edgesTex), texcoord, float2(-1.0, 1.0), end); + d.x += float(end.y > 0.9); + } else + d.xz = float2(0.0, 0.0); + d.yw = SMAASearchDiag1(SMAATexturePass2D(edgesTex), texcoord, float2(1.0, -1.0), end); + + SMAA_BRANCH + if (d.x + d.y > 2.0) { // d.x + d.y + 1 > 3 + // Fetch the crossing edges: + float4 coords = mad(float4(-d.x + 0.25, d.x, d.y, -d.y - 0.25), SMAA_RT_METRICS.xyxy, texcoord.xyxy); + float4 c; + c.xy = SMAASampleLevelZeroOffset(edgesTex, coords.xy, int2(-1, 0)).rg; + c.zw = SMAASampleLevelZeroOffset(edgesTex, coords.zw, int2( 1, 0)).rg; + c.yxwz = SMAADecodeDiagBilinearAccess(c.xyzw); + + // Non-optimized version: + // float4 coords = mad(float4(-d.x, d.x, d.y, -d.y), SMAA_RT_METRICS.xyxy, texcoord.xyxy); + // float4 c; + // c.x = SMAASampleLevelZeroOffset(edgesTex, coords.xy, int2(-1, 0)).g; + // c.y = SMAASampleLevelZeroOffset(edgesTex, coords.xy, int2( 0, 0)).r; + // c.z = SMAASampleLevelZeroOffset(edgesTex, coords.zw, int2( 1, 0)).g; + // c.w = SMAASampleLevelZeroOffset(edgesTex, coords.zw, int2( 1, -1)).r; + + // Merge crossing edges at each side into a single value: + float2 cc = mad(float2(2.0, 2.0), c.xz, c.yw); + + // Remove the crossing edge if we didn't found the end of the line: + SMAAMovc(bool2(step(0.9, d.zw)), cc, float2(0.0, 0.0)); + + // Fetch the areas for this line: + weights += SMAAAreaDiag(SMAATexturePass2D(areaTex), d.xy, cc, subsampleIndices.z); + } + + // Search for the line ends: + d.xz = SMAASearchDiag2(SMAATexturePass2D(edgesTex), texcoord, float2(-1.0, -1.0), end); + if (SMAASampleLevelZeroOffset(edgesTex, texcoord, int2(1, 0)).r > 0.0) { + d.yw = SMAASearchDiag2(SMAATexturePass2D(edgesTex), texcoord, float2(1.0, 1.0), end); + d.y += float(end.y > 0.9); + } else + d.yw = float2(0.0, 0.0); + + SMAA_BRANCH + if (d.x + d.y > 2.0) { // d.x + d.y + 1 > 3 + // Fetch the crossing edges: + float4 coords = mad(float4(-d.x, -d.x, d.y, d.y), SMAA_RT_METRICS.xyxy, texcoord.xyxy); + float4 c; + c.x = SMAASampleLevelZeroOffset(edgesTex, coords.xy, int2(-1, 0)).g; + c.y = SMAASampleLevelZeroOffset(edgesTex, coords.xy, int2( 0, -1)).r; + c.zw = SMAASampleLevelZeroOffset(edgesTex, coords.zw, int2( 1, 0)).gr; + float2 cc = mad(float2(2.0, 2.0), c.xz, c.yw); + + // Remove the crossing edge if we didn't found the end of the line: + SMAAMovc(bool2(step(0.9, d.zw)), cc, float2(0.0, 0.0)); + + // Fetch the areas for this line: + weights += SMAAAreaDiag(SMAATexturePass2D(areaTex), d.xy, cc, subsampleIndices.w).gr; + } + + return weights; +} +#endif + +//----------------------------------------------------------------------------- +// Horizontal/Vertical Search Functions + +/** + * This allows to determine how much length should we add in the last step + * of the searches. It takes the bilinearly interpolated edge (see + * @PSEUDO_GATHER4), and adds 0, 1 or 2, depending on which edges and + * crossing edges are active. + */ +float SMAASearchLength(SMAATexture2D(searchTex), float2 e, float offset) { + // The texture is flipped vertically, with left and right cases taking half + // of the space horizontally: + float2 scale = SMAA_SEARCHTEX_SIZE * float2(0.5, -1.0); + float2 bias = SMAA_SEARCHTEX_SIZE * float2(offset, 1.0); + + // Scale and bias to access texel centers: + scale += float2(-1.0, 1.0); + bias += float2( 0.5, -0.5); + + // Convert from pixel coordinates to texcoords: + // (We use SMAA_SEARCHTEX_PACKED_SIZE because the texture is cropped) + scale *= 1.0 / SMAA_SEARCHTEX_PACKED_SIZE; + bias *= 1.0 / SMAA_SEARCHTEX_PACKED_SIZE; + + // Lookup the search texture: + return SMAA_SEARCHTEX_SELECT(SMAASampleLevelZero(searchTex, mad(scale, e, bias))); +} + +/** + * Horizontal/vertical search functions for the 2nd pass. + */ +float SMAASearchXLeft(SMAATexture2D(edgesTex), SMAATexture2D(searchTex), float2 texcoord, float end) { + /** + * @PSEUDO_GATHER4 + * This texcoord has been offset by (-0.25, -0.125) in the vertex shader to + * sample between edge, thus fetching four edges in a row. + * Sampling with different offsets in each direction allows to disambiguate + * which edges are active from the four fetched ones. + */ + float2 e = float2(0.0, 1.0); + while (texcoord.x > end && + e.g > 0.8281 && // Is there some edge not activated? + e.r == 0.0) { // Or is there a crossing edge that breaks the line? + e = SMAASampleLevelZero(edgesTex, texcoord).rg; + texcoord = mad(-float2(2.0, 0.0), SMAA_RT_METRICS.xy, texcoord); + } + + float offset = mad(-(255.0 / 127.0), SMAASearchLength(SMAATexturePass2D(searchTex), e, 0.0), 3.25); + return mad(SMAA_RT_METRICS.x, offset, texcoord.x); + + // Non-optimized version: + // We correct the previous (-0.25, -0.125) offset we applied: + // texcoord.x += 0.25 * SMAA_RT_METRICS.x; + + // The searches are bias by 1, so adjust the coords accordingly: + // texcoord.x += SMAA_RT_METRICS.x; + + // Disambiguate the length added by the last step: + // texcoord.x += 2.0 * SMAA_RT_METRICS.x; // Undo last step + // texcoord.x -= SMAA_RT_METRICS.x * (255.0 / 127.0) * SMAASearchLength(SMAATexturePass2D(searchTex), e, 0.0); + // return mad(SMAA_RT_METRICS.x, offset, texcoord.x); +} + +float SMAASearchXRight(SMAATexture2D(edgesTex), SMAATexture2D(searchTex), float2 texcoord, float end) { + float2 e = float2(0.0, 1.0); + while (texcoord.x < end && + e.g > 0.8281 && // Is there some edge not activated? + e.r == 0.0) { // Or is there a crossing edge that breaks the line? + e = SMAASampleLevelZero(edgesTex, texcoord).rg; + texcoord = mad(float2(2.0, 0.0), SMAA_RT_METRICS.xy, texcoord); + } + float offset = mad(-(255.0 / 127.0), SMAASearchLength(SMAATexturePass2D(searchTex), e, 0.5), 3.25); + return mad(-SMAA_RT_METRICS.x, offset, texcoord.x); +} + +float SMAASearchYUp(SMAATexture2D(edgesTex), SMAATexture2D(searchTex), float2 texcoord, float end) { + float2 e = float2(1.0, 0.0); + while (texcoord.y > end && + e.r > 0.8281 && // Is there some edge not activated? + e.g == 0.0) { // Or is there a crossing edge that breaks the line? + e = SMAASampleLevelZero(edgesTex, texcoord).rg; + texcoord = mad(-float2(0.0, 2.0), SMAA_RT_METRICS.xy, texcoord); + } + float offset = mad(-(255.0 / 127.0), SMAASearchLength(SMAATexturePass2D(searchTex), e.gr, 0.0), 3.25); + return mad(SMAA_RT_METRICS.y, offset, texcoord.y); +} + +float SMAASearchYDown(SMAATexture2D(edgesTex), SMAATexture2D(searchTex), float2 texcoord, float end) { + float2 e = float2(1.0, 0.0); + while (texcoord.y < end && + e.r > 0.8281 && // Is there some edge not activated? + e.g == 0.0) { // Or is there a crossing edge that breaks the line? + e = SMAASampleLevelZero(edgesTex, texcoord).rg; + texcoord = mad(float2(0.0, 2.0), SMAA_RT_METRICS.xy, texcoord); + } + float offset = mad(-(255.0 / 127.0), SMAASearchLength(SMAATexturePass2D(searchTex), e.gr, 0.5), 3.25); + return mad(-SMAA_RT_METRICS.y, offset, texcoord.y); +} + +/** + * Ok, we have the distance and both crossing edges. So, what are the areas + * at each side of current edge? + */ +float2 SMAAArea(SMAATexture2D(areaTex), float2 dist, float e1, float e2, float offset) { + // Rounding prevents precision errors of bilinear filtering: + float2 texcoord = mad(float2(SMAA_AREATEX_MAX_DISTANCE, SMAA_AREATEX_MAX_DISTANCE), round(4.0 * float2(e1, e2)), dist); + + // We do a scale and bias for mapping to texel space: + texcoord = mad(SMAA_AREATEX_PIXEL_SIZE, texcoord, 0.5 * SMAA_AREATEX_PIXEL_SIZE); + + // Move to proper place, according to the subpixel offset: + texcoord.y = mad(SMAA_AREATEX_SUBTEX_SIZE, offset, texcoord.y); + + // Do it! + return SMAA_AREATEX_SELECT(SMAASampleLevelZero(areaTex, texcoord)); +} + +//----------------------------------------------------------------------------- +// Corner Detection Functions + +void SMAADetectHorizontalCornerPattern(SMAATexture2D(edgesTex), inout float2 weights, float4 texcoord, float2 d) { + #if !defined(SMAA_DISABLE_CORNER_DETECTION) + float2 leftRight = step(d.xy, d.yx); + float2 rounding = (1.0 - SMAA_CORNER_ROUNDING_NORM) * leftRight; + + rounding /= leftRight.x + leftRight.y; // Reduce blending for pixels in the center of a line. + + float2 factor = float2(1.0, 1.0); + factor.x -= rounding.x * SMAASampleLevelZeroOffset(edgesTex, texcoord.xy, int2(0, 1)).r; + factor.x -= rounding.y * SMAASampleLevelZeroOffset(edgesTex, texcoord.zw, int2(1, 1)).r; + factor.y -= rounding.x * SMAASampleLevelZeroOffset(edgesTex, texcoord.xy, int2(0, -2)).r; + factor.y -= rounding.y * SMAASampleLevelZeroOffset(edgesTex, texcoord.zw, int2(1, -2)).r; + + weights *= saturate(factor); + #endif +} + +void SMAADetectVerticalCornerPattern(SMAATexture2D(edgesTex), inout float2 weights, float4 texcoord, float2 d) { + #if !defined(SMAA_DISABLE_CORNER_DETECTION) + float2 leftRight = step(d.xy, d.yx); + float2 rounding = (1.0 - SMAA_CORNER_ROUNDING_NORM) * leftRight; + + rounding /= leftRight.x + leftRight.y; + + float2 factor = float2(1.0, 1.0); + factor.x -= rounding.x * SMAASampleLevelZeroOffset(edgesTex, texcoord.xy, int2( 1, 0)).g; + factor.x -= rounding.y * SMAASampleLevelZeroOffset(edgesTex, texcoord.zw, int2( 1, 1)).g; + factor.y -= rounding.x * SMAASampleLevelZeroOffset(edgesTex, texcoord.xy, int2(-2, 0)).g; + factor.y -= rounding.y * SMAASampleLevelZeroOffset(edgesTex, texcoord.zw, int2(-2, 1)).g; + + weights *= saturate(factor); + #endif +} + +//----------------------------------------------------------------------------- +// Blending Weight Calculation Pixel Shader (Second Pass) + +float4 SMAABlendingWeightCalculationPS(float2 texcoord, + float2 pixcoord, + float4 offset[3], + SMAATexture2D(edgesTex), + SMAATexture2D(areaTex), + SMAATexture2D(searchTex), + float4 subsampleIndices) { // Just pass zero for SMAA 1x, see @SUBSAMPLE_INDICES. + float4 weights = float4(0.0, 0.0, 0.0, 0.0); + + float2 e = SMAASample(edgesTex, texcoord).rg; + + SMAA_BRANCH + if (e.g > 0.0) { // Edge at north + #if !defined(SMAA_DISABLE_DIAG_DETECTION) + // Diagonals have both north and west edges, so searching for them in + // one of the boundaries is enough. + weights.rg = SMAACalculateDiagWeights(SMAATexturePass2D(edgesTex), SMAATexturePass2D(areaTex), texcoord, e, subsampleIndices); + + // We give priority to diagonals, so if we find a diagonal we skip + // horizontal/vertical processing. + SMAA_BRANCH + if (weights.r == -weights.g) { // weights.r + weights.g == 0.0 + #endif + + float2 d; + + // Find the distance to the left: + float3 coords; + coords.x = SMAASearchXLeft(SMAATexturePass2D(edgesTex), SMAATexturePass2D(searchTex), offset[0].xy, offset[2].x); + coords.y = offset[1].y; // offset[1].y = texcoord.y - 0.25 * SMAA_RT_METRICS.y (@CROSSING_OFFSET) + d.x = coords.x; + + // Now fetch the left crossing edges, two at a time using bilinear + // filtering. Sampling at -0.25 (see @CROSSING_OFFSET) enables to + // discern what value each edge has: + float e1 = SMAASampleLevelZero(edgesTex, coords.xy).r; + + // Find the distance to the right: + coords.z = SMAASearchXRight(SMAATexturePass2D(edgesTex), SMAATexturePass2D(searchTex), offset[0].zw, offset[2].y); + d.y = coords.z; + + // We want the distances to be in pixel units (doing this here allow to + // better interleave arithmetic and memory accesses): + d = abs(round(mad(SMAA_RT_METRICS.zz, d, -pixcoord.xx))); + + // SMAAArea below needs a sqrt, as the areas texture is compressed + // quadratically: + float2 sqrt_d = sqrt(d); + + // Fetch the right crossing edges: + float e2 = SMAASampleLevelZeroOffset(edgesTex, coords.zy, int2(1, 0)).r; + + // Ok, we know how this pattern looks like, now it is time for getting + // the actual area: + weights.rg = SMAAArea(SMAATexturePass2D(areaTex), sqrt_d, e1, e2, subsampleIndices.y); + + // Fix corners: + coords.y = texcoord.y; + SMAADetectHorizontalCornerPattern(SMAATexturePass2D(edgesTex), weights.rg, coords.xyzy, d); + + #if !defined(SMAA_DISABLE_DIAG_DETECTION) + } else + e.r = 0.0; // Skip vertical processing. + #endif + } + + SMAA_BRANCH + if (e.r > 0.0) { // Edge at west + float2 d; + + // Find the distance to the top: + float3 coords; + coords.y = SMAASearchYUp(SMAATexturePass2D(edgesTex), SMAATexturePass2D(searchTex), offset[1].xy, offset[2].z); + coords.x = offset[0].x; // offset[1].x = texcoord.x - 0.25 * SMAA_RT_METRICS.x; + d.x = coords.y; + + // Fetch the top crossing edges: + float e1 = SMAASampleLevelZero(edgesTex, coords.xy).g; + + // Find the distance to the bottom: + coords.z = SMAASearchYDown(SMAATexturePass2D(edgesTex), SMAATexturePass2D(searchTex), offset[1].zw, offset[2].w); + d.y = coords.z; + + // We want the distances to be in pixel units: + d = abs(round(mad(SMAA_RT_METRICS.ww, d, -pixcoord.yy))); + + // SMAAArea below needs a sqrt, as the areas texture is compressed + // quadratically: + float2 sqrt_d = sqrt(d); + + // Fetch the bottom crossing edges: + float e2 = SMAASampleLevelZeroOffset(edgesTex, coords.xz, int2(0, 1)).g; + + // Get the area for this direction: + weights.ba = SMAAArea(SMAATexturePass2D(areaTex), sqrt_d, e1, e2, subsampleIndices.x); + + // Fix corners: + coords.x = texcoord.x; + SMAADetectVerticalCornerPattern(SMAATexturePass2D(edgesTex), weights.ba, coords.xyxz, d); + } + + return weights; +} + +//----------------------------------------------------------------------------- +// Neighborhood Blending Pixel Shader (Third Pass) + +float4 SMAANeighborhoodBlendingPS(float2 texcoord, + float4 offset, + SMAATexture2D(colorTex), + SMAATexture2D(blendTex) + ) { + // Fetch the blending weights for current pixel: + float4 a; + a.x = SMAASample(blendTex, offset.xy).a; // Right + a.y = SMAASample(blendTex, offset.zw).g; // Top + a.wz = SMAASample(blendTex, texcoord).xz; // Bottom / Left + + // Is there any blending weight with a value greater than 0.0? + SMAA_BRANCH + if (dot(a, float4(1.0, 1.0, 1.0, 1.0)) < 1e-5) { + float4 color = SMAA_GET_COLOR(SMAASampleLevelZero(colorTex, texcoord)); + return color; + } else { + bool h = max(a.x, a.z) > max(a.y, a.w); // max(horizontal) > max(vertical) + + // Calculate the blending offsets: + float4 blendingOffset = float4(0.0, a.y, 0.0, a.w); + float2 blendingWeight = a.yw; + SMAAMovc(bool4(h, h, h, h), blendingOffset, float4(a.x, 0.0, a.z, 0.0)); + SMAAMovc(bool2(h, h), blendingWeight, a.xz); + blendingWeight /= dot(blendingWeight, float2(1.0, 1.0)); + + // Calculate the texture coordinates: + float4 blendingCoord = mad(blendingOffset, float4(SMAA_RT_METRICS.xy, -SMAA_RT_METRICS.xy), texcoord.xyxy); + + // We exploit bilinear filtering to mix current pixel with the chosen + // neighbor: + float4 color = blendingWeight.x * SMAA_GET_COLOR(SMAASampleLevelZero(colorTex, blendingCoord.xy)); + color += blendingWeight.y * SMAA_GET_COLOR(SMAASampleLevelZero(colorTex, blendingCoord.zw)); + return color; + } +} + +//----------------------------------------------------------------------------- +// Separate Multisamples Pixel Shader (Optional Pass) + +#ifdef SMAALoad +void SMAASeparatePS(float4 position, + float2 texcoord, + out float4 target0, + out float4 target1, + SMAATexture2DMS2(colorTexMS)) { + int2 pos = int2(position.xy); + target0 = SMAALoad(colorTexMS, pos, 0); + target1 = SMAALoad(colorTexMS, pos, 1); +} +#endif + +//----------------------------------------------------------------------------- +#endif // SMAA_INCLUDE_PS diff --git a/rpplugins/smaa/shader/blending_weights.frag.glsl b/rpplugins/smaa/shader/blending_weights.frag.glsl new file mode 100644 index 0000000..43a1919 --- /dev/null +++ b/rpplugins/smaa/shader/blending_weights.frag.glsl @@ -0,0 +1,60 @@ +/** + * + * RenderPipeline + * + * Copyright (c) 2014-2016 tobspr + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + */ + +#version 430 + +#pragma include "render_pipeline_base.inc.glsl" +#pragma include "smaa_wrapper.inc.glsl" + +uniform sampler2D EdgeTex; +uniform sampler2D AreaTex; +uniform sampler2D SearchTex; +out vec4 result; + +void main() { + + vec2 texcoord = get_texcoord(); + + // "Vertex shader" + vec4 offset[3]; + vec2 pixcoord; + SMAABlendingWeightCalculationVS(texcoord, pixcoord, offset); + + // XXX: Find the right indices + // #if GET_SETTING(smaa, use_reprojection) + // vec4 subsampleIndices = MainSceneData.frame_index % 2 == 1 ? vec4(1, 1, 1, 0) : vec4(2, 2, 2, 0); + // #else + vec4 subsampleIndices = vec4(0); + // #endif + + // subsampleIndices = vec4(0); + + // subsampleIndices = vec4(2, 2, 2, 0); + + // Actual Fragment shader + result = SMAABlendingWeightCalculationPS(texcoord, pixcoord, offset, + EdgeTex, AreaTex, SearchTex, subsampleIndices); +} diff --git a/rpplugins/smaa/shader/edge_detection.frag.glsl b/rpplugins/smaa/shader/edge_detection.frag.glsl new file mode 100644 index 0000000..f945564 --- /dev/null +++ b/rpplugins/smaa/shader/edge_detection.frag.glsl @@ -0,0 +1,50 @@ +/** + * + * RenderPipeline + * + * Copyright (c) 2014-2016 tobspr + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + */ + +#version 430 + +#pragma include "render_pipeline_base.inc.glsl" + +#pragma include "smaa_wrapper.inc.glsl" +#pragma include "includes/gbuffer.inc.glsl" + +uniform GBufferData GBuffer; +uniform sampler2D ShadedScene; +out vec4 result; + +void main() { + + vec2 texcoord = get_texcoord(); + + // "Vertex shader" + vec4 offset[3]; + SMAAEdgeDetectionVS(texcoord, offset); + + // Actual Fragment shader + result = vec4(0); + result.xy = SMAAColorEdgeDetectionPS(texcoord, offset, ShadedScene); + result.w = 1.0; +} diff --git a/rpplugins/smaa/shader/neighborhood_blending.frag.glsl b/rpplugins/smaa/shader/neighborhood_blending.frag.glsl new file mode 100644 index 0000000..d7b5563 --- /dev/null +++ b/rpplugins/smaa/shader/neighborhood_blending.frag.glsl @@ -0,0 +1,47 @@ +/** + * + * RenderPipeline + * + * Copyright (c) 2014-2016 tobspr + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + */ + +#version 430 + +#pragma include "render_pipeline_base.inc.glsl" +#pragma include "smaa_wrapper.inc.glsl" +#pragma include "includes/gbuffer.inc.glsl" + +uniform sampler2D BlendTex; +uniform sampler2D ShadedScene; + +out vec4 result; + +void main() { + vec2 texcoord = get_texcoord(); + + // "Vertex shader" + vec4 offset; + SMAANeighborhoodBlendingVS(texcoord, offset); + + // Actual Fragment shader + result = SMAANeighborhoodBlendingPS(texcoord, offset, ShadedScene, BlendTex); +} diff --git a/rpplugins/smaa/shader/resolve_smaa.frag.glsl b/rpplugins/smaa/shader/resolve_smaa.frag.glsl new file mode 100644 index 0000000..95ba0b2 --- /dev/null +++ b/rpplugins/smaa/shader/resolve_smaa.frag.glsl @@ -0,0 +1,52 @@ +/** + * + * RenderPipeline + * + * Copyright (c) 2014-2016 tobspr + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + */ + +#version 430 + +#pragma include "render_pipeline_base.inc.glsl" + +#define RS_MAX_CLIP_DIST 0.4 +#define RS_DISTANCE_SCALE 1.5 +#define RS_KEEP_GOOD_DURATION float(GET_SETTING(smaa, history_length)) +#define RS_KEEP_BAD_DURATION RS_KEEP_GOOD_DURATION * 0.5 + +#pragma include "includes/temporal_resolve.inc.glsl" + +uniform sampler2D CurrentTex; +uniform sampler2D Previous_SMAAPostResolve; +uniform sampler2D CombinedVelocity; + +uniform int jitterIndex; + +out vec3 result; + +void main() { + vec2 texcoord = get_texcoord(); + vec2 velocity = textureLod(CombinedVelocity, texcoord, 0).xy; + vec2 last_coord = texcoord + velocity; + + result = resolve_temporal(CurrentTex, Previous_SMAAPostResolve, texcoord, last_coord).xyz; +} diff --git a/rpplugins/smaa/shader/smaa_wrapper.inc.glsl b/rpplugins/smaa/shader/smaa_wrapper.inc.glsl new file mode 100644 index 0000000..97c4664 --- /dev/null +++ b/rpplugins/smaa/shader/smaa_wrapper.inc.glsl @@ -0,0 +1,74 @@ +/** + * + * RenderPipeline + * + * Copyright (c) 2014-2016 tobspr + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + */ + +#pragma once + +// This file just sets a few defines and then includes the SMAA header + +#define SMAA_GLSL_4 +#define SMAA_RT_METRICS vec4(1.0 / WINDOW_WIDTH, 1.0 / WINDOW_HEIGHT, WINDOW_WIDTH, WINDOW_HEIGHT) + + +// Get seleted SMAA quality +#if ENUM_V_ACTIVE(smaa, smaa_quality, low) + #define SMAA_PRESET_LOW +#elif ENUM_V_ACTIVE(smaa, smaa_quality, medium) + #define SMAA_PRESET_MEDIUM +#elif ENUM_V_ACTIVE(smaa, smaa_quality, high) + #define SMAA_PRESET_HIGH +#elif ENUM_V_ACTIVE(smaa, smaa_quality, ultra) + #define SMAA_PRESET_ULTRA +#else + #error Unkown smaa quality value! +#endif + + +// Include both Pixel and Vertex shader, because we do the vertex shader logic +// in the pixel shader. +#define SMAA_INCLUDE_VS 1 +#define SMAA_INCLUDE_PS 1 +#define SMAA_DECODE_VELOCITY(_sample) error, custom resolve pass + +vec3 SMAA_GET_COLOR(vec3 _color) { + return _color; +} + +vec4 SMAA_GET_COLOR(vec4 _color) { + return _color; +} + +// Optionally enable smaa predication +// #define SMAA_PREDICATION 1 +// #define SMAA_PREDICATION_SCALE 3.0 +// #define SMAA_PREDICATION_THRESHOLD 0.00001 + +// SMAA defines its own saturate, make sure we don't run into conflicts +#ifdef saturate + #undef saturate +#endif + +// Include the actual smaa header +#pragma include "SMAA.inc.glsl" diff --git a/rpplugins/smaa/smaa_stage.py b/rpplugins/smaa/smaa_stage.py new file mode 100644 index 0000000..e0b60ba --- /dev/null +++ b/rpplugins/smaa/smaa_stage.py @@ -0,0 +1,106 @@ +""" + +RenderPipeline + +Copyright (c) 2014-2016 tobspr + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. + +""" +from __future__ import division + +from panda3d.core import PTAInt + +from rpcore.render_stage import RenderStage + + +class SMAAStage(RenderStage): + + """ This stage does the actual SMAA """ + + required_inputs = [] + + def __init__(self, pipeline): + RenderStage.__init__(self, pipeline) + self.area_tex = None + self.search_tex = None + self.use_reprojection = True + self._jitter_index = PTAInt.empty_array(1) + + def set_jitter_index(self, idx): + """ Sets the current jitter index """ + self._jitter_index[0] = idx + + @property + def required_pipes(self): + pipes = ["ShadedScene", "GBuffer", "CombinedVelocity"] + if self.use_reprojection: + pipes.append("PreviousFrame::SMAAPostResolve") + return pipes + + @property + def produced_pipes(self): + if self.use_reprojection: + return { + "ShadedScene": self.resolve_target.color_tex, + "SMAAPostResolve": self.resolve_target.color_tex + } + else: + return {"ShadedScene": self.neighbor_target.color_tex} + + def create(self): + # Edge detection + self.edge_target = self.create_target("EdgeDetection") + self.edge_target.add_color_attachment() + self.edge_target.prepare_buffer() + self.edge_target.set_clear_color(0, 0, 0, 0) + + # Weight blending + self.blend_target = self.create_target("BlendWeights") + self.blend_target.add_color_attachment(alpha=True) + self.blend_target.prepare_buffer() + + self.blend_target.set_shader_inputs( + EdgeTex=self.edge_target.color_tex, + AreaTex=self.area_tex, + SearchTex=self.search_tex, + jitterIndex=self._jitter_index) + + # Neighbor blending + self.neighbor_target = self.create_target("NeighborBlending") + self.neighbor_target.add_color_attachment(bits=16) + self.neighbor_target.prepare_buffer() + self.neighbor_target.set_shader_input("BlendTex", self.blend_target.color_tex) + + # Resolving + if self.use_reprojection: + self.resolve_target = self.create_target("Resolve") + self.resolve_target.add_color_attachment(bits=16) + self.resolve_target.prepare_buffer() + self.resolve_target.set_shader_inputs( + jitterIndex=self._jitter_index, + # Set initial textures + CurrentTex=self.neighbor_target.color_tex) + + def reload_shaders(self): + self.edge_target.shader = self.load_plugin_shader("edge_detection.frag.glsl") + self.blend_target.shader = self.load_plugin_shader("blending_weights.frag.glsl") + self.neighbor_target.shader = self.load_plugin_shader("neighborhood_blending.frag.glsl") + if self.use_reprojection: + self.resolve_target.shader = self.load_plugin_shader("resolve_smaa.frag.glsl") diff --git a/rpplugins/ssr/__init__.py b/rpplugins/ssr/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/rpplugins/ssr/config.yaml b/rpplugins/ssr/config.yaml new file mode 100644 index 0000000..b306cfe --- /dev/null +++ b/rpplugins/ssr/config.yaml @@ -0,0 +1,103 @@ + +settings: !!omap + + + - effect_scale: + type: float + range: [0.0, 1.0] + default: 1.0 + label: SSR Strength + shader_runtime: true + description: > + Controls the strength of the reflections, lower values will reduce + the influence of ssr, increasing the influence of other plugins + like environment probes + + - trace_steps: + type: int + range: [4, 512] + default: 64 + label: Trace Steps + shader_runtime: true + description: > + Amount of trace steps. A higher amount will lead to less missed + details, although it will also be more computationally expensive. + + - history_length: + type: int + range: [1, 32] + default: 16 + shader_runtime: true + label: History Length + description: > + History buffer size. This controls how long pixels will stay + in the history buffer, greater values lead to smoother results + but also might produce more artifacts. + + - abort_on_object_infront: + type: bool + default: true + label: Abort on invalid hit + shader_runtime: true + description: > + Aborts the trace when an object is found in front of the ray. + This might lead to artifacts on floating objects, but might + also improve the quality. + + - intial_bias: + type: float + range: [0.05, 10.0] + default: 0.1 + label: Initial ray bias + shader_runtime: true + description: > + Offsets the ray a bit in the tracing direction to avoid self- + intersection. A too small value will cause artifacts due to self + intersection, a too high value will miss details near to objects. + + - hit_tolerance: + type: float + range: [0.05, 10.0] + default: 0.1 + label: Hit tolerance + shader_runtime: true + description: > + Higher values will produce more intersections, but also produce + false positives. If you set this value too low, artifacts and noise + will occur. + + - roughness_fade: + type: float + range: [0.1, 1.0] + default: 0.72 + shader_runtime: true + label: Roughness Fade + description: > + Fades out the reflections at high roughness values, so that other + solutions like environment probes have more influence. This is + to prevent noise, and controls the maximum roughness where ssr is + active. + + - skip_invalid_samples: + type: bool + default: false + shader_runtime: true + label: Skip Invalid Pixels + description: > + Whether to skip pixels which could not successfully be reprojected + from the last frames color texture. This affects the effect when + moving. Setting this to true will produce more accurate but also + more noisy results. Setting this to false might produce artifacts. + + - border_fade: + type: float + range: [0.001, 1.0] + default: 0.005 + shader_runtime: true + label: Border Fade + description: > + Fades out the effect at the screen borders to avoid rough transitions. + A value of 0.0 means no transitions while a value of 1.0 means a + very smooth transition. + +daytime_settings: diff --git a/rpplugins/ssr/plugin.py b/rpplugins/ssr/plugin.py new file mode 100644 index 0000000..35f3ee8 --- /dev/null +++ b/rpplugins/ssr/plugin.py @@ -0,0 +1,50 @@ +""" + +RenderPipeline + +Copyright (c) 2014-2016 tobspr + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. + +""" + +from rpcore.pluginbase.base_plugin import BasePlugin + +from .ssr_stage import SSRStage + + +class Plugin(BasePlugin): + + name = "Screen Space Reflections" + author = "tobspr " + description = ("This plugin adds support for stochastik screen space reflections " + "and is still very experimental!") + version = "beta (!)" + + def on_stage_setup(self): + self.ssr_stage = self.create_stage(SSRStage) + + if self.is_plugin_enabled("color_correction"): + self.ssr_stage.required_pipes.append("FuturePipe::Exposure") + + def reload_shaders(self): + BasePlugin.reload_shaders(self) + + # Also update the ambient stage + self._pipeline.stage_mgr.get_stage("AmbientStage").reload_shaders() diff --git a/rpplugins/ssr/shader/reflection_velocity.frag.glsl b/rpplugins/ssr/shader/reflection_velocity.frag.glsl new file mode 100644 index 0000000..29a6348 --- /dev/null +++ b/rpplugins/ssr/shader/reflection_velocity.frag.glsl @@ -0,0 +1,92 @@ +/** + * + * RenderPipeline + * + * Copyright (c) 2014-2016 tobspr + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + */ + +#version 430 + +// Copies the reflection velocity vector + +#define USE_GBUFFER_EXTENSIONS +#pragma include "render_pipeline_base.inc.glsl" +#pragma include "includes/color_spaces.inc.glsl" +#pragma include "includes/gbuffer.inc.glsl" +#pragma include "includes/transforms.inc.glsl" + +uniform sampler2D TraceResult; +out vec2 velocity; + +void main() { + vec2 texcoord = get_texcoord(); + + // Get bilateral start coordinates + ivec2 coord = ivec2(gl_FragCoord.xy); + ivec2 bil_start_coord = get_bilateral_coord(coord); + float mid_depth = get_depth_at(texcoord); + + // Find the position of the closest fragment + const int kernel_size = 0; + vec2 best_result = vec2(0); + float best_score = 0.0; + + for (int i = -kernel_size; i < 2 + kernel_size; ++i) { + for (int j = -kernel_size; j < 2 + kernel_size; ++j) { + + ivec2 source_coord = bil_start_coord + ivec2(i, j); + ivec2 screen_coord = source_coord * 2; + + vec2 trace_result = texelFetch(TraceResult, source_coord, 0).xy; + float trace_depth = get_depth_at(screen_coord); + float trace_score = max(0.0, 1.0 - 10.0 * abs(trace_depth - mid_depth)); + + // Weight the sample, so that depths closer to the viewer have a greater weight. + // Also scale by the fade factor to make sure a sample is present + trace_score = (1 - trace_depth) * (trace_result.x > 1e-5 ? 1.0 : 0.0); + + if (trace_score > best_score) { + best_result = trace_result; + best_score = trace_score; + } + } + } + + // In case no sample was found, fall back to the current pixels coordinate + if (length_squared(best_result) < 1e-4) { + best_result = texcoord; + } + + best_result = truncate_coordinate(best_result); // xxx + + // Find depth of intersection + float intersection_depth = get_depth_at(best_result); + + // Reconstruct last frame texcoord + vec2 film_offset_bias = MainSceneData.current_film_offset * vec2(1.0, 1.0 / ASPECT_RATIO); + vec3 pos = calculate_surface_pos(intersection_depth, texcoord - film_offset_bias); + vec4 last_proj = MainSceneData.last_view_proj_mat_no_jitter * vec4(pos, 1); + vec2 last_coord = fma(last_proj.xy / last_proj.w, vec2(0.5), vec2(0.5)); + + // Compute velocity + velocity = last_coord - texcoord; +} diff --git a/rpplugins/ssr/shader/reproject_lighting.frag.glsl b/rpplugins/ssr/shader/reproject_lighting.frag.glsl new file mode 100644 index 0000000..b39c1af --- /dev/null +++ b/rpplugins/ssr/shader/reproject_lighting.frag.glsl @@ -0,0 +1,96 @@ +/** + * + * RenderPipeline + * + * Copyright (c) 2014-2016 tobspr + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + */ + +#version 430 + +// Copies the previous scene color to the first mipmap. +// Also outputs the current frame intersection depth + +#define USE_GBUFFER_EXTENSIONS +#pragma include "render_pipeline_base.inc.glsl" +#pragma include "includes/color_spaces.inc.glsl" +#pragma include "includes/gbuffer.inc.glsl" +#pragma include "includes/transforms.inc.glsl" + +uniform sampler2D CombinedVelocity; +uniform sampler2D Previous_PostAmbientScene; +uniform sampler2D Previous_SceneDepth; + +#if HAVE_PLUGIN(color_correction) + uniform samplerBuffer Exposure; +#endif + +out vec4 result; + +void main() { + vec2 texcoord = get_texcoord(); + vec2 velocity = textureLod(CombinedVelocity, texcoord, 0).xy; + vec2 last_coord = texcoord + velocity; + + // Out of screen, can early out + if (out_of_screen(last_coord)) { + result = vec4(0); + return; + } + + float fade = 1.0; + + // Check if reprojected position matches + float curr_depth = get_depth_at(texcoord); + + #if GET_SETTING(ssr, skip_invalid_samples) + // Skip samples which are invalid due to a position change or due to being + // occluded in the last frame. + + // TODO: Should probably use the 3x3 AABB for this, but might be too + // performance heavy. I think this should work out well. + vec3 curr_pos = calculate_surface_pos(curr_depth, texcoord); + float last_depth = textureLod(Previous_SceneDepth, last_coord, 0).x; + + vec3 last_pos = calculate_surface_pos(last_depth, last_coord, + MainSceneData.last_inv_view_proj_mat_no_jitter); + + if (distance(curr_pos, last_pos) > 0.9) { + // fade = 0.0; + } + #endif + + vec3 intersected_color = textureLod(Previous_PostAmbientScene, last_coord, 0).xyz; + + #if HAVE_PLUGIN(color_correction) + // Prevent super bright spots by clamping to a reasonable high color. + // Otherwise very bright highlights lead to artifacts. + // Since this heavily depends on the scene brightness, we base this on + // the exposure. Basically the color is only allowed to be twice as bright + // as the average screen brightness. + + float current_ev = 1.0 / texelFetch(Exposure, 0).x; + intersected_color = clamp(intersected_color, 0.0, 2 * current_ev); + #endif + + // Finally store the result in the mip-chain + result = vec4(intersected_color, 1) * fade; +} diff --git a/rpplugins/ssr/shader/resolve_ssr.frag.glsl b/rpplugins/ssr/shader/resolve_ssr.frag.glsl new file mode 100644 index 0000000..900484a --- /dev/null +++ b/rpplugins/ssr/shader/resolve_ssr.frag.glsl @@ -0,0 +1,55 @@ +/** + * + * RenderPipeline + * + * Copyright (c) 2014-2016 tobspr + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + */ + +#version 430 + +#define USE_GBUFFER_EXTENSIONS +#pragma include "render_pipeline_base.inc.glsl" +#pragma include "includes/transforms.inc.glsl" +#pragma include "includes/gbuffer.inc.glsl" + +uniform sampler2D CurrentTex; +uniform sampler2D VelocityTex; +uniform sampler2D Previous_SSRSpecular; + +#define RS_MAX_CLIP_DIST 5.0 +#define RS_DISTANCE_SCALE 0.2 +#define RS_KEEP_GOOD_DURATION float(GET_SETTING(ssr, history_length)) +#define RS_KEEP_BAD_DURATION float(GET_SETTING(ssr, history_length)) +#define RS_AABB_SIZE 1.5 +#define RS_USE_SMOOTH_TECHNIQUE 1 + + +#pragma include "includes/temporal_resolve.inc.glsl" + +out vec4 result; + +void main() { + vec2 texcoord = get_texcoord(); + vec2 velocity = textureLod(VelocityTex, texcoord, 0).xy; + vec2 last_coord = texcoord + velocity; + result = resolve_temporal(CurrentTex, Previous_SSRSpecular, texcoord, last_coord); +} diff --git a/rpplugins/ssr/shader/ssr_trace.frag.glsl b/rpplugins/ssr/shader/ssr_trace.frag.glsl new file mode 100644 index 0000000..f67629c --- /dev/null +++ b/rpplugins/ssr/shader/ssr_trace.frag.glsl @@ -0,0 +1,244 @@ +/** + * + * RenderPipeline + * + * Copyright (c) 2014-2016 tobspr + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + */ + +#version 430 + +#define USE_GBUFFER_EXTENSIONS +#pragma include "render_pipeline_base.inc.glsl" +#pragma include "includes/gbuffer.inc.glsl" +#pragma include "includes/noise.inc.glsl" +#pragma include "includes/brdf.inc.glsl" +#pragma include "includes/transforms.inc.glsl" +#pragma include "includes/importance_sampling.inc.glsl" + +uniform sampler2D DownscaledDepth; + +out vec2 result; + +#define USE_LINEAR_DEPTH 0 +#define NUM_RAYDIR_RETRIES 3 + +const int num_steps = GET_SETTING(ssr, trace_steps); +const float hit_tolerance_ws = 0.00001 * GET_SETTING(ssr, hit_tolerance); +const float hit_tolerance_backface = 0.00001; + +bool point_between_planes(float z, float z_a, float z_b, float trace_length, out bool hit_factor) { + + // This traces correct, but looks weird because gaps are not filled + // return z + hit_tolerance_ws >= min(z_a, z_b) - 0.00015 && z - hit_tolerance_ws <= max(z_a, z_b); + + hit_factor = false; + + // This traces "incorrect", but looks better because gaps are getting filled then + if (z - hit_tolerance_ws * trace_length <= max(z_a, z_b)) { + + #if GET_SETTING(ssr, abort_on_object_infront) + hit_factor = (z + hit_tolerance_ws * trace_length) >= + min(z_a, z_b) - hit_tolerance_backface; + #else + hit_factor = true; + #endif + + return true; + } + + return false; +} + + +void main() +{ + ivec2 coord = ivec2(gl_FragCoord.xy); + vec2 texcoord = get_half_texcoord(); + + vec3 normal_vs = get_view_normal(texcoord); + Material m = unpack_material(GBuffer, texcoord); + normal_vs = world_normal_to_view(m.normal); + + vec3 ray_start_vs = get_view_pos_at(texcoord); + float pixeldist = distance(m.position, MainSceneData.camera_pos); + + // Skip skybox and distant pixels + if (pixeldist > 3000) { + result = vec2(0); + return; + } + + // Important: For clearcoat we trace the outer layer (with low roughness) + // instead of the high roughness layer + float roughness = get_effective_roughness(m); + + // Skip pixels with too high roughness + if (roughness > GET_SETTING(ssr, roughness_fade)) { + result = vec2(0); + return; + } + + + // Get ray start + vec3 view_dir = normalize(ray_start_vs); + vec3 ray_dir = normalize(reflect(view_dir, normal_vs)); + + // Get tangent and binormal + vec3 tangent, binormal; + find_arbitrary_tangent(ray_dir, tangent, binormal); + + vec3 importance_ray_dir = vec3(0); + + + // Generate ray directions until we find a value which is valid + int retry = 0; + for (;retry < NUM_RAYDIR_RETRIES; ++retry) { + + vec2 seed = texcoord + 1.3123 * retry + 0.176445 * (MainSceneData.frame_index % 32); + + // Get random sequence, should probably use halton or so + vec2 xi = clamp(abs(rand_rgb(seed).xy), vec2(0.01), vec2(0.99)); + + // Clamp brdf tail, see frostbite slides for details + const float brdf_bias = 0.8; + xi.y = mix(xi.y, 0.0, brdf_bias); + + // Get importance sampled directory + vec3 rho = importance_sample_ggx(xi, clamp(sqrt(roughness), 0.0001, 1.0)); + importance_ray_dir = normalize(1e-5 + rho.x * tangent + rho.y * binormal + rho.z * ray_dir); + + // If the ray dir is fine, abort, otherwise continue + if (dot(importance_ray_dir, normal_vs) > 0.005) { + break; + } + } + + // Still didn't find a good ray dir + if (retry >= NUM_RAYDIR_RETRIES - 1) { + result = vec2(0); + return; + } + + ray_dir = importance_ray_dir; + + // Ray not in view + if (dot(ray_dir, view_dir) < 1e-5) { + result = vec2(0); + return; + } + + float max_ray_len = 1.0 * pixeldist; + + // Clip ray to near plane + #if 1 + float ray_len = ((ray_start_vs.z + ray_dir.z * max_ray_len) > CAMERA_NEAR) ? + (CAMERA_NEAR - ray_start_vs.z) / ray_dir.z : + max_ray_len; + #else + float ray_len = max_ray_len; + #endif + + // Convert start and end pos from view to screen space + vec3 ray_start_screen = view_to_screen(ray_start_vs); + vec3 ray_end_screen = view_to_screen(ray_start_vs + ray_len * ray_dir); + + vec3 ray_pos = ray_start_screen; + vec3 ray_dir_screen = ray_end_screen - ray_start_screen; + + // Make sure the ray does not leave the screen + float scale_max_x = min(1, 0.99 * (1.0 - ray_start_screen.x) / max(1e-5, ray_dir_screen.x)); + float scale_max_y = min(1, 0.99 * (1.0 - ray_start_screen.y) / max(1e-5, ray_dir_screen.y)); + float scale_min_x = min(1, 0.99 * ray_start_screen.x / max(1e-5, -ray_dir_screen.x)); + float scale_min_y = min(1, 0.99 * ray_start_screen.y / max(1e-5, -ray_dir_screen.y)); + ray_dir_screen *= min(scale_max_x, scale_max_y); + ray_dir_screen *= min(scale_min_x, scale_min_y); + + #if USE_LINEAR_DEPTH + // Linearize depth so we can interpolate it + ray_start_screen.z = get_linear_z_from_z(ray_start_screen.z); + ray_end_screen.z = get_linear_z_from_z(ray_end_screen.z); + #endif + + vec3 ray_step = (ray_end_screen - ray_start_screen) / num_steps; + + float distance_scale = 1.0 + 0.00001 * pixeldist; + + // Initial ray bias to avoid self intersection + // ray_pos += (15.0 + roughness * 0.0) * ray_step * float(num_steps) / 512.0 / clamp(dot(normal_vs, -view_dir), 0.1, 1.0) * GET_SETTING(ssr, intial_bias) * distance_scale; + + vec2 intersection = vec2(-1); + + // Jitter ray position to make sure we catch all details + float jitter = abs(rand(ivec2(gl_FragCoord.xy) % 8 + + (MainSceneData.frame_index % GET_SETTING(ssr, history_length)) * 0.1)); + + // Rough sourfaces need more jitter + jitter *= max(0.5, m.roughness); + + ray_pos += jitter * ray_step; + + int i = 0; + float intersection_weight = 0.0; + bool hit_factor = false; + + for (i = 1; i < num_steps; ++i) { + ray_pos += ray_step; + + // Current coordinate is in the mid of two samples, not at the end, so + // substract half of a step + vec2 curr_coord = ray_pos.xy - 0.5 * ray_step.xy; + + + // Increase ray bias as we advance the ray + float trace_len = GET_SETTING(ssr, intial_bias) * 10.0 + + 100.0 * distance_squared(curr_coord, texcoord); + trace_len *= 1.0 + 1.0 * roughness; + + // Check for intersection + #if USE_LINEAR_DEPTH + float depth_sample = textureLod(DownscaledDepth, curr_coord, 0).x; + #else + float depth_sample = textureLod(GBuffer.Depth, curr_coord, 0).x; + #endif + + if (point_between_planes(depth_sample, ray_pos.z, + ray_pos.z - ray_step.z, trace_len, hit_factor)) { + intersection = curr_coord; + break; + } + } + + // Make sure we hit exactly one pixel + intersection = truncate_coordinate(intersection); + + // Check if we hit something + if (min(intersection.x, intersection.y) <= 0.0 || out_of_screen(intersection)) { + result = vec2(0); + return; + } + + if (!hit_factor) { + result = vec2(0); + return; + } + result = intersection; +} diff --git a/rpplugins/ssr/shader/upscale_bilateral_brdf.frag.glsl b/rpplugins/ssr/shader/upscale_bilateral_brdf.frag.glsl new file mode 100644 index 0000000..a383c33 --- /dev/null +++ b/rpplugins/ssr/shader/upscale_bilateral_brdf.frag.glsl @@ -0,0 +1,138 @@ +/** + * + * RenderPipeline + * + * Copyright (c) 2014-2016 tobspr + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + */ + +#version 430 + +#pragma optionNV (unroll all) + +#pragma include "render_pipeline_base.inc.glsl" +#pragma include "includes/gbuffer.inc.glsl" +#pragma include "includes/brdf.inc.glsl" +#pragma include "includes/color_spaces.inc.glsl" + +layout(location = 0) out vec4 result; + +uniform sampler2D SourceTex; +uniform sampler2D LastFrameColor; +uniform GBufferData GBuffer; + +// Fades out a coordinate on the screen edges +float get_border_fade(vec2 coord) { + const float border_fade = max(1e-5, GET_SETTING(ssr, border_fade)); + float fade = 1.0; + fade *= saturate(coord.x / border_fade) * saturate(coord.y / border_fade); + fade *= saturate((1 - coord.x) / border_fade) * saturate((1 - coord.y) / border_fade); + return fade; +} + +void main() { + + // Get bilateral sample coordinates + ivec2 coord = ivec2(gl_FragCoord.xy); + ivec2 bil_start_coord = get_bilateral_coord(coord); + vec2 texcoord = ((bil_start_coord * 2) + 0.5) / SCREEN_SIZE; + + // Get current pixel data + float mid_depth = get_gbuffer_depth(GBuffer, coord); + vec3 ws_normal = get_gbuffer_normal(GBuffer, coord); + + Material m = unpack_material(GBuffer, texcoord); + + // Early out on skybox + if (is_skybox(m.position)) { + result = vec4(0); + return; + } + + const float max_depth_diff = 0.002; + + float weights = 0.0; + vec4 accum = vec4(0); + + // Controls how many other pixels should be taken into account, besides + // of the 4 direct neighbors. + const int search_radius = 0; + + vec3 view_vector = normalize(MainSceneData.camera_pos - m.position); + vec4 avg_position = vec4(0); + + // Get reflection directory + vec3 reflected_dir = get_reflection_vector(m, -view_vector); + float roughness = get_effective_roughness(m); + + // Accumulate all samples + for (int x = -search_radius; x < 2 + search_radius; ++x) { + for (int y = -search_radius; y < 2 + search_radius; ++y) { + + // Get sample coordinate + ivec2 source_coord = bil_start_coord + ivec2(x, y); + ivec2 screen_coord = source_coord * 2; + vec2 intersection = texelFetch(SourceTex, source_coord, 0).xy; + float intersection_weight = intersection.x > 1e-5 ? 1 : 0.0; + + // Skip empty samples + if (intersection_weight < 0.5) { + weights += 1.0; + continue; + } + + float sample_depth = get_gbuffer_depth(GBuffer, screen_coord); + + // Find depth of intersection pixel + float intersection_depth = get_gbuffer_depth(GBuffer, intersection); + + // Get world space position of intersection pixel + vec3 ws_intersection = calculate_surface_pos(intersection_depth, intersection); + + // Find distance and vector to intersection based on the pixels position + float distance_to_intersection = 1e-9 + distance(ws_intersection, m.position); + vec3 l = (ws_intersection - m.position) / distance_to_intersection; + + // Get the halfway vector + vec3 h = normalize(view_vector + l); + float NxH = max(1e-5, dot(m.normal, h)); + + float weight = clamp(brdf_distribution_ggx(NxH, 0.05 + sqrt(roughness)), 0.0, 1.0); + weight *= 1 - saturate(abs(mid_depth - sample_depth) / max_depth_diff); + vec4 color_sample = textureLod(LastFrameColor, intersection, 0); + + // Fade out samples at the screen border + // XXX: Do we really have to this per sample? + color_sample *= get_border_fade(intersection); + + accum += color_sample * weight; + weights += weight; + } + } + + if (weights < 0.4) { + accum = vec4(0); + } else { + accum /= weights; + } + + result = accum; +} diff --git a/rpplugins/ssr/ssr_stage.py b/rpplugins/ssr/ssr_stage.py new file mode 100644 index 0000000..90b702c --- /dev/null +++ b/rpplugins/ssr/ssr_stage.py @@ -0,0 +1,90 @@ +""" + +RenderPipeline + +Copyright (c) 2014-2016 tobspr + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. + +""" + +from panda3d.core import SamplerState + +from rpcore.render_stage import RenderStage +from rpcore.stages.ambient_stage import AmbientStage + + +class SSRStage(RenderStage): + + """ This stage does the SSR pass """ + + required_inputs = [] + required_pipes = ["ShadedScene", "CombinedVelocity", "GBuffer", + "DownscaledDepth", "PreviousFrame::PostAmbientScene", + "PreviousFrame::SSRSpecular", "PreviousFrame::SceneDepth"] + + @property + def produced_pipes(self): + return {"SSRSpecular": self.target_resolve.color_tex} + + def create(self): + self.target = self.create_target("ComputeSSR") + self.target.size = -2 + self.target.add_color_attachment(bits=(16, 16, 0, 0)) + self.target.prepare_buffer() + + self.target.color_tex.set_minfilter(SamplerState.FT_nearest) + self.target.color_tex.set_magfilter(SamplerState.FT_nearest) + + self.target_velocity = self.create_target("ReflectionVelocity") + self.target_velocity.add_color_attachment(bits=(16, 16, 0, 0)) + self.target_velocity.prepare_buffer() + self.target_velocity.set_shader_input("TraceResult", self.target.color_tex) + + self.target_reproject_lighting = self.create_target("CopyLighting") + self.target_reproject_lighting.add_color_attachment(bits=16, alpha=True) + self.target_reproject_lighting.prepare_buffer() + + self.target_upscale = self.create_target("UpscaleSSR") + self.target_upscale.add_color_attachment(bits=16, alpha=True) + self.target_upscale.prepare_buffer() + self.target_upscale.set_shader_inputs( + SourceTex=self.target.color_tex, + LastFrameColor=self.target_reproject_lighting.color_tex) + + self.target_resolve = self.create_target("ResolveSSR") + self.target_resolve.add_color_attachment(bits=16, alpha=True) + self.target_resolve.prepare_buffer() + self.target_resolve.set_shader_inputs( + CurrentTex=self.target_upscale.color_tex, + VelocityTex=self.target_velocity.color_tex) + + AmbientStage.required_pipes.append("SSRSpecular") + + def reload_shaders(self): + self.target.shader = self.load_plugin_shader( + "ssr_trace.frag.glsl") + self.target_velocity.shader = self.load_plugin_shader( + "reflection_velocity.frag.glsl") + self.target_reproject_lighting.shader = self.load_plugin_shader( + "reproject_lighting.frag.glsl") + self.target_upscale.shader = self.load_plugin_shader( + "upscale_bilateral_brdf.frag.glsl") + self.target_resolve.shader = self.load_plugin_shader( + "resolve_ssr.frag.glsl") diff --git a/rpplugins/volumetrics/__init__.py b/rpplugins/volumetrics/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/rpplugins/volumetrics/config.yaml b/rpplugins/volumetrics/config.yaml new file mode 100644 index 0000000..defda34 --- /dev/null +++ b/rpplugins/volumetrics/config.yaml @@ -0,0 +1,114 @@ + +settings: !!omap + + - enable_volumetric_shadows: + type: bool + default: true + label: Volumetric Shadows + description: > + Whether to enable volumetric shadows + + - volumetric_shadow_intensity: + display_if: { enable_volumetric_shadows: true } + type: float + range: [0.1, 10.0] + default: 1.0 + shader_runtime: true + label: Intensity + description: > + Controls the intensity/density of the volumetric shadows + + - volumetric_shadow_brightness: + display_if: { enable_volumetric_shadows: true } + type: float + range: [0.1, 10.0] + default: 1.0 + shader_runtime: true + label: Brightness + description: > + Controls the brightness of the volumetric shadows. + + - volumetric_shadow_pow: + display_if: { enable_volumetric_shadows: true } + type: float + range: [0.25, 4.0] + default: 1.0 + shader_runtime: true + label: Detail + description: > + Decreases/Increases the detail of the volumetric shadows. The shadow is computed as pow(shadow, detail). + + - volumetric_max_distance: + display_if: { enable_volumetric_shadows: true } + type: float + range: [1.0, 500.0] + default: 150.0 + shader_runtime: true + label: Maximum distance + description: > + Maximum distance until volumetric shadows is computed, after that + distance no "godrays" are visible. Lower values provide more details. + + - volumetric_shadow_fadein_distance: + display_if: { enable_volumetric_shadows: true } + type: float + range: [1.0, 100.0] + default: 15.0 + shader_runtime: true + label: Fade-In Distance + description: > + Volumetric shadows are faded out near to the camera, this controls + the distance at which this happens. + + + - volumetric_num_steps: + display_if: { enable_volumetric_shadows: true} + type: int + range: [4, 128] + default: 32 + shader_runtime: true + label: Sample count + description: > + Controls how many samples to take along the path, higher values require + more performance but produce more detailed results. + + +daytime_settings: !!omap + + - fog_ramp_size: + type: scalar + unit: meter + range: [0.5, 30000.0] + default: 2000 + label: Fog Ramp + logarithmic_factor: 2.0 + description: > + Size of the transition from no fog to fog in world space units. + Higher values produce a smoother transition from no fog to fog, + while lower values will produce a more sharp transition. + + - fog_color: + type: color + default: [127, 127, 127] + label: Fog Color + description: > + Color of the fog, usually should match the atmosphere color + + - fog_brightness: + type: scalar + unit: klux + range: [0.0, 20.0] + logarithmic_factor: 2.0 + default: 12.0 + label: Fog Brightness + description: > + Controls the brightness of the fog, should match the sun intensity. + + - fog_intensity: + type: scalar + unit: none + range: [0.01, 50.0] + default: 30.0 + label: Fog Intensity + description: > + Controls the intensity/amount of the volumetric height fog. diff --git a/rpplugins/volumetrics/plugin.py b/rpplugins/volumetrics/plugin.py new file mode 100644 index 0000000..cf856a9 --- /dev/null +++ b/rpplugins/volumetrics/plugin.py @@ -0,0 +1,47 @@ +""" + +RenderPipeline + +Copyright (c) 2014-2016 tobspr + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. + +""" + +from rpcore.pluginbase.base_plugin import BasePlugin +from .volumetrics_stage import VolumetricsStage + + +class Plugin(BasePlugin): + + name = "Volumetric Lighting" + author = "tobspr " + description = ("This plugins adds support for volumetric lighting") + version = "0.1 alpha (!)" + + required_plugins = ("pssm",) + + def on_stage_setup(self): + self.stage = self.create_stage(VolumetricsStage) + self.stage.enable_volumetric_shadows = self.get_setting("enable_volumetric_shadows") + + if self.get_plugin_instance("pssm").get_setting("use_pcf"): + self.stage.required_pipes.append("PSSMShadowAtlasPCF") + else: + self.stage.required_pipes.append("PSSMShadowAtlas") diff --git a/rpplugins/volumetrics/shader/apply_volumetrics.frag.glsl b/rpplugins/volumetrics/shader/apply_volumetrics.frag.glsl new file mode 100644 index 0000000..e3f0db0 --- /dev/null +++ b/rpplugins/volumetrics/shader/apply_volumetrics.frag.glsl @@ -0,0 +1,83 @@ +/** + * + * RenderPipeline + * + * Copyright (c) 2014-2016 tobspr + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + */ + +#version 430 + +#define USE_TIME_OF_DAY 1 +#define USE_GBUFFER_EXTENSIONS +#pragma include "render_pipeline_base.inc.glsl" +#pragma include "includes/gbuffer.inc.glsl" + +uniform sampler2D ShadedScene; + +#if GET_SETTING(volumetrics, enable_volumetric_shadows) + uniform sampler2D VolumetricsTex; +#endif + +out vec3 result; + +float compute_fog(vec3 ray_start, vec3 ray_end) +{ + float dist = length(ray_start - ray_end); + vec3 ray_dir = (ray_start - ray_end) / dist; + const float c = 1.0 * TimeOfDay.volumetrics.fog_intensity; + const float b = 0.2 / TimeOfDay.volumetrics.fog_ramp_size; + ray_dir.z = -ray_dir.z; + if (abs(ray_dir.z) < 1e-2) + ray_dir.z = 1e-2; + return saturate(c * exp(-ray_start.z * b) * (1.0 - exp(-dist * ray_dir.z * b)) / ray_dir.z); +} + +void main() { + vec2 texcoord = get_texcoord(); + + float depth = get_depth_at(texcoord); + vec3 surface_pos = calculate_surface_pos(depth, texcoord); + + #if GET_SETTING(volumetrics, enable_volumetric_shadows) + vec4 volumetrics = textureLod(VolumetricsTex, texcoord, 0); + #else + vec4 volumetrics = vec4(0); + #endif + + vec3 scene_color = textureLod(ShadedScene, texcoord, 0).xyz; + + + vec3 fog_color = TimeOfDay.volumetrics.fog_color * 4.5 * TimeOfDay.volumetrics.fog_brightness * TimeOfDay.scattering.sun_intensity; + + vec3 ray_dir = normalize(MainSceneData.camera_pos - surface_pos); + + float fog_weight = compute_fog(MainSceneData.camera_pos, surface_pos); + + vec3 merged_color = scene_color; + #if !DEBUG_MODE + merged_color = mix(scene_color, fog_color, fog_weight); + merged_color = mix(merged_color, volumetrics.xyz, volumetrics.w); + #endif + + + result = merged_color; +} diff --git a/rpplugins/volumetrics/shader/compute_volumetric_shadows.frag.glsl b/rpplugins/volumetrics/shader/compute_volumetric_shadows.frag.glsl new file mode 100644 index 0000000..1c95388 --- /dev/null +++ b/rpplugins/volumetrics/shader/compute_volumetric_shadows.frag.glsl @@ -0,0 +1,134 @@ +/** + * + * RenderPipeline + * + * Copyright (c) 2014-2016 tobspr + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + */ + +#version 430 + +#define USE_TIME_OF_DAY 1 +#define USE_GBUFFER_EXTENSIONS +#pragma include "render_pipeline_base.inc.glsl" +#pragma include "includes/gbuffer.inc.glsl" +#pragma include "includes/shadows.inc.glsl" +#pragma include "includes/noise.inc.glsl" + + +#if GET_SETTING(pssm, use_pcf) + uniform sampler2DShadow PSSMShadowAtlasPCF; +#else + uniform sampler2D PSSMShadowAtlas; +#endif + + +#pragma include "/$$rp/rpplugins/pssm/shader/filter_pssm.inc.glsl" + +uniform sampler2D ShadedScene; + +uniform sampler2D PSSMShadowAtlas; +uniform mat4 pssm_mvps[GET_SETTING(pssm, split_count)]; +uniform vec2 pssm_nearfar[GET_SETTING(pssm, split_count)]; + +out vec4 result; + + +void main() { + + #if DEBUG_MODE + result = vec4(0); + return; + #endif + + vec2 texcoord = get_half_texcoord(); + + vec3 start_pos = MainSceneData.camera_pos; + vec3 end_pos = get_gbuffer_position(GBuffer, texcoord); + + // Looks weird + // if (is_skybox(end_pos, MainSceneData.camera_pos)) + // { + // result = vec4(0); + // return; + // } + + float max_distance = GET_SETTING(volumetrics, volumetric_max_distance); + + vec3 step_vector = end_pos - start_pos; + if (length(step_vector) > max_distance) { + step_vector = normalize(step_vector) * max_distance; + } + + float total_distance = length(step_vector); + + end_pos = start_pos + step_vector; + + float jitter = rand(ivec2(gl_FragCoord.xy) % 2); + jitter = 0; + + const int num_steps = GET_SETTING(volumetrics, volumetric_num_steps); + vec3 step_offs = step_vector / num_steps; + + float volumetrics = 0.0; + + vec3 sun_vector = get_sun_vector(); + vec3 sun_color = get_sun_color() * get_sun_color_scale(sun_vector); + + const float distance_fade = GET_SETTING(volumetrics, volumetric_shadow_fadein_distance); + + int start_split = 0; + const float fixed_bias = 0.0005; + + for (int i = 0; i < num_steps; ++i) { + vec3 pos = start_pos + (i + jitter) * step_offs; + vec3 proj = project(pssm_mvps[start_split], pos); + + // Check if out of split + while (out_of_screen(proj.xy) && start_split < GET_SETTING(pssm, split_count) - 1) { + ++start_split; + proj = project(pssm_mvps[start_split], pos); + } + + if (out_of_screen(proj.xy)) { + // Out of pssm range + break; + } + + float sun_influence = get_shadow(get_split_coord(proj.xy, start_split), proj.z - get_fixed_bias(start_split)); + + // Apply distance fade + float d = float(i) / float(num_steps) * total_distance; + volumetrics += 0.02 * sun_influence * smoothstep(0, 1, d / distance_fade) * (1 - volumetrics); + } + + + // volumetrics /= float(num_steps); + volumetrics = saturate(volumetrics); + volumetrics = pow(volumetrics, GET_SETTING(volumetrics, volumetric_shadow_pow)); + + vec3 color = sun_color * 0.5 * GET_SETTING(volumetrics, volumetric_shadow_brightness); + result = vec4(color, 0.01 * GET_SETTING(volumetrics, volumetric_shadow_intensity)) * volumetrics; + result.w = saturate(result.w); + + + +} diff --git a/rpplugins/volumetrics/volumetrics_stage.py b/rpplugins/volumetrics/volumetrics_stage.py new file mode 100644 index 0000000..d180122 --- /dev/null +++ b/rpplugins/volumetrics/volumetrics_stage.py @@ -0,0 +1,74 @@ +""" + +RenderPipeline + +Copyright (c) 2014-2016 tobspr + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. + +""" + +from panda3d.core import Vec2 +from rpcore.render_stage import RenderStage + + +class VolumetricsStage(RenderStage): + + """ This stage applies the volumetric lighting """ + + required_inputs = [] + required_pipes = ["ShadedScene", "GBuffer"] + + def __init__(self, pipeline): + RenderStage.__init__(self, pipeline) + self.enable_volumetric_shadows = False + + @property + def produced_pipes(self): + return {"ShadedScene": self.target_combine.color_tex} + + def create(self): + + if self.enable_volumetric_shadows: + self.target = self.create_target("ComputeVolumetrics") + self.target.size = -2 + self.target.add_color_attachment(bits=16, alpha=True) + self.target.prepare_buffer() + + self.target_upscale = self.create_target("Upscale") + self.target_upscale.add_color_attachment(bits=16, alpha=True) + self.target_upscale.prepare_buffer() + + self.target_upscale.set_shader_inputs( + SourceTex=self.target.color_tex, + upscaleWeights=Vec2(0.001, 0.001)) + + self.target_combine = self.create_target("CombineVolumetrics") + self.target_combine.add_color_attachment(bits=16) + self.target_combine.prepare_buffer() + + if self.enable_volumetric_shadows: + self.target_combine.set_shader_input("VolumetricsTex", self.target_upscale.color_tex) + + def reload_shaders(self): + if self.enable_volumetric_shadows: + self.target.shader = self.load_plugin_shader("compute_volumetric_shadows.frag.glsl") + self.target_upscale.shader = self.load_plugin_shader( + "/$$rp/shader/bilateral_upscale.frag.glsl") + self.target_combine.shader = self.load_plugin_shader("apply_volumetrics.frag.glsl") diff --git a/rpplugins/vxgi/__init__.py b/rpplugins/vxgi/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/rpplugins/vxgi/config.yaml b/rpplugins/vxgi/config.yaml new file mode 100644 index 0000000..2530ffe --- /dev/null +++ b/rpplugins/vxgi/config.yaml @@ -0,0 +1,48 @@ + +settings: !!omap + + - grid_resolution: + type: power_of_two + range: [32, 384] + default: 256 + label: Voxel Grid Resolution + description: > + Resolution of the voxel grid. This highly impacts performance and + memory requirements. A grid of 32^3 almost requires no memory, while + a grid of 512^3 requires about 1,0 GB of VRAM. However, the higher + the grid resolution, the more detail will be visible in the GI. + Power-of-two sizes are preferred. + + - grid_ws_size: + type: float + range: [5.0, 150.0] + default: 100.0 + label: Worlspace Grid Size + description: > + This controls the dimensions of the voxel grid. The voxel grid is + centered arround the camera, and has an equal size in each dimension. + This setting controls the size of the grid in world space. A size of + 40.0 for example makes the grid 80x80x80 world-space units big. + + - diffuse_cone_steps: + type: int + range: [2, 32] + default: 32 + shader_runtime: true + label: Diffuse Cone Steps + description: > + Amount of steps to trace for each diffuse cone. A higher amount will + lead to more color bleeding, however it also affects performance. + + - specular_cone_steps: + type: int + range: [2, 150] + default: 150 + shader_runtime: true + label: Specular Cone Steps + description: > + Amount of steps to trace for the specular cone. A higher amount will + cause reflections to range further, however it also affects performance. + + +daytime_settings: diff --git a/rpplugins/vxgi/plugin.py b/rpplugins/vxgi/plugin.py new file mode 100644 index 0000000..0bcc954 --- /dev/null +++ b/rpplugins/vxgi/plugin.py @@ -0,0 +1,97 @@ +""" + +RenderPipeline + +Copyright (c) 2014-2016 tobspr + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. + +""" + +from __future__ import division + +import collections + +from rpcore.globals import Globals +from rpcore.pluginbase.base_plugin import BasePlugin + +from .voxelization_stage import VoxelizationStage +from .vxgi_stage import VXGIStage + + +class Plugin(BasePlugin): + + name = "Voxel Global Illumination" + author = "tobspr " + description = ("Provides Global Illumination using Voxel Cone Tracing. This " + "technique is still very unoptimized and experimental!") + version = "alpha (!)" + + def on_stage_setup(self): + self._voxel_stage = self.create_stage(VoxelizationStage) + self._vxgi_stage = self.create_stage(VXGIStage) + + self._voxel_stage.voxel_resolution = self.get_setting("grid_resolution") + self._voxel_stage.voxel_world_size = self.get_setting("grid_ws_size") + + if self.is_plugin_enabled("pssm"): + # Add shadow map as requirement + self._voxel_stage.required_pipes.append("PSSMSceneSunShadowMapPCF") + self._voxel_stage.required_inputs.append("PSSMSceneSunShadowMVP") + + def on_pre_render_update(self): + task = self._queue[0] + self._queue.rotate(-1) + task() + + def on_pipeline_created(self): + self._queue = collections.deque() + self._queue.extend([self._voxelize_x, self._voxelize_y, self._voxelize_z]) + self._queue.extend([self._generate_mipmaps]) + + def _set_grid_pos(self): + """ Finds the new voxel grid position """ + grid_pos = Globals.base.camera.get_pos(Globals.base.render) + + # Snap the voxel grid + voxel_size = 2.0 * self.get_setting("grid_ws_size") / self.get_setting("grid_resolution") + snap_size = voxel_size * 2**4 + + for dimension in range(3): + cell_val = grid_pos.get_cell(dimension) + grid_pos.set_cell(dimension, cell_val - cell_val % snap_size) + + self._voxel_stage.set_grid_position(grid_pos) + + def _voxelize_x(self): + """ Voxelizes the scene from the x axis """ + self._set_grid_pos() + self._voxel_stage.state = VoxelizationStage.S_voxelize_x + + def _voxelize_y(self): + """ Voxelizes the scene from the y axis """ + self._voxel_stage.state = VoxelizationStage.S_voxelize_y + + def _voxelize_z(self): + """ Voxelizes the scene from the z axis """ + self._voxel_stage.state = VoxelizationStage.S_voxelize_z + + def _generate_mipmaps(self): + """ Generates the mipmaps for the voxel grid """ + self._voxel_stage.state = VoxelizationStage.S_gen_mipmaps diff --git a/rpplugins/vxgi/shader/copy_voxels.frag.glsl b/rpplugins/vxgi/shader/copy_voxels.frag.glsl new file mode 100644 index 0000000..c351336 --- /dev/null +++ b/rpplugins/vxgi/shader/copy_voxels.frag.glsl @@ -0,0 +1,39 @@ +/** + * + * RenderPipeline + * + * Copyright (c) 2014-2016 tobspr + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + */ + +#version 430 + +#pragma include "render_pipeline_base.inc.glsl" + +uniform sampler3D SourceTex; +uniform writeonly image3D RESTRICT DestTex; + +flat in int instance_id; + +void main() { + ivec3 coord = ivec3(gl_FragCoord.xy, instance_id); + imageStore(DestTex, coord, texelFetch(SourceTex, coord, 0)); +} diff --git a/rpplugins/vxgi/shader/generate_mipmaps.frag.glsl b/rpplugins/vxgi/shader/generate_mipmaps.frag.glsl new file mode 100644 index 0000000..dc71803 --- /dev/null +++ b/rpplugins/vxgi/shader/generate_mipmaps.frag.glsl @@ -0,0 +1,54 @@ +/** + * + * RenderPipeline + * + * Copyright (c) 2014-2016 tobspr + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + */ + +#version 430 + +#pragma include "render_pipeline_base.inc.glsl" + +flat in int instance_id; + +uniform int sourceMip; +uniform sampler3D SourceTex; +uniform writeonly image3D RESTRICT DestTex; + +void main() { + ivec3 coord = ivec3(gl_FragCoord.xy, instance_id); + + ivec3 parent_coord = coord * 2; + + vec4 accum = vec4(0); + accum += texelFetch(SourceTex, parent_coord + ivec3(0, 0, 0), sourceMip); + accum += texelFetch(SourceTex, parent_coord + ivec3(1, 0, 0), sourceMip); + accum += texelFetch(SourceTex, parent_coord + ivec3(0, 1, 0), sourceMip); + accum += texelFetch(SourceTex, parent_coord + ivec3(1, 1, 0), sourceMip); + + accum += texelFetch(SourceTex, parent_coord + ivec3(0, 0, 1), sourceMip); + accum += texelFetch(SourceTex, parent_coord + ivec3(1, 0, 1), sourceMip); + accum += texelFetch(SourceTex, parent_coord + ivec3(0, 1, 1), sourceMip); + accum += texelFetch(SourceTex, parent_coord + ivec3(1, 1, 1), sourceMip); + accum /= 8.0; + imageStore(DestTex, coord, accum); +} diff --git a/rpplugins/vxgi/shader/resolve_vxgi.frag.glsl b/rpplugins/vxgi/shader/resolve_vxgi.frag.glsl new file mode 100644 index 0000000..7d9a11c --- /dev/null +++ b/rpplugins/vxgi/shader/resolve_vxgi.frag.glsl @@ -0,0 +1,50 @@ +/** + * + * RenderPipeline + * + * Copyright (c) 2014-2016 tobspr + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + */ + +#version 430 + +#pragma include "render_pipeline_base.inc.glsl" + + +#define RS_MAX_CLIP_DIST 1.5 +#define RS_DISTANCE_SCALE 1.0 +#define RS_KEEP_GOOD_DURATION 64.0 +#define RS_USE_POSITION_TECHNIQUE 1 +#pragma include "includes/temporal_resolve.inc.glsl" + +uniform sampler2D CurrentTex; +uniform sampler2D CombinedVelocity; +uniform sampler2D Previous_VXGIPostSample; + +out vec4 result; + +void main() { + vec2 texcoord = get_texcoord(); + vec2 velocity = textureLod(CombinedVelocity, texcoord, 0).xy; + vec2 last_coord = texcoord + velocity; + + result = resolve_temporal(CurrentTex, Previous_VXGIPostSample, texcoord, last_coord); +} diff --git a/rpplugins/vxgi/shader/vxgi.inc.glsl b/rpplugins/vxgi/shader/vxgi.inc.glsl new file mode 100644 index 0000000..ecf844c --- /dev/null +++ b/rpplugins/vxgi/shader/vxgi.inc.glsl @@ -0,0 +1,92 @@ +/** + * + * RenderPipeline + * + * Copyright (c) 2014-2016 tobspr + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + */ + +#pragma once + +// Required inputs +uniform sampler3D SceneVoxels; +uniform samplerCube ScatteringIBLSpecular; +uniform samplerCube ScatteringIBLDiffuse; + +// Voxel grid parameters +uniform vec3 voxelGridPosition; +uniform float voxelGridSize; +uniform int voxelGridResolution; + + +vec3 worldspace_to_voxelspace(vec3 worldspace) { + vec3 voxel_coord = (worldspace - voxelGridPosition) / GET_SETTING(vxgi, grid_ws_size); + return fma(voxel_coord, vec3(0.5), vec3(0.5)); +} + +float get_mipmap_from_cone_radius(float cone_radius) { + return log2(cone_radius * GET_SETTING(vxgi, grid_resolution) * 0.6) - 1; +} + +vec4 trace_cone(vec3 start_pos, vec3 nrm, vec3 direction, int max_steps, + bool is_specular, float cone_grow_factor, float seed) { + + // Find initial cone radius + float cone_radius = (1.0 + 5.0 * cone_grow_factor) / GET_SETTING(vxgi, grid_resolution); + + // Offset start position to avoid self intersection + start_pos += nrm * 1.5 / GET_SETTING(vxgi, grid_resolution); + start_pos += direction * 5.5 / GET_SETTING(vxgi, grid_resolution); + + if (!is_specular) { + // start_pos += nrm * 1.5 / GET_SETTING(vxgi, grid_resolution); + } + + // Cone parameters + vec3 current_pos = start_pos; + vec4 accum = vec4(0); + float mipmap = 0.0; + + current_pos += direction * cone_radius * seed; + + // Trace the cone over the voxel grid + for (int i = 0; i < max_steps; ++i) { + mipmap = get_mipmap_from_cone_radius(cone_radius); + vec4 sampled = textureLod(SceneVoxels, current_pos, mipmap); + sampled.w *= 2.0; + sampled.w = saturate(sampled.w); + accum += sampled * (1.0 - accum.w); + current_pos += direction * cone_radius / 2.25; + cone_radius *= 1.01 + cone_grow_factor; + } + + // Unpack packed color, since we use 8 bit targets only + accum.xyz = accum.xyz / (1 - accum.xyz); + // accum.xyz *= 15.0; + + if (is_specular) { + // accum.xyz += textureLod(ScatteringIBLSpecular, direction, mipmap).xyz * (1-accum.w); + } else { + // accum.xyz += textureLod(ScatteringIBLDiffuse, direction, 0).xyz * (1-accum.w) * 0.1; + } + + return accum; +} diff --git a/rpplugins/vxgi/shader/vxgi_diffuse.frag.glsl b/rpplugins/vxgi/shader/vxgi_diffuse.frag.glsl new file mode 100644 index 0000000..c0de307 --- /dev/null +++ b/rpplugins/vxgi/shader/vxgi_diffuse.frag.glsl @@ -0,0 +1,89 @@ +/** + * + * RenderPipeline + * + * Copyright (c) 2014-2016 tobspr + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + */ + +#version 430 + +#pragma include "render_pipeline_base.inc.glsl" +#pragma include "includes/gbuffer.inc.glsl" +#pragma include "includes/poisson_disk.inc.glsl" +#pragma include "includes/noise.inc.glsl" +#pragma include "vxgi.inc.glsl" + +uniform sampler2D ShadedScene; +uniform GBufferData GBuffer; +out vec4 result; + +void main() { + // Get texture coordinate + ivec2 coord = ivec2(gl_FragCoord.xy) * 2; + vec2 texcoord = (coord + 0.5) / SCREEN_SIZE; + vec3 noise_vec = vec3(0, 0, 0); + + // Get material data + Material m = unpack_material(GBuffer, texcoord); + vec3 voxel_coord = worldspace_to_voxelspace(m.position); + + // Get view vector + vec3 view_vector = normalize(MainSceneData.camera_pos - m.position); + vec3 reflected_dir = reflect(-view_vector, m.normal); + + if (out_of_unit_box(voxel_coord)) + { + result = textureLod(ScatteringIBLDiffuse, m.normal, 0); + return; + } + + // Trace diffuse cones + vec4 accum = vec4(0); + + // float jitter = 16.0 / (MainSceneData.frame_index % 512); + float jitter = 0.0; + + for (int i = 0; i < 8; ++i) { + vec3 direction = rand_rgb(vec2(texcoord + i * 0.001 + + 0.134 * (MainSceneData.frame_index % 1024))); + + direction = normalize(direction); + direction = face_forward(direction, m.normal); + float weight = max(0.0, dot(m.normal, direction)); // Guaranteed to be > 0 + // weight = 1.0; + vec4 cone = trace_cone( + voxel_coord, + m.normal, + direction, + // GET_SETTING(vxgi, diffuse_cone_steps), + 32, + false, + 0.05, + jitter); + accum.xyz += cone.xyz * weight; + accum.w += weight; + } + accum /= max(1e-3, accum.w); + accum *= 1.0; + accum = clamp(accum, vec4(0.0), vec4(100.0)); + result = accum; +} diff --git a/rpplugins/vxgi/shader/vxgi_specular.frag.glsl b/rpplugins/vxgi/shader/vxgi_specular.frag.glsl new file mode 100644 index 0000000..392f806 --- /dev/null +++ b/rpplugins/vxgi/shader/vxgi_specular.frag.glsl @@ -0,0 +1,70 @@ +/** + * + * RenderPipeline + * + * Copyright (c) 2014-2016 tobspr + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + */ + +#version 430 + + +#pragma include "render_pipeline_base.inc.glsl" +#pragma include "includes/gbuffer.inc.glsl" +#pragma include "includes/poisson_disk.inc.glsl" +#pragma include "vxgi.inc.glsl" + +uniform sampler2D ShadedScene; +uniform GBufferData GBuffer; +out vec4 result; + +void main() { + + Material m = unpack_material(GBuffer); + vec3 voxel_coord = worldspace_to_voxelspace(m.position); + + // Get view vector + vec3 view_vector = normalize(MainSceneData.camera_pos - m.position); + vec3 reflected_dir = reflect(-view_vector, m.normal); + + if (out_of_unit_box(voxel_coord)) + { + result = textureLod(ScatteringIBLSpecular, reflected_dir, 7) * 0.5; + return; + } + + // Trace specular cone + vec4 specular = trace_cone( + voxel_coord, + m.normal, + reflected_dir, + GET_SETTING(vxgi, specular_cone_steps), + true, + m.roughness * 0.17); + + // specular *= 0.1; + // specular.xyz = pow(specular.xyz, vec3(2.2)); + // specular.xyz *= 0.01; + // specular.xyz = specular.xyz / (1 - specular.xyz); + specular.xyz = max(vec3(0.0), specular.xyz); + + result = specular; +} diff --git a/rpplugins/vxgi/voxelization_stage.py b/rpplugins/vxgi/voxelization_stage.py new file mode 100644 index 0000000..07839f4 --- /dev/null +++ b/rpplugins/vxgi/voxelization_stage.py @@ -0,0 +1,203 @@ +""" + +RenderPipeline + +Copyright (c) 2014-2016 tobspr + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. + +""" + +from __future__ import division + +from rpcore.globals import Globals +from rpcore.image import Image +from rpcore.render_stage import RenderStage + +from panda3d.core import Camera, OrthographicLens, NodePath, CullFaceAttrib +from panda3d.core import DepthTestAttrib, Vec4, PTALVecBase3, Vec3, SamplerState +from panda3d.core import ColorWriteAttrib + + +class VoxelizationStage(RenderStage): + + """ This stage voxelizes the whole scene """ + + required_inputs = ["DefaultEnvmap", "AllLightsData", "maxLightIndex"] + required_pipes = [] + + # The different states of voxelization + S_disabled = 0 + S_voxelize_x = 1 + S_voxelize_y = 2 + S_voxelize_z = 3 + S_gen_mipmaps = 4 + + def __init__(self, pipeline): + RenderStage.__init__(self, pipeline) + self.voxel_resolution = 256 + self.voxel_world_size = -1 + self.state = self.S_disabled + self.create_ptas() + + def set_grid_position(self, pos): + self.pta_next_grid_pos[0] = pos + + def create_ptas(self): + self.pta_next_grid_pos = PTALVecBase3.empty_array(1) + self.pta_grid_pos = PTALVecBase3.empty_array(1) + + @property + def produced_inputs(self): + return {"voxelGridPosition": self.pta_grid_pos} + + @property + def produced_pipes(self): + return {"SceneVoxels": self.voxel_grid} + + def create(self): + # Create the voxel grid used to generate the voxels + self.voxel_temp_grid = Image.create_3d( + "VoxelsTemp", self.voxel_resolution, self.voxel_resolution, + self.voxel_resolution, "RGBA8") + self.voxel_temp_grid.set_clear_color(Vec4(0)) + self.voxel_temp_nrm_grid = Image.create_3d( + "VoxelsTemp", self.voxel_resolution, self.voxel_resolution, + self.voxel_resolution, "R11G11B10") + self.voxel_temp_nrm_grid.set_clear_color(Vec4(0)) + + # Create the voxel grid which is a copy of the temporary grid, but stable + self.voxel_grid = Image.create_3d( + "Voxels", self.voxel_resolution, self.voxel_resolution, self.voxel_resolution, "RGBA8") + self.voxel_grid.set_clear_color(Vec4(0)) + self.voxel_grid.set_minfilter(SamplerState.FT_linear_mipmap_linear) + + # Create the camera for voxelization + self.voxel_cam = Camera("VoxelizeCam") + self.voxel_cam.set_camera_mask(self._pipeline.tag_mgr.get_mask("voxelize")) + self.voxel_cam_lens = OrthographicLens() + self.voxel_cam_lens.set_film_size( + -2.0 * self.voxel_world_size, 2.0 * self.voxel_world_size) + self.voxel_cam_lens.set_near_far(0.0, 2.0 * self.voxel_world_size) + self.voxel_cam.set_lens(self.voxel_cam_lens) + self.voxel_cam_np = Globals.base.render.attach_new_node(self.voxel_cam) + self._pipeline.tag_mgr.register_camera("voxelize", self.voxel_cam) + + # Create the voxelization target + self.voxel_target = self.create_target("VoxelizeScene") + self.voxel_target.size = self.voxel_resolution + self.voxel_target.prepare_render(self.voxel_cam_np) + + # Create the target which copies the voxel grid + self.copy_target = self.create_target("CopyVoxels") + self.copy_target.size = self.voxel_resolution + self.copy_target.prepare_buffer() + + # TODO! Does not work with the new render target yet - maybe add option + # to post process region for instances? + self.copy_target.instance_count = self.voxel_resolution + self.copy_target.set_shader_inputs( + SourceTex=self.voxel_temp_grid, + DestTex=self.voxel_grid) + + # Create the target which generates the mipmaps + self.mip_targets = [] + mip_size, mip = self.voxel_resolution, 0 + while mip_size > 1: + mip_size, mip = mip_size // 2, mip + 1 + mip_target = self.create_target("GenMipmaps:" + str(mip)) + mip_target.size = mip_size + mip_target.prepare_buffer() + mip_target.instance_count = mip_size + mip_target.set_shader_inputs( + SourceTex=self.voxel_grid, + sourceMip=(mip - 1)) + mip_target.set_shader_input("DestTex", self.voxel_grid, False, True, -1, mip, 0) + self.mip_targets.append(mip_target) + + # Create the initial state used for rendering voxels + initial_state = NodePath("VXGIInitialState") + initial_state.set_attrib(CullFaceAttrib.make(CullFaceAttrib.M_cull_none), 100000) + initial_state.set_attrib(DepthTestAttrib.make(DepthTestAttrib.M_none), 100000) + initial_state.set_attrib(ColorWriteAttrib.make(ColorWriteAttrib.C_off), 100000) + self.voxel_cam.set_initial_state(initial_state.get_state()) + + Globals.base.render.set_shader_inputs( + voxelGridPosition=self.pta_next_grid_pos, + VoxelGridDest=self.voxel_temp_grid) + + def update(self): + self.voxel_cam_np.show() + self.voxel_target.active = True + self.copy_target.active = False + + for target in self.mip_targets: + target.active = False + + # Voxelization disable + if self.state == self.S_disabled: + self.voxel_cam_np.hide() + self.voxel_target.active = False + + # Voxelization from X-Axis + elif self.state == self.S_voxelize_x: + # Clear voxel grid + self.voxel_temp_grid.clear_image() + self.voxel_cam_np.set_pos( + self.pta_next_grid_pos[0] + Vec3(self.voxel_world_size, 0, 0)) + self.voxel_cam_np.look_at(self.pta_next_grid_pos[0]) + + # Voxelization from Y-Axis + elif self.state == self.S_voxelize_y: + self.voxel_cam_np.set_pos( + self.pta_next_grid_pos[0] + Vec3(0, self.voxel_world_size, 0)) + self.voxel_cam_np.look_at(self.pta_next_grid_pos[0]) + + # Voxelization from Z-Axis + elif self.state == self.S_voxelize_z: + self.voxel_cam_np.set_pos( + self.pta_next_grid_pos[0] + Vec3(0, 0, self.voxel_world_size)) + self.voxel_cam_np.look_at(self.pta_next_grid_pos[0]) + + # Generate mipmaps + elif self.state == self.S_gen_mipmaps: + self.voxel_target.active = False + self.copy_target.active = True + self.voxel_cam_np.hide() + + for target in self.mip_targets: + target.active = True + + # As soon as we generate the mipmaps, we need to update the grid position + # as well + self.pta_grid_pos[0] = self.pta_next_grid_pos[0] + + def reload_shaders(self): + self.copy_target.shader = self.load_plugin_shader( + "/$$rp/shader/default_post_process_instanced.vert.glsl", "copy_voxels.frag.glsl") + mip_shader = self.load_plugin_shader( + "/$$rp/shader/default_post_process_instanced.vert.glsl", "generate_mipmaps.frag.glsl") + for target in self.mip_targets: + target.shader = mip_shader + + def set_shader_input(self, *args): + Globals.render.set_shader_input(*args) + + def set_shader_inputs(self, **kwargs): + Globals.render.set_shader_inputs(**kwargs) diff --git a/rpplugins/vxgi/vxgi_stage.py b/rpplugins/vxgi/vxgi_stage.py new file mode 100644 index 0000000..4a49caa --- /dev/null +++ b/rpplugins/vxgi/vxgi_stage.py @@ -0,0 +1,105 @@ +""" + +RenderPipeline + +Copyright (c) 2014-2016 tobspr + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. + +""" +from __future__ import division + +from panda3d.core import LVecBase2i, Vec2 + +from rpcore.render_stage import RenderStage +from rpcore.stages.ambient_stage import AmbientStage + + +class VXGIStage(RenderStage): + + required_inputs = ["voxelGridPosition"] + required_pipes = ["ShadedScene", "SceneVoxels", "GBuffer", "ScatteringIBLSpecular", + "ScatteringIBLDiffuse", "PreviousFrame::VXGIPostSample", + "CombinedVelocity", "PreviousFrame::SceneDepth"] + + @property + def produced_pipes(self): + return { + # "VXGISpecular": self.target_spec.color_tex, + "VXGIDiffuse": self.target_resolve.color_tex, + "VXGIPostSample": self.target_resolve.color_tex + } + + def create(self): + # Create a target for the specular GI + # self.target_spec = self.create_target("SpecularGI") + # self.target_spec.add_color_attachment(bits=16, alpha=True) + # self.target_spec.prepare_buffer() + + # Create a target for the diffuse GI + self.target_diff = self.create_target("DiffuseGI") + self.target_diff.size = -2 + self.target_diff.add_color_attachment(bits=16) + self.target_diff.prepare_buffer() + + # Create the target which blurs the diffuse result + self.target_blur_v = self.create_target("BlurV") + self.target_blur_v.size = -2 + self.target_blur_v.add_color_attachment(bits=16) + self.target_blur_v.has_color_alpha = True + self.target_blur_v.prepare_buffer() + self.target_blur_v.set_shader_input("SourceTex", self.target_diff.color_tex) + + self.target_blur_h = self.create_target("BlurH") + self.target_blur_h.size = -2 + self.target_blur_h.add_color_attachment(bits=16) + self.target_blur_h.has_color_alpha = True + self.target_blur_h.prepare_buffer() + self.target_blur_h.set_shader_input("SourceTex", self.target_blur_v.color_tex) + + # Set blur parameters + self.target_blur_v.set_shader_input("blur_direction", LVecBase2i(0, 1)) + self.target_blur_h.set_shader_input("blur_direction", LVecBase2i(1, 0)) + + # Create the target which bilateral upsamples the diffuse target + self.target_upscale_diff = self.create_target("UpscaleDiffuse") + self.target_upscale_diff.add_color_attachment(bits=16) + self.target_upscale_diff.prepare_buffer() + self.target_upscale_diff.set_shader_inputs( + SourceTex=self.target_blur_h.color_tex, + upscaleWeights=Vec2(0.0001, 0.001)) + + self.target_resolve = self.create_target("ResolveVXGI") + self.target_resolve.add_color_attachment(bits=16) + self.target_resolve.prepare_buffer() + self.target_resolve.set_shader_input("CurrentTex", self.target_upscale_diff.color_tex) + + # Make the ambient stage use the GI result + AmbientStage.required_pipes += ["VXGIDiffuse"] + + def reload_shaders(self): + # self.target_spec.shader = self.load_plugin_shader("vxgi_specular.frag.glsl") + self.target_diff.shader = self.load_plugin_shader("vxgi_diffuse.frag.glsl") + self.target_upscale_diff.shader = self.load_plugin_shader( + "/$$rp/shader/bilateral_upscale.frag.glsl") + blur_shader = self.load_plugin_shader( + "/$$rp/shader/bilateral_halfres_blur.frag.glsl") + self.target_blur_v.shader = blur_shader + self.target_blur_h.shader = blur_shader + self.target_resolve.shader = self.load_plugin_shader("resolve_vxgi.frag.glsl") diff --git a/setup.py b/setup.py new file mode 100644 index 0000000..7259ab4 --- /dev/null +++ b/setup.py @@ -0,0 +1,312 @@ +""" + +RenderPipeline + +Copyright (c) 2014-2016 tobspr + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. + +""" + +# Setup script to install everything required to run the pipeline. + +# pylint: skip-file +# flake8: noqa + +from __future__ import print_function +import os +import sys +import subprocess +import webbrowser +import gzip +import shutil +import argparse + +sys.dont_write_bytecode = True + +DEVNULL = open(os.path.devnull, "w") +SETUP_DIR = os.path.dirname(os.path.realpath(__file__)) +CURRENT_STEP = 0 + +os.chdir(SETUP_DIR) +sys.path.insert(0, ".") + +from rplibs.six.moves import input # pylint: disable=import-error + +# Load and init colorama, used to color the output +from rplibs.colorama import init as init_colorama +from rplibs.colorama import Fore, Style +init_colorama() + +def parse_cmd_args(): + """ Parses the command line arguments """ + parser = argparse.ArgumentParser(description="Render Pipeline Setup") + parser.add_argument( + "--clean", help="Clean rebuild of the native modules", action="store_true") + parser.add_argument( + "--verbose", help="Output additional debug information", action="store_true") + parser.add_argument( + "--skip-update", help="Skip updating the module builder to avoid overriding changes", action="store_true") + parser.add_argument( + "--skip-native", help="Skip native module compilation", action="store_true") + parser.add_argument( + "--ci-build", help="Skip setup steps requiring gpu drivers, only for travis ci", action="store_true") + return parser.parse_args() + +CMD_ARGS = parse_cmd_args() + +def color(string, col): + """ Colors a string """ + return col + string + Style.RESET_ALL + +def error(msg): + """ Prints an error message and then exists the program """ + print("\n" + color("Setup failed:\t", Fore.RED + Style.BRIGHT), msg) + print(color("\nPlease fix the above errors and then restart the setup.\n", + Fore.RED + Style.BRIGHT)) + sys.exit(-1) + +def print_step(title): + """ Prints a new section """ + global CURRENT_STEP + CURRENT_STEP += 1 + print("\n\n[", str(CURRENT_STEP).zfill(2), "] ", color(title, Fore.CYAN + Style.BRIGHT)) + +def ask_for_troubleshoot(url): + if CMD_ARGS.ci_build: + print("\nSETUP FAILED!") + return + + if not url: + print("\nSorry, no troubleshooting options are available.\n") + return + + query = "\nIt seems the setup failed, do you want to open the troubleshooting page for this step? (y/n):" + if get_user_choice(query): + print("OK, opening", url,"\n") + webbrowser.open(url, new=2) + +def exec_python_file(pth, args=None, troubleshoot=None): + """ Executes a python file and checks the return value """ + basedir = os.path.dirname(os.path.abspath(os.path.join(SETUP_DIR, pth))) + "/" + print("\tRunning script:", Fore.YELLOW + Style.BRIGHT + pth + Style.RESET_ALL) + pth = os.path.basename(pth) + os.chdir(basedir) + cmd = [sys.executable, "-B", pth] + (args or []) + if CMD_ARGS.verbose: + print("Executing", ' '.join(cmd)) + print("CWD is", basedir) + try: + output = subprocess.check_output(cmd, stderr=sys.stderr) + except subprocess.CalledProcessError as msg: + print(color("Failed to execute '" + pth + "'", Fore.YELLOW + Style.BRIGHT)) + print("Output:", msg, "\n", msg.output.decode("utf-8", errors="ignore")) + ask_for_troubleshoot(troubleshoot) + error("Python script didn't return properly!") + except IOError as msg: + print("Python script error:", msg) + ask_for_troubleshoot(troubleshoot) + error("Error during script execution") + if CMD_ARGS.verbose: + print(output.decode("utf-8", errors="ignore")) + os.chdir(SETUP_DIR) + +def extract_gz_files(pth): + """ Extract all gz files in the given path recursively """ + files = os.listdir(pth) + for fname in files: + fullpath = os.path.join(pth, fname) + if os.path.isfile(fullpath) and fname.endswith(".gz"): + print("\tExtracting", fname) + try: + with open(fullpath[:-3], 'wb') as dest, gzip.open(fullpath, 'rb') as src: + shutil.copyfileobj(src, dest) + except IOError as msg: + error("Failed to extract file '" + fname + "': " + str(msg)) + elif os.path.isdir(fullpath): + extract_gz_files(fullpath) + +def check_file_exists(fpath): + """ Checks if the given file exists """ + return os.path.isfile(os.path.join(SETUP_DIR, fpath)) + +def ask_download_samples(): + """ Asks the user if he wants to download the samples """ + query = "\nDo you want to download the Render Pipeline samples (~450MB)? (y/n):" + + if get_user_choice(query): + print_step("Downloading samples (Might take a while, depending on your " + "internet connection) ...") + exec_python_file("samples/download_samples.py") + +def get_user_choice(query): + """ Asks the user a boolean question """ + print("\n") + query = color(query, Fore.GREEN + Style.BRIGHT) + " " + + while True: + print(query, end="") + user_choice = input().strip().lower() + + if user_choice in ["y", "yes", "1"]: + return True + + if user_choice in ["n", "no", "0"]: + return False + + print(color("Invalid input: '" + user_choice + "'", Fore.RED + Style.BRIGHT)) + +def write_flag(flag_location, flag_value): + """ Writes a binary flag """ + flag_location = os.path.join(SETUP_DIR, flag_location) + try: + with open(flag_location, "w") as handle: + handle.write("1" if flag_value else "0") + except IOError as msg: + error("Failed to write flag to "+ flag_location + ", reason: " + str(msg)) + +def check_cmake(): + """ Checks if cmake is installed """ + try: + subprocess.call(["cmake", "--version"], stdout=subprocess.PIPE) + except Exception as msg: + print("\n") + print(color("Could not find cmake!", Fore.RED + Style.BRIGHT)) + print("It seems that cmake is not installed on this system, or not on") + print("your path. Please install cmake and make sure it is on your path.") + print("You can ensure this by running 'cmake --version' in a command line.") + print("Full error message:") + print(msg) + error("cmake missing") + +def check_panda_version(): + """ Checks whether the Panda3D version used is up to date. This is important + when using the C++ modules """ + + from panda3d.core import Texture + + if not hasattr(Texture, "F_r16i"): + print("\n") + print("It seems your Panda3D version is outdated. Please get the newest version ") + print("from", color("https://github.com/panda3d/panda3d", Fore.MAGENTA + Style.BRIGHT), + "(you can also build from source).") + error("Panda3D version outdated") + +def check_panda_rplight(): + """ Checks whether Panda3D provides the rpcore native module. """ + + try: + from panda3d import _rplight + return True + except ImportError: + pass + + return False + +def setup(): + """ Main setup routine """ + + print("-" * 79) + print("\nRender Pipeline Setup 1.3\n") + print("-" * 79) + + + if CMD_ARGS.ci_build: + print() + print(color("Running CI setup without steps requiring a GPU", Fore.BLUE + Style.BRIGHT)) + + print_step("Checking Panda3D Modules") + # Make sure this python build is using Panda3D + try: + from panda3d.core import NodePath + except ImportError: + print("\n") + print("Could not import Panda3D modules! Please make sure they are ") + print("on your path, and you are using the correct python version!") + error("Failed to import Panda3D modules") + + check_panda_version() + + if not CMD_ARGS.ci_build: + print_step("Checking requirements ..") + exec_python_file("data/setup/check_requirements.py", + troubleshoot="https://github.com/tobspr/RenderPipeline/wiki/Setup-Troubleshooting#requirements-check") + + if check_panda_rplight(): + write_flag("rpcore/native/use_cxx.flag", True) + + elif not CMD_ARGS.skip_native: + query = ("The C++ modules of the pipeline are faster and produce better \n" + "results, but we will have to compile them. As alternative, \n" + "a Python fallback is used, which is slower and produces worse \n" + "results. Also some plugins only partially work with the python \n" + "fallback (e.g. PSSM). Do you want to compile the C++ modules? (y/n):") + + # Dont install the c++ modules when using travis + if CMD_ARGS.ci_build or get_user_choice(query): + check_cmake() + write_flag("rpcore/native/use_cxx.flag", True) + + if not CMD_ARGS.skip_update: + print_step("Downloading the module builder ...") + exec_python_file("rpcore/native/update_module_builder.py", + troubleshoot="https://github.com/tobspr/RenderPipeline/wiki/Setup-Troubleshooting#downloading-module-builder") + + print_step("Building the native code .. (This might take a while!)") + exec_python_file("rpcore/native/build.py", ["--clean"] if CMD_ARGS.clean else [], + troubleshoot="https://github.com/tobspr/RenderPipeline/wiki/Setup-Troubleshooting#building-the-native-code") + + else: + write_flag("rpcore/native/use_cxx.flag", False) + + print_step("Generating .txo files ...") + exec_python_file("data/generate_txo_files.py", + troubleshoot="https://github.com/tobspr/RenderPipeline/wiki/Setup-Troubleshooting#extracting-txo-files") + + if not CMD_ARGS.ci_build: + print_step("Filtering default cubemap ..") + exec_python_file("data/default_cubemap/filter.py", + troubleshoot="https://github.com/tobspr/RenderPipeline/wiki/Setup-Troubleshooting#filtering-default-cubemap") + + print_step("Precomputing film grain .. ") + exec_python_file("data/film_grain/generate.py", + troubleshoot="https://github.com/tobspr/RenderPipeline/wiki/Setup-Troubleshooting#precomputing-film-grain") + + print_step("Running shader scripts .. ") + exec_python_file("rpplugins/env_probes/shader/generate_mip_shaders.py", + troubleshoot="https://github.com/tobspr/RenderPipeline/wiki/Setup-Troubleshooting#running-shader-scripts") + + + if not CMD_ARGS.ci_build: + print_step("Precomputing clouds ..") + exec_python_file("rpplugins/clouds/resources/precompute.py", + troubleshoot="https://github.com/tobspr/RenderPipeline/wiki/Setup-Troubleshooting#precomputing-clouds") + + write_flag("data/install.flag", True) + + # -- Further setup code follows here -- + + print(color("\n\n-- Setup finished sucessfully! --", Fore.GREEN + Style.BRIGHT)) + + if not CMD_ARGS.ci_build: + ask_download_samples() + + +if __name__ == "__main__": + setup() diff --git a/start_daytime_editor.py b/start_daytime_editor.py new file mode 100644 index 0000000..356b985 --- /dev/null +++ b/start_daytime_editor.py @@ -0,0 +1,12 @@ +#!/usr/bin/env python + +import os +import sys +import subprocess +this_dir = os.path.dirname(os.path.realpath(__file__)) + +if not os.path.isfile(os.path.join(this_dir, "data", "install.flag")): + print("Please install the pipeline first by running setup.py") + sys.exit(-1) +to_execute = os.path.join(this_dir, "toolkit", "day_time_editor", "main.py") +subprocess.call([sys.executable, to_execute]) diff --git a/start_plugin_configurator.py b/start_plugin_configurator.py new file mode 100644 index 0000000..6ac5633 --- /dev/null +++ b/start_plugin_configurator.py @@ -0,0 +1,12 @@ +#!/usr/bin/env python + +import os +import sys +import subprocess +this_dir = os.path.dirname(os.path.realpath(__file__)) + +if not os.path.isfile(os.path.join(this_dir, "data", "install.flag")): + print("Please install the pipeline first by running setup.py") + sys.exit(-1) +to_execute = os.path.join(this_dir, "toolkit", "plugin_configurator", "main.py") +subprocess.call([sys.executable, to_execute]) diff --git a/toolkit/bake_gi/bake.py b/toolkit/bake_gi/bake.py new file mode 100644 index 0000000..dd24601 --- /dev/null +++ b/toolkit/bake_gi/bake.py @@ -0,0 +1,264 @@ +""" + +Precomputed GI using spherical harmonics. + +""" + +from __future__ import division, print_function + +import os +import sys + +os.chdir(os.path.realpath(os.path.dirname(__file__))) +sys.path.insert(0, "../../") + +# Shouldn't import everything, but saves a lot of code +from panda3d.core import * +from direct.showbase.ShowBase import ShowBase + +from rpcore.globals import Globals +from rpcore.render_target import RenderTarget +from rplibs.progressbar import ETA, ProgressBar, Percentage, Bar, Counter, Rate + +class Application(ShowBase): + + def __init__(self): + + # Load settings + load_prc_file_data("", """ + win-size 10 10 + window-type offscreen + win-title GI Bake + textures-power-2 none + gl-coordinate-system default + sync-video #f + support-stencil #f + framebuffer-stencil #f + framebuffer-multisample #f + multisamples 0 + gl-cube-map-seamless #t + gl-force-fbo-color #f + """) + + ShowBase.__init__(self) + Globals.load(self) + Globals.resolution = LVecBase2i(1600, 900) + sun_vector = Vec3(0.2, 0.5, 1.2).normalized() + capture_resolution = 32 + sun_shadow_map_resolution = 2048 + num_probes = LVecBase3i(64) + divisor = 128 + num_bakers = 8 + padding = 0.5 + + for region in self.win.get_display_regions(): + region.set_active(False) + + print("Loading scene ...") + # model = loader.load_model("resources/test-scene.bam") + model = loader.load_model("scene/scene.bam") + # model = loader.load_model("scene/LivingRoom.egg") + model.reparent_to(render) + model.flatten_strong() + + start_point, end_point = model.get_tight_bounds() + start_point -= padding + end_point += padding + diameter = (start_point - end_point).length() * 0.5 + model_center = (start_point + end_point) * 0.5 + model_size = end_point - start_point + + print("Rendering sun shadow map ..") + sun_shadow_cam = Camera("SunShadowCamera") + sun_shadow_lens = OrthographicLens() + sun_shadow_lens.set_film_size(diameter * 2, diameter * 2) + sun_shadow_lens.set_near_far(0, 2 * diameter) + sun_shadow_cam.set_lens(sun_shadow_lens) + sun_shadow_cam_np = render.attach_new_node(sun_shadow_cam) + sun_shadow_cam_np.set_pos(model_center + sun_vector * diameter) + sun_shadow_cam_np.look_at(model_center) + + sun_shadow_target = RenderTarget() + sun_shadow_target.size = sun_shadow_map_resolution + sun_shadow_target.add_depth_attachment(bits=32) + sun_shadow_target.prepare_render(sun_shadow_cam_np) + + self.render_frame() + sun_shadow_target.active = False + shadow_mvp = self.get_mvp(sun_shadow_cam_np) + + print("Computing first bounce ..") + + # Target to store all results + max_probes = num_probes.x * num_probes.y * num_probes.z + + if max_probes % divisor != 0: + print("WARNING: Bad divisor:", divisor, "for", max_probes) + + num_rows = (max_probes + divisor - 1) // divisor + final_data = Texture("FinalProbeResult") + final_data.setup_2d_texture(6 * divisor, num_rows, Texture.T_float, Texture.F_rgba16) + final_data.set_clear_color(Vec4(1.0, 0.6, 0.2, 1.0)) + + worker_handles = [] + + store_shader = Shader.load(Shader.SL_GLSL, "resources/default.vert.glsl", "resources/copy_cubemap.frag.glsl") + convolute_shader = Shader.load(Shader.SL_GLSL, "resources/default.vert.glsl", "resources/convolute.frag.glsl") + + for worked_id in range(num_bakers): + probe_position = Vec3(0, 0, 4) + capture_target = RenderTarget() + capture_target.size = capture_resolution * 6, capture_resolution + capture_target.add_depth_attachment(bits=16) + capture_target.add_color_attachment(bits=16, alpha=True) + capture_target.prepare_render(None) + + # Remove all unused display regions + internal_buffer = capture_target.internal_buffer + internal_buffer.remove_all_display_regions() + internal_buffer.disable_clears() + internal_buffer.get_overlay_display_region().disable_clears() + + # Setup the cubemap capture rig + directions = (Vec3(1, 0, 0), Vec3(-1, 0, 0), Vec3(0, 1, 0), + Vec3(0, -1, 0), Vec3(0, 0, 1), Vec3(0, 0, -1)) + capture_regions = [] + capture_cams = [] + capture_rig = render.attach_new_node("CaptureRig") + capture_rig.set_pos(probe_position) + + # Prepare the display regions + for i in range(6): + region = capture_target.internal_buffer.make_display_region( + i / 6, i / 6 + 1 / 6, 0, 1) + region.set_sort(25 + i) + region.set_active(True) + region.disable_clears() + + # Set the correct clears + region.set_clear_depth_active(True) + region.set_clear_depth(1.0) + region.set_clear_color_active(True) + region.set_clear_color(Vec4(0.0, 0.0, 0.0, 0.0)) + + lens = PerspectiveLens() + lens.set_fov(90) + lens.set_near_far(0.05, 2 * diameter) + camera = Camera("CaptureCam-" + str(i), lens) + camera_np = capture_rig.attach_new_node(camera) + camera_np.look_at(camera_np, directions[i]) + region.set_camera(camera_np) + capture_regions.append(region) + capture_cams.append(camera_np) + + capture_cams[0].set_r(90) + capture_cams[1].set_r(-90) + capture_cams[3].set_r(180) + capture_cams[5].set_r(180) + + destination_cubemap = Texture("TemporaryCubemap") + destination_cubemap.setup_cube_map(capture_resolution, Texture.T_float, Texture.F_rgba16) + + # Target to convert the FBO to a cubemap + target_store_cubemap = RenderTarget() + target_store_cubemap.size = capture_resolution * 6, capture_resolution + target_store_cubemap.prepare_buffer() + target_store_cubemap.set_shader_inputs( + SourceTex=capture_target.color_tex, + DestTex=destination_cubemap) + + target_store_cubemap.shader = store_shader + + # Target to filter the data + store_pta = PTALVecBase2i.empty_array(1) + target_convolute = RenderTarget() + target_convolute.size = 6, 1 + # target_convolute.add_color_attachment(bits=16) + target_convolute.prepare_buffer() + target_convolute.set_shader_inputs( + SourceTex=destination_cubemap, + DestTex=final_data, + storeCoord=store_pta) + target_convolute.shader = convolute_shader + + # Set initial shader + shader = Shader.load(Shader.SL_GLSL, + "resources/first-bounce.vert.glsl", "resources/first-bounce.frag.glsl") + render.set_shader(shader) + render.set_shader_inputs( + ShadowMap=sun_shadow_target.depth_tex, + shadowMVP=shadow_mvp, + sunVector=sun_vector) + + worker_handles.append((capture_rig, store_pta)) + + print("Preparing to render", max_probes, "probes ..") + widgets = [Counter(), " ", Bar(), " ", Percentage(), " ", ETA(), " ", Rate()] + progressbar = ProgressBar(widgets=widgets, maxval=max_probes).start() + progressbar.update(0) + + work_queue = [] + + for z_pos in range(num_probes.z): + for y_pos in range(num_probes.y): + for x_pos in range(num_probes.x): + index = x_pos + y_pos * num_probes.x + z_pos * num_probes.y * num_probes.x + # print("Baking", index, "out of", max_probes) + offs_x = start_point.x + x_pos / (num_probes.x + 0.5) * model_size.x + offs_y = start_point.y + y_pos / (num_probes.y + 0.5) * model_size.y + offs_z = start_point.z + z_pos / (num_probes.z + 0.5) * model_size.z + + store_x = index % divisor + store_y = index // divisor + + work_queue.append((Vec3(offs_x, offs_y, offs_z), LVecBase2i(store_x, store_y))) + + for i, (pos, store) in enumerate(work_queue): + worker_handles[i%num_bakers][0].set_pos(pos) + worker_handles[i%num_bakers][1][0] = store + if i % num_bakers == num_bakers - 1: + self.render_frame() + progressbar.update(i) + + + progressbar.finish() + self.render_frame() + + + print("Writing out data ..") + self.graphicsEngine.extract_texture_data(final_data, self.win.gsg) + final_data.write("raw-bake.png") + + print("Writing out configuration") + with open("_bake_params.py", "w") as handle: + handle.write("#Autogenerated\n") + handle.write("from panda3d.core import LPoint3f, LVecBase3i, LVector3f\n") + handle.write("BAKE_MESH_START = " + str(start_point) + "\n") + handle.write("BAKE_MESH_END = " + str(end_point) + "\n") + handle.write("BAKE_MESH_PROBECOUNT = " + str(num_probes) + "\n") + handle.write("BAKE_DIVISOR = " + str(divisor) + "\n") + handle.write("BAKE_SUN_VECTOR = " + str(sun_vector) + "\n") + + with open("_bake_params.glsl", "w") as handle: + handle.write("// Autogenerated\n") + handle.write("#define LPoint3f vec3\n") + handle.write("#define LVector3f vec3\n") + handle.write("#define LVecBase3i ivec3\n") + handle.write("const vec3 bake_mesh_start = " + str(start_point) + ";\n") + handle.write("const vec3 bake_mesh_end = " + str(end_point) + ";\n") + handle.write("const ivec3 bake_mesh_probecount = " + str(num_probes) + ";\n") + handle.write("const int bake_divisor = " + str(divisor) + ";\n") + handle.write("const vec3 sun_vector = " + str(sun_vector) + ";\n") + + def render_frame(self): + """ Convenience function to render a frame """ + self.graphicsEngine.render_frame() + + def get_mvp(self, cam_node): + """ Computes the view-projection matrix of a camera """ + return render.get_transform(cam_node).get_mat() * cam_node.node().get_lens().get_projection_mat() + + +Application() + + diff --git a/toolkit/bake_gi/display.py b/toolkit/bake_gi/display.py new file mode 100644 index 0000000..41d9133 --- /dev/null +++ b/toolkit/bake_gi/display.py @@ -0,0 +1,100 @@ +""" + +Test-script to view the baked GI + +""" + +import os +import sys + +os.chdir(os.path.realpath(os.path.dirname(__file__))) +sys.path.insert(0, "../../") + +from _bake_params import * + +from panda3d.core import * +from direct.showbase.ShowBase import ShowBase + +from rpcore.globals import Globals +from rpcore.render_target import RenderTarget + +class Application(ShowBase): + + def __init__(self): + + load_prc_file_data("", """ + textures-power-2 none + win-size 1600 900 + """) + + ShowBase.__init__(self) + Globals.load(self) + Globals.resolution = LVecBase2i(1600, 900) + sun_vector = Vec3(BAKE_SUN_VECTOR).normalized() + + diameter = (BAKE_MESH_END - BAKE_MESH_START).length() + model_center = (BAKE_MESH_START + BAKE_MESH_END) * 0.5 + sun_shadow_map_resolution = 8192 + + + # model = loader.load_model("resources/test-scene.bam") + model = loader.load_model("scene/scene.bam") + model.reparent_to(render) + model.flatten_strong() + + + print("Rendering sun shadow map ..") + sun_shadow_cam = Camera("SunShadowCamera") + sun_shadow_lens = OrthographicLens() + sun_shadow_lens.set_film_size(diameter * 2, diameter * 2) + sun_shadow_lens.set_near_far(0, 2 * diameter) + sun_shadow_cam.set_lens(sun_shadow_lens) + sun_shadow_cam_np = render.attach_new_node(sun_shadow_cam) + sun_shadow_cam_np.set_pos(model_center + sun_vector * diameter) + sun_shadow_cam_np.look_at(model_center) + + sun_shadow_target = RenderTarget() + sun_shadow_target.size = sun_shadow_map_resolution + sun_shadow_target.add_depth_attachment(bits=32) + sun_shadow_target.prepare_render(sun_shadow_cam_np) + + self.graphicsEngine.render_frame() + sun_shadow_target.active = False + shadow_mvp = self.get_mvp(sun_shadow_cam_np) + + # Load the dataset + dataset = loader.load_texture("raw-bake.png") + render.set_shader_input("GIDataTexture", dataset) + + # Load the display shader + shader = Shader.load(Shader.SL_GLSL, "resources/display.vert.glsl", "resources/display.frag.glsl") + render.set_shader(shader) + + render.set_shader_inputs( + ShadowMap=sun_shadow_target.depth_tex, + shadowMVP=shadow_mvp, + sunVector=sun_vector) + + # Render spheres distributed over the mesh + mesh_size = BAKE_MESH_END - BAKE_MESH_START + + for i in range(11): + for j in range(11): + for k in range(11): + offs_x = i / 10.0 * mesh_size.x + BAKE_MESH_START.x + offs_y = j / 10.0 * mesh_size.y + BAKE_MESH_START.y + offs_z = k / 10.0 * mesh_size.z + BAKE_MESH_START.z + + sphere = loader.load_model("resources/sphere.bam") + sphere.reparent_to(render) + sphere.set_scale(0.02) + sphere.set_pos(offs_x, offs_y, offs_z) + + + def get_mvp(self, cam_node): + """ Computes the view-projection matrix of a camera """ + return render.get_transform(cam_node).get_mat() * cam_node.node().get_lens().get_projection_mat() + + +Application().run() + diff --git a/toolkit/bake_gi/resources/convolute.frag.glsl b/toolkit/bake_gi/resources/convolute.frag.glsl new file mode 100644 index 0000000..c66f93d --- /dev/null +++ b/toolkit/bake_gi/resources/convolute.frag.glsl @@ -0,0 +1,65 @@ +#version 430 + +uniform samplerCube SourceTex; +layout(rgba16f) uniform image2D DestTex; +uniform ivec2 storeCoord; +// out vec3 color; + +#define TWO_PI 6.2831853071795864769252867 + +vec2 hammersley(uint i, uint N) { + return vec2(float(i) / float(N), float(bitfieldReverse(i)) * 2.3283064365386963e-10); +} + +vec3 importance_sample_lambert(vec2 xi) { + float phi = TWO_PI * xi.x; + float cos_theta = sqrt(xi.y); + float sin_theta = sqrt(1 - cos_theta * cos_theta); + vec3 H; + H.x = sin_theta * cos(phi); + H.y = sin_theta * sin(phi); + H.z = cos_theta; + return vec3(H); +} + +vec3 get_sky_color(vec3 v) { + return vec3(51, 137, 233) / 255.0 * max(0, v.z) * 0.5; +} + +void main() { + int offs = int(gl_FragCoord.x); + vec3 direction = vec3(0); + switch(offs) { + case 0: direction = vec3(1, 0, 0); break; + case 1: direction = vec3(-1, 0, 0); break; + case 2: direction = vec3(0, 1, 0); break; + case 3: direction = vec3(0, -1, 0); break; + case 4: direction = vec3(0, 0, 1); break; + case 5: direction = vec3(0, 0, -1); break; + } + + const int num_samples = 512; + + // Find tangent / binormal + vec3 v0 = abs(direction.z) < 0.999 ? vec3(0, 0, 1) : vec3(0, 1, 0); + vec3 tangent = normalize(cross(v0, direction)); + vec3 bitangent = normalize(cross(tangent, direction)); + + vec3 accum = vec3(0); + + for (uint i = 0; i < num_samples; ++i) { + vec2 xi = hammersley(i, num_samples); + vec3 h = importance_sample_lambert(xi); + h = normalize(h.x * tangent + h.y * bitangent + h.z * direction); + + // vec3 l = -reflect(direction, h); + vec4 sampled_color = textureLod(SourceTex, h, 0); + accum += sampled_color.xyz * sampled_color.w + get_sky_color(h) * (1 - sampled_color.w); + } + + accum /= num_samples; + + // color = vec3(accum); + + imageStore(DestTex, ivec2(storeCoord.x * 6 + gl_FragCoord.x, storeCoord.y), vec4(accum, 1)); +} diff --git a/toolkit/bake_gi/resources/copy_cubemap.frag.glsl b/toolkit/bake_gi/resources/copy_cubemap.frag.glsl new file mode 100644 index 0000000..db13dcb --- /dev/null +++ b/toolkit/bake_gi/resources/copy_cubemap.frag.glsl @@ -0,0 +1,16 @@ +#version 430 + +uniform sampler2D SourceTex; +uniform writeonly imageCube DestTex; + +void main() { + ivec2 coord = ivec2(gl_FragCoord.xy); + int size = textureSize(SourceTex, 0).y; + vec4 source_data = texelFetch(SourceTex, coord, 0); + + // Convert to local cubemap coordinate + int offset = coord.x / size; + coord.x = coord.x % size; + + imageStore(DestTex, ivec3(coord.x, coord.y, offset), source_data); +} diff --git a/toolkit/bake_gi/resources/default.vert.glsl b/toolkit/bake_gi/resources/default.vert.glsl new file mode 100644 index 0000000..4b469e0 --- /dev/null +++ b/toolkit/bake_gi/resources/default.vert.glsl @@ -0,0 +1,6 @@ +#version 430 +in vec4 p3d_Vertex; + +void main() { + gl_Position = vec4(p3d_Vertex.xz, 0, 1); +} diff --git a/toolkit/bake_gi/resources/display.frag.glsl b/toolkit/bake_gi/resources/display.frag.glsl new file mode 100644 index 0000000..1a5dc1e --- /dev/null +++ b/toolkit/bake_gi/resources/display.frag.glsl @@ -0,0 +1,93 @@ +#version 430 + +#pragma include "../_bake_params.glsl" + +in vec3 ws_normal; +in vec3 ws_position; +in vec2 ms_uv; + +uniform sampler2D p3d_Texture0; +uniform sampler2D GIDataTexture; + +uniform sampler2D ShadowMap; +uniform mat4 shadowMVP; +uniform vec3 sunVector; + +out vec3 color; + +vec3 get_probe_at(ivec3 coord, vec3 nrm) { + int offs = coord.x + coord.y * bake_mesh_probecount.x + + coord.z * bake_mesh_probecount.y * bake_mesh_probecount.x; + if (offs > bake_mesh_probecount.x * bake_mesh_probecount.y * bake_mesh_probecount.z || + offs < 0) { + return vec3(1, 0, 0); + } + + ivec2 base_coord = ivec2((offs % bake_divisor) * 6, offs / bake_divisor); + vec3 baked = vec3(0); + baked += texelFetch( + GIDataTexture, ivec2(0, 0) + base_coord, 0).xyz * max(0, dot(nrm, vec3(1, 0, 0))); + baked += texelFetch( + GIDataTexture, ivec2(1, 0) + base_coord, 0).xyz * max(0, dot(nrm, vec3(-1, 0, 0))); + baked += texelFetch( + GIDataTexture, ivec2(2, 0) + base_coord, 0).xyz * max(0, dot(nrm, vec3(0, 1, 0))); + baked += texelFetch( + GIDataTexture, ivec2(3, 0) + base_coord, 0).xyz * max(0, dot(nrm, vec3(0, -1, 0))); + baked += texelFetch( + GIDataTexture, ivec2(4, 0) + base_coord, 0).xyz * max(0, dot(nrm, vec3(0, 0, 1))); + baked += texelFetch( + GIDataTexture, ivec2(5, 0) + base_coord, 0).xyz * max(0, dot(nrm, vec3(0, 0, -1))); + + return baked; +} + +void main() { + + vec3 biased_position = ws_position + 0.4 * ws_normal; + vec3 local_coord = (biased_position - bake_mesh_start) / (bake_mesh_end - bake_mesh_start); + + ivec3 local_index = ivec3(local_coord * bake_mesh_probecount); + vec3 fract_coord = (local_coord * bake_mesh_probecount - local_index); + + // 3D Lerp + vec3 probe_000 = get_probe_at(local_index + ivec3(0, 0, 0), ws_normal); + vec3 probe_001 = get_probe_at(local_index + ivec3(0, 0, 1), ws_normal); + vec3 probe_010 = get_probe_at(local_index + ivec3(0, 1, 0), ws_normal); + vec3 probe_011 = get_probe_at(local_index + ivec3(0, 1, 1), ws_normal); + vec3 probe_100 = get_probe_at(local_index + ivec3(1, 0, 0), ws_normal); + vec3 probe_101 = get_probe_at(local_index + ivec3(1, 0, 1), ws_normal); + vec3 probe_110 = get_probe_at(local_index + ivec3(1, 1, 0), ws_normal); + vec3 probe_111 = get_probe_at(local_index + ivec3(1, 1, 1), ws_normal); + + vec3 lerp_bottom = mix( + mix(probe_000, probe_100, fract_coord.x), + mix(probe_010, probe_110, fract_coord.x), + fract_coord.y + ); + + vec3 lerp_top = mix( + mix(probe_001, probe_101, fract_coord.x), + mix(probe_011, probe_111, fract_coord.x), + fract_coord.y + ); + + vec3 precomputed_gi = mix(lerp_bottom, lerp_top, fract_coord.z); + + vec3 basecolor = textureLod(p3d_Texture0, ms_uv, 0).xyz; + // basecolor = vec3(0.8); + + + // Shadows + vec4 projected = shadowMVP * vec4(ws_position, 1); + vec3 shadow_space_pos = projected.xyz / projected.w * 0.5 + 0.5; + + float actual_depth = textureLod(ShadowMap, shadow_space_pos.xy, 0).x; + + const float bias = 0.001; + float shadow = actual_depth >= shadow_space_pos.z - bias ? 1.0 : 0.0; + float NxL = max(0, dot(sunVector, ws_normal)); + const vec3 sun_color = vec3(1.4, 1.2, 1.0); + + color = vec3(basecolor * precomputed_gi + basecolor * shadow * sun_color * NxL); + color = pow(color, vec3(1.0 / 2.2)); +} diff --git a/toolkit/bake_gi/resources/display.vert.glsl b/toolkit/bake_gi/resources/display.vert.glsl new file mode 100644 index 0000000..0c7f497 --- /dev/null +++ b/toolkit/bake_gi/resources/display.vert.glsl @@ -0,0 +1,20 @@ +#version 430 + +in vec4 p3d_Vertex; +in vec3 p3d_Normal; +in vec2 p3d_MultiTexCoord0; + +uniform mat4 p3d_ViewProjectionMatrix; +uniform mat4 p3d_ModelMatrix; +uniform mat3 tpose_world_to_model; + +out vec3 ws_position; +out vec3 ws_normal; +out vec2 ms_uv; + +void main() { + ms_uv = p3d_MultiTexCoord0; + ws_normal = normalize(tpose_world_to_model * p3d_Normal).xyz; + ws_position = (p3d_ModelMatrix * p3d_Vertex).xyz; + gl_Position = p3d_ViewProjectionMatrix * vec4(ws_position, 1); +} diff --git a/toolkit/bake_gi/resources/first-bounce.frag.glsl b/toolkit/bake_gi/resources/first-bounce.frag.glsl new file mode 100644 index 0000000..e5d5899 --- /dev/null +++ b/toolkit/bake_gi/resources/first-bounce.frag.glsl @@ -0,0 +1,32 @@ +#version 430 + +in vec3 ws_position; +in vec3 ws_normal; +in vec2 ws_uv; + +uniform sampler2D p3d_Texture0; +uniform sampler2D ShadowMap; +uniform mat4 shadowMVP; +uniform vec3 sunVector; + +out vec4 color; + +const vec3 sun_color = vec3(1.4, 1.1, 1.0) * 1; + +void main() { + vec4 projected = shadowMVP * vec4(ws_position, 1); + vec3 shadow_space_pos = projected.xyz / projected.w * 0.5 + 0.5; + + float actual_depth = textureLod(ShadowMap, shadow_space_pos.xy, 0).x; + + const float bias = 0.001; + float shadow = actual_depth >= shadow_space_pos.z - bias ? 1.0 : 0.0; + + float NxL = max(0.0, dot(ws_normal, sunVector)); + vec3 basecolor = texture(p3d_Texture0, ws_uv).xyz; + // basecolor = vec3(0.8); + + vec3 ambient = vec3(0.0001) * basecolor; + + color = vec4(basecolor * NxL * shadow * sun_color + ambient, 1); +} diff --git a/toolkit/bake_gi/resources/first-bounce.vert.glsl b/toolkit/bake_gi/resources/first-bounce.vert.glsl new file mode 100644 index 0000000..0c7f497 --- /dev/null +++ b/toolkit/bake_gi/resources/first-bounce.vert.glsl @@ -0,0 +1,20 @@ +#version 430 + +in vec4 p3d_Vertex; +in vec3 p3d_Normal; +in vec2 p3d_MultiTexCoord0; + +uniform mat4 p3d_ViewProjectionMatrix; +uniform mat4 p3d_ModelMatrix; +uniform mat3 tpose_world_to_model; + +out vec3 ws_position; +out vec3 ws_normal; +out vec2 ms_uv; + +void main() { + ms_uv = p3d_MultiTexCoord0; + ws_normal = normalize(tpose_world_to_model * p3d_Normal).xyz; + ws_position = (p3d_ModelMatrix * p3d_Vertex).xyz; + gl_Position = p3d_ViewProjectionMatrix * vec4(ws_position, 1); +} diff --git a/toolkit/day_time_editor/curve_widget.py b/toolkit/day_time_editor/curve_widget.py new file mode 100644 index 0000000..594c7cb --- /dev/null +++ b/toolkit/day_time_editor/curve_widget.py @@ -0,0 +1,344 @@ +""" + +RenderPipeline + +Copyright (c) 2014-2016 tobspr + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. + +""" + +from __future__ import print_function +from rplibs.six.moves import range # pylint: disable=import-error + +import math + +from rplibs.pyqt_imports import * # noqa + +class CurveWidget(QWidget): + + """ This is a resizeable Widget which shows an editable curve which can + be modified. """ + + def __init__(self, parent): + """ Constructs the CurveWidget, we start with an initial curve """ + QWidget.__init__(self, parent) + self.setFocusPolicy(Qt.ClickFocus) + self._curves = [] + + # Store current display time + self._current_time = 0.5 + + # Widget render constants + self._cv_point_size = 3 + self._legend_border = 52 + self._bar_h = 30 + + # Currently dragged control point, format is: + # (CurveIndex, PointIndex, Drag-Offset (x,y)) + self._drag_point = None + self._drag_time = 0.0 + + # Currently selected control point, format is: + # (CurveIndex, PointIndex) + self._selected_point = None + + self._unit_processor = lambda v: str(round(v, 2)) + self._change_handler = lambda: None + + def set_unit_processor(self, proc): + """ Sets the function which gets called to map values from 0 .. 1 to + values like 10% to 30% """ + self._unit_processor = proc + + def set_change_handler(self, handler): + """ Sets a function which gets called when the data in this widget got + edited """ + self._change_handler = handler + + def paintEvent(self, e): # noqa + """ Internal QT paint event, draws the entire widget """ + qp = QPainter() + qp.begin(self) + self._draw(qp) + qp.end() + + def mousePressEvent(self, QMouseEvent): # noqa + """ Internal mouse-press handler """ + self._drag_point = None + self._selected_point = None + mouse_pos = QMouseEvent.pos() + mouse_x = mouse_pos.x() - self._legend_border + mouse_y = mouse_pos.y() - self._bar_h + + for index, curve in enumerate(self._curves): + + # Check for clicks on control points + for cv_index, (x, y) in enumerate(curve.control_points): + point_x = self._get_x_value_for(x) + point_y = self._get_y_value_for(y) - self._bar_h + if abs(point_x - mouse_x) < self._cv_point_size + 6: + if (abs(point_y - mouse_y)) < self._cv_point_size + 6: + drag_x_offset = mouse_x - point_x + drag_y_offset = mouse_y - point_y + mpos_relx = float(mouse_x) / (self.width() - self._legend_border) + self._drag_point = (index, cv_index, (drag_x_offset, drag_y_offset)) + self._drag_time = mpos_relx + self._selected_point = (index, cv_index) + + # If still no intersection, check if we clicked a curve + if mouse_x > 0 and mouse_x < self.width() - self._legend_border: + if mouse_y > 0 and mouse_y < self.height() - self._legend_border: + mpos_relx = float(mouse_x) / (self.width() - self._legend_border) + curve_py = curve.get_value(mpos_relx) + curve_offy = self._get_y_value_for(curve_py) - self._bar_h + + if abs(curve_offy - mouse_y) < 8 and self._selected_point is None: + # Clicked on curve, spawn new point + cv_index = curve.append_cv(mpos_relx, curve_py) + + self._selected_point = (index, cv_index) + self._drag_point = (index, cv_index, (0, 0)) + self._drag_time = mpos_relx + self._change_handler() + self.update() + + def mouseReleaseEvent(self, event): # noqa + """ Internal mouse-release handler """ + self._drag_point = None + self._drag_time = -1 + self.update() + + def mouseMoveEvent(self, event): # noqa + """ Internal mouse-move handler """ + if len(self._curves) < 1: + return + + if self._drag_point is not None: + mouse_x = event.pos().x() - self._drag_point[2][0] - self._legend_border + mouse_y = event.pos().y() - self._drag_point[2][1] - self._bar_h + + # Convert to local coordinate + local_x = max(0, min(1, mouse_x / float(self.width() - self._legend_border))) + local_y = mouse_y / float(self.height() - self._legend_border - self._bar_h) + local_y = 1 - max(0, min(1, local_y)) + + self._drag_time = local_x + + # Set new point data + self._curves[self._drag_point[0]].set_cv_value(self._drag_point[1], local_x, local_y) + + # Redraw curve + self._curves[self._drag_point[0]].build_curve() + self.update() + self._change_handler() + + def keyPressEvent(self, event): # noqa + """ Internal keypress handler """ + # Delete anchor point + if event.key() == Qt.Key_Delete: + self.delete_current_point() + + def delete_current_point(self): + """ Deletes the currently selected point """ + if self._selected_point is not None: + self._curves[self._selected_point[0]].remove_cv(self._selected_point[1]) + self._selected_point = None + self._drag_point = None + self.update() + self._change_handler() + + def set_curves(self, curves): + """ Sets the list of displayed curves """ + self._selected_point = None + self._drag_point = None + self._curves = curves + self.update() + + def _get_y_value_for(self, local_value): + """ Converts a value from 0 to 1 to a value from 0 .. canvas height """ + local_value = max(0, min(1.0, 1.0 - local_value)) + local_value *= self.height() - self._legend_border - self._bar_h + local_value += self._bar_h + return local_value + + def _get_x_value_for(self, local_value): + """ Converts a value from 0 to 1 to a value from 0 .. canvas width """ + local_value = max(0, min(1.0, local_value)) + local_value *= self.width() - self._legend_border + return local_value + + def set_current_time(self, local_time): + """ Sets the current displayed time, should range from 0 to 1 """ + self._current_time = max(0.0, min(1.0, local_time)) + self.update() + + def _draw(self, painter): + """ Internal method to draw the widget """ + + canvas_width = self.width() - self._legend_border + canvas_height = self.height() - self._legend_border - self._bar_h + + # Draw field background + # painter.setPen(QColor(200, 200, 200)) + # painter.setBrush(QColor(230, 230, 230)) + # painter.drawRect(0, 0, self.width() - 1, self.height() - 1) + + # Draw legend + + # Compute amount of horizontal / vertical lines + num_vert_lines = 12 # 24 / 12 = 2, one entry per 2 hours + line_spacing_x = (self.width() - self._legend_border) / num_vert_lines + line_spacing_y = (self.height() - self._legend_border - self._bar_h) / 20.0 + num_horiz_lines = int(math.ceil(canvas_height / float(line_spacing_y)) + 1) + + # Draw vertical lines + painter.setPen(QColor(200, 200, 200)) + for i in range(num_vert_lines + 1): + line_pos = i * line_spacing_x + self._legend_border - 1 + painter.drawLine( + int(line_pos), int(self._bar_h), + int(line_pos), int(canvas_height + self._bar_h)) + + # Draw horizontal lines + painter.setPen(QColor(200, 200, 200)) + for i in range(num_horiz_lines): + line_pos = canvas_height - i * line_spacing_y + self._bar_h + painter.drawLine( + int(self._legend_border), int(line_pos), + int(self.width()), int(line_pos)) + + # Draw vetical legend labels + painter.setPen(QColor(120, 120, 120)) + for i in range(num_horiz_lines): + line_pos = canvas_height - i * line_spacing_y + self._bar_h + # painter.drawText(6, line_pos + 3, str(round(float(i) / (num_horiz_lines-1), 2))) + painter.drawText( + 6, int(line_pos + 3), self._unit_processor(float(i) / (num_horiz_lines - 1))) + + # Draw horizontal legend labels + for i in range(num_vert_lines + 1): + line_pos = i * line_spacing_x + self._legend_border + offpos_x = -14 + if i == 0: + offpos_x = -2 + elif i == num_vert_lines: + offpos_x = -27 + time_string = str(int(float(i) / num_vert_lines * 24)).zfill(2) + ":00" + painter.drawText( + int(line_pos + offpos_x), int(canvas_height + self._bar_h + 18), time_string) + + # Draw curve + for index, curve in enumerate(self._curves): + painter.setPen(QColor(*curve.color)) + last_value = 0 + for i in range(canvas_width): + rel_offset = i / (canvas_width - 1.0) + curve_height = self._get_y_value_for(curve.get_value(rel_offset)) + + if i == 0: + last_value = curve_height + + painter.drawLine( + int(self._legend_border + i - 1), int(last_value), + int(self._legend_border + i), int(curve_height)) + last_value = curve_height + + # Draw the CV points of the curve + painter.setBrush(QColor(240, 240, 240)) + + for cv_index, (x, y) in enumerate(curve.control_points): + offs_x = x * canvas_width + self._legend_border + offs_y = (1 - y) * canvas_height + self._bar_h + + if (self._selected_point and self._selected_point[0] == index and + self._selected_point[1] == cv_index): + painter.setPen(QColor(255, 0, 0)) + else: + painter.setPen(QColor(100, 100, 100)) + painter.drawRect( + int(offs_x - self._cv_point_size), int(offs_y - self._cv_point_size), + int(2 * self._cv_point_size), int(2 * self._cv_point_size)) + + # Draw bar background + bar_half_height = 4 + bar_top_pos = 10 + + painter.setBrush(QColor(255, 0, 0)) + painter.setPen(QColor(110, 110, 110)) + + painter.drawRect( + int(self._legend_border - 1), int(bar_top_pos - 1), + int(self.width() - self._legend_border), int(2 * bar_half_height + 2)) + + # Draw bar + if len(self._curves) == 0: + return + + if len(self._curves) == 1: + bar_curve = self._curves[0] + else: + bar_curve = self._curves[0:3] + + for i in range(canvas_width - 1): + xpos = self._legend_border + i + relv = float(i) / float(canvas_width) + + if len(self._curves) == 1: + val = max(0, min(255, int(bar_curve.get_value(relv) * 255.0))) + painter.setPen(QColor(val, val, val)) + else: + r = max(0, min(255, int(bar_curve[0].get_value(relv) * 255.0))) + g = max(0, min(255, int(bar_curve[1].get_value(relv) * 255.0))) + b = max(0, min(255, int(bar_curve[2].get_value(relv) * 255.0))) + painter.setPen(QColor(r, g, b)) + painter.drawLine(xpos, bar_top_pos, xpos, bar_top_pos + 2 * bar_half_height) + + # Draw selected time + if self._drag_point: + painter.setBrush(QColor(200, 200, 200)) + painter.setPen(QColor(90, 90, 90)) + offs_x = max(0, min( + canvas_width + 10, self._drag_time * canvas_width + self._legend_border - 19)) + offs_y = self.height() - self._legend_border + minutes = int(self._drag_time * 24 * 60) + hours = minutes / 60 + minutes = minutes % 60 + painter.drawRect(offs_x, self.height() - self._legend_border + 5, 40, 20) + painter.drawText(offs_x + 7, offs_y + 20, "{:02}:{:02}".format(hours, minutes)) + + painter.setPen(QColor(150, 150, 150)) + painter.drawLine( + offs_x + 19, bar_top_pos + 15, offs_x + 19, self.height() - self._legend_border + 5) + + # Display current time + pen = QPen() + pen.setColor(QColor(255, 100, 100)) + pen.setStyle(Qt.DashLine) + painter.setPen(pen) + + xoffs = self._legend_border + self._current_time * (canvas_width - 1) + painter.drawLine(int(xoffs), int(self._bar_h), int(xoffs), int(self._bar_h + canvas_height)) + + # Draw usage hints + painter.setPen(QColor(100, 100, 100)) + painter.drawText( + 5, self.height() - 2, + "Click on the curve to add new control points, click and drag " + "existing points to move them.") diff --git a/toolkit/day_time_editor/main.py b/toolkit/day_time_editor/main.py new file mode 100644 index 0000000..ab1cf30 --- /dev/null +++ b/toolkit/day_time_editor/main.py @@ -0,0 +1,295 @@ +""" + +RenderPipeline + +Copyright (c) 2014-2016 tobspr + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. + +""" + +# This tool offers an interface to configure the time of day settings + + +from __future__ import print_function, division + +import os +import sys +import time +from threading import Thread + +# Change to the current directory +os.chdir(os.path.join(os.path.dirname(os.path.realpath(__file__)))) + +# Add the render pipeline to the path +sys.path.insert(0, "../../") + +from rplibs.six import iteritems # noqa +from rplibs.pyqt_imports import * # noqa + +from curve_widget import CurveWidget # noqa + +from rpcore.pluginbase.manager import PluginManager # noqa +from rpcore.mount_manager import MountManager # noqa +from rpcore.util.network_communication import NetworkCommunication # noqa + +from ui.main_window_generated import Ui_MainWindow # noqa +from ui.point_insert_dialog_generated import Ui_Dialog as Ui_PointDialog # noqa + +class PointDialog(QDialog, Ui_PointDialog): + + def __init__(self, parent): + QDialog.__init__(self, parent) + self.setupUi(self) + qt_connect(self.btn_insert, "clicked()", lambda: self.done(1)) + + def get_value(self): + time = self.ipt_time.time() + val = self.ipt_value.value() + return time, val + + +class DayTimeEditor(QMainWindow, Ui_MainWindow): + + """ This is the main editor class which handles the user interface """ + + def __init__(self): + + # Init mounts + self._mount_mgr = MountManager(None) + self._mount_mgr.mount() + + self._plugin_mgr = PluginManager(None) + self._plugin_mgr.load() + + QMainWindow.__init__(self) + self.setupUi() + self._tree_widgets = [] + self._cmd_queue = set() + + self._selected_setting_handle = None + self._selected_setting = None + self._selected_plugin = None + self._current_time = 0.5 + + self._update_settings_list() + self._on_time_changed(self.time_slider.value()) + + self._bg_thread = Thread(target=self.updateThread) + self._bg_thread.start() + + def set_settings_visible(self, visibility): + if not visibility: + self.frame_current_setting.hide() + else: + self.frame_current_setting.show() + + def closeEvent(self, event): # noqa + event.accept() + import os + os._exit(1) + + def updateThread(self): # noqa + """ Seperate update thread """ + + while True: + if self._cmd_queue: + cmd = self._cmd_queue.pop() + if cmd == "settime": + NetworkCommunication.send_async( + NetworkCommunication.DAYTIME_PORT, "settime " + str(self._current_time)) + continue + elif cmd == "write_settings": + self._plugin_mgr.save_daytime_overrides("/$$rpconfig/daytime.yaml") + NetworkCommunication.send_async( + NetworkCommunication.DAYTIME_PORT, "loadconf") + else: + print("Unkown cmd:", cmd) + + time.sleep(0.1) + + def setupUi(self): # noqa + """ Setups the UI Components """ + Ui_MainWindow.setupUi(self, self) + self.settings_tree.setColumnWidth(0, 160) + self.settings_tree.expandAll() + + self.edit_widget = CurveWidget(self) + self.edit_widget.set_change_handler(self._on_curve_edited) + self.prefab_edit_widget.addWidget(self.edit_widget) + + qt_connect(self.time_slider, "valueChanged(int)", self._on_time_changed) + qt_connect(self.settings_tree, "itemSelectionChanged()", self._on_setting_selected) + qt_connect(self.btn_insert_point, "clicked()", self._insert_point) + qt_connect(self.btn_reset, "clicked()", self._reset_settings) + + def _reset_settings(self): + """ Resets the current plugins settings """ + # QMessageBox.warning(self, "Houston, we have a problem!", + # "This functionality is not yet implemented! Blame tobspr if you need it.\n\n" + # "On a more serious note, you can still hand-edit config/daytime.yaml.", + # QMessageBox.Ok, QMessageBox.Ok) + + # Ask the user if he's really sure about it + msg = "Are you sure you want to reset the control points of '" +\ + self._selected_setting_handle.label + "'?\n" + msg += "!! This cannot be undone !! They will be lost forever (a long time!)." + reply = QMessageBox.question( + self, "Warning", msg, QMessageBox.Yes, QMessageBox.No) + if reply == QMessageBox.Yes: + + QMessageBox.information(self, "Success", "Control points have been reset!") + default = self._selected_setting_handle.default + self._selected_setting_handle.curves[0].set_single_value(default) + self._update_settings_list() + self._cmd_queue.add("write_settings") + + def _insert_point(self): + """ Asks the user to insert a new point """ + dialog = PointDialog(self) + if dialog.exec_(): + time, val = dialog.get_value() + minutes = (time.hour() * 60 + time.minute()) / (24 * 60) + + if (val < self._selected_setting_handle.minvalue or + val > self._selected_setting_handle.maxvalue): + QMessageBox.information( + self, "Invalid Value", "Value is out of setting range!", QMessageBox.Ok) + return + + val_linear = self._selected_setting_handle.get_linear_value(val) + self._selected_setting_handle.curves[0].append_cv(minutes, val_linear) + self._cmd_queue.add("write_settings") + + def _update_tree_widgets(self): + """ Updates the tree widgets """ + for setting_handle, widget in self._tree_widgets: + value = setting_handle.get_scaled_value_at(self._current_time) + formatted = setting_handle.format(value) + widget.setText(1, formatted) + + if setting_handle.type == "color": + # QColor wants integers; day time settings store 0..1 floats. + rgb = [int(v * 255) if isinstance(v, float) else int(v) for v in value] + widget.setBackground(1, QBrush(QColor(*rgb))) + + def _on_curve_edited(self): + """ Called when the curve got edited in the curve widget """ + self._cmd_queue.add("write_settings") + self._update_tree_widgets() + + def _on_setting_selected(self): + """ Called when a setting got selected in the settings tree """ + selected = self.settings_tree.selectedItems() + if len(selected) != 1: + self._selected_setting = None + self._selected_plugin = None + self._selected_setting_handle = None + self.edit_widget.set_curves([]) + self.set_settings_visible(False) + else: + selected = selected[0] + + self._selected_plugin = selected._plugin_id + self._selected_setting = selected._setting_id + self._selected_setting_handle = selected._setting_handle + + self.lbl_current_setting.setText(self._selected_setting_handle.label) + self.lbl_setting_desc.setText(self._selected_setting_handle.description) + + self.edit_widget.set_curves(self._selected_setting_handle.curves) + + if self._selected_setting_handle.type == "color": + self.edit_widget.set_unit_processor(lambda x: str(int(x * 255))) + self.btn_insert_point.hide() + else: + self.edit_widget.set_unit_processor( + lambda x: self._selected_setting_handle.format( + self._selected_setting_handle.get_scaled_value(x))) + self.btn_insert_point.show() + + self.set_settings_visible(True) + self._update_tree_widgets() + + def _on_time_changed(self, val): + """ Handler when the time slider got moved """ + hour = val // (60 * 60 * 60) + minute = (val // (60 * 60)) % 60 + ftime = float(val) / (24 * 60 * 60 * 60) + + self.time_label.setText(str(hour).zfill(2) + ":" + str(minute).zfill(2)) + self.time_float_label.setText("{:1.4f}".format(ftime)) + self.edit_widget.set_current_time(ftime) + self._current_time = ftime + self._update_tree_widgets() + self._cmd_queue.add("settime") + + def _update_settings_list(self): + """ Updates the list of visible settings """ + + self.settings_tree.clear() + self._tree_widgets = [] + + first_item = None + + for plugin_id, plugin in iteritems(self._plugin_mgr.instances): + + daytime_settings = self._plugin_mgr.day_settings[plugin_id] + + if not daytime_settings: + # Skip plugins with empty settings + continue + + plugin_head = QTreeWidgetItem(self.settings_tree) + plugin_head.setText(0, plugin.name) + plugin_head.setFlags(Qt.ItemIsEnabled) + font = QFont() + font.setBold(True) + if not self._plugin_mgr.is_plugin_enabled(plugin_id): + plugin_head.setText(0, plugin.name) + plugin_head.setFont(0, font) + + # Display all settings + for setting, setting_handle in iteritems(daytime_settings): + setting_item = QTreeWidgetItem(plugin_head) + setting_item.setText(0, setting_handle.label) + if PYQT_VERSION == 4: + setting_item.setTextColor(0, QColor(150, 150, 150)) + else: + setting_item.setForeground(0, QColor(150, 150, 150)) + setting_item.setFlags(Qt.ItemIsEnabled | Qt.ItemIsSelectable) + setting_item._setting_id = setting + setting_item._setting_handle = setting_handle + setting_item._plugin_id = plugin_id + setting_item.setToolTip(0, setting_handle.description) + setting_item.setToolTip(1, setting_handle.description) + self._tree_widgets.append((setting_handle, setting_item)) + if not first_item: + first_item = setting_item + + self.settings_tree.expandAll() + if first_item: + self.settings_tree.setCurrentItem(first_item) + +# Start application +app = QApplication(sys.argv) +qt_register_fonts() +editor = DayTimeEditor() +editor.show() +app.exec_() diff --git a/toolkit/day_time_editor/ui/__init__.py b/toolkit/day_time_editor/ui/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/toolkit/day_time_editor/ui/compile_ui_qt4.bat b/toolkit/day_time_editor/ui/compile_ui_qt4.bat new file mode 100644 index 0000000..aba27fd --- /dev/null +++ b/toolkit/day_time_editor/ui/compile_ui_qt4.bat @@ -0,0 +1,10 @@ +@echo off + +rem Adjust the path to match your PyQt4 installation +SET PYQTPATH="C:\Projekte\Panda3D\built_x64\python\Lib\site-packages\PyQt4" + +python -m PyQt4.uic.pyuic --from-imports main_window.ui -o main_window_generated.py +python -m PyQt4.uic.pyuic --from-imports point_insert.ui -o point_insert_dialog_generated.py +"%PYQTPATH%\pyrcc4.exe" -py3 resources.qrc -o resources_rc.py + +pause diff --git a/toolkit/day_time_editor/ui/compile_ui_qt5.bat b/toolkit/day_time_editor/ui/compile_ui_qt5.bat new file mode 100644 index 0000000..0ac03bf --- /dev/null +++ b/toolkit/day_time_editor/ui/compile_ui_qt5.bat @@ -0,0 +1,7 @@ +@echo off + +python -m PyQt5.uic.pyuic --from-imports main_window.ui -o main_window_generated.py +python -m PyQt5.uic.pyuic --from-imports point_insert.ui -o point_insert_dialog_generated.py +python -m PyQt5.pyrcc_main resources.qrc -o resources_rc.py + +pause diff --git a/toolkit/day_time_editor/ui/main_window.ui b/toolkit/day_time_editor/ui/main_window.ui new file mode 100644 index 0000000..a249f51 --- /dev/null +++ b/toolkit/day_time_editor/ui/main_window.ui @@ -0,0 +1,1107 @@ + + + MainWindow + + + + 0 + 0 + 973 + 632 + + + + + 973 + 632 + + + + + 973 + 632 + + + + + + + + + 255 + 255 + 255 + + + + + + + 255 + 255 + 255 + + + + + + + 63 + 63 + 63 + + + + + + + 52 + 52 + 52 + + + + + + + 21 + 21 + 21 + + + + + + + 28 + 28 + 28 + + + + + + + 255 + 255 + 255 + + + + + + + 255 + 255 + 255 + + + + + + + 255 + 255 + 255 + + + + + + + 255 + 255 + 255 + + + + + + + 255 + 255 + 255 + + + + + + + 0 + 0 + 0 + + + + + + + 21 + 21 + 21 + + + + + + + 255 + 255 + 220 + + + + + + + 0 + 0 + 0 + + + + + + + + + 255 + 255 + 255 + + + + + + + 255 + 255 + 255 + + + + + + + 63 + 63 + 63 + + + + + + + 52 + 52 + 52 + + + + + + + 21 + 21 + 21 + + + + + + + 28 + 28 + 28 + + + + + + + 255 + 255 + 255 + + + + + + + 255 + 255 + 255 + + + + + + + 255 + 255 + 255 + + + + + + + 255 + 255 + 255 + + + + + + + 255 + 255 + 255 + + + + + + + 0 + 0 + 0 + + + + + + + 21 + 21 + 21 + + + + + + + 255 + 255 + 220 + + + + + + + 0 + 0 + 0 + + + + + + + + + 21 + 21 + 21 + + + + + + + 255 + 255 + 255 + + + + + + + 63 + 63 + 63 + + + + + + + 52 + 52 + 52 + + + + + + + 21 + 21 + 21 + + + + + + + 28 + 28 + 28 + + + + + + + 21 + 21 + 21 + + + + + + + 255 + 255 + 255 + + + + + + + 21 + 21 + 21 + + + + + + + 255 + 255 + 255 + + + + + + + 255 + 255 + 255 + + + + + + + 0 + 0 + 0 + + + + + + + 42 + 42 + 42 + + + + + + + 255 + 255 + 220 + + + + + + + 0 + 0 + 0 + + + + + + + + Day Time Editor + + + + :/res/res/icon.png:/res/res/icon.png + + + false + + + QMainWindow { background: #fff;} +*, QLabel { font-family: Roboto; font-weight: 300; } + +QScrollBar { + background: #eee; +} + + +QScrollBar:vertical { + width: 9px; + margin: 0; + } + + QScrollBar::handle:vertical { + min-height: 15px; + background: #aaa; + + } + + + QScrollBar::handle:vertical:hover { + + background: #999; + + } + QScrollBar::add-line:vertical { + } + + QScrollBar::sub-line:vertical { + } + + + QScrollBar::add-page:vertical { + background: #ddd; + + } + QScrollBar::sub-page:vertical { + background: #ddd; + } + + + + + + + 350 + 80 + 641 + 551 + + + + QFrame { background: #e5e5e5;} + + + QFrame::NoFrame + + + QFrame::Plain + + + + + 20 + 16 + 221 + 31 + + + + + Roboto + -1 + 37 + false + + + + color: #555; border: 0; font-size: 15px; text-transform: uppercase; + + + Occlusion Strength + + + + + + 500 + 14 + 101 + 31 + + + + QPushButton { +color: #eee; +background: #666; +border: 0; +} + +QPushButton:hover { + background: #555; +} + +QPushButton:pressed { + background: #111; +} + + + Reset curve + + + + + + 20 + 94 + 581 + 441 + + + + QFrame { +} + + + QFrame::StyledPanel + + + QFrame::Raised + + + + + 0 + 0 + 571 + 441 + + + + + 0 + + + + + + + + 20 + 50 + 571 + 41 + + + + + Roboto + 37 + false + + + + color: #888; + + + Description: Some Description about the setting, to give the user a rough idea what this does. This description may be so long, it can even go into the next line. + + + true + + + + + + 368 + 14 + 131 + 31 + + + + QPushButton { +color: #eee; +background: #666; +border: 0; +} + +QPushButton:hover { + background: #555; +} + +QPushButton:pressed { + background: #111; +} + + + Insert point from data + + + + + + + -1 + 80 + 351 + 551 + + + + background: #eee; + + + QFrame::StyledPanel + + + QFrame::Raised + + + + + 14 + 20 + 311 + 511 + + + + QTreeWidget::item { +padding: 7px 7px 6px; +background: #ddd; +outline: 0 !important; +margin-bottom: 1px; +margin-right: 0px; +color: #777; +border: 0; +border-radius: 0; +} + +QTreeWidget::item:hover { +background: #ccc; +} + +QTreeWidget::item:selected { +background: #555; +color: #eee; +} + +QTreeWidget { +padding: 0; +color: #eee; +background: transparent; + +} + +* { +outline: 0; +} + + + + + QFrame::NoFrame + + + Qt::ScrollBarAsNeeded + + + Qt::ScrollBarAsNeeded + + + QAbstractItemView::NoEditTriggers + + + false + + + false + + + QAbstractItemView::SelectRows + + + QAbstractItemView::ScrollPerPixel + + + 18 + + + true + + + false + + + true + + + false + + + true + + + false + + + true + + + true + + + false + + + false + + + 150 + + + false + + + + Setting + + + + + Value + + + + + Scattering + + + + Sun Height + + + 0,4 + + + + + Sun Color + + + [128, 255, 100] + + + + + Sun Angle + + + 180 ° + + + + + + Ambient Occlusion + + + + + + ItemIsSelectable|ItemIsDragEnabled|ItemIsUserCheckable|ItemIsEnabled|ItemIsTristate + + + + Occlusion Strength + + + 0.5 + + + + + + + + + 420 + 10 + 551 + 61 + + + + QFrame { + background: #fff; +} + + + + QFrame::NoFrame + + + QFrame::Plain + + + + + 10 + 11 + 521 + 20 + + + + 5184000 + + + 3600 + + + 3600 + + + 2592000 + + + true + + + Qt::Horizontal + + + false + + + false + + + QSlider::TicksBelow + + + 432000 + + + + + + 254 + 30 + 32 + 32 + + + + + + + :/res/res/12_00.png + + + + + + 341 + 30 + 32 + 32 + + + + + + + :/res/res/16_00.png + + + + + + 0 + 30 + 32 + 32 + + + + + + + :/res/res/0_00.png + + + + + + 84 + 30 + 32 + 32 + + + + + + + :/res/res/4_00.png + + + + + + 170 + 30 + 32 + 32 + + + + + + + :/res/res/8_00.png + + + + + + 422 + 30 + 32 + 32 + + + + + + + :/res/res/20_00.png + + + + + + 510 + 30 + 32 + 32 + + + + + + + :/res/res/0_00.png + + + + + + + 20 + 35 + 261 + 31 + + + + font-size: 20px; color: #2aa877; +font-weight: 100; + + + TIME OF DAY EDITOR + + + + + + 350 + 47 + 41 + 18 + + + + + Roboto + -1 + 37 + false + + + + color: #777; font-size: 12px; + + + 0.486 + + + + + + 350 + 20 + 81 + 31 + + + + + Roboto + -1 + 37 + false + + + + color: #444; font-size: 22px; + + + 11:15 + + + + + + 20 + 16 + 261 + 31 + + + + font-size: 13px; +color: #aaa; +font-weight: 600; + + + RENDER PIPELINE + + + frame_2 + frame_current_setting + frame_4 + label + time_float_label + time_label + label_9 + + + + + + + diff --git a/toolkit/day_time_editor/ui/main_window_generated.py b/toolkit/day_time_editor/ui/main_window_generated.py new file mode 100644 index 0000000..cbdd91e --- /dev/null +++ b/toolkit/day_time_editor/ui/main_window_generated.py @@ -0,0 +1,468 @@ +# -*- coding: utf-8 -*- + +# Form implementation generated from reading ui file 'main_window.ui' +# +# Created by: PyQt5 UI code generator 5.7 +# +# WARNING! All changes made in this file will be lost! + +from PyQt5 import QtCore, QtGui, QtWidgets + +class Ui_MainWindow(object): + def setupUi(self, MainWindow): + MainWindow.setObjectName("MainWindow") + MainWindow.resize(973, 632) + MainWindow.setMinimumSize(QtCore.QSize(973, 632)) + MainWindow.setMaximumSize(QtCore.QSize(973, 632)) + palette = QtGui.QPalette() + brush = QtGui.QBrush(QtGui.QColor(255, 255, 255)) + brush.setStyle(QtCore.Qt.SolidPattern) + palette.setBrush(QtGui.QPalette.Active, QtGui.QPalette.WindowText, brush) + brush = QtGui.QBrush(QtGui.QColor(255, 255, 255)) + brush.setStyle(QtCore.Qt.SolidPattern) + palette.setBrush(QtGui.QPalette.Active, QtGui.QPalette.Button, brush) + brush = QtGui.QBrush(QtGui.QColor(63, 63, 63)) + brush.setStyle(QtCore.Qt.SolidPattern) + palette.setBrush(QtGui.QPalette.Active, QtGui.QPalette.Light, brush) + brush = QtGui.QBrush(QtGui.QColor(52, 52, 52)) + brush.setStyle(QtCore.Qt.SolidPattern) + palette.setBrush(QtGui.QPalette.Active, QtGui.QPalette.Midlight, brush) + brush = QtGui.QBrush(QtGui.QColor(21, 21, 21)) + brush.setStyle(QtCore.Qt.SolidPattern) + palette.setBrush(QtGui.QPalette.Active, QtGui.QPalette.Dark, brush) + brush = QtGui.QBrush(QtGui.QColor(28, 28, 28)) + brush.setStyle(QtCore.Qt.SolidPattern) + palette.setBrush(QtGui.QPalette.Active, QtGui.QPalette.Mid, brush) + brush = QtGui.QBrush(QtGui.QColor(255, 255, 255)) + brush.setStyle(QtCore.Qt.SolidPattern) + palette.setBrush(QtGui.QPalette.Active, QtGui.QPalette.Text, brush) + brush = QtGui.QBrush(QtGui.QColor(255, 255, 255)) + brush.setStyle(QtCore.Qt.SolidPattern) + palette.setBrush(QtGui.QPalette.Active, QtGui.QPalette.BrightText, brush) + brush = QtGui.QBrush(QtGui.QColor(255, 255, 255)) + brush.setStyle(QtCore.Qt.SolidPattern) + palette.setBrush(QtGui.QPalette.Active, QtGui.QPalette.ButtonText, brush) + brush = QtGui.QBrush(QtGui.QColor(255, 255, 255)) + brush.setStyle(QtCore.Qt.SolidPattern) + palette.setBrush(QtGui.QPalette.Active, QtGui.QPalette.Base, brush) + brush = QtGui.QBrush(QtGui.QColor(255, 255, 255)) + brush.setStyle(QtCore.Qt.SolidPattern) + palette.setBrush(QtGui.QPalette.Active, QtGui.QPalette.Window, brush) + brush = QtGui.QBrush(QtGui.QColor(0, 0, 0)) + brush.setStyle(QtCore.Qt.SolidPattern) + palette.setBrush(QtGui.QPalette.Active, QtGui.QPalette.Shadow, brush) + brush = QtGui.QBrush(QtGui.QColor(21, 21, 21)) + brush.setStyle(QtCore.Qt.SolidPattern) + palette.setBrush(QtGui.QPalette.Active, QtGui.QPalette.AlternateBase, brush) + brush = QtGui.QBrush(QtGui.QColor(255, 255, 220)) + brush.setStyle(QtCore.Qt.SolidPattern) + palette.setBrush(QtGui.QPalette.Active, QtGui.QPalette.ToolTipBase, brush) + brush = QtGui.QBrush(QtGui.QColor(0, 0, 0)) + brush.setStyle(QtCore.Qt.SolidPattern) + palette.setBrush(QtGui.QPalette.Active, QtGui.QPalette.ToolTipText, brush) + brush = QtGui.QBrush(QtGui.QColor(255, 255, 255)) + brush.setStyle(QtCore.Qt.SolidPattern) + palette.setBrush(QtGui.QPalette.Inactive, QtGui.QPalette.WindowText, brush) + brush = QtGui.QBrush(QtGui.QColor(255, 255, 255)) + brush.setStyle(QtCore.Qt.SolidPattern) + palette.setBrush(QtGui.QPalette.Inactive, QtGui.QPalette.Button, brush) + brush = QtGui.QBrush(QtGui.QColor(63, 63, 63)) + brush.setStyle(QtCore.Qt.SolidPattern) + palette.setBrush(QtGui.QPalette.Inactive, QtGui.QPalette.Light, brush) + brush = QtGui.QBrush(QtGui.QColor(52, 52, 52)) + brush.setStyle(QtCore.Qt.SolidPattern) + palette.setBrush(QtGui.QPalette.Inactive, QtGui.QPalette.Midlight, brush) + brush = QtGui.QBrush(QtGui.QColor(21, 21, 21)) + brush.setStyle(QtCore.Qt.SolidPattern) + palette.setBrush(QtGui.QPalette.Inactive, QtGui.QPalette.Dark, brush) + brush = QtGui.QBrush(QtGui.QColor(28, 28, 28)) + brush.setStyle(QtCore.Qt.SolidPattern) + palette.setBrush(QtGui.QPalette.Inactive, QtGui.QPalette.Mid, brush) + brush = QtGui.QBrush(QtGui.QColor(255, 255, 255)) + brush.setStyle(QtCore.Qt.SolidPattern) + palette.setBrush(QtGui.QPalette.Inactive, QtGui.QPalette.Text, brush) + brush = QtGui.QBrush(QtGui.QColor(255, 255, 255)) + brush.setStyle(QtCore.Qt.SolidPattern) + palette.setBrush(QtGui.QPalette.Inactive, QtGui.QPalette.BrightText, brush) + brush = QtGui.QBrush(QtGui.QColor(255, 255, 255)) + brush.setStyle(QtCore.Qt.SolidPattern) + palette.setBrush(QtGui.QPalette.Inactive, QtGui.QPalette.ButtonText, brush) + brush = QtGui.QBrush(QtGui.QColor(255, 255, 255)) + brush.setStyle(QtCore.Qt.SolidPattern) + palette.setBrush(QtGui.QPalette.Inactive, QtGui.QPalette.Base, brush) + brush = QtGui.QBrush(QtGui.QColor(255, 255, 255)) + brush.setStyle(QtCore.Qt.SolidPattern) + palette.setBrush(QtGui.QPalette.Inactive, QtGui.QPalette.Window, brush) + brush = QtGui.QBrush(QtGui.QColor(0, 0, 0)) + brush.setStyle(QtCore.Qt.SolidPattern) + palette.setBrush(QtGui.QPalette.Inactive, QtGui.QPalette.Shadow, brush) + brush = QtGui.QBrush(QtGui.QColor(21, 21, 21)) + brush.setStyle(QtCore.Qt.SolidPattern) + palette.setBrush(QtGui.QPalette.Inactive, QtGui.QPalette.AlternateBase, brush) + brush = QtGui.QBrush(QtGui.QColor(255, 255, 220)) + brush.setStyle(QtCore.Qt.SolidPattern) + palette.setBrush(QtGui.QPalette.Inactive, QtGui.QPalette.ToolTipBase, brush) + brush = QtGui.QBrush(QtGui.QColor(0, 0, 0)) + brush.setStyle(QtCore.Qt.SolidPattern) + palette.setBrush(QtGui.QPalette.Inactive, QtGui.QPalette.ToolTipText, brush) + brush = QtGui.QBrush(QtGui.QColor(21, 21, 21)) + brush.setStyle(QtCore.Qt.SolidPattern) + palette.setBrush(QtGui.QPalette.Disabled, QtGui.QPalette.WindowText, brush) + brush = QtGui.QBrush(QtGui.QColor(255, 255, 255)) + brush.setStyle(QtCore.Qt.SolidPattern) + palette.setBrush(QtGui.QPalette.Disabled, QtGui.QPalette.Button, brush) + brush = QtGui.QBrush(QtGui.QColor(63, 63, 63)) + brush.setStyle(QtCore.Qt.SolidPattern) + palette.setBrush(QtGui.QPalette.Disabled, QtGui.QPalette.Light, brush) + brush = QtGui.QBrush(QtGui.QColor(52, 52, 52)) + brush.setStyle(QtCore.Qt.SolidPattern) + palette.setBrush(QtGui.QPalette.Disabled, QtGui.QPalette.Midlight, brush) + brush = QtGui.QBrush(QtGui.QColor(21, 21, 21)) + brush.setStyle(QtCore.Qt.SolidPattern) + palette.setBrush(QtGui.QPalette.Disabled, QtGui.QPalette.Dark, brush) + brush = QtGui.QBrush(QtGui.QColor(28, 28, 28)) + brush.setStyle(QtCore.Qt.SolidPattern) + palette.setBrush(QtGui.QPalette.Disabled, QtGui.QPalette.Mid, brush) + brush = QtGui.QBrush(QtGui.QColor(21, 21, 21)) + brush.setStyle(QtCore.Qt.SolidPattern) + palette.setBrush(QtGui.QPalette.Disabled, QtGui.QPalette.Text, brush) + brush = QtGui.QBrush(QtGui.QColor(255, 255, 255)) + brush.setStyle(QtCore.Qt.SolidPattern) + palette.setBrush(QtGui.QPalette.Disabled, QtGui.QPalette.BrightText, brush) + brush = QtGui.QBrush(QtGui.QColor(21, 21, 21)) + brush.setStyle(QtCore.Qt.SolidPattern) + palette.setBrush(QtGui.QPalette.Disabled, QtGui.QPalette.ButtonText, brush) + brush = QtGui.QBrush(QtGui.QColor(255, 255, 255)) + brush.setStyle(QtCore.Qt.SolidPattern) + palette.setBrush(QtGui.QPalette.Disabled, QtGui.QPalette.Base, brush) + brush = QtGui.QBrush(QtGui.QColor(255, 255, 255)) + brush.setStyle(QtCore.Qt.SolidPattern) + palette.setBrush(QtGui.QPalette.Disabled, QtGui.QPalette.Window, brush) + brush = QtGui.QBrush(QtGui.QColor(0, 0, 0)) + brush.setStyle(QtCore.Qt.SolidPattern) + palette.setBrush(QtGui.QPalette.Disabled, QtGui.QPalette.Shadow, brush) + brush = QtGui.QBrush(QtGui.QColor(42, 42, 42)) + brush.setStyle(QtCore.Qt.SolidPattern) + palette.setBrush(QtGui.QPalette.Disabled, QtGui.QPalette.AlternateBase, brush) + brush = QtGui.QBrush(QtGui.QColor(255, 255, 220)) + brush.setStyle(QtCore.Qt.SolidPattern) + palette.setBrush(QtGui.QPalette.Disabled, QtGui.QPalette.ToolTipBase, brush) + brush = QtGui.QBrush(QtGui.QColor(0, 0, 0)) + brush.setStyle(QtCore.Qt.SolidPattern) + palette.setBrush(QtGui.QPalette.Disabled, QtGui.QPalette.ToolTipText, brush) + MainWindow.setPalette(palette) + icon = QtGui.QIcon() + icon.addPixmap(QtGui.QPixmap(":/res/res/icon.png"), QtGui.QIcon.Normal, QtGui.QIcon.Off) + MainWindow.setWindowIcon(icon) + MainWindow.setAutoFillBackground(False) + MainWindow.setStyleSheet("QMainWindow { background: #fff;}\n" +"*, QLabel { font-family: Roboto; font-weight: 300; }\n" +"\n" +"QScrollBar {\n" +" background: #eee;\n" +"}\n" +"\n" +"\n" +"QScrollBar:vertical {\n" +" width: 9px;\n" +" margin: 0;\n" +" }\n" +"\n" +" QScrollBar::handle:vertical {\n" +" min-height: 15px;\n" +" background: #aaa;\n" +"\n" +" }\n" +"\n" +"\n" +" QScrollBar::handle:vertical:hover {\n" +" \n" +" background: #999;\n" +"\n" +" }\n" +" QScrollBar::add-line:vertical {\n" +" }\n" +"\n" +" QScrollBar::sub-line:vertical {\n" +" }\n" +"\n" +"\n" +" QScrollBar::add-page:vertical {\n" +" background: #ddd;\n" +"\n" +" }\n" +" QScrollBar::sub-page:vertical {\n" +" background: #ddd;\n" +" }\n" +"") + self.centralwidget = QtWidgets.QWidget(MainWindow) + self.centralwidget.setObjectName("centralwidget") + self.frame_current_setting = QtWidgets.QFrame(self.centralwidget) + self.frame_current_setting.setGeometry(QtCore.QRect(350, 80, 641, 551)) + self.frame_current_setting.setStyleSheet("QFrame { background: #e5e5e5;}") + self.frame_current_setting.setFrameShape(QtWidgets.QFrame.NoFrame) + self.frame_current_setting.setFrameShadow(QtWidgets.QFrame.Plain) + self.frame_current_setting.setObjectName("frame_current_setting") + self.lbl_current_setting = QtWidgets.QLabel(self.frame_current_setting) + self.lbl_current_setting.setGeometry(QtCore.QRect(20, 16, 221, 31)) + font = QtGui.QFont() + font.setFamily("Roboto") + font.setPointSize(-1) + font.setBold(False) + font.setWeight(37) + self.lbl_current_setting.setFont(font) + self.lbl_current_setting.setStyleSheet("color: #555; border: 0; font-size: 15px; text-transform: uppercase;") + self.lbl_current_setting.setObjectName("lbl_current_setting") + self.btn_reset = QtWidgets.QPushButton(self.frame_current_setting) + self.btn_reset.setGeometry(QtCore.QRect(500, 14, 101, 31)) + self.btn_reset.setStyleSheet("QPushButton {\n" +"color: #eee;\n" +"background: #666;\n" +"border: 0; \n" +"}\n" +"\n" +"QPushButton:hover {\n" +" background: #555;\n" +"}\n" +"\n" +"QPushButton:pressed {\n" +" background: #111;\n" +"}") + self.btn_reset.setObjectName("btn_reset") + self.frame_3 = QtWidgets.QFrame(self.frame_current_setting) + self.frame_3.setGeometry(QtCore.QRect(20, 94, 581, 441)) + self.frame_3.setStyleSheet("QFrame {\n" +"}") + self.frame_3.setFrameShape(QtWidgets.QFrame.StyledPanel) + self.frame_3.setFrameShadow(QtWidgets.QFrame.Raised) + self.frame_3.setObjectName("frame_3") + self.verticalLayoutWidget = QtWidgets.QWidget(self.frame_3) + self.verticalLayoutWidget.setGeometry(QtCore.QRect(0, 0, 571, 441)) + self.verticalLayoutWidget.setObjectName("verticalLayoutWidget") + self.prefab_edit_widget = QtWidgets.QVBoxLayout(self.verticalLayoutWidget) + self.prefab_edit_widget.setContentsMargins(0, 0, 0, 0) + self.prefab_edit_widget.setSpacing(0) + self.prefab_edit_widget.setObjectName("prefab_edit_widget") + self.lbl_setting_desc = QtWidgets.QLabel(self.frame_current_setting) + self.lbl_setting_desc.setGeometry(QtCore.QRect(20, 50, 571, 41)) + font = QtGui.QFont() + font.setFamily("Roboto") + font.setBold(False) + font.setWeight(37) + self.lbl_setting_desc.setFont(font) + self.lbl_setting_desc.setStyleSheet("color: #888;") + self.lbl_setting_desc.setWordWrap(True) + self.lbl_setting_desc.setObjectName("lbl_setting_desc") + self.btn_insert_point = QtWidgets.QPushButton(self.frame_current_setting) + self.btn_insert_point.setGeometry(QtCore.QRect(368, 14, 131, 31)) + self.btn_insert_point.setStyleSheet("QPushButton {\n" +"color: #eee;\n" +"background: #666;\n" +"border: 0; \n" +"}\n" +"\n" +"QPushButton:hover {\n" +" background: #555;\n" +"}\n" +"\n" +"QPushButton:pressed {\n" +" background: #111;\n" +"}") + self.btn_insert_point.setObjectName("btn_insert_point") + self.frame_2 = QtWidgets.QFrame(self.centralwidget) + self.frame_2.setGeometry(QtCore.QRect(-1, 80, 351, 551)) + self.frame_2.setStyleSheet("background: #eee;") + self.frame_2.setFrameShape(QtWidgets.QFrame.StyledPanel) + self.frame_2.setFrameShadow(QtWidgets.QFrame.Raised) + self.frame_2.setObjectName("frame_2") + self.settings_tree = QtWidgets.QTreeWidget(self.frame_2) + self.settings_tree.setGeometry(QtCore.QRect(14, 20, 311, 511)) + self.settings_tree.setStyleSheet("QTreeWidget::item {\n" +"padding: 7px 7px 6px;\n" +"background: #ddd;\n" +"outline: 0 !important;\n" +"margin-bottom: 1px;\n" +"margin-right: 0px;\n" +"color: #777;\n" +"border: 0;\n" +"border-radius: 0;\n" +"}\n" +"\n" +"QTreeWidget::item:hover {\n" +"background: #ccc;\n" +"}\n" +"\n" +"QTreeWidget::item:selected {\n" +"background: #555;\n" +"color: #eee;\n" +"}\n" +"\n" +"QTreeWidget {\n" +"padding: 0;\n" +"color: #eee;\n" +"background: transparent;\n" +"\n" +"}\n" +"\n" +"* {\n" +"outline: 0;\n" +"}\n" +"\n" +"") + self.settings_tree.setFrameShape(QtWidgets.QFrame.NoFrame) + self.settings_tree.setVerticalScrollBarPolicy(QtCore.Qt.ScrollBarAsNeeded) + self.settings_tree.setHorizontalScrollBarPolicy(QtCore.Qt.ScrollBarAsNeeded) + self.settings_tree.setEditTriggers(QtWidgets.QAbstractItemView.NoEditTriggers) + self.settings_tree.setProperty("showDropIndicator", False) + self.settings_tree.setAlternatingRowColors(False) + self.settings_tree.setSelectionBehavior(QtWidgets.QAbstractItemView.SelectRows) + self.settings_tree.setVerticalScrollMode(QtWidgets.QAbstractItemView.ScrollPerPixel) + self.settings_tree.setIndentation(18) + self.settings_tree.setRootIsDecorated(True) + self.settings_tree.setUniformRowHeights(False) + self.settings_tree.setItemsExpandable(True) + self.settings_tree.setAnimated(True) + self.settings_tree.setAllColumnsShowFocus(False) + self.settings_tree.setWordWrap(True) + self.settings_tree.setHeaderHidden(True) + self.settings_tree.setObjectName("settings_tree") + item_0 = QtWidgets.QTreeWidgetItem(self.settings_tree) + item_1 = QtWidgets.QTreeWidgetItem(item_0) + item_1 = QtWidgets.QTreeWidgetItem(item_0) + item_1 = QtWidgets.QTreeWidgetItem(item_0) + item_0 = QtWidgets.QTreeWidgetItem(self.settings_tree) + item_0.setFlags(QtCore.Qt.ItemIsSelectable|QtCore.Qt.ItemIsDragEnabled|QtCore.Qt.ItemIsUserCheckable|QtCore.Qt.ItemIsEnabled|QtCore.Qt.ItemIsTristate) + item_1 = QtWidgets.QTreeWidgetItem(item_0) + self.settings_tree.header().setVisible(False) + self.settings_tree.header().setCascadingSectionResizes(False) + self.settings_tree.header().setDefaultSectionSize(150) + self.settings_tree.header().setStretchLastSection(False) + self.frame_4 = QtWidgets.QFrame(self.centralwidget) + self.frame_4.setGeometry(QtCore.QRect(420, 10, 551, 61)) + self.frame_4.setStyleSheet("QFrame {\n" +" background: #fff;\n" +"}\n" +"") + self.frame_4.setFrameShape(QtWidgets.QFrame.NoFrame) + self.frame_4.setFrameShadow(QtWidgets.QFrame.Plain) + self.frame_4.setObjectName("frame_4") + self.time_slider = QtWidgets.QSlider(self.frame_4) + self.time_slider.setGeometry(QtCore.QRect(10, 11, 521, 20)) + self.time_slider.setMaximum(5184000) + self.time_slider.setSingleStep(3600) + self.time_slider.setPageStep(3600) + self.time_slider.setProperty("value", 2592000) + self.time_slider.setTracking(True) + self.time_slider.setOrientation(QtCore.Qt.Horizontal) + self.time_slider.setInvertedAppearance(False) + self.time_slider.setInvertedControls(False) + self.time_slider.setTickPosition(QtWidgets.QSlider.TicksBelow) + self.time_slider.setTickInterval(432000) + self.time_slider.setObjectName("time_slider") + self.label_2 = QtWidgets.QLabel(self.frame_4) + self.label_2.setGeometry(QtCore.QRect(254, 30, 32, 32)) + self.label_2.setText("") + self.label_2.setPixmap(QtGui.QPixmap(":/res/res/12_00.png")) + self.label_2.setObjectName("label_2") + self.label_3 = QtWidgets.QLabel(self.frame_4) + self.label_3.setGeometry(QtCore.QRect(341, 30, 32, 32)) + self.label_3.setText("") + self.label_3.setPixmap(QtGui.QPixmap(":/res/res/16_00.png")) + self.label_3.setObjectName("label_3") + self.label_4 = QtWidgets.QLabel(self.frame_4) + self.label_4.setGeometry(QtCore.QRect(0, 30, 32, 32)) + self.label_4.setText("") + self.label_4.setPixmap(QtGui.QPixmap(":/res/res/0_00.png")) + self.label_4.setObjectName("label_4") + self.label_5 = QtWidgets.QLabel(self.frame_4) + self.label_5.setGeometry(QtCore.QRect(84, 30, 32, 32)) + self.label_5.setText("") + self.label_5.setPixmap(QtGui.QPixmap(":/res/res/4_00.png")) + self.label_5.setObjectName("label_5") + self.label_6 = QtWidgets.QLabel(self.frame_4) + self.label_6.setGeometry(QtCore.QRect(170, 30, 32, 32)) + self.label_6.setText("") + self.label_6.setPixmap(QtGui.QPixmap(":/res/res/8_00.png")) + self.label_6.setObjectName("label_6") + self.label_7 = QtWidgets.QLabel(self.frame_4) + self.label_7.setGeometry(QtCore.QRect(422, 30, 32, 32)) + self.label_7.setText("") + self.label_7.setPixmap(QtGui.QPixmap(":/res/res/20_00.png")) + self.label_7.setObjectName("label_7") + self.label_8 = QtWidgets.QLabel(self.frame_4) + self.label_8.setGeometry(QtCore.QRect(510, 30, 32, 32)) + self.label_8.setText("") + self.label_8.setPixmap(QtGui.QPixmap(":/res/res/0_00.png")) + self.label_8.setObjectName("label_8") + self.label = QtWidgets.QLabel(self.centralwidget) + self.label.setGeometry(QtCore.QRect(20, 35, 261, 31)) + self.label.setStyleSheet("font-size: 20px; color: #2aa877;\n" +"font-weight: 100;") + self.label.setObjectName("label") + self.time_float_label = QtWidgets.QLabel(self.centralwidget) + self.time_float_label.setGeometry(QtCore.QRect(350, 47, 41, 18)) + font = QtGui.QFont() + font.setFamily("Roboto") + font.setPointSize(-1) + font.setBold(False) + font.setWeight(37) + self.time_float_label.setFont(font) + self.time_float_label.setStyleSheet("color: #777; font-size: 12px;") + self.time_float_label.setObjectName("time_float_label") + self.time_label = QtWidgets.QLabel(self.centralwidget) + self.time_label.setGeometry(QtCore.QRect(350, 20, 81, 31)) + font = QtGui.QFont() + font.setFamily("Roboto") + font.setPointSize(-1) + font.setBold(False) + font.setWeight(37) + self.time_label.setFont(font) + self.time_label.setStyleSheet("color: #444; font-size: 22px;") + self.time_label.setObjectName("time_label") + self.label_9 = QtWidgets.QLabel(self.centralwidget) + self.label_9.setGeometry(QtCore.QRect(20, 16, 261, 31)) + self.label_9.setStyleSheet("font-size: 13px;\n" +"color: #aaa;\n" +"font-weight: 600;") + self.label_9.setObjectName("label_9") + self.frame_2.raise_() + self.frame_current_setting.raise_() + self.frame_4.raise_() + self.label.raise_() + self.time_float_label.raise_() + self.time_label.raise_() + self.label_9.raise_() + MainWindow.setCentralWidget(self.centralwidget) + + self.retranslateUi(MainWindow) + QtCore.QMetaObject.connectSlotsByName(MainWindow) + + def retranslateUi(self, MainWindow): + _translate = QtCore.QCoreApplication.translate + MainWindow.setWindowTitle(_translate("MainWindow", "Day Time Editor")) + self.lbl_current_setting.setText(_translate("MainWindow", "Occlusion Strength")) + self.btn_reset.setText(_translate("MainWindow", "Reset curve")) + self.lbl_setting_desc.setText(_translate("MainWindow", "Description: Some Description about the setting, to give the user a rough idea what this does. This description may be so long, it can even go into the next line.")) + self.btn_insert_point.setText(_translate("MainWindow", "Insert point from data")) + self.settings_tree.setSortingEnabled(False) + self.settings_tree.headerItem().setText(0, _translate("MainWindow", "Setting")) + self.settings_tree.headerItem().setText(1, _translate("MainWindow", "Value")) + __sortingEnabled = self.settings_tree.isSortingEnabled() + self.settings_tree.setSortingEnabled(False) + self.settings_tree.topLevelItem(0).setText(0, _translate("MainWindow", "Scattering")) + self.settings_tree.topLevelItem(0).child(0).setText(0, _translate("MainWindow", "Sun Height")) + self.settings_tree.topLevelItem(0).child(0).setText(1, _translate("MainWindow", "0,4")) + self.settings_tree.topLevelItem(0).child(1).setText(0, _translate("MainWindow", "Sun Color")) + self.settings_tree.topLevelItem(0).child(1).setText(1, _translate("MainWindow", "[128, 255, 100]")) + self.settings_tree.topLevelItem(0).child(2).setText(0, _translate("MainWindow", "Sun Angle")) + self.settings_tree.topLevelItem(0).child(2).setText(1, _translate("MainWindow", "180 °")) + self.settings_tree.topLevelItem(1).setText(0, _translate("MainWindow", "Ambient Occlusion")) + self.settings_tree.topLevelItem(1).child(0).setText(0, _translate("MainWindow", "Occlusion Strength")) + self.settings_tree.topLevelItem(1).child(0).setText(1, _translate("MainWindow", "0.5")) + self.settings_tree.setSortingEnabled(__sortingEnabled) + self.label.setText(_translate("MainWindow", "TIME OF DAY EDITOR")) + self.time_float_label.setText(_translate("MainWindow", "0.486")) + self.time_label.setText(_translate("MainWindow", "11:15")) + self.label_9.setText(_translate("MainWindow", "RENDER PIPELINE")) + +from . import resources_rc diff --git a/toolkit/day_time_editor/ui/point_insert.ui b/toolkit/day_time_editor/ui/point_insert.ui new file mode 100644 index 0000000..0c5b7ba --- /dev/null +++ b/toolkit/day_time_editor/ui/point_insert.ui @@ -0,0 +1,124 @@ + + + Dialog + + + + 0 + 0 + 342 + 197 + + + + + 342 + 197 + + + + + 342 + 197 + + + + Insert Point + + + + + 10 + 10 + 301 + 71 + + + + Enter the values of the point you want to insert. + +Did you know: If you dont want to enter concrete values, just click and drag anywhere on the curve to insert a new point. + + + true + + + + + + 10 + 100 + 46 + 21 + + + + Time: + + + + + + 10 + 130 + 46 + 21 + + + + Value: + + + + + + 70 + 130 + 121 + 22 + + + + 99999.990000000005239 + + + + + + 70 + 100 + 121 + 22 + + + + HH:mm + + + + + + 240 + 160 + 75 + 23 + + + + Qt::TabFocus + + + Insert + + + + + ipt_time + ipt_value + btn_insert + + + + + + diff --git a/toolkit/day_time_editor/ui/point_insert_dialog_generated.py b/toolkit/day_time_editor/ui/point_insert_dialog_generated.py new file mode 100644 index 0000000..ba19fa0 --- /dev/null +++ b/toolkit/day_time_editor/ui/point_insert_dialog_generated.py @@ -0,0 +1,55 @@ +# -*- coding: utf-8 -*- + +# Form implementation generated from reading ui file 'point_insert.ui' +# +# Created by: PyQt5 UI code generator 5.7 +# +# WARNING! All changes made in this file will be lost! + +from PyQt5 import QtCore, QtGui, QtWidgets + +class Ui_Dialog(object): + def setupUi(self, Dialog): + Dialog.setObjectName("Dialog") + Dialog.resize(342, 197) + Dialog.setMinimumSize(QtCore.QSize(342, 197)) + Dialog.setMaximumSize(QtCore.QSize(342, 197)) + self.label = QtWidgets.QLabel(Dialog) + self.label.setGeometry(QtCore.QRect(10, 10, 301, 71)) + self.label.setWordWrap(True) + self.label.setObjectName("label") + self.label_2 = QtWidgets.QLabel(Dialog) + self.label_2.setGeometry(QtCore.QRect(10, 100, 46, 21)) + self.label_2.setObjectName("label_2") + self.label_3 = QtWidgets.QLabel(Dialog) + self.label_3.setGeometry(QtCore.QRect(10, 130, 46, 21)) + self.label_3.setObjectName("label_3") + self.ipt_value = QtWidgets.QDoubleSpinBox(Dialog) + self.ipt_value.setGeometry(QtCore.QRect(70, 130, 121, 22)) + self.ipt_value.setMaximum(99999.99) + self.ipt_value.setObjectName("ipt_value") + self.ipt_time = QtWidgets.QTimeEdit(Dialog) + self.ipt_time.setGeometry(QtCore.QRect(70, 100, 121, 22)) + self.ipt_time.setObjectName("ipt_time") + self.btn_insert = QtWidgets.QPushButton(Dialog) + self.btn_insert.setGeometry(QtCore.QRect(240, 160, 75, 23)) + self.btn_insert.setFocusPolicy(QtCore.Qt.TabFocus) + self.btn_insert.setObjectName("btn_insert") + + self.retranslateUi(Dialog) + QtCore.QMetaObject.connectSlotsByName(Dialog) + Dialog.setTabOrder(self.ipt_time, self.ipt_value) + Dialog.setTabOrder(self.ipt_value, self.btn_insert) + + def retranslateUi(self, Dialog): + _translate = QtCore.QCoreApplication.translate + Dialog.setWindowTitle(_translate("Dialog", "Insert Point")) + self.label.setText(_translate("Dialog", "Enter the values of the point you want to insert. \n" +"\n" +"Did you know: If you dont want to enter concrete values, just click and drag anywhere on the curve to insert a new point.")) + self.label_2.setText(_translate("Dialog", "Time:")) + self.label_3.setText(_translate("Dialog", "Value:")) + self.ipt_time.setDisplayFormat(_translate("Dialog", "HH:mm")) + self.btn_insert.setText(_translate("Dialog", "Insert")) + +from . import resources_rc diff --git a/toolkit/day_time_editor/ui/res/0_00.png b/toolkit/day_time_editor/ui/res/0_00.png new file mode 100644 index 0000000..57af3ee Binary files /dev/null and b/toolkit/day_time_editor/ui/res/0_00.png differ diff --git a/toolkit/day_time_editor/ui/res/12_00.png b/toolkit/day_time_editor/ui/res/12_00.png new file mode 100644 index 0000000..3e023ec Binary files /dev/null and b/toolkit/day_time_editor/ui/res/12_00.png differ diff --git a/toolkit/day_time_editor/ui/res/16_00.png b/toolkit/day_time_editor/ui/res/16_00.png new file mode 100644 index 0000000..6266dca Binary files /dev/null and b/toolkit/day_time_editor/ui/res/16_00.png differ diff --git a/toolkit/day_time_editor/ui/res/20_00.png b/toolkit/day_time_editor/ui/res/20_00.png new file mode 100644 index 0000000..77ded06 Binary files /dev/null and b/toolkit/day_time_editor/ui/res/20_00.png differ diff --git a/toolkit/day_time_editor/ui/res/4_00.png b/toolkit/day_time_editor/ui/res/4_00.png new file mode 100644 index 0000000..d128fcf Binary files /dev/null and b/toolkit/day_time_editor/ui/res/4_00.png differ diff --git a/toolkit/day_time_editor/ui/res/8_00.png b/toolkit/day_time_editor/ui/res/8_00.png new file mode 100644 index 0000000..7064591 Binary files /dev/null and b/toolkit/day_time_editor/ui/res/8_00.png differ diff --git a/toolkit/day_time_editor/ui/res/daytime_editor_logo.png b/toolkit/day_time_editor/ui/res/daytime_editor_logo.png new file mode 100644 index 0000000..2d6a292 Binary files /dev/null and b/toolkit/day_time_editor/ui/res/daytime_editor_logo.png differ diff --git a/toolkit/day_time_editor/ui/res/icon.png b/toolkit/day_time_editor/ui/res/icon.png new file mode 100644 index 0000000..8ac6138 Binary files /dev/null and b/toolkit/day_time_editor/ui/res/icon.png differ diff --git a/toolkit/day_time_editor/ui/resources.qrc b/toolkit/day_time_editor/ui/resources.qrc new file mode 100644 index 0000000..29cbc9e --- /dev/null +++ b/toolkit/day_time_editor/ui/resources.qrc @@ -0,0 +1,14 @@ + + + res/0_00.png + res/4_00.png + res/8_00.png + res/12_00.png + res/16_00.png + res/20_00.png + res/icon.png + res/12_00.png + res/daytime_editor_logo.png + res/icon.png + + diff --git a/toolkit/day_time_editor/ui/resources_rc.py b/toolkit/day_time_editor/ui/resources_rc.py new file mode 100644 index 0000000..8683401 --- /dev/null +++ b/toolkit/day_time_editor/ui/resources_rc.py @@ -0,0 +1,1392 @@ +# -*- coding: utf-8 -*- + +# Resource object code +# +# Created by: The Resource Compiler for PyQt5 (Qt v5.7.0) +# +# WARNING! All changes made in this file will be lost! + +from PyQt5 import QtCore + +qt_resource_data = b"\ +\x00\x00\x03\x92\ +\x89\ +\x50\x4e\x47\x0d\x0a\x1a\x0a\x00\x00\x00\x0d\x49\x48\x44\x52\x00\ +\x00\x00\x20\x00\x00\x00\x20\x08\x06\x00\x00\x00\x73\x7a\x7a\xf4\ +\x00\x00\x00\x04\x73\x42\x49\x54\x08\x08\x08\x08\x7c\x08\x64\x88\ +\x00\x00\x00\x09\x70\x48\x59\x73\x00\x00\x0b\x13\x00\x00\x0b\x13\ +\x01\x00\x9a\x9c\x18\x00\x00\x03\x34\x49\x44\x41\x54\x58\x85\xed\ +\x95\x4f\x68\x14\x57\x1c\xc7\xbf\xbf\x37\x33\x49\x30\x71\xff\xcc\ +\xee\xcb\x8e\x2b\x71\xb2\xd9\xf1\x60\x1a\xa1\xd0\x43\x29\x68\x05\ +\xb1\xd4\xb3\x14\xc4\xe0\x29\x94\x56\x45\x54\x54\xea\xc9\x96\x82\ +\x50\x3d\x14\x52\x28\x2d\xbd\x04\x7b\x08\x85\x7a\x16\x3c\xa8\x54\ +\xa4\x39\xf8\x07\xdb\x6a\x25\x98\x75\x45\xbb\x26\x6b\x66\xb2\x6b\ +\x74\x5d\xb3\x66\xe7\xfd\x7a\x90\x15\xdd\x64\xb3\xb3\x58\x2c\xa5\ +\xf9\xde\x66\xde\xf7\x7d\x7f\x9f\x79\xef\xf7\xe6\x01\xcb\x5a\xd6\ +\x7f\x59\x8e\x69\x86\xfa\xa5\xec\x7a\x9d\x0c\xf1\x3a\x93\x59\x17\ +\x7b\xe7\x04\x76\xbf\x11\x80\x3e\xab\x7b\x57\xaa\x3b\x36\xf8\x0a\ +\x80\x80\x00\xa0\xbd\xfc\x2e\x95\x88\x0f\xa5\x12\xf1\xa1\x7f\x1c\ +\x40\x43\xf5\x02\x20\x4e\x38\xa6\x19\x7a\x01\xc0\x98\x24\xc2\x64\ +\xed\xd9\xb6\xc3\x11\x41\x74\x8c\x7c\x5c\x0c\x9e\x1b\x50\x85\xd2\ +\x53\xcf\xec\xea\x5c\x4d\xba\x16\x2e\x94\x9e\xfc\x01\x00\x0f\x9f\ +\x94\xaf\x15\x4b\xe5\xdf\x6b\x9e\x58\x47\x68\x07\x11\xe7\xb2\xd3\ +\xde\xcf\x41\x73\x69\xa9\x31\xc7\x34\x57\x66\x0a\x85\x47\xf5\x03\ +\xa9\x55\xf1\x8d\xc4\xd8\xce\xa0\xb7\x00\x80\x14\xdf\x24\xa6\xd1\ +\xdb\xae\x3b\x56\xef\x75\x4c\x33\xb4\x58\x46\x53\x80\xb5\x96\xb9\ +\x4e\x81\xce\x33\x8b\x61\xb1\x32\x3c\x9c\xc9\x64\x2a\x7d\xd1\x68\ +\x98\xdb\xb4\x93\xed\x6d\x3c\xb0\x73\x73\xe7\xe4\x86\x81\x8e\x18\ +\x00\x5c\xbc\x5e\x29\x8c\x9e\x2b\x25\x2b\xbe\xb8\x32\x47\xfa\xd0\ +\xd4\xd4\x54\xd9\x71\x9c\x76\x7e\x3c\x7b\x10\xa4\xf6\x71\x95\xde\ +\xcf\x7a\xde\x44\xab\x2b\x80\x74\x32\xda\x03\xa5\x9f\x60\xa8\x0b\ +\xd1\xfc\xcc\x48\xc1\x8a\xfd\xb2\x71\x7d\xfb\xfc\xb7\xfb\x23\x1b\ +\xda\x84\xf6\xca\xf6\x3d\xf3\x7d\xff\x93\xaf\x67\xc7\x2e\x8f\x57\ +\x2a\xb7\xf3\xde\xd6\x74\x42\xee\x01\xf0\xae\x30\xfc\x23\x13\xb9\ +\xc2\xfd\x96\x57\x60\x01\x8c\x25\x0f\xf7\x74\x6b\xdb\xce\x1c\x97\ +\xef\x2d\xe5\xdb\xf2\xd9\x83\xcb\x79\x8f\x4f\x66\xf2\xee\x77\x41\ +\x72\x83\xff\x07\x14\xef\xfd\x7e\x5f\x64\x75\x33\xdb\xf0\x2e\x53\ +\x32\x70\x20\x68\xec\xa2\x00\xef\x00\x86\x6d\x87\x23\xb6\x1d\x8e\ +\x00\x10\xe9\x64\xb4\xc7\x30\xc0\xa9\xa4\xb1\xa6\x59\xe0\x40\x9f\ +\xd1\xab\x69\xe8\xb0\xa5\xb4\x00\x68\xb5\x9c\x4d\x80\x1e\x18\xa0\ +\x68\xc5\x8f\xe8\x15\x7d\x5c\xaf\xe8\xe3\x7d\xdd\xf1\xed\xfe\xbc\ +\x6e\x76\x18\x78\x1c\xf4\xab\x42\x5d\x98\x68\xd3\xfc\x68\xda\x92\ +\x83\xb5\x9c\xbf\x12\xf2\xd0\x62\xde\x40\x3d\x60\x4b\x69\x19\x1a\ +\x5d\xbd\x31\x92\x48\x06\xf1\xaf\xff\x78\x72\xfa\xa9\x98\x5f\x97\ +\xcb\x3d\x2a\x34\xf3\x06\xea\x81\xbb\xae\x9b\xf7\xa1\x8a\xbf\xdd\ +\x7a\x36\xde\xcc\xfb\xeb\x8d\xb9\xeb\xaa\x2a\xee\x05\x29\x0e\x34\ +\x58\x01\xc7\x92\x7b\x18\xea\xf3\x7a\x2f\x13\x48\x23\xc0\x8a\xea\ +\x57\x4f\x1f\x8f\xdd\xda\xf1\x65\x71\x40\x37\x58\x8d\x1e\x8d\xff\ +\xf9\xc1\x21\xb7\xdf\x9b\xad\xbe\xed\x33\x40\x0c\x06\xc0\x2f\x4f\ +\x66\xe0\x8b\x6c\x7e\xe6\x87\x40\x00\x00\x44\xbf\x94\x2b\x1a\x51\ +\x87\x5c\xd7\x77\x2d\x39\xc2\xc0\x0a\x02\x34\xc5\x3c\xa3\x1e\x78\ +\x9f\x76\x4a\xb9\x68\xa3\x01\xc0\x4d\xd7\x2d\x03\x50\x41\x01\x00\ +\x00\xbd\x96\x65\x0b\xae\x2e\x3c\xf7\x44\x83\x0c\x94\xd7\xe4\xdd\ +\x9d\xf7\x1d\x47\x53\xa5\xd9\x53\xc4\x5c\x65\x60\xe1\x1d\x20\xfc\ +\xb1\xec\x54\xf1\x5e\xa3\x1a\x0d\x89\x9f\x0f\x56\x7b\x15\xd1\x96\ +\x3a\x62\x62\xf0\xa5\x3b\x79\xef\xab\x3b\x80\x8f\x4c\xa6\xba\x09\ +\xd8\x96\x4b\xc8\xa3\x44\xea\x43\x86\xf0\xeb\x52\x72\x00\x1a\x02\ +\xfc\xeb\x0a\x74\x0c\xd3\x96\x3c\xcc\xe0\x8f\x5a\x4a\x56\xf8\x29\ +\x3b\xed\x7d\xd3\xcc\xb6\xe4\x16\xd4\x44\xd0\x7e\x14\xc2\x3f\xdb\ +\x4a\x7d\x22\x3d\xd7\x8a\x7f\x59\xcb\xfa\xff\xea\x6f\xcd\x62\x28\ +\x7d\x4b\x8a\x77\x07\x00\x00\x00\x00\x49\x45\x4e\x44\xae\x42\x60\ +\x82\ +\x00\x00\x03\xe9\ +\x89\ +\x50\x4e\x47\x0d\x0a\x1a\x0a\x00\x00\x00\x0d\x49\x48\x44\x52\x00\ +\x00\x00\x20\x00\x00\x00\x20\x08\x06\x00\x00\x00\x73\x7a\x7a\xf4\ +\x00\x00\x00\x04\x73\x42\x49\x54\x08\x08\x08\x08\x7c\x08\x64\x88\ +\x00\x00\x00\x09\x70\x48\x59\x73\x00\x00\x0b\x13\x00\x00\x0b\x13\ +\x01\x00\x9a\x9c\x18\x00\x00\x03\x8b\x49\x44\x41\x54\x58\x85\xed\ +\x96\x5f\x68\xdb\x55\x14\xc7\xbf\xe7\xde\xdf\x2f\xc9\x7e\x69\x9b\ +\xa6\x69\xf2\x6b\xcc\xdc\xaf\x26\x6d\x61\x6b\x29\xcc\x8d\x81\x5b\ +\x5d\xa7\x3e\x14\x06\xb3\xe2\x98\x7f\x86\xa8\x0c\xe6\x54\x9c\xc5\ +\x09\x13\x8a\x8c\x22\x4c\xd0\x47\xc5\xfa\xa0\x20\x0a\x4a\x19\x3e\ +\x29\xc8\x64\x0c\x54\xc4\x3d\x0d\x1f\xca\xaa\xb0\xa6\x69\xba\x48\ +\xda\x25\xb4\x4b\xb7\xa6\x49\x93\xdf\x3d\x3e\x8c\xb4\x51\x97\x3f\ +\x85\x20\x88\xfd\xbe\xdd\x73\xbe\xf7\x9c\x0f\x87\x7b\x2f\x17\xd8\ +\xd2\x96\xfe\x83\x22\xcb\xb2\x5c\x8d\x2a\xa6\x6d\xc6\x1c\xf1\xfb\ +\xf7\x93\xc4\x88\x5a\xcb\xfe\x01\xe0\x4c\x23\x00\x44\xdd\xcd\x83\ +\xed\x27\xa5\x26\x2e\xb8\x74\xd9\x23\x18\x57\xee\xe9\x31\xfd\xa7\ +\xc3\xa6\x19\x68\x38\x40\x24\x10\x18\xd6\xa5\x36\xfa\xed\xc5\x57\ +\x65\x51\xa0\x89\x6d\xfc\xfa\xcf\xe6\xbe\x43\xcc\x78\x85\xa9\xf8\ +\x76\x43\x01\xc2\x5e\xaf\x87\x89\x3f\xfa\xfc\x8b\x17\x0a\xa1\x90\ +\xa7\xa3\xb8\xc6\x06\x49\x99\x29\xaf\x11\x31\xfd\xaf\x41\xc8\xaf\ +\xde\x79\xef\xfd\x65\xa7\xd3\x75\x38\x62\xfa\xc6\xc2\xa6\xbb\xae\ +\x49\xd4\x9e\x80\x43\x7b\xe9\xc1\xdd\xf7\x47\x7b\xfb\x83\xdd\x00\ +\xe0\x74\xd0\x9d\x02\x15\x7c\xa5\xb4\xe5\xf7\x07\x98\xd4\x49\xab\ +\x33\x1c\x3d\x76\xfc\xf8\xde\xd3\x23\x6f\x26\x41\x34\x20\x94\x71\ +\xb0\x1e\x80\x9a\x87\x90\x18\x4f\xbf\x71\xf6\x91\xa6\xd2\x7a\xfb\ +\x0e\x6f\x6a\xfa\x7a\x7a\x1f\x80\xdf\x01\x20\x9e\x4a\xcd\x5b\x96\ +\x67\x30\x36\x33\xfd\xd9\xd0\xc0\x81\x2b\x73\x37\x62\x21\x56\x72\ +\x38\x96\xba\x39\x59\x0f\x40\xd5\x09\x0c\x02\x1a\x4b\x74\xf7\xee\ +\x0a\xf6\x94\x62\xcf\x3c\xbb\x4f\x03\xf8\xb9\x72\x5f\x3c\x9e\xb9\ +\x65\x3b\x0b\x27\xe2\x37\x66\xbd\x60\x1a\x8d\xdd\xac\xaf\x79\x4d\ +\x80\x64\x30\xd8\x2a\x20\xee\x68\x9a\x46\xa5\xd8\xf0\x13\x7d\x7b\ +\x75\x87\x1e\x0e\x07\x02\x8f\x95\x7b\xe7\xe6\x32\x4b\x94\xb7\x0f\ +\xcc\x2c\xa4\x27\xea\x6d\x5e\x13\xe0\x36\x90\x85\x62\xa3\x3c\xe6\ +\x70\xe8\xf2\xc3\x0f\x9e\x5a\x85\xe4\x73\x3b\x5b\x5b\xad\xf2\xdc\ +\xcc\xd2\x52\x06\x9b\x54\xf5\x09\x24\x93\x59\x66\x95\x89\xc7\x6f\ +\x25\xca\xe3\x0f\x0d\x3c\xd0\x37\xfa\xd6\x90\xcc\xbb\xb4\x89\x48\ +\xd0\x3f\xb4\xd9\xa6\xe5\x92\xb5\x0c\x5e\xb7\xd1\x9d\xcf\x15\xe4\ +\xa1\x47\x7b\x3a\xcb\xe3\x7d\xfd\xf7\xed\xd8\xb3\xdb\xca\x5c\xfa\ +\xfe\xda\x91\x66\xe7\xb6\xa3\x6d\x2d\x86\xee\x6b\x31\xb8\xd9\x68\ +\x76\x05\x3c\x46\xa7\xc7\x30\x0e\xb7\xb9\x8d\x13\xfd\x2b\xd9\x4b\ +\x71\x40\x55\xaa\x4f\x95\x12\x25\x75\x77\xb4\xed\x54\xa4\x5d\xfe\ +\xe9\xe7\x33\x6e\x8f\xc7\xd5\xf2\xf7\x7c\xa1\xc0\xea\xbb\x8b\x93\ +\x57\x27\xbe\xbc\x9a\x8b\xcd\xa6\xda\xec\x9c\x32\x34\x97\xc8\xda\ +\xb6\x9d\xcf\xe5\xec\x6b\x33\xc9\xf4\xf3\xd5\xea\x57\x04\x18\x2c\ +\xbb\xa2\x89\x8e\xf6\xf3\xdb\x43\xde\x87\xbf\xfe\xe6\xe5\x3d\x12\ +\xaa\xe6\xd4\x62\xb3\x4b\xf1\x63\x4f\x7e\xea\x14\xb6\x3a\x12\x4a\ +\xa7\x27\x01\xe0\x47\xa0\x58\x37\x40\xd8\x6c\x7f\x1d\xc4\xef\xde\ +\x35\xd0\x2f\xc4\xac\x6c\xd0\xea\xdd\x2c\xbb\x88\xa8\x22\x84\x6d\ +\x53\x4e\x03\x08\x82\x0b\x4c\x68\x02\x78\x3f\x00\x08\x88\xb3\xd3\ +\xf3\xa9\xf1\x5a\xf0\xff\xba\xaa\x9e\x81\x88\x69\xf6\x2a\x52\x07\ +\x89\xd8\xb9\xbe\x81\x49\x03\xf3\x5c\x74\x21\x7d\xe1\x2f\x5e\x9f\ +\xef\x71\xe8\xd4\xc5\xb4\x71\xe0\x98\x29\xaf\xc1\xfe\xe1\xfa\xfc\ +\xe2\x6f\x95\x7a\x54\x7d\x8a\x99\x8a\xdb\x24\x09\x0f\x83\xd6\x3f\ +\x20\x24\x88\x55\x11\x47\x23\xa6\x7f\x57\x74\x21\x35\x06\x00\xe1\ +\x8e\xc0\x39\x56\xdc\x2b\x04\x4d\x11\x00\x28\x30\x00\x56\xc2\xd6\ +\x19\xa2\xea\xe7\xa5\xe6\x2d\xb8\x97\x2c\xcb\xd3\xaa\x67\x1d\x1f\ +\x2b\x0d\x51\xa1\x00\x26\x44\x68\xcd\x3e\x35\xbd\xb8\xb8\xbc\xd9\ +\x5a\x75\x01\x44\x4c\xff\x18\x98\x5f\x5c\x0f\x08\xba\xec\xb4\x31\ +\x92\x23\x1e\x27\x52\xc2\x0d\xfd\xd4\x6d\xd8\xe3\x82\x31\xb8\xe1\ +\xc1\x27\xd1\xf9\xf4\xf9\x86\x00\x74\x75\x75\x39\xc5\xca\x4a\x73\ +\x69\x9d\x95\x72\x25\x91\x48\xac\x62\xe3\x21\xb3\x83\xc1\xa0\xd1\ +\x0c\xac\x3f\xdb\x9a\x37\xb9\x3c\x35\x85\xb5\x7a\xea\x6f\x69\x4b\ +\xff\x6f\xfd\x09\xec\x59\x33\x5e\xbb\x11\x8b\x6a\x00\x00\x00\x00\ +\x49\x45\x4e\x44\xae\x42\x60\x82\ +\x00\x00\x17\x50\ +\x89\ +\x50\x4e\x47\x0d\x0a\x1a\x0a\x00\x00\x00\x0d\x49\x48\x44\x52\x00\ +\x00\x03\xe8\x00\x00\x00\x44\x08\x06\x00\x00\x00\x12\x95\x1f\xec\ +\x00\x00\x00\x09\x70\x48\x59\x73\x00\x00\x0b\x13\x00\x00\x0b\x13\ +\x01\x00\x9a\x9c\x18\x00\x00\x0a\x4f\x69\x43\x43\x50\x50\x68\x6f\ +\x74\x6f\x73\x68\x6f\x70\x20\x49\x43\x43\x20\x70\x72\x6f\x66\x69\ +\x6c\x65\x00\x00\x78\xda\x9d\x53\x67\x54\x53\xe9\x16\x3d\xf7\xde\ +\xf4\x42\x4b\x88\x80\x94\x4b\x6f\x52\x15\x08\x20\x52\x42\x8b\x80\ +\x14\x91\x26\x2a\x21\x09\x10\x4a\x88\x21\xa1\xd9\x15\x51\xc1\x11\ +\x45\x45\x04\x1b\xc8\xa0\x88\x03\x8e\x8e\x80\x8c\x15\x51\x2c\x0c\ +\x8a\x0a\xd8\x07\xe4\x21\xa2\x8e\x83\xa3\x88\x8a\xca\xfb\xe1\x7b\ +\xa3\x6b\xd6\xbc\xf7\xe6\xcd\xfe\xb5\xd7\x3e\xe7\xac\xf3\x9d\xb3\ +\xcf\x07\xc0\x08\x0c\x96\x48\x33\x51\x35\x80\x0c\xa9\x42\x1e\x11\ +\xe0\x83\xc7\xc4\xc6\xe1\xe4\x2e\x40\x81\x0a\x24\x70\x00\x10\x08\ +\xb3\x64\x21\x73\xfd\x23\x01\x00\xf8\x7e\x3c\x3c\x2b\x22\xc0\x07\ +\xbe\x00\x01\x78\xd3\x0b\x08\x00\xc0\x4d\x9b\xc0\x30\x1c\x87\xff\ +\x0f\xea\x42\x99\x5c\x01\x80\x84\x01\xc0\x74\x91\x38\x4b\x08\x80\ +\x14\x00\x40\x7a\x8e\x42\xa6\x00\x40\x46\x01\x80\x9d\x98\x26\x53\ +\x00\xa0\x04\x00\x60\xcb\x63\x62\xe3\x00\x50\x2d\x00\x60\x27\x7f\ +\xe6\xd3\x00\x80\x9d\xf8\x99\x7b\x01\x00\x5b\x94\x21\x15\x01\xa0\ +\x91\x00\x20\x13\x65\x88\x44\x00\x68\x3b\x00\xac\xcf\x56\x8a\x45\ +\x00\x58\x30\x00\x14\x66\x4b\xc4\x39\x00\xd8\x2d\x00\x30\x49\x57\ +\x66\x48\x00\xb0\xb7\x00\xc0\xce\x10\x0b\xb2\x00\x08\x0c\x00\x30\ +\x51\x88\x85\x29\x00\x04\x7b\x00\x60\xc8\x23\x23\x78\x00\x84\x99\ +\x00\x14\x46\xf2\x57\x3c\xf1\x2b\xae\x10\xe7\x2a\x00\x00\x78\x99\ +\xb2\x3c\xb9\x24\x39\x45\x81\x5b\x08\x2d\x71\x07\x57\x57\x2e\x1e\ +\x28\xce\x49\x17\x2b\x14\x36\x61\x02\x61\x9a\x40\x2e\xc2\x79\x99\ +\x19\x32\x81\x34\x0f\xe0\xf3\xcc\x00\x00\xa0\x91\x15\x11\xe0\x83\ +\xf3\xfd\x78\xce\x0e\xae\xce\xce\x36\x8e\xb6\x0e\x5f\x2d\xea\xbf\ +\x06\xff\x22\x62\x62\xe3\xfe\xe5\xcf\xab\x70\x40\x00\x00\xe1\x74\ +\x7e\xd1\xfe\x2c\x2f\xb3\x1a\x80\x3b\x06\x80\x6d\xfe\xa2\x25\xee\ +\x04\x68\x5e\x0b\xa0\x75\xf7\x8b\x66\xb2\x0f\x40\xb5\x00\xa0\xe9\ +\xda\x57\xf3\x70\xf8\x7e\x3c\x3c\x45\xa1\x90\xb9\xd9\xd9\xe5\xe4\ +\xe4\xd8\x4a\xc4\x42\x5b\x61\xca\x57\x7d\xfe\x67\xc2\x5f\xc0\x57\ +\xfd\x6c\xf9\x7e\x3c\xfc\xf7\xf5\xe0\xbe\xe2\x24\x81\x32\x5d\x81\ +\x47\x04\xf8\xe0\xc2\xcc\xf4\x4c\xa5\x1c\xcf\x92\x09\x84\x62\xdc\ +\xe6\x8f\x47\xfc\xb7\x0b\xff\xfc\x1d\xd3\x22\xc4\x49\x62\xb9\x58\ +\x2a\x14\xe3\x51\x12\x71\x8e\x44\x9a\x8c\xf3\x32\xa5\x22\x89\x42\ +\x92\x29\xc5\x25\xd2\xff\x64\xe2\xdf\x2c\xfb\x03\x3e\xdf\x35\x00\ +\xb0\x6a\x3e\x01\x7b\x91\x2d\xa8\x5d\x63\x03\xf6\x4b\x27\x10\x58\ +\x74\xc0\xe2\xf7\x00\x00\xf2\xbb\x6f\xc1\xd4\x28\x08\x03\x80\x68\ +\x83\xe1\xcf\x77\xff\xef\x3f\xfd\x47\xa0\x25\x00\x80\x66\x49\x92\ +\x71\x00\x00\x5e\x44\x24\x2e\x54\xca\xb3\x3f\xc7\x08\x00\x00\x44\ +\xa0\x81\x2a\xb0\x41\x1b\xf4\xc1\x18\x2c\xc0\x06\x1c\xc1\x05\xdc\ +\xc1\x0b\xfc\x60\x36\x84\x42\x24\xc4\xc2\x42\x10\x42\x0a\x64\x80\ +\x1c\x72\x60\x29\xac\x82\x42\x28\x86\xcd\xb0\x1d\x2a\x60\x2f\xd4\ +\x40\x1d\x34\xc0\x51\x68\x86\x93\x70\x0e\x2e\xc2\x55\xb8\x0e\x3d\ +\x70\x0f\xfa\x61\x08\x9e\xc1\x28\xbc\x81\x09\x04\x41\xc8\x08\x13\ +\x61\x21\xda\x88\x01\x62\x8a\x58\x23\x8e\x08\x17\x99\x85\xf8\x21\ +\xc1\x48\x04\x12\x8b\x24\x20\xc9\x88\x14\x51\x22\x4b\x91\x35\x48\ +\x31\x52\x8a\x54\x20\x55\x48\x1d\xf2\x3d\x72\x02\x39\x87\x5c\x46\ +\xba\x91\x3b\xc8\x00\x32\x82\xfc\x86\xbc\x47\x31\x94\x81\xb2\x51\ +\x3d\xd4\x0c\xb5\x43\xb9\xa8\x37\x1a\x84\x46\xa2\x0b\xd0\x64\x74\ +\x31\x9a\x8f\x16\xa0\x9b\xd0\x72\xb4\x1a\x3d\x8c\x36\xa1\xe7\xd0\ +\xab\x68\x0f\xda\x8f\x3e\x43\xc7\x30\xc0\xe8\x18\x07\x33\xc4\x6c\ +\x30\x2e\xc6\xc3\x42\xb1\x38\x2c\x09\x93\x63\xcb\xb1\x22\xac\x0c\ +\xab\xc6\x1a\xb0\x56\xac\x03\xbb\x89\xf5\x63\xcf\xb1\x77\x04\x12\ +\x81\x45\xc0\x09\x36\x04\x77\x42\x20\x61\x1e\x41\x48\x58\x4c\x58\ +\x4e\xd8\x48\xa8\x20\x1c\x24\x34\x11\xda\x09\x37\x09\x03\x84\x51\ +\xc2\x27\x22\x93\xa8\x4b\xb4\x26\xba\x11\xf9\xc4\x18\x62\x32\x31\ +\x87\x58\x48\x2c\x23\xd6\x12\x8f\x13\x2f\x10\x7b\x88\x43\xc4\x37\ +\x24\x12\x89\x43\x32\x27\xb9\x90\x02\x49\xb1\xa4\x54\xd2\x12\xd2\ +\x46\xd2\x6e\x52\x23\xe9\x2c\xa9\x9b\x34\x48\x1a\x23\x93\xc9\xda\ +\x64\x6b\xb2\x07\x39\x94\x2c\x20\x2b\xc8\x85\xe4\x9d\xe4\xc3\xe4\ +\x33\xe4\x1b\xe4\x21\xf2\x5b\x0a\x9d\x62\x40\x71\xa4\xf8\x53\xe2\ +\x28\x52\xca\x6a\x4a\x19\xe5\x10\xe5\x34\xe5\x06\x65\x98\x32\x41\ +\x55\xa3\x9a\x52\xdd\xa8\xa1\x54\x11\x35\x8f\x5a\x42\xad\xa1\xb6\ +\x52\xaf\x51\x87\xa8\x13\x34\x75\x9a\x39\xcd\x83\x16\x49\x4b\xa5\ +\xad\xa2\x95\xd3\x1a\x68\x17\x68\xf7\x69\xaf\xe8\x74\xba\x11\xdd\ +\x95\x1e\x4e\x97\xd0\x57\xd2\xcb\xe9\x47\xe8\x97\xe8\x03\xf4\x77\ +\x0c\x0d\x86\x15\x83\xc7\x88\x67\x28\x19\x9b\x18\x07\x18\x67\x19\ +\x77\x18\xaf\x98\x4c\xa6\x19\xd3\x8b\x19\xc7\x54\x30\x37\x31\xeb\ +\x98\xe7\x99\x0f\x99\x6f\x55\x58\x2a\xb6\x2a\x7c\x15\x91\xca\x0a\ +\x95\x4a\x95\x26\x95\x1b\x2a\x2f\x54\xa9\xaa\xa6\xaa\xde\xaa\x0b\ +\x55\xf3\x55\xcb\x54\x8f\xa9\x5e\x53\x7d\xae\x46\x55\x33\x53\xe3\ +\xa9\x09\xd4\x96\xab\x55\xaa\x9d\x50\xeb\x53\x1b\x53\x67\xa9\x3b\ +\xa8\x87\xaa\x67\xa8\x6f\x54\x3f\xa4\x7e\x59\xfd\x89\x06\x59\xc3\ +\x4c\xc3\x4f\x43\xa4\x51\xa0\xb1\x5f\xe3\xbc\xc6\x20\x0b\x63\x19\ +\xb3\x78\x2c\x21\x6b\x0d\xab\x86\x75\x81\x35\xc4\x26\xb1\xcd\xd9\ +\x7c\x76\x2a\xbb\x98\xfd\x1d\xbb\x8b\x3d\xaa\xa9\xa1\x39\x43\x33\ +\x4a\x33\x57\xb3\x52\xf3\x94\x66\x3f\x07\xe3\x98\x71\xf8\x9c\x74\ +\x4e\x09\xe7\x28\xa7\x97\xf3\x7e\x8a\xde\x14\xef\x29\xe2\x29\x1b\ +\xa6\x34\x4c\xb9\x31\x65\x5c\x6b\xaa\x96\x97\x96\x58\xab\x48\xab\ +\x51\xab\x47\xeb\xbd\x36\xae\xed\xa7\x9d\xa6\xbd\x45\xbb\x59\xfb\ +\x81\x0e\x41\xc7\x4a\x27\x5c\x27\x47\x67\x8f\xce\x05\x9d\xe7\x53\ +\xd9\x53\xdd\xa7\x0a\xa7\x16\x4d\x3d\x3a\xf5\xae\x2e\xaa\x6b\xa5\ +\x1b\xa1\xbb\x44\x77\xbf\x6e\xa7\xee\x98\x9e\xbe\x5e\x80\x9e\x4c\ +\x6f\xa7\xde\x79\xbd\xe7\xfa\x1c\x7d\x2f\xfd\x54\xfd\x6d\xfa\xa7\ +\xf5\x47\x0c\x58\x06\xb3\x0c\x24\x06\xdb\x0c\xce\x18\x3c\xc5\x35\ +\x71\x6f\x3c\x1d\x2f\xc7\xdb\xf1\x51\x43\x5d\xc3\x40\x43\xa5\x61\ +\x95\x61\x97\xe1\x84\x91\xb9\xd1\x3c\xa3\xd5\x46\x8d\x46\x0f\x8c\ +\x69\xc6\x5c\xe3\x24\xe3\x6d\xc6\x6d\xc6\xa3\x26\x06\x26\x21\x26\ +\x4b\x4d\xea\x4d\xee\x9a\x52\x4d\xb9\xa6\x29\xa6\x3b\x4c\x3b\x4c\ +\xc7\xcd\xcc\xcd\xa2\xcd\xd6\x99\x35\x9b\x3d\x31\xd7\x32\xe7\x9b\ +\xe7\x9b\xd7\x9b\xdf\xb7\x60\x5a\x78\x5a\x2c\xb6\xa8\xb6\xb8\x65\ +\x49\xb2\xe4\x5a\xa6\x59\xee\xb6\xbc\x6e\x85\x5a\x39\x59\xa5\x58\ +\x55\x5a\x5d\xb3\x46\xad\x9d\xad\x25\xd6\xbb\xad\xbb\xa7\x11\xa7\ +\xb9\x4e\x93\x4e\xab\x9e\xd6\x67\xc3\xb0\xf1\xb6\xc9\xb6\xa9\xb7\ +\x19\xb0\xe5\xd8\x06\xdb\xae\xb6\x6d\xb6\x7d\x61\x67\x62\x17\x67\ +\xb7\xc5\xae\xc3\xee\x93\xbd\x93\x7d\xba\x7d\x8d\xfd\x3d\x07\x0d\ +\x87\xd9\x0e\xab\x1d\x5a\x1d\x7e\x73\xb4\x72\x14\x3a\x56\x3a\xde\ +\x9a\xce\x9c\xee\x3f\x7d\xc5\xf4\x96\xe9\x2f\x67\x58\xcf\x10\xcf\ +\xd8\x33\xe3\xb6\x13\xcb\x29\xc4\x69\x9d\x53\x9b\xd3\x47\x67\x17\ +\x67\xb9\x73\x83\xf3\x88\x8b\x89\x4b\x82\xcb\x2e\x97\x3e\x2e\x9b\ +\x1b\xc6\xdd\xc8\xbd\xe4\x4a\x74\xf5\x71\x5d\xe1\x7a\xd2\xf5\x9d\ +\x9b\xb3\x9b\xc2\xed\xa8\xdb\xaf\xee\x36\xee\x69\xee\x87\xdc\x9f\ +\xcc\x34\x9f\x29\x9e\x59\x33\x73\xd0\xc3\xc8\x43\xe0\x51\xe5\xd1\ +\x3f\x0b\x9f\x95\x30\x6b\xdf\xac\x7e\x4f\x43\x4f\x81\x67\xb5\xe7\ +\x23\x2f\x63\x2f\x91\x57\xad\xd7\xb0\xb7\xa5\x77\xaa\xf7\x61\xef\ +\x17\x3e\xf6\x3e\x72\x9f\xe3\x3e\xe3\x3c\x37\xde\x32\xde\x59\x5f\ +\xcc\x37\xc0\xb7\xc8\xb7\xcb\x4f\xc3\x6f\x9e\x5f\x85\xdf\x43\x7f\ +\x23\xff\x64\xff\x7a\xff\xd1\x00\xa7\x80\x25\x01\x67\x03\x89\x81\ +\x41\x81\x5b\x02\xfb\xf8\x7a\x7c\x21\xbf\x8e\x3f\x3a\xdb\x65\xf6\ +\xb2\xd9\xed\x41\x8c\xa0\xb9\x41\x15\x41\x8f\x82\xad\x82\xe5\xc1\ +\xad\x21\x68\xc8\xec\x90\xad\x21\xf7\xe7\x98\xce\x91\xce\x69\x0e\ +\x85\x50\x7e\xe8\xd6\xd0\x07\x61\xe6\x61\x8b\xc3\x7e\x0c\x27\x85\ +\x87\x85\x57\x86\x3f\x8e\x70\x88\x58\x1a\xd1\x31\x97\x35\x77\xd1\ +\xdc\x43\x73\xdf\x44\xfa\x44\x96\x44\xde\x9b\x67\x31\x4f\x39\xaf\ +\x2d\x4a\x35\x2a\x3e\xaa\x2e\x6a\x3c\xda\x37\xba\x34\xba\x3f\xc6\ +\x2e\x66\x59\xcc\xd5\x58\x9d\x58\x49\x6c\x4b\x1c\x39\x2e\x2a\xae\ +\x36\x6e\x6c\xbe\xdf\xfc\xed\xf3\x87\xe2\x9d\xe2\x0b\xe3\x7b\x17\ +\x98\x2f\xc8\x5d\x70\x79\xa1\xce\xc2\xf4\x85\xa7\x16\xa9\x2e\x12\ +\x2c\x3a\x96\x40\x4c\x88\x4e\x38\x94\xf0\x41\x10\x2a\xa8\x16\x8c\ +\x25\xf2\x13\x77\x25\x8e\x0a\x79\xc2\x1d\xc2\x67\x22\x2f\xd1\x36\ +\xd1\x88\xd8\x43\x5c\x2a\x1e\x4e\xf2\x48\x2a\x4d\x7a\x92\xec\x91\ +\xbc\x35\x79\x24\xc5\x33\xa5\x2c\xe5\xb9\x84\x27\xa9\x90\xbc\x4c\ +\x0d\x4c\xdd\x9b\x3a\x9e\x16\x9a\x76\x20\x6d\x32\x3d\x3a\xbd\x31\ +\x83\x92\x91\x90\x71\x42\xaa\x21\x4d\x93\xb6\x67\xea\x67\xe6\x66\ +\x76\xcb\xac\x65\x85\xb2\xfe\xc5\x6e\x8b\xb7\x2f\x1e\x95\x07\xc9\ +\x6b\xb3\x90\xac\x05\x59\x2d\x0a\xb6\x42\xa6\xe8\x54\x5a\x28\xd7\ +\x2a\x07\xb2\x67\x65\x57\x66\xbf\xcd\x89\xca\x39\x96\xab\x9e\x2b\ +\xcd\xed\xcc\xb3\xca\xdb\x90\x37\x9c\xef\x9f\xff\xed\x12\xc2\x12\ +\xe1\x92\xb6\xa5\x86\x4b\x57\x2d\x1d\x58\xe6\xbd\xac\x6a\x39\xb2\ +\x3c\x71\x79\xdb\x0a\xe3\x15\x05\x2b\x86\x56\x06\xac\x3c\xb8\x8a\ +\xb6\x2a\x6d\xd5\x4f\xab\xed\x57\x97\xae\x7e\xbd\x26\x7a\x4d\x6b\ +\x81\x5e\xc1\xca\x82\xc1\xb5\x01\x6b\xeb\x0b\x55\x0a\xe5\x85\x7d\ +\xeb\xdc\xd7\xed\x5d\x4f\x58\x2f\x59\xdf\xb5\x61\xfa\x86\x9d\x1b\ +\x3e\x15\x89\x8a\xae\x14\xdb\x17\x97\x15\x7f\xd8\x28\xdc\x78\xe5\ +\x1b\x87\x6f\xca\xbf\x99\xdc\x94\xb4\xa9\xab\xc4\xb9\x64\xcf\x66\ +\xd2\x66\xe9\xe6\xde\x2d\x9e\x5b\x0e\x96\xaa\x97\xe6\x97\x0e\x6e\ +\x0d\xd9\xda\xb4\x0d\xdf\x56\xb4\xed\xf5\xf6\x45\xdb\x2f\x97\xcd\ +\x28\xdb\xbb\x83\xb6\x43\xb9\xa3\xbf\x3c\xb8\xbc\x65\xa7\xc9\xce\ +\xcd\x3b\x3f\x54\xa4\x54\xf4\x54\xfa\x54\x36\xee\xd2\xdd\xb5\x61\ +\xd7\xf8\x6e\xd1\xee\x1b\x7b\xbc\xf6\x34\xec\xd5\xdb\x5b\xbc\xf7\ +\xfd\x3e\xc9\xbe\xdb\x55\x01\x55\x4d\xd5\x66\xd5\x65\xfb\x49\xfb\ +\xb3\xf7\x3f\xae\x89\xaa\xe9\xf8\x96\xfb\x6d\x5d\xad\x4e\x6d\x71\ +\xed\xc7\x03\xd2\x03\xfd\x07\x23\x0e\xb6\xd7\xb9\xd4\xd5\x1d\xd2\ +\x3d\x54\x52\x8f\xd6\x2b\xeb\x47\x0e\xc7\x1f\xbe\xfe\x9d\xef\x77\ +\x2d\x0d\x36\x0d\x55\x8d\x9c\xc6\xe2\x23\x70\x44\x79\xe4\xe9\xf7\ +\x09\xdf\xf7\x1e\x0d\x3a\xda\x76\x8c\x7b\xac\xe1\x07\xd3\x1f\x76\ +\x1d\x67\x1d\x2f\x6a\x42\x9a\xf2\x9a\x46\x9b\x53\x9a\xfb\x5b\x62\ +\x5b\xba\x4f\xcc\x3e\xd1\xd6\xea\xde\x7a\xfc\x47\xdb\x1f\x0f\x9c\ +\x34\x3c\x59\x79\x4a\xf3\x54\xc9\x69\xda\xe9\x82\xd3\x93\x67\xf2\ +\xcf\x8c\x9d\x95\x9d\x7d\x7e\x2e\xf9\xdc\x60\xdb\xa2\xb6\x7b\xe7\ +\x63\xce\xdf\x6a\x0f\x6f\xef\xba\x10\x74\xe1\xd2\x45\xff\x8b\xe7\ +\x3b\xbc\x3b\xce\x5c\xf2\xb8\x74\xf2\xb2\xdb\xe5\x13\x57\xb8\x57\ +\x9a\xaf\x3a\x5f\x6d\xea\x74\xea\x3c\xfe\x93\xd3\x4f\xc7\xbb\x9c\ +\xbb\x9a\xae\xb9\x5c\x6b\xb9\xee\x7a\xbd\xb5\x7b\x66\xf7\xe9\x1b\ +\x9e\x37\xce\xdd\xf4\xbd\x79\xf1\x16\xff\xd6\xd5\x9e\x39\x3d\xdd\ +\xbd\xf3\x7a\x6f\xf7\xc5\xf7\xf5\xdf\x16\xdd\x7e\x72\x27\xfd\xce\ +\xcb\xbb\xd9\x77\x27\xee\xad\xbc\x4f\xbc\x5f\xf4\x40\xed\x41\xd9\ +\x43\xdd\x87\xd5\x3f\x5b\xfe\xdc\xd8\xef\xdc\x7f\x6a\xc0\x77\xa0\ +\xf3\xd1\xdc\x47\xf7\x06\x85\x83\xcf\xfe\x91\xf5\x8f\x0f\x43\x05\ +\x8f\x99\x8f\xcb\x86\x0d\x86\xeb\x9e\x38\x3e\x39\x39\xe2\x3f\x72\ +\xfd\xe9\xfc\xa7\x43\xcf\x64\xcf\x26\x9e\x17\xfe\xa2\xfe\xcb\xae\ +\x17\x16\x2f\x7e\xf8\xd5\xeb\xd7\xce\xd1\x98\xd1\xa1\x97\xf2\x97\ +\x93\xbf\x6d\x7c\xa5\xfd\xea\xc0\xeb\x19\xaf\xdb\xc6\xc2\xc6\x1e\ +\xbe\xc9\x78\x33\x31\x5e\xf4\x56\xfb\xed\xc1\x77\xdc\x77\x1d\xef\ +\xa3\xdf\x0f\x4f\xe4\x7c\x20\x7f\x28\xff\x68\xf9\xb1\xf5\x53\xd0\ +\xa7\xfb\x93\x19\x93\x93\xff\x04\x03\x98\xf3\xfc\x63\x33\x2d\xdb\ +\x00\x00\x00\x20\x63\x48\x52\x4d\x00\x00\x7a\x25\x00\x00\x80\x83\ +\x00\x00\xf9\xff\x00\x00\x80\xe9\x00\x00\x75\x30\x00\x00\xea\x60\ +\x00\x00\x3a\x98\x00\x00\x17\x6f\x92\x5f\xc5\x46\x00\x00\x0c\x7b\ +\x49\x44\x41\x54\x78\xda\xec\xdd\x5b\x6c\xd4\x55\x02\xc7\xf1\xdf\ +\x74\xee\x33\x5c\x86\xd6\x34\x81\x8c\x98\x5e\xd4\xd4\xaa\x54\xdb\ +\x05\xd2\x58\x62\x25\x1b\x21\x2b\x98\xac\x84\xb0\x66\xab\xae\xc9\ +\xee\x1a\x62\xb2\x64\xb3\x3e\xe8\x83\xc9\xf2\x20\xd9\x68\x8c\x24\ +\xae\x9a\xdd\x07\xc4\xcb\x66\xd7\x60\xb2\xca\xee\x56\xa2\x02\x01\ +\x43\x50\x41\x51\xac\x44\x43\x5b\x02\x0d\x93\x6d\xb6\x30\x40\xa7\ +\x73\xeb\x74\xf6\x61\x98\xff\xdc\xaf\x2d\x9d\x52\xbe\x9f\x84\x84\ +\xd2\x99\xff\xe5\x9c\x33\x13\x7e\xe7\x9c\xff\x39\xa6\xce\xce\xce\ +\xb8\x00\x00\xd3\x16\x0c\x06\x29\x04\x00\x00\x00\x54\xad\x8e\x22\ +\x00\x00\x00\x00\x00\x80\x80\x0e\x00\x00\x00\x00\x00\x08\xe8\x00\ +\x00\x00\x00\x00\x10\xd0\x01\x00\x00\x00\x00\x00\x01\x1d\x00\x00\ +\x00\x00\x00\x02\x3a\x00\x00\x00\x00\x00\x20\xa0\x03\x00\x00\x00\ +\x00\x40\x40\x07\x00\x00\x00\x00\x00\x04\x74\x00\x00\x00\x00\x00\ +\x08\xe8\x00\x00\x00\x00\x00\x80\x80\x0e\x00\x00\x00\x00\x00\x01\ +\x1d\x00\x00\x00\x00\x00\x10\xd0\x01\x00\x00\x00\x00\x20\xa0\x03\ +\x00\x00\x00\x00\x00\x02\x3a\x00\x00\x00\x00\x00\x04\x74\x00\x00\ +\x00\x00\x00\x40\x40\x07\x00\x00\x00\x00\x80\x80\x0e\x00\x00\x00\ +\x00\x00\x08\xe8\x00\x00\x00\x00\x00\x10\xd0\x01\x00\x00\x00\x00\ +\x00\x01\x1d\x00\x00\x00\x00\x00\x02\x3a\x00\x00\x00\x00\x00\x20\ +\xa0\x03\x00\x00\x00\x00\x40\x40\x07\x00\x00\x00\x00\x00\x04\x74\ +\x00\x00\x00\x00\x00\x08\xe8\x00\x00\x00\x00\x00\xa0\x0a\x96\x6b\ +\x76\x60\x6f\x87\x4c\x8e\x85\x15\xbd\x27\x1e\xba\xa2\xc9\x91\x13\ +\xc6\xcf\xe6\x86\x26\xd5\x2d\xf1\x4a\x92\x26\xcf\x0f\x28\x3e\x71\ +\x21\xe3\xf5\x26\x57\xbd\x2c\xcb\xda\x8d\x9f\xa3\xa7\x0f\x97\x75\ +\x9e\xf4\xe3\x66\x9f\xb3\x9a\xeb\x2f\x74\x8c\x72\x98\x5c\xf5\xb2\ +\x36\xad\x92\xa5\xb1\x49\x92\x34\x75\x79\x54\x93\xff\x3d\x5d\xd6\ +\xf1\xac\xad\x3d\x65\x9f\x67\xea\xe2\x88\x62\x63\xc3\x65\x5f\x53\ +\x7a\xb9\xce\xd4\xbd\x26\xcb\xbd\xd4\x31\xd2\xcf\x5f\xce\xf9\xd2\ +\xeb\x2a\x5f\x3b\x99\x89\x36\x9a\x7d\x1d\xc5\xca\xa8\x92\xb2\x4e\ +\xd6\x61\xf6\x7b\x2a\xa9\xdb\x72\xce\x9b\xaf\x9d\x45\xcf\x1c\x2f\ +\x79\x9d\xc5\xee\x73\xba\xed\x01\x00\x00\x00\xc0\x2c\x05\x74\xf7\ +\x9a\x27\x64\x69\x6c\xae\xe8\x3d\x93\xa3\x43\xba\xf4\xb7\x6d\xc6\ +\xcf\xf6\xbb\xd7\xcb\xb9\x62\x9d\x24\xe9\xf2\xbf\x5e\xcc\x09\xe0\ +\x96\x65\xed\x5a\xf4\xd0\x33\xc6\xcf\x97\xf6\x94\x17\x16\x5c\xbd\ +\xbf\x91\xcd\xdb\x9e\xf7\x9c\xd5\x5c\x7f\xa1\x63\x94\xbe\x8e\xad\ +\x72\xdc\x71\xbf\x4c\x56\x47\xde\x63\x06\x0e\xbd\x59\xf4\x7e\xd2\ +\xef\xbd\x94\xe0\x37\x1f\x69\xe2\xc0\x6b\xe5\x35\x8a\xac\x72\xcd\ +\x09\x65\xd1\x90\x22\x67\xbf\x53\xf0\xc8\xdb\x65\x07\x51\x49\x5a\ +\xf4\xf3\x3f\xaa\xce\xed\x51\x3c\x1a\xd2\x85\x3f\x6f\x2e\x7c\xfc\ +\x89\x0b\x5a\xd0\xfb\x6b\xd5\xb9\x3d\x92\x24\xff\xdb\xbf\x2b\x1a\ +\x3c\x17\x3d\xfc\x9c\x4c\x56\x87\xe2\xd1\x90\x2e\xee\x7a\xea\x9a\ +\xb4\xd1\xec\x3a\x2e\xb7\x8c\x02\x9f\xbe\x5a\xb4\xc3\x20\x79\x8c\ +\xec\xfa\xa9\xa4\x6e\x8b\xd5\xb1\xc9\x55\x2f\x57\xcf\x93\x72\xb4\ +\xad\xc9\x7d\x43\xcf\x63\x9a\x1c\x1d\xd2\xf8\xbe\x9d\x05\xcb\xb7\ +\xd4\x7d\x56\x72\xaf\x00\x00\x00\x00\x6a\x14\xd0\x27\xc7\x46\x72\ +\xc3\x94\xcd\x29\xb3\x67\xa9\x24\x29\xe6\xf7\x29\x1e\x09\x96\x7c\ +\x4f\x25\x1c\xf7\x6c\xd4\x78\x89\x80\x6e\x6e\x68\x32\xc2\x79\x39\ +\xe2\xd1\x90\x62\x17\xcf\x57\x7c\xaf\xa5\x2c\xdc\xb4\x23\xe3\x3a\ +\x26\x47\x87\x24\x49\x75\xee\x7a\xd5\xb9\x3d\xb2\x34\x36\x6b\xd1\ +\xc3\xcf\xe9\xf2\x07\x2f\x94\xec\x74\x98\x0a\xf8\x35\x15\x28\x1e\ +\x8c\xa6\x2e\x8f\x56\x55\xa6\xe9\xf5\x94\xac\x3f\x93\xd5\x21\x7b\ +\x4b\x97\x6c\xcb\xef\xd4\xf8\xc1\x5d\x8a\x0c\xf4\x97\x6e\x68\xde\ +\x0e\x23\x70\x9b\xac\x0e\x39\x3a\x37\x29\x74\x7c\x4f\xe1\xb0\xf9\ +\xd5\x87\x72\xf7\x3c\x26\x49\x72\x76\xf7\x69\x7c\xef\xf6\xbc\xaf\ +\x73\xae\xda\x62\x74\x70\x84\xbe\x3f\x58\x55\x40\x9c\x6e\x1d\x17\ +\x2f\xa3\x37\xca\xaa\xc3\x7c\x1d\x02\xd9\x92\x6d\xa3\xd0\xef\xb3\ +\xeb\xd8\xe4\xaa\xd7\xe2\xcd\x3b\x8c\xcf\x5c\xfa\x7d\x9a\x97\x2c\ +\x93\xc9\xea\x90\xa5\xb1\x59\x8b\xb7\xfc\xa9\xac\x6b\xcc\xfe\xcc\ +\x26\xaf\x27\x79\xaf\x96\x86\x1d\xba\xf4\xde\xb3\x84\x74\x00\x00\ +\x00\x60\xae\x05\xf4\xc0\xbe\x97\x72\xfe\xcd\xda\xda\x63\x8c\xc6\ +\x05\x3e\x7b\xa7\xec\x29\xe9\xe5\xb2\x2d\xbf\xb3\xf4\x6b\x6e\x5f\ +\x53\x59\x40\xbd\x78\xbe\xaa\xd1\xf1\x62\x5c\xbd\x5b\x8d\x70\x1e\ +\x19\x19\xd0\xf8\x7f\x5e\xcc\x08\x35\x8e\xce\x4d\x72\xad\xde\x2c\ +\x93\xd5\xa1\x45\x0f\x3f\xa7\x8b\xbb\x9e\x2a\x1a\x7a\xc2\xa7\x8f\ +\x96\x3d\x3a\x5e\x71\x3d\x66\xd5\x93\xc9\x55\x2f\x47\xc7\x06\x39\ +\xef\xf9\x99\x4c\x56\x87\x16\xdc\xff\x2b\x5d\xbe\xe4\x2b\x19\xee\ +\x1c\xf7\x6c\xcc\x6c\x0b\x4d\x9d\x45\x03\x7a\xe8\xf8\x1e\x39\xef\ +\xdd\xa8\x3a\xb7\x47\xf6\x96\x2e\x05\x1b\x9a\x72\x46\x79\x4d\xae\ +\x7a\x39\xee\xb8\xdf\xe8\xa4\xa8\xb6\x0c\xa6\x5b\xc7\xf9\xca\xc8\ +\xb9\x6a\x8b\x9c\x2b\xd6\x19\x75\x58\x69\x48\xcf\x77\x3d\xae\xde\ +\xad\xc6\x8c\x92\x72\xae\xd7\xbd\xf6\x69\x23\x9c\x87\x07\x8f\xe5\ +\x8c\x70\x3b\xbb\x1f\x97\x6b\xe5\x23\x32\x59\x1d\x5a\xb8\xfe\xf7\ +\xf2\xbf\xbb\xad\x68\x3b\xcb\xf7\x99\x35\xb9\xea\xe5\x5e\xfb\xb4\ +\xec\x2d\x5d\x32\x7b\x96\xca\xd5\xf3\x64\xde\xcf\x3e\x00\x00\x00\ +\x80\xd2\xe6\xd5\x22\x71\xc9\x91\xd9\xa2\x41\xb1\x7d\x6d\x6d\xaf\ +\xd1\x55\x6f\x84\xac\x98\xdf\xa7\x2b\x7b\x72\x47\x1c\x43\xc7\xf7\ +\x68\xfc\xe0\x2e\xe3\x9e\xdc\x6b\x9f\x9e\x33\x65\x1c\x9f\xb8\xa0\ +\xe0\x91\xdd\xba\xfc\xc1\x0b\xa9\xeb\x5b\xf3\x44\xc9\x7b\x4e\x76\ +\x9e\xc4\xfc\xbe\x44\x47\x89\xb7\x5d\xe6\x86\xa6\xa2\xef\x1b\x3f\ +\xf0\xd7\xb4\x30\xd9\x97\xf3\xfb\xf4\xd1\xf3\xe0\x57\x1f\xce\xa9\ +\x32\x9a\x38\xf0\x9a\x02\x87\xdf\x2a\xbb\x8c\x66\x9a\xc5\xdb\x21\ +\x7b\x4b\x97\xa4\xab\x9d\x40\x7b\xb7\xe7\xb4\xb3\xe0\x91\xdd\x9a\ +\xf8\xe2\xfd\xc4\x17\x81\xdb\x23\xe7\xaa\x2d\x55\xb6\x87\xb7\x53\ +\x1d\x2f\x4b\x6f\xe5\x5b\x15\x00\x00\x00\xb8\xd1\x03\x7a\x64\x64\ +\x40\x92\x64\xbf\xfd\xbe\x82\xaf\xb1\xb6\xf6\x18\x53\x84\x93\xaf\ +\x9f\x6d\xf6\xb6\x07\x8c\xbf\x4f\x7c\xf9\xcf\xc2\xf7\x33\xd0\x6f\ +\x4c\x63\x2e\x67\x66\xc0\x6c\x9b\x1c\x39\xa1\xf0\xe0\xb1\x44\x18\ +\x6c\x6c\x96\xc5\xdb\x51\xf4\x9e\x93\x41\x7a\xfc\x93\xd7\x15\x8f\ +\x86\x12\xf7\x55\x62\x36\x43\xf4\xf4\x61\xa3\x0c\xec\x2d\x5d\x19\ +\x81\xde\xdc\xd0\x64\x8c\x9e\xc7\xfc\xbe\xa2\xa3\xf1\xb5\x12\x3a\ +\xbe\x27\xa3\x8c\x4a\x75\x48\xcc\x24\xdb\xad\xdd\xa9\x20\x7e\xf4\ +\x1f\x05\x5f\x17\x3c\xb2\x5b\x53\x01\x7f\xe2\x3d\xb7\xac\xa8\xea\ +\x5c\xb1\xb1\x61\xa3\x9e\x92\x23\xf6\x00\x00\x00\x00\x6e\xe0\x80\ +\x1e\x3e\x75\xa8\x64\x10\xb2\xb7\xf5\x1a\x81\x2e\x36\x76\xae\x26\ +\xd7\x69\x59\x76\x47\x46\x08\x2f\x1a\x50\x7d\x3f\x4a\x4a\x8c\xc0\ +\x16\x0b\xc0\x35\x0b\xa0\x5f\x7f\x98\x37\x10\x66\x73\xdc\xf5\xd3\ +\xc4\xfd\x8e\x0c\x68\x72\xe4\x84\x22\x67\xbf\x4b\xfc\x7b\x19\xb3\ +\x19\x92\x23\xbc\x52\xe6\x28\xba\xb3\xbb\xcf\x08\xfd\x81\xcf\xde\ +\x99\xc3\xed\xf2\x40\xaa\x8c\x2a\x7c\xbc\x62\x3a\xac\x4b\x6f\x93\ +\x94\x98\xfa\x5f\x6a\x6a\x7d\xe4\xec\xb7\x33\x16\xae\xf3\x3d\x1b\ +\x0f\x00\x00\x00\xe0\x06\x0b\xe8\xf1\xf0\xb8\x31\x12\xe8\xe8\x7a\ +\x24\xe7\xf7\x26\x57\xbd\x31\xe5\x37\x74\xf2\x63\x23\xc0\xcc\x36\ +\xf3\xc2\x7a\x23\x38\x95\x12\x3d\x77\x32\x75\xfd\x15\x6e\x59\x37\ +\x1b\xca\x79\xa6\xda\xdc\xd0\x64\x04\xbf\xe8\xf0\xf1\x44\x20\x1c\ +\xfa\x32\xd1\xf8\xdc\x9e\x92\xdb\x89\x45\x4f\x1f\x4e\xcd\x8e\xb8\ +\x3a\x8a\x6e\x6e\x68\x32\xea\x72\x72\x74\x68\xc6\xd7\x32\x98\x49\ +\x19\xcf\xa6\xdb\xdd\xb3\x7e\xfe\x52\x8b\x07\x4a\x52\x3c\x32\x91\ +\x51\x5f\x95\xb2\x78\x3b\x8c\xd5\xf0\x23\x67\xbe\xe6\x5b\x15\x00\ +\x00\x00\xa8\x92\x65\x3e\xdd\x4c\xf8\xf4\x51\x39\x57\xac\x93\xbd\ +\x75\xa5\x02\xfb\x32\x7f\xe7\xe8\xd8\x90\x08\x23\xd1\x90\xc2\xa7\ +\xf6\x17\x9d\x0a\x9f\x51\x40\x8d\xcd\x6a\xd8\x56\xf8\xf9\xe6\x4a\ +\xb6\x2f\xab\x34\x38\x95\xcb\xba\xf4\x36\xb9\x7a\xb7\x16\x2e\x97\ +\x6f\xfb\x2b\xda\x0e\x6d\x26\x25\x3b\x4b\xe2\xd1\x90\x31\x0d\x3d\ +\x32\xd0\xaf\xa9\xee\x5f\x24\x16\x80\x6b\xeb\x2d\x19\xb0\x27\x0e\ +\xfc\x45\xb6\xbe\x9d\x92\x72\x9f\x45\x4f\x1f\x61\xaf\xfa\x43\x70\ +\x8d\xea\xf8\x7a\x54\xb7\xc4\x5b\xb0\xad\xd8\xdb\x7a\x65\xbd\xf9\ +\xae\xcc\xd7\x2f\xb8\xc9\x78\x04\x63\x72\x74\x48\xa1\x13\x7b\xf9\ +\x56\x05\x00\x00\x00\x08\xe8\x89\x20\x9a\x5c\x39\xdb\xd6\xbe\x3e\ +\x63\x0a\x79\x72\x3a\x75\xe4\xec\x77\xf3\x6e\x1b\x28\x4b\x63\x73\ +\xd1\xfd\xbc\xa3\xe7\x4e\xd6\x2c\xa0\xdb\x5b\x57\x1a\xe5\x9e\x2e\ +\x72\xf6\x5b\x39\xda\xd6\xc8\xb6\xfc\x4e\x99\x5c\xf5\x45\xeb\x24\ +\x36\x36\xac\xf0\xe0\x31\xd9\x5b\xba\x8c\x91\x73\x29\xb1\x32\xf9\ +\x5c\x1e\x3d\x9f\x6f\xd2\xcb\x3e\x5b\xf6\x3e\xf1\x00\x00\x00\x00\ +\x6e\xf0\x80\x1e\x1b\x1b\x56\x64\x64\x40\x36\x6f\xbb\xec\x6d\x6b\ +\x8c\x80\x9e\xbe\x07\x77\xfa\x73\xd3\x65\x1d\xd3\xef\x2b\xfa\x8c\ +\xf3\xd4\xc5\x91\x9a\xdf\xf7\xe4\xe8\x90\xf1\xbc\xfa\x5c\xba\x46\ +\x5b\xfb\x7a\xe3\x39\xf1\xf4\x67\xb1\x25\x29\x3c\xf0\x89\x1c\x6d\ +\x6b\x12\x7b\x68\xb7\x3d\x50\x72\x91\xb7\xc0\xa7\xaf\xca\xb6\xfc\ +\x0d\xe3\x78\x92\x32\x56\x0f\x9f\x56\xbb\xb9\x0e\xea\x78\x4e\x7c\ +\xbe\xb2\xf6\x41\x4f\xee\xf9\x2e\x25\x3a\x89\x16\x6c\x78\x3e\x67\ +\x2b\x37\x00\x00\x00\x00\x37\x68\x40\x4f\x04\xc1\x43\xb2\x79\xdb\ +\x8d\x6d\xbc\x62\x63\xc3\xc6\x1e\xdc\x31\xbf\xaf\xa2\xbd\xa8\x25\ +\x29\x1e\x09\x5e\x93\x51\x5a\xf3\x92\x65\x33\x76\xac\xa8\xef\xc7\ +\x39\x39\x05\xdb\xde\x96\x5a\x14\xcd\x7a\xf3\x5d\x39\xd3\xa3\xe3\ +\xd1\x50\x22\xa0\xdf\x7e\x5f\xc9\x80\x1e\x9f\xb8\xa0\xd0\xf7\x07\ +\x8d\x2d\xea\x42\xa7\x0e\xcd\xd8\xac\x80\x6b\x55\xc7\x52\x62\xed\ +\x83\xeb\xc9\xe4\xf9\xc2\xbb\x1b\xe4\xdb\x07\xdd\xdc\xd0\x24\x67\ +\x77\x9f\x31\xbb\x21\x1e\x61\x1f\x74\x00\x00\x00\xa0\x5a\x75\xf3\ +\xed\x86\x22\x03\xfd\xc6\x02\x6c\xf6\xbb\xd7\x67\xec\xc1\x1d\x3a\ +\xf9\x71\xed\x03\xd0\x58\x62\x34\xd6\x64\x75\x94\x0c\x6f\xe9\x81\ +\x76\x2e\x8e\xe2\xa6\x2f\xf0\x16\x0f\x07\x72\x82\x9b\xcd\xdb\x6e\ +\xfc\xec\x5c\xb1\x2e\xe7\x4f\x72\x34\xbc\xdc\x2d\xc8\xd2\x17\xcd\ +\x8b\x0c\x7e\x7e\x5d\xb4\x47\x6b\xd3\xaa\x54\x1d\x5e\x1e\x9d\xf5\ +\xf3\x97\xd3\x11\x54\xb7\xe0\xa6\x54\x3d\x56\x38\xfa\x1d\x1b\x1b\ +\xce\x98\xc9\x60\x69\xf0\xf2\xad\x0a\x00\x00\x00\x10\xd0\x53\xc2\ +\xa7\x8f\x26\x02\x7a\xeb\x6a\x63\x0f\xee\xe4\xe2\x70\xb5\x16\xfb\ +\xdf\x19\xe3\xef\xe9\x7b\xa2\xe7\x63\x6f\x5d\x9d\x08\x4d\xd1\x50\ +\xcd\x9e\x21\x2f\x7a\x7d\x57\xb7\xad\x93\xa4\xc8\x0f\x87\x32\x7f\ +\x77\xf7\xfa\x54\xa7\xc4\xe8\x50\xc1\x3f\xf9\x5e\x3f\x9f\x38\x57\ +\x3c\x98\xea\x60\x38\x73\x7c\xd6\xce\x9b\x5c\x4d\xdd\x64\x75\x14\ +\x5d\x29\x3f\xbd\x03\x2b\xe6\xf7\x55\xd7\xa6\xc7\x86\x8d\xf7\x16\ +\x5b\x0b\x01\x00\x00\x00\x40\x71\x96\xf9\x78\x53\xc9\xc5\xe2\xea\ +\xdc\x1e\xb9\x7b\x1e\x4b\x04\x96\x39\xb2\x38\x5c\xf8\xd4\x7e\xb9\ +\x56\x6f\x96\xc9\xea\x90\xf3\xde\x8d\x0a\x9f\xda\x9f\xf7\xba\x9c\ +\xdd\x8f\xa7\x9e\x9b\xff\xfe\xe0\x9c\x2b\x63\x47\xe7\xa6\x8c\xad\ +\xce\xb2\x3b\x10\x92\x9d\x0b\x31\xbf\xaf\xe8\xe2\x61\x8b\x1f\x7d\ +\x45\x96\xc6\x66\xd9\x5b\x57\xcf\xbb\x95\xd2\x1d\x9d\x9b\x8c\xc0\ +\x1a\x1e\x3c\x36\xab\x9d\x2c\x91\x1f\x0e\xc9\xb5\x32\xb1\x82\xbe\ +\xfb\xbe\x5f\xca\x5f\x60\x0a\xbf\xab\xe7\x49\x63\x26\xc3\x74\x66\ +\x98\xa4\x3f\x9b\x0e\x00\x00\x00\xa0\x3a\xf3\x72\x04\x3d\xb9\x58\ +\x5c\xba\x99\x5a\x50\x6c\xba\xe2\x13\x17\x14\xfc\xfa\xdf\x89\xc2\ +\x77\x7b\xb4\x78\xf3\x8e\x8c\xe9\xdd\x26\x57\xbd\x5c\xbd\x5b\x8d\ +\x70\x35\x15\xf0\x2b\xf8\xf9\xdf\xe7\x4c\xd9\x5a\xbc\x1d\x5a\xb0\ +\xe1\x79\xa3\xe3\x23\x1e\x0d\x69\x7c\xdf\xce\x8c\xd7\x58\x5b\x7b\ +\x52\x9d\x0b\x25\x42\x5f\xf8\x87\xcf\x8c\xb2\xb0\xb5\xcf\x8f\x51\ +\xf4\x7c\x65\x14\xf8\xf4\xd5\x59\xff\x0c\x84\x4e\x25\x66\x35\x98\ +\x3d\x4b\xb5\xf8\xd1\x57\x72\xda\x99\xfb\xc1\x3f\xc8\x71\x75\x9d\ +\x80\x98\xdf\x57\x72\x1d\x80\x62\xa6\x08\xe8\x00\x00\x00\xc0\xf4\ +\xb3\xc4\x7c\xbd\xb1\xe4\x62\x71\x52\xfe\x11\xde\xb2\x0b\xa8\xc4\ +\x1e\xd9\xc9\xe3\x57\xb2\xc5\x54\xf0\xc8\x6e\x99\x1b\x6e\x91\xbd\ +\xa5\x4b\x66\xcf\x52\x79\xfa\x76\x6a\x2a\xe0\x57\x3c\x1a\x34\x56\ +\xc5\x4e\x06\xbb\x2b\xfd\x2f\xd7\x74\xe4\x7f\xd1\x43\xcf\x48\x7a\ +\x26\x7f\x28\x0b\xf8\x75\xa5\xff\xe5\xdc\xd1\xf3\xb4\xa9\xef\xa5\ +\x1e\x2b\x08\x9f\xda\x6f\x04\x59\x5b\xf3\x4f\x32\xb6\xc6\x9b\xb5\ +\x0f\xc1\x34\xeb\xb8\x58\x19\xc5\xfc\x3e\x8d\x7f\xf2\x7a\x4d\xea\ +\x30\xb0\xef\x25\x99\x6c\x2e\xd9\x5b\xba\x64\x69\x6c\x96\xa7\x6f\ +\xa7\x31\x15\x3d\xbd\x9d\xc5\xfc\x3e\x5d\x7a\xef\xd9\x69\x76\x08\ +\x9c\x93\xae\x7e\xde\x92\x8b\x33\x02\x00\x00\x00\xa8\x4c\xdd\x7c\ +\xbd\xb1\xf4\xc5\xe2\x92\xa3\xb4\x73\xc9\xf8\xde\xed\x0a\x1c\x7e\ +\xcb\xb8\xc6\x3a\xb7\x27\x23\x34\x85\x07\x8f\xe9\xe2\xae\xa7\x2a\ +\x5e\x75\x7e\x36\xc4\xfc\x3e\x4d\x7c\xf1\xbe\xfc\xef\x6e\xcb\xb9\ +\x3e\x93\xab\xde\x98\xfa\x1e\x1e\x3c\x56\x32\x98\xc6\x27\x2e\x28\ +\x3c\x78\x2c\x11\xec\x5b\xba\xae\xbb\x55\xcf\x8b\x95\x51\xe0\xf0\ +\x5b\xf2\xbf\xf9\xdb\x9a\xd6\xe1\xf8\xde\xed\x0a\x7e\xf3\x91\xe2\ +\xd1\x90\x11\xcc\x93\xed\x2c\x1e\x0d\x29\xf8\xcd\x47\xba\xf4\xde\ +\xb3\xd3\xee\x40\x48\x5f\xc0\xcf\xd9\xdd\xc7\x37\x2b\x00\x00\x00\ +\x50\x05\x53\x67\x67\x67\x9c\x62\xa8\x2d\x8b\xb7\x43\x26\xc7\xc2\ +\x54\xd8\xb9\x46\x5b\x7e\x81\x76\x46\x3b\xbb\xb6\x82\x41\xa6\xfa\ +\x03\x00\x00\x60\x1a\xff\x67\xa7\x08\x6a\x6f\x2e\x8e\x92\x83\x76\ +\x06\x00\x00\x00\x60\x76\xd5\x51\x04\x00\x00\x00\x00\x00\x10\xd0\ +\x01\x00\x00\x00\x00\x00\x01\x1d\x00\x00\x00\x00\x00\x02\x3a\x00\ +\x00\x00\x00\x00\x20\xa0\x03\x00\x00\x00\x00\x40\x40\x07\x00\x00\ +\x00\x00\x00\x04\x74\x00\x00\x00\x00\x00\x08\xe8\x00\x00\x00\x00\ +\x00\x80\x80\x0e\x00\x00\x00\x00\x00\x01\x1d\x00\x00\x00\x00\x00\ +\x10\xd0\x01\x00\x00\x00\x00\x20\xa0\x03\x00\x00\x00\x00\x00\x02\ +\x3a\x00\x00\x00\x00\x00\x04\x74\x00\x00\x00\x00\x00\x40\x40\x07\ +\x00\x00\x00\x00\x80\x80\x0e\x00\x00\x00\x00\x00\x08\xe8\x00\x00\ +\x00\x00\x00\x10\xd0\x01\x00\x00\x00\x00\x00\x01\x1d\x00\x00\x00\ +\x00\x00\x02\x3a\x00\x00\x00\x00\x00\x20\xa0\x03\x00\x00\x00\x00\ +\x70\xfd\xf8\x3f\x00\x00\x00\xff\xff\x03\x00\xce\x28\x15\x65\x5d\ +\xb8\xdc\xe1\x00\x00\x00\x00\x49\x45\x4e\x44\xae\x42\x60\x82\ +\x00\x00\x03\xe6\ +\x89\ +\x50\x4e\x47\x0d\x0a\x1a\x0a\x00\x00\x00\x0d\x49\x48\x44\x52\x00\ +\x00\x00\x20\x00\x00\x00\x20\x08\x06\x00\x00\x00\x73\x7a\x7a\xf4\ +\x00\x00\x00\x04\x73\x42\x49\x54\x08\x08\x08\x08\x7c\x08\x64\x88\ +\x00\x00\x00\x09\x70\x48\x59\x73\x00\x00\x0b\x13\x00\x00\x0b\x13\ +\x01\x00\x9a\x9c\x18\x00\x00\x03\x88\x49\x44\x41\x54\x58\x85\xed\ +\x56\x5d\x68\x1c\x55\x18\x3d\xf7\xde\xd9\x9f\xce\x76\xb3\xdd\x24\ +\x33\x93\x61\x63\x36\xee\x66\x5b\x34\x6d\xa5\xb6\x14\x6c\x63\x53\ +\xf5\xc1\x12\x29\x11\x4b\xfd\x09\xd2\x4a\xa1\xc5\x8a\x21\xd8\x8a\ +\xd0\x22\x12\x84\x3c\x28\xe2\x83\x22\x14\x14\x8a\xc1\x9f\x22\x82\ +\x60\x41\x2a\x45\x50\x11\xed\x4b\x11\x0c\xfd\xa1\x4d\x76\x77\x6a\ +\xcb\xa6\xd9\x8d\xe9\xd6\x64\xb3\xc9\xce\xdc\xcf\x87\xb0\x76\x50\ +\xb3\x3f\xb0\x3e\x88\x39\x6f\x73\xbe\xef\x9e\x73\xf8\xf8\xe6\x72\ +\x81\x15\xac\xe0\x3f\x08\x16\x8d\x46\xfd\x8d\x12\x53\xea\x69\x8e\ +\x6b\xda\x36\x26\x30\x24\x17\x0b\x37\x00\x1c\x69\x44\x00\x5e\xb3\ +\xb9\xd9\x7a\x50\x28\xfc\x33\xbf\x57\xac\xe3\x84\x9f\xfe\xb1\xc7\ +\xd0\x06\x63\x86\xa1\x37\x3c\x40\x5c\xd7\xfb\x3d\x42\x39\x7e\xfa\ +\xcc\x0b\xc2\x66\x08\x90\x83\x9f\xff\x6e\xde\xb2\x93\x08\x87\x89\ +\xd9\xaf\x36\x34\x40\x2c\x1c\x0e\x11\xa3\xf7\x3e\x1c\xdd\x5f\x8a\ +\x44\x42\x6d\xf6\x22\xa9\x4c\x88\xbc\x5b\x23\x6e\x68\x2f\x82\x8b\ +\x4f\x5e\x7f\xe3\xcd\xdb\x3e\x9f\xbf\x2f\x6e\x68\xc3\x31\x23\x50\ +\xd3\x24\xaa\x4f\xc0\xab\x1c\xba\x7f\xd3\x5d\x13\xdd\x1b\xcd\x04\ +\x00\xf8\xbc\x6c\xb6\xc4\x4a\x2d\xe5\x72\x54\xd3\x74\x62\xf2\x60\ +\x47\x67\x74\x62\xef\xc0\xc0\x96\xc1\xa1\xa3\x19\x87\x51\x0f\x97\ +\xea\x8e\x5a\x02\x54\x5d\x42\x46\x78\xea\xa5\x57\x1e\x5a\x5d\xfe\ +\x6e\xef\x08\x67\xc7\xaf\xe6\xb6\x02\xb8\x0c\x00\x56\x36\x3b\x19\ +\x8d\x86\x7a\xd3\xc9\xd4\xc9\x5d\x3d\xdb\xcf\x59\xbf\xa6\x22\x4c\ +\x8a\xfe\xf1\xec\xd4\x58\x2d\x01\x2a\x4e\xa0\x17\x50\x48\x20\xd1\ +\x7d\xaf\xb9\xb6\xcc\x3d\xfd\xcc\x56\x05\xa0\x67\xdd\x7d\x96\x95\ +\xbf\xe5\xf8\x4a\x07\xd2\xe9\xf4\x1a\x10\x3b\x9e\x9a\xaa\xcd\xbc\ +\x6a\x80\x8c\x69\xae\xe1\xe0\xb3\x8a\xa2\xb0\x32\xd7\xff\xf8\xfa\ +\x2d\x1e\xaf\x27\x16\xd3\xf5\x47\xdc\xbd\xd7\xae\xe5\x67\x98\xed\ +\x6c\x4f\xde\xcc\x9d\xaa\xd5\xbc\x6a\x80\xdf\x81\x02\x24\xa9\x6e\ +\xce\xeb\xf5\x88\x77\xdf\x79\x72\x1e\x02\xaf\xad\x0b\x85\x3a\xdd\ +\xb5\xe4\xcc\x4c\x1e\x75\xa2\xf2\x04\x32\x99\x02\x91\xcc\x5b\xd6\ +\xad\xeb\x6e\xfe\x81\x9e\xbb\xd7\x1f\x3b\xb6\x8b\x97\x54\xcf\xa7\ +\x71\x53\x7b\xb4\x5e\x53\x37\x44\xb5\x86\x70\x40\x4d\x2c\x14\x4b\ +\x62\xe7\xc3\x6b\x3b\xdd\xfc\x86\x0d\x66\xc7\xe6\x4d\xd1\xfc\xd9\ +\xaf\x2f\xec\x0e\xfa\x56\xed\x69\x6e\x52\x3d\x2d\x4d\x2a\x05\xd5\ +\xa0\x5f\x0f\xa9\x9d\x21\x55\xed\x6b\x0e\xa8\x07\x36\xce\x15\xce\ +\x5a\x80\x5c\x4e\x9f\x2d\x57\x28\x23\xd1\xd6\x7c\x8f\x64\xca\x37\ +\xdf\xff\x70\x24\x10\x0a\xf9\x9b\xfe\x5a\x2f\x95\x48\x7e\x75\x66\ +\xec\xfc\xa9\x8f\xcf\x17\x53\xe9\x6c\xb3\x53\x94\xaa\xe2\xe7\x05\ +\xe9\x60\x61\xbe\xb8\x78\x21\x99\xc9\xed\xab\xa4\xbf\x6c\x80\x5e\ +\xd7\x2f\x7a\xbd\xad\x75\xa4\x3d\x12\x7e\xf0\xf3\x2f\x9f\xdf\x2c\ +\x20\x05\x17\x8c\xbb\x17\x13\x00\x6c\xdb\x26\xe9\x90\x04\x80\x54\ +\x7a\xc6\xda\xfb\xc4\x07\x3e\xee\xc8\xdd\x91\x5c\x6e\x0c\x00\xbe\ +\x03\xec\x9a\x03\xc4\xf4\xd6\x21\x70\x1a\x59\x6a\x60\x3f\x32\x22\ +\xe9\x80\xcd\x2f\x55\xc9\xdf\xa6\x07\x6f\x7c\x71\xfa\x70\x7a\xff\ +\xc0\xc9\xfb\x98\x87\xcb\xd1\xd1\x7d\xbf\x3c\xd6\x77\x22\x3e\x3d\ +\x3d\xdb\xee\x38\xac\xa8\x00\x0c\x9c\x4a\xc4\xb0\x1a\xa0\x6d\x4b\ +\xe7\xc4\xcb\xc9\xc9\xa9\x13\x35\x4f\xa0\x12\x4c\xd3\x54\x3d\xb6\ +\xfd\xb6\xc2\x31\xe7\x30\xf2\x0a\x4e\x7e\xc7\x33\x3d\x68\x59\x28\ +\xd6\xab\x55\x31\x40\xdc\x30\xba\x25\x93\x3b\x18\x23\xdf\x9f\xa4\ +\x03\x02\x9c\x04\x13\xca\xf4\x44\x26\x3b\x0c\x00\x31\x43\x7b\x0b\ +\x44\x7e\x00\x57\x20\xee\x68\x12\xb1\x05\x05\xce\xb7\x57\x27\x7f\ +\xbb\xb4\x9c\x47\xc5\xab\x98\x98\xbd\x8a\x18\x6f\x22\xe2\xde\x32\ +\xc7\x39\xc0\x25\x9d\x1b\xcf\x64\x3f\x2a\x73\xc9\x9b\xd9\xa3\x09\ +\xbd\xf5\x90\xc3\x58\x07\x93\x77\x36\x9e\x38\x9f\x27\x46\x0d\x7b\ +\xbc\xfc\x2b\xa8\x69\x07\xe2\x86\x36\x0c\xa2\xe7\xea\x52\xe6\x78\ +\x7f\x62\x32\x37\xd2\x90\x00\x5d\x5d\x5d\x3e\x3e\x37\x17\xac\xc7\ +\x5f\x09\x67\x6e\x5f\xbc\x88\xc5\x7a\xce\xac\x60\x05\xff\x4f\xfc\ +\x01\xa0\xdd\x38\x94\xa3\x9e\x46\x4d\x00\x00\x00\x00\x49\x45\x4e\ +\x44\xae\x42\x60\x82\ +\x00\x00\x03\x6b\ +\x89\ +\x50\x4e\x47\x0d\x0a\x1a\x0a\x00\x00\x00\x0d\x49\x48\x44\x52\x00\ +\x00\x00\x20\x00\x00\x00\x20\x08\x06\x00\x00\x00\x73\x7a\x7a\xf4\ +\x00\x00\x00\x04\x73\x42\x49\x54\x08\x08\x08\x08\x7c\x08\x64\x88\ +\x00\x00\x00\x09\x70\x48\x59\x73\x00\x00\x0b\x13\x00\x00\x0b\x13\ +\x01\x00\x9a\x9c\x18\x00\x00\x03\x0d\x49\x44\x41\x54\x58\x85\xed\ +\x96\x6f\x48\x13\x71\x18\xc7\x9f\xbb\x6d\x77\xbb\xbb\xdd\x36\x37\ +\xb7\xdb\xf9\x1f\x9d\x6d\x5d\x26\x65\x89\x15\x92\x26\x24\x1a\xea\ +\x0b\x49\x05\x5f\x28\x91\x98\x41\x6f\x82\xe8\x4d\xbd\xea\x65\x84\ +\xa0\x44\x68\xf9\x22\xb2\x08\x7c\x11\x41\xf8\x46\x51\x22\x03\x2b\ +\x41\xca\x3f\x24\xfe\x29\x06\xba\x9b\x4d\x45\xa7\xde\xfe\xdd\xee\ +\x7a\xa5\xcc\xbf\xdb\x42\xa2\x60\x9f\x77\xf7\x7b\xbe\xf7\x3c\x1f\ +\xee\x39\xb8\x03\x88\x13\x27\xce\xff\x08\xc7\x01\x76\x54\xbd\xd0\ +\x58\xc2\xd9\x0c\x53\x90\x65\x31\xc9\xe2\xaa\xb9\xff\xaf\x0b\x70\ +\x19\x6c\xb3\x46\x8b\x0f\xe0\xb8\x52\x0a\x85\xa4\x27\xfb\x0a\x26\ +\x9b\x6f\x1c\x63\xd9\xc4\x23\x17\xb0\x26\x31\x95\x14\x89\xb5\xf6\ +\xbc\xb9\x4e\xe9\xf5\xe4\xba\x1c\x82\xd1\xdd\x99\x4c\xd6\x54\x28\ +\x85\xe4\x0e\x0c\xc7\x1f\x1c\xa9\x80\xd5\x60\xd0\xe2\x6a\xc5\x8b\ +\x8e\x67\xf5\x14\xcb\xea\xc0\xbb\x19\x50\xa0\x4a\xe5\x6a\x58\x04\ +\xb1\x27\xb3\xcd\x24\xa9\x79\xd7\xd6\xf1\x14\xb4\x09\xba\x06\x5b\ +\x0a\x3b\x90\x91\x64\xb4\x1d\x89\x00\x46\xa9\x6e\x96\x97\x72\xb8\ +\xcd\xc6\x00\x00\x00\xa9\xc5\xc5\x20\x12\x34\x6e\xd5\xd3\x4d\x26\ +\x26\x18\x12\x3b\xf3\x0b\x0a\x34\xe5\x95\x55\x70\xf7\xde\x7d\x4a\ +\x14\xc5\x12\x54\x42\x1b\xa2\x11\x50\x46\x0a\xa8\x09\xbc\xa9\xb6\ +\xfe\x0c\xb1\x75\x9d\x73\x82\x41\x5c\xce\xb5\x7c\x00\x98\x02\x00\ +\x70\xb8\xdd\x2e\x7b\x52\x52\xe2\xe8\x97\x91\x9e\xc6\xba\x9a\x8b\ +\x63\xa3\xa3\x6b\x80\xc8\xa5\x3f\xf8\xa5\x3d\x6b\xda\x8f\x43\x9f\ +\x40\x11\x80\xd2\xeb\xf5\xa7\xda\xed\x96\xed\xb3\x2b\x15\xb9\x3a\ +\x8a\xc6\x5b\xc2\x73\x53\x4e\xe7\xb2\x5f\xf0\xd6\x0e\x7f\x1c\x52\ +\xfa\xfc\xbe\xdb\x73\x51\x0e\x8f\x28\xc0\xb3\xac\x9e\x24\xb0\x20\ +\x8a\x22\xdb\x67\xc5\xc5\xd9\x40\x12\xaa\x93\x59\x8c\xf1\xd2\x6e\ +\x09\x05\xa2\x34\x4d\x2f\xb8\xba\xa3\x1d\x1e\x51\x60\x1d\x40\xf0\ +\x07\xc4\x1d\x6b\x52\x28\x50\x78\xf8\xa8\x9a\x06\x04\x1d\xb4\x9a\ +\xcd\xe7\xc2\x6b\xd3\x3c\xbf\x14\xcb\xf0\x88\x02\x3c\xcf\x0b\x08\ +\x0a\x82\xcb\xe5\xd9\x71\x9e\x97\x97\x0a\x65\x65\x9c\x24\xa3\xf2\ +\x70\x26\x63\x2c\x89\x75\x68\x38\x8a\x48\x01\x8b\x51\xcf\xe9\x74\ +\x78\xee\xa9\xd3\xa9\x48\xf8\xf9\xe5\xd2\xe3\xc8\x85\xf3\x99\xf0\ +\xf9\xd3\xcf\x6a\x83\x56\x53\x45\xaa\x70\xd1\x40\xd1\x62\x62\x02\ +\x8e\xe9\x09\x6d\x7a\x02\x4d\x96\x9b\xf4\x54\x67\x8e\x47\x78\xee\ +\x00\x90\x0e\xea\x8f\x1c\x54\xd8\xc2\x6a\x31\x70\x14\x4d\x8d\xf4\ +\xf5\xdf\x22\x29\x0d\xbe\xa7\x2e\x49\x32\x0c\x7d\x98\x85\xde\xde\ +\x09\xcf\xf7\x09\x67\xc8\x23\xf8\x15\x34\xa1\x96\xdc\xcb\x1b\x5a\ +\x9f\x37\x88\xce\xb9\xdc\x87\xce\x88\x28\x00\x00\x90\x6b\x4d\x7e\ +\x9c\x77\x36\xfd\x5a\x7b\x7b\x0d\x19\xfe\x42\x1e\xc4\xfc\xfc\x2a\ +\xd4\x5d\xed\xda\x14\x04\x7f\xe1\x8c\xd3\xfd\xf5\xb0\x6c\xc4\x15\ +\x00\x00\xd8\x57\xd6\xfb\x1c\x3e\xb9\x64\xfc\xdb\x82\xb9\xa8\x38\ +\x1b\x53\xa9\x0e\xbe\x6d\x72\x92\x87\xa6\xc6\xee\x0d\xc1\xeb\x6f\ +\x99\x5e\x70\x47\xfc\x68\x45\x25\xe0\x00\x90\x6c\x2b\x9e\x57\x33\ +\x02\x58\x5e\xbf\x1c\xe1\x50\x14\x51\x30\x16\x1a\xa5\x69\x35\x00\ +\x00\x84\x44\x09\xc6\xc7\x9c\xd0\xd6\x36\xb8\xd9\xde\xfa\x7e\x7d\ +\xcd\x13\xa8\x9d\xe5\x7f\xbd\x8d\xa6\x77\x54\x2b\x08\xc7\x6a\x31\ +\x70\x04\x45\xdc\x91\x25\xa8\x90\xc4\x90\x16\xc3\x94\xa2\xe0\x0b\ +\xa8\x08\x8d\x6a\xce\x2b\x04\xbb\xd4\x01\xa4\x73\x6c\x71\x71\x33\ +\xd6\xbe\x7f\x44\x4a\x4a\x0a\x91\x96\xa6\x4b\x80\x18\xff\x2b\xe2\ +\xc4\x89\xf3\x4f\xf1\x1b\x22\xca\x00\x6f\xd0\x10\xcf\x18\x00\x00\ +\x00\x00\x49\x45\x4e\x44\xae\x42\x60\x82\ +\x00\x00\x0f\x88\ +\x89\ +\x50\x4e\x47\x0d\x0a\x1a\x0a\x00\x00\x00\x0d\x49\x48\x44\x52\x00\ +\x00\x00\x40\x00\x00\x00\x40\x08\x06\x00\x00\x00\xaa\x69\x71\xde\ +\x00\x00\x00\x09\x70\x48\x59\x73\x00\x00\x0b\x13\x00\x00\x0b\x13\ +\x01\x00\x9a\x9c\x18\x00\x00\x0a\x4f\x69\x43\x43\x50\x50\x68\x6f\ +\x74\x6f\x73\x68\x6f\x70\x20\x49\x43\x43\x20\x70\x72\x6f\x66\x69\ +\x6c\x65\x00\x00\x78\xda\x9d\x53\x67\x54\x53\xe9\x16\x3d\xf7\xde\ +\xf4\x42\x4b\x88\x80\x94\x4b\x6f\x52\x15\x08\x20\x52\x42\x8b\x80\ +\x14\x91\x26\x2a\x21\x09\x10\x4a\x88\x21\xa1\xd9\x15\x51\xc1\x11\ +\x45\x45\x04\x1b\xc8\xa0\x88\x03\x8e\x8e\x80\x8c\x15\x51\x2c\x0c\ +\x8a\x0a\xd8\x07\xe4\x21\xa2\x8e\x83\xa3\x88\x8a\xca\xfb\xe1\x7b\ +\xa3\x6b\xd6\xbc\xf7\xe6\xcd\xfe\xb5\xd7\x3e\xe7\xac\xf3\x9d\xb3\ +\xcf\x07\xc0\x08\x0c\x96\x48\x33\x51\x35\x80\x0c\xa9\x42\x1e\x11\ +\xe0\x83\xc7\xc4\xc6\xe1\xe4\x2e\x40\x81\x0a\x24\x70\x00\x10\x08\ +\xb3\x64\x21\x73\xfd\x23\x01\x00\xf8\x7e\x3c\x3c\x2b\x22\xc0\x07\ +\xbe\x00\x01\x78\xd3\x0b\x08\x00\xc0\x4d\x9b\xc0\x30\x1c\x87\xff\ +\x0f\xea\x42\x99\x5c\x01\x80\x84\x01\xc0\x74\x91\x38\x4b\x08\x80\ +\x14\x00\x40\x7a\x8e\x42\xa6\x00\x40\x46\x01\x80\x9d\x98\x26\x53\ +\x00\xa0\x04\x00\x60\xcb\x63\x62\xe3\x00\x50\x2d\x00\x60\x27\x7f\ +\xe6\xd3\x00\x80\x9d\xf8\x99\x7b\x01\x00\x5b\x94\x21\x15\x01\xa0\ +\x91\x00\x20\x13\x65\x88\x44\x00\x68\x3b\x00\xac\xcf\x56\x8a\x45\ +\x00\x58\x30\x00\x14\x66\x4b\xc4\x39\x00\xd8\x2d\x00\x30\x49\x57\ +\x66\x48\x00\xb0\xb7\x00\xc0\xce\x10\x0b\xb2\x00\x08\x0c\x00\x30\ +\x51\x88\x85\x29\x00\x04\x7b\x00\x60\xc8\x23\x23\x78\x00\x84\x99\ +\x00\x14\x46\xf2\x57\x3c\xf1\x2b\xae\x10\xe7\x2a\x00\x00\x78\x99\ +\xb2\x3c\xb9\x24\x39\x45\x81\x5b\x08\x2d\x71\x07\x57\x57\x2e\x1e\ +\x28\xce\x49\x17\x2b\x14\x36\x61\x02\x61\x9a\x40\x2e\xc2\x79\x99\ +\x19\x32\x81\x34\x0f\xe0\xf3\xcc\x00\x00\xa0\x91\x15\x11\xe0\x83\ +\xf3\xfd\x78\xce\x0e\xae\xce\xce\x36\x8e\xb6\x0e\x5f\x2d\xea\xbf\ +\x06\xff\x22\x62\x62\xe3\xfe\xe5\xcf\xab\x70\x40\x00\x00\xe1\x74\ +\x7e\xd1\xfe\x2c\x2f\xb3\x1a\x80\x3b\x06\x80\x6d\xfe\xa2\x25\xee\ +\x04\x68\x5e\x0b\xa0\x75\xf7\x8b\x66\xb2\x0f\x40\xb5\x00\xa0\xe9\ +\xda\x57\xf3\x70\xf8\x7e\x3c\x3c\x45\xa1\x90\xb9\xd9\xd9\xe5\xe4\ +\xe4\xd8\x4a\xc4\x42\x5b\x61\xca\x57\x7d\xfe\x67\xc2\x5f\xc0\x57\ +\xfd\x6c\xf9\x7e\x3c\xfc\xf7\xf5\xe0\xbe\xe2\x24\x81\x32\x5d\x81\ +\x47\x04\xf8\xe0\xc2\xcc\xf4\x4c\xa5\x1c\xcf\x92\x09\x84\x62\xdc\ +\xe6\x8f\x47\xfc\xb7\x0b\xff\xfc\x1d\xd3\x22\xc4\x49\x62\xb9\x58\ +\x2a\x14\xe3\x51\x12\x71\x8e\x44\x9a\x8c\xf3\x32\xa5\x22\x89\x42\ +\x92\x29\xc5\x25\xd2\xff\x64\xe2\xdf\x2c\xfb\x03\x3e\xdf\x35\x00\ +\xb0\x6a\x3e\x01\x7b\x91\x2d\xa8\x5d\x63\x03\xf6\x4b\x27\x10\x58\ +\x74\xc0\xe2\xf7\x00\x00\xf2\xbb\x6f\xc1\xd4\x28\x08\x03\x80\x68\ +\x83\xe1\xcf\x77\xff\xef\x3f\xfd\x47\xa0\x25\x00\x80\x66\x49\x92\ +\x71\x00\x00\x5e\x44\x24\x2e\x54\xca\xb3\x3f\xc7\x08\x00\x00\x44\ +\xa0\x81\x2a\xb0\x41\x1b\xf4\xc1\x18\x2c\xc0\x06\x1c\xc1\x05\xdc\ +\xc1\x0b\xfc\x60\x36\x84\x42\x24\xc4\xc2\x42\x10\x42\x0a\x64\x80\ +\x1c\x72\x60\x29\xac\x82\x42\x28\x86\xcd\xb0\x1d\x2a\x60\x2f\xd4\ +\x40\x1d\x34\xc0\x51\x68\x86\x93\x70\x0e\x2e\xc2\x55\xb8\x0e\x3d\ +\x70\x0f\xfa\x61\x08\x9e\xc1\x28\xbc\x81\x09\x04\x41\xc8\x08\x13\ +\x61\x21\xda\x88\x01\x62\x8a\x58\x23\x8e\x08\x17\x99\x85\xf8\x21\ +\xc1\x48\x04\x12\x8b\x24\x20\xc9\x88\x14\x51\x22\x4b\x91\x35\x48\ +\x31\x52\x8a\x54\x20\x55\x48\x1d\xf2\x3d\x72\x02\x39\x87\x5c\x46\ +\xba\x91\x3b\xc8\x00\x32\x82\xfc\x86\xbc\x47\x31\x94\x81\xb2\x51\ +\x3d\xd4\x0c\xb5\x43\xb9\xa8\x37\x1a\x84\x46\xa2\x0b\xd0\x64\x74\ +\x31\x9a\x8f\x16\xa0\x9b\xd0\x72\xb4\x1a\x3d\x8c\x36\xa1\xe7\xd0\ +\xab\x68\x0f\xda\x8f\x3e\x43\xc7\x30\xc0\xe8\x18\x07\x33\xc4\x6c\ +\x30\x2e\xc6\xc3\x42\xb1\x38\x2c\x09\x93\x63\xcb\xb1\x22\xac\x0c\ +\xab\xc6\x1a\xb0\x56\xac\x03\xbb\x89\xf5\x63\xcf\xb1\x77\x04\x12\ +\x81\x45\xc0\x09\x36\x04\x77\x42\x20\x61\x1e\x41\x48\x58\x4c\x58\ +\x4e\xd8\x48\xa8\x20\x1c\x24\x34\x11\xda\x09\x37\x09\x03\x84\x51\ +\xc2\x27\x22\x93\xa8\x4b\xb4\x26\xba\x11\xf9\xc4\x18\x62\x32\x31\ +\x87\x58\x48\x2c\x23\xd6\x12\x8f\x13\x2f\x10\x7b\x88\x43\xc4\x37\ +\x24\x12\x89\x43\x32\x27\xb9\x90\x02\x49\xb1\xa4\x54\xd2\x12\xd2\ +\x46\xd2\x6e\x52\x23\xe9\x2c\xa9\x9b\x34\x48\x1a\x23\x93\xc9\xda\ +\x64\x6b\xb2\x07\x39\x94\x2c\x20\x2b\xc8\x85\xe4\x9d\xe4\xc3\xe4\ +\x33\xe4\x1b\xe4\x21\xf2\x5b\x0a\x9d\x62\x40\x71\xa4\xf8\x53\xe2\ +\x28\x52\xca\x6a\x4a\x19\xe5\x10\xe5\x34\xe5\x06\x65\x98\x32\x41\ +\x55\xa3\x9a\x52\xdd\xa8\xa1\x54\x11\x35\x8f\x5a\x42\xad\xa1\xb6\ +\x52\xaf\x51\x87\xa8\x13\x34\x75\x9a\x39\xcd\x83\x16\x49\x4b\xa5\ +\xad\xa2\x95\xd3\x1a\x68\x17\x68\xf7\x69\xaf\xe8\x74\xba\x11\xdd\ +\x95\x1e\x4e\x97\xd0\x57\xd2\xcb\xe9\x47\xe8\x97\xe8\x03\xf4\x77\ +\x0c\x0d\x86\x15\x83\xc7\x88\x67\x28\x19\x9b\x18\x07\x18\x67\x19\ +\x77\x18\xaf\x98\x4c\xa6\x19\xd3\x8b\x19\xc7\x54\x30\x37\x31\xeb\ +\x98\xe7\x99\x0f\x99\x6f\x55\x58\x2a\xb6\x2a\x7c\x15\x91\xca\x0a\ +\x95\x4a\x95\x26\x95\x1b\x2a\x2f\x54\xa9\xaa\xa6\xaa\xde\xaa\x0b\ +\x55\xf3\x55\xcb\x54\x8f\xa9\x5e\x53\x7d\xae\x46\x55\x33\x53\xe3\ +\xa9\x09\xd4\x96\xab\x55\xaa\x9d\x50\xeb\x53\x1b\x53\x67\xa9\x3b\ +\xa8\x87\xaa\x67\xa8\x6f\x54\x3f\xa4\x7e\x59\xfd\x89\x06\x59\xc3\ +\x4c\xc3\x4f\x43\xa4\x51\xa0\xb1\x5f\xe3\xbc\xc6\x20\x0b\x63\x19\ +\xb3\x78\x2c\x21\x6b\x0d\xab\x86\x75\x81\x35\xc4\x26\xb1\xcd\xd9\ +\x7c\x76\x2a\xbb\x98\xfd\x1d\xbb\x8b\x3d\xaa\xa9\xa1\x39\x43\x33\ +\x4a\x33\x57\xb3\x52\xf3\x94\x66\x3f\x07\xe3\x98\x71\xf8\x9c\x74\ +\x4e\x09\xe7\x28\xa7\x97\xf3\x7e\x8a\xde\x14\xef\x29\xe2\x29\x1b\ +\xa6\x34\x4c\xb9\x31\x65\x5c\x6b\xaa\x96\x97\x96\x58\xab\x48\xab\ +\x51\xab\x47\xeb\xbd\x36\xae\xed\xa7\x9d\xa6\xbd\x45\xbb\x59\xfb\ +\x81\x0e\x41\xc7\x4a\x27\x5c\x27\x47\x67\x8f\xce\x05\x9d\xe7\x53\ +\xd9\x53\xdd\xa7\x0a\xa7\x16\x4d\x3d\x3a\xf5\xae\x2e\xaa\x6b\xa5\ +\x1b\xa1\xbb\x44\x77\xbf\x6e\xa7\xee\x98\x9e\xbe\x5e\x80\x9e\x4c\ +\x6f\xa7\xde\x79\xbd\xe7\xfa\x1c\x7d\x2f\xfd\x54\xfd\x6d\xfa\xa7\ +\xf5\x47\x0c\x58\x06\xb3\x0c\x24\x06\xdb\x0c\xce\x18\x3c\xc5\x35\ +\x71\x6f\x3c\x1d\x2f\xc7\xdb\xf1\x51\x43\x5d\xc3\x40\x43\xa5\x61\ +\x95\x61\x97\xe1\x84\x91\xb9\xd1\x3c\xa3\xd5\x46\x8d\x46\x0f\x8c\ +\x69\xc6\x5c\xe3\x24\xe3\x6d\xc6\x6d\xc6\xa3\x26\x06\x26\x21\x26\ +\x4b\x4d\xea\x4d\xee\x9a\x52\x4d\xb9\xa6\x29\xa6\x3b\x4c\x3b\x4c\ +\xc7\xcd\xcc\xcd\xa2\xcd\xd6\x99\x35\x9b\x3d\x31\xd7\x32\xe7\x9b\ +\xe7\x9b\xd7\x9b\xdf\xb7\x60\x5a\x78\x5a\x2c\xb6\xa8\xb6\xb8\x65\ +\x49\xb2\xe4\x5a\xa6\x59\xee\xb6\xbc\x6e\x85\x5a\x39\x59\xa5\x58\ +\x55\x5a\x5d\xb3\x46\xad\x9d\xad\x25\xd6\xbb\xad\xbb\xa7\x11\xa7\ +\xb9\x4e\x93\x4e\xab\x9e\xd6\x67\xc3\xb0\xf1\xb6\xc9\xb6\xa9\xb7\ +\x19\xb0\xe5\xd8\x06\xdb\xae\xb6\x6d\xb6\x7d\x61\x67\x62\x17\x67\ +\xb7\xc5\xae\xc3\xee\x93\xbd\x93\x7d\xba\x7d\x8d\xfd\x3d\x07\x0d\ +\x87\xd9\x0e\xab\x1d\x5a\x1d\x7e\x73\xb4\x72\x14\x3a\x56\x3a\xde\ +\x9a\xce\x9c\xee\x3f\x7d\xc5\xf4\x96\xe9\x2f\x67\x58\xcf\x10\xcf\ +\xd8\x33\xe3\xb6\x13\xcb\x29\xc4\x69\x9d\x53\x9b\xd3\x47\x67\x17\ +\x67\xb9\x73\x83\xf3\x88\x8b\x89\x4b\x82\xcb\x2e\x97\x3e\x2e\x9b\ +\x1b\xc6\xdd\xc8\xbd\xe4\x4a\x74\xf5\x71\x5d\xe1\x7a\xd2\xf5\x9d\ +\x9b\xb3\x9b\xc2\xed\xa8\xdb\xaf\xee\x36\xee\x69\xee\x87\xdc\x9f\ +\xcc\x34\x9f\x29\x9e\x59\x33\x73\xd0\xc3\xc8\x43\xe0\x51\xe5\xd1\ +\x3f\x0b\x9f\x95\x30\x6b\xdf\xac\x7e\x4f\x43\x4f\x81\x67\xb5\xe7\ +\x23\x2f\x63\x2f\x91\x57\xad\xd7\xb0\xb7\xa5\x77\xaa\xf7\x61\xef\ +\x17\x3e\xf6\x3e\x72\x9f\xe3\x3e\xe3\x3c\x37\xde\x32\xde\x59\x5f\ +\xcc\x37\xc0\xb7\xc8\xb7\xcb\x4f\xc3\x6f\x9e\x5f\x85\xdf\x43\x7f\ +\x23\xff\x64\xff\x7a\xff\xd1\x00\xa7\x80\x25\x01\x67\x03\x89\x81\ +\x41\x81\x5b\x02\xfb\xf8\x7a\x7c\x21\xbf\x8e\x3f\x3a\xdb\x65\xf6\ +\xb2\xd9\xed\x41\x8c\xa0\xb9\x41\x15\x41\x8f\x82\xad\x82\xe5\xc1\ +\xad\x21\x68\xc8\xec\x90\xad\x21\xf7\xe7\x98\xce\x91\xce\x69\x0e\ +\x85\x50\x7e\xe8\xd6\xd0\x07\x61\xe6\x61\x8b\xc3\x7e\x0c\x27\x85\ +\x87\x85\x57\x86\x3f\x8e\x70\x88\x58\x1a\xd1\x31\x97\x35\x77\xd1\ +\xdc\x43\x73\xdf\x44\xfa\x44\x96\x44\xde\x9b\x67\x31\x4f\x39\xaf\ +\x2d\x4a\x35\x2a\x3e\xaa\x2e\x6a\x3c\xda\x37\xba\x34\xba\x3f\xc6\ +\x2e\x66\x59\xcc\xd5\x58\x9d\x58\x49\x6c\x4b\x1c\x39\x2e\x2a\xae\ +\x36\x6e\x6c\xbe\xdf\xfc\xed\xf3\x87\xe2\x9d\xe2\x0b\xe3\x7b\x17\ +\x98\x2f\xc8\x5d\x70\x79\xa1\xce\xc2\xf4\x85\xa7\x16\xa9\x2e\x12\ +\x2c\x3a\x96\x40\x4c\x88\x4e\x38\x94\xf0\x41\x10\x2a\xa8\x16\x8c\ +\x25\xf2\x13\x77\x25\x8e\x0a\x79\xc2\x1d\xc2\x67\x22\x2f\xd1\x36\ +\xd1\x88\xd8\x43\x5c\x2a\x1e\x4e\xf2\x48\x2a\x4d\x7a\x92\xec\x91\ +\xbc\x35\x79\x24\xc5\x33\xa5\x2c\xe5\xb9\x84\x27\xa9\x90\xbc\x4c\ +\x0d\x4c\xdd\x9b\x3a\x9e\x16\x9a\x76\x20\x6d\x32\x3d\x3a\xbd\x31\ +\x83\x92\x91\x90\x71\x42\xaa\x21\x4d\x93\xb6\x67\xea\x67\xe6\x66\ +\x76\xcb\xac\x65\x85\xb2\xfe\xc5\x6e\x8b\xb7\x2f\x1e\x95\x07\xc9\ +\x6b\xb3\x90\xac\x05\x59\x2d\x0a\xb6\x42\xa6\xe8\x54\x5a\x28\xd7\ +\x2a\x07\xb2\x67\x65\x57\x66\xbf\xcd\x89\xca\x39\x96\xab\x9e\x2b\ +\xcd\xed\xcc\xb3\xca\xdb\x90\x37\x9c\xef\x9f\xff\xed\x12\xc2\x12\ +\xe1\x92\xb6\xa5\x86\x4b\x57\x2d\x1d\x58\xe6\xbd\xac\x6a\x39\xb2\ +\x3c\x71\x79\xdb\x0a\xe3\x15\x05\x2b\x86\x56\x06\xac\x3c\xb8\x8a\ +\xb6\x2a\x6d\xd5\x4f\xab\xed\x57\x97\xae\x7e\xbd\x26\x7a\x4d\x6b\ +\x81\x5e\xc1\xca\x82\xc1\xb5\x01\x6b\xeb\x0b\x55\x0a\xe5\x85\x7d\ +\xeb\xdc\xd7\xed\x5d\x4f\x58\x2f\x59\xdf\xb5\x61\xfa\x86\x9d\x1b\ +\x3e\x15\x89\x8a\xae\x14\xdb\x17\x97\x15\x7f\xd8\x28\xdc\x78\xe5\ +\x1b\x87\x6f\xca\xbf\x99\xdc\x94\xb4\xa9\xab\xc4\xb9\x64\xcf\x66\ +\xd2\x66\xe9\xe6\xde\x2d\x9e\x5b\x0e\x96\xaa\x97\xe6\x97\x0e\x6e\ +\x0d\xd9\xda\xb4\x0d\xdf\x56\xb4\xed\xf5\xf6\x45\xdb\x2f\x97\xcd\ +\x28\xdb\xbb\x83\xb6\x43\xb9\xa3\xbf\x3c\xb8\xbc\x65\xa7\xc9\xce\ +\xcd\x3b\x3f\x54\xa4\x54\xf4\x54\xfa\x54\x36\xee\xd2\xdd\xb5\x61\ +\xd7\xf8\x6e\xd1\xee\x1b\x7b\xbc\xf6\x34\xec\xd5\xdb\x5b\xbc\xf7\ +\xfd\x3e\xc9\xbe\xdb\x55\x01\x55\x4d\xd5\x66\xd5\x65\xfb\x49\xfb\ +\xb3\xf7\x3f\xae\x89\xaa\xe9\xf8\x96\xfb\x6d\x5d\xad\x4e\x6d\x71\ +\xed\xc7\x03\xd2\x03\xfd\x07\x23\x0e\xb6\xd7\xb9\xd4\xd5\x1d\xd2\ +\x3d\x54\x52\x8f\xd6\x2b\xeb\x47\x0e\xc7\x1f\xbe\xfe\x9d\xef\x77\ +\x2d\x0d\x36\x0d\x55\x8d\x9c\xc6\xe2\x23\x70\x44\x79\xe4\xe9\xf7\ +\x09\xdf\xf7\x1e\x0d\x3a\xda\x76\x8c\x7b\xac\xe1\x07\xd3\x1f\x76\ +\x1d\x67\x1d\x2f\x6a\x42\x9a\xf2\x9a\x46\x9b\x53\x9a\xfb\x5b\x62\ +\x5b\xba\x4f\xcc\x3e\xd1\xd6\xea\xde\x7a\xfc\x47\xdb\x1f\x0f\x9c\ +\x34\x3c\x59\x79\x4a\xf3\x54\xc9\x69\xda\xe9\x82\xd3\x93\x67\xf2\ +\xcf\x8c\x9d\x95\x9d\x7d\x7e\x2e\xf9\xdc\x60\xdb\xa2\xb6\x7b\xe7\ +\x63\xce\xdf\x6a\x0f\x6f\xef\xba\x10\x74\xe1\xd2\x45\xff\x8b\xe7\ +\x3b\xbc\x3b\xce\x5c\xf2\xb8\x74\xf2\xb2\xdb\xe5\x13\x57\xb8\x57\ +\x9a\xaf\x3a\x5f\x6d\xea\x74\xea\x3c\xfe\x93\xd3\x4f\xc7\xbb\x9c\ +\xbb\x9a\xae\xb9\x5c\x6b\xb9\xee\x7a\xbd\xb5\x7b\x66\xf7\xe9\x1b\ +\x9e\x37\xce\xdd\xf4\xbd\x79\xf1\x16\xff\xd6\xd5\x9e\x39\x3d\xdd\ +\xbd\xf3\x7a\x6f\xf7\xc5\xf7\xf5\xdf\x16\xdd\x7e\x72\x27\xfd\xce\ +\xcb\xbb\xd9\x77\x27\xee\xad\xbc\x4f\xbc\x5f\xf4\x40\xed\x41\xd9\ +\x43\xdd\x87\xd5\x3f\x5b\xfe\xdc\xd8\xef\xdc\x7f\x6a\xc0\x77\xa0\ +\xf3\xd1\xdc\x47\xf7\x06\x85\x83\xcf\xfe\x91\xf5\x8f\x0f\x43\x05\ +\x8f\x99\x8f\xcb\x86\x0d\x86\xeb\x9e\x38\x3e\x39\x39\xe2\x3f\x72\ +\xfd\xe9\xfc\xa7\x43\xcf\x64\xcf\x26\x9e\x17\xfe\xa2\xfe\xcb\xae\ +\x17\x16\x2f\x7e\xf8\xd5\xeb\xd7\xce\xd1\x98\xd1\xa1\x97\xf2\x97\ +\x93\xbf\x6d\x7c\xa5\xfd\xea\xc0\xeb\x19\xaf\xdb\xc6\xc2\xc6\x1e\ +\xbe\xc9\x78\x33\x31\x5e\xf4\x56\xfb\xed\xc1\x77\xdc\x77\x1d\xef\ +\xa3\xdf\x0f\x4f\xe4\x7c\x20\x7f\x28\xff\x68\xf9\xb1\xf5\x53\xd0\ +\xa7\xfb\x93\x19\x93\x93\xff\x04\x03\x98\xf3\xfc\x63\x33\x2d\xdb\ +\x00\x00\x00\x20\x63\x48\x52\x4d\x00\x00\x7a\x25\x00\x00\x80\x83\ +\x00\x00\xf9\xff\x00\x00\x80\xe9\x00\x00\x75\x30\x00\x00\xea\x60\ +\x00\x00\x3a\x98\x00\x00\x17\x6f\x92\x5f\xc5\x46\x00\x00\x04\xb3\ +\x49\x44\x41\x54\x78\xda\xec\x9b\x5d\x4c\x5b\x65\x18\xc7\xff\x6f\ +\x4b\x19\x8e\xca\x12\xc0\x36\x2d\x6b\x9a\x8d\x2e\xbb\x11\x24\x54\ +\xbe\x12\x68\x71\x4b\xb6\x25\xf3\x6e\x8a\x5c\x98\x5d\x90\x6c\x6e\ +\x44\x2f\xd8\x00\xfb\xe1\x16\xa6\x59\x84\x69\x24\x21\x82\xcb\xa2\ +\x2e\x61\x12\x58\xa2\x89\x37\x66\x03\xa7\x6e\xf8\x31\x3e\xa6\x2b\ +\xf3\xaa\x4a\xa6\xb6\x7c\xa4\xf5\x60\x32\x53\x3e\xd2\x7a\xce\xf1\ +\x02\x06\x6b\x7b\xca\xd6\xd3\x73\x0e\xa7\xe9\x79\xae\xda\x73\xd2\ +\xf3\xbc\xef\xef\x3c\xef\xf3\x3e\x1f\x6f\x09\x4e\x7d\xcd\x22\x83\ +\x45\x85\x0c\x17\x05\x80\x02\x40\x01\xa0\x00\x50\x00\x6c\x85\x38\ +\x6c\x06\x50\x6e\x2b\x28\xb7\x15\x6d\x75\x86\xcc\x03\xd0\x5a\x67\ +\x84\x8a\x00\x2a\x02\xbc\x69\x33\x66\x1e\x00\x15\xe1\xfe\xac\xf8\ +\x00\x05\x80\x02\x20\x33\x00\x30\x2c\xf7\xe7\xb4\x00\xf0\x7a\x8d\ +\x1e\x01\x67\x39\x82\xae\x72\x9c\xdd\x57\xc4\x4b\xf1\x07\x3f\xcc\ +\x83\x61\x57\x27\xdf\x35\x3a\xc7\xeb\x19\x1d\xfb\x77\x22\xe8\x2a\ +\x47\xc0\x59\x8e\xe6\x2a\x3d\xaf\x67\x10\x3e\xe9\x70\xc0\x55\x0e\ +\xcd\x23\xae\xfb\xd2\x64\x10\x8e\x61\xbf\xa4\x6f\xae\xeb\xa0\x09\ +\xc7\x2a\x74\xeb\xdf\x23\x34\x0b\xfd\xbb\xbf\x48\x63\x01\xb1\xbb\ +\xd6\xf1\x0a\x1d\xce\xed\xdf\x29\xd9\xe4\xcf\x1f\x88\x9e\x3c\x00\ +\x10\x22\xe1\x12\xe8\x1b\x0f\xc6\x5d\x7b\xa3\x46\x0f\x87\x4d\xfc\ +\x88\xce\x65\x37\xe2\x64\xa5\x2e\xee\xfa\x87\xb7\x03\xd2\x01\xe8\ +\xf8\x66\x06\x97\x26\xe3\x21\x34\x57\xeb\x45\x07\x70\x92\x63\xad\ +\x7f\x34\x11\xc4\xdb\xdf\xcd\xf2\x7a\x5e\x16\xef\x58\x7e\xd8\x0f\ +\x02\x44\x99\xe2\x52\x84\xd9\x74\xd9\x1c\xab\xd0\xa1\xa1\x24\x1f\ +\x96\x82\x1c\x68\xb3\xd5\xeb\x11\x20\xc3\x02\xa1\x30\x8d\xe9\x85\ +\x15\x0c\xdd\xfb\x07\x9f\xdc\x09\x22\x91\x63\x5a\xfe\x8f\x41\x6e\ +\xf6\xc6\x7b\xbb\x38\x11\x84\x7b\x84\xbf\xff\x21\xa9\xd6\x04\xdd\ +\xf5\x46\xbc\x56\xa9\xc3\x72\x84\xc1\xd1\xcf\xef\x63\xdc\x1f\x8a\ +\xba\xaf\x26\x04\xdd\x87\xcd\x68\x28\xc9\x47\xb6\xfa\xc9\x16\x6a\ +\x98\x66\x71\xf5\xd7\x05\x9c\xfa\xca\x07\x9a\x8d\x1e\x5e\xb5\x49\ +\x8b\xfe\x97\x8a\x91\xa3\x21\xe8\x1b\x0f\xa2\xf3\xd6\x5c\x4a\x16\ +\x45\xc4\x2c\x8a\x1e\xb0\xec\xc0\xa7\x47\x76\x63\xbb\x86\x5f\xb8\ +\xb1\x14\x61\xd0\xf4\xc5\x7d\x8c\x4c\x3f\x48\xbf\x40\xa8\xad\xce\ +\x80\xa1\x46\x0b\xef\xc9\x03\xc0\x76\x8d\x0a\x43\x8d\x16\x51\xd3\ +\x65\x51\x00\x9c\xae\x35\xc0\x69\x17\x2e\xc5\x75\xda\x8d\x38\x5d\ +\x6b\x48\x0f\x00\x2f\xec\xce\x83\xbb\x5e\xf8\xfc\xde\x5d\x6f\x84\ +\x7d\x57\x9e\xbc\x01\x64\xa9\x08\xae\xbc\x5c\x2c\x9a\xb9\x0e\x34\ +\x14\x43\x4d\x88\x7c\x01\xf4\xbc\x68\x4e\x69\xcd\x3f\x89\x4f\xe8\ +\x3e\x6c\x96\x27\x00\x15\x01\x8e\x3c\x9b\x2f\x7a\x20\xf4\x4a\x49\ +\x3e\x88\x1c\x01\x34\x59\x75\x51\x09\x92\x58\xa2\x51\x13\x34\x59\ +\x9f\x91\x1f\x80\xc6\x52\xf1\xdf\xfe\x86\xae\x02\xf9\x01\xb0\x14\ +\xe4\x48\x06\x60\x4f\xa1\x70\xba\x12\xe6\x02\x0e\x9b\x61\xbd\x74\ +\x1d\x5b\xc9\xe9\x1a\x9d\xc3\x7b\xdf\xcf\x47\x5d\xd7\x66\xab\x25\ +\x03\xc0\xa5\x2b\xd9\xf1\x3e\xd6\x02\xb8\x1e\xf6\xd0\xd9\x71\xd5\ +\xf1\xa5\x2c\x6d\x73\xe9\x4a\x76\xbc\xa2\x87\xc2\xe9\x22\x09\x01\ +\x3c\xac\xd9\xc5\x4a\xa2\x1a\x9e\x94\x85\x4d\x2e\x5d\xc9\x8e\x57\ +\xf0\x6c\xf0\xcf\xb6\x32\xe4\x6d\x93\xc6\x0f\x3c\x58\xa1\xb1\xeb\ +\x7d\x8f\xbc\x76\x01\x2f\xb5\x22\x99\x05\x78\xa9\x65\xf9\x6d\x83\ +\x83\x53\x94\x64\x00\x06\xa7\x16\xe4\x07\xa0\xff\x2e\x85\x08\x2d\ +\xbe\x23\x88\xd0\x2c\xfa\xef\x52\xf2\x03\xc0\xb0\xc0\x80\x04\x56\ +\x30\x30\x45\x41\x48\xcc\x82\x6e\x83\xad\xd7\x7c\x58\x0c\x33\xa2\ +\x4d\x3e\x14\xa6\xd1\x7a\xcd\x27\xdf\x74\x98\x61\x81\xc6\xab\xbf\ +\x43\x8c\x85\xc0\x02\x68\x18\x9c\x16\x7c\xbb\x15\x3c\x10\xfa\xf1\ +\xaf\x10\xde\x1a\x11\xbe\x4d\xe6\x1c\xf6\x63\x2c\xa6\xe2\x2c\x4b\ +\x00\xc0\x6a\xa3\xc2\x31\xec\x17\xc4\x12\x58\x00\xed\xd7\xfd\x9c\ +\x8d\x18\xd9\x02\x00\x56\x1b\xa6\x87\x2e\x7b\x37\x6d\x96\x3c\x4e\ +\x96\x22\x0c\x0e\x5d\xf6\xe2\xe3\x3b\x41\xd1\xfc\x4a\xca\x00\x5c\ +\x76\x23\x7c\xed\x65\xf0\xb6\x94\xa2\xca\xa4\x8d\xba\x37\x39\x1b\ +\x82\xf9\x82\x07\x9f\x79\x16\x10\x4e\x62\x8b\x0c\xd3\x2c\xae\x78\ +\x28\x98\x2f\x78\x30\x39\x1b\x6d\xf6\xd5\x26\x2d\xbc\x2d\xa5\xf0\ +\xb5\x97\xc1\x21\x40\xe5\x39\xa5\x50\xb8\xf3\xa0\x09\xc7\x1f\x69\ +\x8d\xfd\xbd\x18\xc1\xde\xee\x7b\x09\x14\x09\xd3\x1a\xfb\xad\xe5\ +\x39\x14\xe6\x6e\x64\xf1\x17\x27\x82\x70\xa5\xe0\x73\xb2\x84\x9a\ +\x3c\x00\x3c\xb5\x49\x41\x94\x5d\x5b\x16\xa9\xae\xe5\x58\x1d\x27\ +\xd6\x3a\xc5\x7c\x21\xf0\x5a\x02\x67\xf7\x15\xc5\x4d\x1e\x00\xfa\ +\xc6\x02\x10\x5b\x7a\xc7\xe3\x75\x9c\xa8\xd4\xa1\x83\xe7\xf9\x04\ +\x7e\x47\x64\x38\xda\xe0\xbd\x63\x01\x74\x8e\xce\x8b\x0e\xa0\xf3\ +\xd6\x1c\x7a\x39\x40\x37\x57\xe9\xa4\x03\x10\xd3\xb0\x45\xcf\xed\ +\x00\xce\xdc\x98\x91\x2c\x19\x3a\x73\x63\x06\x3d\x31\x07\x22\x58\ +\x9e\x9e\x4c\x8d\x9a\xa3\x1d\xc9\xfe\x68\x85\x66\x50\x6b\x7e\x1a\ +\xec\xda\xe4\xcf\x7d\x9b\xfc\xe1\x04\x87\xcd\x80\x2f\x5f\xdd\x8b\ +\x76\x9b\x11\x2c\x80\x9f\x7c\xc9\x05\x39\x37\xff\xf8\x17\xdb\xb2\ +\x54\x78\xbe\x28\x17\x34\x03\xbc\x73\x73\x16\x13\x33\x8b\xd2\xee\ +\x02\xa9\x08\xe5\xb6\x46\xed\x02\x85\xe7\x7f\xde\x8a\x61\x28\x67\ +\x85\x95\xa2\xa8\x02\x40\x01\xb0\x35\x92\xd6\x67\x85\x85\x10\x21\ +\xce\x0a\x0b\x21\x44\xf9\xeb\xac\xe2\x03\x14\x00\x0a\x80\x4c\x96\ +\xff\x07\x00\x85\xfa\xad\x10\xc5\x6e\x22\x46\x00\x00\x00\x00\x49\ +\x45\x4e\x44\xae\x42\x60\x82\ +\x00\x00\x0f\x88\ +\x89\ +\x50\x4e\x47\x0d\x0a\x1a\x0a\x00\x00\x00\x0d\x49\x48\x44\x52\x00\ +\x00\x00\x40\x00\x00\x00\x40\x08\x06\x00\x00\x00\xaa\x69\x71\xde\ +\x00\x00\x00\x09\x70\x48\x59\x73\x00\x00\x0b\x13\x00\x00\x0b\x13\ +\x01\x00\x9a\x9c\x18\x00\x00\x0a\x4f\x69\x43\x43\x50\x50\x68\x6f\ +\x74\x6f\x73\x68\x6f\x70\x20\x49\x43\x43\x20\x70\x72\x6f\x66\x69\ +\x6c\x65\x00\x00\x78\xda\x9d\x53\x67\x54\x53\xe9\x16\x3d\xf7\xde\ +\xf4\x42\x4b\x88\x80\x94\x4b\x6f\x52\x15\x08\x20\x52\x42\x8b\x80\ +\x14\x91\x26\x2a\x21\x09\x10\x4a\x88\x21\xa1\xd9\x15\x51\xc1\x11\ +\x45\x45\x04\x1b\xc8\xa0\x88\x03\x8e\x8e\x80\x8c\x15\x51\x2c\x0c\ +\x8a\x0a\xd8\x07\xe4\x21\xa2\x8e\x83\xa3\x88\x8a\xca\xfb\xe1\x7b\ +\xa3\x6b\xd6\xbc\xf7\xe6\xcd\xfe\xb5\xd7\x3e\xe7\xac\xf3\x9d\xb3\ +\xcf\x07\xc0\x08\x0c\x96\x48\x33\x51\x35\x80\x0c\xa9\x42\x1e\x11\ +\xe0\x83\xc7\xc4\xc6\xe1\xe4\x2e\x40\x81\x0a\x24\x70\x00\x10\x08\ +\xb3\x64\x21\x73\xfd\x23\x01\x00\xf8\x7e\x3c\x3c\x2b\x22\xc0\x07\ +\xbe\x00\x01\x78\xd3\x0b\x08\x00\xc0\x4d\x9b\xc0\x30\x1c\x87\xff\ +\x0f\xea\x42\x99\x5c\x01\x80\x84\x01\xc0\x74\x91\x38\x4b\x08\x80\ +\x14\x00\x40\x7a\x8e\x42\xa6\x00\x40\x46\x01\x80\x9d\x98\x26\x53\ +\x00\xa0\x04\x00\x60\xcb\x63\x62\xe3\x00\x50\x2d\x00\x60\x27\x7f\ +\xe6\xd3\x00\x80\x9d\xf8\x99\x7b\x01\x00\x5b\x94\x21\x15\x01\xa0\ +\x91\x00\x20\x13\x65\x88\x44\x00\x68\x3b\x00\xac\xcf\x56\x8a\x45\ +\x00\x58\x30\x00\x14\x66\x4b\xc4\x39\x00\xd8\x2d\x00\x30\x49\x57\ +\x66\x48\x00\xb0\xb7\x00\xc0\xce\x10\x0b\xb2\x00\x08\x0c\x00\x30\ +\x51\x88\x85\x29\x00\x04\x7b\x00\x60\xc8\x23\x23\x78\x00\x84\x99\ +\x00\x14\x46\xf2\x57\x3c\xf1\x2b\xae\x10\xe7\x2a\x00\x00\x78\x99\ +\xb2\x3c\xb9\x24\x39\x45\x81\x5b\x08\x2d\x71\x07\x57\x57\x2e\x1e\ +\x28\xce\x49\x17\x2b\x14\x36\x61\x02\x61\x9a\x40\x2e\xc2\x79\x99\ +\x19\x32\x81\x34\x0f\xe0\xf3\xcc\x00\x00\xa0\x91\x15\x11\xe0\x83\ +\xf3\xfd\x78\xce\x0e\xae\xce\xce\x36\x8e\xb6\x0e\x5f\x2d\xea\xbf\ +\x06\xff\x22\x62\x62\xe3\xfe\xe5\xcf\xab\x70\x40\x00\x00\xe1\x74\ +\x7e\xd1\xfe\x2c\x2f\xb3\x1a\x80\x3b\x06\x80\x6d\xfe\xa2\x25\xee\ +\x04\x68\x5e\x0b\xa0\x75\xf7\x8b\x66\xb2\x0f\x40\xb5\x00\xa0\xe9\ +\xda\x57\xf3\x70\xf8\x7e\x3c\x3c\x45\xa1\x90\xb9\xd9\xd9\xe5\xe4\ +\xe4\xd8\x4a\xc4\x42\x5b\x61\xca\x57\x7d\xfe\x67\xc2\x5f\xc0\x57\ +\xfd\x6c\xf9\x7e\x3c\xfc\xf7\xf5\xe0\xbe\xe2\x24\x81\x32\x5d\x81\ +\x47\x04\xf8\xe0\xc2\xcc\xf4\x4c\xa5\x1c\xcf\x92\x09\x84\x62\xdc\ +\xe6\x8f\x47\xfc\xb7\x0b\xff\xfc\x1d\xd3\x22\xc4\x49\x62\xb9\x58\ +\x2a\x14\xe3\x51\x12\x71\x8e\x44\x9a\x8c\xf3\x32\xa5\x22\x89\x42\ +\x92\x29\xc5\x25\xd2\xff\x64\xe2\xdf\x2c\xfb\x03\x3e\xdf\x35\x00\ +\xb0\x6a\x3e\x01\x7b\x91\x2d\xa8\x5d\x63\x03\xf6\x4b\x27\x10\x58\ +\x74\xc0\xe2\xf7\x00\x00\xf2\xbb\x6f\xc1\xd4\x28\x08\x03\x80\x68\ +\x83\xe1\xcf\x77\xff\xef\x3f\xfd\x47\xa0\x25\x00\x80\x66\x49\x92\ +\x71\x00\x00\x5e\x44\x24\x2e\x54\xca\xb3\x3f\xc7\x08\x00\x00\x44\ +\xa0\x81\x2a\xb0\x41\x1b\xf4\xc1\x18\x2c\xc0\x06\x1c\xc1\x05\xdc\ +\xc1\x0b\xfc\x60\x36\x84\x42\x24\xc4\xc2\x42\x10\x42\x0a\x64\x80\ +\x1c\x72\x60\x29\xac\x82\x42\x28\x86\xcd\xb0\x1d\x2a\x60\x2f\xd4\ +\x40\x1d\x34\xc0\x51\x68\x86\x93\x70\x0e\x2e\xc2\x55\xb8\x0e\x3d\ +\x70\x0f\xfa\x61\x08\x9e\xc1\x28\xbc\x81\x09\x04\x41\xc8\x08\x13\ +\x61\x21\xda\x88\x01\x62\x8a\x58\x23\x8e\x08\x17\x99\x85\xf8\x21\ +\xc1\x48\x04\x12\x8b\x24\x20\xc9\x88\x14\x51\x22\x4b\x91\x35\x48\ +\x31\x52\x8a\x54\x20\x55\x48\x1d\xf2\x3d\x72\x02\x39\x87\x5c\x46\ +\xba\x91\x3b\xc8\x00\x32\x82\xfc\x86\xbc\x47\x31\x94\x81\xb2\x51\ +\x3d\xd4\x0c\xb5\x43\xb9\xa8\x37\x1a\x84\x46\xa2\x0b\xd0\x64\x74\ +\x31\x9a\x8f\x16\xa0\x9b\xd0\x72\xb4\x1a\x3d\x8c\x36\xa1\xe7\xd0\ +\xab\x68\x0f\xda\x8f\x3e\x43\xc7\x30\xc0\xe8\x18\x07\x33\xc4\x6c\ +\x30\x2e\xc6\xc3\x42\xb1\x38\x2c\x09\x93\x63\xcb\xb1\x22\xac\x0c\ +\xab\xc6\x1a\xb0\x56\xac\x03\xbb\x89\xf5\x63\xcf\xb1\x77\x04\x12\ +\x81\x45\xc0\x09\x36\x04\x77\x42\x20\x61\x1e\x41\x48\x58\x4c\x58\ +\x4e\xd8\x48\xa8\x20\x1c\x24\x34\x11\xda\x09\x37\x09\x03\x84\x51\ +\xc2\x27\x22\x93\xa8\x4b\xb4\x26\xba\x11\xf9\xc4\x18\x62\x32\x31\ +\x87\x58\x48\x2c\x23\xd6\x12\x8f\x13\x2f\x10\x7b\x88\x43\xc4\x37\ +\x24\x12\x89\x43\x32\x27\xb9\x90\x02\x49\xb1\xa4\x54\xd2\x12\xd2\ +\x46\xd2\x6e\x52\x23\xe9\x2c\xa9\x9b\x34\x48\x1a\x23\x93\xc9\xda\ +\x64\x6b\xb2\x07\x39\x94\x2c\x20\x2b\xc8\x85\xe4\x9d\xe4\xc3\xe4\ +\x33\xe4\x1b\xe4\x21\xf2\x5b\x0a\x9d\x62\x40\x71\xa4\xf8\x53\xe2\ +\x28\x52\xca\x6a\x4a\x19\xe5\x10\xe5\x34\xe5\x06\x65\x98\x32\x41\ +\x55\xa3\x9a\x52\xdd\xa8\xa1\x54\x11\x35\x8f\x5a\x42\xad\xa1\xb6\ +\x52\xaf\x51\x87\xa8\x13\x34\x75\x9a\x39\xcd\x83\x16\x49\x4b\xa5\ +\xad\xa2\x95\xd3\x1a\x68\x17\x68\xf7\x69\xaf\xe8\x74\xba\x11\xdd\ +\x95\x1e\x4e\x97\xd0\x57\xd2\xcb\xe9\x47\xe8\x97\xe8\x03\xf4\x77\ +\x0c\x0d\x86\x15\x83\xc7\x88\x67\x28\x19\x9b\x18\x07\x18\x67\x19\ +\x77\x18\xaf\x98\x4c\xa6\x19\xd3\x8b\x19\xc7\x54\x30\x37\x31\xeb\ +\x98\xe7\x99\x0f\x99\x6f\x55\x58\x2a\xb6\x2a\x7c\x15\x91\xca\x0a\ +\x95\x4a\x95\x26\x95\x1b\x2a\x2f\x54\xa9\xaa\xa6\xaa\xde\xaa\x0b\ +\x55\xf3\x55\xcb\x54\x8f\xa9\x5e\x53\x7d\xae\x46\x55\x33\x53\xe3\ +\xa9\x09\xd4\x96\xab\x55\xaa\x9d\x50\xeb\x53\x1b\x53\x67\xa9\x3b\ +\xa8\x87\xaa\x67\xa8\x6f\x54\x3f\xa4\x7e\x59\xfd\x89\x06\x59\xc3\ +\x4c\xc3\x4f\x43\xa4\x51\xa0\xb1\x5f\xe3\xbc\xc6\x20\x0b\x63\x19\ +\xb3\x78\x2c\x21\x6b\x0d\xab\x86\x75\x81\x35\xc4\x26\xb1\xcd\xd9\ +\x7c\x76\x2a\xbb\x98\xfd\x1d\xbb\x8b\x3d\xaa\xa9\xa1\x39\x43\x33\ +\x4a\x33\x57\xb3\x52\xf3\x94\x66\x3f\x07\xe3\x98\x71\xf8\x9c\x74\ +\x4e\x09\xe7\x28\xa7\x97\xf3\x7e\x8a\xde\x14\xef\x29\xe2\x29\x1b\ +\xa6\x34\x4c\xb9\x31\x65\x5c\x6b\xaa\x96\x97\x96\x58\xab\x48\xab\ +\x51\xab\x47\xeb\xbd\x36\xae\xed\xa7\x9d\xa6\xbd\x45\xbb\x59\xfb\ +\x81\x0e\x41\xc7\x4a\x27\x5c\x27\x47\x67\x8f\xce\x05\x9d\xe7\x53\ +\xd9\x53\xdd\xa7\x0a\xa7\x16\x4d\x3d\x3a\xf5\xae\x2e\xaa\x6b\xa5\ +\x1b\xa1\xbb\x44\x77\xbf\x6e\xa7\xee\x98\x9e\xbe\x5e\x80\x9e\x4c\ +\x6f\xa7\xde\x79\xbd\xe7\xfa\x1c\x7d\x2f\xfd\x54\xfd\x6d\xfa\xa7\ +\xf5\x47\x0c\x58\x06\xb3\x0c\x24\x06\xdb\x0c\xce\x18\x3c\xc5\x35\ +\x71\x6f\x3c\x1d\x2f\xc7\xdb\xf1\x51\x43\x5d\xc3\x40\x43\xa5\x61\ +\x95\x61\x97\xe1\x84\x91\xb9\xd1\x3c\xa3\xd5\x46\x8d\x46\x0f\x8c\ +\x69\xc6\x5c\xe3\x24\xe3\x6d\xc6\x6d\xc6\xa3\x26\x06\x26\x21\x26\ +\x4b\x4d\xea\x4d\xee\x9a\x52\x4d\xb9\xa6\x29\xa6\x3b\x4c\x3b\x4c\ +\xc7\xcd\xcc\xcd\xa2\xcd\xd6\x99\x35\x9b\x3d\x31\xd7\x32\xe7\x9b\ +\xe7\x9b\xd7\x9b\xdf\xb7\x60\x5a\x78\x5a\x2c\xb6\xa8\xb6\xb8\x65\ +\x49\xb2\xe4\x5a\xa6\x59\xee\xb6\xbc\x6e\x85\x5a\x39\x59\xa5\x58\ +\x55\x5a\x5d\xb3\x46\xad\x9d\xad\x25\xd6\xbb\xad\xbb\xa7\x11\xa7\ +\xb9\x4e\x93\x4e\xab\x9e\xd6\x67\xc3\xb0\xf1\xb6\xc9\xb6\xa9\xb7\ +\x19\xb0\xe5\xd8\x06\xdb\xae\xb6\x6d\xb6\x7d\x61\x67\x62\x17\x67\ +\xb7\xc5\xae\xc3\xee\x93\xbd\x93\x7d\xba\x7d\x8d\xfd\x3d\x07\x0d\ +\x87\xd9\x0e\xab\x1d\x5a\x1d\x7e\x73\xb4\x72\x14\x3a\x56\x3a\xde\ +\x9a\xce\x9c\xee\x3f\x7d\xc5\xf4\x96\xe9\x2f\x67\x58\xcf\x10\xcf\ +\xd8\x33\xe3\xb6\x13\xcb\x29\xc4\x69\x9d\x53\x9b\xd3\x47\x67\x17\ +\x67\xb9\x73\x83\xf3\x88\x8b\x89\x4b\x82\xcb\x2e\x97\x3e\x2e\x9b\ +\x1b\xc6\xdd\xc8\xbd\xe4\x4a\x74\xf5\x71\x5d\xe1\x7a\xd2\xf5\x9d\ +\x9b\xb3\x9b\xc2\xed\xa8\xdb\xaf\xee\x36\xee\x69\xee\x87\xdc\x9f\ +\xcc\x34\x9f\x29\x9e\x59\x33\x73\xd0\xc3\xc8\x43\xe0\x51\xe5\xd1\ +\x3f\x0b\x9f\x95\x30\x6b\xdf\xac\x7e\x4f\x43\x4f\x81\x67\xb5\xe7\ +\x23\x2f\x63\x2f\x91\x57\xad\xd7\xb0\xb7\xa5\x77\xaa\xf7\x61\xef\ +\x17\x3e\xf6\x3e\x72\x9f\xe3\x3e\xe3\x3c\x37\xde\x32\xde\x59\x5f\ +\xcc\x37\xc0\xb7\xc8\xb7\xcb\x4f\xc3\x6f\x9e\x5f\x85\xdf\x43\x7f\ +\x23\xff\x64\xff\x7a\xff\xd1\x00\xa7\x80\x25\x01\x67\x03\x89\x81\ +\x41\x81\x5b\x02\xfb\xf8\x7a\x7c\x21\xbf\x8e\x3f\x3a\xdb\x65\xf6\ +\xb2\xd9\xed\x41\x8c\xa0\xb9\x41\x15\x41\x8f\x82\xad\x82\xe5\xc1\ +\xad\x21\x68\xc8\xec\x90\xad\x21\xf7\xe7\x98\xce\x91\xce\x69\x0e\ +\x85\x50\x7e\xe8\xd6\xd0\x07\x61\xe6\x61\x8b\xc3\x7e\x0c\x27\x85\ +\x87\x85\x57\x86\x3f\x8e\x70\x88\x58\x1a\xd1\x31\x97\x35\x77\xd1\ +\xdc\x43\x73\xdf\x44\xfa\x44\x96\x44\xde\x9b\x67\x31\x4f\x39\xaf\ +\x2d\x4a\x35\x2a\x3e\xaa\x2e\x6a\x3c\xda\x37\xba\x34\xba\x3f\xc6\ +\x2e\x66\x59\xcc\xd5\x58\x9d\x58\x49\x6c\x4b\x1c\x39\x2e\x2a\xae\ +\x36\x6e\x6c\xbe\xdf\xfc\xed\xf3\x87\xe2\x9d\xe2\x0b\xe3\x7b\x17\ +\x98\x2f\xc8\x5d\x70\x79\xa1\xce\xc2\xf4\x85\xa7\x16\xa9\x2e\x12\ +\x2c\x3a\x96\x40\x4c\x88\x4e\x38\x94\xf0\x41\x10\x2a\xa8\x16\x8c\ +\x25\xf2\x13\x77\x25\x8e\x0a\x79\xc2\x1d\xc2\x67\x22\x2f\xd1\x36\ +\xd1\x88\xd8\x43\x5c\x2a\x1e\x4e\xf2\x48\x2a\x4d\x7a\x92\xec\x91\ +\xbc\x35\x79\x24\xc5\x33\xa5\x2c\xe5\xb9\x84\x27\xa9\x90\xbc\x4c\ +\x0d\x4c\xdd\x9b\x3a\x9e\x16\x9a\x76\x20\x6d\x32\x3d\x3a\xbd\x31\ +\x83\x92\x91\x90\x71\x42\xaa\x21\x4d\x93\xb6\x67\xea\x67\xe6\x66\ +\x76\xcb\xac\x65\x85\xb2\xfe\xc5\x6e\x8b\xb7\x2f\x1e\x95\x07\xc9\ +\x6b\xb3\x90\xac\x05\x59\x2d\x0a\xb6\x42\xa6\xe8\x54\x5a\x28\xd7\ +\x2a\x07\xb2\x67\x65\x57\x66\xbf\xcd\x89\xca\x39\x96\xab\x9e\x2b\ +\xcd\xed\xcc\xb3\xca\xdb\x90\x37\x9c\xef\x9f\xff\xed\x12\xc2\x12\ +\xe1\x92\xb6\xa5\x86\x4b\x57\x2d\x1d\x58\xe6\xbd\xac\x6a\x39\xb2\ +\x3c\x71\x79\xdb\x0a\xe3\x15\x05\x2b\x86\x56\x06\xac\x3c\xb8\x8a\ +\xb6\x2a\x6d\xd5\x4f\xab\xed\x57\x97\xae\x7e\xbd\x26\x7a\x4d\x6b\ +\x81\x5e\xc1\xca\x82\xc1\xb5\x01\x6b\xeb\x0b\x55\x0a\xe5\x85\x7d\ +\xeb\xdc\xd7\xed\x5d\x4f\x58\x2f\x59\xdf\xb5\x61\xfa\x86\x9d\x1b\ +\x3e\x15\x89\x8a\xae\x14\xdb\x17\x97\x15\x7f\xd8\x28\xdc\x78\xe5\ +\x1b\x87\x6f\xca\xbf\x99\xdc\x94\xb4\xa9\xab\xc4\xb9\x64\xcf\x66\ +\xd2\x66\xe9\xe6\xde\x2d\x9e\x5b\x0e\x96\xaa\x97\xe6\x97\x0e\x6e\ +\x0d\xd9\xda\xb4\x0d\xdf\x56\xb4\xed\xf5\xf6\x45\xdb\x2f\x97\xcd\ +\x28\xdb\xbb\x83\xb6\x43\xb9\xa3\xbf\x3c\xb8\xbc\x65\xa7\xc9\xce\ +\xcd\x3b\x3f\x54\xa4\x54\xf4\x54\xfa\x54\x36\xee\xd2\xdd\xb5\x61\ +\xd7\xf8\x6e\xd1\xee\x1b\x7b\xbc\xf6\x34\xec\xd5\xdb\x5b\xbc\xf7\ +\xfd\x3e\xc9\xbe\xdb\x55\x01\x55\x4d\xd5\x66\xd5\x65\xfb\x49\xfb\ +\xb3\xf7\x3f\xae\x89\xaa\xe9\xf8\x96\xfb\x6d\x5d\xad\x4e\x6d\x71\ +\xed\xc7\x03\xd2\x03\xfd\x07\x23\x0e\xb6\xd7\xb9\xd4\xd5\x1d\xd2\ +\x3d\x54\x52\x8f\xd6\x2b\xeb\x47\x0e\xc7\x1f\xbe\xfe\x9d\xef\x77\ +\x2d\x0d\x36\x0d\x55\x8d\x9c\xc6\xe2\x23\x70\x44\x79\xe4\xe9\xf7\ +\x09\xdf\xf7\x1e\x0d\x3a\xda\x76\x8c\x7b\xac\xe1\x07\xd3\x1f\x76\ +\x1d\x67\x1d\x2f\x6a\x42\x9a\xf2\x9a\x46\x9b\x53\x9a\xfb\x5b\x62\ +\x5b\xba\x4f\xcc\x3e\xd1\xd6\xea\xde\x7a\xfc\x47\xdb\x1f\x0f\x9c\ +\x34\x3c\x59\x79\x4a\xf3\x54\xc9\x69\xda\xe9\x82\xd3\x93\x67\xf2\ +\xcf\x8c\x9d\x95\x9d\x7d\x7e\x2e\xf9\xdc\x60\xdb\xa2\xb6\x7b\xe7\ +\x63\xce\xdf\x6a\x0f\x6f\xef\xba\x10\x74\xe1\xd2\x45\xff\x8b\xe7\ +\x3b\xbc\x3b\xce\x5c\xf2\xb8\x74\xf2\xb2\xdb\xe5\x13\x57\xb8\x57\ +\x9a\xaf\x3a\x5f\x6d\xea\x74\xea\x3c\xfe\x93\xd3\x4f\xc7\xbb\x9c\ +\xbb\x9a\xae\xb9\x5c\x6b\xb9\xee\x7a\xbd\xb5\x7b\x66\xf7\xe9\x1b\ +\x9e\x37\xce\xdd\xf4\xbd\x79\xf1\x16\xff\xd6\xd5\x9e\x39\x3d\xdd\ +\xbd\xf3\x7a\x6f\xf7\xc5\xf7\xf5\xdf\x16\xdd\x7e\x72\x27\xfd\xce\ +\xcb\xbb\xd9\x77\x27\xee\xad\xbc\x4f\xbc\x5f\xf4\x40\xed\x41\xd9\ +\x43\xdd\x87\xd5\x3f\x5b\xfe\xdc\xd8\xef\xdc\x7f\x6a\xc0\x77\xa0\ +\xf3\xd1\xdc\x47\xf7\x06\x85\x83\xcf\xfe\x91\xf5\x8f\x0f\x43\x05\ +\x8f\x99\x8f\xcb\x86\x0d\x86\xeb\x9e\x38\x3e\x39\x39\xe2\x3f\x72\ +\xfd\xe9\xfc\xa7\x43\xcf\x64\xcf\x26\x9e\x17\xfe\xa2\xfe\xcb\xae\ +\x17\x16\x2f\x7e\xf8\xd5\xeb\xd7\xce\xd1\x98\xd1\xa1\x97\xf2\x97\ +\x93\xbf\x6d\x7c\xa5\xfd\xea\xc0\xeb\x19\xaf\xdb\xc6\xc2\xc6\x1e\ +\xbe\xc9\x78\x33\x31\x5e\xf4\x56\xfb\xed\xc1\x77\xdc\x77\x1d\xef\ +\xa3\xdf\x0f\x4f\xe4\x7c\x20\x7f\x28\xff\x68\xf9\xb1\xf5\x53\xd0\ +\xa7\xfb\x93\x19\x93\x93\xff\x04\x03\x98\xf3\xfc\x63\x33\x2d\xdb\ +\x00\x00\x00\x20\x63\x48\x52\x4d\x00\x00\x7a\x25\x00\x00\x80\x83\ +\x00\x00\xf9\xff\x00\x00\x80\xe9\x00\x00\x75\x30\x00\x00\xea\x60\ +\x00\x00\x3a\x98\x00\x00\x17\x6f\x92\x5f\xc5\x46\x00\x00\x04\xb3\ +\x49\x44\x41\x54\x78\xda\xec\x9b\x5d\x4c\x5b\x65\x18\xc7\xff\x6f\ +\x4b\x19\x8e\xca\x12\xc0\x36\x2d\x6b\x9a\x8d\x2e\xbb\x11\x24\x54\ +\xbe\x12\x68\x71\x4b\xb6\x25\xf3\x6e\x8a\x5c\x98\x5d\x90\x6c\x6e\ +\x44\x2f\xd8\x00\xfb\xe1\x16\xa6\x59\x84\x69\x24\x21\x82\xcb\xa2\ +\x2e\x61\x12\x58\xa2\x89\x37\x66\x03\xa7\x6e\xf8\x31\x3e\xa6\x2b\ +\xf3\xaa\x4a\xa6\xb6\x7c\xa4\xf5\x60\x32\x53\x3e\xd2\x7a\xce\xf1\ +\x02\x06\x6b\x7b\xca\xd6\xd3\x73\x0e\xa7\xe9\x79\xae\xda\x73\xd2\ +\xf3\xbc\xef\xef\x3c\xef\xf3\x3e\x1f\x6f\x09\x4e\x7d\xcd\x22\x83\ +\x45\x85\x0c\x17\x05\x80\x02\x40\x01\xa0\x00\x50\x00\x6c\x85\x38\ +\x6c\x06\x50\x6e\x2b\x28\xb7\x15\x6d\x75\x86\xcc\x03\xd0\x5a\x67\ +\x84\x8a\x00\x2a\x02\xbc\x69\x33\x66\x1e\x00\x15\xe1\xfe\xac\xf8\ +\x00\x05\x80\x02\x20\x33\x00\x30\x2c\xf7\xe7\xb4\x00\xf0\x7a\x8d\ +\x1e\x01\x67\x39\x82\xae\x72\x9c\xdd\x57\xc4\x4b\xf1\x07\x3f\xcc\ +\x83\x61\x57\x27\xdf\x35\x3a\xc7\xeb\x19\x1d\xfb\x77\x22\xe8\x2a\ +\x47\xc0\x59\x8e\xe6\x2a\x3d\xaf\x67\x10\x3e\xe9\x70\xc0\x55\x0e\ +\xcd\x23\xae\xfb\xd2\x64\x10\x8e\x61\xbf\xa4\x6f\xae\xeb\xa0\x09\ +\xc7\x2a\x74\xeb\xdf\x23\x34\x0b\xfd\xbb\xbf\x48\x63\x01\xb1\xbb\ +\xd6\xf1\x0a\x1d\xce\xed\xdf\x29\xd9\xe4\xcf\x1f\x88\x9e\x3c\x00\ +\x10\x22\xe1\x12\xe8\x1b\x0f\xc6\x5d\x7b\xa3\x46\x0f\x87\x4d\xfc\ +\x88\xce\x65\x37\xe2\x64\xa5\x2e\xee\xfa\x87\xb7\x03\xd2\x01\xe8\ +\xf8\x66\x06\x97\x26\xe3\x21\x34\x57\xeb\x45\x07\x70\x92\x63\xad\ +\x7f\x34\x11\xc4\xdb\xdf\xcd\xf2\x7a\x5e\x16\xef\x58\x7e\xd8\x0f\ +\x02\x44\x99\xe2\x52\x84\xd9\x74\xd9\x1c\xab\xd0\xa1\xa1\x24\x1f\ +\x96\x82\x1c\x68\xb3\xd5\xeb\x11\x20\xc3\x02\xa1\x30\x8d\xe9\x85\ +\x15\x0c\xdd\xfb\x07\x9f\xdc\x09\x22\x91\x63\x5a\xfe\x8f\x41\x6e\ +\xf6\xc6\x7b\xbb\x38\x11\x84\x7b\x84\xbf\xff\x21\xa9\xd6\x04\xdd\ +\xf5\x46\xbc\x56\xa9\xc3\x72\x84\xc1\xd1\xcf\xef\x63\xdc\x1f\x8a\ +\xba\xaf\x26\x04\xdd\x87\xcd\x68\x28\xc9\x47\xb6\xfa\xc9\x16\x6a\ +\x98\x66\x71\xf5\xd7\x05\x9c\xfa\xca\x07\x9a\x8d\x1e\x5e\xb5\x49\ +\x8b\xfe\x97\x8a\x91\xa3\x21\xe8\x1b\x0f\xa2\xf3\xd6\x5c\x4a\x16\ +\x45\xc4\x2c\x8a\x1e\xb0\xec\xc0\xa7\x47\x76\x63\xbb\x86\x5f\xb8\ +\xb1\x14\x61\xd0\xf4\xc5\x7d\x8c\x4c\x3f\x48\xbf\x40\xa8\xad\xce\ +\x80\xa1\x46\x0b\xef\xc9\x03\xc0\x76\x8d\x0a\x43\x8d\x16\x51\xd3\ +\x65\x51\x00\x9c\xae\x35\xc0\x69\x17\x2e\xc5\x75\xda\x8d\x38\x5d\ +\x6b\x48\x0f\x00\x2f\xec\xce\x83\xbb\x5e\xf8\xfc\xde\x5d\x6f\x84\ +\x7d\x57\x9e\xbc\x01\x64\xa9\x08\xae\xbc\x5c\x2c\x9a\xb9\x0e\x34\ +\x14\x43\x4d\x88\x7c\x01\xf4\xbc\x68\x4e\x69\xcd\x3f\x89\x4f\xe8\ +\x3e\x6c\x96\x27\x00\x15\x01\x8e\x3c\x9b\x2f\x7a\x20\xf4\x4a\x49\ +\x3e\x88\x1c\x01\x34\x59\x75\x51\x09\x92\x58\xa2\x51\x13\x34\x59\ +\x9f\x91\x1f\x80\xc6\x52\xf1\xdf\xfe\x86\xae\x02\xf9\x01\xb0\x14\ +\xe4\x48\x06\x60\x4f\xa1\x70\xba\x12\xe6\x02\x0e\x9b\x61\xbd\x74\ +\x1d\x5b\xc9\xe9\x1a\x9d\xc3\x7b\xdf\xcf\x47\x5d\xd7\x66\xab\x25\ +\x03\xc0\xa5\x2b\xd9\xf1\x3e\xd6\x02\xb8\x1e\xf6\xd0\xd9\x71\xd5\ +\xf1\xa5\x2c\x6d\x73\xe9\x4a\x76\xbc\xa2\x87\xc2\xe9\x22\x09\x01\ +\x3c\xac\xd9\xc5\x4a\xa2\x1a\x9e\x94\x85\x4d\x2e\x5d\xc9\x8e\x57\ +\xf0\x6c\xf0\xcf\xb6\x32\xe4\x6d\x93\xc6\x0f\x3c\x58\xa1\xb1\xeb\ +\x7d\x8f\xbc\x76\x01\x2f\xb5\x22\x99\x05\x78\xa9\x65\xf9\x6d\x83\ +\x83\x53\x94\x64\x00\x06\xa7\x16\xe4\x07\xa0\xff\x2e\x85\x08\x2d\ +\xbe\x23\x88\xd0\x2c\xfa\xef\x52\xf2\x03\xc0\xb0\xc0\x80\x04\x56\ +\x30\x30\x45\x41\x48\xcc\x82\x6e\x83\xad\xd7\x7c\x58\x0c\x33\xa2\ +\x4d\x3e\x14\xa6\xd1\x7a\xcd\x27\xdf\x74\x98\x61\x81\xc6\xab\xbf\ +\x43\x8c\x85\xc0\x02\x68\x18\x9c\x16\x7c\xbb\x15\x3c\x10\xfa\xf1\ +\xaf\x10\xde\x1a\x11\xbe\x4d\xe6\x1c\xf6\x63\x2c\xa6\xe2\x2c\x4b\ +\x00\xc0\x6a\xa3\xc2\x31\xec\x17\xc4\x12\x58\x00\xed\xd7\xfd\x9c\ +\x8d\x18\xd9\x02\x00\x56\x1b\xa6\x87\x2e\x7b\x37\x6d\x96\x3c\x4e\ +\x96\x22\x0c\x0e\x5d\xf6\xe2\xe3\x3b\x41\xd1\xfc\x4a\xca\x00\x5c\ +\x76\x23\x7c\xed\x65\xf0\xb6\x94\xa2\xca\xa4\x8d\xba\x37\x39\x1b\ +\x82\xf9\x82\x07\x9f\x79\x16\x10\x4e\x62\x8b\x0c\xd3\x2c\xae\x78\ +\x28\x98\x2f\x78\x30\x39\x1b\x6d\xf6\xd5\x26\x2d\xbc\x2d\xa5\xf0\ +\xb5\x97\xc1\x21\x40\xe5\x39\xa5\x50\xb8\xf3\xa0\x09\xc7\x1f\x69\ +\x8d\xfd\xbd\x18\xc1\xde\xee\x7b\x09\x14\x09\xd3\x1a\xfb\xad\xe5\ +\x39\x14\xe6\x6e\x64\xf1\x17\x27\x82\x70\xa5\xe0\x73\xb2\x84\x9a\ +\x3c\x00\x3c\xb5\x49\x41\x94\x5d\x5b\x16\xa9\xae\xe5\x58\x1d\x27\ +\xd6\x3a\xc5\x7c\x21\xf0\x5a\x02\x67\xf7\x15\xc5\x4d\x1e\x00\xfa\ +\xc6\x02\x10\x5b\x7a\xc7\xe3\x75\x9c\xa8\xd4\xa1\x83\xe7\xf9\x04\ +\x7e\x47\x64\x38\xda\xe0\xbd\x63\x01\x74\x8e\xce\x8b\x0e\xa0\xf3\ +\xd6\x1c\x7a\x39\x40\x37\x57\xe9\xa4\x03\x10\xd3\xb0\x45\xcf\xed\ +\x00\xce\xdc\x98\x91\x2c\x19\x3a\x73\x63\x06\x3d\x31\x07\x22\x58\ +\x9e\x9e\x4c\x8d\x9a\xa3\x1d\xc9\xfe\x68\x85\x66\x50\x6b\x7e\x1a\ +\xec\xda\xe4\xcf\x7d\x9b\xfc\xe1\x04\x87\xcd\x80\x2f\x5f\xdd\x8b\ +\x76\x9b\x11\x2c\x80\x9f\x7c\xc9\x05\x39\x37\xff\xf8\x17\xdb\xb2\ +\x54\x78\xbe\x28\x17\x34\x03\xbc\x73\x73\x16\x13\x33\x8b\xd2\xee\ +\x02\xa9\x08\xe5\xb6\x46\xed\x02\x85\xe7\x7f\xde\x8a\x61\x28\x67\ +\x85\x95\xa2\xa8\x02\x40\x01\xb0\x35\x92\xd6\x67\x85\x85\x10\x21\ +\xce\x0a\x0b\x21\x44\xf9\xeb\xac\xe2\x03\x14\x00\x0a\x80\x4c\x96\ +\xff\x07\x00\x85\xfa\xad\x10\xc5\x6e\x22\x46\x00\x00\x00\x00\x49\ +\x45\x4e\x44\xae\x42\x60\x82\ +\x00\x00\x03\xd7\ +\x89\ +\x50\x4e\x47\x0d\x0a\x1a\x0a\x00\x00\x00\x0d\x49\x48\x44\x52\x00\ +\x00\x00\x20\x00\x00\x00\x20\x08\x06\x00\x00\x00\x73\x7a\x7a\xf4\ +\x00\x00\x00\x04\x73\x42\x49\x54\x08\x08\x08\x08\x7c\x08\x64\x88\ +\x00\x00\x00\x09\x70\x48\x59\x73\x00\x00\x0b\x13\x00\x00\x0b\x13\ +\x01\x00\x9a\x9c\x18\x00\x00\x03\x79\x49\x44\x41\x54\x58\x85\xed\ +\x56\x5f\x68\x5b\x75\x14\xfe\xce\xcd\xcd\xbf\xf6\xa6\x59\x96\x7b\ +\x93\xdb\x88\x6b\x93\x9b\xd2\x91\xcd\x0e\x11\x1f\x2a\x6c\x63\x22\ +\x0a\xb3\x74\x22\xfa\x30\x1f\xf6\xb0\x37\xeb\x7c\xe8\x60\x0a\xa2\ +\x20\x88\xff\xc0\xaa\xb5\xe2\x9c\x6f\xfa\x30\x11\x61\x9b\x4e\x41\ +\x11\x04\x61\xa0\xf5\xcf\x1c\x6c\xa6\xf6\xbf\x12\x5d\x93\x26\x59\ +\x48\x73\x13\xdb\xdc\xe4\x1e\x5f\x8c\xa4\x35\x49\x6f\xdb\x21\x0c\ +\xfa\xbd\xfd\xce\xf9\xee\x77\x3e\xce\xbd\xe7\xdc\x1f\xb0\x8d\x6d\ +\xdc\xca\x88\xc5\xe0\xb8\x0b\xb0\x6f\x45\xc3\xb6\x95\x87\x3d\x82\ +\x72\x6a\xc5\xe3\xbe\x3b\xa7\xff\xf5\xed\x66\x35\x04\xab\xc4\x68\ +\x48\xbe\x53\x53\x95\x37\x57\x05\x89\x45\x66\x61\x55\x07\x22\xaa\ +\x3c\xa6\x05\x83\x7b\x6e\xba\x01\xb4\xed\x88\x9b\x30\x07\xb4\x40\ +\xa0\xbf\xce\x41\x82\x05\x33\x51\x3b\xf5\xa8\xf2\x01\x32\xe9\xbe\ +\x1d\xa9\xd4\x94\x65\xdd\x8d\x20\x1c\x94\x1f\xd4\x82\xca\x0b\xcd\ +\xf2\x9a\x2a\xbf\xaa\x75\x2a\x0f\x6c\x44\x93\x5a\x25\xbb\x15\x65\ +\x5f\x9b\x92\x9e\x88\xc7\x51\xae\x0b\x0b\xd1\x4e\xff\x51\xaf\x24\ +\x3e\xb1\x5c\xe6\xdd\x00\xe0\xb2\xd3\xaf\x4b\xa5\xea\x5b\xd3\xd7\ +\x33\x1f\x01\xe0\x1a\xb1\xab\xab\xcb\xe5\x30\x4a\xbb\xa7\xaf\xa7\ +\xaf\x6c\xca\xc0\x3f\xef\xfc\xb0\xc9\x3c\x3c\x9f\xca\x7c\xbe\x6b\ +\x97\xd7\xe7\x13\x9c\x5f\x45\x42\x62\xef\xd0\x11\x49\xea\x0b\x3b\ +\x00\x00\x3f\xcf\x96\xf1\xce\x27\xba\xfe\xfb\x62\xf9\xda\x72\x9e\ +\xef\x9f\xcc\x66\x0b\x5a\xc0\x3f\x68\x0a\x78\x83\x98\xce\xcd\xa5\ +\x32\xa7\x36\x65\x00\x00\xb4\x40\xa0\x9f\x05\x1e\x98\x4b\xa6\x9f\ +\xeb\xeb\x0e\x8c\x1f\x3d\xe4\xde\x37\xfc\x68\xc7\x7f\x46\x8f\x19\ +\x78\xe9\xc3\x7c\xf9\xe2\xa5\xe5\xef\xaf\xfc\xb6\xb8\x5f\x53\xe5\ +\x97\x05\xb6\x5d\x98\x4e\xa5\xc6\x5b\xe9\xaf\x6b\xa0\x86\x68\xa7\ +\xff\xb1\xbe\xb0\xf3\xcc\xd9\x67\xfd\x52\x33\x0e\x33\xf0\xc8\xf3\ +\x19\x7d\x6a\xa1\x7a\x6c\xfa\x8f\xc5\xf3\x56\x74\x2d\x4f\x81\x57\ +\x12\x4f\x0c\x3d\x24\x35\x2d\x0e\x00\x44\xc0\xe3\x47\x3c\x92\xd7\ +\xc5\x4f\x5a\xd5\x15\x1b\x05\x63\x31\x38\x96\xb3\xca\x49\x10\x8b\ +\x00\x25\xe6\x92\xe9\xf7\x0d\xc3\xec\xdd\xdb\xbd\xfe\xd2\xdb\xdb\ +\x2d\x22\xa7\xe3\x10\x00\x84\x83\xf2\x71\x22\x84\xc0\x64\xdc\x9e\ +\x4a\x8f\x7c\x03\x54\xd6\xf2\x1b\x76\xc0\x1d\x07\x13\x99\x06\x98\ +\x2a\x4c\x66\x05\x00\xaa\x4c\xc4\xdc\x88\xbd\x1a\xf5\x14\x81\xa8\ +\x02\xa6\x0a\x11\x1b\xcd\xf8\x0d\x3b\xf0\x13\x60\x20\x99\x1d\xa9\ +\x8f\x39\xed\x34\x71\x75\xde\xb8\xe7\x40\x9f\xb3\xa5\x81\xab\xf3\ +\x06\x7c\x12\xbe\x06\x80\xd9\x64\xfa\x83\x5a\x7c\xb6\x09\xdf\xf2\ +\x37\x50\x28\x56\xdf\x7e\xef\x33\xbd\xd0\x8a\xc3\x0c\xbc\xfb\xa9\ +\xae\x17\x4a\xe6\xa8\x55\xdd\x75\x7f\x46\xe1\x4e\x79\xbf\x5f\x6a\ +\x1b\x9a\x49\x66\x46\xed\xa2\x73\x30\xaf\x9b\x81\xfe\x98\xcb\x46\ +\x6b\xe6\x87\x19\x78\xf1\x6c\xbe\x7c\x79\xb2\xfc\xdd\xb5\x44\xe6\ +\x99\x48\x50\x19\xf1\x75\xb4\x17\x73\x7a\x29\xd1\x58\xd9\x82\x81\ +\x88\x2a\x8f\x09\x4c\xc3\x10\xe8\x74\x4e\x2f\xcd\x78\xc8\xf5\xf1\ +\xec\x82\x79\xef\x17\x3f\xae\xf8\x76\x76\xd8\x1c\xed\x2e\x42\x69\ +\x85\x31\x3e\x61\xe0\xa9\x33\xf9\xc2\xe5\xa9\xf2\x0f\xd5\x92\x30\ +\x90\x2a\x16\x0d\x9f\xa7\x4d\x24\xa6\xd3\x3e\xa9\x3d\x92\x2b\x96\ +\xbe\x6c\x56\xa3\xe5\x1e\x08\x07\x02\x77\xb8\xe5\xc5\xc9\x35\xab\ +\x18\x3d\xb7\x29\x0f\x7b\xdd\x38\x51\xa9\xf0\x9e\x2a\x40\x4e\x3b\ +\xfd\x92\x2f\x61\x6c\xfa\xcf\xf4\xb9\x7a\x5e\x2c\x06\x47\xf9\xc6\ +\xce\xe8\x4c\xf2\x46\xbc\x55\x1d\xcb\xd0\x02\xfe\x41\x4d\x95\x5f\ +\x69\x96\x8f\x04\x95\xd7\x22\xaa\x7c\x78\x23\x9a\xd6\xef\x03\xd1\ +\xa8\xd3\x14\xf0\xba\xc0\xb6\x7f\x37\x5c\x38\x28\x1f\xd7\x54\xe5\ +\x58\x9d\xda\x05\x06\x8f\xc6\x62\x70\xdc\x74\x03\xd5\xa5\xa5\x5e\ +\x62\x3a\x5f\xbf\xdb\x89\x10\x62\x46\xa8\x76\x9e\x5b\x48\x5f\x22\ +\x16\x2e\xae\x64\x83\x3d\x56\x75\xb7\x84\x48\x50\x79\x5a\x53\xe5\ +\x93\xff\x4b\xb1\x46\x38\x08\x88\x07\x9b\x2c\xb3\x6d\x6c\xe3\x96\ +\xc1\xdf\xd0\x8a\x3c\x4e\x76\x81\x84\x65\x00\x00\x00\x00\x49\x45\ +\x4e\x44\xae\x42\x60\x82\ +\x00\x00\x03\xd7\ +\x89\ +\x50\x4e\x47\x0d\x0a\x1a\x0a\x00\x00\x00\x0d\x49\x48\x44\x52\x00\ +\x00\x00\x20\x00\x00\x00\x20\x08\x06\x00\x00\x00\x73\x7a\x7a\xf4\ +\x00\x00\x00\x04\x73\x42\x49\x54\x08\x08\x08\x08\x7c\x08\x64\x88\ +\x00\x00\x00\x09\x70\x48\x59\x73\x00\x00\x0b\x13\x00\x00\x0b\x13\ +\x01\x00\x9a\x9c\x18\x00\x00\x03\x79\x49\x44\x41\x54\x58\x85\xed\ +\x56\x5f\x68\x5b\x75\x14\xfe\xce\xcd\xcd\xbf\xf6\xa6\x59\x96\x7b\ +\x93\xdb\x88\x6b\x93\x9b\xd2\x91\xcd\x0e\x11\x1f\x2a\x6c\x63\x22\ +\x0a\xb3\x74\x22\xfa\x30\x1f\xf6\xb0\x37\xeb\x7c\xe8\x60\x0a\xa2\ +\x20\x88\xff\xc0\xaa\xb5\xe2\x9c\x6f\xfa\x30\x11\x61\x9b\x4e\x41\ +\x11\x04\x61\xa0\xf5\xcf\x1c\x6c\xa6\xf6\xbf\x12\x5d\x93\x26\x59\ +\x48\x73\x13\xdb\xdc\xe4\x1e\x5f\x8c\xa4\x35\x49\x6f\xdb\x21\x0c\ +\xfa\xbd\xfd\xce\xf9\xee\x77\x3e\xce\xbd\xe7\xdc\x1f\xb0\x8d\x6d\ +\xdc\xca\x88\xc5\xe0\xb8\x0b\xb0\x6f\x45\xc3\xb6\x95\x87\x3d\x82\ +\x72\x6a\xc5\xe3\xbe\x3b\xa7\xff\xf5\xed\x66\x35\x04\xab\xc4\x68\ +\x48\xbe\x53\x53\x95\x37\x57\x05\x89\x45\x66\x61\x55\x07\x22\xaa\ +\x3c\xa6\x05\x83\x7b\x6e\xba\x01\xb4\xed\x88\x9b\x30\x07\xb4\x40\ +\xa0\xbf\xce\x41\x82\x05\x33\x51\x3b\xf5\xa8\xf2\x01\x32\xe9\xbe\ +\x1d\xa9\xd4\x94\x65\xdd\x8d\x20\x1c\x94\x1f\xd4\x82\xca\x0b\xcd\ +\xf2\x9a\x2a\xbf\xaa\x75\x2a\x0f\x6c\x44\x93\x5a\x25\xbb\x15\x65\ +\x5f\x9b\x92\x9e\x88\xc7\x51\xae\x0b\x0b\xd1\x4e\xff\x51\xaf\x24\ +\x3e\xb1\x5c\xe6\xdd\x00\xe0\xb2\xd3\xaf\x4b\xa5\xea\x5b\xd3\xd7\ +\x33\x1f\x01\xe0\x1a\xb1\xab\xab\xcb\xe5\x30\x4a\xbb\xa7\xaf\xa7\ +\xaf\x6c\xca\xc0\x3f\xef\xfc\xb0\xc9\x3c\x3c\x9f\xca\x7c\xbe\x6b\ +\x97\xd7\xe7\x13\x9c\x5f\x45\x42\x62\xef\xd0\x11\x49\xea\x0b\x3b\ +\x00\x00\x3f\xcf\x96\xf1\xce\x27\xba\xfe\xfb\x62\xf9\xda\x72\x9e\ +\xef\x9f\xcc\x66\x0b\x5a\xc0\x3f\x68\x0a\x78\x83\x98\xce\xcd\xa5\ +\x32\xa7\x36\x65\x00\x00\xb4\x40\xa0\x9f\x05\x1e\x98\x4b\xa6\x9f\ +\xeb\xeb\x0e\x8c\x1f\x3d\xe4\xde\x37\xfc\x68\xc7\x7f\x46\x8f\x19\ +\x78\xe9\xc3\x7c\xf9\xe2\xa5\xe5\xef\xaf\xfc\xb6\xb8\x5f\x53\xe5\ +\x97\x05\xb6\x5d\x98\x4e\xa5\xc6\x5b\xe9\xaf\x6b\xa0\x86\x68\xa7\ +\xff\xb1\xbe\xb0\xf3\xcc\xd9\x67\xfd\x52\x33\x0e\x33\xf0\xc8\xf3\ +\x19\x7d\x6a\xa1\x7a\x6c\xfa\x8f\xc5\xf3\x56\x74\x2d\x4f\x81\x57\ +\x12\x4f\x0c\x3d\x24\x35\x2d\x0e\x00\x44\xc0\xe3\x47\x3c\x92\xd7\ +\xc5\x4f\x5a\xd5\x15\x1b\x05\x63\x31\x38\x96\xb3\xca\x49\x10\x8b\ +\x00\x25\xe6\x92\xe9\xf7\x0d\xc3\xec\xdd\xdb\xbd\xfe\xd2\xdb\xdb\ +\x2d\x22\xa7\xe3\x10\x00\x84\x83\xf2\x71\x22\x84\xc0\x64\xdc\x9e\ +\x4a\x8f\x7c\x03\x54\xd6\xf2\x1b\x76\xc0\x1d\x07\x13\x99\x06\x98\ +\x2a\x4c\x66\x05\x00\xaa\x4c\xc4\xdc\x88\xbd\x1a\xf5\x14\x81\xa8\ +\x02\xa6\x0a\x11\x1b\xcd\xf8\x0d\x3b\xf0\x13\x60\x20\x99\x1d\xa9\ +\x8f\x39\xed\x34\x71\x75\xde\xb8\xe7\x40\x9f\xb3\xa5\x81\xab\xf3\ +\x06\x7c\x12\xbe\x06\x80\xd9\x64\xfa\x83\x5a\x7c\xb6\x09\xdf\xf2\ +\x37\x50\x28\x56\xdf\x7e\xef\x33\xbd\xd0\x8a\xc3\x0c\xbc\xfb\xa9\ +\xae\x17\x4a\xe6\xa8\x55\xdd\x75\x7f\x46\xe1\x4e\x79\xbf\x5f\x6a\ +\x1b\x9a\x49\x66\x46\xed\xa2\x73\x30\xaf\x9b\x81\xfe\x98\xcb\x46\ +\x6b\xe6\x87\x19\x78\xf1\x6c\xbe\x7c\x79\xb2\xfc\xdd\xb5\x44\xe6\ +\x99\x48\x50\x19\xf1\x75\xb4\x17\x73\x7a\x29\xd1\x58\xd9\x82\x81\ +\x88\x2a\x8f\x09\x4c\xc3\x10\xe8\x74\x4e\x2f\xcd\x78\xc8\xf5\xf1\ +\xec\x82\x79\xef\x17\x3f\xae\xf8\x76\x76\xd8\x1c\xed\x2e\x42\x69\ +\x85\x31\x3e\x61\xe0\xa9\x33\xf9\xc2\xe5\xa9\xf2\x0f\xd5\x92\x30\ +\x90\x2a\x16\x0d\x9f\xa7\x4d\x24\xa6\xd3\x3e\xa9\x3d\x92\x2b\x96\ +\xbe\x6c\x56\xa3\xe5\x1e\x08\x07\x02\x77\xb8\xe5\xc5\xc9\x35\xab\ +\x18\x3d\xb7\x29\x0f\x7b\xdd\x38\x51\xa9\xf0\x9e\x2a\x40\x4e\x3b\ +\xfd\x92\x2f\x61\x6c\xfa\xcf\xf4\xb9\x7a\x5e\x2c\x06\x47\xf9\xc6\ +\xce\xe8\x4c\xf2\x46\xbc\x55\x1d\xcb\xd0\x02\xfe\x41\x4d\x95\x5f\ +\x69\x96\x8f\x04\x95\xd7\x22\xaa\x7c\x78\x23\x9a\xd6\xef\x03\xd1\ +\xa8\xd3\x14\xf0\xba\xc0\xb6\x7f\x37\x5c\x38\x28\x1f\xd7\x54\xe5\ +\x58\x9d\xda\x05\x06\x8f\xc6\x62\x70\xdc\x74\x03\xd5\xa5\xa5\x5e\ +\x62\x3a\x5f\xbf\xdb\x89\x10\x62\x46\xa8\x76\x9e\x5b\x48\x5f\x22\ +\x16\x2e\xae\x64\x83\x3d\x56\x75\xb7\x84\x48\x50\x79\x5a\x53\xe5\ +\x93\xff\x4b\xb1\x46\x38\x08\x88\x07\x9b\x2c\xb3\x6d\x6c\xe3\x96\ +\xc1\xdf\xd0\x8a\x3c\x4e\x76\x81\x84\x65\x00\x00\x00\x00\x49\x45\ +\x4e\x44\xae\x42\x60\x82\ +\x00\x00\x03\xdd\ +\x89\ +\x50\x4e\x47\x0d\x0a\x1a\x0a\x00\x00\x00\x0d\x49\x48\x44\x52\x00\ +\x00\x00\x20\x00\x00\x00\x20\x08\x06\x00\x00\x00\x73\x7a\x7a\xf4\ +\x00\x00\x00\x04\x73\x42\x49\x54\x08\x08\x08\x08\x7c\x08\x64\x88\ +\x00\x00\x00\x09\x70\x48\x59\x73\x00\x00\x0b\x13\x00\x00\x0b\x13\ +\x01\x00\x9a\x9c\x18\x00\x00\x03\x7f\x49\x44\x41\x54\x58\x85\xed\ +\x94\x5f\x68\x5b\x55\x1c\xc7\xbf\xbf\x73\xee\x6d\xb3\xa6\x4d\x72\ +\x6f\x72\x9b\x9b\xcc\x2e\x6b\x13\x27\x9d\x54\x10\x87\x68\xd9\x10\ +\x44\xc1\xc7\x22\xc2\xd0\x87\x0d\x64\x32\xa6\x75\x0a\x56\xf6\xe6\ +\xde\xa4\x3e\xf8\x20\x1b\x0e\x5f\xe6\x8b\xa2\xf8\xe8\x83\xf8\xe8\ +\xbf\xee\x41\x2b\x2a\xce\x51\xba\xae\xb0\x9a\x36\xb1\x37\x49\x75\ +\xc6\xb4\xb7\xc9\x39\x3f\x1f\x5c\xb2\xb6\x24\xed\x1d\x1b\x82\xd8\ +\xef\xd3\xf9\xf3\x3d\xdf\xdf\xe7\x1c\xce\x39\xc0\xae\x76\xf5\x5f\ +\x56\xce\xb6\x23\x07\x1d\xa7\xf7\x4e\x32\xc4\x9d\x2c\x66\x43\x8c\ +\xaf\x09\x9c\xfa\x57\x00\x86\xdc\xf8\xc9\xac\xeb\x1c\xdb\x04\x20\ +\x20\x00\xc8\xcd\x3e\xe7\xf8\x60\x32\xf1\xfc\x5d\x07\x90\xe0\xaf\ +\x00\x4c\x0e\x59\x56\xb4\x05\xc0\x58\x22\xc2\x52\xb3\x9f\xc9\x44\ +\x63\x00\xde\x24\x85\xaf\x83\xe7\x06\x54\xa5\xba\x5a\xb2\xc2\xe1\ +\x14\x19\xc2\x5a\xa9\xd6\x7e\x02\x80\xdf\xff\xaa\xfd\xd0\x6c\x03\ +\x40\x3c\x14\x79\x96\x88\xf3\xf3\xcb\xa5\x4f\x82\xe6\xd2\x76\x73\ +\x39\xdb\xee\x9b\xab\x54\x6e\x6c\x9d\x18\x4c\x25\x8e\x10\xe3\x28\ +\x83\xee\x07\x00\xd2\x7c\x85\x98\x3e\xbc\xe6\x79\x97\xb6\x7a\x73\ +\xb6\x1d\x69\x97\xd1\x54\xc7\x13\xb8\xd7\xb5\x87\x59\xd2\xb4\x15\ +\xee\x15\xa9\x4c\x6d\xda\xf3\xa0\x86\x2c\x2b\x1a\x8b\xf6\x7e\xdc\ +\x6d\xf2\x0b\xc7\x9f\x0c\xf7\x9c\x1e\xeb\x4b\x8c\x8d\xee\x09\xdb\ +\x11\x11\xf9\x65\xc1\x3f\xd6\x17\xee\x1d\xdd\xd3\x17\xfd\xac\x5a\ +\xad\xd6\x73\xb9\x5c\x77\xcc\x94\xaf\xc3\xc0\x07\x56\x28\xfc\xe9\ +\x4a\xad\x56\xb9\xdd\x13\x40\x36\x6d\x0d\x40\x1b\x6f\x31\xf4\x97\ +\x56\xb1\x7c\xb1\xe2\xc6\xbf\x38\x32\xd2\x5d\x3f\xff\x4a\xec\x70\ +\x97\x90\x9b\xe0\xd7\x95\x52\x27\xdf\xfe\xe3\xd2\xb7\x33\xbe\x7f\ +\xad\x58\x7a\x2a\x9b\x74\x4e\x01\x78\x44\x98\xea\xcc\xd5\x7c\x65\ +\xb1\x53\x8d\x6d\x01\x36\xc1\xb8\xce\xc4\x40\xbf\x7c\xfa\xf3\x49\ +\xe7\xd1\xed\x7c\x4f\x4c\x94\xa6\x8b\x95\xc6\xfb\x73\x45\xef\xdd\ +\x20\xb9\xc1\xff\x01\xcd\xe3\x17\x4e\xc7\xf6\xee\x64\x3b\xf7\x52\ +\xa4\x9f\x81\x57\x83\xc6\xb6\x05\x78\x08\x30\x33\x99\x68\xec\xe6\ +\xb3\x12\xd9\xb4\x35\x60\x9a\xe0\xc1\xb4\xb9\x6f\xa7\xc0\xe1\xc1\ +\xae\x7d\x52\x22\x94\x71\x1c\x17\x80\x6c\xe6\x3c\x06\x18\x81\x01\ +\x56\xdc\xc4\x19\xc3\x37\x66\x0c\xdf\x98\x19\xea\x4f\x1c\x55\x75\ +\xc3\x0e\x99\xf8\x33\xe8\xae\xac\x1e\x39\x67\x4a\x65\x67\x5d\xe7\ +\xb9\x66\xce\xaf\x49\xe7\xb5\x76\xde\x40\x77\x20\xe3\x38\xae\x29\ +\xe9\xfb\xcb\x17\x93\xe9\x20\xfe\x91\x13\x4b\xcb\xab\xa2\x3e\x9c\ +\xcf\xdf\x68\x7b\xf3\x37\x2a\xd0\x1d\xb8\xee\x79\x45\x05\xbd\xf2\ +\xe3\xec\xfa\xcc\x4e\xde\xa9\xcb\x6b\x3f\xeb\x86\x58\x08\x52\x1c\ +\xe8\x70\x02\x39\xd7\x79\x91\xa1\xdf\xb8\xc9\x38\xcd\x00\x43\xeb\ +\x35\x69\x8a\x2e\x43\x52\x88\xb4\x6e\x0b\xde\x10\x42\x0b\xcd\xfe\ +\xaa\xd2\xbe\x64\x11\x22\x80\x00\x7d\x08\x00\x18\x38\x3b\x5f\x2c\ +\xbf\x17\x08\x00\x80\x38\xe8\x38\x3d\x00\x50\x16\x82\xe3\x5a\x93\ +\x21\x04\x37\xb4\xa6\x66\xbf\xdd\xa2\xb2\x10\x9c\x6c\xc2\x6c\xf1\ +\x5e\xf1\xbc\x1a\x00\x1d\x14\x00\x00\xb0\xdf\x75\x33\x04\x75\x88\ +\x98\xcd\xd6\x02\x29\x59\xb2\x58\x9c\x2d\x14\xbe\xd9\xe8\x3d\x90\ +\x4a\x1d\x66\xa8\x01\xa5\x35\x37\xc7\x98\xa8\x4e\xd4\xf8\x6e\xbe\ +\xb0\xb2\xd0\xa9\x46\xdb\xa7\x71\x6b\xb2\xb1\x5f\x13\x3f\x08\x2d\ +\xbb\x5b\x83\x0d\xe6\x3a\xfb\x63\x07\x9c\xf8\xc8\xac\x57\xbe\xf0\ +\x4f\xf1\xc4\x89\x75\xf6\x1f\x97\x30\xf2\x80\x68\x6d\x8a\x48\xf9\ +\x80\xf1\x1b\x80\x8e\x00\x81\x7f\xc2\x8d\xba\x2f\x1e\x4f\xfb\x06\ +\x9d\x93\x24\xa6\x08\x60\xad\xd5\xa8\x62\xf1\xf2\x75\xcf\x2b\xde\ +\x6e\x56\x20\x80\xac\xeb\x4c\x30\xf8\x99\xd6\x00\xd3\x94\x20\x39\ +\xa9\xb5\x3a\x4f\xac\xb4\x69\x86\xc6\x7d\xed\x9f\x25\xd0\xc3\x2d\ +\x8f\xc6\x47\xf3\xcb\xa5\x77\xee\x0a\x40\xce\x75\x1d\x12\xea\xd6\ +\x37\x2c\x94\x77\x35\x5f\x59\x7c\x20\x99\x0c\x7b\x42\x70\xa1\x50\ +\xa8\xe5\xf6\xda\xf7\x10\xcb\x44\x2b\x98\x8d\xfc\x6c\xa1\x50\x0a\ +\x92\xbf\xab\x5d\xfd\xbf\xf5\x37\xb2\xeb\x52\xa6\x18\x05\x8f\xcd\ +\x00\x00\x00\x00\x49\x45\x4e\x44\xae\x42\x60\x82\ +" + +qt_resource_name = b"\ +\x00\x03\ +\x00\x00\x78\xc3\ +\x00\x72\ +\x00\x65\x00\x73\ +\x00\x08\ +\x02\x33\x50\x87\ +\x00\x38\ +\x00\x5f\x00\x30\x00\x30\x00\x2e\x00\x70\x00\x6e\x00\x67\ +\x00\x08\ +\x02\x33\x50\x07\ +\x00\x34\ +\x00\x5f\x00\x30\x00\x30\x00\x2e\x00\x70\x00\x6e\x00\x67\ +\x00\x17\ +\x07\x37\x30\x67\ +\x00\x64\ +\x00\x61\x00\x79\x00\x74\x00\x69\x00\x6d\x00\x65\x00\x5f\x00\x65\x00\x64\x00\x69\x00\x74\x00\x6f\x00\x72\x00\x5f\x00\x6c\x00\x6f\ +\x00\x67\x00\x6f\x00\x2e\x00\x70\x00\x6e\x00\x67\ +\x00\x09\ +\x02\x33\x3d\x87\ +\x00\x32\ +\x00\x30\x00\x5f\x00\x30\x00\x30\x00\x2e\x00\x70\x00\x6e\x00\x67\ +\x00\x08\ +\x02\x33\x51\x87\ +\x00\x30\ +\x00\x5f\x00\x30\x00\x30\x00\x2e\x00\x70\x00\x6e\x00\x67\ +\x00\x08\ +\x0a\x61\x5a\xa7\ +\x00\x69\ +\x00\x63\x00\x6f\x00\x6e\x00\x2e\x00\x70\x00\x6e\x00\x67\ +\x00\x09\ +\x02\x33\x3e\x47\ +\x00\x31\ +\x00\x32\x00\x5f\x00\x30\x00\x30\x00\x2e\x00\x70\x00\x6e\x00\x67\ +\x00\x09\ +\x02\x33\x3e\xc7\ +\x00\x31\ +\x00\x36\x00\x5f\x00\x30\x00\x30\x00\x2e\x00\x70\x00\x6e\x00\x67\ +" + +qt_resource_struct = b"\ +\x00\x00\x00\x00\x00\x02\x00\x00\x00\x01\x00\x00\x00\x01\ +\x00\x00\x00\x00\x00\x02\x00\x00\x00\x01\x00\x00\x00\x02\ +\x00\x00\x00\x00\x00\x02\x00\x00\x00\x0a\x00\x00\x00\x03\ +\x00\x00\x00\x6c\x00\x00\x00\x00\x00\x01\x00\x00\x1e\xd7\ +\x00\x00\x00\xb0\x00\x00\x00\x00\x00\x01\x00\x00\x49\x23\ +\x00\x00\x00\xb0\x00\x00\x00\x00\x00\x01\x00\x00\x45\x48\ +\x00\x00\x00\xc8\x00\x00\x00\x00\x00\x01\x00\x00\x4c\xfe\ +\x00\x00\x00\x22\x00\x00\x00\x00\x00\x01\x00\x00\x03\x96\ +\x00\x00\x00\x0c\x00\x00\x00\x00\x00\x01\x00\x00\x00\x00\ +\x00\x00\x00\x84\x00\x00\x00\x00\x00\x01\x00\x00\x22\xc1\ +\x00\x00\x00\x38\x00\x00\x00\x00\x00\x01\x00\x00\x07\x83\ +\x00\x00\x00\x9a\x00\x00\x00\x00\x00\x01\x00\x00\x35\xbc\ +\x00\x00\x00\x9a\x00\x00\x00\x00\x00\x01\x00\x00\x26\x30\ +" + +def qInitResources(): + QtCore.qRegisterResourceData(0x01, qt_resource_struct, qt_resource_name, qt_resource_data) + +def qCleanupResources(): + QtCore.qUnregisterResourceData(0x01, qt_resource_struct, qt_resource_name, qt_resource_data) + +qInitResources() diff --git a/toolkit/import_sun_data/README.md b/toolkit/import_sun_data/README.md new file mode 100644 index 0000000..732c684 --- /dev/null +++ b/toolkit/import_sun_data/README.md @@ -0,0 +1,14 @@ + +## Importing real-world sun data + +This script imports real world sun position data into the pipeline. +Edit `import_data.py` so it contains the date and location where the data +should be fetched for. + +The script will then download the sun data for different times of the day +and configure the render pipeline to match those locations. + + +### Requirements + +- Internet connection diff --git a/toolkit/import_sun_data/import_data.py b/toolkit/import_sun_data/import_data.py new file mode 100644 index 0000000..7119d21 --- /dev/null +++ b/toolkit/import_sun_data/import_data.py @@ -0,0 +1,108 @@ +""" + +This script downloads real world sun position data and imports them into the +pipelines time of day system. + +(c) 2016 tobpsr + +""" + +from __future__ import print_function, division + +# You can get this data from http://sunpath.azurewebsites.net/ +CONFIG = { + "year": 2016, + "month": 7, + "day": 21, + "latitude": 50.778228759765625, + "longitude": 6.088640213012695, + "height": 167, + "precision": 6 +} + +if __name__ == "__main__": + + import sys + import math + + sys.path.insert(0, "../../") + from rplibs.six.moves import urllib # pylint: disable=import-error + + CONFIG["end_day"] = CONFIG["day"] + + API = "http://www.nrel.gov/midc/apps/spa.pl?syear={year}&smonth={month}&sday={day}&eyear={year}&emonth={month}&eday={end_day}&step={precision}&stepunit=1&latitude={latitude}&longitude={longitude}&timezone=%2B1&elev={height}&press=1013&temp=20&dut1=0.0&deltat=64.797&azmrot=180&slope=0&refract=0.5667&field=2&field=35&field=36&field=38&zip=0" # noqa + + url = API.format(**CONFIG) + + query_str = ("Are you sure you want to import the data? This overrides your " + "current sun azimuth, altitude and intensity settings! (y/n): ") + if sys.version_info.major >= 3: + query_result = input(query_str) + else: + query_result = raw_input(query_str) + + if query_result.strip().lower() not in ["y", "yes", "j"]: + print("Aborted.") + sys.exit(0) + + print("Querying api ..") + handle = urllib.request.urlopen(url) + data = handle.read().decode("utf-8") + handle.close() + + # Extract data + print("Extracting data ..") + lines = data.replace("\r", "").split("\n")[1:] + + # Load render pipeline api + print("Loading plugin api ..") + sys.path.insert(0, "../../") + from rpcore.pluginbase.manager import PluginManager + from rpcore.mount_manager import MountManager + + mount_mgr = MountManager(None) + mount_mgr.mount() + + plugin_mgr = PluginManager(None) + plugin_mgr.load() + + convert_to_linear = plugin_mgr.day_settings["scattering"]["sun_intensity"].get_linear_value + + hour, minutes = 0, 0 + + data_points_azimuth = [] + data_points_altitude = [] + data_points_intensity = [] + + for line in lines: + if not line: + break + date, time, azim_angle, declination, ascension, elevation = line.split(",") + + float_azim = (float(azim_angle) + 180) / 360 + float_elev = (float(elevation) / 60) * 0.5 + 0.5 + + float_time = (minutes + hour * 60) / (24 * 60) + + data_points_azimuth.append((float_time, float_azim)) + data_points_altitude.append((float_time, float_elev)) + + # Approximated intensity + approx_intensity = 2.0 * (1 - math.cos(math.pi * max(0, 8.0 + float(elevation)) / 60.0)) + approx_intensity = max(0, min(150.0, approx_intensity * 0.25)) + data_points_intensity.append((float_time, approx_intensity)) + + minutes += CONFIG["precision"] + if minutes >= 60: + hour += 1 + minutes = minutes % 60 + + print("Saving ..") + settings = plugin_mgr.day_settings["scattering"] + settings["sun_azimuth"].curves[0].control_points = data_points_azimuth + settings["sun_altitude"].curves[0].control_points = data_points_altitude + settings["sun_intensity"].curves[0].control_points = data_points_intensity + + plugin_mgr.save_daytime_overrides("/$$rpconfig/daytime.yaml") + + print("Done!") diff --git a/toolkit/material_editor/main.py b/toolkit/material_editor/main.py new file mode 100644 index 0000000..6eb68e5 --- /dev/null +++ b/toolkit/material_editor/main.py @@ -0,0 +1,329 @@ +""" + +RenderPipeline + +Copyright (c) 2014-2016 tobspr + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. + +""" + +# This tool offers an interface to modify materials +# Hacked together in a hour, I'm sorry. + +from __future__ import print_function + +import os +import sys +import time +import math +import tempfile +import colorsys +from threading import Thread +from functools import partial + +os.chdir(os.path.join(os.path.dirname(os.path.realpath(__file__)))) +sys.path.insert(0, os.getcwd()) +sys.path.insert(0, "../../") + +from rplibs.six import iteritems # noqa +from rplibs.pyqt_imports import * # noqa + +from ui.main_window_generated import Ui_MainWindow # noqa +from rpcore.util.network_communication import NetworkCommunication # noqa + +# Allow working with an older version of the material DB. +# ONLY for debugging the viewer. +ALLOW_OUTDATED_MATERIALS = False + + +class MaterialData: + + def __init__(self): + self.name = "" + self.shading_model = 0 + self.metallic = False + self.roughness = 0.0 + self.specular = 0.0 + self.normal_strength = 0.0 + self.shading_model_param1 = 0.0 + self.shading_model_param2 = 0.0 + self.basecolor_r = 0.6 + self.basecolor_g = 0.6 + self.basecolor_b = 0.6 + + +class MaterialEditor(QMainWindow, Ui_MainWindow): + + """ Interface to change the plugin settings """ + + SHADING_MODELS = [ + ("Default", 0, None), + ("Emissive", 1, None), + ("Clearcoat", 2, None), + ("Transparent", 3, "Transparency"), + ("Skin", 4, None), + ("Foliage", 5, None), + ] + + def __init__(self): + QMainWindow.__init__(self) + Ui_MainWindow.__init__(self) + + self.in_update = False + self.materials = [] + self.material = MaterialData() + + self.setupUi(self) + self.init_shading_models() + self.init_bindings() + self.update_material_list() + self.on_material_selected() + + def init_bindings(self): + qt_connect(self.cb_shading_model, "currentIndexChanged", self.read_from_ui) + qt_connect(self.cb_material, "currentIndexChanged", self.on_material_selected) + qt_connect(self.cb_metallic, "stateChanged", self.read_from_ui) + + self.sliders = [ + (self.slider_roughness, self.lbl_roughness, 0.0, 1.0, "roughness"), + (self.slider_specular, self.lbl_specular, 1.0, 2.51, "specular"), + (self.slider_normal, self.lbl_normal, 0.0, 1.0, "normal_strength"), + (self.slider_param1, self.lbl_param1, 0.0, 1.0, "shading_model_param1"), + ] + + for slider, lbl, start, end, prop in self.sliders: + qt_connect(slider, "valueChanged", self.read_from_ui) + + qt_connect(self.basecolor_1, "valueChanged", self.read_from_ui) + qt_connect(self.basecolor_2, "valueChanged", self.read_from_ui) + qt_connect(self.basecolor_3, "valueChanged", self.read_from_ui) + + for cb in (self.cb_rgb, self.cb_srgb, self.cb_hsv): + qt_connect(cb, "toggled", self.write_to_ui) + + def update_ui(self): + # Basecolor + labels = "R", "G", "B" + if self.cb_hsv.isChecked(): + labels = "H", "S", "V" + self.lbl_basecolor1.setText(labels[0]) + self.lbl_basecolor2.setText(labels[1]) + self.lbl_basecolor3.setText(labels[2]) + + a, b, c = (self.basecolor_1.value() / 100.0, + self.basecolor_2.value() / 100.0, + self.basecolor_3.value() / 100.0) + rgb = self.tuple_to_basecolor(a, b, c) + self.lbl_basecolor_val1.setText("{:0.2f}".format(a)) + self.lbl_basecolor_val2.setText("{:0.2f}".format(b)) + self.lbl_basecolor_val3.setText("{:0.2f}".format(c)) + self.lbl_color_preview.setStyleSheet("background: rgb({}, {}, {});".format( + int(rgb[0] * 255), int(rgb[1] * 255), int(rgb[2] * 255))) + + # Shading model + self._update_shading_model() + + def read_from_ui(self): + if self.in_update: + return + + # Rest of sliders + for slider, lbl, start, end, prop in self.sliders: + val = (slider.value() / 100.0) * (end - start) + start + lbl.setText("{:0.2f}".format(val)) + setattr(self.material, prop, val) + + # Basecolor + rgb = self._get_ui_basecolor_rgb() + self.material.basecolor_r = rgb[0] + self.material.basecolor_g = rgb[1] + self.material.basecolor_b = rgb[2] + + # Metallic + self.material.metallic = self.cb_metallic.isChecked() + + # Shading model + self.material.shading_model = self.cb_shading_model.currentIndex() + + self.update_ui() + self.send_update() + + def write_to_ui(self): + self.in_update = True + + # Basecolor + values = self.basecolor_to_tuple(self.material) + self.basecolor_1.setValue(values[0] * 100.0) + self.basecolor_2.setValue(values[1] * 100.0) + self.basecolor_3.setValue(values[2] * 100.0) + + # Shading model + self.cb_shading_model.setCurrentIndex(self.material.shading_model) + + # Metallics + self.cb_metallic.setChecked(self.material.metallic) + self.slider_specular.setEnabled(not self.material.metallic) + + # Rest of sliders + for slider, lbl, start, end, prop in self.sliders: + val = getattr(self.material, prop) + slider.setValue((val - start) / (end - start) * 100.0) + + self.in_update = False + self.update_ui() + + def _get_ui_basecolor_rgb(self): + """ Extracts the RGB color which is currently edited in the UI """ + a, b, c = (self.basecolor_1.value() / 100.0, + self.basecolor_2.value() / 100.0, + self.basecolor_3.value() / 100.0) + return self.tuple_to_basecolor(a, b, c) + + def update_material_list(self): + temp_path = os.path.join(tempfile.gettempdir(), "rp_materials.data") + print("Waiting for creation of", temp_path) + if not ALLOW_OUTDATED_MATERIALS: + try: + os.remove(temp_path) + except: + pass + NetworkCommunication.send_async(NetworkCommunication.MATERIAL_PORT, "dump_materials " + temp_path) + start_time = time.time() + while not os.path.isfile(temp_path) and time.time() - start_time < 5.0: + time.sleep(0.5) + if not os.path.isfile(temp_path): + QMessageBox.critical( + self, "Error", "Render Pipeline not responding! Make sure a render pipeline application is running, and try again later.") + sys.exit(-1) + if not ALLOW_OUTDATED_MATERIALS: + time.sleep(0.5) + self._load_material_list(temp_path) + + def _load_material_list(self, pth): + self.materials = [] + self.cb_material.clear() + with open(pth) as handle: + for line in handle.readlines(): + parts = line.strip().split(" ") + material = self._read_in_material(parts) + self.materials.append(material) + self.cb_material.addItem(material.name) + + def _read_in_material(self, parts): + material = MaterialData() + material.name = parts[0] + material.basecolor_r = float(parts[1]) + material.basecolor_g = float(parts[2]) + material.basecolor_b = float(parts[3]) + material.roughness = float(parts[4]) + material.specular = float(parts[5]) + material.metallic = float(parts[6]) > 0.5 + material.shading_model = int(float(parts[7])) + material.normal_strength = float(parts[8]) + material.shading_model_param1 = float(parts[9]) + material.shading_model_param2 = float(parts[10]) + return material + + def basecolor_to_tuple(self, mat): + def to_srgb(v): return math.pow(v, 1.0 / 2.2) + if self.cb_rgb.isChecked(): + return mat.basecolor_r, mat.basecolor_g, mat.basecolor_b + elif self.cb_srgb.isChecked(): + return to_srgb(mat.basecolor_r), to_srgb(mat.basecolor_g), to_srgb(mat.basecolor_b) + elif self.cb_hsv.isChecked(): + return colorsys.rgb_to_hsv(mat.basecolor_r, mat.basecolor_g, mat.basecolor_b) + else: + assert False + + def tuple_to_basecolor(self, a, b, c): + def from_srgb(v): return math.pow(v, 2.2) + if self.cb_rgb.isChecked(): + return a, b, c + elif self.cb_srgb.isChecked(): + return from_srgb(a), from_srgb(b), from_srgb(c) + elif self.cb_hsv.isChecked(): + return colorsys.hsv_to_rgb(a, b, c) + else: + assert False + + def on_material_selected(self): + index = self.cb_material.currentIndex() + if index < 0 or index >= len(self.materials): + print("Invalid material with index", index, "only have", len(self.materials), "materials") + return + self.material = self.materials[index] + print("Loaded material", self.material.name) + self.write_to_ui() + + def send_update(self): + serialized = ("{} " * 11).format( + self.material.name, + self.material.basecolor_r, + self.material.basecolor_g, + self.material.basecolor_b, + self.material.roughness, + self.material.specular, + 1.0 if self.material.metallic else 0.0, + self.material.shading_model, + self.material.normal_strength, + self.material.shading_model_param1, + self.material.shading_model_param2, + ) + NetworkCommunication.send_async(NetworkCommunication.MATERIAL_PORT, "update_material " + serialized) + + def _update_shading_model(self): + name, val, optional_param = self.SHADING_MODELS[self.cb_shading_model.currentIndex()] + if optional_param is None: + self.slider_param1.setEnabled(False) + self.lbl_shading_model_param1.setText("Unused") + else: + self.slider_param1.setEnabled(True) + self.lbl_shading_model_param1.setText(optional_param) + + self.cb_metallic.show() + self.slider_roughness.setEnabled(True) + self.slider_normal.setEnabled(True) + + if name == "Emissive": + self.cb_metallic.hide() + self.slider_roughness.setEnabled(False) + self.slider_specular.setEnabled(False) + self.slider_normal.setEnabled(False) + elif name == "Clearcoat": + self.cb_metallic.hide() + self.slider_specular.setEnabled(False) + elif name == "Transparent": + pass + elif name == "Skin": + self.cb_metallic.hide() + elif name == "Foliage": + self.cb_metallic.hide() + + def init_shading_models(self): + self.cb_shading_model.clear() + for name, val, optional_param in self.SHADING_MODELS: + self.cb_shading_model.addItem(name) + +# Start application +app = QApplication(sys.argv) +qt_register_fonts() +editor = MaterialEditor() +editor.show() +app.exec_() diff --git a/toolkit/material_editor/ui/checked.png b/toolkit/material_editor/ui/checked.png new file mode 100644 index 0000000..7458e74 Binary files /dev/null and b/toolkit/material_editor/ui/checked.png differ diff --git a/toolkit/material_editor/ui/compile_ui_qt4.bat b/toolkit/material_editor/ui/compile_ui_qt4.bat new file mode 100644 index 0000000..2392f6a --- /dev/null +++ b/toolkit/material_editor/ui/compile_ui_qt4.bat @@ -0,0 +1,9 @@ +@echo off + +rem Adjust the path to match your PyQt4 installation +SET PYQTPATH="C:\Projekte\Panda3D\built_x64\python\Lib\site-packages\PyQt4" + +python -m PyQt4.uic.pyuic --from-imports main_window.ui -o main_window_generated.py +"%PYQTPATH%\pyrcc4.exe" -py3 resources.qrc -o resources_rc.py + +pause diff --git a/toolkit/material_editor/ui/compile_ui_qt5.bat b/toolkit/material_editor/ui/compile_ui_qt5.bat new file mode 100644 index 0000000..202b514 --- /dev/null +++ b/toolkit/material_editor/ui/compile_ui_qt5.bat @@ -0,0 +1,6 @@ +@echo off + +python -m PyQt5.uic.pyuic --from-imports main_window.ui -o main_window_generated.py +python -m PyQt5.pyrcc_main resources.qrc -o resources_rc.py + +pause diff --git a/toolkit/material_editor/ui/down-arrow.png b/toolkit/material_editor/ui/down-arrow.png new file mode 100644 index 0000000..bb78580 Binary files /dev/null and b/toolkit/material_editor/ui/down-arrow.png differ diff --git a/toolkit/material_editor/ui/main_window.ui b/toolkit/material_editor/ui/main_window.ui new file mode 100644 index 0000000..bf64748 --- /dev/null +++ b/toolkit/material_editor/ui/main_window.ui @@ -0,0 +1,807 @@ + + + MainWindow + + + + 0 + 0 + 262 + 608 + + + + + 262 + 608 + + + + + 262 + 5560 + + + + Render Pipeline Material Editor + + + QMainWindow { background: #fff;} +*, QLabel { font-family: Roboto; font-weight: 300; } + +QSlider::groove:horizontal { + border: 0; + height: 4px; + background: rgba(0, 0, 0, 15); +} + +QSlider::handle:horizonal { + background: #666; + width: 8px; + margin: -6px 0; +} + +QSlider::handle:horizontal:disabled { + background: #ccc; +} +QSlider::groove:horizontal:disabled { + background: rgba(0, 0, 0, 8); +} + +QRadioButton { + background: #fafafa; + padding: 4px 6px 3px; + font-size: 12px; + color: #333; +} + +QRadioButton::indicator { + width: 15px; + height: 15px; + margin-top: -1px; +} + +QRadioButton:checked { +background: #eee; +} + +QRadioButton:hover { +background: #eaeaea; +} + +QComboBox { +border: 0; +background: #fff; +padding: 7px 10px 3px; +font-family: Roboto; +color: #777; +font-size: 12px; +} + +QComboBox::down-arrow { + border: 0; + margin: -3px; + background: #ddd; + margin-left: -16px; +margin-bottom: -4px; + image: url(":/img/down-arrow.png"); +} + +QCheckBox::indicator { + border: 1px solid #aaa; + background: #39f; + width: 14px; + height: 14px; + image: url(":/img/checked.png"); +} + +QCheckBox { +text-transform: uppercase; +color: #555; +} + +QCheckBox::indicator:unchecked { + background: #fff; + image: none; +} + + + + + 0 + + + 0 + + + + + + 0 + 65 + + + + + 16777215 + 65 + + + + QFrame::StyledPanel + + + QFrame::Raised + + + + + 20 + 26 + 261 + 31 + + + + font-size: 20px; color: #03C03C; +font-weight: 100; + + + MATERIAL EDITOR + + + + + + 20 + 6 + 261 + 31 + + + + font-size: 13px; +color: #aaa; +font-weight: 600; + + + RENDER PIPELINE + + + + + + + + 0 + + + + + + 0 + 0 + + + + + 999999 + 16777215 + + + + QFrame { background: #eee; } QFrame>QLabel { text-transform: uppercase; color: #888; background: transparent; } + + + QFrame::StyledPanel + + + QFrame::Raised + + + + + 20 + 20 + 61 + 16 + + + + Material + + + + + + 20 + 40 + 221 + 30 + + + + + tree01 + + + + + + + 20 + 80 + 141 + 16 + + + + Shading model + + + + + + 20 + 100 + 221 + 30 + + + + + Default + + + + + Emissive + + + + + Transparent + + + + + + + 20 + 140 + 81 + 17 + + + + Metallic + + + + + + 30 + 240 + 201 + 73 + + + + + 6 + + + + + + + + 30 + 0 + + + + + 30 + 16777215 + + + + background: transparent; + + + 0.43 + + + Qt::AlignCenter + + + + + + + 100 + + + 53 + + + Qt::Horizontal + + + + + + + 100 + + + 12 + + + Qt::Horizontal + + + + + + + 100 + + + 43 + + + Qt::Horizontal + + + + + + + + 30 + 0 + + + + + 30 + 16777215 + + + + background: transparent; + + + 0.53 + + + Qt::AlignCenter + + + + + + + + 30 + 0 + + + + + 30 + 16777215 + + + + background: transparent; + + + 0.12 + + + Qt::AlignCenter + + + + + + + + 11 + 0 + + + + background: transparent; color: #555; + + + R + + + + + + + + 11 + 0 + + + + background: transparent; color: #555; + + + G + + + + + + + + 11 + 0 + + + + background: transparent; color: #555; + + + B + + + + + + + + + + 30 + 0 + + + + + 30 + 16777215 + + + + background: rgba(60, 120, 255); + + + + + + + + + + + + 20 + 180 + 131 + 16 + + + + Basecolor + + + + + + 20 + 340 + 131 + 16 + + + + Roughness + + + + + + 20 + 360 + 191 + 19 + + + + 100 + + + 32 + + + Qt::Horizontal + + + + + + 20 + 390 + 131 + 16 + + + + Specular IOR + + + + + + 20 + 410 + 191 + 19 + + + + 100 + + + 20 + + + Qt::Horizontal + + + + + + 20 + 440 + 131 + 16 + + + + Normal-Strength + + + + + + 20 + 460 + 191 + 19 + + + + 100 + + + 80 + + + Qt::Horizontal + + + + + + 220 + 360 + 31 + 20 + + + + color: #333; + + + 0.32 + + + + + + 220 + 410 + 31 + 20 + + + + color: #333; + + + 1.43 + + + + + + 220 + 459 + 31 + 20 + + + + color: #333; + + + 0.80 + + + + + + -10 + 166 + 311 + 561 + + + + QFrame { background: #fff; } + + + QFrame::StyledPanel + + + QFrame::Raised + + + + + 230 + 339 + 31 + 20 + + + + color: #333; + + + 0.20 + + + + + false + + + + 30 + 340 + 191 + 19 + + + + 100 + + + 80 + + + Qt::Horizontal + + + + + + 30 + 320 + 141 + 16 + + + + Shading-model-param + + + + + + 30 + 34 + 60 + 27 + + + + RGB + + + true + + + + + + 92 + 34 + 71 + 27 + + + + SRGB + + + + + + 165 + 34 + 62 + 27 + + + + HSV + + + + + + 30 + 59 + 220 + 96 + + + + QFrame { background: #eee; } + + + QFrame::StyledPanel + + + QFrame::Raised + + + lbl_param1 + slider_param1 + lbl_shading_model_param1 + cb_rgb + cb_srgb + lbl_basecolor_val1 + cb_hsv + frame_3 + + frame_2 + label_2 + cb_material + label_14 + cb_shading_model + cb_metallic + horizontalLayoutWidget_3 + label_15 + label_16 + slider_roughness + label_17 + slider_specular + label_18 + slider_normal + lbl_roughness + lbl_specular + lbl_normal + + + + + + + + + + + + diff --git a/toolkit/material_editor/ui/main_window_generated.py b/toolkit/material_editor/ui/main_window_generated.py new file mode 100644 index 0000000..0f6f565 --- /dev/null +++ b/toolkit/material_editor/ui/main_window_generated.py @@ -0,0 +1,360 @@ +# -*- coding: utf-8 -*- + +# Form implementation generated from reading ui file 'main_window.ui' +# +# Created by: PyQt5 UI code generator 5.7 +# +# WARNING! All changes made in this file will be lost! + +from PyQt5 import QtCore, QtGui, QtWidgets + +class Ui_MainWindow(object): + def setupUi(self, MainWindow): + MainWindow.setObjectName("MainWindow") + MainWindow.resize(262, 608) + MainWindow.setMinimumSize(QtCore.QSize(262, 608)) + MainWindow.setMaximumSize(QtCore.QSize(262, 5560)) + MainWindow.setStyleSheet("QMainWindow { background: #fff;}\n" +"*, QLabel { font-family: Roboto; font-weight: 300; }\n" +"\n" +"QSlider::groove:horizontal {\n" +" border: 0;\n" +" height: 4px;\n" +" background: rgba(0, 0, 0, 15);\n" +"}\n" +"\n" +"QSlider::handle:horizonal {\n" +" background: #666;\n" +" width: 8px;\n" +" margin: -6px 0;\n" +"}\n" +"\n" +"QSlider::handle:horizontal:disabled {\n" +" background: #ccc;\n" +"}\n" +"QSlider::groove:horizontal:disabled {\n" +" background: rgba(0, 0, 0, 8);\n" +"}\n" +"\n" +"QRadioButton {\n" +" background: #fafafa;\n" +" padding: 4px 6px 3px;\n" +" font-size: 12px;\n" +" color: #333;\n" +"}\n" +"\n" +"QRadioButton::indicator {\n" +" width: 15px;\n" +" height: 15px;\n" +" margin-top: -1px;\n" +"}\n" +"\n" +"QRadioButton:checked {\n" +"background: #eee;\n" +"}\n" +"\n" +"QRadioButton:hover {\n" +"background: #eaeaea;\n" +"}\n" +"\n" +"QComboBox {\n" +"border: 0;\n" +"background: #fff;\n" +"padding: 7px 10px 3px;\n" +"font-family: Roboto;\n" +"color: #777;\n" +"font-size: 12px;\n" +"}\n" +"\n" +"QComboBox::down-arrow {\n" +" border: 0;\n" +" margin: -3px;\n" +" background: #ddd;\n" +" margin-left: -16px;\n" +"margin-bottom: -4px;\n" +" image: url(\":/img/down-arrow.png\");\n" +"}\n" +"\n" +"QCheckBox::indicator {\n" +" border: 1px solid #aaa;\n" +" background: #39f;\n" +" width: 14px;\n" +" height: 14px;\n" +" image: url(\":/img/checked.png\");\n" +"}\n" +"\n" +"QCheckBox {\n" +"text-transform: uppercase;\n" +"color: #555;\n" +"}\n" +"\n" +"QCheckBox::indicator:unchecked {\n" +" background: #fff;\n" +" image: none;\n" +"}") + self.centralwidget = QtWidgets.QWidget(MainWindow) + self.centralwidget.setObjectName("centralwidget") + self.verticalLayout = QtWidgets.QVBoxLayout(self.centralwidget) + self.verticalLayout.setContentsMargins(0, 0, 0, 0) + self.verticalLayout.setSpacing(0) + self.verticalLayout.setObjectName("verticalLayout") + self.frame = QtWidgets.QFrame(self.centralwidget) + self.frame.setMinimumSize(QtCore.QSize(0, 65)) + self.frame.setMaximumSize(QtCore.QSize(16777215, 65)) + self.frame.setFrameShape(QtWidgets.QFrame.StyledPanel) + self.frame.setFrameShadow(QtWidgets.QFrame.Raised) + self.frame.setObjectName("frame") + self.label = QtWidgets.QLabel(self.frame) + self.label.setGeometry(QtCore.QRect(20, 26, 261, 31)) + self.label.setStyleSheet("font-size: 20px; color: #03C03C;\n" +"font-weight: 100;") + self.label.setObjectName("label") + self.label_9 = QtWidgets.QLabel(self.frame) + self.label_9.setGeometry(QtCore.QRect(20, 6, 261, 31)) + self.label_9.setStyleSheet("font-size: 13px;\n" +"color: #aaa;\n" +"font-weight: 600;") + self.label_9.setObjectName("label_9") + self.verticalLayout.addWidget(self.frame) + self.horizontalLayout = QtWidgets.QHBoxLayout() + self.horizontalLayout.setSpacing(0) + self.horizontalLayout.setObjectName("horizontalLayout") + self.sidebar_material = QtWidgets.QFrame(self.centralwidget) + self.sidebar_material.setMinimumSize(QtCore.QSize(0, 0)) + self.sidebar_material.setMaximumSize(QtCore.QSize(999999, 16777215)) + self.sidebar_material.setStyleSheet("QFrame { background: #eee; } QFrame>QLabel { text-transform: uppercase; color: #888; background: transparent; }") + self.sidebar_material.setFrameShape(QtWidgets.QFrame.StyledPanel) + self.sidebar_material.setFrameShadow(QtWidgets.QFrame.Raised) + self.sidebar_material.setObjectName("sidebar_material") + self.label_2 = QtWidgets.QLabel(self.sidebar_material) + self.label_2.setGeometry(QtCore.QRect(20, 20, 61, 16)) + self.label_2.setObjectName("label_2") + self.cb_material = QtWidgets.QComboBox(self.sidebar_material) + self.cb_material.setGeometry(QtCore.QRect(20, 40, 221, 30)) + self.cb_material.setObjectName("cb_material") + self.cb_material.addItem("") + self.label_14 = QtWidgets.QLabel(self.sidebar_material) + self.label_14.setGeometry(QtCore.QRect(20, 80, 141, 16)) + self.label_14.setObjectName("label_14") + self.cb_shading_model = QtWidgets.QComboBox(self.sidebar_material) + self.cb_shading_model.setGeometry(QtCore.QRect(20, 100, 221, 30)) + self.cb_shading_model.setObjectName("cb_shading_model") + self.cb_shading_model.addItem("") + self.cb_shading_model.addItem("") + self.cb_shading_model.addItem("") + self.cb_metallic = QtWidgets.QCheckBox(self.sidebar_material) + self.cb_metallic.setGeometry(QtCore.QRect(20, 140, 81, 17)) + self.cb_metallic.setObjectName("cb_metallic") + self.horizontalLayoutWidget_3 = QtWidgets.QWidget(self.sidebar_material) + self.horizontalLayoutWidget_3.setGeometry(QtCore.QRect(30, 240, 201, 73)) + self.horizontalLayoutWidget_3.setObjectName("horizontalLayoutWidget_3") + self.horizontalLayout_4 = QtWidgets.QHBoxLayout(self.horizontalLayoutWidget_3) + self.horizontalLayout_4.setContentsMargins(0, 0, 0, 0) + self.horizontalLayout_4.setSpacing(6) + self.horizontalLayout_4.setObjectName("horizontalLayout_4") + self.gridLayout = QtWidgets.QGridLayout() + self.gridLayout.setObjectName("gridLayout") + self.lbl_basecolor_val2 = QtWidgets.QLabel(self.horizontalLayoutWidget_3) + self.lbl_basecolor_val2.setMinimumSize(QtCore.QSize(30, 0)) + self.lbl_basecolor_val2.setMaximumSize(QtCore.QSize(30, 16777215)) + self.lbl_basecolor_val2.setStyleSheet("background: transparent;") + self.lbl_basecolor_val2.setAlignment(QtCore.Qt.AlignCenter) + self.lbl_basecolor_val2.setObjectName("lbl_basecolor_val2") + self.gridLayout.addWidget(self.lbl_basecolor_val2, 1, 2, 1, 1) + self.basecolor_3 = QtWidgets.QSlider(self.horizontalLayoutWidget_3) + self.basecolor_3.setMaximum(100) + self.basecolor_3.setProperty("value", 53) + self.basecolor_3.setOrientation(QtCore.Qt.Horizontal) + self.basecolor_3.setObjectName("basecolor_3") + self.gridLayout.addWidget(self.basecolor_3, 2, 1, 1, 1) + self.basecolor_1 = QtWidgets.QSlider(self.horizontalLayoutWidget_3) + self.basecolor_1.setMaximum(100) + self.basecolor_1.setProperty("value", 12) + self.basecolor_1.setOrientation(QtCore.Qt.Horizontal) + self.basecolor_1.setObjectName("basecolor_1") + self.gridLayout.addWidget(self.basecolor_1, 0, 1, 1, 1) + self.basecolor_2 = QtWidgets.QSlider(self.horizontalLayoutWidget_3) + self.basecolor_2.setMaximum(100) + self.basecolor_2.setProperty("value", 43) + self.basecolor_2.setOrientation(QtCore.Qt.Horizontal) + self.basecolor_2.setObjectName("basecolor_2") + self.gridLayout.addWidget(self.basecolor_2, 1, 1, 1, 1) + self.lbl_basecolor_val3 = QtWidgets.QLabel(self.horizontalLayoutWidget_3) + self.lbl_basecolor_val3.setMinimumSize(QtCore.QSize(30, 0)) + self.lbl_basecolor_val3.setMaximumSize(QtCore.QSize(30, 16777215)) + self.lbl_basecolor_val3.setStyleSheet("background: transparent;") + self.lbl_basecolor_val3.setAlignment(QtCore.Qt.AlignCenter) + self.lbl_basecolor_val3.setObjectName("lbl_basecolor_val3") + self.gridLayout.addWidget(self.lbl_basecolor_val3, 2, 2, 1, 1) + self.lbl_basecolor_val1 = QtWidgets.QLabel(self.horizontalLayoutWidget_3) + self.lbl_basecolor_val1.setMinimumSize(QtCore.QSize(30, 0)) + self.lbl_basecolor_val1.setMaximumSize(QtCore.QSize(30, 16777215)) + self.lbl_basecolor_val1.setStyleSheet("background: transparent;") + self.lbl_basecolor_val1.setAlignment(QtCore.Qt.AlignCenter) + self.lbl_basecolor_val1.setObjectName("lbl_basecolor_val1") + self.gridLayout.addWidget(self.lbl_basecolor_val1, 0, 2, 1, 1) + self.lbl_basecolor1 = QtWidgets.QLabel(self.horizontalLayoutWidget_3) + self.lbl_basecolor1.setMinimumSize(QtCore.QSize(11, 0)) + self.lbl_basecolor1.setStyleSheet("background: transparent; color: #555; ") + self.lbl_basecolor1.setObjectName("lbl_basecolor1") + self.gridLayout.addWidget(self.lbl_basecolor1, 0, 0, 1, 1) + self.lbl_basecolor2 = QtWidgets.QLabel(self.horizontalLayoutWidget_3) + self.lbl_basecolor2.setMinimumSize(QtCore.QSize(11, 0)) + self.lbl_basecolor2.setStyleSheet("background: transparent; color: #555; ") + self.lbl_basecolor2.setObjectName("lbl_basecolor2") + self.gridLayout.addWidget(self.lbl_basecolor2, 1, 0, 1, 1) + self.lbl_basecolor3 = QtWidgets.QLabel(self.horizontalLayoutWidget_3) + self.lbl_basecolor3.setMinimumSize(QtCore.QSize(11, 0)) + self.lbl_basecolor3.setStyleSheet("background: transparent; color: #555; ") + self.lbl_basecolor3.setObjectName("lbl_basecolor3") + self.gridLayout.addWidget(self.lbl_basecolor3, 2, 0, 1, 1) + self.horizontalLayout_4.addLayout(self.gridLayout) + self.lbl_color_preview = QtWidgets.QLabel(self.horizontalLayoutWidget_3) + self.lbl_color_preview.setMinimumSize(QtCore.QSize(30, 0)) + self.lbl_color_preview.setMaximumSize(QtCore.QSize(30, 16777215)) + self.lbl_color_preview.setStyleSheet("background: rgba(60, 120, 255);") + self.lbl_color_preview.setText("") + self.lbl_color_preview.setObjectName("lbl_color_preview") + self.horizontalLayout_4.addWidget(self.lbl_color_preview) + self.label_15 = QtWidgets.QLabel(self.sidebar_material) + self.label_15.setGeometry(QtCore.QRect(20, 180, 131, 16)) + self.label_15.setObjectName("label_15") + self.label_16 = QtWidgets.QLabel(self.sidebar_material) + self.label_16.setGeometry(QtCore.QRect(20, 340, 131, 16)) + self.label_16.setObjectName("label_16") + self.slider_roughness = QtWidgets.QSlider(self.sidebar_material) + self.slider_roughness.setGeometry(QtCore.QRect(20, 360, 191, 19)) + self.slider_roughness.setMaximum(100) + self.slider_roughness.setProperty("value", 32) + self.slider_roughness.setOrientation(QtCore.Qt.Horizontal) + self.slider_roughness.setObjectName("slider_roughness") + self.label_17 = QtWidgets.QLabel(self.sidebar_material) + self.label_17.setGeometry(QtCore.QRect(20, 390, 131, 16)) + self.label_17.setObjectName("label_17") + self.slider_specular = QtWidgets.QSlider(self.sidebar_material) + self.slider_specular.setGeometry(QtCore.QRect(20, 410, 191, 19)) + self.slider_specular.setMaximum(100) + self.slider_specular.setSliderPosition(20) + self.slider_specular.setOrientation(QtCore.Qt.Horizontal) + self.slider_specular.setObjectName("slider_specular") + self.label_18 = QtWidgets.QLabel(self.sidebar_material) + self.label_18.setGeometry(QtCore.QRect(20, 440, 131, 16)) + self.label_18.setObjectName("label_18") + self.slider_normal = QtWidgets.QSlider(self.sidebar_material) + self.slider_normal.setGeometry(QtCore.QRect(20, 460, 191, 19)) + self.slider_normal.setMaximum(100) + self.slider_normal.setSliderPosition(80) + self.slider_normal.setOrientation(QtCore.Qt.Horizontal) + self.slider_normal.setObjectName("slider_normal") + self.lbl_roughness = QtWidgets.QLabel(self.sidebar_material) + self.lbl_roughness.setGeometry(QtCore.QRect(220, 360, 31, 20)) + self.lbl_roughness.setStyleSheet("color: #333;") + self.lbl_roughness.setObjectName("lbl_roughness") + self.lbl_specular = QtWidgets.QLabel(self.sidebar_material) + self.lbl_specular.setGeometry(QtCore.QRect(220, 410, 31, 20)) + self.lbl_specular.setStyleSheet("color: #333;") + self.lbl_specular.setObjectName("lbl_specular") + self.lbl_normal = QtWidgets.QLabel(self.sidebar_material) + self.lbl_normal.setGeometry(QtCore.QRect(220, 459, 31, 20)) + self.lbl_normal.setStyleSheet("color: #333;") + self.lbl_normal.setObjectName("lbl_normal") + self.frame_2 = QtWidgets.QFrame(self.sidebar_material) + self.frame_2.setGeometry(QtCore.QRect(-10, 166, 311, 561)) + self.frame_2.setStyleSheet("QFrame { background: #fff; }") + self.frame_2.setFrameShape(QtWidgets.QFrame.StyledPanel) + self.frame_2.setFrameShadow(QtWidgets.QFrame.Raised) + self.frame_2.setObjectName("frame_2") + self.lbl_param1 = QtWidgets.QLabel(self.frame_2) + self.lbl_param1.setGeometry(QtCore.QRect(230, 339, 31, 20)) + self.lbl_param1.setStyleSheet("color: #333;") + self.lbl_param1.setObjectName("lbl_param1") + self.slider_param1 = QtWidgets.QSlider(self.frame_2) + self.slider_param1.setEnabled(False) + self.slider_param1.setGeometry(QtCore.QRect(30, 340, 191, 19)) + self.slider_param1.setMaximum(100) + self.slider_param1.setSliderPosition(80) + self.slider_param1.setOrientation(QtCore.Qt.Horizontal) + self.slider_param1.setObjectName("slider_param1") + self.lbl_shading_model_param1 = QtWidgets.QLabel(self.frame_2) + self.lbl_shading_model_param1.setGeometry(QtCore.QRect(30, 320, 141, 16)) + self.lbl_shading_model_param1.setObjectName("lbl_shading_model_param1") + self.cb_rgb = QtWidgets.QRadioButton(self.frame_2) + self.cb_rgb.setGeometry(QtCore.QRect(30, 34, 60, 27)) + self.cb_rgb.setChecked(True) + self.cb_rgb.setObjectName("cb_rgb") + self.cb_srgb = QtWidgets.QRadioButton(self.frame_2) + self.cb_srgb.setGeometry(QtCore.QRect(92, 34, 71, 27)) + self.cb_srgb.setObjectName("cb_srgb") + self.cb_hsv = QtWidgets.QRadioButton(self.frame_2) + self.cb_hsv.setGeometry(QtCore.QRect(165, 34, 62, 27)) + self.cb_hsv.setObjectName("cb_hsv") + self.frame_3 = QtWidgets.QFrame(self.frame_2) + self.frame_3.setGeometry(QtCore.QRect(30, 59, 220, 96)) + self.frame_3.setStyleSheet("QFrame { background: #eee; }") + self.frame_3.setFrameShape(QtWidgets.QFrame.StyledPanel) + self.frame_3.setFrameShadow(QtWidgets.QFrame.Raised) + self.frame_3.setObjectName("frame_3") + self.lbl_param1.raise_() + self.slider_param1.raise_() + self.lbl_shading_model_param1.raise_() + self.cb_rgb.raise_() + self.cb_srgb.raise_() + self.lbl_basecolor_val1.raise_() + self.cb_hsv.raise_() + self.frame_3.raise_() + self.frame_2.raise_() + self.label_2.raise_() + self.cb_material.raise_() + self.label_14.raise_() + self.cb_shading_model.raise_() + self.cb_metallic.raise_() + self.horizontalLayoutWidget_3.raise_() + self.label_15.raise_() + self.label_16.raise_() + self.slider_roughness.raise_() + self.label_17.raise_() + self.slider_specular.raise_() + self.label_18.raise_() + self.slider_normal.raise_() + self.lbl_roughness.raise_() + self.lbl_specular.raise_() + self.lbl_normal.raise_() + self.horizontalLayout.addWidget(self.sidebar_material) + self.verticalLayout.addLayout(self.horizontalLayout) + MainWindow.setCentralWidget(self.centralwidget) + + self.retranslateUi(MainWindow) + QtCore.QMetaObject.connectSlotsByName(MainWindow) + + def retranslateUi(self, MainWindow): + _translate = QtCore.QCoreApplication.translate + MainWindow.setWindowTitle(_translate("MainWindow", "Render Pipeline Material Editor")) + self.label.setText(_translate("MainWindow", "MATERIAL EDITOR")) + self.label_9.setText(_translate("MainWindow", "RENDER PIPELINE")) + self.label_2.setText(_translate("MainWindow", "Material")) + self.cb_material.setItemText(0, _translate("MainWindow", "tree01")) + self.label_14.setText(_translate("MainWindow", "Shading model")) + self.cb_shading_model.setItemText(0, _translate("MainWindow", "Default")) + self.cb_shading_model.setItemText(1, _translate("MainWindow", "Emissive")) + self.cb_shading_model.setItemText(2, _translate("MainWindow", "Transparent")) + self.cb_metallic.setText(_translate("MainWindow", "Metallic")) + self.lbl_basecolor_val2.setText(_translate("MainWindow", "0.43")) + self.lbl_basecolor_val3.setText(_translate("MainWindow", "0.53")) + self.lbl_basecolor_val1.setText(_translate("MainWindow", "0.12")) + self.lbl_basecolor1.setText(_translate("MainWindow", "R")) + self.lbl_basecolor2.setText(_translate("MainWindow", "G")) + self.lbl_basecolor3.setText(_translate("MainWindow", "B")) + self.label_15.setText(_translate("MainWindow", "Basecolor")) + self.label_16.setText(_translate("MainWindow", "Roughness")) + self.label_17.setText(_translate("MainWindow", "Specular IOR")) + self.label_18.setText(_translate("MainWindow", "Normal-Strength")) + self.lbl_roughness.setText(_translate("MainWindow", "0.32")) + self.lbl_specular.setText(_translate("MainWindow", "1.43")) + self.lbl_normal.setText(_translate("MainWindow", "0.80")) + self.lbl_param1.setText(_translate("MainWindow", "0.20")) + self.lbl_shading_model_param1.setText(_translate("MainWindow", "Shading-model-param")) + self.cb_rgb.setText(_translate("MainWindow", "RGB")) + self.cb_srgb.setText(_translate("MainWindow", "SRGB")) + self.cb_hsv.setText(_translate("MainWindow", "HSV")) + +from . import resources_rc diff --git a/toolkit/material_editor/ui/resources.qrc b/toolkit/material_editor/ui/resources.qrc new file mode 100644 index 0000000..2d0a50d --- /dev/null +++ b/toolkit/material_editor/ui/resources.qrc @@ -0,0 +1,6 @@ + + + checked.png + down-arrow.png + + diff --git a/toolkit/material_editor/ui/resources_rc.py b/toolkit/material_editor/ui/resources_rc.py new file mode 100644 index 0000000..9251ba3 --- /dev/null +++ b/toolkit/material_editor/ui/resources_rc.py @@ -0,0 +1,88 @@ +# -*- coding: utf-8 -*- + +# Resource object code +# +# Created by: The Resource Compiler for PyQt5 (Qt v5.7.0) +# +# WARNING! All changes made in this file will be lost! + +from PyQt5 import QtCore + +qt_resource_data = b"\ +\x00\x00\x01\xb0\ +\x89\ +\x50\x4e\x47\x0d\x0a\x1a\x0a\x00\x00\x00\x0d\x49\x48\x44\x52\x00\ +\x00\x00\x10\x00\x00\x00\x10\x08\x04\x00\x00\x00\xb5\xfa\x37\xea\ +\x00\x00\x00\x04\x67\x41\x4d\x41\x00\x00\xb1\x8f\x0b\xfc\x61\x05\ +\x00\x00\x00\x20\x63\x48\x52\x4d\x00\x00\x7a\x26\x00\x00\x80\x84\ +\x00\x00\xfa\x00\x00\x00\x80\xe8\x00\x00\x75\x30\x00\x00\xea\x60\ +\x00\x00\x3a\x98\x00\x00\x17\x70\x9c\xba\x51\x3c\x00\x00\x00\x02\ +\x62\x4b\x47\x44\x00\x00\xaa\x8d\x23\x32\x00\x00\x00\x09\x70\x48\ +\x59\x73\x00\x00\x0d\xd7\x00\x00\x0d\xd7\x01\x42\x28\x9b\x78\x00\ +\x00\x00\x07\x74\x49\x4d\x45\x07\xe0\x0b\x13\x14\x13\x01\xe2\x2b\ +\x02\xea\x00\x00\x00\x7e\x49\x44\x41\x54\x28\xcf\x63\x60\x18\x78\ +\xc0\xd8\xcd\xfd\x75\x2e\x43\x56\xc3\x3b\x4c\xa9\x06\x11\x86\xe9\ +\x92\x51\x4c\xa5\x5f\x19\x9e\x33\xec\x69\x10\xc2\x22\xbd\x8f\xe1\ +\x4e\xfa\x6f\x26\x06\x86\x86\x42\x86\x83\xe8\x4a\xda\x84\x19\xf6\ +\x32\x6c\x6d\xa8\x64\x60\x60\x84\xaa\xef\x67\xb0\x67\x70\x81\x59\ +\xd4\x26\xfc\x6b\x2f\xc3\xf6\x86\x4a\x06\x06\xb8\x02\x64\x25\x0d\ +\x42\x0c\x7b\x19\x76\x40\xa4\x91\x14\xc0\x94\x30\x30\x20\x4b\xa3\ +\x28\x80\x2a\x61\x60\xd8\x89\x90\xc6\xf4\x5a\x6b\x63\xfd\x40\x87\ +\x3c\x26\x00\x00\x8c\x5b\x28\xe0\xab\xb2\x1c\xe7\x00\x00\x00\x25\ +\x74\x45\x58\x74\x64\x61\x74\x65\x3a\x63\x72\x65\x61\x74\x65\x00\ +\x32\x30\x31\x36\x2d\x31\x31\x2d\x31\x39\x54\x32\x30\x3a\x31\x39\ +\x3a\x30\x31\x2b\x30\x31\x3a\x30\x30\x22\xee\x27\xba\x00\x00\x00\ +\x25\x74\x45\x58\x74\x64\x61\x74\x65\x3a\x6d\x6f\x64\x69\x66\x79\ +\x00\x32\x30\x31\x36\x2d\x31\x31\x2d\x31\x39\x54\x32\x30\x3a\x31\ +\x39\x3a\x30\x31\x2b\x30\x31\x3a\x30\x30\x53\xb3\x9f\x06\x00\x00\ +\x00\x19\x74\x45\x58\x74\x53\x6f\x66\x74\x77\x61\x72\x65\x00\x77\ +\x77\x77\x2e\x69\x6e\x6b\x73\x63\x61\x70\x65\x2e\x6f\x72\x67\x9b\ +\xee\x3c\x1a\x00\x00\x00\x00\x49\x45\x4e\x44\xae\x42\x60\x82\ +\x00\x00\x00\xe7\ +\x89\ +\x50\x4e\x47\x0d\x0a\x1a\x0a\x00\x00\x00\x0d\x49\x48\x44\x52\x00\ +\x00\x00\x10\x00\x00\x00\x10\x04\x03\x00\x00\x00\xed\xdd\xe2\x52\ +\x00\x00\x00\x03\x73\x42\x49\x54\x08\x08\x08\xdb\xe1\x4f\xe0\x00\ +\x00\x00\x09\x70\x48\x59\x73\x00\x00\x03\xd1\x00\x00\x03\xd1\x01\ +\x98\x8a\x89\xb4\x00\x00\x00\x19\x74\x45\x58\x74\x53\x6f\x66\x74\ +\x77\x61\x72\x65\x00\x77\x77\x77\x2e\x69\x6e\x6b\x73\x63\x61\x70\ +\x65\x2e\x6f\x72\x67\x9b\xee\x3c\x1a\x00\x00\x00\x30\x50\x4c\x54\ +\x45\x8b\x92\x9e\x97\x9d\xa8\x99\xa0\xab\xa0\xa7\xb1\xa4\xab\xb4\ +\xa6\xac\xb5\xa7\xad\xb6\xb3\xb9\xc0\xb5\xbb\xc2\xb6\xbc\xc3\xc1\ +\xc7\xcc\xc3\xc9\xcf\xd0\xd5\xd9\xe3\xe8\xea\xe6\xeb\xec\xe7\xec\ +\xed\x53\xe8\xb6\xd9\x00\x00\x00\x29\x49\x44\x41\x54\x08\x5b\x63\ +\xf8\x0f\x05\x0c\x44\x33\xae\x43\x19\xff\x78\xa0\x8c\x8f\xfb\xc1\ +\x0c\xaf\xff\x91\x10\x35\x8f\x22\xf2\xa1\x8a\x27\x23\x74\x11\xc9\ +\x00\x00\xa9\xd1\x7a\xfc\xeb\x17\x98\xb3\x00\x00\x00\x00\x49\x45\ +\x4e\x44\xae\x42\x60\x82\ +" + +qt_resource_name = b"\ +\x00\x03\ +\x00\x00\x70\x37\ +\x00\x69\ +\x00\x6d\x00\x67\ +\x00\x0e\ +\x04\xac\x3c\xa7\ +\x00\x64\ +\x00\x6f\x00\x77\x00\x6e\x00\x2d\x00\x61\x00\x72\x00\x72\x00\x6f\x00\x77\x00\x2e\x00\x70\x00\x6e\x00\x67\ +\x00\x0b\ +\x01\x64\x80\x07\ +\x00\x63\ +\x00\x68\x00\x65\x00\x63\x00\x6b\x00\x65\x00\x64\x00\x2e\x00\x70\x00\x6e\x00\x67\ +" + +qt_resource_struct = b"\ +\x00\x00\x00\x00\x00\x02\x00\x00\x00\x01\x00\x00\x00\x01\ +\x00\x00\x00\x00\x00\x02\x00\x00\x00\x02\x00\x00\x00\x02\ +\x00\x00\x00\x2e\x00\x00\x00\x00\x00\x01\x00\x00\x01\xb4\ +\x00\x00\x00\x0c\x00\x00\x00\x00\x00\x01\x00\x00\x00\x00\ +" + +def qInitResources(): + QtCore.qRegisterResourceData(0x01, qt_resource_struct, qt_resource_name, qt_resource_data) + +def qCleanupResources(): + QtCore.qUnregisterResourceData(0x01, qt_resource_struct, qt_resource_name, qt_resource_data) + +qInitResources() diff --git a/toolkit/pathtracing_reference/README.md b/toolkit/pathtracing_reference/README.md new file mode 100644 index 0000000..cb9cdd2 --- /dev/null +++ b/toolkit/pathtracing_reference/README.md @@ -0,0 +1,9 @@ + +# Pathtracer Reference + +This is a utility tool to generate a pathtracer reference. +You need to get a copy of the Mitsuba renderer, and copy it to `C:/mitsuba`. + +The Mitsuba renderer can be acquired from: + +https://www.mitsuba-renderer.org/download.html diff --git a/toolkit/pathtracing_reference/batch_compare.py b/toolkit/pathtracing_reference/batch_compare.py new file mode 100644 index 0000000..d0b76aa --- /dev/null +++ b/toolkit/pathtracing_reference/batch_compare.py @@ -0,0 +1,208 @@ +""" + +Compares various results + +""" + +from __future__ import print_function + +import os +import sys + +from panda3d.core import PNMImage + +try: + os.makedirs("batch_compare") +except: + pass + +overlay = PNMImage("res/overlay.png") + +materials_to_test = [] + +GOLD_F0 = (1, 0.867136, 0.358654) + +# materials_to_test.append({ +# "name": "Gold", +# "basecolor": GOLD_F0, +# "roughness": 0.1, +# "type": "metallic", +# "material_src": "Au" +# }) + +# materials_to_test.append({ +# "name": "Foliage", +# "basecolor": (0.6, 0.9, 0.6), +# "roughness": 0.6, +# "type": "foliage" +# }) + +# materials_to_test.append({ +# "name": "GoldRough", +# "basecolor": GOLD_F0, +# "roughness": 0.4, +# "type": "metallic", +# "material_src": "Au" +# }) + + +# materials_to_test.append({ +# "name": "Test-R0", +# "basecolor": (0, 0, 0), +# "ior": 1.51, +# "roughness": 0.3 +# }) + +# materials_to_test.append({ +# "name": "Test-IOR1.1", +# "basecolor": (0, 0, 1), +# "ior": 1.1, +# "roughness": 0.0 +# }) + +# materials_to_test.append({ +# "name": "Test-IOR2", +# "basecolor": (0, 0, 1), +# "ior": 2.0, +# "roughness": 0.0 +# }) + +# materials_to_test.append({ +# "name": "Test-IOR2.5", +# "basecolor": (0, 0, 1), +# "ior": 2.5, +# "roughness": 0.0 +# }) + + +# materials_to_test.append({ +# "name": "Test-SpecOnly", +# "basecolor": (0, 0, 0), +# "ior": 1.5, +# "roughness": 0.0 +# }) + +# materials_to_test.append({ +# "name": "Test-SpecOnly-R0.3", +# "basecolor": (0, 0, 0), +# "ior": 1.5, +# "roughness": 0.3 +# }) + +# materials_to_test.append({ +# "name": "Nonrefractive-Diffuse", +# "basecolor": (0.5, 0.5, 0.5), +# "ior": 1.0, +# "roughness": 1.0 +# }) + +# materials_to_test.append({ +# "name": "Rough-Diffuse", +# "basecolor": (0.5, 0.5, 0.5), +# "ior": 1.5, +# "roughness": 0.8 +# }) +# materials_to_test.append({ +# "name": "Normal-Diffuse", +# "basecolor": (00.5, 0.5, 0.5), +# "ior": 1.5, +# "roughness": 0.4 +# }) + + +for i in range(11): + roughness = i / 10.0 + + materials_to_test.append({ + "name": "Plastic-R" + str(roughness), + "basecolor": (1, 0, 0), + "ior": 1.51, + "roughness": roughness + }) + + # materials_to_test.append({ + # "name": "Gold-R" + str(roughness), + # "basecolor": GOLD_F0, + # "ior": 1.51, + # "type": "metallic", + # "material_src": "Au", + # "roughness": roughness + # }) + + # materials_to_test.append({ + # "name": "Clearcoat-R" + str(roughness), + # "basecolor": (1, 0.85, 0.345), + # "material_src": "Au", + # "type": "clearcoat", + # "roughness": roughness + # }) + + # materials_to_test.append({ + # "name": "Diffuse-R" + str(roughness), + # "basecolor": (0.8, 0.8, 0.8), + # "ior": 1.16, + # "roughness": roughness + # }) + + +for material in materials_to_test: + + print("Testing material", material["name"]) + + # Write material def + with open("_tmp_material.py", "w") as handle: + handle.write("# Autogenerated\n") + handle.write("name = '{}'".format(material["name"]) + "\n") + handle.write("roughness = {}".format(material["roughness"]) + "\n") + handle.write("ior = {}".format(material.get("ior", 1.51)) + "\n") + handle.write("basecolor = {}".format(material["basecolor"]) + "\n") + handle.write("mat_type = '{}'".format(material.get("type", "default")) + "\n") + + # run rp + print(" Running RP ..") + cmd = '"{}"'.format(sys.executable) + " -B run_renderpipeline.py silent > nul" + os.system(cmd) + + print(" Running mitsuba ..") + # run mitsuba + with open("res/scene.templ.xml", "r") as handle: + content = handle.read() + + mat_type = material.get("type", "default") + + use_default = mat_type == "default" + use_metallic = mat_type == "metallic" + + for shading_type in (("default", "metallic", "clearcoat")): + def_name = shading_type.upper() + if mat_type == shading_type: + content = content.replace("%IF_" + def_name + "%", "") + content = content.replace("%ENDIF_" + def_name + "%", "") + else: + content = content.replace("%IF_" + def_name + "%", "") + + content = content.replace("%ALPHA%", str(material["roughness"] * material["roughness"])) + content = content.replace("%IOR%", str(material.get("ior", 1.51))) + content = content.replace("%BASECOLOR%", str(material["basecolor"]).strip("()")) + content = content.replace("%MATERIAL_SRC%", material.get("material_src", "").strip("()")) + + with open("res/scene.xml", "w") as handle: + handle.write(content) + + os.system("run_mitsuba.bat > nul") + + print(" Writing result ..") + img = PNMImage("scene-rp.png") + img_ref = PNMImage("scene.png") + + img.copy_sub_image(img_ref, 256, 0, 256, 0, 256, 512) + img.mult_sub_image(overlay, 0, 0) + img.write("batch_compare/" + material["name"] + ".png") + +try: + os.remove("_tmp_material.py") +except: + pass + +print("Done!") diff --git a/toolkit/pathtracing_reference/config/daytime.yaml b/toolkit/pathtracing_reference/config/daytime.yaml new file mode 100644 index 0000000..90e061b --- /dev/null +++ b/toolkit/pathtracing_reference/config/daytime.yaml @@ -0,0 +1,24 @@ + +# Render Pipeline Time Of Day Configuration +# Instead of editing this file, prefer to use the Time Of Day Editor +# Any formatting and comments will be lost + +control_points: + clouds: + cloud_brightness: [[[0.5000000000,0.5000000000]]] + cloud_intensity: [[[0.5,0.5]]] + cumulus_amount: [[[0.5,1.0000000000]]] + stratus_amount: [[[0.1103700000,1.0000000000]]] + soft_amount: [[[0.5,1.0000000000]]] + color_correction: + camera_iso: [[[0.5345489443,0.5136513820]]] + camera_shutter: [[[0.5095969290,0.1128516483]]] + camera_aperture: [[[0.5019193858,0.4838709677]]] + scattering: + sun_intensity: [[[0.5000000000,0.5000000000]]] + sun_color: [[[0.4971900000,0.5763000000],[0.0433100000,0.8999700000],[0.8597400000,0.9130000000],[0.1785000000,0.8973600000],[0.8099800000,0.8651100000],[0.2360800000,0.7712700000],[0.6602700000,0.6451700000],[0.1286000000,0.9530800000]],[[0.5058900000,0.5160300000],[0.0572700000,0.6541600000],[0.2395000000,0.5976800000],[0.8104600000,0.6009000000],[0.6967400000,0.5483900000]],[[0.0862400000,0.4257800000],[0.4955600000,0.4033000000],[0.8234200000,0.4340200000]]] + sun_azimuth: [[[0.5000000000,0.5000000000]]] + sun_altitude: [[[0.5000000000,0.5000000000]]] + fog_ramp_size: [[[0.6468330134,0.9178885631]]] + dof: + some_scalar: [[[0.5000000000,0.5000000000]]] diff --git a/toolkit/pathtracing_reference/config/debugging.yaml b/toolkit/pathtracing_reference/config/debugging.yaml new file mode 100644 index 0000000..fa9cfc3 --- /dev/null +++ b/toolkit/pathtracing_reference/config/debugging.yaml @@ -0,0 +1,17 @@ + +# This file contains all available debug modes. +# You can add or remove debug modes here, aswell as +# disable or enable them, whatever fits to you. + +# NOTICE: This file only has effect if debugging is enabled +# in the pipeline.yaml (settings.pipeline.display_debuger == True) + +render_modes: + - { name: "Diffuse", key: "DIFFUSE" } + - { name: "Roughness", key: "ROUGHNESS" } + - { name: "Specular", key: "SPECULAR" } + - { name: "Normal", key: "NORMAL" } + - { name: "Metallic", key: "METALLIC" } + - { name: "Translucency", key: "TRANSLUCENCY" } + - { name: "PSSM Splits", key: "PSSM_SPLITS", requires: "pssm", cxx_only: true } + - { name: "Ambient Occlusion", key: "OCCLUSION", requires: "ao" } diff --git a/toolkit/pathtracing_reference/config/panda3d-config.prc b/toolkit/pathtracing_reference/config/panda3d-config.prc new file mode 100644 index 0000000..dfdb0fe --- /dev/null +++ b/toolkit/pathtracing_reference/config/panda3d-config.prc @@ -0,0 +1,172 @@ + + +# This is the config file used to configure basic settings for Panda3D. +# The pipeline loads it at startup to ensure the environment is setup properly. + +# -------------- Debugging options -------------- + +# gl-dump-compiled-shaders #t +# notify-level-glgsg debug +# notify-level-glgsg warning +# notify-level-gobj debug +pstats-gpu-timing #t +pstats-max-rate 200 +gl-debug #t +gl-debug-object-labels #t +sync-video #f + +# ----------------- Misc Settings ----------------- + +# No stack trace on assertion, set this to true to make panda crash on assertions +# (which will allow to debug it) +assert-abort #t + +# File system should be case sensitive +# NOTICE: Set this to #f if you are using tempfile, since it returns +# wrong cased directory paths +vfs-case-sensitive #t + +# Enable state cache, this seems to actually help the performance by a lot +state-cache #t +transform-cache #t + +# Frame rate meter style +frame-rate-meter-milliseconds #t +frame-rate-meter-update-interval 1.0 +frame-rate-meter-text-pattern %0.2f fps +frame-rate-meter-ms-text-pattern %0.3f ms +frame-rate-meter-layer-sort 1000 +frame-rate-meter-scale 0.036 +frame-rate-meter-side-margins 0.4 +show-frame-rate-meter #f + +# Set text settings +text-minfilter linear +text-magfilter linear +text-page-size 512 512 + +# Better text performance since rdb's patch +text-flatten 0 +text-dynamic-merge 1 + +# For smoother animations +# even-animation #t + +# Threading, really buggy! +#threading-model App/Cull/Draw + +support-stencil #f +framebuffer-stencil #f + +# Don't use srgb correction, we do that ourself +framebuffer-srgb #f + +# Don't use multisamples +framebuffer-multisample #f +multisamples 0 + +# Don't rescale textures which are no power-of-2 +textures-power-2 none + +# This is required, the pipeline does not support resizing yet +win-fixed-size #t + +# Set default texture filters +texture-anisotropic-degree 8 +texture-magfilter linear +texture-minfilter linear +texture-quality-level fastest + +# Enable seamless cubemap filtering, thats important for environment filtering +gl-cube-map-seamless #t + +# Set model cache dir +model-cache-dir $USER_APPDATA/Panda3D-1.9/cache +model-cache-textures #f + +# Disable the annoying SRGB warning from pnmimage +notify-level-pnmimage error + +# Disable the buffer viewer, we have our own +show-buffers #f + +# Use the default coordinate system, this makes our matrix transformations +# faster because we don't have have to transform them to a different coordinate +# system before +gl-coordinate-system default + +# This makes animations smoother, especially if they were exported at 30 FPS +# and are played at 60 FPS +interpolate-frames #t + +# Disable workarround in panda which causes our shadow atlas to take twice +# the amount of vram it should, due to an intel driver bug. +gl-force-fbo-color #f + +# ----------- OpenGL / Performance Settings ------------ + +# Animations on the gpu. The default shader has to get adjusted to support this +# feature before this option can be turned on. +# hardware-animated-vertices #t + +# Try this options for performance +# uniquify-matrix #t +# uniquify-transforms #t +# uniquify-states #t +# uniquify-attribs #f + +# Enable garbarge collection +garbage-collect-states #t +# garbage-collect-states-rate 0.2 + +# Compress textures on the drivers? +# driver-compress-textures #t + +# Faster animations? (Have to test) +# matrix-palette #t +# display-list-animation #t + +# Better GL performance by not using gl-finish and so on +gl-finish #f +gl-force-no-error #t +gl-check-errors #f +gl-force-no-flush #t +gl-force-no-scissor #t + +# Eventually disable memory barriers, have to check if this is faster +gl-enable-memory-barriers #f + +# Disable threading +lock-to-one-cpu #t +support-threads #f + +# Let the driver generate the mipmaps +driver-generate-mipmaps #t +#gl-ignore-mipmaps #t + +# Use immutable texture storage, it is *supposed* to be faster, but might not be +gl-immutable-texture-storage #t + +# auto-flip #f + +# Default window settings +# depth-bits 0 +color-bits 0 + +framebuffer-depth #f + +gl-fixed-vertex-attrib-locations #f + +# Disable the fragment shader performance warning +gl-validate-shaders #f +gl-skip-shader-recompilation-warnings #t + +alpha-scale-via-texture #f +bounds-type best # best/fastest/sphere/box +pstats-name Render Pipeline Stats +rescale-normals #f +screenshot-extension png + +# Required for correct velocity +always-store-prev-transform #t +allow-incomplete-render #t diff --git a/toolkit/pathtracing_reference/config/pipeline.yaml b/toolkit/pathtracing_reference/config/pipeline.yaml new file mode 100644 index 0000000..d87cbaa --- /dev/null +++ b/toolkit/pathtracing_reference/config/pipeline.yaml @@ -0,0 +1,19 @@ + +pipeline: + display_debugger: false + use_r11_g11_b10: false + resolution_scale: 2.0 + reference_mode: true + +lighting: + culling_grid_size_x: 32 + culling_grid_size_y: 16 + culling_grid_slices: 32 + culling_max_distance: 50.0 + culling_slice_width: 256 + max_lights_per_cell: 64 + +shadows: + atlas_size: 4096 + max_updates: 40 + max_update_distance: 150.0 diff --git a/toolkit/pathtracing_reference/config/plugins.yaml b/toolkit/pathtracing_reference/config/plugins.yaml new file mode 100644 index 0000000..728beb5 --- /dev/null +++ b/toolkit/pathtracing_reference/config/plugins.yaml @@ -0,0 +1,155 @@ + +# Render Pipeline Plugin Configuration +# Instead of editing this file, prefer to use the Plugin Configurator +# Any formatting and comments will be lost + +enabled: + # - ao + # - bloom + # - color_correction + # - env_probes + # - pssm + # - scattering + # - smaa + # - ssr + # - clouds + # - dof + # - fxaa + # - motion_blur + # - skin_shading + # - volumetrics + # - vxgi + + +overrides: + ao: + blur_normal_factor: 4.94 + blur_depth_factor: 4.83 + occlusion_strength: 1.21 + technique: SSAO + ssao_sample_radius: 79.61 + ssao_sample_count: 8 + ssao_bias: 0.0333 + ssao_max_distance: 6.89 + hbao_sample_radius: 119.11 + hbao_ray_count: 4 + hbao_ray_steps: 3 + hbao_tangent_bias: 0.5889 + hbao_max_distance: 4.9 + ssvo_sample_count: 4 + ssvo_sphere_radius: 7.86 + ssvo_max_distance: 0.6 + alchemy_sample_radius: 127.8901 + alchemy_num_samples: 8 + alchemy_max_distance: 6.07 + ue4ao_sample_radius: 110.33 + ue4ao_sample_count: 8 + ue4ao_max_distance: 1.87 + + bloom: + num_mipmaps: 8 + bloom_strength: 0.45 + remove_fireflies: False + lens_dirt_factor: 0.7111 + + clouds: + cloud_decay: 5.78 + raymarch_steps: 64 + + color_correction: + tonemap_operator: optimized + reinhard_version: rgb + exponential_factor: 1.4 + uc2t_shoulder_strength: 0.22 + uc2t_linear_strength: 0.3 + uc2t_linear_angle: 0.1 + uc2t_toe_strength: 0.2 + uc2t_toe_numerator: 0.01 + uc2t_toe_denumerator: 0.3 + uc2t_reference_white: 11.2 + vignette_strength: 0.4444 + film_grain_strength: 0.2889 + color_lut: color_lut.png + use_chromatic_aberration: True + chromatic_aberration_strength: 0.22 + chromatic_aberration_samples: 2 + manual_camera_parameters: False + min_exposure_value: 0.012 + max_exposure_value: 1.0 + exposure_bias: 0.0 + brightness_adaption_rate: 2.67 + darkness_adaption_rate: 0.79 + use_sharpen: False + sharpen_strength: 0.5 + sharpen_twice: False + + dof: + + env_probes: + probe_resolution: 128 + diffuse_probe_resolution: 4 + max_probes: 16 + max_probes_per_cell: 5 + + fxaa: + quality: ultra + subpixel_quality: 0.5 + edge_threshold: 0.075 + min_threshold: 0.7114 + + motion_blur: + num_camera_samples: 6 + camera_blur_factor: 0.5778 + blur_factor: 0.5 + tile_size: 32 + max_blur_radius: 10.0 + num_samples: 12 + + pssm: + max_distance: 45.0 + logarithmic_factor: 2.67 + sun_distance: 1145.0 + split_count: 3 + resolution: 2048 + border_bias: 0.01943 + use_pcf: True + filter_sample_count: 32 + filter_radius: 9.89 + fixed_bias: 0.0889 + slope_bias: 0.39 + normal_bias: 0.0 + use_pcss: False + pcss_search_samples: 32 + pcss_penumbra_size: 300.0 + use_distant_shadows: True + dist_shadow_resolution: 1024 + dist_shadow_clipsize: 150.0 + scene_shadow_resolution: 1024 + + scattering: + scattering_method: eric_bruneton + ground_reflectance: 0.1 + rayleigh_height_scale: 8.0 + mie_height_scale: 1.45 + mie_phase_factor: 0.21 + beta_mie_scattering: 4.0 + enable_godrays: False + + skin_shading: + quality: high + blur_scale: 1.0 + + smaa: + use_reprojection: True + smaa_quality: ultra + + ssr: + + volumetrics: + + vxgi: + grid_resolution: 256 + grid_ws_size: 20.0 + diffuse_cone_steps: 32 + specular_cone_steps: 150 + diff --git a/toolkit/pathtracing_reference/config/stages.yaml b/toolkit/pathtracing_reference/config/stages.yaml new file mode 100644 index 0000000..c76ef0a --- /dev/null +++ b/toolkit/pathtracing_reference/config/stages.yaml @@ -0,0 +1,61 @@ + +# This file controls the order of all render stages. +# Usually you do not have to modify this, except if you are adding new plugins. +# If you move stages, you should know what you do. +# Commenting out a stage won't disable it, but instead produce an error when +# it is created. + +global_stage_order: + + # Shadows, Environment and Voxelization + - PSSMShadowStage + - PSSMDistShadowStage + - PSSMSceneShadowStage + - ScatteringEnvmapStage + - EnvironmentCaptureStage + - VoxelizationStage + + # Main scene + - GBufferStage + - ShadowStage + - DownscaleZStage + - CombineVelocityStage + + # Light(-culling) + - FlagUsedCellsStage + - CollectUsedCellsStage + - CullLightsStage + - CullProbesStage + + # Plugins + - CloudVoxelStage + - AOStage + - ApplyLightsStage + - PSSMStage + - ScatteringStage + - ApplyEnvprobesStage + - VXGIStage + - SSRStage + - SSSRStage + - AmbientStage + - ApplyCloudsStage + - GodrayStage + - VolumetricsStage + - AutoExposureStage + - ManualExposureStage + + # Post AA & Effects + - BloomStage + - TonemappingStage + - SMAAStage + - FXAAStage + - DoFStage + - MotionBlurStage + - SkinShadingStage + - SharpenStage + - ColorCorrectionStage + + # Finishing stages, do not insert anything below + - UpscaleStage + - FinalStage + - UpdatePreviousPipesStage diff --git a/toolkit/pathtracing_reference/config/task-scheduler.yaml b/toolkit/pathtracing_reference/config/task-scheduler.yaml new file mode 100644 index 0000000..23d6c7f --- /dev/null +++ b/toolkit/pathtracing_reference/config/task-scheduler.yaml @@ -0,0 +1,33 @@ + +# This file controls which tasks are allowed to run each frame. +# Usually you do not have to edit this file, except when developing plugins. + +frame_cycles: !!omap + + - frame1: + - envprobes_select_and_cull + - pssm_scene_shadows + + - frame2: + - envprobes_capture_envmap_face0 + - pssm_distant_shadows + + - frame3: + - envprobes_capture_envmap_face1 + - pssm_convert_distant_to_esm + + - frame4: + - envprobes_capture_envmap_face2 + - pssm_blur_distant_vert + + - frame5: + - pssm_blur_distant_horiz + - envprobes_capture_envmap_face3 + - envprobes_capture_envmap_face4 + + - frame6: + - envprobes_capture_envmap_face5 + - scattering_update_envmap + + - frame7: + - envprobes_filter_and_store_envmap diff --git a/toolkit/pathtracing_reference/generate_difference.py b/toolkit/pathtracing_reference/generate_difference.py new file mode 100644 index 0000000..8088e7e --- /dev/null +++ b/toolkit/pathtracing_reference/generate_difference.py @@ -0,0 +1,42 @@ +""" + +Compares both renders + +""" + +from __future__ import print_function + +from panda3d.core import PNMImage + +source_a = "scene.png" +source_b = "scene-rp.png" + +write_diff_img = False + +img_a = PNMImage(source_a) +img_b = PNMImage(source_b) + +w, h = img_a.get_x_size(), img_a.get_y_size() +img_dest = PNMImage(w, h, 3) + +error_scale = 10.0 + +total_diff = 0.0 + +for x in xrange(w): + for y in xrange(h): + val_a = img_a.get_xel(x, y) + val_b = img_b.get_xel(x, y) + + abs_diff = (val_a - val_b) * error_scale + r, g, b = abs(abs_diff.x), abs(abs_diff.y), abs(abs_diff.z) + + img_dest.set_xel(x, y, r, g, b) + total_diff += r + g + b + +total_diff /= float(w * h) +total_diff /= error_scale + +print("Average difference: ", total_diff, " in RGB: ", total_diff * 255) + +img_dest.write("difference.png") diff --git a/toolkit/pathtracing_reference/get_brightness.py b/toolkit/pathtracing_reference/get_brightness.py new file mode 100644 index 0000000..109e82f --- /dev/null +++ b/toolkit/pathtracing_reference/get_brightness.py @@ -0,0 +1,32 @@ + +from __future__ import division, print_function + +from panda3d.core import PNMImage, Vec3 + + +def approx(roughness): + return 1.0 - 0.5 * roughness + +for i in range(11): + r = i / 10.0 + fname = "batch_compare/Gold-R" + str(r) + ".png" + + img = PNMImage(fname) + # color = (img.get_xel(img.get_x_size() // 2 + 3, img.get_y_size() // 2)) + color = (img.get_xel(256, 47)) + + color.x = pow(color.x, 2.2) + color.y = pow(color.y, 2.2) + color.z = pow(color.z, 2.2) + + # print(color) + + basecolor = Vec3(1, 0.867136, 0.358654) + + ref_r, apprx_r = color.x, approx(r) * (0.5 + 0.5 * basecolor.x) + ref_g, apprx_g = color.y, approx(r) * (0.5 + 0.5 * basecolor.y) + ref_b, apprx_b = color.z, approx(r) * (0.5 + 0.5 * basecolor.z) + print("Roughness:", r, ", color = ", ref_r, ref_g, ref_b, "vs", apprx_r, apprx_g, apprx_b) + l = abs(ref_r - apprx_r) + abs(ref_g - apprx_g) + abs(ref_b - apprx_b) + print(" --> ", l) + # print("Roughness:", r, ", color = ", ref, "vs", apprx, " =\t", abs(ref - apprx) * 100.0) diff --git a/toolkit/pathtracing_reference/res/overlay.png b/toolkit/pathtracing_reference/res/overlay.png new file mode 100644 index 0000000..1315fe8 Binary files /dev/null and b/toolkit/pathtracing_reference/res/overlay.png differ diff --git a/toolkit/pathtracing_reference/res/scene.templ.xml b/toolkit/pathtracing_reference/res/scene.templ.xml new file mode 100644 index 0000000..5ab5a7d --- /dev/null +++ b/toolkit/pathtracing_reference/res/scene.templ.xml @@ -0,0 +1,119 @@ + + + + + + + + + + + + + + %IF_DEFAULT% + + + + + + + + %ENDIF_DEFAULT% + + %IF_METALLIC% + + + + + + + + %ENDIF_METALLIC% + + %IF_CLEARCOAT% + + + + + + + + + + + + + + + + %ENDIF_CLEARCOAT% + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/toolkit/pathtracing_reference/res/scene.xml b/toolkit/pathtracing_reference/res/scene.xml new file mode 100644 index 0000000..187d5d1 --- /dev/null +++ b/toolkit/pathtracing_reference/res/scene.xml @@ -0,0 +1,119 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/toolkit/pathtracing_reference/res/sphere.bam b/toolkit/pathtracing_reference/res/sphere.bam new file mode 100644 index 0000000..d33af9a Binary files /dev/null and b/toolkit/pathtracing_reference/res/sphere.bam differ diff --git a/toolkit/pathtracing_reference/res/tex/convert_cubemap.py b/toolkit/pathtracing_reference/res/tex/convert_cubemap.py new file mode 100644 index 0000000..0e3b921 --- /dev/null +++ b/toolkit/pathtracing_reference/res/tex/convert_cubemap.py @@ -0,0 +1,66 @@ +""" +Converts the cubemap to a spherical one +""" + +from __future__ import division, print_function + +from panda3d.core import * # noqa +load_prc_file_data("", "textures-power-2 none") + +import direct.directbase.DirectStart # noqa + +cubemap = loader.load_cube_map("../../../../data/default_cubemap/source/#.jpg") +w, h = 4096, 2048 + +cshader = Shader.make_compute(Shader.SL_GLSL, """ +#version 430 +layout (local_size_x = 16, local_size_y = 16, local_size_z = 1) in; + +uniform samplerCube SourceTex; +uniform writeonly image2D DestTex; +#define M_PI 3.1415926535897932384626433 +#define TWO_PI 6.2831853071795864769252867 + +// Converts a normalized spherical coordinate (r = 1) to cartesian coordinates +vec3 spherical_to_vector(float theta, float phi) { + float sin_theta = sin(theta); + return normalize(vec3( + sin_theta * cos(phi), + sin_theta * sin(phi), + cos(theta) + )); +} + +// Fixes the cubemap direction +vec3 fix_cubemap_coord(vec3 coord) { + return normalize(coord.xzy * vec3(1,-1,1)); +} + +void main() { + ivec2 dimensions = imageSize(DestTex).xy; + ivec2 coord = ivec2(gl_GlobalInvocationID.xy); + float theta = (coord.x + 0.5) / float(dimensions.x) * TWO_PI; + float phi = (dimensions.y - coord.y - 0.5) / float(dimensions.y) * M_PI; + vec3 v = spherical_to_vector(phi, theta); + v = fix_cubemap_coord(v); + vec4 color = texture(SourceTex, v); + imageStore(DestTex, coord, vec4(color)); +} +""") + +dest_tex = Texture("") +dest_tex.setup_2d_texture(w, h, Texture.T_float, Texture.F_rgba16) + +print("Converting to spherical coordinates ..") +np = NodePath("np") +np.set_shader(cshader) +np.set_shader_input("SourceTex", cubemap) +np.set_shader_input("DestTex", dest_tex) +attr = np.get_attrib(ShaderAttrib) +base.graphicsEngine.dispatch_compute((w // 16, h // 16, 1), attr, base.win.gsg) + +print("Extracting data ..") +base.graphicsEngine.extract_texture_data(dest_tex, base.win.gsg) + +print("Writing texture ..") +dest_tex.write("envmap.png") diff --git a/toolkit/pathtracing_reference/res/tex/empty_basecolor.png b/toolkit/pathtracing_reference/res/tex/empty_basecolor.png new file mode 100644 index 0000000..437c244 Binary files /dev/null and b/toolkit/pathtracing_reference/res/tex/empty_basecolor.png differ diff --git a/toolkit/pathtracing_reference/res/tex/empty_normal.png b/toolkit/pathtracing_reference/res/tex/empty_normal.png new file mode 100644 index 0000000..863dc2e Binary files /dev/null and b/toolkit/pathtracing_reference/res/tex/empty_normal.png differ diff --git a/toolkit/pathtracing_reference/res/tex/empty_roughness.png b/toolkit/pathtracing_reference/res/tex/empty_roughness.png new file mode 100644 index 0000000..437c244 Binary files /dev/null and b/toolkit/pathtracing_reference/res/tex/empty_roughness.png differ diff --git a/toolkit/pathtracing_reference/res/tex/empty_specular.png b/toolkit/pathtracing_reference/res/tex/empty_specular.png new file mode 100644 index 0000000..26ee224 Binary files /dev/null and b/toolkit/pathtracing_reference/res/tex/empty_specular.png differ diff --git a/toolkit/pathtracing_reference/res/tex/white.png b/toolkit/pathtracing_reference/res/tex/white.png new file mode 100644 index 0000000..33b80f8 Binary files /dev/null and b/toolkit/pathtracing_reference/res/tex/white.png differ diff --git a/toolkit/pathtracing_reference/run_mitsuba.bat b/toolkit/pathtracing_reference/run_mitsuba.bat new file mode 100644 index 0000000..3219f7e --- /dev/null +++ b/toolkit/pathtracing_reference/run_mitsuba.bat @@ -0,0 +1,12 @@ +@echo off + +"C:/mitsuba/mitsuba" -p 6 res/scene.xml +echo "" +echo Rendering done +echo "" +echo "" +echo "" +"C:/mitsuba/mtsutil" tonemap res/scene.exr +copy res\scene.png scene.png +del res\scene.exr +del mitsuba.*.log diff --git a/toolkit/pathtracing_reference/run_renderpipeline.py b/toolkit/pathtracing_reference/run_renderpipeline.py new file mode 100644 index 0000000..f8e8104 --- /dev/null +++ b/toolkit/pathtracing_reference/run_renderpipeline.py @@ -0,0 +1,94 @@ +""" + +Renders the sphere using the render pipeline + +""" + +import _tmp_material as material + +import sys +from panda3d.core import load_prc_file_data, Vec4 +from direct.showbase.ShowBase import ShowBase + + +class Application(ShowBase): + + def __init__(self): + sys.path.insert(0, "../../") + load_prc_file_data("", "win-size 512 512") + load_prc_file_data("", "textures-power-2 none") + load_prc_file_data("", "print-pipe-types #f") + load_prc_file_data("", "notify-level-glgsg error") + # load_prc_file_data("", "win-size 1024 1024") + + from rpcore import RenderPipeline, PointLight + + self.render_pipeline = RenderPipeline() + self.render_pipeline.mount_mgr.config_dir = "config/" + self.render_pipeline.create(self) + + sphere = self.loader.loadModel("res/sphere.bam") + sphere.reparent_to(self.render) + + self.disableMouse() + self.camLens.setFov(40) + self.camLens.setNearFar(0.03, 2000.0) + self.camera.set_pos(0, -3.5, 0) + self.camera.look_at(0, -2.5, 0) + + self.render2d.hide() + self.aspect2d.hide() + + light = PointLight() + light.pos = 10, -10, 10 + light.radius = 1e20 + light.color = (1, 1, 1) + light.inner_radius = 4.0 + light.energy = 3 + self.render_pipeline.add_light(light) + + light = PointLight() + light.pos = -10, -10, 10 + light.radius = 1e20 + light.color = (1, 1, 1) + light.inner_radius = 4.0 + light.energy = 3 + self.render_pipeline.add_light(light) + + for mat in sphere.find_all_materials(): + mat.roughness = material.roughness + mat.base_color = Vec4(*(list(material.basecolor) + [1])) + mat.refractive_index = material.ior + + mat.metallic = 1.0 if material.mat_type == "metallic" else 0.0 + + if material.mat_type == "clearcoat": + mat.emission = (2, 0, 0, 0) + mat.metallic = 1.0 + mat.refractive_index = 1.51 + + if material.mat_type == "foliage": + mat.emission = (5, 0, 0, 0) + mat.metallic = 0.0 + mat.refractive_index = 1.51 + + for i in range(10): + self.taskMgr.step() + + self.win.save_screenshot("scene-rp.png") + + self.accept("r", self.reload) + + def reload(self): + print("Reloading") + self.render_pipeline.reload_shaders() + + for i in range(4): + self.taskMgr.step() + + self.win.save_screenshot("scene-rp.png") + +if len(sys.argv) <= 1: + Application().run() +else: + Application() diff --git a/toolkit/plugin_configurator/main.py b/toolkit/plugin_configurator/main.py new file mode 100644 index 0000000..750b533 --- /dev/null +++ b/toolkit/plugin_configurator/main.py @@ -0,0 +1,495 @@ +""" + +RenderPipeline + +Copyright (c) 2014-2016 tobspr + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. + +""" + +# This tool offers an interface to configure the pipeline + +from __future__ import print_function + +import os +import sys +import time +from threading import Thread +from functools import partial + +# Change to the current directory +os.chdir(os.path.join(os.path.dirname(os.path.realpath(__file__)))) + +# Append the current directory to the path +sys.path.insert(0, os.getcwd()) + +# Add the render pipeline to the path +sys.path.insert(0, "../../") + +from rplibs.six import iteritems # noqa +from rplibs.pyqt_imports import * #noqa + +# Load the generated UI Layout +from ui.main_window_generated import Ui_MainWindow # noqa + +from rpcore.pluginbase.manager import PluginManager # noqa +from rpcore.util.network_communication import NetworkCommunication # noqa +from rpcore.mount_manager import MountManager # noqa + + +class PluginConfigurator(QMainWindow, Ui_MainWindow): + + """ Interface to change the plugin settings """ + + def __init__(self): + + + # Init mounts + self._mount_mgr = MountManager(None) + self._mount_mgr.mount() + + self._plugin_mgr = PluginManager(None) + self._plugin_mgr.requires_daytime_settings = False + + QMainWindow.__init__(self) + Ui_MainWindow.__init__(self) + self.setupUi(self) + + + + self._current_plugin = None + self._current_plugin_instance = None + self.lbl_restart_pipeline.hide() + self._set_settings_visible(False) + self._update_queue = list() + + qt_connect(self.lst_plugins, "itemSelectionChanged()", + self.on_plugin_selected) + qt_connect(self.lst_plugins, "itemChanged(QListWidgetItem*)", + self.on_plugin_state_changed) + qt_connect(self.btn_reset_plugin_settings, "clicked()", + self.on_reset_plugin_settings) + + self._load_plugin_list() + + # Adjust column widths + self.table_plugin_settings.setColumnWidth(0, 140) + self.table_plugin_settings.setColumnWidth(1, 105) + self.table_plugin_settings.setColumnWidth(2, 160) + + update_thread = Thread(target=self.update_thread, args=()) + update_thread.start() + + def closeEvent(self, event): # noqa + event.accept() + import os + os._exit(1) + + def on_reset_plugin_settings(self): + """ Gets called when the user wants to reset settings of a plugin """ + + # Ask the user if he's really sure about it + msg = "Are you sure you want to reset the settings of '" + msg += self._current_plugin_instance.name + "'?\n" + msg += "This does not reset the Time of Day settings of this plugin.\n\n" + msg += "!! This cannot be undone !! They will be lost forever (a long time!)." + reply = QMessageBox.question( + self, "Warning", msg, QMessageBox.Yes, QMessageBox.No) + if reply == QMessageBox.Yes: + + QMessageBox.information( + self, "Success", + "Settings have been reset! You may have to restart the pipeline.") + self._plugin_mgr.reset_plugin_settings(self._current_plugin) + + # Save config + self._plugin_mgr.save_overrides("/$$rpconfig/plugins.yaml") + + # Always show the restart hint, even if its not always required + self._show_restart_hint() + + # Re-render everything + self._load_plugin_list() + + def on_plugin_state_changed(self, item): + """ Handler when a plugin got activated/deactivated """ + plugin_id = item._plugin_id + state = item.checkState() == Qt.Checked + self._plugin_mgr.set_plugin_enabled(plugin_id, state) + self._rewrite_plugin_config() + self._show_restart_hint() + + def on_plugin_selected(self): + """ Gets called when a plugin got selected in the plugin list """ + selected_item = self.lst_plugins.selectedItems() + if not selected_item: + self._current_plugin = None + self._current_plugin_instance = None + self._set_settings_visible(False) + return + assert len(selected_item) == 1 + selected_item = selected_item[0] + self._current_plugin = selected_item._plugin_id + self._current_plugin_instance = self._plugin_mgr.instances[self._current_plugin] + assert(self._current_plugin_instance is not None) + self._render_current_plugin() + self._set_settings_visible(True) + + def update_thread(self): + """ Internal update thread """ + while True: + if len(self._update_queue) > 0: + item = self._update_queue.pop(-1) + NetworkCommunication.send_async(NetworkCommunication.CONFIG_PORT, item) + + if item.startswith("setval "): + setting_id = item.split()[1] + for entry in list(self._update_queue): + if entry.split()[1] == setting_id: + self._update_queue.remove(entry) + time.sleep(0.2) + + def _rewrite_plugin_config(self): + """ Rewrites the plugin configuration """ + self._plugin_mgr.save_overrides("/$$rpconfig/plugins.yaml") + + def _render_current_plugin(self): + """ Displays the currently selected plugin """ + self.lbl_plugin_name.setText(self._current_plugin_instance.name.upper() + " [" + self._current_plugin_instance.plugin_id + "]") + + version_str = "Version " + self._current_plugin_instance.version + version_str += " by " + self._current_plugin_instance.author + + self.lbl_plugin_version.setText(version_str) + self.lbl_plugin_desc.setText(self._current_plugin_instance.description) + + self._render_current_settings() + + def _show_restart_hint(self): + """ Shows a hint to restart the pipeline """ + self.lbl_restart_pipeline.show() + + def _render_current_settings(self): + """ Renders the current plugin settings """ + settings = self._plugin_mgr.settings[self._current_plugin] + + # remove all rows + while self.table_plugin_settings.rowCount() > 0: + self.table_plugin_settings.removeRow(0) + + label_font = QFont() + label_font.setPointSize(10) + label_font.setFamily("Roboto") + + desc_font = QFont() + desc_font.setPointSize(8) + desc_font.setFamily("Roboto") + + for index, (name, handle) in enumerate(iteritems(settings)): + if not handle.should_be_visible(settings): + continue + + row_index = self.table_plugin_settings.rowCount() + + # Increase row count + self.table_plugin_settings.insertRow(self.table_plugin_settings.rowCount()) + + label = QLabel() + label.setText(handle.label) + label.setWordWrap(True) + label.setFont(label_font) + + if not (handle.shader_runtime or handle.runtime ): + label.setStyleSheet("color: #999;") + + if handle.display_conditions: + label.setStyleSheet(label.styleSheet() + "padding-left: 10px;") + + label.setMargin(10) + + self.table_plugin_settings.setCellWidget(row_index, 0, label) + + item_default = QTableWidgetItem() + item_default.setText(str(handle.default)) + item_default.setTextAlignment(Qt.AlignCenter) + self.table_plugin_settings.setItem(row_index, 1, item_default) + + setting_widget = self._get_widget_for_setting(name, handle) + self.table_plugin_settings.setCellWidget(row_index, 2, setting_widget) + + label_desc = QLabel() + label_desc.setText(handle.description) + label_desc.setWordWrap(True) + label_desc.setFont(desc_font) + label_desc.setStyleSheet("color: #555;padding: 5px;") + + self.table_plugin_settings.setCellWidget(row_index, 3, label_desc) + + def _do_update_setting(self, setting_id, value): + """ Updates a setting of the current plugin """ + + # Check whether the setting is a runtime setting + setting_handle = self._plugin_mgr.get_setting_handle( + self._current_plugin, setting_id) + + # Skip the setting in case the value is equal + if setting_handle.value == value: + return + + # Otherwise set the new value + setting_handle.set_value(value) + self._rewrite_plugin_config() + + if not setting_handle.runtime and not setting_handle.shader_runtime: + self._show_restart_hint() + else: + # In case the setting is dynamic, notice the pipeline about it: + # print("Sending reload packet ...") + self._update_queue.append("setval {}.{} {}".format( + self._current_plugin, setting_id, value)) + + # Update GUI, but only in case of enum and bool values, since they can trigger + # display conditions: + if setting_handle.type == "enum" or setting_handle.type == "bool": + self._render_current_settings() + + def _on_setting_bool_changed(self, setting_id, value): + self._do_update_setting(setting_id, value == Qt.Checked) + + def _on_setting_scalar_changed(self, setting_id, value): + self._do_update_setting(setting_id, value) + + def _on_setting_enum_changed(self, setting_id, value): + self._do_update_setting(setting_id, value) + + def _on_setting_power_of_two_changed(self, setting_id, value): + self._do_update_setting(setting_id, value) + + def _on_setting_slider_changed(self, setting_id, setting_type, bound_objs, value): + if setting_type == "float": + value /= 100000.0 + self._do_update_setting(setting_id, value) + + for obj in bound_objs: + obj.setValue(value) + + def _on_setting_spinbox_changed(self, setting_id, setting_type, bound_objs, value): + self._do_update_setting(setting_id, value) + # Assume objects are sliders, so we need to rescale the value + for obj in bound_objs: + obj.setValue(value * 100000.0 if setting_type == "float" else value) + + def _choose_path(self, setting_id, setting_handle, bound_objs): + """ Shows a file chooser to show an path from """ + + this_dir = os.path.dirname(os.path.realpath(__file__)) + plugin_dir = os.path.join(this_dir, "../../rpplugins/" + self._current_plugin, "resources") + plugin_dir = os.path.abspath(plugin_dir) + search_dir = os.path.join(plugin_dir, setting_handle.base_path) + + print("Plugin dir =", plugin_dir) + print("Search dir =", search_dir) + + current_file = setting_handle.value.replace("\\", "/").split("/")[-1] + print("Current file =", current_file) + file_dlg = QFileDialog(self, "Choose File ..", search_dir, setting_handle.file_type) + file_dlg.selectFile(current_file) + # file_dlg.setViewMode(QFileDialog.Detail) + + if file_dlg.exec_(): + filename = file_dlg.selectedFiles() + filename = filename[-1] + print("QT selected files returned:", filename) + + filename = os.path.relpath(str(filename), plugin_dir) + filename = filename.replace("\\", "/") + print("Relative path is", filename) + self._do_update_setting(setting_id, filename) + + display_file = filename.split("/")[-1] + for obj in bound_objs: + obj.setText(display_file) + + def _get_widget_for_setting(self, setting_id, setting): + """ Returns an appropriate widget to control the given setting """ + + widget = QWidget() + layout = QHBoxLayout() + layout.setAlignment(Qt.AlignCenter) + widget.setLayout(layout) + + + if setting.type == "bool": + box = QCheckBox() + box.setChecked(Qt.Checked if setting.value else Qt.Unchecked) + qt_connect(box, "stateChanged(int)", + partial(self._on_setting_bool_changed, setting_id)) + layout.addWidget(box) + + elif setting.type == "float" or setting.type == "int": + + if setting.type == "float": + box = QDoubleSpinBox() + + if setting.maxval - setting.minval <= 2.0: + box.setDecimals(4) + else: + box = QSpinBox() + box.setMinimum(setting.minval) + box.setMaximum(setting.maxval) + box.setValue(setting.value) + + box.setAlignment(Qt.AlignCenter) + + slider = QSlider() + slider.setOrientation(Qt.Horizontal) + + if setting.type == "float": + box.setSingleStep(abs(setting.maxval - setting.minval) / 100.0) + # QSlider expects ints; scale float range and cast explicitly. + slider.setMinimum(int(setting.minval * 100000.0)) + slider.setMaximum(int(setting.maxval * 100000.0)) + slider.setValue(int(setting.value * 100000.0)) + elif setting.type == "int": + box.setSingleStep(int(max(1, (setting.maxval - setting.minval) / 32))) + slider.setMinimum(setting.minval) + slider.setMaximum(setting.maxval) + slider.setValue(setting.value) + + layout.addWidget(box) + layout.addWidget(slider) + + qt_connect(slider, "valueChanged(int)", + partial(self._on_setting_slider_changed, setting_id, setting.type, [box])) + + value_type = "int" if setting.type == "int" else "double" + + qt_connect(box, "valueChanged(" + value_type + ")", + partial(self._on_setting_spinbox_changed, setting_id, setting.type, [slider])) + + elif setting.type == "enum": + box = QComboBox() + for value in setting.values: + box.addItem(value) + qt_connect(box, "currentIndexChanged(QString)", + partial(self._on_setting_enum_changed, setting_id)) + box.setCurrentIndex(setting.values.index(setting.value)) + box.setMinimumWidth(145) + + layout.addWidget(box) + + elif setting.type == "power_of_two": + + box = QComboBox() + resolutions = [str(2**i) for i in range(1, 32) if 2**i >= setting.minval and 2**i <= setting.maxval] + for value in resolutions: + box.addItem(value) + qt_connect(box, "currentIndexChanged(QString)", + partial(self._on_setting_power_of_two_changed, setting_id)) + box.setCurrentIndex(resolutions.index(str(setting.value))) + box.setMinimumWidth(145) + layout.addWidget(box) + + elif setting.type == "sample_sequence": + + box = QComboBox() + for value in setting.sequences: + box.addItem(value) + qt_connect(box, "currentIndexChanged(QString)", + partial(self._on_setting_enum_changed, setting_id)) + box.setCurrentIndex(setting.sequences.index(str(setting.value))) + box.setMinimumWidth(145) + layout.addWidget(box) + + elif setting.type == "path": + + label = QLabel() + display_file = setting.value.replace("\\", "/").split("/")[-1] + + desc_font = QFont() + desc_font.setPointSize(7) + desc_font.setFamily("Roboto") + + label.setText(display_file) + label.setFont(desc_font) + + button = QPushButton() + button.setText("Choose File ...") + qt_connect(button, "clicked()", partial( + self._choose_path, setting_id, setting, (label,))) + + layout.addWidget(label) + layout.addWidget(button) + + else: + print("ERROR: Unkown setting type:", setting.type) + + return widget + + def _set_settings_visible(self, flag): + """ Sets whether the settings panel is visible or not """ + if flag: + self.frame_details.show() + else: + self.frame_details.hide() + + def _load_plugin_list(self): + """ Reloads the whole plugin list """ + print("Loading plugin list") + + # Reset selection + self._current_plugin = None + self._current_plugin_instance = None + self._set_settings_visible(False) + + # Plugins are all plugins in the plugins directory + self._plugin_mgr.unload() + self._plugin_mgr.load() + + self.lst_plugins.clear() + plugins = sorted(iteritems(self._plugin_mgr.instances), key=lambda plg: plg[1].name) + + + item_font = QFont() + item_font.setBold(False) + item_font.setPointSize(10) + + for plugin_id, instance in plugins: + + item = QListWidgetItem() + item.setText(" " + instance.name) + item.setFont(item_font) + + if self._plugin_mgr.is_plugin_enabled(plugin_id): + item.setCheckState(Qt.Checked) + else: + item.setCheckState(Qt.Unchecked) + + item._plugin_id = plugin_id + self.lst_plugins.addItem(item) + + self.lst_plugins.setCurrentRow(0) + +# Start application +app = QApplication(sys.argv) +qt_register_fonts() +configurator = PluginConfigurator() +configurator.show() +app.exec_() diff --git a/toolkit/plugin_configurator/ui/__init__.py b/toolkit/plugin_configurator/ui/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/toolkit/plugin_configurator/ui/compile_ui_qt4.bat b/toolkit/plugin_configurator/ui/compile_ui_qt4.bat new file mode 100644 index 0000000..2392f6a --- /dev/null +++ b/toolkit/plugin_configurator/ui/compile_ui_qt4.bat @@ -0,0 +1,9 @@ +@echo off + +rem Adjust the path to match your PyQt4 installation +SET PYQTPATH="C:\Projekte\Panda3D\built_x64\python\Lib\site-packages\PyQt4" + +python -m PyQt4.uic.pyuic --from-imports main_window.ui -o main_window_generated.py +"%PYQTPATH%\pyrcc4.exe" -py3 resources.qrc -o resources_rc.py + +pause diff --git a/toolkit/plugin_configurator/ui/compile_ui_qt5.bat b/toolkit/plugin_configurator/ui/compile_ui_qt5.bat new file mode 100644 index 0000000..202b514 --- /dev/null +++ b/toolkit/plugin_configurator/ui/compile_ui_qt5.bat @@ -0,0 +1,6 @@ +@echo off + +python -m PyQt5.uic.pyuic --from-imports main_window.ui -o main_window_generated.py +python -m PyQt5.pyrcc_main resources.qrc -o resources_rc.py + +pause diff --git a/toolkit/plugin_configurator/ui/main_window.ui b/toolkit/plugin_configurator/ui/main_window.ui new file mode 100644 index 0000000..baec7a1 --- /dev/null +++ b/toolkit/plugin_configurator/ui/main_window.ui @@ -0,0 +1,1845 @@ + + + MainWindow + + + + 0 + 0 + 1000 + 680 + + + + + 0 + 0 + + + + + 1000 + 680 + + + + + 1000 + 680 + + + + Plugin Configurator + + + + :/icon/res/icon.png:/icon/res/icon.png + + + QMainWindow { background: #fff;} +*, QLabel { font-family: Roboto; font-weight: 300; } + +QScrollBar { + background: #eee; +} + + +QScrollBar:vertical { + width: 9px; + margin: 0; + } + + QScrollBar::handle:vertical { + min-height: 15px; + background: #aaa; + + } + + + QScrollBar::handle:vertical:hover { + + background: #999; + + } + QScrollBar::add-line:vertical { + } + + QScrollBar::sub-line:vertical { + } + + + QScrollBar::add-page:vertical { + background: #ddd; + + } + QScrollBar::sub-page:vertical { + background: #ddd; + } + + + + + + + 20 + 80 + 251 + 531 + + + + QListWidget::item { +padding: 8px 7px 5px; +background: #ddd; +outline: 0 !important; +margin-bottom: 1px; +margin-right: 10px; +color: #777; +font-weight: 500; +border: 0; +border-radius: 0; +} + +QListWidget::item:hover { +background: #ccc; +} + +QListWidget::item:selected { +background: #555; +color: #eee; +} + +QListWidget { +padding: 0; +color: #eee; +background: transparent; +/* +background: #222; +padding: 5px 8px; +border: 1px solid #444; +*/ +} + +* { +outline: 0; +} + + + + + QFrame::NoFrame + + + 0 + + + + Ambient Occlusion + + + + + Another Ite + + + + + Bloom + + + + + Volumetric Clouds + + + + + Depth of Field + + + + + Environment Probes + + + + + FXAA (Antialiasing) + + + + + SKAA + + + + + Motion Blur + + + + + PSSM Shadows + + + + + Atmospheric Scattering + + + + + Skin Shading + + + + + SMAA (Antialiasing) + + + + + Screen Space Reflections + + + + + Volumetric Lighting + + + + + VXGI + + + + + Item 346 + + + + + Other Item + + + + + Other Item to force scrollbars + + + + + + + 281 + 60 + 721 + 621 + + + + + + + + + 255 + 255 + 255 + + + + + + + 229 + 229 + 229 + + + + + + + 63 + 63 + 63 + + + + + + + 52 + 52 + 52 + + + + + + + 21 + 21 + 21 + + + + + + + 28 + 28 + 28 + + + + + + + 255 + 255 + 255 + + + + + + + 255 + 255 + 255 + + + + + + + 255 + 255 + 255 + + + + + + + 229 + 229 + 229 + + + + + + + 229 + 229 + 229 + + + + + + + 0 + 0 + 0 + + + + + + + 21 + 21 + 21 + + + + + + + 255 + 255 + 220 + + + + + + + 0 + 0 + 0 + + + + + + + + + 255 + 255 + 255 + + + + + + + 229 + 229 + 229 + + + + + + + 63 + 63 + 63 + + + + + + + 52 + 52 + 52 + + + + + + + 21 + 21 + 21 + + + + + + + 28 + 28 + 28 + + + + + + + 255 + 255 + 255 + + + + + + + 255 + 255 + 255 + + + + + + + 255 + 255 + 255 + + + + + + + 229 + 229 + 229 + + + + + + + 229 + 229 + 229 + + + + + + + 0 + 0 + 0 + + + + + + + 21 + 21 + 21 + + + + + + + 255 + 255 + 220 + + + + + + + 0 + 0 + 0 + + + + + + + + + 21 + 21 + 21 + + + + + + + 229 + 229 + 229 + + + + + + + 63 + 63 + 63 + + + + + + + 52 + 52 + 52 + + + + + + + 21 + 21 + 21 + + + + + + + 28 + 28 + 28 + + + + + + + 21 + 21 + 21 + + + + + + + 255 + 255 + 255 + + + + + + + 21 + 21 + 21 + + + + + + + 229 + 229 + 229 + + + + + + + 229 + 229 + 229 + + + + + + + 0 + 0 + 0 + + + + + + + 42 + 42 + 42 + + + + + + + 255 + 255 + 220 + + + + + + + 0 + 0 + 0 + + + + + + + + false + + + #frame_details { background: #e5e5e5; } + + + QFrame::NoFrame + + + QFrame::Plain + + + 1 + + + + + 20 + 40 + 391 + 21 + + + + + + + + + 255 + 151 + 25 + + + + + + + 236 + 236 + 236 + + + + + + + 255 + 151 + 25 + + + + + + + 255 + 151 + 25 + + + + + + + 236 + 236 + 236 + + + + + + + 236 + 236 + 236 + + + + + + + + + 255 + 151 + 25 + + + + + + + 236 + 236 + 236 + + + + + + + 255 + 151 + 25 + + + + + + + 255 + 151 + 25 + + + + + + + 236 + 236 + 236 + + + + + + + 236 + 236 + 236 + + + + + + + + + 255 + 151 + 25 + + + + + + + 236 + 236 + 236 + + + + + + + 255 + 151 + 25 + + + + + + + 255 + 151 + 25 + + + + + + + 236 + 236 + 236 + + + + + + + 236 + 236 + 236 + + + + + + + + + Roboto + 75 + true + + + + color: #ff9719; border: 0; border-radius: 4px; font-weight: bold; + + + version 0.1 by some author + + + Qt::PlainText + + + Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter + + + + + + 20 + 60 + 441 + 51 + + + + color: #777; border: 0; font-size: 11px; + + + This is a fancy description +It shows information about the plugin and maybe +a website or so. + + + Qt::PlainText + + + Qt::AlignLeading|Qt::AlignLeft|Qt::AlignTop + + + true + + + + + + 20 + 110 + 681 + 491 + + + + + + + + + 0 + 0 + 0 + + + + + + + 240 + 240 + 240 + + + + + + + 255 + 255 + 255 + + + + + + + 247 + 247 + 247 + + + + + + + 120 + 120 + 120 + + + + + + + 160 + 160 + 160 + + + + + + + 0 + 0 + 0 + + + + + + + 255 + 255 + 255 + + + + + + + 0 + 0 + 0 + + + + + + + 255 + 255 + 255 + + + + + + + 240 + 240 + 240 + + + + + + + 0 + 0 + 0 + + + + + + + 247 + 247 + 247 + + + + + + + 255 + 255 + 220 + + + + + + + 0 + 0 + 0 + + + + + + + + + 0 + 0 + 0 + + + + + + + 240 + 240 + 240 + + + + + + + 255 + 255 + 255 + + + + + + + 247 + 247 + 247 + + + + + + + 120 + 120 + 120 + + + + + + + 160 + 160 + 160 + + + + + + + 0 + 0 + 0 + + + + + + + 255 + 255 + 255 + + + + + + + 0 + 0 + 0 + + + + + + + 255 + 255 + 255 + + + + + + + 240 + 240 + 240 + + + + + + + 0 + 0 + 0 + + + + + + + 247 + 247 + 247 + + + + + + + 255 + 255 + 220 + + + + + + + 0 + 0 + 0 + + + + + + + + + 120 + 120 + 120 + + + + + + + 240 + 240 + 240 + + + + + + + 255 + 255 + 255 + + + + + + + 247 + 247 + 247 + + + + + + + 120 + 120 + 120 + + + + + + + 160 + 160 + 160 + + + + + + + 120 + 120 + 120 + + + + + + + 255 + 255 + 255 + + + + + + + 120 + 120 + 120 + + + + + + + 240 + 240 + 240 + + + + + + + 240 + 240 + 240 + + + + + + + 0 + 0 + 0 + + + + + + + 240 + 240 + 240 + + + + + + + 255 + 255 + 220 + + + + + + + 0 + 0 + 0 + + + + + + + + + Roboto + -1 + 37 + false + + + + QTableWidget { border: 1px solid #ccc; font-family: Roboto; font-size: 11px; } + + + QFrame::StyledPanel + + + Qt::ScrollBarAsNeeded + + + Qt::ScrollBarAlwaysOff + + + QAbstractItemView::NoEditTriggers + + + false + + + false + + + true + + + QAbstractItemView::NoSelection + + + QAbstractItemView::SelectRows + + + Qt::ElideNone + + + QAbstractItemView::ScrollPerPixel + + + QAbstractItemView::ScrollPerPixel + + + false + + + Qt::NoPen + + + true + + + true + + + true + + + false + + + true + + + false + + + true + + + false + + + false + + + 45 + + + false + + + false + + + + Row + + + AlignHCenter|AlignVCenter|AlignCenter + + + + + Row2 + + + + + Setting + + + + + Default + + + AlignHCenter|AlignVCenter|AlignCenter + + + + + Current Value + + + + + Description + + + + + Long setting name which requires + + + + + DefaultRow0 + + + + + CurrentRow0 + + + + + DescRow0 + + + + + DefaultRow1 + + + + + CurrentRow1 + + + + + aasd\n\nsdf\n\ndfdfG\n\nfgaasd\n\nsdf\n\ndfdfG\n\nfgaasd\n\nsdf\n\ndfdfG\n\nfgaasd\n\nsdf\n\ndfdfG\n\nfgaasd\n\nsdf\n\ndfdfG\n\nfgaasd\n\nsdf\n\ndfdfG\n\nfgaasd\n\nsdf\n\ndfdfG\n\nfgaasd\n\nsdf\n\ndfdfG\n\nfgaasd\n\nsdf\n\ndfdfG\n\nfgaasd\n\nsdf\n\ndfdfG\n\nfgaasd\n\nsdf\n\ndfdfG\n\nfgaasd\n\nsdf\n\ndfdfG\n\nfgaasd\n\nsdf\n\ndfdfG\n\nfgaasd\n\nsdf\n\ndfdfG\n\nfgaasd\n\nsdf\n\ndfdfG\n\nfgaasd\n\nsdf\n\ndfdfG\n\nfgaasd\n\nsdf\n\ndfdfG\n\nfgaasd\n\nsdf\n\ndfdfG\n\nfgaasd\n\nsdf\n\ndfdfG\n\nfgaasd\n\nsdf\n\ndfdfG\n\nfgaasd\n\nsdf\n\ndfdfG\n\nfgaasd\n\nsdf\n\ndfdfG\n\nfgaasd\n\nsdf\n\ndfdfG\n\nfgaasd\n\nsdf\n\ndfdfG\n\nfgaasd\n\nsdf\n\ndfdfG\n\nfgaasd\n\nsdf\n\ndfdfG\n\nfgaasd\n\nsdf\n\ndfdfG\n\nfgaasd\n\nsdf\n\ndfdfG\n\nfgaasd\n\nsdf\n\ndfdfG\n\nfgaasd\n\nsdf\n\ndfdfG\n\nfgaasd\n\nsdf\n\ndfdfG\n\nfgaasd\n\nsdf\n\ndfdfG\n\nfgaasd\n\nsdf\n\ndfdfG\n\nfgaasd\n\nsdf\n\ndfdfG\n\nfgaasd\n\nsdf\n\ndfdfG\n\nfgaasd\n\nsdf\n\ndfdfG\n\nfgaasd\n\nsdf\n\ndfdfG\n\nfgaasd\n\nsdf\n\ndfdfG\n\nfgaasd\n\nsdf\n\ndfdfG\n\nfgaasd\n\nsdf\n\ndfdfG\n\nfgaasd\n\nsdf\n\ndfdfG\n\nfgaasd\n\nsdf\n\ndfdfG\n\nfgaasd\n\nsdf\n\ndfdfG\n\nfgaasd\n\nsdf\n\ndfdfG\n\nfgaasd\n\nsdf\n\ndfdfG\n\nfgaasd\n\nsdf\n\ndfdfG\n\nfgaasd\n\nsdf\n\ndfdfG\n\nfgaasd\n\nsdf\n\ndfdfG\n\nfgaasd\n\nsdf\n\ndfdfG\n\nfgaasd\n\nsdf\n\ndfdfG\n\nfgaasd\n\nsdf\n\ndfdfG\n\nfgaasd\n\nsdf\n\ndfdfG\n\nfgaasd\n\nsdf\n\ndfdfG\n\nfgaasd\n\nsdf\n\ndfdfG\n\nfg + + + + + + + 20 + 20 + 391 + 21 + + + + + Roboto + -1 + 37 + false + + + + color: #555; border: 0; font-size: 15px; + + + Ambient Occlusion + + + Qt::RichText + + + + + + 520 + 20 + 180 + 31 + + + + QPushButton { +color: #eee; +background: #666; +border: 0; +} + +QPushButton:hover { + background: #555; +} + +QPushButton:pressed { + background: #111; +} + + + Reset Settings of this Plugin + + + + + + + 0 + 60 + 281 + 621 + + + + false + + + QFrame {background: #eee;} + + + QFrame::StyledPanel + + + QFrame::Raised + + + + + 20 + 560 + 251 + 51 + + + + + + + + + 153 + 153 + 153 + + + + + + + 238 + 238 + 238 + + + + + + + 153 + 153 + 153 + + + + + + + 153 + 153 + 153 + + + + + + + 238 + 238 + 238 + + + + + + + 238 + 238 + 238 + + + + + + + + + 153 + 153 + 153 + + + + + + + 238 + 238 + 238 + + + + + + + 153 + 153 + 153 + + + + + + + 153 + 153 + 153 + + + + + + + 238 + 238 + 238 + + + + + + + 238 + 238 + 238 + + + + + + + + + 153 + 153 + 153 + + + + + + + 238 + 238 + 238 + + + + + + + 153 + 153 + 153 + + + + + + + 153 + 153 + 153 + + + + + + + 238 + 238 + 238 + + + + + + + 238 + 238 + 238 + + + + + + + + + Roboto + 37 + false + + + + border-top: 1px dotted #aaa; color: #999; padding: 0; + + + Hint: Settings with a gray color require a pipeline restart when changed. + + + Qt::PlainText + + + false + + + Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter + + + true + + + + + + + 687 + 18 + 294 + 28 + + + + + Roboto + -1 + 37 + false + + + + false + + + background: #ff9719; color: #eee; padding: 5px; border: 0; font-size: 12px; + + + Pipeline needs to be restarted to apply all changes! + + + Qt::AlignCenter + + + + + + 20 + 25 + 261 + 31 + + + + font-size: 20px; color: #ff9719; +font-weight: 100; + + + PLUGIN CONFIGURATOR + + + + + + 20 + 6 + 261 + 31 + + + + font-size: 13px; +color: #aaa; +font-weight: 600; + + + RENDER PIPELINE + + + frame + lst_plugins + lbl_restart_pipeline + frame_details + label + label_9 + + + + + + + diff --git a/toolkit/plugin_configurator/ui/main_window_generated.py b/toolkit/plugin_configurator/ui/main_window_generated.py new file mode 100644 index 0000000..3b8004c --- /dev/null +++ b/toolkit/plugin_configurator/ui/main_window_generated.py @@ -0,0 +1,790 @@ +# -*- coding: utf-8 -*- + +# Form implementation generated from reading ui file 'main_window.ui' +# +# Created by: PyQt5 UI code generator 5.7 +# +# WARNING! All changes made in this file will be lost! + +from PyQt5 import QtCore, QtGui, QtWidgets + +class Ui_MainWindow(object): + def setupUi(self, MainWindow): + MainWindow.setObjectName("MainWindow") + MainWindow.resize(1000, 680) + sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Fixed, QtWidgets.QSizePolicy.Fixed) + sizePolicy.setHorizontalStretch(0) + sizePolicy.setVerticalStretch(0) + sizePolicy.setHeightForWidth(MainWindow.sizePolicy().hasHeightForWidth()) + MainWindow.setSizePolicy(sizePolicy) + MainWindow.setMinimumSize(QtCore.QSize(1000, 680)) + MainWindow.setMaximumSize(QtCore.QSize(1000, 680)) + icon = QtGui.QIcon() + icon.addPixmap(QtGui.QPixmap(":/icon/res/icon.png"), QtGui.QIcon.Normal, QtGui.QIcon.Off) + MainWindow.setWindowIcon(icon) + MainWindow.setStyleSheet("QMainWindow { background: #fff;}\n" +"*, QLabel { font-family: Roboto; font-weight: 300; }\n" +"\n" +"QScrollBar {\n" +" background: #eee;\n" +"}\n" +"\n" +"\n" +"QScrollBar:vertical {\n" +" width: 9px;\n" +" margin: 0;\n" +" }\n" +"\n" +" QScrollBar::handle:vertical {\n" +" min-height: 15px;\n" +" background: #aaa;\n" +"\n" +" }\n" +"\n" +"\n" +" QScrollBar::handle:vertical:hover {\n" +" \n" +" background: #999;\n" +"\n" +" }\n" +" QScrollBar::add-line:vertical {\n" +" }\n" +"\n" +" QScrollBar::sub-line:vertical {\n" +" }\n" +"\n" +"\n" +" QScrollBar::add-page:vertical {\n" +" background: #ddd;\n" +"\n" +" }\n" +" QScrollBar::sub-page:vertical {\n" +" background: #ddd;\n" +" }\n" +"") + self.centralwidget = QtWidgets.QWidget(MainWindow) + self.centralwidget.setObjectName("centralwidget") + self.lst_plugins = QtWidgets.QListWidget(self.centralwidget) + self.lst_plugins.setGeometry(QtCore.QRect(20, 80, 251, 531)) + self.lst_plugins.setStyleSheet("QListWidget::item {\n" +"padding: 8px 7px 5px;\n" +"background: #ddd;\n" +"outline: 0 !important;\n" +"margin-bottom: 1px;\n" +"margin-right: 10px;\n" +"color: #777;\n" +"font-weight: 500;\n" +"border: 0;\n" +"border-radius: 0;\n" +"}\n" +"\n" +"QListWidget::item:hover {\n" +"background: #ccc;\n" +"}\n" +"\n" +"QListWidget::item:selected {\n" +"background: #555;\n" +"color: #eee;\n" +"}\n" +"\n" +"QListWidget {\n" +"padding: 0;\n" +"color: #eee;\n" +"background: transparent;\n" +"/*\n" +"background: #222;\n" +"padding: 5px 8px;\n" +"border: 1px solid #444;\n" +"*/\n" +"}\n" +"\n" +"* {\n" +"outline: 0;\n" +"}\n" +"\n" +"") + self.lst_plugins.setFrameShape(QtWidgets.QFrame.NoFrame) + self.lst_plugins.setLineWidth(0) + self.lst_plugins.setObjectName("lst_plugins") + item = QtWidgets.QListWidgetItem() + self.lst_plugins.addItem(item) + item = QtWidgets.QListWidgetItem() + self.lst_plugins.addItem(item) + item = QtWidgets.QListWidgetItem() + self.lst_plugins.addItem(item) + item = QtWidgets.QListWidgetItem() + self.lst_plugins.addItem(item) + item = QtWidgets.QListWidgetItem() + self.lst_plugins.addItem(item) + item = QtWidgets.QListWidgetItem() + self.lst_plugins.addItem(item) + item = QtWidgets.QListWidgetItem() + self.lst_plugins.addItem(item) + item = QtWidgets.QListWidgetItem() + self.lst_plugins.addItem(item) + item = QtWidgets.QListWidgetItem() + self.lst_plugins.addItem(item) + item = QtWidgets.QListWidgetItem() + self.lst_plugins.addItem(item) + item = QtWidgets.QListWidgetItem() + self.lst_plugins.addItem(item) + item = QtWidgets.QListWidgetItem() + self.lst_plugins.addItem(item) + item = QtWidgets.QListWidgetItem() + self.lst_plugins.addItem(item) + item = QtWidgets.QListWidgetItem() + self.lst_plugins.addItem(item) + item = QtWidgets.QListWidgetItem() + self.lst_plugins.addItem(item) + item = QtWidgets.QListWidgetItem() + self.lst_plugins.addItem(item) + item = QtWidgets.QListWidgetItem() + self.lst_plugins.addItem(item) + item = QtWidgets.QListWidgetItem() + self.lst_plugins.addItem(item) + item = QtWidgets.QListWidgetItem() + self.lst_plugins.addItem(item) + self.frame_details = QtWidgets.QFrame(self.centralwidget) + self.frame_details.setGeometry(QtCore.QRect(281, 60, 721, 621)) + palette = QtGui.QPalette() + brush = QtGui.QBrush(QtGui.QColor(255, 255, 255)) + brush.setStyle(QtCore.Qt.SolidPattern) + palette.setBrush(QtGui.QPalette.Active, QtGui.QPalette.WindowText, brush) + brush = QtGui.QBrush(QtGui.QColor(229, 229, 229)) + brush.setStyle(QtCore.Qt.SolidPattern) + palette.setBrush(QtGui.QPalette.Active, QtGui.QPalette.Button, brush) + brush = QtGui.QBrush(QtGui.QColor(63, 63, 63)) + brush.setStyle(QtCore.Qt.SolidPattern) + palette.setBrush(QtGui.QPalette.Active, QtGui.QPalette.Light, brush) + brush = QtGui.QBrush(QtGui.QColor(52, 52, 52)) + brush.setStyle(QtCore.Qt.SolidPattern) + palette.setBrush(QtGui.QPalette.Active, QtGui.QPalette.Midlight, brush) + brush = QtGui.QBrush(QtGui.QColor(21, 21, 21)) + brush.setStyle(QtCore.Qt.SolidPattern) + palette.setBrush(QtGui.QPalette.Active, QtGui.QPalette.Dark, brush) + brush = QtGui.QBrush(QtGui.QColor(28, 28, 28)) + brush.setStyle(QtCore.Qt.SolidPattern) + palette.setBrush(QtGui.QPalette.Active, QtGui.QPalette.Mid, brush) + brush = QtGui.QBrush(QtGui.QColor(255, 255, 255)) + brush.setStyle(QtCore.Qt.SolidPattern) + palette.setBrush(QtGui.QPalette.Active, QtGui.QPalette.Text, brush) + brush = QtGui.QBrush(QtGui.QColor(255, 255, 255)) + brush.setStyle(QtCore.Qt.SolidPattern) + palette.setBrush(QtGui.QPalette.Active, QtGui.QPalette.BrightText, brush) + brush = QtGui.QBrush(QtGui.QColor(255, 255, 255)) + brush.setStyle(QtCore.Qt.SolidPattern) + palette.setBrush(QtGui.QPalette.Active, QtGui.QPalette.ButtonText, brush) + brush = QtGui.QBrush(QtGui.QColor(229, 229, 229)) + brush.setStyle(QtCore.Qt.SolidPattern) + palette.setBrush(QtGui.QPalette.Active, QtGui.QPalette.Base, brush) + brush = QtGui.QBrush(QtGui.QColor(229, 229, 229)) + brush.setStyle(QtCore.Qt.SolidPattern) + palette.setBrush(QtGui.QPalette.Active, QtGui.QPalette.Window, brush) + brush = QtGui.QBrush(QtGui.QColor(0, 0, 0)) + brush.setStyle(QtCore.Qt.SolidPattern) + palette.setBrush(QtGui.QPalette.Active, QtGui.QPalette.Shadow, brush) + brush = QtGui.QBrush(QtGui.QColor(21, 21, 21)) + brush.setStyle(QtCore.Qt.SolidPattern) + palette.setBrush(QtGui.QPalette.Active, QtGui.QPalette.AlternateBase, brush) + brush = QtGui.QBrush(QtGui.QColor(255, 255, 220)) + brush.setStyle(QtCore.Qt.SolidPattern) + palette.setBrush(QtGui.QPalette.Active, QtGui.QPalette.ToolTipBase, brush) + brush = QtGui.QBrush(QtGui.QColor(0, 0, 0)) + brush.setStyle(QtCore.Qt.SolidPattern) + palette.setBrush(QtGui.QPalette.Active, QtGui.QPalette.ToolTipText, brush) + brush = QtGui.QBrush(QtGui.QColor(255, 255, 255)) + brush.setStyle(QtCore.Qt.SolidPattern) + palette.setBrush(QtGui.QPalette.Inactive, QtGui.QPalette.WindowText, brush) + brush = QtGui.QBrush(QtGui.QColor(229, 229, 229)) + brush.setStyle(QtCore.Qt.SolidPattern) + palette.setBrush(QtGui.QPalette.Inactive, QtGui.QPalette.Button, brush) + brush = QtGui.QBrush(QtGui.QColor(63, 63, 63)) + brush.setStyle(QtCore.Qt.SolidPattern) + palette.setBrush(QtGui.QPalette.Inactive, QtGui.QPalette.Light, brush) + brush = QtGui.QBrush(QtGui.QColor(52, 52, 52)) + brush.setStyle(QtCore.Qt.SolidPattern) + palette.setBrush(QtGui.QPalette.Inactive, QtGui.QPalette.Midlight, brush) + brush = QtGui.QBrush(QtGui.QColor(21, 21, 21)) + brush.setStyle(QtCore.Qt.SolidPattern) + palette.setBrush(QtGui.QPalette.Inactive, QtGui.QPalette.Dark, brush) + brush = QtGui.QBrush(QtGui.QColor(28, 28, 28)) + brush.setStyle(QtCore.Qt.SolidPattern) + palette.setBrush(QtGui.QPalette.Inactive, QtGui.QPalette.Mid, brush) + brush = QtGui.QBrush(QtGui.QColor(255, 255, 255)) + brush.setStyle(QtCore.Qt.SolidPattern) + palette.setBrush(QtGui.QPalette.Inactive, QtGui.QPalette.Text, brush) + brush = QtGui.QBrush(QtGui.QColor(255, 255, 255)) + brush.setStyle(QtCore.Qt.SolidPattern) + palette.setBrush(QtGui.QPalette.Inactive, QtGui.QPalette.BrightText, brush) + brush = QtGui.QBrush(QtGui.QColor(255, 255, 255)) + brush.setStyle(QtCore.Qt.SolidPattern) + palette.setBrush(QtGui.QPalette.Inactive, QtGui.QPalette.ButtonText, brush) + brush = QtGui.QBrush(QtGui.QColor(229, 229, 229)) + brush.setStyle(QtCore.Qt.SolidPattern) + palette.setBrush(QtGui.QPalette.Inactive, QtGui.QPalette.Base, brush) + brush = QtGui.QBrush(QtGui.QColor(229, 229, 229)) + brush.setStyle(QtCore.Qt.SolidPattern) + palette.setBrush(QtGui.QPalette.Inactive, QtGui.QPalette.Window, brush) + brush = QtGui.QBrush(QtGui.QColor(0, 0, 0)) + brush.setStyle(QtCore.Qt.SolidPattern) + palette.setBrush(QtGui.QPalette.Inactive, QtGui.QPalette.Shadow, brush) + brush = QtGui.QBrush(QtGui.QColor(21, 21, 21)) + brush.setStyle(QtCore.Qt.SolidPattern) + palette.setBrush(QtGui.QPalette.Inactive, QtGui.QPalette.AlternateBase, brush) + brush = QtGui.QBrush(QtGui.QColor(255, 255, 220)) + brush.setStyle(QtCore.Qt.SolidPattern) + palette.setBrush(QtGui.QPalette.Inactive, QtGui.QPalette.ToolTipBase, brush) + brush = QtGui.QBrush(QtGui.QColor(0, 0, 0)) + brush.setStyle(QtCore.Qt.SolidPattern) + palette.setBrush(QtGui.QPalette.Inactive, QtGui.QPalette.ToolTipText, brush) + brush = QtGui.QBrush(QtGui.QColor(21, 21, 21)) + brush.setStyle(QtCore.Qt.SolidPattern) + palette.setBrush(QtGui.QPalette.Disabled, QtGui.QPalette.WindowText, brush) + brush = QtGui.QBrush(QtGui.QColor(229, 229, 229)) + brush.setStyle(QtCore.Qt.SolidPattern) + palette.setBrush(QtGui.QPalette.Disabled, QtGui.QPalette.Button, brush) + brush = QtGui.QBrush(QtGui.QColor(63, 63, 63)) + brush.setStyle(QtCore.Qt.SolidPattern) + palette.setBrush(QtGui.QPalette.Disabled, QtGui.QPalette.Light, brush) + brush = QtGui.QBrush(QtGui.QColor(52, 52, 52)) + brush.setStyle(QtCore.Qt.SolidPattern) + palette.setBrush(QtGui.QPalette.Disabled, QtGui.QPalette.Midlight, brush) + brush = QtGui.QBrush(QtGui.QColor(21, 21, 21)) + brush.setStyle(QtCore.Qt.SolidPattern) + palette.setBrush(QtGui.QPalette.Disabled, QtGui.QPalette.Dark, brush) + brush = QtGui.QBrush(QtGui.QColor(28, 28, 28)) + brush.setStyle(QtCore.Qt.SolidPattern) + palette.setBrush(QtGui.QPalette.Disabled, QtGui.QPalette.Mid, brush) + brush = QtGui.QBrush(QtGui.QColor(21, 21, 21)) + brush.setStyle(QtCore.Qt.SolidPattern) + palette.setBrush(QtGui.QPalette.Disabled, QtGui.QPalette.Text, brush) + brush = QtGui.QBrush(QtGui.QColor(255, 255, 255)) + brush.setStyle(QtCore.Qt.SolidPattern) + palette.setBrush(QtGui.QPalette.Disabled, QtGui.QPalette.BrightText, brush) + brush = QtGui.QBrush(QtGui.QColor(21, 21, 21)) + brush.setStyle(QtCore.Qt.SolidPattern) + palette.setBrush(QtGui.QPalette.Disabled, QtGui.QPalette.ButtonText, brush) + brush = QtGui.QBrush(QtGui.QColor(229, 229, 229)) + brush.setStyle(QtCore.Qt.SolidPattern) + palette.setBrush(QtGui.QPalette.Disabled, QtGui.QPalette.Base, brush) + brush = QtGui.QBrush(QtGui.QColor(229, 229, 229)) + brush.setStyle(QtCore.Qt.SolidPattern) + palette.setBrush(QtGui.QPalette.Disabled, QtGui.QPalette.Window, brush) + brush = QtGui.QBrush(QtGui.QColor(0, 0, 0)) + brush.setStyle(QtCore.Qt.SolidPattern) + palette.setBrush(QtGui.QPalette.Disabled, QtGui.QPalette.Shadow, brush) + brush = QtGui.QBrush(QtGui.QColor(42, 42, 42)) + brush.setStyle(QtCore.Qt.SolidPattern) + palette.setBrush(QtGui.QPalette.Disabled, QtGui.QPalette.AlternateBase, brush) + brush = QtGui.QBrush(QtGui.QColor(255, 255, 220)) + brush.setStyle(QtCore.Qt.SolidPattern) + palette.setBrush(QtGui.QPalette.Disabled, QtGui.QPalette.ToolTipBase, brush) + brush = QtGui.QBrush(QtGui.QColor(0, 0, 0)) + brush.setStyle(QtCore.Qt.SolidPattern) + palette.setBrush(QtGui.QPalette.Disabled, QtGui.QPalette.ToolTipText, brush) + self.frame_details.setPalette(palette) + self.frame_details.setAutoFillBackground(False) + self.frame_details.setStyleSheet("#frame_details { background: #e5e5e5; }") + self.frame_details.setFrameShape(QtWidgets.QFrame.NoFrame) + self.frame_details.setFrameShadow(QtWidgets.QFrame.Plain) + self.frame_details.setLineWidth(1) + self.frame_details.setObjectName("frame_details") + self.lbl_plugin_version = QtWidgets.QLabel(self.frame_details) + self.lbl_plugin_version.setGeometry(QtCore.QRect(20, 40, 391, 21)) + palette = QtGui.QPalette() + brush = QtGui.QBrush(QtGui.QColor(255, 151, 25)) + brush.setStyle(QtCore.Qt.SolidPattern) + palette.setBrush(QtGui.QPalette.Active, QtGui.QPalette.WindowText, brush) + brush = QtGui.QBrush(QtGui.QColor(236, 236, 236)) + brush.setStyle(QtCore.Qt.SolidPattern) + palette.setBrush(QtGui.QPalette.Active, QtGui.QPalette.Button, brush) + brush = QtGui.QBrush(QtGui.QColor(255, 151, 25)) + brush.setStyle(QtCore.Qt.SolidPattern) + palette.setBrush(QtGui.QPalette.Active, QtGui.QPalette.Text, brush) + brush = QtGui.QBrush(QtGui.QColor(255, 151, 25)) + brush.setStyle(QtCore.Qt.SolidPattern) + palette.setBrush(QtGui.QPalette.Active, QtGui.QPalette.ButtonText, brush) + brush = QtGui.QBrush(QtGui.QColor(236, 236, 236)) + brush.setStyle(QtCore.Qt.SolidPattern) + palette.setBrush(QtGui.QPalette.Active, QtGui.QPalette.Base, brush) + brush = QtGui.QBrush(QtGui.QColor(236, 236, 236)) + brush.setStyle(QtCore.Qt.SolidPattern) + palette.setBrush(QtGui.QPalette.Active, QtGui.QPalette.Window, brush) + brush = QtGui.QBrush(QtGui.QColor(255, 151, 25)) + brush.setStyle(QtCore.Qt.SolidPattern) + palette.setBrush(QtGui.QPalette.Inactive, QtGui.QPalette.WindowText, brush) + brush = QtGui.QBrush(QtGui.QColor(236, 236, 236)) + brush.setStyle(QtCore.Qt.SolidPattern) + palette.setBrush(QtGui.QPalette.Inactive, QtGui.QPalette.Button, brush) + brush = QtGui.QBrush(QtGui.QColor(255, 151, 25)) + brush.setStyle(QtCore.Qt.SolidPattern) + palette.setBrush(QtGui.QPalette.Inactive, QtGui.QPalette.Text, brush) + brush = QtGui.QBrush(QtGui.QColor(255, 151, 25)) + brush.setStyle(QtCore.Qt.SolidPattern) + palette.setBrush(QtGui.QPalette.Inactive, QtGui.QPalette.ButtonText, brush) + brush = QtGui.QBrush(QtGui.QColor(236, 236, 236)) + brush.setStyle(QtCore.Qt.SolidPattern) + palette.setBrush(QtGui.QPalette.Inactive, QtGui.QPalette.Base, brush) + brush = QtGui.QBrush(QtGui.QColor(236, 236, 236)) + brush.setStyle(QtCore.Qt.SolidPattern) + palette.setBrush(QtGui.QPalette.Inactive, QtGui.QPalette.Window, brush) + brush = QtGui.QBrush(QtGui.QColor(255, 151, 25)) + brush.setStyle(QtCore.Qt.SolidPattern) + palette.setBrush(QtGui.QPalette.Disabled, QtGui.QPalette.WindowText, brush) + brush = QtGui.QBrush(QtGui.QColor(236, 236, 236)) + brush.setStyle(QtCore.Qt.SolidPattern) + palette.setBrush(QtGui.QPalette.Disabled, QtGui.QPalette.Button, brush) + brush = QtGui.QBrush(QtGui.QColor(255, 151, 25)) + brush.setStyle(QtCore.Qt.SolidPattern) + palette.setBrush(QtGui.QPalette.Disabled, QtGui.QPalette.Text, brush) + brush = QtGui.QBrush(QtGui.QColor(255, 151, 25)) + brush.setStyle(QtCore.Qt.SolidPattern) + palette.setBrush(QtGui.QPalette.Disabled, QtGui.QPalette.ButtonText, brush) + brush = QtGui.QBrush(QtGui.QColor(236, 236, 236)) + brush.setStyle(QtCore.Qt.SolidPattern) + palette.setBrush(QtGui.QPalette.Disabled, QtGui.QPalette.Base, brush) + brush = QtGui.QBrush(QtGui.QColor(236, 236, 236)) + brush.setStyle(QtCore.Qt.SolidPattern) + palette.setBrush(QtGui.QPalette.Disabled, QtGui.QPalette.Window, brush) + self.lbl_plugin_version.setPalette(palette) + font = QtGui.QFont() + font.setFamily("Roboto") + font.setBold(True) + font.setWeight(75) + self.lbl_plugin_version.setFont(font) + self.lbl_plugin_version.setStyleSheet("color: #ff9719; border: 0; border-radius: 4px; font-weight: bold;") + self.lbl_plugin_version.setTextFormat(QtCore.Qt.PlainText) + self.lbl_plugin_version.setAlignment(QtCore.Qt.AlignLeading|QtCore.Qt.AlignLeft|QtCore.Qt.AlignVCenter) + self.lbl_plugin_version.setObjectName("lbl_plugin_version") + self.lbl_plugin_desc = QtWidgets.QLabel(self.frame_details) + self.lbl_plugin_desc.setGeometry(QtCore.QRect(20, 60, 441, 51)) + self.lbl_plugin_desc.setStyleSheet("color: #777; border: 0; font-size: 11px;") + self.lbl_plugin_desc.setTextFormat(QtCore.Qt.PlainText) + self.lbl_plugin_desc.setAlignment(QtCore.Qt.AlignLeading|QtCore.Qt.AlignLeft|QtCore.Qt.AlignTop) + self.lbl_plugin_desc.setWordWrap(True) + self.lbl_plugin_desc.setObjectName("lbl_plugin_desc") + self.table_plugin_settings = QtWidgets.QTableWidget(self.frame_details) + self.table_plugin_settings.setGeometry(QtCore.QRect(20, 110, 681, 491)) + palette = QtGui.QPalette() + brush = QtGui.QBrush(QtGui.QColor(0, 0, 0)) + brush.setStyle(QtCore.Qt.SolidPattern) + palette.setBrush(QtGui.QPalette.Active, QtGui.QPalette.WindowText, brush) + brush = QtGui.QBrush(QtGui.QColor(240, 240, 240)) + brush.setStyle(QtCore.Qt.SolidPattern) + palette.setBrush(QtGui.QPalette.Active, QtGui.QPalette.Button, brush) + brush = QtGui.QBrush(QtGui.QColor(255, 255, 255)) + brush.setStyle(QtCore.Qt.SolidPattern) + palette.setBrush(QtGui.QPalette.Active, QtGui.QPalette.Light, brush) + brush = QtGui.QBrush(QtGui.QColor(247, 247, 247)) + brush.setStyle(QtCore.Qt.SolidPattern) + palette.setBrush(QtGui.QPalette.Active, QtGui.QPalette.Midlight, brush) + brush = QtGui.QBrush(QtGui.QColor(120, 120, 120)) + brush.setStyle(QtCore.Qt.SolidPattern) + palette.setBrush(QtGui.QPalette.Active, QtGui.QPalette.Dark, brush) + brush = QtGui.QBrush(QtGui.QColor(160, 160, 160)) + brush.setStyle(QtCore.Qt.SolidPattern) + palette.setBrush(QtGui.QPalette.Active, QtGui.QPalette.Mid, brush) + brush = QtGui.QBrush(QtGui.QColor(0, 0, 0)) + brush.setStyle(QtCore.Qt.SolidPattern) + palette.setBrush(QtGui.QPalette.Active, QtGui.QPalette.Text, brush) + brush = QtGui.QBrush(QtGui.QColor(255, 255, 255)) + brush.setStyle(QtCore.Qt.SolidPattern) + palette.setBrush(QtGui.QPalette.Active, QtGui.QPalette.BrightText, brush) + brush = QtGui.QBrush(QtGui.QColor(0, 0, 0)) + brush.setStyle(QtCore.Qt.SolidPattern) + palette.setBrush(QtGui.QPalette.Active, QtGui.QPalette.ButtonText, brush) + brush = QtGui.QBrush(QtGui.QColor(255, 255, 255)) + brush.setStyle(QtCore.Qt.SolidPattern) + palette.setBrush(QtGui.QPalette.Active, QtGui.QPalette.Base, brush) + brush = QtGui.QBrush(QtGui.QColor(240, 240, 240)) + brush.setStyle(QtCore.Qt.SolidPattern) + palette.setBrush(QtGui.QPalette.Active, QtGui.QPalette.Window, brush) + brush = QtGui.QBrush(QtGui.QColor(0, 0, 0)) + brush.setStyle(QtCore.Qt.SolidPattern) + palette.setBrush(QtGui.QPalette.Active, QtGui.QPalette.Shadow, brush) + brush = QtGui.QBrush(QtGui.QColor(247, 247, 247)) + brush.setStyle(QtCore.Qt.SolidPattern) + palette.setBrush(QtGui.QPalette.Active, QtGui.QPalette.AlternateBase, brush) + brush = QtGui.QBrush(QtGui.QColor(255, 255, 220)) + brush.setStyle(QtCore.Qt.SolidPattern) + palette.setBrush(QtGui.QPalette.Active, QtGui.QPalette.ToolTipBase, brush) + brush = QtGui.QBrush(QtGui.QColor(0, 0, 0)) + brush.setStyle(QtCore.Qt.SolidPattern) + palette.setBrush(QtGui.QPalette.Active, QtGui.QPalette.ToolTipText, brush) + brush = QtGui.QBrush(QtGui.QColor(0, 0, 0)) + brush.setStyle(QtCore.Qt.SolidPattern) + palette.setBrush(QtGui.QPalette.Inactive, QtGui.QPalette.WindowText, brush) + brush = QtGui.QBrush(QtGui.QColor(240, 240, 240)) + brush.setStyle(QtCore.Qt.SolidPattern) + palette.setBrush(QtGui.QPalette.Inactive, QtGui.QPalette.Button, brush) + brush = QtGui.QBrush(QtGui.QColor(255, 255, 255)) + brush.setStyle(QtCore.Qt.SolidPattern) + palette.setBrush(QtGui.QPalette.Inactive, QtGui.QPalette.Light, brush) + brush = QtGui.QBrush(QtGui.QColor(247, 247, 247)) + brush.setStyle(QtCore.Qt.SolidPattern) + palette.setBrush(QtGui.QPalette.Inactive, QtGui.QPalette.Midlight, brush) + brush = QtGui.QBrush(QtGui.QColor(120, 120, 120)) + brush.setStyle(QtCore.Qt.SolidPattern) + palette.setBrush(QtGui.QPalette.Inactive, QtGui.QPalette.Dark, brush) + brush = QtGui.QBrush(QtGui.QColor(160, 160, 160)) + brush.setStyle(QtCore.Qt.SolidPattern) + palette.setBrush(QtGui.QPalette.Inactive, QtGui.QPalette.Mid, brush) + brush = QtGui.QBrush(QtGui.QColor(0, 0, 0)) + brush.setStyle(QtCore.Qt.SolidPattern) + palette.setBrush(QtGui.QPalette.Inactive, QtGui.QPalette.Text, brush) + brush = QtGui.QBrush(QtGui.QColor(255, 255, 255)) + brush.setStyle(QtCore.Qt.SolidPattern) + palette.setBrush(QtGui.QPalette.Inactive, QtGui.QPalette.BrightText, brush) + brush = QtGui.QBrush(QtGui.QColor(0, 0, 0)) + brush.setStyle(QtCore.Qt.SolidPattern) + palette.setBrush(QtGui.QPalette.Inactive, QtGui.QPalette.ButtonText, brush) + brush = QtGui.QBrush(QtGui.QColor(255, 255, 255)) + brush.setStyle(QtCore.Qt.SolidPattern) + palette.setBrush(QtGui.QPalette.Inactive, QtGui.QPalette.Base, brush) + brush = QtGui.QBrush(QtGui.QColor(240, 240, 240)) + brush.setStyle(QtCore.Qt.SolidPattern) + palette.setBrush(QtGui.QPalette.Inactive, QtGui.QPalette.Window, brush) + brush = QtGui.QBrush(QtGui.QColor(0, 0, 0)) + brush.setStyle(QtCore.Qt.SolidPattern) + palette.setBrush(QtGui.QPalette.Inactive, QtGui.QPalette.Shadow, brush) + brush = QtGui.QBrush(QtGui.QColor(247, 247, 247)) + brush.setStyle(QtCore.Qt.SolidPattern) + palette.setBrush(QtGui.QPalette.Inactive, QtGui.QPalette.AlternateBase, brush) + brush = QtGui.QBrush(QtGui.QColor(255, 255, 220)) + brush.setStyle(QtCore.Qt.SolidPattern) + palette.setBrush(QtGui.QPalette.Inactive, QtGui.QPalette.ToolTipBase, brush) + brush = QtGui.QBrush(QtGui.QColor(0, 0, 0)) + brush.setStyle(QtCore.Qt.SolidPattern) + palette.setBrush(QtGui.QPalette.Inactive, QtGui.QPalette.ToolTipText, brush) + brush = QtGui.QBrush(QtGui.QColor(120, 120, 120)) + brush.setStyle(QtCore.Qt.SolidPattern) + palette.setBrush(QtGui.QPalette.Disabled, QtGui.QPalette.WindowText, brush) + brush = QtGui.QBrush(QtGui.QColor(240, 240, 240)) + brush.setStyle(QtCore.Qt.SolidPattern) + palette.setBrush(QtGui.QPalette.Disabled, QtGui.QPalette.Button, brush) + brush = QtGui.QBrush(QtGui.QColor(255, 255, 255)) + brush.setStyle(QtCore.Qt.SolidPattern) + palette.setBrush(QtGui.QPalette.Disabled, QtGui.QPalette.Light, brush) + brush = QtGui.QBrush(QtGui.QColor(247, 247, 247)) + brush.setStyle(QtCore.Qt.SolidPattern) + palette.setBrush(QtGui.QPalette.Disabled, QtGui.QPalette.Midlight, brush) + brush = QtGui.QBrush(QtGui.QColor(120, 120, 120)) + brush.setStyle(QtCore.Qt.SolidPattern) + palette.setBrush(QtGui.QPalette.Disabled, QtGui.QPalette.Dark, brush) + brush = QtGui.QBrush(QtGui.QColor(160, 160, 160)) + brush.setStyle(QtCore.Qt.SolidPattern) + palette.setBrush(QtGui.QPalette.Disabled, QtGui.QPalette.Mid, brush) + brush = QtGui.QBrush(QtGui.QColor(120, 120, 120)) + brush.setStyle(QtCore.Qt.SolidPattern) + palette.setBrush(QtGui.QPalette.Disabled, QtGui.QPalette.Text, brush) + brush = QtGui.QBrush(QtGui.QColor(255, 255, 255)) + brush.setStyle(QtCore.Qt.SolidPattern) + palette.setBrush(QtGui.QPalette.Disabled, QtGui.QPalette.BrightText, brush) + brush = QtGui.QBrush(QtGui.QColor(120, 120, 120)) + brush.setStyle(QtCore.Qt.SolidPattern) + palette.setBrush(QtGui.QPalette.Disabled, QtGui.QPalette.ButtonText, brush) + brush = QtGui.QBrush(QtGui.QColor(240, 240, 240)) + brush.setStyle(QtCore.Qt.SolidPattern) + palette.setBrush(QtGui.QPalette.Disabled, QtGui.QPalette.Base, brush) + brush = QtGui.QBrush(QtGui.QColor(240, 240, 240)) + brush.setStyle(QtCore.Qt.SolidPattern) + palette.setBrush(QtGui.QPalette.Disabled, QtGui.QPalette.Window, brush) + brush = QtGui.QBrush(QtGui.QColor(0, 0, 0)) + brush.setStyle(QtCore.Qt.SolidPattern) + palette.setBrush(QtGui.QPalette.Disabled, QtGui.QPalette.Shadow, brush) + brush = QtGui.QBrush(QtGui.QColor(240, 240, 240)) + brush.setStyle(QtCore.Qt.SolidPattern) + palette.setBrush(QtGui.QPalette.Disabled, QtGui.QPalette.AlternateBase, brush) + brush = QtGui.QBrush(QtGui.QColor(255, 255, 220)) + brush.setStyle(QtCore.Qt.SolidPattern) + palette.setBrush(QtGui.QPalette.Disabled, QtGui.QPalette.ToolTipBase, brush) + brush = QtGui.QBrush(QtGui.QColor(0, 0, 0)) + brush.setStyle(QtCore.Qt.SolidPattern) + palette.setBrush(QtGui.QPalette.Disabled, QtGui.QPalette.ToolTipText, brush) + self.table_plugin_settings.setPalette(palette) + font = QtGui.QFont() + font.setFamily("Roboto") + font.setPointSize(-1) + font.setBold(False) + font.setWeight(37) + self.table_plugin_settings.setFont(font) + self.table_plugin_settings.setStyleSheet("QTableWidget { border: 1px solid #ccc; font-family: Roboto; font-size: 11px; }") + self.table_plugin_settings.setFrameShape(QtWidgets.QFrame.StyledPanel) + self.table_plugin_settings.setVerticalScrollBarPolicy(QtCore.Qt.ScrollBarAsNeeded) + self.table_plugin_settings.setHorizontalScrollBarPolicy(QtCore.Qt.ScrollBarAlwaysOff) + self.table_plugin_settings.setEditTriggers(QtWidgets.QAbstractItemView.NoEditTriggers) + self.table_plugin_settings.setProperty("showDropIndicator", False) + self.table_plugin_settings.setDragDropOverwriteMode(False) + self.table_plugin_settings.setAlternatingRowColors(True) + self.table_plugin_settings.setSelectionMode(QtWidgets.QAbstractItemView.NoSelection) + self.table_plugin_settings.setSelectionBehavior(QtWidgets.QAbstractItemView.SelectRows) + self.table_plugin_settings.setTextElideMode(QtCore.Qt.ElideNone) + self.table_plugin_settings.setVerticalScrollMode(QtWidgets.QAbstractItemView.ScrollPerPixel) + self.table_plugin_settings.setHorizontalScrollMode(QtWidgets.QAbstractItemView.ScrollPerPixel) + self.table_plugin_settings.setShowGrid(False) + self.table_plugin_settings.setGridStyle(QtCore.Qt.NoPen) + self.table_plugin_settings.setWordWrap(True) + self.table_plugin_settings.setCornerButtonEnabled(True) + self.table_plugin_settings.setObjectName("table_plugin_settings") + self.table_plugin_settings.setColumnCount(4) + self.table_plugin_settings.setRowCount(2) + item = QtWidgets.QTableWidgetItem() + item.setTextAlignment(QtCore.Qt.AlignHCenter|QtCore.Qt.AlignVCenter|QtCore.Qt.AlignCenter) + self.table_plugin_settings.setVerticalHeaderItem(0, item) + item = QtWidgets.QTableWidgetItem() + self.table_plugin_settings.setVerticalHeaderItem(1, item) + item = QtWidgets.QTableWidgetItem() + self.table_plugin_settings.setHorizontalHeaderItem(0, item) + item = QtWidgets.QTableWidgetItem() + item.setTextAlignment(QtCore.Qt.AlignHCenter|QtCore.Qt.AlignVCenter|QtCore.Qt.AlignCenter) + self.table_plugin_settings.setHorizontalHeaderItem(1, item) + item = QtWidgets.QTableWidgetItem() + self.table_plugin_settings.setHorizontalHeaderItem(2, item) + item = QtWidgets.QTableWidgetItem() + self.table_plugin_settings.setHorizontalHeaderItem(3, item) + item = QtWidgets.QTableWidgetItem() + self.table_plugin_settings.setItem(0, 0, item) + item = QtWidgets.QTableWidgetItem() + self.table_plugin_settings.setItem(0, 1, item) + item = QtWidgets.QTableWidgetItem() + self.table_plugin_settings.setItem(0, 2, item) + item = QtWidgets.QTableWidgetItem() + self.table_plugin_settings.setItem(0, 3, item) + item = QtWidgets.QTableWidgetItem() + self.table_plugin_settings.setItem(1, 1, item) + item = QtWidgets.QTableWidgetItem() + self.table_plugin_settings.setItem(1, 2, item) + item = QtWidgets.QTableWidgetItem() + self.table_plugin_settings.setItem(1, 3, item) + self.table_plugin_settings.horizontalHeader().setVisible(True) + self.table_plugin_settings.horizontalHeader().setCascadingSectionResizes(False) + self.table_plugin_settings.horizontalHeader().setHighlightSections(True) + self.table_plugin_settings.horizontalHeader().setSortIndicatorShown(False) + self.table_plugin_settings.horizontalHeader().setStretchLastSection(True) + self.table_plugin_settings.verticalHeader().setVisible(False) + self.table_plugin_settings.verticalHeader().setCascadingSectionResizes(False) + self.table_plugin_settings.verticalHeader().setDefaultSectionSize(45) + self.table_plugin_settings.verticalHeader().setSortIndicatorShown(False) + self.table_plugin_settings.verticalHeader().setStretchLastSection(False) + self.lbl_plugin_name = QtWidgets.QLabel(self.frame_details) + self.lbl_plugin_name.setGeometry(QtCore.QRect(20, 20, 391, 21)) + font = QtGui.QFont() + font.setFamily("Roboto") + font.setPointSize(-1) + font.setBold(False) + font.setWeight(37) + self.lbl_plugin_name.setFont(font) + self.lbl_plugin_name.setStyleSheet("color: #555; border: 0; font-size: 15px;") + self.lbl_plugin_name.setTextFormat(QtCore.Qt.RichText) + self.lbl_plugin_name.setObjectName("lbl_plugin_name") + self.btn_reset_plugin_settings = QtWidgets.QPushButton(self.frame_details) + self.btn_reset_plugin_settings.setGeometry(QtCore.QRect(520, 60, 180, 31)) + self.btn_reset_plugin_settings.setStyleSheet("QPushButton {\n" +"color: #eee;\n" +"background: #666;\n" +"border: 0; \n" +"}\n" +"\n" +"QPushButton:hover {\n" +" background: #555;\n" +"}\n" +"\n" +"QPushButton:pressed {\n" +" background: #111;\n" +"}") + self.btn_reset_plugin_settings.setObjectName("btn_reset_plugin_settings") + self.frame = QtWidgets.QFrame(self.centralwidget) + self.frame.setGeometry(QtCore.QRect(0, 60, 281, 621)) + self.frame.setAutoFillBackground(False) + self.frame.setStyleSheet("QFrame {background: #eee;}") + self.frame.setFrameShape(QtWidgets.QFrame.StyledPanel) + self.frame.setFrameShadow(QtWidgets.QFrame.Raised) + self.frame.setObjectName("frame") + self.lbl_hint_restart = QtWidgets.QLabel(self.frame) + self.lbl_hint_restart.setGeometry(QtCore.QRect(20, 560, 251, 51)) + palette = QtGui.QPalette() + brush = QtGui.QBrush(QtGui.QColor(153, 153, 153)) + brush.setStyle(QtCore.Qt.SolidPattern) + palette.setBrush(QtGui.QPalette.Active, QtGui.QPalette.WindowText, brush) + brush = QtGui.QBrush(QtGui.QColor(238, 238, 238)) + brush.setStyle(QtCore.Qt.SolidPattern) + palette.setBrush(QtGui.QPalette.Active, QtGui.QPalette.Button, brush) + brush = QtGui.QBrush(QtGui.QColor(153, 153, 153)) + brush.setStyle(QtCore.Qt.SolidPattern) + palette.setBrush(QtGui.QPalette.Active, QtGui.QPalette.Text, brush) + brush = QtGui.QBrush(QtGui.QColor(153, 153, 153)) + brush.setStyle(QtCore.Qt.SolidPattern) + palette.setBrush(QtGui.QPalette.Active, QtGui.QPalette.ButtonText, brush) + brush = QtGui.QBrush(QtGui.QColor(238, 238, 238)) + brush.setStyle(QtCore.Qt.SolidPattern) + palette.setBrush(QtGui.QPalette.Active, QtGui.QPalette.Base, brush) + brush = QtGui.QBrush(QtGui.QColor(238, 238, 238)) + brush.setStyle(QtCore.Qt.SolidPattern) + palette.setBrush(QtGui.QPalette.Active, QtGui.QPalette.Window, brush) + brush = QtGui.QBrush(QtGui.QColor(153, 153, 153)) + brush.setStyle(QtCore.Qt.SolidPattern) + palette.setBrush(QtGui.QPalette.Inactive, QtGui.QPalette.WindowText, brush) + brush = QtGui.QBrush(QtGui.QColor(238, 238, 238)) + brush.setStyle(QtCore.Qt.SolidPattern) + palette.setBrush(QtGui.QPalette.Inactive, QtGui.QPalette.Button, brush) + brush = QtGui.QBrush(QtGui.QColor(153, 153, 153)) + brush.setStyle(QtCore.Qt.SolidPattern) + palette.setBrush(QtGui.QPalette.Inactive, QtGui.QPalette.Text, brush) + brush = QtGui.QBrush(QtGui.QColor(153, 153, 153)) + brush.setStyle(QtCore.Qt.SolidPattern) + palette.setBrush(QtGui.QPalette.Inactive, QtGui.QPalette.ButtonText, brush) + brush = QtGui.QBrush(QtGui.QColor(238, 238, 238)) + brush.setStyle(QtCore.Qt.SolidPattern) + palette.setBrush(QtGui.QPalette.Inactive, QtGui.QPalette.Base, brush) + brush = QtGui.QBrush(QtGui.QColor(238, 238, 238)) + brush.setStyle(QtCore.Qt.SolidPattern) + palette.setBrush(QtGui.QPalette.Inactive, QtGui.QPalette.Window, brush) + brush = QtGui.QBrush(QtGui.QColor(153, 153, 153)) + brush.setStyle(QtCore.Qt.SolidPattern) + palette.setBrush(QtGui.QPalette.Disabled, QtGui.QPalette.WindowText, brush) + brush = QtGui.QBrush(QtGui.QColor(238, 238, 238)) + brush.setStyle(QtCore.Qt.SolidPattern) + palette.setBrush(QtGui.QPalette.Disabled, QtGui.QPalette.Button, brush) + brush = QtGui.QBrush(QtGui.QColor(153, 153, 153)) + brush.setStyle(QtCore.Qt.SolidPattern) + palette.setBrush(QtGui.QPalette.Disabled, QtGui.QPalette.Text, brush) + brush = QtGui.QBrush(QtGui.QColor(153, 153, 153)) + brush.setStyle(QtCore.Qt.SolidPattern) + palette.setBrush(QtGui.QPalette.Disabled, QtGui.QPalette.ButtonText, brush) + brush = QtGui.QBrush(QtGui.QColor(238, 238, 238)) + brush.setStyle(QtCore.Qt.SolidPattern) + palette.setBrush(QtGui.QPalette.Disabled, QtGui.QPalette.Base, brush) + brush = QtGui.QBrush(QtGui.QColor(238, 238, 238)) + brush.setStyle(QtCore.Qt.SolidPattern) + palette.setBrush(QtGui.QPalette.Disabled, QtGui.QPalette.Window, brush) + self.lbl_hint_restart.setPalette(palette) + font = QtGui.QFont() + font.setFamily("Roboto") + font.setBold(False) + font.setWeight(37) + self.lbl_hint_restart.setFont(font) + self.lbl_hint_restart.setStyleSheet("border-top: 1px dotted #aaa; color: #999; padding: 0;") + self.lbl_hint_restart.setTextFormat(QtCore.Qt.PlainText) + self.lbl_hint_restart.setScaledContents(False) + self.lbl_hint_restart.setAlignment(QtCore.Qt.AlignLeading|QtCore.Qt.AlignLeft|QtCore.Qt.AlignVCenter) + self.lbl_hint_restart.setWordWrap(True) + self.lbl_hint_restart.setObjectName("lbl_hint_restart") + self.lbl_restart_pipeline = QtWidgets.QLabel(self.centralwidget) + self.lbl_restart_pipeline.setGeometry(QtCore.QRect(687, 18, 294, 28)) + font = QtGui.QFont() + font.setFamily("Roboto") + font.setPointSize(-1) + font.setBold(False) + font.setWeight(37) + self.lbl_restart_pipeline.setFont(font) + self.lbl_restart_pipeline.setAutoFillBackground(False) + self.lbl_restart_pipeline.setStyleSheet("background: #ff9719; color: #eee; padding: 5px; border: 0; font-size: 12px;") + self.lbl_restart_pipeline.setAlignment(QtCore.Qt.AlignCenter) + self.lbl_restart_pipeline.setObjectName("lbl_restart_pipeline") + self.label = QtWidgets.QLabel(self.centralwidget) + self.label.setGeometry(QtCore.QRect(20, 25, 261, 31)) + self.label.setStyleSheet("font-size: 20px; color: #ff9719;\n" +"font-weight: 100;") + self.label.setObjectName("label") + self.label_9 = QtWidgets.QLabel(self.centralwidget) + self.label_9.setGeometry(QtCore.QRect(20, 6, 261, 31)) + self.label_9.setStyleSheet("font-size: 13px;\n" +"color: #aaa;\n" +"font-weight: 600;") + self.label_9.setObjectName("label_9") + self.frame.raise_() + self.lst_plugins.raise_() + self.lbl_restart_pipeline.raise_() + self.frame_details.raise_() + self.label.raise_() + self.label_9.raise_() + MainWindow.setCentralWidget(self.centralwidget) + + self.retranslateUi(MainWindow) + QtCore.QMetaObject.connectSlotsByName(MainWindow) + + def retranslateUi(self, MainWindow): + _translate = QtCore.QCoreApplication.translate + MainWindow.setWindowTitle(_translate("MainWindow", "Plugin Configurator")) + __sortingEnabled = self.lst_plugins.isSortingEnabled() + self.lst_plugins.setSortingEnabled(False) + item = self.lst_plugins.item(0) + item.setText(_translate("MainWindow", "Ambient Occlusion")) + item = self.lst_plugins.item(1) + item.setText(_translate("MainWindow", "Another Ite")) + item = self.lst_plugins.item(2) + item.setText(_translate("MainWindow", "Bloom")) + item = self.lst_plugins.item(3) + item.setText(_translate("MainWindow", "Volumetric Clouds")) + item = self.lst_plugins.item(4) + item.setText(_translate("MainWindow", "Depth of Field")) + item = self.lst_plugins.item(5) + item.setText(_translate("MainWindow", "Environment Probes")) + item = self.lst_plugins.item(6) + item.setText(_translate("MainWindow", "FXAA (Antialiasing)")) + item = self.lst_plugins.item(7) + item.setText(_translate("MainWindow", "SKAA")) + item = self.lst_plugins.item(8) + item.setText(_translate("MainWindow", "Motion Blur")) + item = self.lst_plugins.item(9) + item.setText(_translate("MainWindow", "PSSM Shadows")) + item = self.lst_plugins.item(10) + item.setText(_translate("MainWindow", "Atmospheric Scattering")) + item = self.lst_plugins.item(11) + item.setText(_translate("MainWindow", "Skin Shading")) + item = self.lst_plugins.item(12) + item.setText(_translate("MainWindow", "SMAA (Antialiasing)")) + item = self.lst_plugins.item(13) + item.setText(_translate("MainWindow", "Screen Space Reflections")) + item = self.lst_plugins.item(14) + item.setText(_translate("MainWindow", "Volumetric Lighting")) + item = self.lst_plugins.item(15) + item.setText(_translate("MainWindow", "VXGI")) + item = self.lst_plugins.item(16) + item.setText(_translate("MainWindow", "Item 346")) + item = self.lst_plugins.item(17) + item.setText(_translate("MainWindow", "Other Item")) + item = self.lst_plugins.item(18) + item.setText(_translate("MainWindow", "Other Item to force scrollbars")) + self.lst_plugins.setSortingEnabled(__sortingEnabled) + self.lbl_plugin_version.setText(_translate("MainWindow", "version 0.1 by some author")) + self.lbl_plugin_desc.setText(_translate("MainWindow", "This is a fancy description\n" +"It shows information about the plugin and maybe\n" +"a website or so.")) + item = self.table_plugin_settings.verticalHeaderItem(0) + item.setText(_translate("MainWindow", "Row")) + item = self.table_plugin_settings.verticalHeaderItem(1) + item.setText(_translate("MainWindow", "Row2")) + item = self.table_plugin_settings.horizontalHeaderItem(0) + item.setText(_translate("MainWindow", "Setting")) + item = self.table_plugin_settings.horizontalHeaderItem(1) + item.setText(_translate("MainWindow", "Default")) + item = self.table_plugin_settings.horizontalHeaderItem(2) + item.setText(_translate("MainWindow", "Current Value")) + item = self.table_plugin_settings.horizontalHeaderItem(3) + item.setText(_translate("MainWindow", "Description")) + __sortingEnabled = self.table_plugin_settings.isSortingEnabled() + self.table_plugin_settings.setSortingEnabled(False) + item = self.table_plugin_settings.item(0, 0) + item.setText(_translate("MainWindow", "Long setting name which requires")) + item = self.table_plugin_settings.item(0, 1) + item.setText(_translate("MainWindow", "DefaultRow0")) + item = self.table_plugin_settings.item(0, 2) + item.setText(_translate("MainWindow", "CurrentRow0")) + item = self.table_plugin_settings.item(0, 3) + item.setText(_translate("MainWindow", "DescRow0")) + item = self.table_plugin_settings.item(1, 1) + item.setText(_translate("MainWindow", "DefaultRow1")) + item = self.table_plugin_settings.item(1, 2) + item.setText(_translate("MainWindow", "CurrentRow1")) + item = self.table_plugin_settings.item(1, 3) + item.setText(_translate("MainWindow", "aasd\\n\\nsdf\\n\\ndfdfG\\n\\nfgaasd\\n\\nsdf\\n\\ndfdfG\\n\\nfgaasd\\n\\nsdf\\n\\ndfdfG\\n\\nfgaasd\\n\\nsdf\\n\\ndfdfG\\n\\nfgaasd\\n\\nsdf\\n\\ndfdfG\\n\\nfgaasd\\n\\nsdf\\n\\ndfdfG\\n\\nfgaasd\\n\\nsdf\\n\\ndfdfG\\n\\nfgaasd\\n\\nsdf\\n\\ndfdfG\\n\\nfgaasd\\n\\nsdf\\n\\ndfdfG\\n\\nfgaasd\\n\\nsdf\\n\\ndfdfG\\n\\nfgaasd\\n\\nsdf\\n\\ndfdfG\\n\\nfgaasd\\n\\nsdf\\n\\ndfdfG\\n\\nfgaasd\\n\\nsdf\\n\\ndfdfG\\n\\nfgaasd\\n\\nsdf\\n\\ndfdfG\\n\\nfgaasd\\n\\nsdf\\n\\ndfdfG\\n\\nfgaasd\\n\\nsdf\\n\\ndfdfG\\n\\nfgaasd\\n\\nsdf\\n\\ndfdfG\\n\\nfgaasd\\n\\nsdf\\n\\ndfdfG\\n\\nfgaasd\\n\\nsdf\\n\\ndfdfG\\n\\nfgaasd\\n\\nsdf\\n\\ndfdfG\\n\\nfgaasd\\n\\nsdf\\n\\ndfdfG\\n\\nfgaasd\\n\\nsdf\\n\\ndfdfG\\n\\nfgaasd\\n\\nsdf\\n\\ndfdfG\\n\\nfgaasd\\n\\nsdf\\n\\ndfdfG\\n\\nfgaasd\\n\\nsdf\\n\\ndfdfG\\n\\nfgaasd\\n\\nsdf\\n\\ndfdfG\\n\\nfgaasd\\n\\nsdf\\n\\ndfdfG\\n\\nfgaasd\\n\\nsdf\\n\\ndfdfG\\n\\nfgaasd\\n\\nsdf\\n\\ndfdfG\\n\\nfgaasd\\n\\nsdf\\n\\ndfdfG\\n\\nfgaasd\\n\\nsdf\\n\\ndfdfG\\n\\nfgaasd\\n\\nsdf\\n\\ndfdfG\\n\\nfgaasd\\n\\nsdf\\n\\ndfdfG\\n\\nfgaasd\\n\\nsdf\\n\\ndfdfG\\n\\nfgaasd\\n\\nsdf\\n\\ndfdfG\\n\\nfgaasd\\n\\nsdf\\n\\ndfdfG\\n\\nfgaasd\\n\\nsdf\\n\\ndfdfG\\n\\nfgaasd\\n\\nsdf\\n\\ndfdfG\\n\\nfgaasd\\n\\nsdf\\n\\ndfdfG\\n\\nfgaasd\\n\\nsdf\\n\\ndfdfG\\n\\nfgaasd\\n\\nsdf\\n\\ndfdfG\\n\\nfgaasd\\n\\nsdf\\n\\ndfdfG\\n\\nfgaasd\\n\\nsdf\\n\\ndfdfG\\n\\nfgaasd\\n\\nsdf\\n\\ndfdfG\\n\\nfgaasd\\n\\nsdf\\n\\ndfdfG\\n\\nfgaasd\\n\\nsdf\\n\\ndfdfG\\n\\nfgaasd\\n\\nsdf\\n\\ndfdfG\\n\\nfgaasd\\n\\nsdf\\n\\ndfdfG\\n\\nfgaasd\\n\\nsdf\\n\\ndfdfG\\n\\nfgaasd\\n\\nsdf\\n\\ndfdfG\\n\\nfgaasd\\n\\nsdf\\n\\ndfdfG\\n\\nfgaasd\\n\\nsdf\\n\\ndfdfG\\n\\nfgaasd\\n\\nsdf\\n\\ndfdfG\\n\\nfgaasd\\n\\nsdf\\n\\ndfdfG\\n\\nfg")) + self.table_plugin_settings.setSortingEnabled(__sortingEnabled) + self.lbl_plugin_name.setText(_translate("MainWindow", "Ambient Occlusion")) + self.btn_reset_plugin_settings.setText(_translate("MainWindow", "Reset Settings of this Plugin")) + self.lbl_hint_restart.setText(_translate("MainWindow", "Hint: Settings with a gray color require a pipeline restart when changed.")) + self.lbl_restart_pipeline.setText(_translate("MainWindow", "Pipeline needs to be restarted to apply all changes!")) + self.label.setText(_translate("MainWindow", "PLUGIN CONFIGURATOR")) + self.label_9.setText(_translate("MainWindow", "RENDER PIPELINE")) + +from . import resources_rc diff --git a/toolkit/plugin_configurator/ui/res/icon.png b/toolkit/plugin_configurator/ui/res/icon.png new file mode 100644 index 0000000..6c65abe Binary files /dev/null and b/toolkit/plugin_configurator/ui/res/icon.png differ diff --git a/toolkit/plugin_configurator/ui/res/pipeline_logo.png b/toolkit/plugin_configurator/ui/res/pipeline_logo.png new file mode 100644 index 0000000..f6c7ec2 Binary files /dev/null and b/toolkit/plugin_configurator/ui/res/pipeline_logo.png differ diff --git a/toolkit/plugin_configurator/ui/res/plugin_configurator_logo.png b/toolkit/plugin_configurator/ui/res/plugin_configurator_logo.png new file mode 100644 index 0000000..509fe26 Binary files /dev/null and b/toolkit/plugin_configurator/ui/res/plugin_configurator_logo.png differ diff --git a/toolkit/plugin_configurator/ui/resources.qrc b/toolkit/plugin_configurator/ui/resources.qrc new file mode 100644 index 0000000..fe54e41 --- /dev/null +++ b/toolkit/plugin_configurator/ui/resources.qrc @@ -0,0 +1,9 @@ + + + res/pipeline_logo.png + res/icon.png + + + res/plugin_configurator_logo.png + + diff --git a/toolkit/plugin_configurator/ui/resources_rc.py b/toolkit/plugin_configurator/ui/resources_rc.py new file mode 100644 index 0000000..9234557 --- /dev/null +++ b/toolkit/plugin_configurator/ui/resources_rc.py @@ -0,0 +1,1061 @@ +# -*- coding: utf-8 -*- + +# Resource object code +# +# Created by: The Resource Compiler for PyQt5 (Qt v5.7.0) +# +# WARNING! All changes made in this file will be lost! + +from PyQt5 import QtCore + +qt_resource_data = b"\ +\x00\x00\x17\xe1\ +\x89\ +\x50\x4e\x47\x0d\x0a\x1a\x0a\x00\x00\x00\x0d\x49\x48\x44\x52\x00\ +\x00\x00\x46\x00\x00\x00\x46\x08\x06\x00\x00\x00\x71\x2e\xe2\x84\ +\x00\x00\x00\x09\x70\x48\x59\x73\x00\x00\x0b\x13\x00\x00\x0b\x13\ +\x01\x00\x9a\x9c\x18\x00\x00\x0a\x4f\x69\x43\x43\x50\x50\x68\x6f\ +\x74\x6f\x73\x68\x6f\x70\x20\x49\x43\x43\x20\x70\x72\x6f\x66\x69\ +\x6c\x65\x00\x00\x78\xda\x9d\x53\x67\x54\x53\xe9\x16\x3d\xf7\xde\ +\xf4\x42\x4b\x88\x80\x94\x4b\x6f\x52\x15\x08\x20\x52\x42\x8b\x80\ +\x14\x91\x26\x2a\x21\x09\x10\x4a\x88\x21\xa1\xd9\x15\x51\xc1\x11\ +\x45\x45\x04\x1b\xc8\xa0\x88\x03\x8e\x8e\x80\x8c\x15\x51\x2c\x0c\ +\x8a\x0a\xd8\x07\xe4\x21\xa2\x8e\x83\xa3\x88\x8a\xca\xfb\xe1\x7b\ +\xa3\x6b\xd6\xbc\xf7\xe6\xcd\xfe\xb5\xd7\x3e\xe7\xac\xf3\x9d\xb3\ +\xcf\x07\xc0\x08\x0c\x96\x48\x33\x51\x35\x80\x0c\xa9\x42\x1e\x11\ +\xe0\x83\xc7\xc4\xc6\xe1\xe4\x2e\x40\x81\x0a\x24\x70\x00\x10\x08\ +\xb3\x64\x21\x73\xfd\x23\x01\x00\xf8\x7e\x3c\x3c\x2b\x22\xc0\x07\ +\xbe\x00\x01\x78\xd3\x0b\x08\x00\xc0\x4d\x9b\xc0\x30\x1c\x87\xff\ +\x0f\xea\x42\x99\x5c\x01\x80\x84\x01\xc0\x74\x91\x38\x4b\x08\x80\ +\x14\x00\x40\x7a\x8e\x42\xa6\x00\x40\x46\x01\x80\x9d\x98\x26\x53\ +\x00\xa0\x04\x00\x60\xcb\x63\x62\xe3\x00\x50\x2d\x00\x60\x27\x7f\ +\xe6\xd3\x00\x80\x9d\xf8\x99\x7b\x01\x00\x5b\x94\x21\x15\x01\xa0\ +\x91\x00\x20\x13\x65\x88\x44\x00\x68\x3b\x00\xac\xcf\x56\x8a\x45\ +\x00\x58\x30\x00\x14\x66\x4b\xc4\x39\x00\xd8\x2d\x00\x30\x49\x57\ +\x66\x48\x00\xb0\xb7\x00\xc0\xce\x10\x0b\xb2\x00\x08\x0c\x00\x30\ +\x51\x88\x85\x29\x00\x04\x7b\x00\x60\xc8\x23\x23\x78\x00\x84\x99\ +\x00\x14\x46\xf2\x57\x3c\xf1\x2b\xae\x10\xe7\x2a\x00\x00\x78\x99\ +\xb2\x3c\xb9\x24\x39\x45\x81\x5b\x08\x2d\x71\x07\x57\x57\x2e\x1e\ +\x28\xce\x49\x17\x2b\x14\x36\x61\x02\x61\x9a\x40\x2e\xc2\x79\x99\ +\x19\x32\x81\x34\x0f\xe0\xf3\xcc\x00\x00\xa0\x91\x15\x11\xe0\x83\ +\xf3\xfd\x78\xce\x0e\xae\xce\xce\x36\x8e\xb6\x0e\x5f\x2d\xea\xbf\ +\x06\xff\x22\x62\x62\xe3\xfe\xe5\xcf\xab\x70\x40\x00\x00\xe1\x74\ +\x7e\xd1\xfe\x2c\x2f\xb3\x1a\x80\x3b\x06\x80\x6d\xfe\xa2\x25\xee\ +\x04\x68\x5e\x0b\xa0\x75\xf7\x8b\x66\xb2\x0f\x40\xb5\x00\xa0\xe9\ +\xda\x57\xf3\x70\xf8\x7e\x3c\x3c\x45\xa1\x90\xb9\xd9\xd9\xe5\xe4\ +\xe4\xd8\x4a\xc4\x42\x5b\x61\xca\x57\x7d\xfe\x67\xc2\x5f\xc0\x57\ +\xfd\x6c\xf9\x7e\x3c\xfc\xf7\xf5\xe0\xbe\xe2\x24\x81\x32\x5d\x81\ +\x47\x04\xf8\xe0\xc2\xcc\xf4\x4c\xa5\x1c\xcf\x92\x09\x84\x62\xdc\ +\xe6\x8f\x47\xfc\xb7\x0b\xff\xfc\x1d\xd3\x22\xc4\x49\x62\xb9\x58\ +\x2a\x14\xe3\x51\x12\x71\x8e\x44\x9a\x8c\xf3\x32\xa5\x22\x89\x42\ +\x92\x29\xc5\x25\xd2\xff\x64\xe2\xdf\x2c\xfb\x03\x3e\xdf\x35\x00\ +\xb0\x6a\x3e\x01\x7b\x91\x2d\xa8\x5d\x63\x03\xf6\x4b\x27\x10\x58\ +\x74\xc0\xe2\xf7\x00\x00\xf2\xbb\x6f\xc1\xd4\x28\x08\x03\x80\x68\ +\x83\xe1\xcf\x77\xff\xef\x3f\xfd\x47\xa0\x25\x00\x80\x66\x49\x92\ +\x71\x00\x00\x5e\x44\x24\x2e\x54\xca\xb3\x3f\xc7\x08\x00\x00\x44\ +\xa0\x81\x2a\xb0\x41\x1b\xf4\xc1\x18\x2c\xc0\x06\x1c\xc1\x05\xdc\ +\xc1\x0b\xfc\x60\x36\x84\x42\x24\xc4\xc2\x42\x10\x42\x0a\x64\x80\ +\x1c\x72\x60\x29\xac\x82\x42\x28\x86\xcd\xb0\x1d\x2a\x60\x2f\xd4\ +\x40\x1d\x34\xc0\x51\x68\x86\x93\x70\x0e\x2e\xc2\x55\xb8\x0e\x3d\ +\x70\x0f\xfa\x61\x08\x9e\xc1\x28\xbc\x81\x09\x04\x41\xc8\x08\x13\ +\x61\x21\xda\x88\x01\x62\x8a\x58\x23\x8e\x08\x17\x99\x85\xf8\x21\ +\xc1\x48\x04\x12\x8b\x24\x20\xc9\x88\x14\x51\x22\x4b\x91\x35\x48\ +\x31\x52\x8a\x54\x20\x55\x48\x1d\xf2\x3d\x72\x02\x39\x87\x5c\x46\ +\xba\x91\x3b\xc8\x00\x32\x82\xfc\x86\xbc\x47\x31\x94\x81\xb2\x51\ +\x3d\xd4\x0c\xb5\x43\xb9\xa8\x37\x1a\x84\x46\xa2\x0b\xd0\x64\x74\ +\x31\x9a\x8f\x16\xa0\x9b\xd0\x72\xb4\x1a\x3d\x8c\x36\xa1\xe7\xd0\ +\xab\x68\x0f\xda\x8f\x3e\x43\xc7\x30\xc0\xe8\x18\x07\x33\xc4\x6c\ +\x30\x2e\xc6\xc3\x42\xb1\x38\x2c\x09\x93\x63\xcb\xb1\x22\xac\x0c\ +\xab\xc6\x1a\xb0\x56\xac\x03\xbb\x89\xf5\x63\xcf\xb1\x77\x04\x12\ +\x81\x45\xc0\x09\x36\x04\x77\x42\x20\x61\x1e\x41\x48\x58\x4c\x58\ +\x4e\xd8\x48\xa8\x20\x1c\x24\x34\x11\xda\x09\x37\x09\x03\x84\x51\ +\xc2\x27\x22\x93\xa8\x4b\xb4\x26\xba\x11\xf9\xc4\x18\x62\x32\x31\ +\x87\x58\x48\x2c\x23\xd6\x12\x8f\x13\x2f\x10\x7b\x88\x43\xc4\x37\ +\x24\x12\x89\x43\x32\x27\xb9\x90\x02\x49\xb1\xa4\x54\xd2\x12\xd2\ +\x46\xd2\x6e\x52\x23\xe9\x2c\xa9\x9b\x34\x48\x1a\x23\x93\xc9\xda\ +\x64\x6b\xb2\x07\x39\x94\x2c\x20\x2b\xc8\x85\xe4\x9d\xe4\xc3\xe4\ +\x33\xe4\x1b\xe4\x21\xf2\x5b\x0a\x9d\x62\x40\x71\xa4\xf8\x53\xe2\ +\x28\x52\xca\x6a\x4a\x19\xe5\x10\xe5\x34\xe5\x06\x65\x98\x32\x41\ +\x55\xa3\x9a\x52\xdd\xa8\xa1\x54\x11\x35\x8f\x5a\x42\xad\xa1\xb6\ +\x52\xaf\x51\x87\xa8\x13\x34\x75\x9a\x39\xcd\x83\x16\x49\x4b\xa5\ +\xad\xa2\x95\xd3\x1a\x68\x17\x68\xf7\x69\xaf\xe8\x74\xba\x11\xdd\ +\x95\x1e\x4e\x97\xd0\x57\xd2\xcb\xe9\x47\xe8\x97\xe8\x03\xf4\x77\ +\x0c\x0d\x86\x15\x83\xc7\x88\x67\x28\x19\x9b\x18\x07\x18\x67\x19\ +\x77\x18\xaf\x98\x4c\xa6\x19\xd3\x8b\x19\xc7\x54\x30\x37\x31\xeb\ +\x98\xe7\x99\x0f\x99\x6f\x55\x58\x2a\xb6\x2a\x7c\x15\x91\xca\x0a\ +\x95\x4a\x95\x26\x95\x1b\x2a\x2f\x54\xa9\xaa\xa6\xaa\xde\xaa\x0b\ +\x55\xf3\x55\xcb\x54\x8f\xa9\x5e\x53\x7d\xae\x46\x55\x33\x53\xe3\ +\xa9\x09\xd4\x96\xab\x55\xaa\x9d\x50\xeb\x53\x1b\x53\x67\xa9\x3b\ +\xa8\x87\xaa\x67\xa8\x6f\x54\x3f\xa4\x7e\x59\xfd\x89\x06\x59\xc3\ +\x4c\xc3\x4f\x43\xa4\x51\xa0\xb1\x5f\xe3\xbc\xc6\x20\x0b\x63\x19\ +\xb3\x78\x2c\x21\x6b\x0d\xab\x86\x75\x81\x35\xc4\x26\xb1\xcd\xd9\ +\x7c\x76\x2a\xbb\x98\xfd\x1d\xbb\x8b\x3d\xaa\xa9\xa1\x39\x43\x33\ +\x4a\x33\x57\xb3\x52\xf3\x94\x66\x3f\x07\xe3\x98\x71\xf8\x9c\x74\ +\x4e\x09\xe7\x28\xa7\x97\xf3\x7e\x8a\xde\x14\xef\x29\xe2\x29\x1b\ +\xa6\x34\x4c\xb9\x31\x65\x5c\x6b\xaa\x96\x97\x96\x58\xab\x48\xab\ +\x51\xab\x47\xeb\xbd\x36\xae\xed\xa7\x9d\xa6\xbd\x45\xbb\x59\xfb\ +\x81\x0e\x41\xc7\x4a\x27\x5c\x27\x47\x67\x8f\xce\x05\x9d\xe7\x53\ +\xd9\x53\xdd\xa7\x0a\xa7\x16\x4d\x3d\x3a\xf5\xae\x2e\xaa\x6b\xa5\ +\x1b\xa1\xbb\x44\x77\xbf\x6e\xa7\xee\x98\x9e\xbe\x5e\x80\x9e\x4c\ +\x6f\xa7\xde\x79\xbd\xe7\xfa\x1c\x7d\x2f\xfd\x54\xfd\x6d\xfa\xa7\ +\xf5\x47\x0c\x58\x06\xb3\x0c\x24\x06\xdb\x0c\xce\x18\x3c\xc5\x35\ +\x71\x6f\x3c\x1d\x2f\xc7\xdb\xf1\x51\x43\x5d\xc3\x40\x43\xa5\x61\ +\x95\x61\x97\xe1\x84\x91\xb9\xd1\x3c\xa3\xd5\x46\x8d\x46\x0f\x8c\ +\x69\xc6\x5c\xe3\x24\xe3\x6d\xc6\x6d\xc6\xa3\x26\x06\x26\x21\x26\ +\x4b\x4d\xea\x4d\xee\x9a\x52\x4d\xb9\xa6\x29\xa6\x3b\x4c\x3b\x4c\ +\xc7\xcd\xcc\xcd\xa2\xcd\xd6\x99\x35\x9b\x3d\x31\xd7\x32\xe7\x9b\ +\xe7\x9b\xd7\x9b\xdf\xb7\x60\x5a\x78\x5a\x2c\xb6\xa8\xb6\xb8\x65\ +\x49\xb2\xe4\x5a\xa6\x59\xee\xb6\xbc\x6e\x85\x5a\x39\x59\xa5\x58\ +\x55\x5a\x5d\xb3\x46\xad\x9d\xad\x25\xd6\xbb\xad\xbb\xa7\x11\xa7\ +\xb9\x4e\x93\x4e\xab\x9e\xd6\x67\xc3\xb0\xf1\xb6\xc9\xb6\xa9\xb7\ +\x19\xb0\xe5\xd8\x06\xdb\xae\xb6\x6d\xb6\x7d\x61\x67\x62\x17\x67\ +\xb7\xc5\xae\xc3\xee\x93\xbd\x93\x7d\xba\x7d\x8d\xfd\x3d\x07\x0d\ +\x87\xd9\x0e\xab\x1d\x5a\x1d\x7e\x73\xb4\x72\x14\x3a\x56\x3a\xde\ +\x9a\xce\x9c\xee\x3f\x7d\xc5\xf4\x96\xe9\x2f\x67\x58\xcf\x10\xcf\ +\xd8\x33\xe3\xb6\x13\xcb\x29\xc4\x69\x9d\x53\x9b\xd3\x47\x67\x17\ +\x67\xb9\x73\x83\xf3\x88\x8b\x89\x4b\x82\xcb\x2e\x97\x3e\x2e\x9b\ +\x1b\xc6\xdd\xc8\xbd\xe4\x4a\x74\xf5\x71\x5d\xe1\x7a\xd2\xf5\x9d\ +\x9b\xb3\x9b\xc2\xed\xa8\xdb\xaf\xee\x36\xee\x69\xee\x87\xdc\x9f\ +\xcc\x34\x9f\x29\x9e\x59\x33\x73\xd0\xc3\xc8\x43\xe0\x51\xe5\xd1\ +\x3f\x0b\x9f\x95\x30\x6b\xdf\xac\x7e\x4f\x43\x4f\x81\x67\xb5\xe7\ +\x23\x2f\x63\x2f\x91\x57\xad\xd7\xb0\xb7\xa5\x77\xaa\xf7\x61\xef\ +\x17\x3e\xf6\x3e\x72\x9f\xe3\x3e\xe3\x3c\x37\xde\x32\xde\x59\x5f\ +\xcc\x37\xc0\xb7\xc8\xb7\xcb\x4f\xc3\x6f\x9e\x5f\x85\xdf\x43\x7f\ +\x23\xff\x64\xff\x7a\xff\xd1\x00\xa7\x80\x25\x01\x67\x03\x89\x81\ +\x41\x81\x5b\x02\xfb\xf8\x7a\x7c\x21\xbf\x8e\x3f\x3a\xdb\x65\xf6\ +\xb2\xd9\xed\x41\x8c\xa0\xb9\x41\x15\x41\x8f\x82\xad\x82\xe5\xc1\ +\xad\x21\x68\xc8\xec\x90\xad\x21\xf7\xe7\x98\xce\x91\xce\x69\x0e\ +\x85\x50\x7e\xe8\xd6\xd0\x07\x61\xe6\x61\x8b\xc3\x7e\x0c\x27\x85\ +\x87\x85\x57\x86\x3f\x8e\x70\x88\x58\x1a\xd1\x31\x97\x35\x77\xd1\ +\xdc\x43\x73\xdf\x44\xfa\x44\x96\x44\xde\x9b\x67\x31\x4f\x39\xaf\ +\x2d\x4a\x35\x2a\x3e\xaa\x2e\x6a\x3c\xda\x37\xba\x34\xba\x3f\xc6\ +\x2e\x66\x59\xcc\xd5\x58\x9d\x58\x49\x6c\x4b\x1c\x39\x2e\x2a\xae\ +\x36\x6e\x6c\xbe\xdf\xfc\xed\xf3\x87\xe2\x9d\xe2\x0b\xe3\x7b\x17\ +\x98\x2f\xc8\x5d\x70\x79\xa1\xce\xc2\xf4\x85\xa7\x16\xa9\x2e\x12\ +\x2c\x3a\x96\x40\x4c\x88\x4e\x38\x94\xf0\x41\x10\x2a\xa8\x16\x8c\ +\x25\xf2\x13\x77\x25\x8e\x0a\x79\xc2\x1d\xc2\x67\x22\x2f\xd1\x36\ +\xd1\x88\xd8\x43\x5c\x2a\x1e\x4e\xf2\x48\x2a\x4d\x7a\x92\xec\x91\ +\xbc\x35\x79\x24\xc5\x33\xa5\x2c\xe5\xb9\x84\x27\xa9\x90\xbc\x4c\ +\x0d\x4c\xdd\x9b\x3a\x9e\x16\x9a\x76\x20\x6d\x32\x3d\x3a\xbd\x31\ +\x83\x92\x91\x90\x71\x42\xaa\x21\x4d\x93\xb6\x67\xea\x67\xe6\x66\ +\x76\xcb\xac\x65\x85\xb2\xfe\xc5\x6e\x8b\xb7\x2f\x1e\x95\x07\xc9\ +\x6b\xb3\x90\xac\x05\x59\x2d\x0a\xb6\x42\xa6\xe8\x54\x5a\x28\xd7\ +\x2a\x07\xb2\x67\x65\x57\x66\xbf\xcd\x89\xca\x39\x96\xab\x9e\x2b\ +\xcd\xed\xcc\xb3\xca\xdb\x90\x37\x9c\xef\x9f\xff\xed\x12\xc2\x12\ +\xe1\x92\xb6\xa5\x86\x4b\x57\x2d\x1d\x58\xe6\xbd\xac\x6a\x39\xb2\ +\x3c\x71\x79\xdb\x0a\xe3\x15\x05\x2b\x86\x56\x06\xac\x3c\xb8\x8a\ +\xb6\x2a\x6d\xd5\x4f\xab\xed\x57\x97\xae\x7e\xbd\x26\x7a\x4d\x6b\ +\x81\x5e\xc1\xca\x82\xc1\xb5\x01\x6b\xeb\x0b\x55\x0a\xe5\x85\x7d\ +\xeb\xdc\xd7\xed\x5d\x4f\x58\x2f\x59\xdf\xb5\x61\xfa\x86\x9d\x1b\ +\x3e\x15\x89\x8a\xae\x14\xdb\x17\x97\x15\x7f\xd8\x28\xdc\x78\xe5\ +\x1b\x87\x6f\xca\xbf\x99\xdc\x94\xb4\xa9\xab\xc4\xb9\x64\xcf\x66\ +\xd2\x66\xe9\xe6\xde\x2d\x9e\x5b\x0e\x96\xaa\x97\xe6\x97\x0e\x6e\ +\x0d\xd9\xda\xb4\x0d\xdf\x56\xb4\xed\xf5\xf6\x45\xdb\x2f\x97\xcd\ +\x28\xdb\xbb\x83\xb6\x43\xb9\xa3\xbf\x3c\xb8\xbc\x65\xa7\xc9\xce\ +\xcd\x3b\x3f\x54\xa4\x54\xf4\x54\xfa\x54\x36\xee\xd2\xdd\xb5\x61\ +\xd7\xf8\x6e\xd1\xee\x1b\x7b\xbc\xf6\x34\xec\xd5\xdb\x5b\xbc\xf7\ +\xfd\x3e\xc9\xbe\xdb\x55\x01\x55\x4d\xd5\x66\xd5\x65\xfb\x49\xfb\ +\xb3\xf7\x3f\xae\x89\xaa\xe9\xf8\x96\xfb\x6d\x5d\xad\x4e\x6d\x71\ +\xed\xc7\x03\xd2\x03\xfd\x07\x23\x0e\xb6\xd7\xb9\xd4\xd5\x1d\xd2\ +\x3d\x54\x52\x8f\xd6\x2b\xeb\x47\x0e\xc7\x1f\xbe\xfe\x9d\xef\x77\ +\x2d\x0d\x36\x0d\x55\x8d\x9c\xc6\xe2\x23\x70\x44\x79\xe4\xe9\xf7\ +\x09\xdf\xf7\x1e\x0d\x3a\xda\x76\x8c\x7b\xac\xe1\x07\xd3\x1f\x76\ +\x1d\x67\x1d\x2f\x6a\x42\x9a\xf2\x9a\x46\x9b\x53\x9a\xfb\x5b\x62\ +\x5b\xba\x4f\xcc\x3e\xd1\xd6\xea\xde\x7a\xfc\x47\xdb\x1f\x0f\x9c\ +\x34\x3c\x59\x79\x4a\xf3\x54\xc9\x69\xda\xe9\x82\xd3\x93\x67\xf2\ +\xcf\x8c\x9d\x95\x9d\x7d\x7e\x2e\xf9\xdc\x60\xdb\xa2\xb6\x7b\xe7\ +\x63\xce\xdf\x6a\x0f\x6f\xef\xba\x10\x74\xe1\xd2\x45\xff\x8b\xe7\ +\x3b\xbc\x3b\xce\x5c\xf2\xb8\x74\xf2\xb2\xdb\xe5\x13\x57\xb8\x57\ +\x9a\xaf\x3a\x5f\x6d\xea\x74\xea\x3c\xfe\x93\xd3\x4f\xc7\xbb\x9c\ +\xbb\x9a\xae\xb9\x5c\x6b\xb9\xee\x7a\xbd\xb5\x7b\x66\xf7\xe9\x1b\ +\x9e\x37\xce\xdd\xf4\xbd\x79\xf1\x16\xff\xd6\xd5\x9e\x39\x3d\xdd\ +\xbd\xf3\x7a\x6f\xf7\xc5\xf7\xf5\xdf\x16\xdd\x7e\x72\x27\xfd\xce\ +\xcb\xbb\xd9\x77\x27\xee\xad\xbc\x4f\xbc\x5f\xf4\x40\xed\x41\xd9\ +\x43\xdd\x87\xd5\x3f\x5b\xfe\xdc\xd8\xef\xdc\x7f\x6a\xc0\x77\xa0\ +\xf3\xd1\xdc\x47\xf7\x06\x85\x83\xcf\xfe\x91\xf5\x8f\x0f\x43\x05\ +\x8f\x99\x8f\xcb\x86\x0d\x86\xeb\x9e\x38\x3e\x39\x39\xe2\x3f\x72\ +\xfd\xe9\xfc\xa7\x43\xcf\x64\xcf\x26\x9e\x17\xfe\xa2\xfe\xcb\xae\ +\x17\x16\x2f\x7e\xf8\xd5\xeb\xd7\xce\xd1\x98\xd1\xa1\x97\xf2\x97\ +\x93\xbf\x6d\x7c\xa5\xfd\xea\xc0\xeb\x19\xaf\xdb\xc6\xc2\xc6\x1e\ +\xbe\xc9\x78\x33\x31\x5e\xf4\x56\xfb\xed\xc1\x77\xdc\x77\x1d\xef\ +\xa3\xdf\x0f\x4f\xe4\x7c\x20\x7f\x28\xff\x68\xf9\xb1\xf5\x53\xd0\ +\xa7\xfb\x93\x19\x93\x93\xff\x04\x03\x98\xf3\xfc\x63\x33\x2d\xdb\ +\x00\x00\x00\x20\x63\x48\x52\x4d\x00\x00\x7a\x25\x00\x00\x80\x83\ +\x00\x00\xf9\xff\x00\x00\x80\xe9\x00\x00\x75\x30\x00\x00\xea\x60\ +\x00\x00\x3a\x98\x00\x00\x17\x6f\x92\x5f\xc5\x46\x00\x00\x0d\x0c\ +\x49\x44\x41\x54\x78\xda\xec\x9c\x7d\x70\x5c\xd5\x79\xc6\x7f\xe7\ +\xdc\xbb\xbb\x77\xbf\xbc\x5a\xc9\xb2\x8c\x31\xc6\xc6\x60\x6c\x62\ +\x13\x8c\x09\xb8\x21\x34\x04\x4c\xec\x60\xe3\xa4\x8d\x29\x6e\x61\ +\xa6\xb4\x49\xda\xd0\x4c\x9a\xe2\x36\x1d\xca\x30\x43\x4a\x81\x69\ +\xd2\xc9\x1f\x09\x90\xc1\xa4\x9d\x7c\x0c\x13\x3e\x12\xf3\x61\xc0\ +\xb2\x63\x17\x9c\x2a\xc4\x01\x83\xb1\xb1\x94\x20\x6c\xab\x76\x2d\ +\xdb\xb2\xf5\xb1\x5a\x69\xb5\xbb\x77\xf7\xde\x7b\xfa\xc7\xbd\x6b\ +\x7d\xee\x6a\x25\xaf\x84\xe2\xd1\x33\x73\xc6\x2b\xef\xbd\xe7\x9c\ +\xfb\xdc\xf7\x7d\xcf\xfb\x3e\xe7\x48\x42\x29\xc5\x34\x86\x43\x4e\ +\x53\x30\x4d\xcc\x34\x31\xd3\xc4\x4c\x13\x33\x4d\xcc\x94\x81\x5e\ +\xea\xcb\xa5\x4b\x97\x56\x7a\xbc\x38\x70\x39\xf0\x31\x60\x31\x70\ +\x31\x30\x0b\xa8\xf3\xbe\x13\xc0\x64\xe4\x0f\x01\xe0\x64\x63\x63\ +\xe3\xc7\xc6\x45\x4c\x05\xad\xf2\x0b\xc0\x17\x81\x6b\x80\x45\x53\ +\xc4\x28\x8c\x71\x5b\xcc\x39\x62\x2e\xb0\x11\xb8\xdb\xb3\x90\xa9\ +\x86\xee\xc9\x26\x26\x00\xfc\x2d\xf0\x2f\xc0\xec\x29\x1c\x46\xc4\ +\x64\x12\xb3\x16\xf8\x0f\x60\xc9\xf4\xaa\xd4\xcf\xfe\x77\x80\x57\ +\xcf\x07\x52\x2a\x65\x31\x71\xe0\x19\x60\xf5\x18\xee\xc9\x03\x47\ +\x81\xff\x05\xce\x00\x6d\x40\x87\xb7\x22\xd5\x78\x2e\x58\x0b\x2c\ +\xf0\x5a\xe0\x0f\x8d\x98\x39\xc0\x4b\xc0\x27\xca\xbc\xfe\xb7\xc0\ +\x76\xe0\x65\xa0\x19\xc8\x94\xb1\x72\x2c\x04\x6e\xf3\xdc\xf4\x53\ +\x7f\x08\xc4\x5c\x02\xfc\x0f\x70\x61\x19\xd7\xd6\x03\x8f\x03\xdb\ +\xc6\x38\x46\x16\x68\xf2\xda\xbf\x03\x37\x01\xf7\x00\x1b\xa6\x6a\ +\x8c\x99\x01\xbc\x58\x06\x29\xfb\x80\x35\xc0\xad\xe3\x20\x65\x24\ +\xbc\x0e\xdc\x0e\xfc\xb1\xf7\x79\x4a\x11\xa3\x7b\xa4\x5c\x39\xca\ +\x75\x0f\x7a\x2e\xb6\xe3\x9c\x27\x29\x20\xe7\x80\xe9\xb8\x9f\x81\ +\x06\xe0\x66\xe0\x1f\xa6\x92\x2b\x3d\xe8\x99\x74\x31\x38\xc0\x5d\ +\xc0\x33\x3d\x7d\x29\x6c\xdb\x41\x88\xfe\x94\xc1\x71\x1c\x22\xa1\ +\x10\x46\x20\x80\xe3\x38\x25\xc9\x68\x33\x15\x59\x5b\x91\x57\x30\ +\x2f\x28\xf1\x0b\x38\xd4\xe7\xe0\x13\x30\x3b\x20\x09\x6a\x7c\xcf\ +\x56\x1c\x02\x9e\x05\xa2\x1f\x25\x31\xab\x81\x07\x4a\x7c\xdf\x23\ +\x84\xd8\x90\xc9\x66\x77\x9a\xf9\x1c\x2b\x96\x2c\x25\x1c\x0a\x61\ +\x59\x56\x7f\x34\x0d\x04\xf8\xdd\x91\xc3\x1c\x3b\x75\x82\x68\x38\ +\x8c\x4f\xf7\x81\x52\x28\xc0\x16\x1a\x42\x08\xf2\x4a\xd1\x91\x53\ +\x6c\xbc\xc0\xc7\x45\x41\x41\x9b\xa9\x58\x35\x53\x23\x28\x05\x2f\ +\x9f\xb6\xb8\x20\x20\x78\xfe\x94\xc5\x87\x29\x87\xba\x80\xd8\x16\ +\xd5\xc5\xcd\xca\x0d\xe8\x17\x7c\x14\xc4\x68\xc0\xf7\x8b\xbe\x61\ +\x29\x73\x59\xd3\x5c\xdf\x95\x4c\xfe\x6a\xf9\x92\x2b\xb8\xe1\xea\ +\x6b\x98\x3f\x67\x2e\xa1\xa0\x81\x65\xdb\xfd\x69\xb1\xcf\xcf\xb2\ +\xcb\x16\xd1\xdd\x9b\xe2\xc3\xa3\x2d\xbc\x7f\xe8\x03\x42\xc1\x10\ +\x02\x85\xee\x58\xa4\x2c\xc5\xb2\xa8\xc6\xdf\xcc\xf3\x71\x63\x8d\ +\x8e\x61\x08\xd7\x06\x2d\x85\xa3\xe0\xd6\x39\x3e\x10\xb0\xba\xd6\ +\xa2\xc7\x56\xfc\xf8\x78\x9e\x57\xce\xd8\x7b\x17\x84\xc4\x2a\xa5\ +\x78\x13\xa8\xaa\x48\x62\x56\x4a\x0c\x1f\x52\x5d\x7f\xbd\x18\x31\ +\x42\x08\x27\x63\x9a\xb7\x1b\x7e\xff\x0b\x97\x2f\xb8\x84\x9b\xae\ +\x5d\xc9\xec\x9a\x5a\xba\x7a\x92\xd8\xb6\x3d\xcc\x95\xc2\xc1\x20\ +\xa1\x60\x90\x64\x6f\x2f\xbd\x7d\x29\x2c\x7f\x88\xa0\x95\x61\xdd\ +\xf1\x6d\xf8\xf2\x19\x74\xbf\xc1\xac\x90\x20\x65\x3a\x98\xf6\xd9\ +\xb8\xd2\xdf\x87\x82\x9a\x80\x00\x9f\xa0\x2b\xed\xf0\x97\xef\x65\ +\x69\x48\xd8\x5c\x1c\x14\x37\xd9\x8a\xd7\x46\x2b\x10\x3d\x9c\x6e\ +\x6c\x6c\x9c\x7d\xae\xc1\xb7\xd6\x8b\x2d\x23\x22\x97\xcf\x3f\x2c\ +\x85\x78\xe1\x8e\x35\x6b\xb9\x73\xed\x7a\x0c\x7f\x80\xf6\x44\x17\ +\x8e\xe3\x68\x62\x20\x2b\xae\x65\x91\x31\x4d\x3a\x12\x09\x1c\xa5\ +\x88\x45\xa2\x84\x82\x21\x22\xc1\x20\x35\x7e\xc9\x9c\x00\x84\x35\ +\xe8\xca\x38\xe4\x9d\xe1\xa4\x14\xe2\x4f\x22\xa7\xe8\xea\x73\x88\ +\xfb\x04\xcf\xac\x30\xf8\x54\x5c\xa3\x25\xad\x5e\x07\xfe\x69\x32\ +\x57\xa5\xbf\xf6\x32\xd2\x91\x5c\x68\x7f\x2a\x93\x7e\xf0\xd2\x79\ +\x17\xb3\xf0\xa2\x79\x9c\xe9\xec\x0c\x58\xb6\xfd\x25\x21\xc4\x76\ +\xe0\xf7\x5e\x7b\xc5\xab\xb4\xe5\x00\x2b\xc3\x71\x1c\xf2\x56\x1e\ +\xcb\xb2\xc8\x5b\x16\x59\x5b\x91\xb6\xdd\xd5\x47\x8c\x9c\x61\x7f\ +\x19\xd8\x0a\xbc\x05\xec\x16\xf0\x48\x97\xa9\x2e\x0f\x49\xc1\xb3\ +\xcb\x0d\x6e\xac\xd6\x68\xcd\x3a\x4f\xe8\x82\x9d\x93\x45\xcc\x97\ +\x8a\xb8\x10\x7d\x99\xf4\xa6\xcb\xe7\x2f\xe0\x8e\xd5\xb7\x62\xe6\ +\x72\xcb\x80\xdd\xc0\x7f\x7a\x81\xfa\x32\x4f\x98\x5a\xe7\x95\x0d\ +\xff\xed\xfd\x3c\x56\xac\x02\xde\x04\x7e\xe8\x65\xc1\xd7\x02\x9f\ +\x06\xee\x97\x82\xfd\x89\x9c\x7a\x24\xa2\x0b\x9e\x5e\x6e\x70\x43\ +\x5c\xe3\xb4\xa9\xbe\x29\x26\x81\x98\xf5\xde\x03\x0e\x43\x3a\x9b\ +\x79\xa3\xae\x66\xe6\x1b\x77\xaf\xff\x53\x7c\xba\x3e\x37\x6b\x9a\ +\x3b\x85\x10\x2b\x4b\xf4\x75\xa3\xf7\xc6\x6b\xc6\x30\xc7\xcf\x00\ +\x3b\x4b\x14\xa7\x86\x14\xdc\xdf\x6e\xaa\xef\xc6\x0c\xc1\xdd\x73\ +\xfd\x28\x38\x60\xbb\x4b\xf8\x84\x12\x73\x57\x11\x6b\x51\xe9\x4c\ +\xf6\x51\xdb\x76\xd0\x75\x9d\x64\x2a\xf5\x03\x29\x65\x5d\x19\xfd\ +\x2d\x02\xbe\x55\xe6\xfc\x22\xc0\x8f\xca\x5a\x5e\x25\x9b\xba\xd2\ +\xea\x96\x2f\xd4\xe9\x7c\x32\xae\xd1\x95\x53\x8f\x02\xe6\x44\x11\ +\x53\x55\xb4\x40\x54\x6a\x9f\xa6\xc9\x5d\x2b\xaf\xbc\x8a\xbc\x65\ +\x5f\x27\xa5\xbc\x6d\x0c\xe3\xde\x03\xcc\x2f\xe3\xba\xaf\xe2\xea\ +\xc2\xe5\x8a\x1f\x0f\x23\x20\xa2\x81\x80\x83\xc0\x1b\x13\x95\xc7\ +\x2c\x2e\xf6\x00\x66\x2e\xb7\x75\xe1\xdc\x79\x7c\x7c\xf1\x12\x94\ +\xe3\x8c\xb5\xea\xd5\xbc\xb2\xa2\xa5\xc4\x1c\x2c\xcf\xf5\xc6\x22\ +\x0a\x5d\x01\x5c\xf2\x8d\x4b\x02\x2d\x7b\x93\x19\x6c\xc5\xcb\x9a\ +\x60\xcd\x44\x10\x53\x6c\x9b\xc0\xee\xcb\x66\xb7\xac\xfc\xf8\x72\ +\x62\xe1\x08\x1d\xdd\x89\x99\xe3\x18\xfb\x2a\xaf\x55\x12\x06\x30\ +\x77\x86\x4e\x8b\x74\x6b\x93\x17\x81\x6f\x7b\x45\x6f\x45\x5d\xa9\ +\x58\xc0\x6b\x91\x42\x7c\x90\x31\xb3\x58\xb6\x05\xd0\x33\xce\x07\ +\x49\x79\xd2\xc2\x48\x2d\x35\x8e\xfe\x72\x40\x2a\xe7\x9c\xdd\x83\ +\x39\x0d\x34\x4e\x84\xc5\xcc\x2b\x46\x8c\x52\xca\xf6\xe9\x3a\x52\ +\x4a\x94\x52\xef\x0e\xc9\xe3\xca\xc1\x9d\x5e\x8e\xe3\x2f\xf1\x90\ +\xdf\x04\xfe\x7c\x0c\x7d\x76\x79\x7d\x0e\xc4\x51\xe0\x93\x95\x26\ +\x66\x56\x91\xff\x6f\xd7\xa4\xa4\xa7\x2f\x45\x2e\x9f\x47\x4a\xf9\ +\xba\x52\xea\xfd\x32\xa4\x88\x02\xb6\x02\x3f\x2b\xe3\xba\x47\xc7\ +\x48\xcc\x0f\x81\x4c\xb5\x4f\xa0\x09\xb0\x5c\xb3\x39\x3c\x11\xab\ +\x52\xb1\xe5\xf7\x64\x38\x14\xe2\x37\xef\xed\xa3\x2b\x99\x24\xe0\ +\xf7\x5b\x5e\x12\x68\x95\x31\xa6\x09\xfc\x73\x99\xf3\x6b\x04\x1e\ +\x2a\xf3\xda\xc3\xb8\x82\x3c\xbb\x3a\x2c\xd2\xf6\xd9\xec\xf9\xf4\ +\x44\x2d\xd7\x23\xa1\x53\x4a\x49\x3a\x9b\xe1\xed\x83\x07\x0a\xda\ +\xca\x3b\x5e\x56\xda\x59\xa2\xbf\x16\x2f\xe0\x36\x7b\x25\x2c\x28\ +\x41\x3e\x17\xc6\xce\x85\x30\x52\x0a\x3d\xaf\x50\x83\x67\xf5\xaf\ +\xc0\xbf\x8d\x32\xcf\x3d\xc0\xa7\x1d\x45\x56\xd3\x05\xcf\x9d\xcc\ +\xd3\x6d\xa9\x42\x9d\x65\x15\x5f\xc4\xc6\x4f\x4c\xe9\x9b\xa5\xe4\ +\xc0\x87\x1f\x70\xaa\xfd\x0c\x01\x7f\x00\x5c\xa1\xfb\x7a\xe0\x49\ +\xef\x6d\x77\x00\x27\x86\xf4\x77\xcc\xcd\x83\x04\xca\xd6\x41\xda\ +\xc4\x66\x1e\x26\x54\x7b\x94\xd6\xc5\x1a\x59\x43\xc3\x97\x55\x28\ +\x71\x76\x74\x07\x38\x30\x34\xe9\x06\xfa\x80\xf7\x81\x47\x3c\xe1\ +\xec\xa4\xa1\x43\x4b\xaf\x4d\xca\x76\x0b\xd1\x42\xc6\x55\x64\xfa\ +\xea\x5c\x88\x29\x76\x73\x1c\x20\x64\x04\x39\xdd\xd9\xc1\x3b\x8d\ +\x07\x89\x86\xc3\x85\xef\x9a\xbd\x04\x6e\x05\xb0\x12\xb8\x0e\xf8\ +\x2f\xef\xbb\x05\x08\xf5\x62\xa1\x5b\xc7\xf6\xa1\xf9\x4c\x2e\x5a\ +\xb4\x93\xda\x25\x0d\xbc\xbf\x4a\xe7\x9d\x9b\x23\xe8\x96\x22\x9a\ +\x70\x30\x7a\x15\xc0\x85\x4a\xf2\xd3\x01\x63\x6f\x04\xfe\xc8\x6b\ +\x2b\x3c\xe1\x2c\x0b\x10\xf6\x0b\x9e\x3e\x99\x67\x4f\xb7\x43\x95\ +\x4f\x8c\x16\x47\x73\x95\x96\x36\xc1\xdd\x36\x41\x29\x45\x4d\xac\ +\x8a\xfd\xcd\xbf\xe7\xda\x65\x57\x52\x1d\x8b\xd3\x97\x49\x0f\x1c\ +\xf8\x88\xf7\xf9\x3e\xe0\xcf\x84\xb4\xa3\x56\x2e\xb4\x1a\x25\x57\ +\xcd\x59\xfa\xcb\x5d\xbe\x60\x12\x3b\x6f\x60\x99\x11\x40\x11\xce\ +\x2a\x92\xb3\x24\xa7\x16\xea\x84\x93\x0e\x20\x88\xb7\xd9\x0f\xa4\ +\xa3\x22\xe4\xe8\x20\x1d\x5e\x53\xf0\x9c\x18\xe1\x75\xc5\xfd\x82\ +\xa3\xbd\x0e\x3f\x3f\x69\xb1\x20\x28\x70\xfa\xaf\x99\x59\x22\x55\ +\xa8\xa8\x18\x5e\xd0\x67\xdc\x14\x56\xd3\xe8\xed\x4b\xb1\xb7\xe9\ +\x20\x45\x97\x6c\xa1\x3a\x50\x7c\xcb\xec\x8b\xa3\x1c\x9d\xd8\x85\ +\x4d\xdf\x09\xc6\x4e\x09\x7f\xa8\x1b\x5f\xb0\x67\x90\xa3\xf9\xb3\ +\x8a\xc6\x1b\xfc\xfc\xfa\x8b\x06\x0d\xb7\x07\xae\x6f\x5b\xa8\x7d\ +\x35\xda\xe5\x10\x49\xa8\x3e\x7f\x5a\x7d\xcd\xe8\x53\xf8\xb3\xca\ +\x35\x3a\x31\xd8\x49\x7f\x76\x22\x4f\x9b\xe9\xe0\x97\xc3\x6a\xb3\ +\x91\xd0\x31\x11\xc4\xcc\x2f\xdc\xab\x94\x22\x1c\x0a\xb3\xe3\xcd\ +\x06\xf6\xec\xdf\x47\x4d\x55\xfc\xac\xc8\x6d\xe7\x42\x58\xd9\x28\ +\x56\x26\x8a\x99\xaa\xf9\x5e\xa4\xfa\x78\xd3\xfc\x4f\x3c\x4f\xdd\ +\xa2\x5f\x2f\xb7\x6d\xff\xbd\xb9\x74\x0c\xc7\xf2\x0f\xf3\x58\x3d\ +\xaf\x08\xa6\x14\x3e\x53\x7d\xff\xad\xf5\x06\x6f\xaf\x33\x48\xcc\ +\x96\x8f\x67\xa3\x1c\x4b\xc7\x04\xbd\xd5\x12\x5b\x07\xe1\xb8\x6a\ +\x5e\x95\x5f\xd0\x69\x2a\x7e\xda\x6a\x11\xd6\x07\x59\x0b\x25\x6a\ +\xad\xff\x9b\x08\x57\x5a\xe8\xb5\x43\x00\x9a\x94\x04\x8d\x20\xef\ +\xfe\xae\x91\x6b\x96\x2e\x23\x1a\x8e\x90\x4a\xa7\x89\xd4\x1d\x46\ +\xd3\x72\x28\x47\xc3\xb6\xfc\x76\xcd\xfc\x7d\x0f\x05\x22\x9d\xcf\ +\xe5\x52\x71\x94\x92\x0f\x20\x78\x02\x94\xe9\xc9\x1a\x17\x7b\x81\ +\xf6\xb0\x37\xe9\x0d\xfe\x0c\x57\x6b\xb6\x43\xeb\x62\xed\x54\xdb\ +\x02\xf9\x88\x6e\xbb\x14\xe6\xfd\x82\xeb\x5e\x31\xa9\x3e\x69\x13\ +\x89\x49\xda\x73\x8a\xaf\x1c\xc8\xd2\x63\x2b\xaa\x7d\x83\xac\xb6\ +\x86\xe2\x47\x50\x9a\x27\x82\x18\x3f\xf0\x27\x85\xbc\x41\x29\x45\ +\x2c\x12\xa1\xf5\x4c\x1b\x3f\x7a\x69\x0b\x1b\xd7\xac\x45\x23\x42\ +\x7c\xde\x7e\x8c\x19\x67\x70\xf2\x06\x08\x85\x9d\x0b\x3e\x9f\x4d\ +\xd5\x7e\x59\x08\xfb\x16\x84\x8a\x03\xcf\x01\xbd\xb8\x1b\x72\xd5\ +\xf4\xe7\x1d\x6f\x00\xd7\x2b\x09\xd2\x82\x48\x42\xfd\x7d\x3e\x40\ +\xef\x40\x43\xb0\x7d\x20\x24\xd8\x40\xfd\x69\x8b\xfa\x76\x8b\x25\ +\x11\x89\x3d\xd8\x5a\xd6\x0d\xe8\x77\x28\xde\x9b\x08\x57\x2a\x08\ +\x58\x83\x44\xee\xaa\xe8\x0c\x9a\x0e\x1f\x62\xd7\x9e\xbd\x5c\x70\ +\x61\x1e\xc7\x51\xe4\x33\x31\x2c\x33\x8c\x95\x8d\xa0\x1c\x0d\x21\ +\xec\xaf\x03\x49\xef\xb6\xcf\x7b\x7a\x4f\xf5\x90\xa4\x72\x23\x70\ +\x51\x21\x4b\x56\x82\x5f\xe8\x39\x38\xdb\xf2\x70\xe4\x0a\x9d\x50\ +\x48\xf2\x50\xb3\xc9\x7d\xcd\x26\x97\x85\x87\x91\x82\xf7\xf2\x46\ +\x42\xef\x68\x35\xd4\xb9\x10\xb3\xd2\x6b\x03\x24\x1a\x45\x75\x2c\ +\x46\xd3\x87\x27\x68\xcd\x6c\xa3\xa6\x26\x87\xca\xfb\x41\x89\xfe\ +\xe6\x9a\xf0\x4f\xc6\x30\xce\xd3\xc3\xcc\x3c\xaf\xf0\xcf\xd5\xd9\ +\x1a\x87\x6d\xc7\xf2\xc8\x91\x1f\xe4\x52\xe0\xb3\x45\xfa\x7c\xd7\ +\xab\xa1\x26\x84\x18\x0d\xb8\x7f\x58\xdd\x1f\x08\x70\xa6\xab\x9d\ +\xa3\xc7\xdb\x09\xf8\x43\x6e\x76\x3b\x5c\x1a\xb8\x76\x0c\xe3\x7c\ +\x65\xa8\xcb\x4b\x1b\x8c\x19\x92\x9d\x61\x38\xd2\x6d\x53\xeb\x17\ +\x23\x25\x5c\xf7\x01\xc1\x22\x7d\xbe\x5a\x29\x31\xbc\x18\x6e\xf3\ +\x12\xb8\x41\x2e\xe5\xf7\xf9\x99\x11\x35\x10\xc2\x61\x84\x6d\xab\ +\x1b\x87\x5a\xda\x28\xb8\x05\xb8\x7a\xd0\x18\x80\x50\x8a\xd9\x9a\ +\x20\xa4\x8b\x42\xb1\x38\x10\x97\xe1\x9e\xfd\x1b\x09\x09\x4f\xac\ +\x9f\x50\x62\xc0\x3d\x5a\x36\xd8\x94\x34\x48\x26\x1d\x7c\x3e\x81\ +\x1c\x3e\xc2\xb2\x71\x8c\x71\xc5\xe0\x52\x04\xb2\x59\x45\x22\xe1\ +\xa0\x69\x23\x5e\xff\x6d\xcf\xa2\x47\xc2\x2f\x06\xc4\xb8\x09\x25\ +\xe6\x06\x60\xd3\xa0\xca\xb3\x4a\xe3\x85\x2d\x7d\xbc\xf4\x52\x9a\ +\x48\x54\x0c\xb5\x9a\xe0\x38\xc6\x88\xf4\xc7\x31\x88\x44\x05\x1d\ +\x1d\x0e\xf5\xdb\xd2\xc4\x62\xc3\x9e\xff\x2f\x4a\x04\x5d\x87\x12\ +\xdb\xcc\x95\x26\xa6\xa0\x9b\xdc\x3c\xf4\x8d\xbe\xf6\x6a\x1f\x9a\ +\x14\x18\x86\x60\xc0\xc1\x86\xd6\x71\xf4\x7f\xcc\x75\x53\x30\x0c\ +\x81\x26\x05\x5b\xb6\xf4\x91\x4e\xab\xa1\x16\xb9\x1c\xd8\x5c\xa2\ +\x9f\x27\xcb\x55\xf4\x2a\x45\x4c\x00\xd8\x52\x30\x79\xa5\x20\x16\ +\x93\xb4\xb7\xdb\x6c\x7e\xb2\x97\x70\x58\x12\x0c\x9e\xb5\x9c\x06\ +\xdc\xf4\xa3\x5c\x24\x80\x77\x94\x82\x60\x50\x10\x0e\x4b\x36\x3f\ +\xd9\xcb\xf6\xfa\xb4\xbb\xe1\x3f\x58\x54\x7b\x61\xa0\x75\x0d\x41\ +\x4f\x19\xf2\x45\xc5\x89\x01\x88\x01\xbb\xf0\xb6\x5b\xa4\x84\x70\ +\x58\x52\x5f\x9f\xe6\xf1\xc7\x92\x18\x86\x20\x5e\x2d\x11\x82\x43\ +\x4a\xf1\xe3\x72\x3b\x55\x8a\xa7\x84\xe0\x54\xbc\x5a\x62\x18\x82\ +\xc7\x1f\x4b\x52\x5f\x9f\xa6\xae\x4e\x43\xd7\x07\x2d\xcd\x6f\x52\ +\x7a\x4b\xe6\x7e\xdc\x43\x90\x93\x4e\x0c\xb8\xe7\x53\x76\x01\x9f\ +\x2d\xc4\x95\x59\xb3\x34\x76\xec\xc8\xf0\xd4\xe6\x1e\x4e\xb4\xda\ +\x84\x42\x12\x21\xf8\x47\x2f\x97\x18\x0d\xdb\x85\xe0\x81\x50\x48\ +\x72\xa2\xd5\xe6\xa9\xcd\x3d\xec\xd8\x91\x61\xd6\x2c\xed\x6c\xbc\ +\xf1\xa4\x87\x9d\x1e\x39\xc5\xf0\x3c\xf0\x44\x25\x15\xbc\xf1\x60\ +\x06\xee\x79\xbb\x7b\x0a\x96\x53\x57\xa7\xb1\x7b\x77\x96\x4d\xf7\ +\x76\xd2\xd0\x90\x61\xf6\x6c\x2d\x19\x08\x88\x5b\x95\xe2\x99\x22\ +\x56\x82\xcf\x27\x36\x87\xc2\x72\x43\x5d\x9d\x66\x35\x34\x64\xd8\ +\x74\x6f\x27\xbb\x77\x67\xa9\xab\xd3\x06\xc6\x95\xbb\x70\xf7\xc3\ +\x4b\x59\xca\x51\xe0\x6b\x63\x7d\x88\xd1\xce\xc7\xb4\x95\xd0\x7d\ +\xcb\xc1\x2b\xc0\xc3\xc0\xdb\x42\x40\x26\xe3\x06\xcb\x4b\x2f\xf5\ +\xb1\xe1\xf6\x30\x2b\x56\xf8\xc9\x66\x59\xe3\xe5\x2a\x8b\xbc\xe4\ +\xb9\xc9\xe7\x63\x7b\x22\xe1\xfc\xaa\xa9\x29\xcf\xae\x9d\x69\x9a\ +\x9b\xf3\x38\x0e\x03\xe3\xd4\x95\x9e\x6e\x7c\xe7\x28\xe3\xf7\x7a\ +\x8a\xe2\xc1\x11\x05\xe5\xc6\xc6\x8a\x17\x91\x63\x49\x00\xd7\x01\ +\x4f\x2b\xc5\x0f\x42\x21\xf1\xdb\x5c\x4e\xf1\xd6\x5b\x26\xdd\xdd\ +\x0e\x6d\xa7\x42\x98\x39\xb5\x1d\xc5\xf6\x81\xaf\x27\x1a\x91\xec\ +\xdd\x9b\x65\xcf\x6f\x4c\x14\x10\x89\x9c\x5d\xd9\xae\xc2\xdd\xb6\ +\xfd\x2b\x8a\x6f\xbb\x14\x60\x79\xe3\x1f\x1c\xcf\xc4\x27\xda\x62\ +\x86\xe6\x10\xdb\x81\x6d\x52\xb2\xd5\x34\xd5\xc9\x64\xb7\x63\x0b\ +\x09\xca\x01\xdb\xe9\x4f\x0e\x1d\xc7\x0d\xdc\x91\xb0\x90\xca\x5d\ +\x6d\xd6\x7a\xed\x73\x94\x77\x5a\xaa\x13\xb8\xc3\x73\xb3\xe2\x5b\ +\x10\x25\x2c\x66\x32\x89\x19\x88\x6e\xe0\x03\xdc\x23\xf3\x47\x94\ +\xe2\xb4\x52\xee\xc9\x04\x21\xf0\x0b\x41\x2d\xee\x01\xeb\x05\xb8\ +\xfb\xe7\x63\xd9\x02\x3e\x82\xbb\x17\xb5\x77\xb4\x0b\x3f\x4a\x57\ +\x2a\x86\xaa\x81\xd5\xb9\x10\x6e\xab\x00\x9e\x05\xfe\xce\xcb\x7d\ +\xce\x09\xe7\xcb\xef\x44\xb6\x01\xdf\xf0\x2c\x25\x51\x89\x0e\xf5\ +\xf3\x80\x94\xc7\xbc\x42\xf6\x78\x25\x3b\x1d\x8d\x18\x35\x85\x2d\ +\xe4\x45\xdc\xd3\x56\x7b\x27\x62\x00\xbd\x8c\x58\x30\x55\xd0\x0d\ +\xbc\x0d\xfc\xd2\x53\x00\x3b\x26\x72\xb0\xd1\x88\x69\xc1\xdd\x5c\ +\x33\x27\x91\x00\xd3\x4b\xcc\x3a\xbd\xaa\xba\x19\xd8\xef\xfd\x7b\ +\x78\xb2\x26\x21\xa6\xff\x4c\xca\xf9\xbd\x2a\x4d\x13\x33\x4d\xcc\ +\x34\x31\xd3\xc4\x4c\x13\x73\x3e\xe0\xff\x07\x00\xd9\x01\xc4\xf4\ +\xd1\x48\x28\x2f\x00\x00\x00\x00\x49\x45\x4e\x44\xae\x42\x60\x82\ +\ +\x00\x00\x10\xfe\ +\x89\ +\x50\x4e\x47\x0d\x0a\x1a\x0a\x00\x00\x00\x0d\x49\x48\x44\x52\x00\ +\x00\x00\x40\x00\x00\x00\x40\x08\x06\x00\x00\x00\xaa\x69\x71\xde\ +\x00\x00\x00\x09\x70\x48\x59\x73\x00\x00\x0b\x13\x00\x00\x0b\x13\ +\x01\x00\x9a\x9c\x18\x00\x00\x0a\x4f\x69\x43\x43\x50\x50\x68\x6f\ +\x74\x6f\x73\x68\x6f\x70\x20\x49\x43\x43\x20\x70\x72\x6f\x66\x69\ +\x6c\x65\x00\x00\x78\xda\x9d\x53\x67\x54\x53\xe9\x16\x3d\xf7\xde\ +\xf4\x42\x4b\x88\x80\x94\x4b\x6f\x52\x15\x08\x20\x52\x42\x8b\x80\ +\x14\x91\x26\x2a\x21\x09\x10\x4a\x88\x21\xa1\xd9\x15\x51\xc1\x11\ +\x45\x45\x04\x1b\xc8\xa0\x88\x03\x8e\x8e\x80\x8c\x15\x51\x2c\x0c\ +\x8a\x0a\xd8\x07\xe4\x21\xa2\x8e\x83\xa3\x88\x8a\xca\xfb\xe1\x7b\ +\xa3\x6b\xd6\xbc\xf7\xe6\xcd\xfe\xb5\xd7\x3e\xe7\xac\xf3\x9d\xb3\ +\xcf\x07\xc0\x08\x0c\x96\x48\x33\x51\x35\x80\x0c\xa9\x42\x1e\x11\ +\xe0\x83\xc7\xc4\xc6\xe1\xe4\x2e\x40\x81\x0a\x24\x70\x00\x10\x08\ +\xb3\x64\x21\x73\xfd\x23\x01\x00\xf8\x7e\x3c\x3c\x2b\x22\xc0\x07\ +\xbe\x00\x01\x78\xd3\x0b\x08\x00\xc0\x4d\x9b\xc0\x30\x1c\x87\xff\ +\x0f\xea\x42\x99\x5c\x01\x80\x84\x01\xc0\x74\x91\x38\x4b\x08\x80\ +\x14\x00\x40\x7a\x8e\x42\xa6\x00\x40\x46\x01\x80\x9d\x98\x26\x53\ +\x00\xa0\x04\x00\x60\xcb\x63\x62\xe3\x00\x50\x2d\x00\x60\x27\x7f\ +\xe6\xd3\x00\x80\x9d\xf8\x99\x7b\x01\x00\x5b\x94\x21\x15\x01\xa0\ +\x91\x00\x20\x13\x65\x88\x44\x00\x68\x3b\x00\xac\xcf\x56\x8a\x45\ +\x00\x58\x30\x00\x14\x66\x4b\xc4\x39\x00\xd8\x2d\x00\x30\x49\x57\ +\x66\x48\x00\xb0\xb7\x00\xc0\xce\x10\x0b\xb2\x00\x08\x0c\x00\x30\ +\x51\x88\x85\x29\x00\x04\x7b\x00\x60\xc8\x23\x23\x78\x00\x84\x99\ +\x00\x14\x46\xf2\x57\x3c\xf1\x2b\xae\x10\xe7\x2a\x00\x00\x78\x99\ +\xb2\x3c\xb9\x24\x39\x45\x81\x5b\x08\x2d\x71\x07\x57\x57\x2e\x1e\ +\x28\xce\x49\x17\x2b\x14\x36\x61\x02\x61\x9a\x40\x2e\xc2\x79\x99\ +\x19\x32\x81\x34\x0f\xe0\xf3\xcc\x00\x00\xa0\x91\x15\x11\xe0\x83\ +\xf3\xfd\x78\xce\x0e\xae\xce\xce\x36\x8e\xb6\x0e\x5f\x2d\xea\xbf\ +\x06\xff\x22\x62\x62\xe3\xfe\xe5\xcf\xab\x70\x40\x00\x00\xe1\x74\ +\x7e\xd1\xfe\x2c\x2f\xb3\x1a\x80\x3b\x06\x80\x6d\xfe\xa2\x25\xee\ +\x04\x68\x5e\x0b\xa0\x75\xf7\x8b\x66\xb2\x0f\x40\xb5\x00\xa0\xe9\ +\xda\x57\xf3\x70\xf8\x7e\x3c\x3c\x45\xa1\x90\xb9\xd9\xd9\xe5\xe4\ +\xe4\xd8\x4a\xc4\x42\x5b\x61\xca\x57\x7d\xfe\x67\xc2\x5f\xc0\x57\ +\xfd\x6c\xf9\x7e\x3c\xfc\xf7\xf5\xe0\xbe\xe2\x24\x81\x32\x5d\x81\ +\x47\x04\xf8\xe0\xc2\xcc\xf4\x4c\xa5\x1c\xcf\x92\x09\x84\x62\xdc\ +\xe6\x8f\x47\xfc\xb7\x0b\xff\xfc\x1d\xd3\x22\xc4\x49\x62\xb9\x58\ +\x2a\x14\xe3\x51\x12\x71\x8e\x44\x9a\x8c\xf3\x32\xa5\x22\x89\x42\ +\x92\x29\xc5\x25\xd2\xff\x64\xe2\xdf\x2c\xfb\x03\x3e\xdf\x35\x00\ +\xb0\x6a\x3e\x01\x7b\x91\x2d\xa8\x5d\x63\x03\xf6\x4b\x27\x10\x58\ +\x74\xc0\xe2\xf7\x00\x00\xf2\xbb\x6f\xc1\xd4\x28\x08\x03\x80\x68\ +\x83\xe1\xcf\x77\xff\xef\x3f\xfd\x47\xa0\x25\x00\x80\x66\x49\x92\ +\x71\x00\x00\x5e\x44\x24\x2e\x54\xca\xb3\x3f\xc7\x08\x00\x00\x44\ +\xa0\x81\x2a\xb0\x41\x1b\xf4\xc1\x18\x2c\xc0\x06\x1c\xc1\x05\xdc\ +\xc1\x0b\xfc\x60\x36\x84\x42\x24\xc4\xc2\x42\x10\x42\x0a\x64\x80\ +\x1c\x72\x60\x29\xac\x82\x42\x28\x86\xcd\xb0\x1d\x2a\x60\x2f\xd4\ +\x40\x1d\x34\xc0\x51\x68\x86\x93\x70\x0e\x2e\xc2\x55\xb8\x0e\x3d\ +\x70\x0f\xfa\x61\x08\x9e\xc1\x28\xbc\x81\x09\x04\x41\xc8\x08\x13\ +\x61\x21\xda\x88\x01\x62\x8a\x58\x23\x8e\x08\x17\x99\x85\xf8\x21\ +\xc1\x48\x04\x12\x8b\x24\x20\xc9\x88\x14\x51\x22\x4b\x91\x35\x48\ +\x31\x52\x8a\x54\x20\x55\x48\x1d\xf2\x3d\x72\x02\x39\x87\x5c\x46\ +\xba\x91\x3b\xc8\x00\x32\x82\xfc\x86\xbc\x47\x31\x94\x81\xb2\x51\ +\x3d\xd4\x0c\xb5\x43\xb9\xa8\x37\x1a\x84\x46\xa2\x0b\xd0\x64\x74\ +\x31\x9a\x8f\x16\xa0\x9b\xd0\x72\xb4\x1a\x3d\x8c\x36\xa1\xe7\xd0\ +\xab\x68\x0f\xda\x8f\x3e\x43\xc7\x30\xc0\xe8\x18\x07\x33\xc4\x6c\ +\x30\x2e\xc6\xc3\x42\xb1\x38\x2c\x09\x93\x63\xcb\xb1\x22\xac\x0c\ +\xab\xc6\x1a\xb0\x56\xac\x03\xbb\x89\xf5\x63\xcf\xb1\x77\x04\x12\ +\x81\x45\xc0\x09\x36\x04\x77\x42\x20\x61\x1e\x41\x48\x58\x4c\x58\ +\x4e\xd8\x48\xa8\x20\x1c\x24\x34\x11\xda\x09\x37\x09\x03\x84\x51\ +\xc2\x27\x22\x93\xa8\x4b\xb4\x26\xba\x11\xf9\xc4\x18\x62\x32\x31\ +\x87\x58\x48\x2c\x23\xd6\x12\x8f\x13\x2f\x10\x7b\x88\x43\xc4\x37\ +\x24\x12\x89\x43\x32\x27\xb9\x90\x02\x49\xb1\xa4\x54\xd2\x12\xd2\ +\x46\xd2\x6e\x52\x23\xe9\x2c\xa9\x9b\x34\x48\x1a\x23\x93\xc9\xda\ +\x64\x6b\xb2\x07\x39\x94\x2c\x20\x2b\xc8\x85\xe4\x9d\xe4\xc3\xe4\ +\x33\xe4\x1b\xe4\x21\xf2\x5b\x0a\x9d\x62\x40\x71\xa4\xf8\x53\xe2\ +\x28\x52\xca\x6a\x4a\x19\xe5\x10\xe5\x34\xe5\x06\x65\x98\x32\x41\ +\x55\xa3\x9a\x52\xdd\xa8\xa1\x54\x11\x35\x8f\x5a\x42\xad\xa1\xb6\ +\x52\xaf\x51\x87\xa8\x13\x34\x75\x9a\x39\xcd\x83\x16\x49\x4b\xa5\ +\xad\xa2\x95\xd3\x1a\x68\x17\x68\xf7\x69\xaf\xe8\x74\xba\x11\xdd\ +\x95\x1e\x4e\x97\xd0\x57\xd2\xcb\xe9\x47\xe8\x97\xe8\x03\xf4\x77\ +\x0c\x0d\x86\x15\x83\xc7\x88\x67\x28\x19\x9b\x18\x07\x18\x67\x19\ +\x77\x18\xaf\x98\x4c\xa6\x19\xd3\x8b\x19\xc7\x54\x30\x37\x31\xeb\ +\x98\xe7\x99\x0f\x99\x6f\x55\x58\x2a\xb6\x2a\x7c\x15\x91\xca\x0a\ +\x95\x4a\x95\x26\x95\x1b\x2a\x2f\x54\xa9\xaa\xa6\xaa\xde\xaa\x0b\ +\x55\xf3\x55\xcb\x54\x8f\xa9\x5e\x53\x7d\xae\x46\x55\x33\x53\xe3\ +\xa9\x09\xd4\x96\xab\x55\xaa\x9d\x50\xeb\x53\x1b\x53\x67\xa9\x3b\ +\xa8\x87\xaa\x67\xa8\x6f\x54\x3f\xa4\x7e\x59\xfd\x89\x06\x59\xc3\ +\x4c\xc3\x4f\x43\xa4\x51\xa0\xb1\x5f\xe3\xbc\xc6\x20\x0b\x63\x19\ +\xb3\x78\x2c\x21\x6b\x0d\xab\x86\x75\x81\x35\xc4\x26\xb1\xcd\xd9\ +\x7c\x76\x2a\xbb\x98\xfd\x1d\xbb\x8b\x3d\xaa\xa9\xa1\x39\x43\x33\ +\x4a\x33\x57\xb3\x52\xf3\x94\x66\x3f\x07\xe3\x98\x71\xf8\x9c\x74\ +\x4e\x09\xe7\x28\xa7\x97\xf3\x7e\x8a\xde\x14\xef\x29\xe2\x29\x1b\ +\xa6\x34\x4c\xb9\x31\x65\x5c\x6b\xaa\x96\x97\x96\x58\xab\x48\xab\ +\x51\xab\x47\xeb\xbd\x36\xae\xed\xa7\x9d\xa6\xbd\x45\xbb\x59\xfb\ +\x81\x0e\x41\xc7\x4a\x27\x5c\x27\x47\x67\x8f\xce\x05\x9d\xe7\x53\ +\xd9\x53\xdd\xa7\x0a\xa7\x16\x4d\x3d\x3a\xf5\xae\x2e\xaa\x6b\xa5\ +\x1b\xa1\xbb\x44\x77\xbf\x6e\xa7\xee\x98\x9e\xbe\x5e\x80\x9e\x4c\ +\x6f\xa7\xde\x79\xbd\xe7\xfa\x1c\x7d\x2f\xfd\x54\xfd\x6d\xfa\xa7\ +\xf5\x47\x0c\x58\x06\xb3\x0c\x24\x06\xdb\x0c\xce\x18\x3c\xc5\x35\ +\x71\x6f\x3c\x1d\x2f\xc7\xdb\xf1\x51\x43\x5d\xc3\x40\x43\xa5\x61\ +\x95\x61\x97\xe1\x84\x91\xb9\xd1\x3c\xa3\xd5\x46\x8d\x46\x0f\x8c\ +\x69\xc6\x5c\xe3\x24\xe3\x6d\xc6\x6d\xc6\xa3\x26\x06\x26\x21\x26\ +\x4b\x4d\xea\x4d\xee\x9a\x52\x4d\xb9\xa6\x29\xa6\x3b\x4c\x3b\x4c\ +\xc7\xcd\xcc\xcd\xa2\xcd\xd6\x99\x35\x9b\x3d\x31\xd7\x32\xe7\x9b\ +\xe7\x9b\xd7\x9b\xdf\xb7\x60\x5a\x78\x5a\x2c\xb6\xa8\xb6\xb8\x65\ +\x49\xb2\xe4\x5a\xa6\x59\xee\xb6\xbc\x6e\x85\x5a\x39\x59\xa5\x58\ +\x55\x5a\x5d\xb3\x46\xad\x9d\xad\x25\xd6\xbb\xad\xbb\xa7\x11\xa7\ +\xb9\x4e\x93\x4e\xab\x9e\xd6\x67\xc3\xb0\xf1\xb6\xc9\xb6\xa9\xb7\ +\x19\xb0\xe5\xd8\x06\xdb\xae\xb6\x6d\xb6\x7d\x61\x67\x62\x17\x67\ +\xb7\xc5\xae\xc3\xee\x93\xbd\x93\x7d\xba\x7d\x8d\xfd\x3d\x07\x0d\ +\x87\xd9\x0e\xab\x1d\x5a\x1d\x7e\x73\xb4\x72\x14\x3a\x56\x3a\xde\ +\x9a\xce\x9c\xee\x3f\x7d\xc5\xf4\x96\xe9\x2f\x67\x58\xcf\x10\xcf\ +\xd8\x33\xe3\xb6\x13\xcb\x29\xc4\x69\x9d\x53\x9b\xd3\x47\x67\x17\ +\x67\xb9\x73\x83\xf3\x88\x8b\x89\x4b\x82\xcb\x2e\x97\x3e\x2e\x9b\ +\x1b\xc6\xdd\xc8\xbd\xe4\x4a\x74\xf5\x71\x5d\xe1\x7a\xd2\xf5\x9d\ +\x9b\xb3\x9b\xc2\xed\xa8\xdb\xaf\xee\x36\xee\x69\xee\x87\xdc\x9f\ +\xcc\x34\x9f\x29\x9e\x59\x33\x73\xd0\xc3\xc8\x43\xe0\x51\xe5\xd1\ +\x3f\x0b\x9f\x95\x30\x6b\xdf\xac\x7e\x4f\x43\x4f\x81\x67\xb5\xe7\ +\x23\x2f\x63\x2f\x91\x57\xad\xd7\xb0\xb7\xa5\x77\xaa\xf7\x61\xef\ +\x17\x3e\xf6\x3e\x72\x9f\xe3\x3e\xe3\x3c\x37\xde\x32\xde\x59\x5f\ +\xcc\x37\xc0\xb7\xc8\xb7\xcb\x4f\xc3\x6f\x9e\x5f\x85\xdf\x43\x7f\ +\x23\xff\x64\xff\x7a\xff\xd1\x00\xa7\x80\x25\x01\x67\x03\x89\x81\ +\x41\x81\x5b\x02\xfb\xf8\x7a\x7c\x21\xbf\x8e\x3f\x3a\xdb\x65\xf6\ +\xb2\xd9\xed\x41\x8c\xa0\xb9\x41\x15\x41\x8f\x82\xad\x82\xe5\xc1\ +\xad\x21\x68\xc8\xec\x90\xad\x21\xf7\xe7\x98\xce\x91\xce\x69\x0e\ +\x85\x50\x7e\xe8\xd6\xd0\x07\x61\xe6\x61\x8b\xc3\x7e\x0c\x27\x85\ +\x87\x85\x57\x86\x3f\x8e\x70\x88\x58\x1a\xd1\x31\x97\x35\x77\xd1\ +\xdc\x43\x73\xdf\x44\xfa\x44\x96\x44\xde\x9b\x67\x31\x4f\x39\xaf\ +\x2d\x4a\x35\x2a\x3e\xaa\x2e\x6a\x3c\xda\x37\xba\x34\xba\x3f\xc6\ +\x2e\x66\x59\xcc\xd5\x58\x9d\x58\x49\x6c\x4b\x1c\x39\x2e\x2a\xae\ +\x36\x6e\x6c\xbe\xdf\xfc\xed\xf3\x87\xe2\x9d\xe2\x0b\xe3\x7b\x17\ +\x98\x2f\xc8\x5d\x70\x79\xa1\xce\xc2\xf4\x85\xa7\x16\xa9\x2e\x12\ +\x2c\x3a\x96\x40\x4c\x88\x4e\x38\x94\xf0\x41\x10\x2a\xa8\x16\x8c\ +\x25\xf2\x13\x77\x25\x8e\x0a\x79\xc2\x1d\xc2\x67\x22\x2f\xd1\x36\ +\xd1\x88\xd8\x43\x5c\x2a\x1e\x4e\xf2\x48\x2a\x4d\x7a\x92\xec\x91\ +\xbc\x35\x79\x24\xc5\x33\xa5\x2c\xe5\xb9\x84\x27\xa9\x90\xbc\x4c\ +\x0d\x4c\xdd\x9b\x3a\x9e\x16\x9a\x76\x20\x6d\x32\x3d\x3a\xbd\x31\ +\x83\x92\x91\x90\x71\x42\xaa\x21\x4d\x93\xb6\x67\xea\x67\xe6\x66\ +\x76\xcb\xac\x65\x85\xb2\xfe\xc5\x6e\x8b\xb7\x2f\x1e\x95\x07\xc9\ +\x6b\xb3\x90\xac\x05\x59\x2d\x0a\xb6\x42\xa6\xe8\x54\x5a\x28\xd7\ +\x2a\x07\xb2\x67\x65\x57\x66\xbf\xcd\x89\xca\x39\x96\xab\x9e\x2b\ +\xcd\xed\xcc\xb3\xca\xdb\x90\x37\x9c\xef\x9f\xff\xed\x12\xc2\x12\ +\xe1\x92\xb6\xa5\x86\x4b\x57\x2d\x1d\x58\xe6\xbd\xac\x6a\x39\xb2\ +\x3c\x71\x79\xdb\x0a\xe3\x15\x05\x2b\x86\x56\x06\xac\x3c\xb8\x8a\ +\xb6\x2a\x6d\xd5\x4f\xab\xed\x57\x97\xae\x7e\xbd\x26\x7a\x4d\x6b\ +\x81\x5e\xc1\xca\x82\xc1\xb5\x01\x6b\xeb\x0b\x55\x0a\xe5\x85\x7d\ +\xeb\xdc\xd7\xed\x5d\x4f\x58\x2f\x59\xdf\xb5\x61\xfa\x86\x9d\x1b\ +\x3e\x15\x89\x8a\xae\x14\xdb\x17\x97\x15\x7f\xd8\x28\xdc\x78\xe5\ +\x1b\x87\x6f\xca\xbf\x99\xdc\x94\xb4\xa9\xab\xc4\xb9\x64\xcf\x66\ +\xd2\x66\xe9\xe6\xde\x2d\x9e\x5b\x0e\x96\xaa\x97\xe6\x97\x0e\x6e\ +\x0d\xd9\xda\xb4\x0d\xdf\x56\xb4\xed\xf5\xf6\x45\xdb\x2f\x97\xcd\ +\x28\xdb\xbb\x83\xb6\x43\xb9\xa3\xbf\x3c\xb8\xbc\x65\xa7\xc9\xce\ +\xcd\x3b\x3f\x54\xa4\x54\xf4\x54\xfa\x54\x36\xee\xd2\xdd\xb5\x61\ +\xd7\xf8\x6e\xd1\xee\x1b\x7b\xbc\xf6\x34\xec\xd5\xdb\x5b\xbc\xf7\ +\xfd\x3e\xc9\xbe\xdb\x55\x01\x55\x4d\xd5\x66\xd5\x65\xfb\x49\xfb\ +\xb3\xf7\x3f\xae\x89\xaa\xe9\xf8\x96\xfb\x6d\x5d\xad\x4e\x6d\x71\ +\xed\xc7\x03\xd2\x03\xfd\x07\x23\x0e\xb6\xd7\xb9\xd4\xd5\x1d\xd2\ +\x3d\x54\x52\x8f\xd6\x2b\xeb\x47\x0e\xc7\x1f\xbe\xfe\x9d\xef\x77\ +\x2d\x0d\x36\x0d\x55\x8d\x9c\xc6\xe2\x23\x70\x44\x79\xe4\xe9\xf7\ +\x09\xdf\xf7\x1e\x0d\x3a\xda\x76\x8c\x7b\xac\xe1\x07\xd3\x1f\x76\ +\x1d\x67\x1d\x2f\x6a\x42\x9a\xf2\x9a\x46\x9b\x53\x9a\xfb\x5b\x62\ +\x5b\xba\x4f\xcc\x3e\xd1\xd6\xea\xde\x7a\xfc\x47\xdb\x1f\x0f\x9c\ +\x34\x3c\x59\x79\x4a\xf3\x54\xc9\x69\xda\xe9\x82\xd3\x93\x67\xf2\ +\xcf\x8c\x9d\x95\x9d\x7d\x7e\x2e\xf9\xdc\x60\xdb\xa2\xb6\x7b\xe7\ +\x63\xce\xdf\x6a\x0f\x6f\xef\xba\x10\x74\xe1\xd2\x45\xff\x8b\xe7\ +\x3b\xbc\x3b\xce\x5c\xf2\xb8\x74\xf2\xb2\xdb\xe5\x13\x57\xb8\x57\ +\x9a\xaf\x3a\x5f\x6d\xea\x74\xea\x3c\xfe\x93\xd3\x4f\xc7\xbb\x9c\ +\xbb\x9a\xae\xb9\x5c\x6b\xb9\xee\x7a\xbd\xb5\x7b\x66\xf7\xe9\x1b\ +\x9e\x37\xce\xdd\xf4\xbd\x79\xf1\x16\xff\xd6\xd5\x9e\x39\x3d\xdd\ +\xbd\xf3\x7a\x6f\xf7\xc5\xf7\xf5\xdf\x16\xdd\x7e\x72\x27\xfd\xce\ +\xcb\xbb\xd9\x77\x27\xee\xad\xbc\x4f\xbc\x5f\xf4\x40\xed\x41\xd9\ +\x43\xdd\x87\xd5\x3f\x5b\xfe\xdc\xd8\xef\xdc\x7f\x6a\xc0\x77\xa0\ +\xf3\xd1\xdc\x47\xf7\x06\x85\x83\xcf\xfe\x91\xf5\x8f\x0f\x43\x05\ +\x8f\x99\x8f\xcb\x86\x0d\x86\xeb\x9e\x38\x3e\x39\x39\xe2\x3f\x72\ +\xfd\xe9\xfc\xa7\x43\xcf\x64\xcf\x26\x9e\x17\xfe\xa2\xfe\xcb\xae\ +\x17\x16\x2f\x7e\xf8\xd5\xeb\xd7\xce\xd1\x98\xd1\xa1\x97\xf2\x97\ +\x93\xbf\x6d\x7c\xa5\xfd\xea\xc0\xeb\x19\xaf\xdb\xc6\xc2\xc6\x1e\ +\xbe\xc9\x78\x33\x31\x5e\xf4\x56\xfb\xed\xc1\x77\xdc\x77\x1d\xef\ +\xa3\xdf\x0f\x4f\xe4\x7c\x20\x7f\x28\xff\x68\xf9\xb1\xf5\x53\xd0\ +\xa7\xfb\x93\x19\x93\x93\xff\x04\x03\x98\xf3\xfc\x63\x33\x2d\xdb\ +\x00\x00\x00\x20\x63\x48\x52\x4d\x00\x00\x7a\x25\x00\x00\x80\x83\ +\x00\x00\xf9\xff\x00\x00\x80\xe9\x00\x00\x75\x30\x00\x00\xea\x60\ +\x00\x00\x3a\x98\x00\x00\x17\x6f\x92\x5f\xc5\x46\x00\x00\x06\x29\ +\x49\x44\x41\x54\x78\xda\xec\x9b\x6b\x4c\x14\x57\x14\xc7\xff\xb3\ +\x6f\x58\xc0\x05\xb3\xac\xb0\xca\x52\x77\xc1\x05\xe4\xb9\x01\x8a\ +\x3c\x8d\x58\xa5\x8d\x52\x51\x13\x8d\x69\x6b\x4d\x63\x6a\x6a\x1a\ +\xb5\x8d\x89\x69\xad\xad\xad\x36\xb5\x35\x4d\x5b\x5b\xfb\x48\x34\ +\x35\xa5\x26\x8d\x62\x51\x12\x4b\x7d\xd0\xa2\xc8\x43\xde\xe0\x22\ +\x2b\x20\xca\x4b\xc1\x07\x08\x0b\xfb\x98\x65\xfb\x41\x34\xe1\x51\ +\x76\x67\x76\x66\x43\xc2\x9c\x4f\x93\x99\x73\xce\xdc\xfb\xcb\xdc\ +\x73\xee\x3d\xf7\x0e\xb1\x61\x6f\x8a\x1d\xb3\x58\x78\x98\xe5\xc2\ +\x01\xe0\x00\x70\x00\x38\x00\x1c\x00\x0e\x00\x07\x80\x03\x30\x6b\ +\x45\xc0\xa6\xf3\xc0\xb9\x2a\x24\x47\xbe\x84\x68\x75\x22\x6e\xb4\ +\x57\xe1\xe4\xa5\xa3\x0e\x6d\xd6\xa4\x6e\x46\x8c\x26\x09\x4d\x77\ +\x6a\x50\x5c\x77\x1e\xdd\x0f\xef\xb0\x0a\x80\x60\x63\x2d\x10\xaf\ +\x4d\x47\x62\xd8\x52\x84\x07\xc7\x8d\xbb\xdf\xd0\x56\x81\xa3\xf9\ +\x9f\xfd\xaf\xdd\xe6\xac\x5d\x48\xd0\x66\x8c\xbb\xa7\x6f\xaf\x46\ +\x99\xfe\x32\x2a\x9b\x8b\x59\x01\xc0\x5f\x9c\x1e\xf4\x31\x93\x0e\ +\x37\x2d\xdf\x8e\xd5\xc9\xaf\x41\x2e\x0b\x98\xf4\x4c\xe1\xab\x84\ +\x5a\x19\x8e\x8a\x9b\xff\x4c\x7a\xb6\x75\xd5\x1e\xe8\x42\x53\x27\ +\xdd\x97\xcb\x02\x10\x1b\xb2\x04\x72\xdf\x00\xd4\xb6\x94\xce\xec\ +\x21\x40\x10\x04\x62\x35\x4b\xa6\xd5\xd1\x06\x45\x63\xf7\xc6\xc3\ +\x68\xbe\x5b\x07\x89\xc8\x13\x23\x66\x23\xd4\xca\x30\x68\x94\x11\ +\xd3\xda\xc5\x85\xa4\x20\xf7\xc2\x11\x58\x49\xcb\xcc\x05\xc0\xe7\ +\xf1\x61\x21\xcd\xf0\x84\xd7\xb4\x7a\x2a\x85\x06\x2a\x85\x86\x92\ +\x6f\x8b\xd5\x04\x01\x5f\xc8\x38\x00\x1e\xb3\x5f\x00\x0f\x04\x88\ +\xd9\x9b\x06\xad\xa4\x05\x7c\x3e\x3b\x89\x45\x20\x10\xc2\x4a\x9a\ +\x67\x36\x80\x79\x7e\x0b\xe0\x21\x96\xb2\x02\x40\x28\x10\x41\x2e\ +\x0b\x9c\xb9\x00\xfc\x7d\x95\xd8\xb1\xfe\x00\xf8\x3c\x3e\x3b\xf9\ +\x1a\x04\xde\xcd\xd9\x3f\x65\x76\x71\x3b\x00\x91\x50\x02\xa9\xc4\ +\x1b\x52\x89\x37\x7c\xa4\xbe\x50\x29\x34\xd8\xbd\xe1\x4b\xf8\x78\ +\xca\x58\x1d\xaf\x73\xbc\xfc\xb0\x7b\xe3\x57\x98\x2f\x7f\x01\x12\ +\x91\x27\x84\x02\x11\x84\x02\x91\x4b\x71\x87\xf2\x44\x68\xf3\xca\ +\x5d\xd0\xaa\x62\x20\x12\x88\xc6\x22\xbf\x00\xc2\xb1\x6b\x77\xca\ +\xd0\xc8\x13\xd8\x6c\x24\xec\xb0\xc3\x4a\x5a\x60\xe8\x6c\x40\xee\ +\x85\x23\xec\xa6\xc1\x68\xf5\x8b\x48\x08\xcb\x60\xac\x13\xa3\xf6\ +\x51\xf0\x08\x7a\xa3\xd0\xcb\xc3\x67\xd2\x84\xa9\xb1\xad\x12\x75\ +\xad\x65\xec\x01\xc8\xd4\xbd\xea\x52\x87\x8d\xa6\x41\x54\x35\x5f\ +\x85\xa1\xb3\x1e\xf7\x1f\x75\xc1\x64\x19\x86\x44\xe4\x09\x85\x9f\ +\x12\x8b\x16\x44\x21\x2e\x34\x05\x52\x89\x37\x6d\xff\xcb\x74\xd9\ +\xec\x01\xf0\x97\x05\x42\xad\x0c\xa7\xdd\xb8\x8b\x55\x67\x50\x58\ +\x71\x0a\x46\xd3\xe0\xa4\x67\x5d\x0f\xda\x51\x6d\x28\xc1\xd9\x92\ +\xdf\xb0\x22\x61\x3d\x6d\xd0\x1a\x65\x04\xe4\xb2\x79\xe8\xeb\xbf\ +\xc7\x7c\x10\x5c\x91\xb0\x8e\x76\xe7\x7f\x3c\x7b\x00\x79\xc5\xc7\ +\xa7\xec\xfc\xc4\x2f\x24\xaf\xf8\x18\x7e\x3a\x7b\x90\xf6\xbb\x32\ +\x75\x39\xec\x64\x01\x5d\x68\x0a\xad\x06\xfd\xf0\xe7\x7e\xd4\xb7\ +\x96\x53\xb2\xa9\x6b\x2d\xc3\xd1\xfc\x4f\x69\xbd\x2f\x91\x62\x8c\ +\x72\x1a\x40\x51\x6d\x01\xe5\xc6\x14\xd5\x9c\x43\xe3\xed\x4a\x5a\ +\x1d\x69\x68\xbb\x8e\xa2\x9a\x73\x94\xed\xca\x9b\x8a\xd8\x01\x90\ +\x7f\xf5\x04\x25\xe7\x26\xcb\x30\xf2\x8a\x8f\xb9\x14\x34\xcf\x5c\ +\x39\x0e\x93\x65\x84\x12\x34\x67\x8a\x2e\xb4\x27\x42\xbf\xfe\xf5\ +\xb5\xd3\x6b\xf2\x8a\xa6\x7f\x61\x1b\xb5\xb9\x04\x80\xb4\x91\xb8\ +\x3e\x45\xed\x60\x2a\x31\x74\x34\xd0\x1a\x36\x94\x93\xf0\xcf\xe7\ +\x3e\xc7\xad\xce\x46\x87\x7a\xfa\x3b\xd5\x8c\xcc\x15\xf4\xed\x35\ +\x0e\x75\xda\xef\x19\xf0\xcd\xa9\x0f\xdd\x37\x15\xbe\x79\xb7\xce\ +\xa1\x4e\x5f\x7f\x0f\x23\x00\x9c\xf1\x53\xdf\x5a\x0e\x3b\xec\xee\ +\x03\x30\x47\xea\xeb\x54\x01\x83\x09\x31\x5b\x1d\xc7\x00\x1f\xa9\ +\x9f\x7b\x17\x43\x4f\x86\xfb\x9d\x5a\x30\x31\x21\x62\xa1\x87\xe3\ +\xf6\x18\x1f\xb9\x0f\x00\x41\x10\x88\x5c\x18\xef\x50\x8f\xa9\x65\ +\xab\x33\x7e\xb4\xaa\x18\xf7\x01\xd8\xb9\xfe\x20\x54\x8a\x10\x87\ +\x7a\x11\x13\x4a\xe2\x74\x25\xdc\x09\x3f\xa1\xf3\x23\xb1\x75\xd5\ +\x1e\xf6\x01\xbc\xb3\x66\x9f\xc3\xea\xed\x33\x89\xd7\x66\xb8\x5c\ +\x1c\xe1\xf3\xf8\x88\xd7\xa6\x3b\xa5\x1b\xa3\x49\xc2\x1b\x2b\x77\ +\xb2\x07\x60\xd3\xf2\xed\x88\x08\xd6\x39\xed\x58\x22\xf2\x40\x4e\ +\xda\x16\x97\x00\xac\x4d\x7f\x0b\x12\x91\x87\xd3\xfa\x89\x61\x4b\ +\x91\x9d\xfc\x3a\x3b\x00\x26\xee\xd8\x38\x23\x4b\x63\x57\x39\x15\ +\x2f\xa6\x92\xc8\x85\x09\xc8\x88\x79\x85\xb2\x5d\x7a\xcc\xcb\xec\ +\x00\xa8\xa0\x38\xc7\x7e\x26\xdb\xb2\xf7\x22\x4a\x9d\x48\xc9\x26\ +\x46\x93\x84\x6d\xd9\xf4\x26\x36\x55\xcd\x57\xd8\x01\xf0\x77\x65\ +\x1e\xed\x4f\xf9\xed\xd5\x1f\x20\x27\xed\x4d\x87\xc5\x0e\xa9\xc4\ +\x1b\x6b\xd3\xb6\xd0\x0e\x68\x4f\xdb\x79\x9a\x9d\x82\x48\x5f\x7f\ +\x0f\x5a\xbb\xf4\xb4\x8b\x22\x99\xba\x35\x48\x8a\xc8\x44\xb5\xe1\ +\x2a\x9a\x3b\xea\xd1\xfb\xb8\x1b\x23\x66\x23\x3c\xc4\x52\xf8\xfb\ +\x06\x62\xd1\x82\x68\xc4\x85\x26\xbb\x54\x11\x32\x74\x36\x50\x2a\ +\x86\x50\x02\x00\x00\x97\xaa\xf3\x5d\xaa\x0a\x49\x25\xde\x48\x8d\ +\xca\x42\x6a\x54\x16\x00\xc0\x6e\xb7\x83\x20\x98\xdb\x49\xba\x54\ +\x95\x4f\xd9\x86\x12\x80\xda\x96\x52\x94\x34\x14\x22\x64\xfe\x62\ +\x08\x05\x62\x10\x04\xc0\xe7\x09\xe1\xed\x39\x87\x56\x83\x5d\xe9\ +\xbc\x85\x34\xc3\x66\x23\xc7\xae\x2d\xb8\x79\xb7\x16\x0d\x6d\x15\ +\xec\x02\x00\x80\xdc\x8b\xdf\x3f\x35\xe4\x0b\x9f\xe7\x6a\xb9\x2c\ +\x00\x3b\xd6\x1d\x80\xa7\xc4\x0b\x6c\x8b\xd1\x34\x88\x6f\x4f\x7f\ +\x84\xfe\xa1\x07\xcf\x97\xdb\x24\x69\x85\x85\xe6\xb6\x19\xed\x9d\ +\x21\xd2\x66\x05\x69\xb3\xc2\x6c\x35\xa1\xb3\xef\x36\x0e\x9d\x7c\ +\x1f\x03\x43\x8f\x58\xed\xfc\x80\xf1\x31\x0e\x9d\x7c\x0f\x1d\xbd\ +\xad\x18\x1c\x1e\xc0\xb0\x69\x08\xc3\xa6\x21\xda\x9d\x77\x09\xc0\ +\x44\xe9\xed\xef\xc6\x77\x79\xfb\x68\x2f\x4b\x9d\x29\x8e\x7c\xfd\ +\xc7\x1e\xca\x41\xce\x6d\x00\x00\xa0\x6f\xa0\x07\x24\x69\x65\x05\ +\xc0\x88\xd9\x88\xde\xfe\x6e\xc6\xfd\x32\x0a\x40\x24\x10\x83\x1c\ +\x0b\x4c\x4c\x8b\x6d\xd4\xca\xca\x16\x1c\xe3\xc7\xe4\x98\x4c\x6b\ +\x93\x21\xd8\x18\xf7\xc9\xe8\x69\x06\x2b\x69\x81\x48\x28\x76\xa8\ +\x77\xab\xb3\x11\xad\x5d\x7a\x48\xc4\x52\x98\xcc\x46\x84\x07\xc7\ +\x21\xc8\xc1\x91\x19\xa1\x40\x0c\xfb\xe8\xe8\xcc\x06\x60\x21\xcd\ +\xa8\x6a\xbe\x32\xed\x12\xb6\xe6\x56\x09\x7e\x29\xf8\x62\xdc\xbd\ +\x82\xd2\xdf\xb1\x3d\xe7\x13\x68\x83\xa2\xa7\xb1\xbb\xc6\x4a\x80\ +\x65\xfc\x98\x5c\x6d\x4b\x29\xee\x3f\xee\x84\x48\x28\x81\xff\x84\ +\x13\x1d\x65\xfa\xcb\x38\x7e\xfe\xf0\x24\x1b\x3b\xec\x28\x6f\x2a\ +\x42\x90\x42\x0d\x85\xaf\x72\xdc\xb3\x1b\xed\x55\x28\xb8\x96\x8b\ +\xc2\xeb\xa7\x58\x19\x56\x04\x9b\x3f\x4d\x05\xcc\x0d\x42\x5a\x74\ +\x16\xc2\x54\xb1\xa8\x31\x5c\x43\x7e\xc9\x09\x87\x36\x1b\x97\x6d\ +\x43\x78\xb0\x0e\x75\x2d\x65\x28\x69\x2c\x44\xcf\xc3\x0e\x56\xe7\ +\x16\x04\xf7\xd7\xd8\x2c\x17\x0e\x00\x07\x80\x03\xc0\x01\xe0\x00\ +\x70\x00\x38\x00\xb3\x57\xfe\x1b\x00\x50\x37\x09\xa9\xfa\xed\xb7\ +\x72\x00\x00\x00\x00\x49\x45\x4e\x44\xae\x42\x60\x82\ +\x00\x00\x15\x73\ +\x89\ +\x50\x4e\x47\x0d\x0a\x1a\x0a\x00\x00\x00\x0d\x49\x48\x44\x52\x00\ +\x00\x03\xe8\x00\x00\x00\x44\x08\x06\x00\x00\x00\x12\x95\x1f\xec\ +\x00\x00\x00\x09\x70\x48\x59\x73\x00\x00\x0b\x13\x00\x00\x0b\x13\ +\x01\x00\x9a\x9c\x18\x00\x00\x0a\x4f\x69\x43\x43\x50\x50\x68\x6f\ +\x74\x6f\x73\x68\x6f\x70\x20\x49\x43\x43\x20\x70\x72\x6f\x66\x69\ +\x6c\x65\x00\x00\x78\xda\x9d\x53\x67\x54\x53\xe9\x16\x3d\xf7\xde\ +\xf4\x42\x4b\x88\x80\x94\x4b\x6f\x52\x15\x08\x20\x52\x42\x8b\x80\ +\x14\x91\x26\x2a\x21\x09\x10\x4a\x88\x21\xa1\xd9\x15\x51\xc1\x11\ +\x45\x45\x04\x1b\xc8\xa0\x88\x03\x8e\x8e\x80\x8c\x15\x51\x2c\x0c\ +\x8a\x0a\xd8\x07\xe4\x21\xa2\x8e\x83\xa3\x88\x8a\xca\xfb\xe1\x7b\ +\xa3\x6b\xd6\xbc\xf7\xe6\xcd\xfe\xb5\xd7\x3e\xe7\xac\xf3\x9d\xb3\ +\xcf\x07\xc0\x08\x0c\x96\x48\x33\x51\x35\x80\x0c\xa9\x42\x1e\x11\ +\xe0\x83\xc7\xc4\xc6\xe1\xe4\x2e\x40\x81\x0a\x24\x70\x00\x10\x08\ +\xb3\x64\x21\x73\xfd\x23\x01\x00\xf8\x7e\x3c\x3c\x2b\x22\xc0\x07\ +\xbe\x00\x01\x78\xd3\x0b\x08\x00\xc0\x4d\x9b\xc0\x30\x1c\x87\xff\ +\x0f\xea\x42\x99\x5c\x01\x80\x84\x01\xc0\x74\x91\x38\x4b\x08\x80\ +\x14\x00\x40\x7a\x8e\x42\xa6\x00\x40\x46\x01\x80\x9d\x98\x26\x53\ +\x00\xa0\x04\x00\x60\xcb\x63\x62\xe3\x00\x50\x2d\x00\x60\x27\x7f\ +\xe6\xd3\x00\x80\x9d\xf8\x99\x7b\x01\x00\x5b\x94\x21\x15\x01\xa0\ +\x91\x00\x20\x13\x65\x88\x44\x00\x68\x3b\x00\xac\xcf\x56\x8a\x45\ +\x00\x58\x30\x00\x14\x66\x4b\xc4\x39\x00\xd8\x2d\x00\x30\x49\x57\ +\x66\x48\x00\xb0\xb7\x00\xc0\xce\x10\x0b\xb2\x00\x08\x0c\x00\x30\ +\x51\x88\x85\x29\x00\x04\x7b\x00\x60\xc8\x23\x23\x78\x00\x84\x99\ +\x00\x14\x46\xf2\x57\x3c\xf1\x2b\xae\x10\xe7\x2a\x00\x00\x78\x99\ +\xb2\x3c\xb9\x24\x39\x45\x81\x5b\x08\x2d\x71\x07\x57\x57\x2e\x1e\ +\x28\xce\x49\x17\x2b\x14\x36\x61\x02\x61\x9a\x40\x2e\xc2\x79\x99\ +\x19\x32\x81\x34\x0f\xe0\xf3\xcc\x00\x00\xa0\x91\x15\x11\xe0\x83\ +\xf3\xfd\x78\xce\x0e\xae\xce\xce\x36\x8e\xb6\x0e\x5f\x2d\xea\xbf\ +\x06\xff\x22\x62\x62\xe3\xfe\xe5\xcf\xab\x70\x40\x00\x00\xe1\x74\ +\x7e\xd1\xfe\x2c\x2f\xb3\x1a\x80\x3b\x06\x80\x6d\xfe\xa2\x25\xee\ +\x04\x68\x5e\x0b\xa0\x75\xf7\x8b\x66\xb2\x0f\x40\xb5\x00\xa0\xe9\ +\xda\x57\xf3\x70\xf8\x7e\x3c\x3c\x45\xa1\x90\xb9\xd9\xd9\xe5\xe4\ +\xe4\xd8\x4a\xc4\x42\x5b\x61\xca\x57\x7d\xfe\x67\xc2\x5f\xc0\x57\ +\xfd\x6c\xf9\x7e\x3c\xfc\xf7\xf5\xe0\xbe\xe2\x24\x81\x32\x5d\x81\ +\x47\x04\xf8\xe0\xc2\xcc\xf4\x4c\xa5\x1c\xcf\x92\x09\x84\x62\xdc\ +\xe6\x8f\x47\xfc\xb7\x0b\xff\xfc\x1d\xd3\x22\xc4\x49\x62\xb9\x58\ +\x2a\x14\xe3\x51\x12\x71\x8e\x44\x9a\x8c\xf3\x32\xa5\x22\x89\x42\ +\x92\x29\xc5\x25\xd2\xff\x64\xe2\xdf\x2c\xfb\x03\x3e\xdf\x35\x00\ +\xb0\x6a\x3e\x01\x7b\x91\x2d\xa8\x5d\x63\x03\xf6\x4b\x27\x10\x58\ +\x74\xc0\xe2\xf7\x00\x00\xf2\xbb\x6f\xc1\xd4\x28\x08\x03\x80\x68\ +\x83\xe1\xcf\x77\xff\xef\x3f\xfd\x47\xa0\x25\x00\x80\x66\x49\x92\ +\x71\x00\x00\x5e\x44\x24\x2e\x54\xca\xb3\x3f\xc7\x08\x00\x00\x44\ +\xa0\x81\x2a\xb0\x41\x1b\xf4\xc1\x18\x2c\xc0\x06\x1c\xc1\x05\xdc\ +\xc1\x0b\xfc\x60\x36\x84\x42\x24\xc4\xc2\x42\x10\x42\x0a\x64\x80\ +\x1c\x72\x60\x29\xac\x82\x42\x28\x86\xcd\xb0\x1d\x2a\x60\x2f\xd4\ +\x40\x1d\x34\xc0\x51\x68\x86\x93\x70\x0e\x2e\xc2\x55\xb8\x0e\x3d\ +\x70\x0f\xfa\x61\x08\x9e\xc1\x28\xbc\x81\x09\x04\x41\xc8\x08\x13\ +\x61\x21\xda\x88\x01\x62\x8a\x58\x23\x8e\x08\x17\x99\x85\xf8\x21\ +\xc1\x48\x04\x12\x8b\x24\x20\xc9\x88\x14\x51\x22\x4b\x91\x35\x48\ +\x31\x52\x8a\x54\x20\x55\x48\x1d\xf2\x3d\x72\x02\x39\x87\x5c\x46\ +\xba\x91\x3b\xc8\x00\x32\x82\xfc\x86\xbc\x47\x31\x94\x81\xb2\x51\ +\x3d\xd4\x0c\xb5\x43\xb9\xa8\x37\x1a\x84\x46\xa2\x0b\xd0\x64\x74\ +\x31\x9a\x8f\x16\xa0\x9b\xd0\x72\xb4\x1a\x3d\x8c\x36\xa1\xe7\xd0\ +\xab\x68\x0f\xda\x8f\x3e\x43\xc7\x30\xc0\xe8\x18\x07\x33\xc4\x6c\ +\x30\x2e\xc6\xc3\x42\xb1\x38\x2c\x09\x93\x63\xcb\xb1\x22\xac\x0c\ +\xab\xc6\x1a\xb0\x56\xac\x03\xbb\x89\xf5\x63\xcf\xb1\x77\x04\x12\ +\x81\x45\xc0\x09\x36\x04\x77\x42\x20\x61\x1e\x41\x48\x58\x4c\x58\ +\x4e\xd8\x48\xa8\x20\x1c\x24\x34\x11\xda\x09\x37\x09\x03\x84\x51\ +\xc2\x27\x22\x93\xa8\x4b\xb4\x26\xba\x11\xf9\xc4\x18\x62\x32\x31\ +\x87\x58\x48\x2c\x23\xd6\x12\x8f\x13\x2f\x10\x7b\x88\x43\xc4\x37\ +\x24\x12\x89\x43\x32\x27\xb9\x90\x02\x49\xb1\xa4\x54\xd2\x12\xd2\ +\x46\xd2\x6e\x52\x23\xe9\x2c\xa9\x9b\x34\x48\x1a\x23\x93\xc9\xda\ +\x64\x6b\xb2\x07\x39\x94\x2c\x20\x2b\xc8\x85\xe4\x9d\xe4\xc3\xe4\ +\x33\xe4\x1b\xe4\x21\xf2\x5b\x0a\x9d\x62\x40\x71\xa4\xf8\x53\xe2\ +\x28\x52\xca\x6a\x4a\x19\xe5\x10\xe5\x34\xe5\x06\x65\x98\x32\x41\ +\x55\xa3\x9a\x52\xdd\xa8\xa1\x54\x11\x35\x8f\x5a\x42\xad\xa1\xb6\ +\x52\xaf\x51\x87\xa8\x13\x34\x75\x9a\x39\xcd\x83\x16\x49\x4b\xa5\ +\xad\xa2\x95\xd3\x1a\x68\x17\x68\xf7\x69\xaf\xe8\x74\xba\x11\xdd\ +\x95\x1e\x4e\x97\xd0\x57\xd2\xcb\xe9\x47\xe8\x97\xe8\x03\xf4\x77\ +\x0c\x0d\x86\x15\x83\xc7\x88\x67\x28\x19\x9b\x18\x07\x18\x67\x19\ +\x77\x18\xaf\x98\x4c\xa6\x19\xd3\x8b\x19\xc7\x54\x30\x37\x31\xeb\ +\x98\xe7\x99\x0f\x99\x6f\x55\x58\x2a\xb6\x2a\x7c\x15\x91\xca\x0a\ +\x95\x4a\x95\x26\x95\x1b\x2a\x2f\x54\xa9\xaa\xa6\xaa\xde\xaa\x0b\ +\x55\xf3\x55\xcb\x54\x8f\xa9\x5e\x53\x7d\xae\x46\x55\x33\x53\xe3\ +\xa9\x09\xd4\x96\xab\x55\xaa\x9d\x50\xeb\x53\x1b\x53\x67\xa9\x3b\ +\xa8\x87\xaa\x67\xa8\x6f\x54\x3f\xa4\x7e\x59\xfd\x89\x06\x59\xc3\ +\x4c\xc3\x4f\x43\xa4\x51\xa0\xb1\x5f\xe3\xbc\xc6\x20\x0b\x63\x19\ +\xb3\x78\x2c\x21\x6b\x0d\xab\x86\x75\x81\x35\xc4\x26\xb1\xcd\xd9\ +\x7c\x76\x2a\xbb\x98\xfd\x1d\xbb\x8b\x3d\xaa\xa9\xa1\x39\x43\x33\ +\x4a\x33\x57\xb3\x52\xf3\x94\x66\x3f\x07\xe3\x98\x71\xf8\x9c\x74\ +\x4e\x09\xe7\x28\xa7\x97\xf3\x7e\x8a\xde\x14\xef\x29\xe2\x29\x1b\ +\xa6\x34\x4c\xb9\x31\x65\x5c\x6b\xaa\x96\x97\x96\x58\xab\x48\xab\ +\x51\xab\x47\xeb\xbd\x36\xae\xed\xa7\x9d\xa6\xbd\x45\xbb\x59\xfb\ +\x81\x0e\x41\xc7\x4a\x27\x5c\x27\x47\x67\x8f\xce\x05\x9d\xe7\x53\ +\xd9\x53\xdd\xa7\x0a\xa7\x16\x4d\x3d\x3a\xf5\xae\x2e\xaa\x6b\xa5\ +\x1b\xa1\xbb\x44\x77\xbf\x6e\xa7\xee\x98\x9e\xbe\x5e\x80\x9e\x4c\ +\x6f\xa7\xde\x79\xbd\xe7\xfa\x1c\x7d\x2f\xfd\x54\xfd\x6d\xfa\xa7\ +\xf5\x47\x0c\x58\x06\xb3\x0c\x24\x06\xdb\x0c\xce\x18\x3c\xc5\x35\ +\x71\x6f\x3c\x1d\x2f\xc7\xdb\xf1\x51\x43\x5d\xc3\x40\x43\xa5\x61\ +\x95\x61\x97\xe1\x84\x91\xb9\xd1\x3c\xa3\xd5\x46\x8d\x46\x0f\x8c\ +\x69\xc6\x5c\xe3\x24\xe3\x6d\xc6\x6d\xc6\xa3\x26\x06\x26\x21\x26\ +\x4b\x4d\xea\x4d\xee\x9a\x52\x4d\xb9\xa6\x29\xa6\x3b\x4c\x3b\x4c\ +\xc7\xcd\xcc\xcd\xa2\xcd\xd6\x99\x35\x9b\x3d\x31\xd7\x32\xe7\x9b\ +\xe7\x9b\xd7\x9b\xdf\xb7\x60\x5a\x78\x5a\x2c\xb6\xa8\xb6\xb8\x65\ +\x49\xb2\xe4\x5a\xa6\x59\xee\xb6\xbc\x6e\x85\x5a\x39\x59\xa5\x58\ +\x55\x5a\x5d\xb3\x46\xad\x9d\xad\x25\xd6\xbb\xad\xbb\xa7\x11\xa7\ +\xb9\x4e\x93\x4e\xab\x9e\xd6\x67\xc3\xb0\xf1\xb6\xc9\xb6\xa9\xb7\ +\x19\xb0\xe5\xd8\x06\xdb\xae\xb6\x6d\xb6\x7d\x61\x67\x62\x17\x67\ +\xb7\xc5\xae\xc3\xee\x93\xbd\x93\x7d\xba\x7d\x8d\xfd\x3d\x07\x0d\ +\x87\xd9\x0e\xab\x1d\x5a\x1d\x7e\x73\xb4\x72\x14\x3a\x56\x3a\xde\ +\x9a\xce\x9c\xee\x3f\x7d\xc5\xf4\x96\xe9\x2f\x67\x58\xcf\x10\xcf\ +\xd8\x33\xe3\xb6\x13\xcb\x29\xc4\x69\x9d\x53\x9b\xd3\x47\x67\x17\ +\x67\xb9\x73\x83\xf3\x88\x8b\x89\x4b\x82\xcb\x2e\x97\x3e\x2e\x9b\ +\x1b\xc6\xdd\xc8\xbd\xe4\x4a\x74\xf5\x71\x5d\xe1\x7a\xd2\xf5\x9d\ +\x9b\xb3\x9b\xc2\xed\xa8\xdb\xaf\xee\x36\xee\x69\xee\x87\xdc\x9f\ +\xcc\x34\x9f\x29\x9e\x59\x33\x73\xd0\xc3\xc8\x43\xe0\x51\xe5\xd1\ +\x3f\x0b\x9f\x95\x30\x6b\xdf\xac\x7e\x4f\x43\x4f\x81\x67\xb5\xe7\ +\x23\x2f\x63\x2f\x91\x57\xad\xd7\xb0\xb7\xa5\x77\xaa\xf7\x61\xef\ +\x17\x3e\xf6\x3e\x72\x9f\xe3\x3e\xe3\x3c\x37\xde\x32\xde\x59\x5f\ +\xcc\x37\xc0\xb7\xc8\xb7\xcb\x4f\xc3\x6f\x9e\x5f\x85\xdf\x43\x7f\ +\x23\xff\x64\xff\x7a\xff\xd1\x00\xa7\x80\x25\x01\x67\x03\x89\x81\ +\x41\x81\x5b\x02\xfb\xf8\x7a\x7c\x21\xbf\x8e\x3f\x3a\xdb\x65\xf6\ +\xb2\xd9\xed\x41\x8c\xa0\xb9\x41\x15\x41\x8f\x82\xad\x82\xe5\xc1\ +\xad\x21\x68\xc8\xec\x90\xad\x21\xf7\xe7\x98\xce\x91\xce\x69\x0e\ +\x85\x50\x7e\xe8\xd6\xd0\x07\x61\xe6\x61\x8b\xc3\x7e\x0c\x27\x85\ +\x87\x85\x57\x86\x3f\x8e\x70\x88\x58\x1a\xd1\x31\x97\x35\x77\xd1\ +\xdc\x43\x73\xdf\x44\xfa\x44\x96\x44\xde\x9b\x67\x31\x4f\x39\xaf\ +\x2d\x4a\x35\x2a\x3e\xaa\x2e\x6a\x3c\xda\x37\xba\x34\xba\x3f\xc6\ +\x2e\x66\x59\xcc\xd5\x58\x9d\x58\x49\x6c\x4b\x1c\x39\x2e\x2a\xae\ +\x36\x6e\x6c\xbe\xdf\xfc\xed\xf3\x87\xe2\x9d\xe2\x0b\xe3\x7b\x17\ +\x98\x2f\xc8\x5d\x70\x79\xa1\xce\xc2\xf4\x85\xa7\x16\xa9\x2e\x12\ +\x2c\x3a\x96\x40\x4c\x88\x4e\x38\x94\xf0\x41\x10\x2a\xa8\x16\x8c\ +\x25\xf2\x13\x77\x25\x8e\x0a\x79\xc2\x1d\xc2\x67\x22\x2f\xd1\x36\ +\xd1\x88\xd8\x43\x5c\x2a\x1e\x4e\xf2\x48\x2a\x4d\x7a\x92\xec\x91\ +\xbc\x35\x79\x24\xc5\x33\xa5\x2c\xe5\xb9\x84\x27\xa9\x90\xbc\x4c\ +\x0d\x4c\xdd\x9b\x3a\x9e\x16\x9a\x76\x20\x6d\x32\x3d\x3a\xbd\x31\ +\x83\x92\x91\x90\x71\x42\xaa\x21\x4d\x93\xb6\x67\xea\x67\xe6\x66\ +\x76\xcb\xac\x65\x85\xb2\xfe\xc5\x6e\x8b\xb7\x2f\x1e\x95\x07\xc9\ +\x6b\xb3\x90\xac\x05\x59\x2d\x0a\xb6\x42\xa6\xe8\x54\x5a\x28\xd7\ +\x2a\x07\xb2\x67\x65\x57\x66\xbf\xcd\x89\xca\x39\x96\xab\x9e\x2b\ +\xcd\xed\xcc\xb3\xca\xdb\x90\x37\x9c\xef\x9f\xff\xed\x12\xc2\x12\ +\xe1\x92\xb6\xa5\x86\x4b\x57\x2d\x1d\x58\xe6\xbd\xac\x6a\x39\xb2\ +\x3c\x71\x79\xdb\x0a\xe3\x15\x05\x2b\x86\x56\x06\xac\x3c\xb8\x8a\ +\xb6\x2a\x6d\xd5\x4f\xab\xed\x57\x97\xae\x7e\xbd\x26\x7a\x4d\x6b\ +\x81\x5e\xc1\xca\x82\xc1\xb5\x01\x6b\xeb\x0b\x55\x0a\xe5\x85\x7d\ +\xeb\xdc\xd7\xed\x5d\x4f\x58\x2f\x59\xdf\xb5\x61\xfa\x86\x9d\x1b\ +\x3e\x15\x89\x8a\xae\x14\xdb\x17\x97\x15\x7f\xd8\x28\xdc\x78\xe5\ +\x1b\x87\x6f\xca\xbf\x99\xdc\x94\xb4\xa9\xab\xc4\xb9\x64\xcf\x66\ +\xd2\x66\xe9\xe6\xde\x2d\x9e\x5b\x0e\x96\xaa\x97\xe6\x97\x0e\x6e\ +\x0d\xd9\xda\xb4\x0d\xdf\x56\xb4\xed\xf5\xf6\x45\xdb\x2f\x97\xcd\ +\x28\xdb\xbb\x83\xb6\x43\xb9\xa3\xbf\x3c\xb8\xbc\x65\xa7\xc9\xce\ +\xcd\x3b\x3f\x54\xa4\x54\xf4\x54\xfa\x54\x36\xee\xd2\xdd\xb5\x61\ +\xd7\xf8\x6e\xd1\xee\x1b\x7b\xbc\xf6\x34\xec\xd5\xdb\x5b\xbc\xf7\ +\xfd\x3e\xc9\xbe\xdb\x55\x01\x55\x4d\xd5\x66\xd5\x65\xfb\x49\xfb\ +\xb3\xf7\x3f\xae\x89\xaa\xe9\xf8\x96\xfb\x6d\x5d\xad\x4e\x6d\x71\ +\xed\xc7\x03\xd2\x03\xfd\x07\x23\x0e\xb6\xd7\xb9\xd4\xd5\x1d\xd2\ +\x3d\x54\x52\x8f\xd6\x2b\xeb\x47\x0e\xc7\x1f\xbe\xfe\x9d\xef\x77\ +\x2d\x0d\x36\x0d\x55\x8d\x9c\xc6\xe2\x23\x70\x44\x79\xe4\xe9\xf7\ +\x09\xdf\xf7\x1e\x0d\x3a\xda\x76\x8c\x7b\xac\xe1\x07\xd3\x1f\x76\ +\x1d\x67\x1d\x2f\x6a\x42\x9a\xf2\x9a\x46\x9b\x53\x9a\xfb\x5b\x62\ +\x5b\xba\x4f\xcc\x3e\xd1\xd6\xea\xde\x7a\xfc\x47\xdb\x1f\x0f\x9c\ +\x34\x3c\x59\x79\x4a\xf3\x54\xc9\x69\xda\xe9\x82\xd3\x93\x67\xf2\ +\xcf\x8c\x9d\x95\x9d\x7d\x7e\x2e\xf9\xdc\x60\xdb\xa2\xb6\x7b\xe7\ +\x63\xce\xdf\x6a\x0f\x6f\xef\xba\x10\x74\xe1\xd2\x45\xff\x8b\xe7\ +\x3b\xbc\x3b\xce\x5c\xf2\xb8\x74\xf2\xb2\xdb\xe5\x13\x57\xb8\x57\ +\x9a\xaf\x3a\x5f\x6d\xea\x74\xea\x3c\xfe\x93\xd3\x4f\xc7\xbb\x9c\ +\xbb\x9a\xae\xb9\x5c\x6b\xb9\xee\x7a\xbd\xb5\x7b\x66\xf7\xe9\x1b\ +\x9e\x37\xce\xdd\xf4\xbd\x79\xf1\x16\xff\xd6\xd5\x9e\x39\x3d\xdd\ +\xbd\xf3\x7a\x6f\xf7\xc5\xf7\xf5\xdf\x16\xdd\x7e\x72\x27\xfd\xce\ +\xcb\xbb\xd9\x77\x27\xee\xad\xbc\x4f\xbc\x5f\xf4\x40\xed\x41\xd9\ +\x43\xdd\x87\xd5\x3f\x5b\xfe\xdc\xd8\xef\xdc\x7f\x6a\xc0\x77\xa0\ +\xf3\xd1\xdc\x47\xf7\x06\x85\x83\xcf\xfe\x91\xf5\x8f\x0f\x43\x05\ +\x8f\x99\x8f\xcb\x86\x0d\x86\xeb\x9e\x38\x3e\x39\x39\xe2\x3f\x72\ +\xfd\xe9\xfc\xa7\x43\xcf\x64\xcf\x26\x9e\x17\xfe\xa2\xfe\xcb\xae\ +\x17\x16\x2f\x7e\xf8\xd5\xeb\xd7\xce\xd1\x98\xd1\xa1\x97\xf2\x97\ +\x93\xbf\x6d\x7c\xa5\xfd\xea\xc0\xeb\x19\xaf\xdb\xc6\xc2\xc6\x1e\ +\xbe\xc9\x78\x33\x31\x5e\xf4\x56\xfb\xed\xc1\x77\xdc\x77\x1d\xef\ +\xa3\xdf\x0f\x4f\xe4\x7c\x20\x7f\x28\xff\x68\xf9\xb1\xf5\x53\xd0\ +\xa7\xfb\x93\x19\x93\x93\xff\x04\x03\x98\xf3\xfc\x63\x33\x2d\xdb\ +\x00\x00\x00\x20\x63\x48\x52\x4d\x00\x00\x7a\x25\x00\x00\x80\x83\ +\x00\x00\xf9\xff\x00\x00\x80\xe9\x00\x00\x75\x30\x00\x00\xea\x60\ +\x00\x00\x3a\x98\x00\x00\x17\x6f\x92\x5f\xc5\x46\x00\x00\x0a\x9e\ +\x49\x44\x41\x54\x78\xda\xec\xdd\xdb\x6f\x5c\x57\xd9\x07\xe0\x77\ +\x4e\x7b\x66\x7c\xc0\x63\x37\x4e\x30\x10\x3e\x7d\x11\x4d\xa4\xba\ +\x84\x42\x50\x73\x81\x7a\x81\xb8\xe6\xaf\xe5\xf2\x13\xe2\xa2\xaa\ +\x3e\x15\x51\x28\x55\x83\x08\x95\x2c\xa0\xa5\x26\x24\xb5\x9d\xf8\ +\x30\xc7\x3d\x9b\x8b\xe9\x8c\xc7\xf6\x1c\xec\xb1\xad\xd8\xf1\xf3\ +\xdc\x45\x3b\xb3\x67\xf6\x5a\x2b\x52\x7e\x7b\x1d\xde\xdc\xa3\x47\ +\x8f\xb2\x00\xb8\x24\xf5\x7a\x5d\x23\x00\x00\xc0\x29\xe4\x35\x01\ +\x00\x00\x00\x08\xe8\x00\x00\x00\x80\x80\x0e\x00\x00\x00\x02\x3a\ +\x00\x00\x00\x20\xa0\x03\x00\x00\x80\x80\x0e\x00\x00\x00\x08\xe8\ +\x00\x00\x00\x20\xa0\x03\x00\x00\x00\x02\x3a\x00\x00\x00\x08\xe8\ +\x00\x00\x00\x80\x80\x0e\x00\x00\x00\x02\x3a\x00\x00\x00\x20\xa0\ +\x03\x00\x00\x80\x80\x0e\x00\x00\x00\x08\xe8\x00\x00\x00\x20\xa0\ +\x03\x00\x00\x00\x02\x3a\x00\x00\x00\x08\xe8\x00\x00\x00\x80\x80\ +\x0e\x00\x00\x00\x02\x3a\x00\x00\x00\x20\xa0\x03\x00\x00\x80\x80\ +\x0e\x00\x00\x00\x08\xe8\x00\x00\x00\x20\xa0\x03\x00\x00\x00\x02\ +\x3a\x00\x00\x00\x08\xe8\x00\x00\x00\xc0\x0c\x8a\x97\xfd\x05\x95\ +\x3b\xe9\xc4\xeb\xad\xed\x7c\x74\x5b\xb9\xb1\xd7\xf3\x49\x16\xc9\ +\x72\xf7\x54\x7f\xf7\xc8\x83\x2d\x64\x51\x9c\xef\x7d\xae\xf1\xac\ +\x70\xaa\xdf\xd8\xd9\xcf\x47\x67\x6f\xf2\xfd\x93\x95\x6e\x94\x57\ +\xd3\xc8\x17\xb3\x88\x88\x68\xbf\xca\x47\x6b\xbb\x30\xf5\x73\xd3\ +\x7e\xcf\xf0\xf5\x69\xcf\x99\xac\x74\x23\x5f\xca\xa2\xdb\xce\x45\ +\x6b\x6b\xf6\x77\x2c\xc5\x85\x2c\x92\xe5\x34\x4a\xdf\xe9\x7d\x6f\ +\xb7\x93\x8b\xe6\xf3\xc2\xd4\x7b\x4e\xeb\xd3\x61\xc3\x6d\x7a\x96\ +\xcf\x1d\xff\xfc\xf0\x38\x38\x8b\xe3\x6d\x39\xad\xaf\xfb\xd7\xa7\ +\xb5\xed\x59\xc7\xe5\xf1\x71\xd3\xa9\xe7\xa3\xf9\x9f\xe9\xe3\xe6\ +\x78\x7f\x95\x6f\xa7\x51\xac\x76\x67\xbe\x07\x00\x00\x70\x83\x03\ +\xfa\xad\xf7\xeb\xd3\x43\xd4\x4e\x21\x5e\xfd\x2d\x19\x19\x5c\x93\ +\xe5\xee\xe0\x1e\x2f\x7e\x5f\x9d\x1a\xb6\xfb\xe6\xff\xa7\x1d\x8b\ +\xf7\x5a\x11\x11\xf1\xd5\x6f\x16\x4e\xf5\x1b\x77\x37\x92\x78\xf9\ +\x24\x19\x1b\xb0\xde\x7a\xd4\x88\x42\x65\x74\x48\x3c\xd8\x2c\xc5\ +\xce\x67\xc9\xd8\xa0\x36\xed\xf7\x0c\x5f\x3f\xd8\x2c\xc5\xd6\x1f\ +\xca\x63\x7f\x6f\x6d\xbd\x19\x49\x2d\x8d\xd6\x4e\x21\xfe\xf3\x61\ +\xf5\xcc\x7d\x92\x4f\xb2\xa8\x3d\x6c\xc5\xdc\x5a\xfb\xe4\xc5\xfb\ +\xbd\xfe\xd8\x79\x52\x1e\x1b\x50\x4f\xd3\xa7\x7d\xc3\x6d\x7a\x96\ +\xcf\x1d\xff\xfc\xf0\x38\x38\x8b\xe3\x63\x66\x5a\x5f\x0f\x7f\xc7\ +\xbf\x7f\x37\x3f\x36\xfc\x9e\x76\x5c\x26\x2b\xdd\x41\x7f\x9d\xb0\ +\xde\x6b\xeb\xad\x3f\x55\x26\x86\xec\x7c\x92\xc5\xad\xc7\x8d\x73\ +\xdd\x03\x00\x00\x10\xd0\x07\xd2\x46\x3e\xd2\xc6\xd1\x00\x51\x5a\ +\xe8\x46\xae\x98\x45\x52\x4b\xe3\xd6\xfb\xf5\xd8\xfa\xb4\x12\x07\ +\x5f\x16\xaf\x5c\x23\xcd\xdd\xed\xc4\xca\x7b\x8d\xc1\x9f\xdb\x7b\ +\xbd\x59\xf3\x42\x35\x8b\xd2\x42\x37\x0a\x95\x6e\xcc\xad\xb5\xa3\ +\xb4\x98\xc6\xf3\x8f\xaa\xa7\x9e\xe5\x1f\xfb\x7d\x6b\xed\x38\xb8\ +\x53\x3c\xf5\xcb\x88\xb3\x86\xf3\xd5\x5f\xd4\xa3\xb4\xd0\x1d\xf4\ +\x4b\x73\xbb\x10\x59\x27\x7a\xb3\xe9\x0b\xdd\x48\x6a\x69\xac\x3e\ +\xae\xc7\xf3\x8f\xab\x13\x67\x91\x47\xf5\xe9\x71\x9d\x7a\xfe\xc8\ +\x8b\x98\xe3\x0a\x95\x6c\xf0\xd2\x63\xd4\xf5\xfe\xe7\xbb\xed\xdc\ +\xc8\xeb\xfd\x31\x94\x75\x72\xd1\xde\x3b\xf9\x5b\xbb\xed\xd9\xfb\ +\x62\xe5\xa7\x8d\x99\x5e\x80\x0c\x87\xf3\xd5\xc7\xf5\xc8\xf5\x57\ +\x5b\x8c\x18\x37\x49\x2d\x8d\x3b\x1f\x1c\xc4\xb3\x0f\xe7\x46\x06\ +\xec\x7c\x92\xc5\xda\xaf\x0e\x8e\xdc\xa3\xbd\xdb\x6b\x87\xd2\xe2\ +\x61\x7f\x4d\xba\x07\x00\x00\x20\xa0\x1f\x71\xf0\x75\x71\xe4\x8c\ +\xe5\x70\xf8\x5d\x7e\xb7\x19\x8d\x67\x85\x73\x07\xdc\x0b\x6d\xa0\ +\x85\x2c\x96\xdf\x6d\x46\x44\x44\xd6\xc9\xc5\x37\x7f\xac\x9c\x08\ +\xce\x2b\x3f\x6f\xf6\x02\xfa\x42\x37\x6a\x0f\x5b\x13\x67\xbf\x4f\ +\x6b\xf9\x61\x33\x36\xff\x6f\xee\xc2\x9f\x67\xf1\xed\xf6\x20\x9c\ +\x8f\x9a\xa9\xaf\xdc\xe9\xbd\x2c\xc9\x15\xb3\x58\xfe\x49\x23\x9e\ +\xfd\x6e\xee\xcc\x7d\x3a\xce\xa8\xb0\xbb\xb4\xde\x1a\xac\x1c\x98\ +\x14\x86\x5b\x5b\xf9\x91\xd7\x6f\x7f\x50\x8f\xa4\x96\x46\x7b\x2f\ +\x7f\xae\x30\x3d\x32\x60\xd7\xd2\x98\xbf\xd7\x89\xfd\x8d\xb3\xff\ +\x33\xc9\x27\xd9\x20\x9c\x67\x9d\x5c\x6c\x7f\x5e\x3e\xf1\xf2\x69\ +\xf9\xbd\x66\xcc\xdf\x6d\x47\xae\x98\x45\xed\xc7\xcd\x78\xf1\xff\ +\x95\x13\xf7\xa9\x3d\x6c\x0d\xc2\xf9\xa8\x59\xff\xf9\x7b\x9d\x58\ +\x5e\x6f\x44\xae\x98\x9d\xfb\x85\x02\x00\x00\xf0\x7a\xbd\xf6\x43\ +\xe2\x0e\xbe\x2c\xc6\xc1\x66\x29\x22\x22\x72\xc5\x6c\xa6\x7d\xca\ +\x97\x69\xf1\x47\x87\x01\x69\xfb\xf3\xf2\xc8\x59\xed\x9d\xcf\x0e\ +\x43\x53\x75\xb5\x73\x21\xdf\x5b\xa8\x74\x63\x69\xbd\x75\xe1\xcf\ +\x53\x5e\x39\x6c\xdf\x57\x7f\x3d\x19\xae\x1b\xcf\x0a\x83\x99\xea\ +\xd2\x42\x37\x92\x95\xee\x8d\xfe\x07\x52\x7b\xd0\x8c\x7c\x92\xcd\ +\xf4\x22\xa4\x3f\x6e\x5e\x6d\x24\x23\x57\x86\xbc\xfc\x4b\x12\x59\ +\xe7\xdb\xfd\xf9\xb7\x46\x8f\x9b\xfe\x78\xca\x3a\xb9\xd8\xfd\xa2\ +\x74\xe2\xfa\xfe\x46\x31\xd2\x46\x7e\xf0\x42\x61\x96\xdf\x0a\x00\ +\x00\x08\xe8\x47\x42\x61\x5f\xff\xc0\xb2\xab\xa2\xb2\xda\x0b\xb4\ +\xed\xbd\xfc\xd8\xe5\xf7\xdd\x56\xee\xc8\x4b\x86\xf3\xea\x07\xae\ +\xc5\x7b\xad\x28\x2e\x5c\x4e\xe0\x4a\x1b\xe3\x0f\xc4\xdb\xff\xd7\ +\x61\x10\xcc\x97\x6e\x66\xe0\xeb\xf7\x41\xae\xd8\xdb\xaf\x7f\xe6\ +\x71\x73\xbb\x33\xb8\xcf\xee\xd3\xd2\xd8\x71\xb3\xf7\xcf\xc3\x6b\ +\xa3\x5e\x4e\xf5\xc7\x53\xa7\x91\x1b\xbb\xb2\x64\xf8\x1e\xb3\x1c\ +\xa4\x07\x00\x00\x5c\x0d\x45\x4d\x30\xd9\x60\x7f\xf4\xf6\xe4\xfd\ +\xe0\x5b\x7f\x28\xc7\x56\x94\x2f\xe4\x3b\x5f\xfe\x35\x89\xe5\x77\ +\x9b\x97\xb2\x6c\xb9\xfb\xed\x8c\x6d\xa1\xd2\x1d\xbb\x7c\x7b\x7f\ +\xa3\x18\xfb\x1b\x0b\x37\xba\xdf\xd3\x46\x2e\x0e\xbe\x4e\x62\xf1\ +\x5e\x6b\xa6\x33\x01\xfa\xdb\x08\x9a\x53\xc6\xcd\xcb\x27\xc9\xc4\ +\x6d\x02\x69\x23\x1f\x85\x4a\x37\x4a\x0b\xdd\xa8\xdc\x49\x47\xfe\ +\x86\xdd\xa7\xa5\xb1\x2f\x01\x00\x00\x80\xeb\xe3\x4a\xcc\xa0\x0f\ +\xcf\x1c\x0e\x1f\x2a\x76\x95\x9c\xe7\xb0\xb1\x33\x7f\x57\x2b\x17\ +\x3b\x4f\x7b\x61\xbf\xbf\x0f\xfa\xa2\x1c\x7c\x75\x18\xc8\x6b\x0f\ +\x9a\xb1\xb4\x7e\x79\xb3\xf4\xd7\xdd\xee\x17\xa5\xc1\x4c\xfa\xd2\ +\x3b\xcd\xd9\x82\x7e\xfd\x7c\xe3\x66\x78\x76\xfc\xad\x9f\x35\x62\ +\x69\xbd\x65\x19\x3b\x00\x00\xbc\xa1\x5e\xfb\x0c\x7a\xe5\x4e\x7a\ +\x64\x9f\x6d\xfd\xab\x82\x5e\x89\xde\x2c\xf6\xfc\xf7\x0b\x91\xd4\ +\xd2\xa8\x3d\x68\x46\xfd\xab\x8b\x39\x3c\xef\xe0\xcb\x62\xe4\x4a\ +\x95\xc1\xc1\x62\x8b\xf7\x7a\x87\xb4\xf5\x4f\x18\xdf\xff\x67\xe9\ +\xd4\xb5\xd5\xfb\x9f\x1d\xe7\x2c\x65\xf1\xae\xa2\x6e\x2b\x17\xdb\ +\x9f\x95\xe3\xd6\xfb\xbd\x53\xef\x97\xd6\x5b\x67\x3a\x14\xef\x42\ +\x5e\x12\x3c\x2d\x45\xb1\xda\x1d\x1c\x26\xd7\x6f\xf3\xd6\x4e\x21\ +\x9a\x5b\x85\xd8\xff\x47\xc9\xc9\xed\x00\x00\x20\xa0\x9f\xcd\xdc\ +\xf7\x3a\x47\x0e\x28\x8b\x38\x2c\x91\xd5\xb7\xf3\xb4\x7c\xa5\x4e\ +\x70\x9f\xe6\xf6\x07\xa3\xeb\x72\x4f\xaa\x21\x7e\x16\x5b\x7f\xaa\ +\xc4\x77\x7f\xb9\x3f\xd8\x07\x7d\x11\xa7\xc3\xf7\xc3\x7f\xba\x5f\ +\x8d\xef\xdc\x6f\x0d\x6a\x6b\x97\x16\x7a\xcb\xa8\xe7\xef\xb6\xa7\ +\xd6\x41\xbf\x49\x1a\xcf\x0a\xd1\x78\x51\x8c\xca\xad\x4e\x2c\xfc\ +\xb0\x7d\x21\x81\xf8\xac\xe3\x66\xfb\xd3\x72\xd4\x37\x8b\x47\xfa\ +\x2b\xa9\xa5\x91\xd4\xd2\x41\x58\x57\x07\x1d\x00\x00\x04\xf4\x53\ +\x2b\x54\xba\x51\xa8\x8c\xbe\xd6\xda\x29\xc4\xab\xbf\x25\xd7\x6e\ +\xb6\xb5\x1f\x96\x8e\xbb\xa8\x83\xd5\x3a\x7b\xb9\xd8\xdd\x98\x7d\ +\x1f\xf4\xd4\xe0\xf9\xac\x1a\xc5\x85\x2c\xaa\xdf\xef\xbd\x3c\x29\ +\xd7\xd2\x41\x5d\xfa\xd3\xd4\x41\x3f\xd8\x2c\x4d\xac\x5b\xdf\xda\ +\x7e\x33\x02\xfe\xd6\x27\xe5\x58\xfb\x55\x7a\x61\x67\x02\xcc\x32\ +\x6e\x46\xf5\x57\xff\xe4\xf7\x7e\x1d\xf4\x69\xfd\x05\x00\x00\x08\ +\xe8\x13\xc3\x5c\x6b\x3b\x7f\xad\x66\xcd\x87\xed\x6e\x1c\x2e\x77\ +\x2e\x54\xb3\x98\x5b\x6b\x5f\xfc\x77\x7c\x51\x8a\xb9\xef\x75\xa2\ +\x50\xe9\x5e\x4a\x6d\xf4\xce\x5e\xae\x77\xc8\x58\x94\x22\x9f\x64\ +\xb1\xf8\x76\x3b\x16\xef\xf5\x4a\xcb\xad\x3e\xae\xc7\xe6\x6f\xe7\ +\xc6\xf6\x4f\x5a\xcf\x5d\xeb\x25\xec\xa7\xd5\x6d\xe5\xe2\xd5\x46\ +\x12\x4b\xf7\x9b\x91\xd4\xd2\x98\xbb\xdb\x39\xd7\x98\x3d\xcf\xb8\ +\x39\xde\x5f\x4b\xef\xb4\x06\xcb\xdf\xdf\x7a\xd4\xb8\xf0\xf1\x01\ +\x00\x00\xbc\x81\x01\xfd\xba\x87\xb9\x42\xf5\xe4\xec\xe6\xf0\x7e\ +\xe4\xca\x9d\xf4\x52\x02\xfa\xf0\x3e\xe8\xcb\xaa\x8d\x3e\xfc\x5d\ +\x2f\x9f\x24\x51\x5e\xe9\x2d\x9f\xee\xd7\xa5\x9f\x34\x4b\x7e\x53\ +\xec\x3e\x2d\x45\xf5\x76\x27\x92\x5a\x1a\xcb\xef\x36\x63\xfb\xf3\ +\xd3\x6d\x37\x18\x55\x36\xf0\xa2\xc6\x4d\xb7\x95\x8b\xed\x4f\xcb\ +\x51\x59\x4d\xbf\x5d\xa1\xd2\xab\x5b\x6f\x16\x1d\x00\x00\xae\xa7\ +\x1b\xf1\x3f\xf9\x51\xf5\xa5\x07\x0d\x30\xe5\x44\xec\xf6\x5e\xaf\ +\x89\xaa\xab\x9d\xd7\x76\x7a\x76\x7f\x1f\x74\x44\xef\x60\xb6\x42\ +\x25\x9b\xb9\x1d\x7e\xf0\xeb\xbd\xf8\xc1\xaf\xf7\x26\xb6\xc9\xde\ +\xdf\x4b\x13\x03\xe6\x4d\xb5\xf3\xa4\x17\xca\x73\xc5\x2c\x16\x7f\ +\x34\xf9\x45\x49\x6b\xa7\xf7\x32\xaa\x5c\x4b\x67\x1e\x37\x4b\xeb\ +\xad\x41\x7f\x4d\xba\xc7\xf0\x49\xef\x37\xb5\x6e\x3d\x00\x00\x08\ +\xe8\x57\x58\x7d\xf3\x70\xd6\x77\xee\xee\xf8\x32\x65\x8b\x6f\x1f\ +\xce\x5e\x8e\x2a\xf1\x76\xf0\x75\x69\x10\xca\x96\xde\x69\xbd\xb6\ +\xe7\xd9\xfa\xa4\x1c\xd9\x50\x0d\xf3\x59\x0c\x97\x8a\x2b\xdf\x4a\ +\x27\x06\xf9\x49\x6d\x72\x53\xb5\xb6\xf2\x83\xe5\xe9\xfd\x3a\xe7\ +\xe3\xec\xff\xeb\x70\xdc\xd4\x1e\xce\x36\x6e\xda\xaf\x0e\xdb\x7e\ +\xfe\x7f\xc7\x8f\xe1\xea\xed\x8e\xce\x01\x00\x00\x01\xfd\x6a\x87\ +\xa9\xfe\xec\xf7\xdc\x5a\x7b\xe4\xd2\xf0\xc5\x07\xed\x41\x99\xb0\ +\xb4\x91\x1f\x59\xe2\x6d\xf7\x69\x69\x70\x9f\xf9\xbb\xed\x58\x7e\ +\xaf\x79\x62\x36\xb3\x72\x27\x8d\xe5\x87\xcd\x4b\x7d\x9e\xfe\x3e\ +\xe8\xf3\xb6\x49\x7f\x66\x77\xf1\x5e\x6b\x64\x4d\xed\xe1\x25\xd7\ +\xca\xde\x9d\x34\x5c\x1b\x7d\x62\x40\xdf\x28\x1e\x19\x7f\x2b\x3f\ +\x3f\x39\x6e\x92\x95\xee\xc4\xfa\xea\x07\x5f\x16\x0f\xeb\xb0\xdf\ +\x6f\xc6\xe2\x83\xf6\xc8\x31\xdc\x3f\x74\x2e\xeb\xdc\x8c\x33\x01\ +\x00\x00\xe0\x4d\x75\xad\x36\x17\xdf\x7a\xbf\x3e\x39\x3c\x6d\x24\ +\x47\xf6\xf7\x6e\xff\xb9\x12\xab\x8f\xeb\x83\xfa\xd1\x0b\x3f\x6c\ +\x0f\x42\xd3\xf0\x49\xda\x59\x27\x17\xdf\x7c\x52\x19\x7b\xf0\xd7\ +\xf3\x8f\xaa\xb1\xfa\x8b\xfa\xa0\x0c\x59\xbf\x14\x59\xae\x98\x9d\ +\x98\x49\x3d\xd8\x2c\x5d\x5a\x48\x1a\xde\x07\x3d\xab\x17\x1f\x57\ +\x06\xcf\x32\x5c\x53\x3b\x22\xa2\x50\xc9\x8e\xcc\xce\x4f\x2b\x7b\ +\x37\xad\x0e\xfa\xa8\x3e\xb9\xee\x86\xcf\x04\x98\x66\x78\xdc\xcc\ +\xad\xb5\x63\x6e\xed\xec\xe3\xe6\x9b\x4f\x0e\xc7\xf0\xd2\xfd\x66\ +\x2c\xdd\x6f\x0e\xfa\x6b\xb8\x4c\x61\xd6\xc9\x9d\x7a\x5f\x3c\x00\ +\x00\x70\x35\xbd\xd1\xeb\x97\x5b\x5b\xf9\xd8\xfc\xed\x5c\x1c\x6c\ +\x1e\x2e\x37\xee\xd7\x8f\x1e\x0e\x46\xcf\x3e\x9c\x9b\x78\xb0\x56\ +\xb7\x95\x8b\xe7\x1f\x55\x63\x77\x23\x19\x2c\x33\x4f\x6a\xe9\x91\ +\x90\xd5\xde\xcb\xc7\xd6\xa7\x95\x0b\xab\x55\x3e\x4e\x7f\x1f\xf4\ +\x79\x02\xe6\xa8\x67\x49\x6a\xe9\x20\x9c\xb7\x76\x0a\xf1\xe2\xf7\ +\xd5\xd8\xdf\x70\x38\xdc\x28\xc3\x67\x02\xcc\xd2\xd6\xc7\xc7\xcd\ +\xf6\x93\xf1\xe3\xa6\x3f\x86\x47\xf5\x57\x3f\x9c\x37\x5e\x14\xe3\ +\xf9\xc7\x55\x87\xf9\x01\x00\xc0\x35\x97\x7b\xf4\xe8\xd1\x8d\x39\ +\x55\xea\xf8\xc1\x68\xb3\xce\x74\x1f\xbf\xcf\x75\x2e\x15\x97\xac\ +\x74\x8f\x1c\x2c\x76\x9d\x9f\xe5\xba\xb5\x75\x67\x3f\x1f\x9d\xbd\ +\xdc\x1b\x3f\xf6\xea\xf5\xba\xce\x07\x00\x80\x53\xb8\x51\x53\x6e\ +\x17\xb5\xf4\xfc\x4d\xda\xe7\xab\x24\xd7\xf5\x6a\x6b\x7b\xcc\x01\ +\x00\xe0\xcd\x25\x9d\x01\x00\x00\x80\x80\x0e\x00\x00\x00\x08\xe8\ +\x00\x00\x00\x20\xa0\x03\x00\x00\x00\x02\x3a\x00\x00\x00\x08\xe8\ +\x00\x00\x00\x80\x80\x0e\x00\x00\x00\x02\x3a\x00\x00\x00\x20\xa0\ +\x03\x00\x00\x80\x80\x0e\x00\x00\x00\x08\xe8\x00\x00\x00\x20\xa0\ +\x03\x00\x00\x00\x02\x3a\x00\x00\x00\x08\xe8\x00\x00\x00\x80\x80\ +\x0e\x00\x00\x00\x02\x3a\x00\x00\x00\x20\xa0\x03\x00\x00\x80\x80\ +\x0e\x00\x00\x00\x08\xe8\x00\x00\x00\x20\xa0\x03\x00\x00\x00\x02\ +\x3a\x00\x00\x00\x5c\x23\xff\x05\x00\x00\xff\xff\x03\x00\x78\x29\ +\xcd\x85\x61\x95\xed\x47\x00\x00\x00\x00\x49\x45\x4e\x44\xae\x42\ +\x60\x82\ +" + +qt_resource_name = b"\ +\x00\x03\ +\x00\x00\x78\xc3\ +\x00\x72\ +\x00\x65\x00\x73\ +\x00\x04\ +\x00\x06\xfa\x5e\ +\x00\x69\ +\x00\x63\x00\x6f\x00\x6e\ +\x00\x11\ +\x01\xb7\x20\x27\ +\x00\x70\ +\x00\x69\x00\x70\x00\x65\x00\x6c\x00\x69\x00\x6e\x00\x65\x00\x5f\x00\x6c\x00\x6f\x00\x67\x00\x6f\x00\x2e\x00\x70\x00\x6e\x00\x67\ +\ +\x00\x08\ +\x0a\x61\x5a\xa7\ +\x00\x69\ +\x00\x63\x00\x6f\x00\x6e\x00\x2e\x00\x70\x00\x6e\x00\x67\ +\x00\x1c\ +\x08\x07\xe3\xc7\ +\x00\x70\ +\x00\x6c\x00\x75\x00\x67\x00\x69\x00\x6e\x00\x5f\x00\x63\x00\x6f\x00\x6e\x00\x66\x00\x69\x00\x67\x00\x75\x00\x72\x00\x61\x00\x74\ +\x00\x6f\x00\x72\x00\x5f\x00\x6c\x00\x6f\x00\x67\x00\x6f\x00\x2e\x00\x70\x00\x6e\x00\x67\ +" + +qt_resource_struct = b"\ +\x00\x00\x00\x00\x00\x02\x00\x00\x00\x02\x00\x00\x00\x01\ +\x00\x00\x00\x00\x00\x02\x00\x00\x00\x01\x00\x00\x00\x06\ +\x00\x00\x00\x0c\x00\x02\x00\x00\x00\x01\x00\x00\x00\x03\ +\x00\x00\x00\x00\x00\x02\x00\x00\x00\x02\x00\x00\x00\x04\ +\x00\x00\x00\x1a\x00\x00\x00\x00\x00\x01\x00\x00\x00\x00\ +\x00\x00\x00\x42\x00\x00\x00\x00\x00\x01\x00\x00\x17\xe5\ +\x00\x00\x00\x00\x00\x02\x00\x00\x00\x01\x00\x00\x00\x07\ +\x00\x00\x00\x58\x00\x00\x00\x00\x00\x01\x00\x00\x28\xe7\ +" + +def qInitResources(): + QtCore.qRegisterResourceData(0x01, qt_resource_struct, qt_resource_name, qt_resource_data) + +def qCleanupResources(): + QtCore.qUnregisterResourceData(0x01, qt_resource_struct, qt_resource_name, qt_resource_data) + +qInitResources() diff --git a/toolkit/poisson_disk_generator/.gitignore b/toolkit/poisson_disk_generator/.gitignore new file mode 100644 index 0000000..a2c9784 --- /dev/null +++ b/toolkit/poisson_disk_generator/.gitignore @@ -0,0 +1,19 @@ + +# Prefab gitignore which can be used by the user to ignore the files generated +# by the module builder + +*.pyd +*.pyc +*.so +*.pdb + +# Various output names +win_*/ +linux_*/ +source/interrogate* + +# Source and script files +scripts/ +CMakeLists.txt +build.py +LICENSE diff --git a/toolkit/poisson_disk_generator/config.ini b/toolkit/poisson_disk_generator/config.ini new file mode 100644 index 0000000..f219245 --- /dev/null +++ b/toolkit/poisson_disk_generator/config.ini @@ -0,0 +1,5 @@ +generate_pdb=0 +module_name=PoissonDiskGenerator +use_lib_eigen=0 +use_lib_freetype=0 +vc_version=Visual Studio 10 2010 diff --git a/toolkit/poisson_disk_generator/generate_poisson_disk.py b/toolkit/poisson_disk_generator/generate_poisson_disk.py new file mode 100644 index 0000000..e97e881 --- /dev/null +++ b/toolkit/poisson_disk_generator/generate_poisson_disk.py @@ -0,0 +1,36 @@ +""" + +RenderPipeline + +Copyright (c) 2014-2016 tobspr + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. + +""" + +import PoissonDiskGenerator + + +# XXX: Read options from stdin +sample_count = 64 +evaluations = 15000 +num_tries = 400 +is_3d = False + +PoissonDiskGenerator.PDGenerator(sample_count, evaluations, num_tries, is_3d) diff --git a/toolkit/poisson_disk_generator/source/PoissonDiskGenerator.h b/toolkit/poisson_disk_generator/source/PoissonDiskGenerator.h new file mode 100644 index 0000000..f9dbd86 --- /dev/null +++ b/toolkit/poisson_disk_generator/source/PoissonDiskGenerator.h @@ -0,0 +1,198 @@ + +#include "pandabase.h" +#include "pnmImage.h" + +#include +#include +#include +#include +#include +#include +#include + +using namespace std; + +#define TWO_PI 6.28318530718f +#define square(x) ((x) * (x)) + +struct Vec { + float x, y, z; + inline float length_sq() const { + return x*x + y*y + z*z; + } + inline float dist_sq(const Vec& other) const { + return square(x - other.x) + square(y - other.y) + square(z - other.z); + } + + inline float angle_signed() const { + return atan2(y, x); + } + + friend inline ostream& operator<<(ostream& stream, const Vec& v) { + return stream << "Vec(" << v.x << ", " << v.y << ", " << v.z << ")"; + } +}; + +int compare_vec(const void * a, const void * b) +{ + return ((Vec*)a)->angle_signed() - ((Vec*)b)->angle_signed(); +} + +class PDGenerator +{ + +PUBLISHED: + + PDGenerator(int sample_count, int evaluations, int num_tries, int is_3d_) + { + is_3d = is_3d_; + rnd_device = new random_device(); + rnd_generator = new mt19937(rnd_device->operator()()); + rng = new uniform_real_distribution(-1.0f, 1.0f); + randvec = is_3d ? &PDGenerator::randvec_3d : &PDGenerator::randvec_2d; + + cout << "Sample count = " << sample_count << endl; + cout << "Evaluations = " << evaluations << endl; + cout << "Num tries = " << num_tries << endl; + + Vec* sample_points = new Vec[sample_count]; + Vec* best_points = new Vec[sample_count]; + + float best_score = -100000.0; + + for (size_t try_count = 0; try_count < num_tries; ++try_count) { + // Generate the initial sample point + sample_points[0] = randvec(this); + + // Fill the points + for (size_t i = 1; i < sample_count; ++i) { + Vec best_point; + float best_point_min_dist = 0.0f; + + // Find the point which has the greatest minimum distance to all current points + for (size_t k = 0; k < evaluations; ++k) { + Vec point = randvec(this); + float min_dist = 10000.0; + + // Get the minimum distance to all current points + for (size_t j = 0; j < i; ++j) { + min_dist = min(min_dist, point.dist_sq(sample_points[j])); + } + + if (min_dist > best_point_min_dist) { + best_point = point; + best_point_min_dist = min_dist; + } + } + + sample_points[i] = best_point; + } + + // Rate the points + float score = 0.0; + + // Check for all points + for (size_t i = 0; i < sample_count; ++i) { + + // Find minimum distance to all other points + // float mindist = 10000.0; + float mindist = 0.0; + Vec point = sample_points[i]; + for (size_t j = 0; j < sample_count; ++j) { + if (j == i) continue; + // mindist = min(mindist, point.dist_sq(sample_points[j])); + mindist += point.dist_sq(sample_points[j]); + } + score += mindist * mindist; + } + + if (try_count % 20 == 0) { + cout << "Try " << try_count << " has a score of " << score << endl; + } + + if (score >= best_score) { + memcpy(best_points, sample_points, sizeof(Vec) * sample_count); + best_score = score; + } + + } + + // Sort points based on their angle + qsort(best_points, sample_count, sizeof(Vec), compare_vec); + + // write results + string datatype = is_3d ? "vec3" : "vec2"; + ofstream output("disk.txt"); + + output << "CONST_ARRAY " << datatype << " poisson_disk_" << (is_3d ? "3D" : "2D") + << "_" << sample_count << "[" << sample_count << "] = " << datatype << "[](" << endl; + + // write out all points + for (size_t i = 0; i < sample_count; ++i) { + Vec v = best_points[i]; + output << " " << datatype << "(" << v.x << ", " << v.y; + if (is_3d) { + output << ", " << v.z; + } + output << ")" << (i == sample_count - 1 ? "" : ",") << endl; + } + + output << ");" << endl; + + output.close(); + + // Plot the points + PNMImage dest(256, 256); + + for (float rad = 0.0f; rad < TWO_PI; rad += 0.005f) { + size_t x = int(sin(rad) * 66.0f) + 127; + size_t y = int(cos(rad) * 66.0f) + 127; + if ( int(rad / TWO_PI * 64.0f) % 2 == 0) { + dest.set_xel(x, y, 0, 0.1, 0.1); + } + } + + for (size_t i = 0; i < sample_count; ++i) { + Vec point = best_points[i]; + int px = int(point.x * 64.0) + 127; + int py = int(point.y * 64.0) + 127; + float f = float(i / float(sample_count)) * 0.8 + 0.2; + dest.set_xel(px, py, f, f, f); + } + + dest.write("result.png"); + } + + inline float frand() { + return rng->operator()(*rnd_generator); + } + + inline Vec randvec_3d() { + float r = frand(); + + // this is so wrong that its almost correct again + float phi = frand() * TWO_PI * 0.5; + float theta = (frand() * 0.5 + 0.5) * TWO_PI; + float sin_phi = sin(phi); + Vec v = { sin_phi * cos(theta) * r, sin_phi * sin(theta) * r, + cos(phi) * r }; + return v; + } + + inline Vec randvec_2d() { + float r = frand() * 0.5 + 0.5; + float phi = (frand() * 0.5 + 0.5) * TWO_PI; + Vec v = { cos(phi) * r, sin(phi) * r, 0.0 }; + return v; + } + + bool is_3d; + +#ifndef INTERROGATE + std::function randvec; + std::random_device* rnd_device; + mt19937* rnd_generator; + uniform_real_distribution* rng; +#endif + +}; diff --git a/toolkit/poisson_disk_generator/update_module_builder.py b/toolkit/poisson_disk_generator/update_module_builder.py new file mode 100644 index 0000000..a1d84a2 --- /dev/null +++ b/toolkit/poisson_disk_generator/update_module_builder.py @@ -0,0 +1,57 @@ +""" + +RenderPipeline + +Copyright (c) 2014-2016 tobspr + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. + +""" + +# This script downloads and updates the module builder. + +# pylint: skip-file + +if __name__ == "__main__": + import os + import sys + from os.path import dirname, realpath, isfile + + # Files which are skipped from the downloaded zip + files_to_ignore = "__init__.py LICENSE README.md config.ini".split() + + current_dir = dirname(realpath(__file__)) + os.chdir(current_dir) + + # Import thirdparty packages + sys.path.insert(0, "../../rpcore/util") + sys.path.insert(0, "../../") + + # Download the module + from submodule_downloader import download_submodule + download_submodule("tobspr", "P3DModuleBuilder", current_dir, files_to_ignore) + + # Make an init script so we can import the code + with open("scripts/__init__.py", "w") as handle: + handle.write("") + + # Update the gitignore using the suggested version from the module builder + if isfile(".gitignore"): + os.remove(".gitignore") + os.rename("prefab.gitignore", ".gitignore") diff --git a/toolkit/render_service/README.md b/toolkit/render_service/README.md new file mode 100644 index 0000000..2579b31 --- /dev/null +++ b/toolkit/render_service/README.md @@ -0,0 +1,11 @@ + +## Render service + +This is a tool to generate previews and renders of materials. +It keeps the render pipeline running in the background, and renders scenes +on demand. + +A render can be triggered over the network. Example code for triggering a render +and waiting for completion can be found in `example_usage.py` + + diff --git a/toolkit/render_service/config/daytime.yaml b/toolkit/render_service/config/daytime.yaml new file mode 100644 index 0000000..cbea235 --- /dev/null +++ b/toolkit/render_service/config/daytime.yaml @@ -0,0 +1,6 @@ + +# Render Pipeline Time Of Day Configuration +# Instead of editing this file, prefer to use the Time Of Day Editor +# Any formatting and comments will be lost + +control_points: diff --git a/toolkit/render_service/config/debugging.yaml b/toolkit/render_service/config/debugging.yaml new file mode 100644 index 0000000..fa9cfc3 --- /dev/null +++ b/toolkit/render_service/config/debugging.yaml @@ -0,0 +1,17 @@ + +# This file contains all available debug modes. +# You can add or remove debug modes here, aswell as +# disable or enable them, whatever fits to you. + +# NOTICE: This file only has effect if debugging is enabled +# in the pipeline.yaml (settings.pipeline.display_debuger == True) + +render_modes: + - { name: "Diffuse", key: "DIFFUSE" } + - { name: "Roughness", key: "ROUGHNESS" } + - { name: "Specular", key: "SPECULAR" } + - { name: "Normal", key: "NORMAL" } + - { name: "Metallic", key: "METALLIC" } + - { name: "Translucency", key: "TRANSLUCENCY" } + - { name: "PSSM Splits", key: "PSSM_SPLITS", requires: "pssm", cxx_only: true } + - { name: "Ambient Occlusion", key: "OCCLUSION", requires: "ao" } diff --git a/toolkit/render_service/config/panda3d-config.prc b/toolkit/render_service/config/panda3d-config.prc new file mode 100644 index 0000000..dfdb0fe --- /dev/null +++ b/toolkit/render_service/config/panda3d-config.prc @@ -0,0 +1,172 @@ + + +# This is the config file used to configure basic settings for Panda3D. +# The pipeline loads it at startup to ensure the environment is setup properly. + +# -------------- Debugging options -------------- + +# gl-dump-compiled-shaders #t +# notify-level-glgsg debug +# notify-level-glgsg warning +# notify-level-gobj debug +pstats-gpu-timing #t +pstats-max-rate 200 +gl-debug #t +gl-debug-object-labels #t +sync-video #f + +# ----------------- Misc Settings ----------------- + +# No stack trace on assertion, set this to true to make panda crash on assertions +# (which will allow to debug it) +assert-abort #t + +# File system should be case sensitive +# NOTICE: Set this to #f if you are using tempfile, since it returns +# wrong cased directory paths +vfs-case-sensitive #t + +# Enable state cache, this seems to actually help the performance by a lot +state-cache #t +transform-cache #t + +# Frame rate meter style +frame-rate-meter-milliseconds #t +frame-rate-meter-update-interval 1.0 +frame-rate-meter-text-pattern %0.2f fps +frame-rate-meter-ms-text-pattern %0.3f ms +frame-rate-meter-layer-sort 1000 +frame-rate-meter-scale 0.036 +frame-rate-meter-side-margins 0.4 +show-frame-rate-meter #f + +# Set text settings +text-minfilter linear +text-magfilter linear +text-page-size 512 512 + +# Better text performance since rdb's patch +text-flatten 0 +text-dynamic-merge 1 + +# For smoother animations +# even-animation #t + +# Threading, really buggy! +#threading-model App/Cull/Draw + +support-stencil #f +framebuffer-stencil #f + +# Don't use srgb correction, we do that ourself +framebuffer-srgb #f + +# Don't use multisamples +framebuffer-multisample #f +multisamples 0 + +# Don't rescale textures which are no power-of-2 +textures-power-2 none + +# This is required, the pipeline does not support resizing yet +win-fixed-size #t + +# Set default texture filters +texture-anisotropic-degree 8 +texture-magfilter linear +texture-minfilter linear +texture-quality-level fastest + +# Enable seamless cubemap filtering, thats important for environment filtering +gl-cube-map-seamless #t + +# Set model cache dir +model-cache-dir $USER_APPDATA/Panda3D-1.9/cache +model-cache-textures #f + +# Disable the annoying SRGB warning from pnmimage +notify-level-pnmimage error + +# Disable the buffer viewer, we have our own +show-buffers #f + +# Use the default coordinate system, this makes our matrix transformations +# faster because we don't have have to transform them to a different coordinate +# system before +gl-coordinate-system default + +# This makes animations smoother, especially if they were exported at 30 FPS +# and are played at 60 FPS +interpolate-frames #t + +# Disable workarround in panda which causes our shadow atlas to take twice +# the amount of vram it should, due to an intel driver bug. +gl-force-fbo-color #f + +# ----------- OpenGL / Performance Settings ------------ + +# Animations on the gpu. The default shader has to get adjusted to support this +# feature before this option can be turned on. +# hardware-animated-vertices #t + +# Try this options for performance +# uniquify-matrix #t +# uniquify-transforms #t +# uniquify-states #t +# uniquify-attribs #f + +# Enable garbarge collection +garbage-collect-states #t +# garbage-collect-states-rate 0.2 + +# Compress textures on the drivers? +# driver-compress-textures #t + +# Faster animations? (Have to test) +# matrix-palette #t +# display-list-animation #t + +# Better GL performance by not using gl-finish and so on +gl-finish #f +gl-force-no-error #t +gl-check-errors #f +gl-force-no-flush #t +gl-force-no-scissor #t + +# Eventually disable memory barriers, have to check if this is faster +gl-enable-memory-barriers #f + +# Disable threading +lock-to-one-cpu #t +support-threads #f + +# Let the driver generate the mipmaps +driver-generate-mipmaps #t +#gl-ignore-mipmaps #t + +# Use immutable texture storage, it is *supposed* to be faster, but might not be +gl-immutable-texture-storage #t + +# auto-flip #f + +# Default window settings +# depth-bits 0 +color-bits 0 + +framebuffer-depth #f + +gl-fixed-vertex-attrib-locations #f + +# Disable the fragment shader performance warning +gl-validate-shaders #f +gl-skip-shader-recompilation-warnings #t + +alpha-scale-via-texture #f +bounds-type best # best/fastest/sphere/box +pstats-name Render Pipeline Stats +rescale-normals #f +screenshot-extension png + +# Required for correct velocity +always-store-prev-transform #t +allow-incomplete-render #t diff --git a/toolkit/render_service/config/pipeline.yaml b/toolkit/render_service/config/pipeline.yaml new file mode 100644 index 0000000..4b3836b --- /dev/null +++ b/toolkit/render_service/config/pipeline.yaml @@ -0,0 +1,19 @@ + +pipeline: + display_debugger: false + use_r11_g11_b10: false + resolution_scale: 1.0 + reference_mode: true + +lighting: + culling_grid_size_x: 32 + culling_grid_size_y: 16 + culling_grid_slices: 32 + culling_max_distance: 50.0 + culling_slice_width: 256 + max_lights_per_cell: 64 + +shadows: + atlas_size: 4096 + max_updates: 40 + max_update_distance: 150.0 diff --git a/toolkit/render_service/config/plugins.yaml b/toolkit/render_service/config/plugins.yaml new file mode 100644 index 0000000..f76c758 --- /dev/null +++ b/toolkit/render_service/config/plugins.yaml @@ -0,0 +1,29 @@ + +# Render Pipeline Plugin Configuration +# Instead of editing this file, prefer to use the Plugin Configurator +# Any formatting and comments will be lost + +enabled: + # - ao + # - bloom + # - color_correction + # - env_probes + # - pssm + # - scattering + # - smaa + # - ssr + # - clouds + # - dof + - fxaa + # - motion_blur + # - skin_shading + # - volumetrics + # - vxgi + + +overrides: + fxaa: + quality: ultra + subpixel_quality: 0.5 + edge_threshold: 0.075 + min_threshold: 0.7114 diff --git a/toolkit/render_service/config/stages.yaml b/toolkit/render_service/config/stages.yaml new file mode 100644 index 0000000..c76ef0a --- /dev/null +++ b/toolkit/render_service/config/stages.yaml @@ -0,0 +1,61 @@ + +# This file controls the order of all render stages. +# Usually you do not have to modify this, except if you are adding new plugins. +# If you move stages, you should know what you do. +# Commenting out a stage won't disable it, but instead produce an error when +# it is created. + +global_stage_order: + + # Shadows, Environment and Voxelization + - PSSMShadowStage + - PSSMDistShadowStage + - PSSMSceneShadowStage + - ScatteringEnvmapStage + - EnvironmentCaptureStage + - VoxelizationStage + + # Main scene + - GBufferStage + - ShadowStage + - DownscaleZStage + - CombineVelocityStage + + # Light(-culling) + - FlagUsedCellsStage + - CollectUsedCellsStage + - CullLightsStage + - CullProbesStage + + # Plugins + - CloudVoxelStage + - AOStage + - ApplyLightsStage + - PSSMStage + - ScatteringStage + - ApplyEnvprobesStage + - VXGIStage + - SSRStage + - SSSRStage + - AmbientStage + - ApplyCloudsStage + - GodrayStage + - VolumetricsStage + - AutoExposureStage + - ManualExposureStage + + # Post AA & Effects + - BloomStage + - TonemappingStage + - SMAAStage + - FXAAStage + - DoFStage + - MotionBlurStage + - SkinShadingStage + - SharpenStage + - ColorCorrectionStage + + # Finishing stages, do not insert anything below + - UpscaleStage + - FinalStage + - UpdatePreviousPipesStage diff --git a/toolkit/render_service/config/task-scheduler.yaml b/toolkit/render_service/config/task-scheduler.yaml new file mode 100644 index 0000000..ea5c9ed --- /dev/null +++ b/toolkit/render_service/config/task-scheduler.yaml @@ -0,0 +1,2 @@ +frame_cycles: !!omap + - frame0: diff --git a/toolkit/render_service/example_usage.py b/toolkit/render_service/example_usage.py new file mode 100644 index 0000000..3ae0119 --- /dev/null +++ b/toolkit/render_service/example_usage.py @@ -0,0 +1,58 @@ +""" + +Example of using the render service to render a simple sphere. +The render service should be running. + +""" + +import sys +import pickle +import socket + +# Address of the render service +renderer_ip = ("127.0.0.1", 62360) + +# Port which the render service will ping when its done. +pingback_port = 62500 + +# Scene data +payload = pickle.dumps({ + "scene": "resources/preview.bam", + "dest": "demo-render.png", + "view_size_x": 512, + "view_size_y": 512, + "pingback_port": pingback_port +}, protocol=0) + +# Start rendering +print("Sending payload ...") +sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) +try: + sock.sendto(payload, renderer_ip) +except Exception as msg: + sock.close() + raise msg + +# Wait until the renderer finished +print("Waiting for response ...") +sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM) +sock.setsockopt(socket.IPPROTO_TCP, socket.TCP_NODELAY, 1) +sock.settimeout(3.0) + +try: + sock.bind(("localhost", pingback_port)) +except Exception as msg: + print("Could not connect to pingback_port - maybe a render result is still waiting?") + print("Error message:", msg) + sys.exit(1) + +sock.listen(1) + +try: + conn, addr = sock.accept() +except socket.timeout: + print("No render pipeline response within timeout! Make sure the service is running.") + sock.close() + sys.exit(1) + +print("Rendering was done!") diff --git a/toolkit/render_service/resources/preview.bam b/toolkit/render_service/resources/preview.bam new file mode 100644 index 0000000..e9985c7 Binary files /dev/null and b/toolkit/render_service/resources/preview.bam differ diff --git a/toolkit/render_service/resources/sphere.bam b/toolkit/render_service/resources/sphere.bam new file mode 100644 index 0000000..d33af9a Binary files /dev/null and b/toolkit/render_service/resources/sphere.bam differ diff --git a/toolkit/render_service/resources/tex/empty_basecolor.png b/toolkit/render_service/resources/tex/empty_basecolor.png new file mode 100644 index 0000000..437c244 Binary files /dev/null and b/toolkit/render_service/resources/tex/empty_basecolor.png differ diff --git a/toolkit/render_service/resources/tex/empty_normal.png b/toolkit/render_service/resources/tex/empty_normal.png new file mode 100644 index 0000000..863dc2e Binary files /dev/null and b/toolkit/render_service/resources/tex/empty_normal.png differ diff --git a/toolkit/render_service/resources/tex/empty_roughness.png b/toolkit/render_service/resources/tex/empty_roughness.png new file mode 100644 index 0000000..437c244 Binary files /dev/null and b/toolkit/render_service/resources/tex/empty_roughness.png differ diff --git a/toolkit/render_service/resources/tex/empty_specular.png b/toolkit/render_service/resources/tex/empty_specular.png new file mode 100644 index 0000000..26ee224 Binary files /dev/null and b/toolkit/render_service/resources/tex/empty_specular.png differ diff --git a/toolkit/render_service/service.py b/toolkit/render_service/service.py new file mode 100644 index 0000000..a9609c5 --- /dev/null +++ b/toolkit/render_service/service.py @@ -0,0 +1,174 @@ +""" + +Render service to render previews of materials + +""" + +from __future__ import print_function + +import sys +import socket +import time +import pickle + +from threading import Thread + +from panda3d.core import load_prc_file_data, Filename, Mat4 +from panda3d.core import CS_zup_right, CS_yup_right, BamCache +from direct.showbase.ShowBase import ShowBase + +sys.path.insert(0, "../../") +from rpcore import RenderPipeline, PointLight # noqa + + +class Application(ShowBase): + + ICOMING_PORT = 62360 + + def __init__(self): + load_prc_file_data("", "win-size 512 512") + load_prc_file_data("", "window-type offscreen") + load_prc_file_data("", "model-cache-dir") + load_prc_file_data("", "model-cache-textures #f") + load_prc_file_data("", "textures-power-2 none") + load_prc_file_data("", "alpha-bits 0") + load_prc_file_data("", "print-pipe-types #f") + + # Construct render pipeline + self.render_pipeline = RenderPipeline() + self.render_pipeline.mount_mgr.config_dir = "config/" + self.render_pipeline.create(self) + + self.setup_scene() + + # Disable model caching + BamCache.get_global_ptr().cache_models = False + + self.update_queue = [] + self.start_listen() + + # Render initial frames + for i in range(10): + self.taskMgr.step() + + last_update = 0.0 + self.scene_node = None + + # Wait for updates + while True: + + # Update once in a while + curr_time = time.time() + if curr_time > last_update + 1.0: + last_update = curr_time + self.taskMgr.step() + + if self.update_queue: + if self.scene_node: + self.scene_node.remove_node() + + # Only take the latest packet + payload = self.update_queue.pop(0) + print("RENDERING:", payload) + + scene = self.loader.loadModel(Filename.from_os_specific(payload["scene"])) + + for light in scene.find_all_matches("**/+PointLight"): + light.remove_node() + for light in scene.find_all_matches("**/+Spotlight"): + light.remove_node() + + # Find camera + main_cam = scene.find("**/Camera") + if main_cam: + transform_mat = main_cam.get_transform(self.render).get_mat() + transform_mat = Mat4.convert_mat(CS_zup_right, CS_yup_right) * transform_mat + self.camera.set_mat(transform_mat) + else: + print("WARNING: No camera found") + self.camera.set_pos(0, -3.5, 0) + self.camera.look_at(0, -2.5, 0) + + self.camLens.set_fov(64.0) + + self.scene_node = scene + scene.reparent_to(self.render) + + # Render scene + for i in range(8): + self.taskMgr.step() + + dest_path = Filename.from_os_specific(payload["dest"]) + print("Saving screenshot to", dest_path) + self.win.save_screenshot(dest_path) + self.notify_about_finish(int(payload["pingback_port"])) + + def start_listen(self): + """ Starts the listener thread """ + thread = Thread(target=self.listener_thread, args=(), name="ListenerThread") + thread.setDaemon(True) + thread.start() + return thread + + def listener_thread(self): + """ Thread which listens to incoming updates """ + sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) + sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1) + print("Listening on 127.0.0.1:" + str(self.ICOMING_PORT)) + try: + sock.bind(("127.0.0.1", self.ICOMING_PORT)) + while True: + data, addr = sock.recvfrom(8192) + self.handle_data(data) + except Exception as msg: + print("Failed to bind to address! Reason:", msg) + finally: + sock.close() + + def handle_data(self, data): + """ Handles a new update """ + # print("Got:", data) + unpacked_data = pickle.loads(data) + # print("Data = ", unpacked_data) + self.update_queue.append(unpacked_data) + + def notify_about_finish(self, port): + """ Notifies the caller that the result finished """ + print("Sending finish result to localhost:" + str(port)) + sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM) + sock.setsockopt(socket.IPPROTO_TCP, socket.TCP_NODELAY, 1) + try: + sock.connect(("localhost", port)) + except Exception as msg: + print("Could not send finish result: ", msg) + return + sock.sendall(b"done") + print("Sent done flag.") + sock.close() + + def setup_scene(self): + """ Setups the basic scene geometry """ + self.disableMouse() + self.render2d.hide() + self.aspect2d.hide() + + light = PointLight() + light.pos = 20.0, -0.85, -1.31 + light.radius = 100.0 + light.energy = 2500 + light.set_color_from_temperature(8000) + # self.render_pipeline.add_light(light) + + light = PointLight() + light.pos = -11.2, -13.84, -9.24 + light.radius = 1e20 + light.set_color_from_temperature(8000) + light.energy = 2500 + # self.render_pipeline.add_light(light) + + # envprobe = self.render_pipeline.add_environment_probe() + # envprobe.set_pos(0, -16.2, 4.4) + # envprobe.set_scale(40, 40, 40) + # envprobe.parallax_correction = False + +Application() diff --git a/toolkit/rp_distributor/README.md b/toolkit/rp_distributor/README.md new file mode 100644 index 0000000..9320548 --- /dev/null +++ b/toolkit/rp_distributor/README.md @@ -0,0 +1,5 @@ +## RP Distributor + +This makes a distributed copy of the render pipeline, with all not-necessary +files (like the whole toolkit/ folder) removed. + diff --git a/toolkit/rp_distributor/launch.templ.bat b/toolkit/rp_distributor/launch.templ.bat new file mode 100644 index 0000000..d3c1007 --- /dev/null +++ b/toolkit/rp_distributor/launch.templ.bat @@ -0,0 +1,23 @@ +@echo off + +rem set required paths +set PANDAPATH=%~dp0panda3d +set PATH=%PANDAPATH%\bin;%PANDAPATH%;%PATH% +set PYTHONPATH=%PANDAPATH%\;%PYTHONPATH% + +rem check for visual studio dlls +where msvcp140.dll >nul 2>nul +if ERRORLEVEL 1 ( + @echo This program requires the Microsoft Visual C++ 2015 Runtime. + @echo Hit a key to visit the download page. + pause + start https://www.microsoft.com/en-us/download/details.aspx?id=48145 + goto end +) + +rem execute actual program +@echo Running Panda3D from "%PANDAPATH%" +"%PANDAPATH%\python\ppython.exe" -B application/main.py +pause + +:end diff --git a/toolkit/rp_distributor/main.py b/toolkit/rp_distributor/main.py new file mode 100644 index 0000000..e8959c3 --- /dev/null +++ b/toolkit/rp_distributor/main.py @@ -0,0 +1,154 @@ +""" Tool to distribute the rp and the panda3d build. """ + +from __future__ import print_function + +import os +import sys +import shutil +from os.path import isdir, join, dirname, realpath, relpath + +base_dir = realpath(dirname(__file__)) +rp_dir = realpath(join(base_dir, "../../")) +os.chdir(base_dir) + +sys.path.insert(0, rp_dir) +from rplibs.six.moves import input # noqa # pylint: disable=import-error + +# TODO: Add option to skip gui folders if debugger is disabled + +rp_ignores = [ + + # data + "skybox-blend.zip", + "skybox.jpg", + "skybox-2.jpg", + "default_cubemap/source", + "default_cubemap/source_2", + "default_cubemap/filter.compute.glsl", + "default_cubemap/filter.py", + "data/generate_txo_files.py", + "README.md", + "environment_brdf/generate_reference.py", + "run_mitsuba.bat", + ".mip", + ".xml", + ".exr", + ".psd", + ".diff", + ".pyc", + ".pdb", + "__pycache__", + "environment_brdf/res/", + "film_grain/generate.py", + "film_grain/grain.compute.glsl", + "ies_profiles/PREVIEWS.jpg", + "loading_screen_bg.png", + + + # rpcore + "native/scripts", + "native/source", + "native/win_amd", + "native/win_i386", + "native/.gitignore", + "native/build.py", + "native/CMakeLists", + "native/update_module_builder.py", + "native/config.ini", + + # rpplugins + ".ffxml", + "bloom/resources/SOURCE.txt", + "bloom/resources/lens_dirt.png", + "clouds/resources/generate_", + "clouds/resources/noise.inc", + "clouds/resources/precompute.py", + "color_correction/resources/film_luts_raw", + "color_correction/resources/generate_", + "plugin_prefab", + "scattering/resources/hosek_wilkie_scattering", + + "toolkit", + +] + +panda_ignores = [ + ".pdb", + ".pyc", + "python/.vs", + "python/include", +] + +app_ignores = [ + ".pyc", + ".blend" +] + + +def copy_tree(source_dir, dest_dir, ignorelist, tree_pth): + source = join(source_dir, tree_pth) + dest = join(dest_dir, tree_pth) + for basepath, dirnames, files in os.walk(source): + for f in files: + abspath = realpath(join(basepath, f)) + abspath = abspath.replace("\\", "/") + + for ignore in ignorelist: + if ignore in abspath: + break + else: + local_pth = relpath(abspath, start=source) + dest_pth = join(dest, local_pth) + dname = dirname(dest_pth) + if not isdir(dname): + print("Creating", dname) + os.makedirs(dname) + shutil.copyfile(abspath, dest_pth) + + +def distribute(): + print("Render Pipeline Distributor v0.1") + print("") + print("Copying tree ..") + + dist_folder_name = "built" + + tmp_dir = join(base_dir, dist_folder_name, "render_pipeline") + if isdir(tmp_dir): + shutil.rmtree(tmp_dir) + os.makedirs(tmp_dir) + + for dname in ("config", "data", "rplibs", "effects", "rpcore", "rpplugins", "toolkit"): + copy_tree(rp_dir, tmp_dir, rp_ignores, dname) + + shutil.copyfile(join(rp_dir, "LICENSE.txt"), join(tmp_dir, "LICENSE.txt")) + + print("Copying Panda3D build ...") + + python_pth = realpath(dirname(sys.executable)) + panda_pth = realpath(join(python_pth, "..")) + + tmp_dir = join(base_dir, dist_folder_name, "panda3d") + if isdir(tmp_dir): + shutil.rmtree(tmp_dir) + os.makedirs(tmp_dir) + + for dname in ("direct", "etc", "models", "panda3d", "pandac", "python"): + copy_tree(panda_pth, tmp_dir, panda_ignores, dname) + + copy_tree(panda_pth, tmp_dir, panda_ignores + [".exe"], "bin") + + shutil.copyfile(join(panda_pth, "LICENSE"), join(tmp_dir, "LICENSE.txt")) + + # Copy launcher script + shutil.copyfile( + join(base_dir, "launch.templ.bat"), join(base_dir, dist_folder_name, "launch.bat")) + + # Copy application + app_pth = join(base_dir, "../../../RenderPipeline-Samples/01-Material-Demo/") + tmp_dir = join(base_dir, dist_folder_name, "application") + + copy_tree(app_pth, tmp_dir, app_ignores, ".") + +if __name__ == "__main__": + distribute() diff --git a/tools/camera_orbit_controller.py b/tools/camera_orbit_controller.py new file mode 100644 index 0000000..dab06e9 --- /dev/null +++ b/tools/camera_orbit_controller.py @@ -0,0 +1,447 @@ +# -*- coding: utf-8 -*- +""" +CameraOrbitController +--------------------- +通用的轨道/平移/缩放 + WASD/QE 漫游控制器,操作习惯贴近 Unity: + +- Alt + 左键拖动:围绕目标轨道旋转。 +- 中键(滚轮按下)拖动:平移。 +- Alt + 右键拖动或滚轮滚动:缩放/推拉。 +- 右键按住:自由视角旋转;右键按住时 WASD/QE/Space 飞行移动。 + +用法: + from camera_orbit_controller import CameraOrbitController + controller = CameraOrbitController(base) # base 为 ShowBase 实例 +""" +import importlib +import importlib.util + +HAS_IMGUI = False +if importlib.util.find_spec("imgui_bundle"): + from imgui_bundle import imgui + HAS_IMGUI = True + +import math +from typing import Optional + +from panda3d.core import LPoint3, Vec3, KeyboardButton, NodePath +from direct.showbase.ShowBaseGlobal import globalClock +from direct.showbase.ShowBase import ShowBase +from panda3d.core import MouseButton,MouseWatcher +import panda3d.core as p3d +from direct.task import Task + + +class CameraOrbitController: + def __init__( + self, + base:ShowBase, + target: Optional[LPoint3] = None, + target_model: Optional[NodePath] = None, + distance: float = 12.0, + yaw: float = 30.0, + pitch: float = -20.0, + move_speed: float = 12.0, + orbit_sensitivity: float = 0.3, + orbit_requires_alt: bool = True, + pan_factor: float = 0.002, + zoom_factor: float = 0.001, + block_io = None + ): + # 传入的 ShowBase 实例(含渲染节点、相机、窗口、任务管理器) + self.base = base + # 关闭 Panda3D 默认 TrackballController,避免它同时改动相机姿态导致绕轨时角度怪异 + if hasattr(self.base, "disableMouse"): + self.base.disableMouse() + self.render: Optional[ShowBase] = base.render + self.cam: Optional[NodePath] = getattr(base, "camera", base.cam) + self.win = base.win + self.mouseWatcher:MouseWatcher = getattr(base, "mouseWatcherNode", None) + self.block_io = block_io + + # 相机围绕的目标点与初始距离/角度 + if target_model and (target_model.children or not target_model.isEmpty): + bounds = target_model.getTightBounds() + min_pt, max_pt = bounds + self.cam_target = (min_pt + max_pt) * 0.5 + extent = (max_pt - min_pt) + self.distance = extent.length() * distance + + else: + self.cam_target = target or LPoint3(0, 0, 0) + self.distance = distance + + self.focus_target_node: Optional[NodePath] = target_model + self.yaw = yaw + self.pitch = pitch + + # 运动与灵敏度参数 + self.move_speed = move_speed + self.orbit_sensitivity = orbit_sensitivity + self.orbit_requires_alt = orbit_requires_alt + self.pan_factor = pan_factor + self.zoom_factor = zoom_factor + + # 鼠标状态缓存 + self.lmb_down = False # 左键 + self.mmb_down = False # 中键(滚轮) + self.rmb_down = False # 右键 + self.mods = [] # 修饰键(来自 Qt 事件的 alt/shift/control) + self.base.accept("alt-lalt", lambda: self._set_mod("alt", True)) + self.base.accept("lalt-up", lambda: self._set_mod("alt", False)) + # self.base.accept("alt-mouse1", self._alt_mouse1) + # self.base.accept("alt-mouse1-up", self._alt_mouse1_up) + + self._last_pointer = None + + # 键盘移动状态 + self.move_state = {"w": False, "a": False, "s": False, "d": False, "q": False, "e": False, "space": False} + + # 事件注册与任务添加 + self.using_mousewatcher = self.mouseWatcher is not None + self.pointer_xy = None # 记录 Qt 事件传入的鼠标位置 + + self._update_camera() + self._mouse_task = None + self._focus_task = None + if self.using_mousewatcher: + self._mouse_task = base.taskMgr.add(self._poll_mouse, "camera-orbit-mouse") + # print("Using mouseWatcher") + else: + # print("Not Using mouseWatcher") + pass + + self._register_events() + + self._move_task = base.taskMgr.add(self._update_task, "camera-orbit-update") + + def _alt_mouse1(self, evt): + self._set_mod("alt", True) + self._set_button_state("lmb", True, evt) + + def _alt_mouse1_up(self, evt): + self._set_mod("alt", False) + self._set_button_state("lmb", False, evt) + + def _set_mod(self, mod: str, state: bool): + if state and mod not in self.mods: + self.mods.append(mod) + elif not state and mod in self.mods: + self.mods.remove(mod) + + # 公共接口 ----------------------------------------------------------- + def set_target(self, target: NodePath|None): + """设置新的注视点并立即更新相机。""" + if target: + self.cam_target = target.get_pos(self.render) + self.focus_target_node = target + + def set_focus_target(self, focus_node: Optional[NodePath]): + """设置按 F 聚焦时使用的目标 NodePath。""" + self.focus_target_node = focus_node + + def destroy(self): + """清理事件与任务,便于在销毁/切换场景时释放。""" + if self._mouse_task: + self.base.taskMgr.remove(self._mouse_task) + if self._move_task: + self.base.taskMgr.remove(self._move_task) + if self._focus_task: + self.base.taskMgr.remove(self._focus_task) + for key in list(self.move_state.keys()): + self.base.ignore(key) + self.base.ignore(f"{key}-up") + for ev in [ + "wheel_up", + "wheel_down", + "wheel", + "mouse1", + "mouse1-up", + "mouse2", + "mouse2-up", + "mouse3", + "mouse3-up", + "mouse-move", + ]: + self.base.ignore(ev) + self.base.ignore("f") + + # 内部逻辑 ----------------------------------------------------------- + def _register_events(self): + """注册鼠标与键盘事件。""" + # 滚轮(Qt 侧会发 'wheel' 事件,常规 Panda3D 为 wheel_up/down) + self.base.accept("wheel_up", lambda: self._on_wheel(120)) + self.base.accept("wheel_down", lambda: self._on_wheel(-120)) + self.base.accept("wheel", lambda evt: self._on_wheel(evt.get("delta", 0) if isinstance(evt, dict) else 0)) + + for key in self.move_state: + self.base.accept(key, self._set_key, [key, True]) + self.base.accept(f"{key}-up", self._set_key, [key, False]) + + # 对嵌入 Qt 的 offscreen,mouseWatcher 常为空,改用事件驱动 + self.base.accept("mouse1", lambda evt=None: self._set_button_state("lmb", True, evt)) + self.base.accept("mouse1-up", lambda evt=None: self._set_button_state("lmb", False, evt)) + self.base.accept("mouse2", lambda evt=None: self._set_button_state("rmb", True, evt)) + self.base.accept("mouse2-up", lambda evt=None: self._set_button_state("rmb", False, evt)) + self.base.accept("mouse3", lambda evt=None: self._set_button_state("mmb", True, evt)) + self.base.accept("mouse3-up", lambda evt=None: self._set_button_state("mmb", False, evt)) + self.base.accept("mouse-move", self._on_mouse_move_event) + # Unity 风格:按 F 聚焦当前选中物体 + self.base.accept("f", self.focus_on_node) + + def _on_wheel(self, delta: float): + """滚轮缩放,按距离比例调整。""" + zoom = 1.0 - (delta * self.zoom_factor) + zoom = max(0.2, min(5.0, zoom)) + self.distance = max(0.5, self.distance * zoom) + self._update_camera() + + def _set_key(self, key, pressed): + # print(f"{key} {pressed}") + """更新键盘按下/抬起状态。""" + self.move_state[key] = pressed + + def _set_button_state(self, name: str, down: bool, evt=None): + """Qt 嵌入时由 messenger 事件更新按键状态。""" + if name == "lmb": + self.lmb_down = down + elif name == "mmb": + self.mmb_down = down + elif name == "rmb": + self.rmb_down = down + if isinstance(evt, dict) and "x" in evt and "y" in evt: + self.pointer_xy = (evt["x"], evt["y"]) + self._last_pointer = None + + def _on_mouse_move_event(self, evt: dict): + """Qt 嵌入时的鼠标移动事件处理(evt: {'x':..,'y':..})。""" + if not isinstance(evt, dict): + return + x, y = evt.get("x"), evt.get("y") + if x is None or y is None: + return + if self._last_pointer is None: + self._last_pointer = (x, y) + return + dx = x - self._last_pointer[0] + dy = y - self._last_pointer[1] + self._last_pointer = (x, y) + + alt_down = ("alt" in self.mods) + if self.lmb_down and (alt_down or not self.orbit_requires_alt): + self.yaw += dx * self.orbit_sensitivity + self.pitch = max(-89.0, min(89.0, self.pitch - + dy * self.orbit_sensitivity)) + self._update_camera() + elif self.mmb_down: + quat = self.cam.getQuat(self.render) + right = quat.getRight() + up = quat.getUp() + pan_speed = self.distance * self.pan_factor + self.cam_target += right * (-dx * pan_speed) + self.cam_target += up * (dy * pan_speed) + self._update_camera() + elif self.rmb_down: + self.yaw += dx * self.orbit_sensitivity + self.pitch = max(-89.0, min(89.0, self.pitch - + dy * self.orbit_sensitivity)) + self._update_camera() + + def _poll_mouse(self, task): + """轮询鼠标指针,计算 dx/dy 并执行轨道或平移。""" + if self.mouseWatcher and self.mouseWatcher.hasMouse(): + # 使用即时按钮状态,避免按 Alt 后再按键导致的事件缺失 + current_lmb = self.mouseWatcher.isButtonDown(MouseButton.one()) + current_mmb = self.mouseWatcher.isButtonDown(MouseButton.two()) + current_rmb = self.mouseWatcher.isButtonDown(MouseButton.three()) + if (current_lmb != self.lmb_down + or current_mmb != self.mmb_down + or current_rmb != self.rmb_down): + self._last_pointer = None + self.lmb_down = current_lmb + self.mmb_down = current_mmb + self.rmb_down = current_rmb + + x = self.win.getPointer(0).getX() + y = self.win.getPointer(0).getY() + if self._last_pointer is None: + self._last_pointer = (x, y) + return task.cont + + dx = x - self._last_pointer[0] + dy = y - self._last_pointer[1] + self._last_pointer = (x, y) + + # Alt 检测兼容左右 Alt(部分系统/窗口管理器会屏蔽 Alt+LMB,可将 orbit_requires_alt 设为 False 仅用 LMB 轨道) + alt_down = ( + self.mouseWatcher.isButtonDown(KeyboardButton.alt()) + or self.mouseWatcher.isButtonDown(KeyboardButton.lalt()) + or self.mouseWatcher.isButtonDown(KeyboardButton.ralt()) + ) + + # Alt + 左键:轨道旋转 + # print(f"alt_down->{alt_down} lmb_down->{self.lmb_down} lmb_down->{self.lmb_down}") + if self.lmb_down and (alt_down or not self.orbit_requires_alt): + self.yaw += dx * self.orbit_sensitivity + self.pitch = max(-89.0, min(89.0, self.pitch -dy * self.orbit_sensitivity)) + self._update_camera() + + # 中键:平移 + elif self.mmb_down: + quat = self.cam.getQuat(self.render) + right = quat.getRight() + up = quat.getUp() + pan_speed = self.distance * self.pan_factor + self.cam_target += right * (-dx * pan_speed) + self.cam_target += up * (dy * pan_speed) + self._update_camera() + + # Alt + 右键:推拉(缩放) + elif alt_down and self.rmb_down: + dolly = 1.0 - (dy * self.zoom_factor) + dolly = max(0.2, min(5.0, dolly)) + self.distance = max(0.5, self.distance * dolly) + self._update_camera() + + # 右键:自由视角旋转 + elif self.rmb_down: + self.yaw += dx * self.orbit_sensitivity + self.pitch = max(-89.0, min(89.0, self.pitch -dy * self.orbit_sensitivity)) + self._update_camera() + return task.cont + + def _update_task(self, task:Task): + if HAS_IMGUI: + io = imgui.get_io() + if io.want_capture_mouse: return task.cont + + """每帧根据键盘状态推动摄像机目标点。""" + dt = globalClock.getDt() + move_vec = Vec3(0, 0, 0) + + quat = self.cam.getQuat(self.render) + forward = quat.getForward() + right = quat.getRight() + up = Vec3(0, 0, 1) + + # 只有右键按住时启用 WASD/QE(符合 Unity 右键飞行视角) + if self.rmb_down: + if self.move_state["w"]: + move_vec += forward + if self.move_state["s"]: + move_vec -= forward + if self.move_state["a"]: + move_vec -= right + if self.move_state["d"]: + move_vec += right + if self.move_state["q"]: + move_vec -= up + if self.move_state["e"] or self.move_state["space"]: + move_vec += up + + if move_vec.length_squared() > 0: + move_vec.normalize() + move_vec *= self.move_speed * dt + self.cam_target += move_vec + self._update_camera() + + return task.cont + + def _update_camera(self, look_at: bool = True): + if HAS_IMGUI: + io = imgui.get_io() + if io.want_capture_mouse: return + + """根据 yaw/pitch/距离刷新相机位置并朝向目标。""" + rad_yaw = math.radians(self.yaw) + rad_pitch = math.radians(self.pitch) + + dir_vec = Vec3( + math.sin(rad_yaw) * math.cos(rad_pitch), + math.cos(rad_yaw) * math.cos(rad_pitch), + math.sin(rad_pitch), + ) + + cam_pos = self.cam_target - dir_vec * self.distance + self.cam.setPos(cam_pos) + if (look_at): + self.cam.lookAt(self.cam_target) + + # 聚焦 --------------------------------------------------------------- + def focus_on_node(self, node: Optional[NodePath] = None, duration: float = 0.2, padding: float = 1.2): + """ + 按 F 聚焦到指定物体或最近一次设置的 focus_target_node。 + 会根据包围盒调整距离,空物体则只平移到其位置。 + """ + target_node = node or self.focus_target_node + if target_node is None: + return + if hasattr(target_node, "is_empty") and target_node.is_empty(): + return + + center, target_distance, has_bounds = self._compute_focus_goal(target_node, padding) + if not has_bounds: + # 空物体或无包围盒:仅移动到位置,距离保持当前的一个合理值 + target_distance = max(self.distance, 3.0) + if abs(p3d.LPoint3f(center-self.cam.get_pos()).length() - target_distance) < 0.1: + target_distance = max(target_distance / 3.0 , 1.0) + + self._start_focus_lerp(center, target_distance, duration) + + def _compute_focus_goal(self, node: NodePath, padding: float) -> tuple[LPoint3, float, bool]: + """返回聚焦中心、距离以及是否使用了有效包围盒。""" + try: + bounds = node.get_tight_bounds(self.render) if hasattr(node, "get_tight_bounds") else node.getTightBounds(self.render) + except Exception: + bounds = None + + if bounds and len(bounds) >= 2 and bounds[0] is not None and bounds[1] is not None: + bmin, bmax = bounds + extent = bmax - bmin + if extent.length_squared() > 1e-6: + center = (bmin + bmax) * 0.5 + radius = extent.length() * 0.5 * padding + lens = self.base.cam.node().getLens() if self.cam else None + if lens: + fov = lens.getFov() + half_fov_x = max(1e-3, math.radians(float(fov[0])) * 0.5) + half_fov_y = max(1e-3, math.radians(float(fov[1])) * 0.5) + dist_x = radius / math.tan(half_fov_x) + dist_y = radius / math.tan(half_fov_y) + distance = max(dist_x, dist_y) + near = getattr(lens, "getNear", lambda: 0.0)() + distance = max(distance, near + radius * 0.5) + else: + distance = radius / math.tan(math.radians(30)) + return center, max(distance, 0.5), True + + # 无有效包围盒:使用节点位置作为聚焦中心 + try: + center = node.get_pos(self.render) + except Exception: + center = self.cam_target + return center, max(self.distance, 0.5), False + + def _start_focus_lerp(self, target_center: LPoint3, target_distance: float, duration: float): + """平滑插值到新的目标与距离。""" + if self._focus_task: + self.base.taskMgr.remove(self._focus_task) + self._focus_task = None + + start_target = LPoint3(self.cam_target) + start_distance = float(self.distance) + duration = max(0.01, duration) + + def _lerp(task): + t = min(task.time / duration, 1.0) + # smoothstep + t = t * t * (3 - 2 * t) + self.cam_target = start_target * (1.0 - t) + target_center * t + self.distance = start_distance + (target_distance - start_distance) * t + self._update_camera() + if t >= 1.0: + self._focus_task = None + return task.done + return task.cont + + self._focus_task = self.base.taskMgr.add(_lerp, "camera-focus-lerp") diff --git a/tools/picker_ray.py b/tools/picker_ray.py new file mode 100644 index 0000000..da267d2 --- /dev/null +++ b/tools/picker_ray.py @@ -0,0 +1,77 @@ +from direct.showbase.ShowBase import ShowBase +from panda3d.core import CollisionTraverser, CollisionNode, CollisionHandlerQueue, GeomNode, CollisionRay, NodePath, LPoint3f, LVector3f + + +class PickerRay(): + def __init__(self, root: ShowBase, pick_root: NodePath = None): + super().__init__() + self.root: ShowBase = root + self.pick_root = pick_root or root.render + self.debug = False + + def __setup_picker(self): + # 创建一个拾取器 + self.picker = CollisionTraverser() + self.pq = CollisionHandlerQueue() + + # 创建一个拾取节点 + self.picker_node = CollisionNode('mouseRay') + self.picker_np = self.root.cam.attachNewNode(self.picker_node) + self.picker_node.setFromCollideMask(GeomNode.getDefaultCollideMask()) + + # 创建射线 + self.picker_ray = CollisionRay() + self.picker_node.addSolid(self.picker_ray) + + # 将拾取器和处理器关联 + self.picker.addCollider(self.picker_np, self.pq) + + # 可选:显示拾取射线(调试用) + # self.picker_np.show() + + def debug_log(self, msg: str) -> None: + if self.debug: + print(f"[ScaleGizmo] -> {msg}") + + def pick_object(self) -> tuple[NodePath | None, LVector3f | None]: + """根据屏幕坐标拾取3D物体""" + if not hasattr(self, 'picker'): + self.__setup_picker() + + mpos = self.root.mouseWatcherNode.getMouse() + screen_x = mpos.x + screen_y = mpos.y + self.debug_log(f"屏幕坐标: {screen_x}, {screen_y}") + + # 从摄像机发射射线 + self.picker_ray.setFromLens(self.root.camNode, screen_x, screen_y) + + # 执行碰撞检测 + self.picker.traverse(self.pick_root) + + picked_object = None + collision_point = LPoint3f(0, 0, 0) + + # 检查是否有碰撞 + if self.pq.getNumEntries() > 0: + # 按距离排序,最近的在前面 + self.pq.sortEntries() + + for i in range(self.pq.getNumEntries()): + # 获取最近的碰撞点 + closest_entry = self.pq.getEntry(i) + picked_object: NodePath = closest_entry.getIntoNodePath() + + if picked_object.isHidden(): + continue + else: + # 获取碰撞点的世界坐标 + collision_point = closest_entry.getSurfacePoint(self.root.render) + + self.debug_log(f"拾取到物体: {picked_object.getName()}") + self.debug_log(f"碰撞点: {collision_point}") + break + return picked_object, collision_point + + self.debug_log("未拾取到任何物体") + return None, None \ No newline at end of file