 |
|
|
04-12-2019, 05:32 AM
|
#161
|
Human being with feelings
Join Date: May 2017
Location: Leipzig
Posts: 6,129
|
Quote:
Originally Posted by woodslanding
As far as I can tell....
When I call:
ultraschall.GetTrackAUXSendReceives(track,index)
Index is 1 based. Track is 1 based. But the track returned is 0 based!
(I finally got smart and put empty tracks between all my tracks (for testing) so if I get a 1-based return it will be even, and a 0-based return will be odd)
|
I'll have a look at it.
Do the HWOut and MasterSend-functions have the samw problem?
Last edited by Meo-Ada Mespotine; 04-12-2019 at 05:53 AM.
|
|
|
04-12-2019, 05:33 AM
|
#162
|
Human being with feelings
Join Date: May 2017
Location: Leipzig
Posts: 6,129
|
Quote:
Originally Posted by X-Raym
@mespotine
https://github.com/Ultraschall/ultra...per_Script.lua
If I understand correctly, the trick is to not use the returned value of native GetUserInput, but to use JS_extension to find what were in the fields ?
Not matter how you solve this, this is brilliant !
|
I'll try the same with MessageBox soon 😁
|
|
|
04-12-2019, 05:40 AM
|
#163
|
Human being with feelings
Join Date: Apr 2013
Location: France
Posts: 9,238
|
@mespotine
I've look under the hood all all functions called by a simple ultrashall user input, and I have to say you have taken a lot of things into account (sanitization etc)...
Well done!
|
|
|
04-12-2019, 05:47 AM
|
#164
|
Human being with feelings
Join Date: May 2017
Location: Leipzig
Posts: 6,129
|
Thanks
It's simple:the better I do that kind of stuff, the fewer the bugreports are
That'll be also the reason, why my next renderfunctions-update will be hellagood to work with
|
|
|
04-16-2019, 09:12 AM
|
#165
|
Human being with feelings
Join Date: May 2017
Location: Leipzig
Posts: 6,129
|
As you all love my teasers, I'll post tomorrow or the day after a first teaser for my RENDER MANIA-update
|
|
|
04-17-2019, 09:32 AM
|
#166
|
Human being with feelings
Join Date: May 2017
Location: Leipzig
Posts: 6,129
|
Teaser 1 for my Render Mania-Update:
You can read and write ALL render-cfg strings.
These are strings, that store the render-output-format settings(the box that changes, when you select MP3, FLAC, OGG, etc) in RPP-projectfiles, render-presets(reper-render.ini) or inside of Reaper itself.
See https://forum.cockos.com/showthread.php?t=219551 on why these functions will be very very helpful in the future
(All in all it's 30 functions I wrote over the last few days to do that.)
|
|
|
04-17-2019, 09:40 AM
|
#167
|
Human being with feelings
Join Date: Aug 2011
Posts: 479
|
Nice!
|
|
|
04-18-2019, 02:54 AM
|
#168
|
Human being with feelings
Join Date: May 2017
Location: Leipzig
Posts: 6,129
|
@TonE
Ok, I started to code some functions for getting parameter-learning for FX.
But I need some more help from you. Could you do some LiceCaps or screenshots of stuff that you are clicking, when working with the whole stuff?
That way I could reproduce what Reaper changes in the background to what you need access.
The first batch of functions will only be basic get/set-access to the stuff, so no convenience-functions atm. But it should help you a little further.
BTW: Would parameter-aliases also be helpful for you?
|
|
|
04-24-2019, 08:31 PM
|
#169
|
Human being with feelings
Join Date: Jun 2009
Location: Earth
Posts: 1,340
|
ProjectState scripts needed
I am looking for a couple of scripts that can manipulate plugin parameter links of the current opened project.
Here is an example of the chunk I'd like to edit. There is actually 16 linkings, I've just posted 2 for this example.
FXID {755FF102-C465-4B31-A5E0-F49599B50BE6}
<PROGRAMENV 945 0
PARAMBASE 0
LFO 0
LFOWT 1 1
AUDIOCTL 0
AUDIOCTLWT 1 1
PLINK 1 1:1 2 0
MODWND 0 1382 297 1730 575
>
<PROGRAMENV 985 0
PARAMBASE 0
LFO 0
LFOWT 1 1
AUDIOCTL 0
AUDIOCTLWT 1 1
PLINK 1 1:1 3 0
MODWND 0 1298 439 1646 618
--------------------------------------------------------------------------
The first script should be able to edit all mappings at once.
It needs to change the lines
"PROGRAMENV 945 0" and "PROGRAMENV 985 0" into
"PROGRAMENV 946 0" and "PROGRAMENV 986 0"
The second script would be similar except instead of changing all 16 linkings it would just change specific ones such as 1,4,8 or whatever.
Any help would be awesome.., thanks
|
|
|
04-25-2019, 07:31 AM
|
#170
|
Human being with feelings
Join Date: May 2017
Location: Leipzig
Posts: 6,129
|
@Anton9
Can't code such scripts right now, but I'm into adding plugin-parameter-functions currently.
Should be doable, but needs some research on my side first
|
|
|
04-25-2019, 07:32 AM
|
#171
|
Human being with feelings
Join Date: May 2017
Location: Leipzig
Posts: 6,129
|
RENDER-MANIA-update!
Let's tease again:
RenderTables, who contain all settings of the Render to File-dialog in a nice handy table.
You'll be able to get and apply them from/to the current project AND projectfiles!
Like in this gif:
Render-Queue and Render-presets are next
Last edited by Meo-Ada Mespotine; 04-25-2019 at 07:43 AM.
|
|
|
04-25-2019, 09:37 PM
|
#172
|
Human being with feelings
Join Date: Jun 2009
Location: Earth
Posts: 1,340
|
Quote:
Originally Posted by mespotine
@Anton9
Can't code such scripts right now, but I'm into adding plugin-parameter-functions currently.
Should be doable, but needs some research on my side first 
|
No problem. By the way, great job on your API extension!
I noticed you had done an extensive amount of work on documenting REAPER's data stucture, including ProjectChunks so that's why I posted here. I have'nt been able to wrap my head around working with chunks yet.
I did'nt notice any info on FX param links in your docs.., so here is a little info encase you may want to add it to the docs.
-----------------
"PARAMBASE 0" not sure what this is.
"PROGRAMENV 946 0"
First param "946" is the "Slave" param. id ---NOTE: see PLINK below for more info.
Second param "0" not sure?
-----------------
"LFOWT 1 1" are "Strength" and "Direction" params of LFO, if active.
value of 1 1 is "Positive"
value of 1 0 is "Centered"
value of 1 -1 is "Negative"
When "Strength" is not at default pos. of 100% the chunk will show a float such as 0.500 1
When LFO is active three additional lines appear in the chunk after PLINK.., they are.
----------------
LFOSHAPE 0
LFOSYNC 0 0 0
LFOSPEED 0.124573 0
----------------
"LFOSHAPE" values.
0 = sine
1 = square
2 = saw L
3 = saw R
4 = triangle
5 = random
----------------
"LFOSYNC 0 0 0" means "Tempo sync" is not ticked and "Phase reset" is set to "On seek/loop (deterministic output)"
value of 0 0 1 "Phase reset" is set to "Free-running (non-deterministic output)"
value of 1 0 0 "Tempo sync" is ticked
value of 1 0 1 "Tempo sync" is ticked and "Phase reset" is "Free-running (non-deterministic output)"
not sure what the middle "0" is for?
----------------
"LFOSPEED" is a little weird.., the slider range is 0.0039 to 8.0000 however you can actually type in values out side this range into the value field.
A chunk reading of "0 0" means that the slider is at min. position, the "Hz" box will read 0.0039 Hz
value of "0 1" means that it's at max position and "Hz" value will be 8.00
A float is used when "Hz" value is between 0.0040 and 7.9 the value will look like this "0.000012 0" and "0.987494 0" in the chunk.
However if you type in a value of 0.0039 the chunk will show a neg. value such as LFOSPEED -0.000013 0
----------------
"AUDIOCTL 0" means "Audio control signal (sidechain)" is not ticked
When ticked it will have a value of 1 and these additional lines will appear in the chunk.
CHAN 1
STEREO 0
RMS 300 300
DBLO -24
DBHI 0
X2 0.5
Y2 0.5
---------------
"PLINK 1 1:1 3 0 "
not sure what the first param "1" is for.
Second param "1:1" is the relationship of the Master vs Slave param. and it's position within the FX chain.
Example: if there is a param link between 2 params within the same plugin the value will be "0:0"
If a param in one plugin is being controlled by a param of another plugin meaning Master is on top of chain and Slave is second then the
value will be something like "0:-1"
Slave at top of chain and Master second will be "1:1"
Third param "3" this is the Master FX param id.
Fourth param "0" is the "Offset"., values other than 0 or 100% will show a pos. or neg. float in the chunk.
-------------
"MODWND 0 194 379 542 845"
First param. is "0" for dialog not visible "1" dialog is visible.
The other four params are of course the position of the "Parameter Modulation" dialog.
Cheers!
Last edited by Anton9; 04-25-2019 at 09:58 PM.
|
|
|
04-26-2019, 06:30 AM
|
#173
|
Human being with feelings
Join Date: May 2017
Location: Leipzig
Posts: 6,129
|
Ooohh nice, this will make things faster to do 
Thanks
I'm also working on a full updated StateChunk-doc for all StateChunks, but it is still very preliminary and needs my full attention for some weeks (for compiling, layouting and corrections and stuff), which I don't have at the moment
|
|
|
04-29-2019, 06:48 AM
|
#174
|
Human being with feelings
Join Date: May 2017
Location: Leipzig
Posts: 6,129
|
a Hotfix for the current release is available, with the following bugfixes. Please update from ReaPack for them.
Hotfix I
Changes:
- GFX: GFX_GetMouseCap - interpreted modifier-keys as mouseclicks, when gfx.getkey had been used in script; mousewheel sometimes kept stuck at one value-> fixed
- Helpers: Base64_Encoder - fixed bug that caused encoded strings to end with wrong letter
- Helpers: GetReaperAppVersion - didn't return subversionnumber for pre-releases -> fixed now; returns pre-release-versions as well now
- Projectmanagement: GetProject_NumberOfTracks - sped code up by magnitudes for huge projects; parameter ProjectStateChunk wasn't working due stupid typo -> fixed now
- Projectmanagement: GetProject_RenderFilename - could produce Lua-error, when no Renderfilename was existing in the projectfile
- Routing: GetTrackAUXSendReceives - recv_tracknumber is now 1-based, as it should be(thanks to woodslanding)
- Routing: SetTrackAUXSendReceives - recv_tracknumber is now 1-based, as it should be(thanks to woodslanding)
- Routing: AddTrackAUXSendReceives - had parameters tracknumber and recv_tracknumber accidentally reversed, when not working with StateChunks .. oops -> fixed (thanks to woodslanding)
@woodslanding
The zero-based tracknumbers for the Send/Receive-functions were a bug on my side, so you may want to have this update for your scripts.
|
|
|
04-30-2019, 07:18 AM
|
#175
|
Human being with feelings
Join Date: May 2017
Location: Leipzig
Posts: 6,129
|
Teaser for the RenderMania update:
I needed GetProjectStateChunk, so I wrote GetProjectStateChunk.
And to demonstrate it, I took X-Raym's request and wrote a GetGroup-Name-function for ProjectStateChunks.
Bleeding Edge, as Bleeding Edge can be
|
|
|
04-30-2019, 07:24 AM
|
#176
|
Human being with feelings
Join Date: Apr 2013
Location: France
Posts: 9,238
|
@mespotine
Interesting !
But we all know the hardest part is the SET function
Does it works with unsaved project/modifications ?
Do you think this code is easily portable to C++ ? Cause bringing that to SWS API will make it accessible to Python and other script language which can be handy too !
|
|
|
04-30-2019, 07:26 AM
|
#177
|
Human being with feelings
Join Date: Oct 2007
Location: home is where the heart is
Posts: 11,824
|
Quote:
Originally Posted by X-Raym
Does it works with unsaved project/modifications ?
|
That was my thought too, i.e. are you reading from the .rpp file or some other way?
|
|
|
04-30-2019, 07:31 AM
|
#178
|
Human being with feelings
Join Date: May 2017
Location: Leipzig
Posts: 6,129
|
Yes it does. As I'm exploiting the Render-queue for that(with a lot of magix here and there), which returns a most update ProjectStateChunk.
This should be doable in C++ as well. Give me some time to give it a intensive tests, so I know, what else would be necessary.
For setting them...I have ... well...ideas
|
|
|
04-30-2019, 07:42 AM
|
#179
|
Human being with feelings
Join Date: Oct 2007
Location: home is where the heart is
Posts: 11,824
|
Nice approach, thumbs up.
|
|
|
04-30-2019, 07:47 AM
|
#180
|
Human being with feelings
Join Date: May 2017
Location: Leipzig
Posts: 6,129
|
Quote:
Originally Posted by mespotine
For setting them...I have ... well...ideas 
|
I may ask some stupid questions in the How do I-thread in the near future for that...
@nofish
Thanks
|
|
|
05-01-2019, 02:27 AM
|
#181
|
Human being with feelings
Join Date: Feb 2017
Posts: 305
|
Oh, cool cool 
Could we propagate items only inside same groups?
And have scripts 'Name/show name items group' would be lovely as well 
Thank you much for your work guys!
|
|
|
05-02-2019, 08:54 AM
|
#182
|
Human being with feelings
Join Date: May 2017
Location: Leipzig
Posts: 6,129
|
TeaseTease
Ok, back to rendering. I couldn't find a nice way to make a licecap-gif to show the stuff I've worked on the last two days, so I simply highlighted them in an overview of all render-functions I've added to the API so far.
Render Queue next.
Last edited by Meo-Ada Mespotine; 05-02-2019 at 09:26 AM.
|
|
|
05-02-2019, 08:56 AM
|
#183
|
Human being with feelings
Join Date: May 2017
Location: Leipzig
Posts: 6,129
|
Quote:
Originally Posted by Ivannn Bennnettt
Oh, cool cool 
Could we propagate items only inside same groups?
And have scripts 'Name/show name items group' would be lovely as well 
Thank you much for your work guys!
|
Yes, but: my implementation of getting this information is quite slow(limits in the API), so you can't do them in an effective way.
So if you need to get them once in a while, no problem. But deferred scripts trying to get them constantly will kill your computer.
|
|
|
05-02-2019, 10:35 AM
|
#184
|
Human being with feelings
Join Date: Apr 2013
Location: France
Posts: 9,238
|
Code:
ultraschall.InsertMediaItem_MediaItem(
Just simple feedback, This function is cool, I used it in various scripts today. :P
I also had Copy items function but for quick scripting, it is easier to use this API than to search my code snippet and use item selection for the copy etc...
Though I have the feeling it could be slighly optimized in performance, I suspect it's because of this API size.
Is there a way to load only desired functions (or at least pack of functions) rather than the whole thing ?
|
|
|
05-02-2019, 10:41 AM
|
#185
|
Human being with feelings
Join Date: May 2017
Location: Leipzig
Posts: 6,129
|
Quote:
Originally Posted by X-Raym
Code:
ultraschall.InsertMediaItem_MediaItem(
Just simple feedback, This function is cool, I used it in various scripts today. :P
I also had Copy items function but for quick scripting, it is easier to use this API than to search my code snippet and use item selection for the copy etc...
Though I have the feeling it could be slighly optimized in performance, I suspect it's because of this API size.
Is there a way to load only desired functions (or at least pack of functions) rather than the whole thing ?
|
I'm thinking about doing that. The biggest problem is, that there are dependencies between many functions, which is a major issue.
My current idea is to make the API somehow more modular, so you could do stuff like
include={"basics", "RenderManagement", "MediaItemmanagement}
before the dofile-line, and it will only load the stuff needed. But this is complicated.
Another try would be to compile the functions as chunk once, when they are started used the first time and just load that chunk after that(from an extstate or so), which should(tm) be faster.
Haven't tried anything of that yet, though. So for now, the API is good for scripts run once in a while and deferred-scripts.
For repeatedly called scripts, it's too laggy.
I've improved starting-performance though for the next release, so lag should be shorter.
Edit: And thanks for your feedback. Once you've started using the API, you'll grow into it quickly. Most of my reverse-engineering stuff is only possible with that
Last edited by Meo-Ada Mespotine; 05-02-2019 at 10:48 AM.
|
|
|
05-02-2019, 03:47 PM
|
#186
|
Human being with feelings
Join Date: Apr 2013
Location: France
Posts: 9,238
|
Quote:
For repeatedly called scripts, it's too laggy.
|
Well its ok but it could be better :P
Ill probably implement my own copy function if needed. Due to how the native IDE work, i like to have all my script functions in the script file without dependency.
But sometimes I just need to make a quick script :P
Anyway, good luck for brainstorming ultrashall modules concept... this propise to be challenging ^^
|
|
|
05-04-2019, 03:11 AM
|
#187
|
Human being with feelings
Join Date: Feb 2009
Location: Reaper HAS send control via midi !!!
Posts: 3,895
|
Quote:
Originally Posted by mespotine
@TonE
Ok, I started to code some functions for getting parameter-learning for FX.
But I need some more help from you. Could you do some LiceCaps or screenshots of stuff that you are clicking, when working with the whole stuff?
That way I could reproduce what Reaper changes in the background to what you need access.
The first batch of functions will only be basic get/set-access to the stuff, so no convenience-functions atm. But it should help you a little further.
BTW: Would parameter-aliases also be helpful for you?
|
Installed 2.74, current latest, it seems there is nothing I can test so far? rgrep'ed for Parm, Learn, no matches so far. Thought the ParmLearn-Get was already implemented, wanted to test this quickly.
Yes, parameter aliases could be useful as well, in case we want to give some other names, because of any reasons.
|
|
|
05-05-2019, 12:44 PM
|
#188
|
Human being with feelings
Join Date: May 2017
Location: Leipzig
Posts: 6,129
|
@TonE
Yes, it's still in the works. 2.75 will have get-functions for them and when I'm done with the new render functions, there will be a public-beta test for 2.75.
Still one or two bugs to solve for parmlearn.
Ok, will add aliases as well.
|
|
|
05-05-2019, 01:09 PM
|
#190
|
Human being with feelings
Join Date: May 2017
Location: Leipzig
Posts: 6,129
|
Was that rpp-files only or could you alter loaded projects as well?
|
|
|
05-05-2019, 01:23 PM
|
#191
|
Human being with feelings
Join Date: Feb 2009
Location: Reaper HAS send control via midi !!!
Posts: 3,895
|
This is just text file processing, so tested with non-loaded myself, if Reaper does not lock the .rpp it should work probably with loaded files, but did not test myself. Something like this might work, load .rpp, go offline, process file (via .ahk for example), go online again. At least offline does release external midi files, this trick I was using for them, meaning for external processing of loaded .mid files.
|
|
|
05-10-2019, 06:22 AM
|
#193
|
Human being with feelings
Join Date: May 2017
Location: Leipzig
Posts: 6,129
|
Let's tease some other stuff I worked on, mostly getting FX-parameter-modulation/learn stuff and how to exchange the button-texts in reaper.ShowMessageBox with your own texts(using ultraschall.MB)
Function ultraschall.MB allows now setting the button-texts:
Get ParameterLearn-values:
Get Parameter Modulation for AudioControl, LFO and MIDI/Parameter-Link:
Currently finishing up the actual rendering-functions and Render-Queue-management. So I hope, I can open a public beta next week on that.
|
|
|
05-12-2019, 05:19 AM
|
#194
|
Human being with feelings
Join Date: Feb 2009
Location: Reaper HAS send control via midi !!!
Posts: 3,895
|
Looks fantastic, thanks for all your efforts. When the set functions will be available, I am not sure if Reaper needs anything more.  Finally we could define the entire project, to our wishes, in one go, after having written that magical script. That script could use normal .csv files as import and export, and there you go. Columns could be something like:
PHP Code:
track, fx, parameter, midi channel, note/cc, pitch/value
Add as many lines/mappings as you want. You could write your setup in Excel, then import into that magical script, which would do the mapping. Those setups could easily be exchanged in this forum. Together with .rpp, in optimum case. I would write a setup for Reason mode as input device, which is supported by the hardware Bitstream 3X directly, for example, switch it on, change to Reason mode, and you could immediately control, whatever was mapped. Same could be defined for any other mapping "standard" or specification.
Last edited by TonE; 05-12-2019 at 05:26 AM.
|
|
|
05-14-2019, 09:16 PM
|
#195
|
Human being with feelings
Join Date: Mar 2007
Location: Denver, CO
Posts: 633
|
Quote:
@woodslanding
The zero-based tracknumbers for the Send/Receive-functions were a bug on my side, so you may want to have this update for your scripts.
|
Yeah, I just took them out,
(The process of figuring out your bug gave me the understanding to write my own methods  ) but I'll remember that they have been fixed in future, thanks!
|
|
|
05-15-2019, 09:35 AM
|
#196
|
Human being with feelings
Join Date: May 2017
Location: Leipzig
Posts: 6,129
|
Thanks to you for reporting that issue. That kind of feedback helps me to make this as good as possible.
There's just so much one alone can keep on track
@all
Rendering-functions finished. Documentation and cleanup time.
|
|
|
05-20-2019, 09:06 AM
|
#197
|
Human being with feelings
Join Date: May 2017
Location: Leipzig
Posts: 6,129
|
For whom it may concern: there is a pre-release available of the UltraschallAPI 4.00 beta 2.75, featuring all render-functions and the get-parmlearn/modulation-functions.
I need some people, who could test this stuff, so I know, I got it right( or know, I need to fix some bugs before release.
https://forum.cockos.com/showthread....39#post2137139
|
|
|
05-21-2019, 10:25 AM
|
#198
|
Human being with feelings
Join Date: Mar 2007
Location: Denver, CO
Posts: 633
|
I have found a nice Lua script for doing color conversions to a user-friendly variant of HCL called HSLuv. It seems to be working really well for me. Thought you might want to add it to your library. If not, a search for HCL or HSV or HSL will turn up this post
Code:
--[[
Copyright (C) 2016 Alexei Boronine
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
]]--
hsluv = {}
hexChars = "0123456789abcdef"
distance_line_from_origin = function(line)
return math.abs(line.intercept) / math.sqrt((line.slope ^ 2) + 1)
end
length_of_ray_until_intersect = function(theta, line)
return line.intercept / (math.sin(theta) - line.slope * math.cos(theta))
end
hsluv.get_bounds = function(l)
local result = {};
local sub2;
local sub1 = ((l + 16) ^ 3) / 1560896;
if sub1 > hsluv.epsilon then
sub2 = sub1;
else
sub2 = l / hsluv.kappa;
end
for i = 1, 3 do
local m1 = hsluv.m[i][1];
local m2 = hsluv.m[i][2];
local m3 = hsluv.m[i][3];
for t = 0, 1 do
local top1 = (284517 * m1 - 94839 * m3) * sub2;
local top2 = (838422 * m3 + 769860 * m2 + 731718 * m1) * l * sub2 - 769860 * t * l;
local bottom = (632260 * m3 - 126452 * m2) * sub2 + 126452 * t;
table.insert(result, {
slope = top1 / bottom,
intercept = top2 / bottom
})
end;
end;
return result
end
hsluv.max_safe_chroma_for_l = function(l)
local bounds = hsluv.get_bounds(l);
local min = 1.7976931348623157e+308;
for i = 1, 6 do
local length = distance_line_from_origin(bounds[i]);
if length >= 0 then
min = math.min(min, length);
end;
end;
return min;
end
hsluv.max_safe_chroma_for_lh = function(l, h)
local hrad = h / 360 * math.pi * 2;
local bounds = hsluv.get_bounds(l);
local min = 1.7976931348623157e+308;
for i = 1, 6 do
local bound = bounds[i];
local length = length_of_ray_until_intersect(hrad, bound);
if length >= 0 then
min = math.min(min, length);
end;
end;
return min
end
hsluv.dot_product = function(a, b)
local sum = 0;
for i = 1, 3 do
sum = sum + a[i] * b[i];
end;
return sum
end
hsluv.from_linear = function(c)
if c <= 0.0031308 then
return 12.92 * c
else
return 1.055 * (c ^ 0.416666666666666685) - 0.055
end;
end
hsluv.to_linear = function(c)
if c > 0.04045 then
return ((c + 0.055) / 1.055) ^ 2.4
else
return c / 12.92
end;
end
hsluv.xyz_to_rgb = function(tuple)
return {
hsluv.from_linear(hsluv.dot_product(hsluv.m[1], tuple)),
hsluv.from_linear(hsluv.dot_product(hsluv.m[2], tuple)),
hsluv.from_linear(hsluv.dot_product(hsluv.m[3], tuple))
}
end
hsluv.rgb_to_xyz = function(tuple)
local rgbl = {
hsluv.to_linear(tuple[1]),
hsluv.to_linear(tuple[2]),
hsluv.to_linear(tuple[3])
};
return {
hsluv.dot_product(hsluv.minv[1], rgbl),
hsluv.dot_product(hsluv.minv[2], rgbl),
hsluv.dot_product(hsluv.minv[3], rgbl)
}
end
hsluv.y_to_l = function(Y)
if Y <= hsluv.epsilon then
return Y / hsluv.refY * hsluv.kappa
else
return 116 * ((Y / hsluv.refY) ^ 0.333333333333333315) - 16
end;
end
hsluv.l_to_y = function(L)
if L <= 8 then
return hsluv.refY * L / hsluv.kappa
else
return hsluv.refY * (((L + 16) / 116) ^ 3)
end;
end
hsluv.xyz_to_luv = function(tuple)
local X = tuple[1];
local Y = tuple[2];
local divider = X + 15 * Y + 3 * tuple[3];
local varU = 4 * X;
local varV = 9 * Y;
if divider ~= 0 then
varU = varU / divider;
varV = varV / divider;
else
varU = 0;
varV = 0;
end
local L = hsluv.y_to_l(Y);
if L == 0 then
return { 0, 0, 0 }
end;
return { L, 13 * L * (varU - hsluv.refU), 13 * L * (varV - hsluv.refV) }
end
hsluv.luv_to_xyz = function(tuple)
local L = tuple[1];
local U = tuple[2];
local V = tuple[3];
if L == 0 then
return { 0, 0, 0 }
end;
local varU = U / (13 * L) + hsluv.refU;
local varV = V / (13 * L) + hsluv.refV;
local Y = hsluv.l_to_y(L);
local X = 0 - (9 * Y * varU) / ((((varU - 4) * varV) - varU * varV));
return { X, Y, (9 * Y - 15 * varV * Y - varV * X) / (3 * varV) }
end
hsluv.luv_to_lch = function(tuple)
local L = tuple[1];
local U = tuple[2];
local V = tuple[3];
local C = math.sqrt(U * U + V * V);
local H
if C < 0.00000001 then
H = 0;
else
H = math.atan2(V, U) * 180.0 / 3.1415926535897932;
if H < 0 then
H = 360 + H;
end;
end;
return { L, C, H }
end
hsluv.lch_to_luv = function(tuple)
local L = tuple[1];
local C = tuple[2];
local Hrad = tuple[3] / 360.0 * 2 * math.pi;
return { L, math.cos(Hrad) * C, math.sin(Hrad) * C };
end
hsluv.hsluv_to_lch = function(tuple)
local H = tuple[1];
local S = tuple[2];
local L = tuple[3];
if L > 99.9999999 then
return { 100, 0, H }
end;
if L < 0.00000001 then
return { 0, 0, H }
end;
return { L, hsluv.max_safe_chroma_for_lh(L, H) / 100 * S, H }
end
hsluv.lch_to_hsluv = function(tuple)
local L = tuple[1];
local C = tuple[2];
local H = tuple[3];
local max_chroma = hsluv.max_safe_chroma_for_lh(L, H)
if L > 99.9999999 then
return { H, 0, 100 }
end;
if L < 0.00000001 then
return { H, 0, 0 }
end;
return { H, C / max_chroma * 100, L }
end
hsluv.hpluv_to_lch = function(tuple)
local H = tuple[1];
local S = tuple[2];
local L = tuple[3];
if L > 99.9999999 then
return { 100, 0, H }
end;
if L < 0.00000001 then
return { 0, 0, H }
end;
return { L, hsluv.max_safe_chroma_for_l(L) / 100 * S, H }
end
hsluv.lch_to_hpluv = function(tuple)
local L = tuple[1];
local C = tuple[2];
local H = tuple[3];
if L > 99.9999999 then
return { H, 0, 100 }
end;
if L < 0.00000001 then
return { H, 0, 0 }
end;
return { H, C / hsluv.max_safe_chroma_for_l(L) * 100, L }
end
hsluv.rgb_to_hex = function(tuple)
local h = "#";
for i = 1, 3 do
local c = math.floor(tuple[i] * 255 + 0.5);
local digit2 = math.fmod(c, 16);
local x = (c - digit2) / 16;
local digit1 = math.floor(x);
h = h .. string.sub(hexChars, digit1 + 1, digit1 + 1)
h = h .. string.sub(hexChars, digit2 + 1, digit2 + 1)
end;
return h
end
hsluv.hex_to_rgb = function(hex)
hex = string.lower(hex)
local ret = {}
for i = 0, 2 do
local char1 = string.sub(hex, i * 2 + 2, i * 2 + 2);
local char2 = string.sub(hex, i * 2 + 3, i * 2 + 3);
local digit1 = string.find(hexChars, char1) - 1
local digit2 = string.find(hexChars, char2) - 1
ret[i + 1] = (digit1 * 16 + digit2) / 255.0;
end;
return ret
end
hsluv.lch_to_rgb = function(tuple)
return hsluv.xyz_to_rgb(hsluv.luv_to_xyz(hsluv.lch_to_luv(tuple)))
end
hsluv.rgb_to_lch = function(tuple)
return hsluv.luv_to_lch(hsluv.xyz_to_luv(hsluv.rgb_to_xyz(tuple)))
end
hsluv.hsluv_to_rgb = function(tuple)
return hsluv.lch_to_rgb(hsluv.hsluv_to_lch(tuple))
end
hsluv.rgb_to_hsluv = function(tuple)
return hsluv.lch_to_hsluv(hsluv.rgb_to_lch(tuple))
end
hsluv.hpluv_to_rgb = function(tuple)
return hsluv.lch_to_rgb(hsluv.hpluv_to_lch(tuple))
end
hsluv.rgb_to_hpluv = function(tuple)
return hsluv.lch_to_hpluv(hsluv.rgb_to_lch(tuple))
end
hsluv.hsluv_to_hex = function(tuple)
return hsluv.rgb_to_hex(hsluv.hsluv_to_rgb(tuple))
end
hsluv.hpluv_to_hex = function(tuple)
return hsluv.rgb_to_hex(hsluv.hpluv_to_rgb(tuple))
end
hsluv.hex_to_hsluv = function(s)
return hsluv.rgb_to_hsluv(hsluv.hex_to_rgb(s))
end
hsluv.hex_to_hpluv = function(s)
return hsluv.rgb_to_hpluv(hsluv.hex_to_rgb(s))
end
hsluv.m = {
{ 3.240969941904521, -1.537383177570093, -0.498610760293 },
{ -0.96924363628087, 1.87596750150772, 0.041555057407175 },
{ 0.055630079696993, -0.20397695888897, 1.056971514242878 }
}
hsluv.minv = {
{ 0.41239079926595, 0.35758433938387, 0.18048078840183 },
{ 0.21263900587151, 0.71516867876775, 0.072192315360733 },
{ 0.019330818715591, 0.11919477979462, 0.95053215224966 }
}
hsluv.refY = 1.0
hsluv.refU = 0.19783000664283
hsluv.refV = 0.46831999493879
hsluv.kappa = 903.2962962
hsluv.epsilon = 0.0088564516
return hsluv
|
|
|
05-21-2019, 10:26 AM
|
#199
|
Human being with feelings
Join Date: Mar 2007
Location: Denver, CO
Posts: 633
|
and here's the method I use to call it... H is 0-360,L & S are 0-100 and RGB are 0-1
more at http://www.hsluv.org/
Code:
function getRGB(hue,sat,level)
color = {}
color[1] = hue
color[2] = sat
color[3] = level
rgb = hsluv.hpluv_to_rgb(color)
return rgb
end
|
|
|
05-21-2019, 10:31 AM
|
#200
|
Human being with feelings
Join Date: May 2017
Location: Leipzig
Posts: 6,129
|
Nice. Will look into it for the next dev-cycle
|
|
|
Thread Tools |
|
Display Modes |
Linear Mode
|
Posting Rules
|
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts
HTML code is Off
|
|
|
All times are GMT -7. The time now is 09:51 PM.
|