this.outlets = 4 local max = require("max") local format = string.format local edited_material_name = nil -- target jit.gl.material being edited local target_materials = {} listener = nil local onames = { getattr = 0, imageui = 1, thumbnails = 2, thispatcher = 3, } -- Global dirty flag -- Set when target_materials are considered -- dirty relative to the editor material dirty = false local dirty_attrs = { -- model diffuse_model = true, specular_model = true, -- model parameters shininess = true, diffuse_size = true, diffuse_smooth = true, specular_size = true, specular_smooth = true, roughness = true, darkness = true, -- colors mat_emission = true, mat_ambient = true, mat_diffuse = true, mat_specular = true, -- fog fog = true, fog_color = true, fog_density = true, fog_range = true, } local get_edited_material local function refresh_patcher() -- connect to message ";max refresh" outlet(onames.getattr, "bang") end local function set_dirty(v) if(v and v ~= dirty) then -- set override on first dirty for i, target_material in ipairs(target_materials) do target_material.override = 1 end end dirty = v outlet(onames.thumbnails, "set_dirty", dirty and 1 or 0) end local cloning = false local function mtl_cb(e) if(e.eventname == "attr_modified") then -- modified current material local attrname = e.args[1] if(dirty_attrs[attrname]) then if(not cloning) then set_dirty(true) local edited_material = get_edited_material() local v = edited_material[attrname] --[[ if(type(v) == "table") then print("attrname", attrname, table.concat(v, " ")) else print("attrname", attrname, v) end --]] for i, target_material in ipairs(target_materials) do -- print(i, target_material) target_material[attrname] = v end end end elseif(e.eventname == "import_material") then -- just imported a new material set_dirty(true) refresh_patcher() local edited_material = get_edited_material() --print("import_material", edited_material.matfile) for i, target_material in ipairs(target_materials) do target_material.matfile = edited_material.matfile end outlet(onames.imageui, "import_material") elseif(e.eventname:match("%a+_texture")) then -- texture set/cleared event set_dirty(true) elseif(e.eventname == "rebuild") then outlet(onames.imageui, "rebuild") else -- print("EVENT:", e.eventname) end end function get_edited_material() -- look up Material's Browser material by name if(not edited_material_name) then edited_material_name = this.material listener = jit.listener(edited_material_name, mtl_cb) end return assert( jit.findregistered(edited_material_name), "couldn't get edited material" ) end local function lose_focus() -- apply edits to target/focus jit.gl.material object if(dirty) then local edited_material = get_edited_material() for i, target_material in ipairs(target_materials) do target_material:clone(edited_material) target_material.override = 1 end end refresh_patcher() --[[ for i, target_material in ipairs(target_materials) do print("lose focus") end --]] end local function gain_focus() if(target_materials[1]) then local target_material = target_materials[1] local edited_material = get_edited_material() cloning = true edited_material:clone(target_material) cloning = false set_dirty(false) outlet(onames.imageui, "import_material") end local title = "Materials Browser" if(#target_materials == 1) then title = "jit.gl.material Editor" elseif(#target_materials > 1) then title = format("jit.gl.material (%d) Editor", #target_materials) end outlet(onames.thispatcher, "title", title) --[[ print("gain focus", #target_materials) for i, target_material in ipairs(target_materials) do print("gain focus:", i, target_material.name) end --]] end function closebang() lose_focus() dirty = false end -- Called on the target_material -- to prepare editing function set_target_material(...) local mtls = {...} lose_focus() target_materials = mtls gain_focus() end local matrix = jit.matrix() function get_texture_data(name) local x = get_edited_material() local res = x:copy_texture(name, matrix) if(res) then outlet(onames.imageui, "jit_matrix", matrix.name) else outlet(onames.imageui, "jit_matrix") end end function init() get_edited_material() end function target_texture(textype, name) --print("target_texture", textype, name) if(target_materials[1]) then local tm = target_materials[1] if(textype == "diffuse_texture") then if(name) then tm:diffuse_texture(name) else tm:diffuse_texture() end elseif(textype == "specular_texture") then if(name) then tm:specular_texture(name) else tm:specular_texture() end elseif(textype == "ambient_texture") then if(name) then tm:ambient_texture(name) else tm:ambient_texture() end elseif(textype == "emission_texture") then if(name) then tm:emission_texture(name) else tm:emission_texture() end elseif(textype == "normals_texture") then if(name) then tm:normals_texture(name) else tm:normals_texture() end elseif(textype == "environment_texture") then if(name) then tm:environment_texture(name) else tm:environment_texture() end end end end