local pow = math.pow local lerp = math.lerp local min = math.min local max = math.max local i local ii local n_LUTS = 0 LUT = {} function LUT:new(data, colors, sunbased) local o = {} setmetatable(o, self) self.__index = self o.data = data o.color_positions = colors or {} o.curve = 1 o.sun_based = sunbased or false o.buffer = {} o.RGBBuffer = {} o.cppLUT = nil o:generate() n_LUTS = n_LUTS + 1 return o end function LUT:setColorPositions(colors) self.color_positions = colors or {} end function LUT:setCurve(curve) self.curve = curve or 1 end function LUT:setSunbased(b) self.sun_based = b end function LUT:convertOldSunAngles() if self.data then if self.data[1][1] and self.data[#self.data][1] then if self.data[1][1] == -180 and self.data[#self.data][1] == 0 then for i=1, #self.data do if self.data[i][1] then self.data[i][1] = self.data[i][1] + 90 end end end end end end local _l_rgb = rgb(0,0,0) function LUT:convertHSVtoRGB() if self.data and self.color_positions and #self.color_positions>0 then for i=1, #self.data do for ii=1, #self.color_positions do HSVToRGB_To(_l_rgb, self.data[i][self.color_positions[ii] + 1], self.data[i][self.color_positions[ii] + 2], self.data[i][self.color_positions[ii] + 3]) self.data[i][self.color_positions[ii] + 1] = _l_rgb.r self.data[i][self.color_positions[ii] + 2] = _l_rgb.g self.data[i][self.color_positions[ii] + 3] = _l_rgb.b end end end end function LUT:convertRGBtoHSV_Buffer() if self.buffer and self.color_positions and #self.color_positions>0 then local color for ii=1, #self.color_positions do -- backup also as rgb for faster access self.RGBBuffer[self.color_positions[ii] + 0] = self.buffer[self.color_positions[ii] + 0] self.RGBBuffer[self.color_positions[ii] + 1] = self.buffer[self.color_positions[ii] + 1] self.RGBBuffer[self.color_positions[ii] + 2] = self.buffer[self.color_positions[ii] + 2] _l_rgb.r = self.buffer[self.color_positions[ii] + 0] _l_rgb.g = self.buffer[self.color_positions[ii] + 1] _l_rgb.b = self.buffer[self.color_positions[ii] + 2] self.buffer[self.color_positions[ii] + 0] = _l_rgb:getHue() self.buffer[self.color_positions[ii] + 1] = _l_rgb:getSaturation() self.buffer[self.color_positions[ii] + 2] = _l_rgb:getValue() end end end function LUT:generate() if self.data then else ac.debug("LUT", "no data given!!!") return end if self.sun_based then self:convertOldSunAngles() end if __CSP_version >= 1655 then -- CSP 1.76p38 (1655) -- build new cppLUT if self.data then local str = "" for i=1, #self.data do str = str..self.data[i][1].."|" for ii=2, #self.data[i] do str = str..self.data[i][ii] if ii<#self.data[i] then str = str.."," else str = str.."\n" end end end self.cppLUT = ac.LutCpp(str, self.color_positions) else ac.debug("LUT", "no data given!!!") end else self:convertHSVtoRGB() end end function LUT:interpolateLUA(index, curve) if self.data == nil then return nil end local pos = 0 local entries = #self.data[1] - 1 -- first entry is index curve = curve or self.curve if #self.data == 0 then ac.debug("plan: no entries!") return nil; end for i=1, #self.data-1 do if self.data[i][1] <= index and self.data[i+1][1] >= index then pos = i break end end if pos==0 then ac.debug("plan: entries out of range!") return nil end --interpolating position local offset = pow( (index - self.data[pos][1]) / max(0.01, self.data[pos+1][1] - self.data[pos][1]), curve ) if offset < 0 then offset = 0 ac.debug("Interpolate error | warning="..offset) elseif offset > 1 then offset = 1 ac.debug("Interpolate error | warning="..offset) end for i=1, entries do self.buffer[i] = lerp(self.data[pos][i+1], self.data[pos+1][i+1], offset) end return self.buffer end function LUT:get(index) index = index or __sun_angle if self.cppLUT then self.cppLUT:calculateTo(self.buffer, index) --self.buffer = self.cppLUT:calculate(index) return self.buffer else if self.data then self:interpolateLUA(index) self:convertRGBtoHSV_Buffer() return self.buffer end end end function __PURE__update_LUT_cycle() end