File size: 14,607 Bytes
103b0f1
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
      
local LumiObjectExtension = {}
LumiObjectExtension.__index = LumiObjectExtension

local function handleAllEntityBySingleParent(_trans, func, func2, ...)
    if _trans.children:size() > 0 and func2(_trans, ...) then
        for i = 1, _trans.children:size() do
            local child = _trans.children:get(i-1)
            handleAllEntityBySingleParent(child, func, func2, ...)
        end
    end
    func(_trans, ...)
end

local function CreateRenderTexture(width, height)
    local rt = Amaz.RenderTexture()
    rt.width = width
    rt.height = height
    rt.depth = 1
    rt.filterMag = Amaz.FilterMode.FilterMode_LINEAR
    rt.filterMin = Amaz.FilterMode.FilterMode_LINEAR
    rt.filterMipmap = Amaz.FilterMipmapMode.FilterMode_NONE
    rt.attachment = Amaz.RenderTextureAttachment.NONE
    return rt
end

function LumiObjectExtension.register(_ent)
    if _ent == nil then return nil end
    local scriptComp = _ent:getComponent("ScriptComponent")
    if scriptComp == nil then return nil end
    local effect_lua = Amaz.ScriptUtils.getLuaObj(scriptComp:getScript())
    if effect_lua == nil then return nil end

    -- Amaz.LOGI("zglog ", "LumiObjectExtension register ".._ent.name)
    local self = setmetatable({}, LumiObjectExtension)
    self.entity = _ent
    self.scriptComp = scriptComp
    self.trans = _ent:getComponent("Transform")
    self.effect_lua = effect_lua
    if effect_lua.__lumi_type~= nil then
        self.__lumi_type = effect_lua.__lumi_type 
    else
        self.__lumi_type = "lumi_obj"
    end
    if effect_lua.__lumi_rt_pingpong_type~= nil then
        self.__lumi_rt_pingpong_type = effect_lua.__lumi_rt_pingpong_type 
    else
        self.__lumi_rt_pingpong_type = "custom"
    end

    if self.entity:getComponents("Camera"):size() > 0 then
        Amaz.LOGE("AE_LUA_TAG", "Error: root entity has camera attached")
        return nil
    end
    self.subLumiObjExt = {}
    if self.__lumi_type == "lumi_effect" then
        for i = 1, self.trans.children:size() do
            local child = self.trans.children:get(i-1)
            local objExt = LumiObjectExtension.register(child.entity)
            if objExt and child.entity.name ~= '' then
                self.subLumiObjExt[child.entity.name] = objExt
            end
        end
    end
    if self.entity.name and self.entity.name ~= '' then
        self.subLumiObjExt[self.entity.name] = self
    end
    effect_lua.__lumi_obj_ext = self
    return self
end

function LumiObjectExtension.deregister(_ent)
    if _ent == nil then return nil end
    local scriptComp = _ent:getComponent("ScriptComponent")
    if scriptComp == nil then return nil end
    local effect_lua = Amaz.ScriptUtils.getLuaObj(scriptComp:getScript())
    if effect_lua == nil then return nil end
    local lumi_obj = effect_lua.__lumi_obj_ext
    if lumi_obj == nil then return nil end

    -- Amaz.LOGI("zglog ", "LumiObjectExtension deregister ".._ent.name)
    if  lumi_obj.__lumi_type == "lumi_effect" then
        for i = 1, lumi_obj.trans.children:size() do
            local child = lumi_obj.trans.children:get(i-1)
            LumiObjectExtension.deregister(child.entity)
        end
    end
    lumi_obj.entity = nil
    lumi_obj.trans = nil
    lumi_obj.effect_lua = nil
    lumi_obj.scriptComp = nil
    lumi_obj.subLumiObjExt = nil
    lumi_obj.__lumi_type = nil
    lumi_obj.__lumi_rt_pingpong_type = nil
    effect_lua.__lumi_obj_ext = nil
end

function LumiObjectExtension.getLumiObjExt(_ent)
    if _ent == nil then return nil end
    local scriptComp = _ent:getComponent("ScriptComponent")
    if scriptComp == nil then return nil end
    local effect_lua = Amaz.ScriptUtils.getLuaObj(scriptComp:getScript())
    if effect_lua == nil then return nil end
    return effect_lua.__lumi_obj_ext
end

function LumiObjectExtension:searchSubLumiObjExt(name)
    if name and self.subLumiObjExt[name] then 
        return self.subLumiObjExt[name]
    end
    for _, subObj in pairs(self.subLumiObjExt) do
        local obj = subObj:searchSubLumiObjExt(name)
        if obj then
            self.subLumiObjExt[name] = obj
            return obj
        end
    end
    return nil
end

function LumiObjectExtension:setInputTex(_tex)
    if self.effect_lua then
        self.effect_lua.InputTex = _tex
        if self.scriptComp and self.scriptComp.properties then
            self.scriptComp.properties:set('InputTex', _tex)
        end
    end
end

function LumiObjectExtension:setOutputTex(_tex)
    if self.effect_lua then
        self.effect_lua.OutputTex = _tex
        if self.scriptComp and self.scriptComp.properties then
            self.scriptComp.properties:set('OutputTex', _tex)
        end
    end
end

function LumiObjectExtension:getInputTex()
    if self.effect_lua then
        return self.effect_lua.InputTex
    end
    return nil
end

function LumiObjectExtension:getOutputTex()
    if self.effect_lua then
        return self.effect_lua.OutputTex
    end
    return nil
end

function LumiObjectExtension:setInputTexSizes(inputSize, originalSize)
    assert(type(inputSize)=="table", "inputSize should be table")
    if self.effect_lua and self.effect_lua.setInputTexSize then
        self.effect_lua:setInputTexSize(inputSize)
    end
    if self.effect_lua and self.effect_lua.setInputOriginalTexSize then
        self.effect_lua:setInputOriginalTexSize(originalSize)
    end
    self._inputTexSize, self._originalTexSize = inputSize, originalSize
end

function LumiObjectExtension:getOutputTexSizes()
    local inputSize = (self.effect_lua and self.effect_lua.getOutputTexSize) and self.effect_lua:getOutputTexSize() or self._inputTexSize
    local originalSize = (self.effect_lua and self.effect_lua.getOutputOriginalTexSize) and self.effect_lua:getOutputOriginalTexSize() or self._originalTexSize
    return inputSize, originalSize
end

function LumiObjectExtension:needChangeOutputTexSize()
    if self.effect_lua and self.effect_lua.__lumi_will_change_out_size then
        return self.effect_lua.__lumi_will_change_out_size
    end
    if self._inputTexSize~=nil and self.effect_lua and self.effect_lua.getOutputTexSize then
        local outSize = self.effect_lua:getOutputTexSize()
        return (outSize[1] ~= self._inputTexSize[1] or outSize[2] ~= self._inputTexSize[2])
    end
    return false
end

function LumiObjectExtension:updateRt(_input_tex, _output_tex, _pingpong_tex)
    self:setInputTex(_input_tex)
    self:setOutputTex(_output_tex)
    if self.effect_lua and self.effect_lua.updateRenderTexture ~= nil then
        self.effect_lua:updateRenderTexture()
    end
    if self.__lumi_type == "lumi_effect" and self.__lumi_rt_pingpong_type == "auto" then
        -- Amaz.LOGI("zglog ", "w: ".._output_tex.width.." ,h: ".._output_tex.height)

        local lumi_obj_list = {}
        local function collect_lumi_obj(_trans)
            local lumi_obj_ext = LumiObjectExtension.getLumiObjExt(_trans.entity)
            if lumi_obj_ext and (lumi_obj_ext.__lumi_type == "lumi_obj" or lumi_obj_ext.__lumi_rt_pingpong_type == "custom") then
                table.insert(lumi_obj_list, lumi_obj_ext)
            end
        end
        local function collect_lumi_obj_flag(_trans)
            local lumi_obj_ext = LumiObjectExtension.getLumiObjExt(_trans.entity)
            if lumi_obj_ext and lumi_obj_ext.__lumi_type == "lumi_effect" and lumi_obj_ext.__lumi_rt_pingpong_type == "auto" then
                return true
            end
            return false
        end
        handleAllEntityBySingleParent(self.trans, collect_lumi_obj, collect_lumi_obj_flag)

        -- Amaz.LOGI("zglog ", "lumi_obj_list: "..#lumi_obj_list)
        if _pingpong_tex then
            self._pingpong_tex = _pingpong_tex
        elseif #lumi_obj_list > 1 then
            self._pingpong_tex = CreateRenderTexture(_output_tex.width, _output_tex.height)
        end
        local pingpong = { _output_tex, self._pingpong_tex }
        if #lumi_obj_list%2 == 0 then
            pingpong = { self._pingpong_tex, _output_tex }
        end
        for i = 1, #lumi_obj_list do
            local lumi_obj = lumi_obj_list[i]
            -- Amaz.LOGI("zglog ", "lumi_obj: "..lumi_obj.scriptComp.entity.name)
            if lumi_obj then
                local idx1 = (i-1)%2+1
                local idx2 = (i)%2+1
                if i == 1 then
                    lumi_obj:setInputTex(_input_tex)
                    lumi_obj:setOutputTex(pingpong[idx1])
                else
                    lumi_obj:setInputTex(pingpong[idx2])
                    lumi_obj:setOutputTex(pingpong[idx1])
                end
                if lumi_obj.effect_lua and lumi_obj.effect_lua.updateRenderTexture ~= nil then
                    lumi_obj.effect_lua:updateRenderTexture()
                end
            end
        end
    end
end

function LumiObjectExtension:getCameraCount()
    local cam_count = 0

    if self.__lumi_type == "lumi_effect" then
        for i = 1, self.trans.children:size() do
            local child = self.trans.children:get(i-1)
            local lumi_obj_ext = LumiObjectExtension.getLumiObjExt(child.entity)
            if lumi_obj_ext then
                cam_count = cam_count + lumi_obj_ext:getCameraCount()
            else             
                local cam = child.entity:getComponent("Camera")
                if cam then
                    cam_count = cam_count + 1
                end
            end
        end
    elseif self.__lumi_type == "lumi_obj" then
        for i = 1, self.trans.children:size() do
            local child = self.trans.children:get(i-1)
            local cam = child.entity:getComponent("Camera")
            if cam then
                cam_count = cam_count + 1
            end
        end
    end

    return cam_count
end

local function _setLayer(_cam, _layer)
    local str = "1"
    for i = 1, _layer do
        str = str.."0"
    end
    local dynamic_bitset = Amaz.DynamicBitset.new(str)

    _cam.layerVisibleMask = dynamic_bitset
end

function LumiObjectExtension:updateCameraLayerAndOrder(_start_layer, _start_order)

    if self.__lumi_type == "lumi_obj" then
        local cur_start_layer = _start_layer
        local cur_start_order = _start_order
        for i = 1, self.trans.children:size() do
            local camTrans = self.trans.children:get(i-1)
            local cam = camTrans.entity:getComponent("Camera")
            if cam then
                cam.renderOrder = cur_start_order
                _setLayer(cam, cur_start_layer)
                for j = 1, camTrans.children:size() do
                    local rendererTrans = camTrans.children:get(j-1)
                    local renderers = rendererTrans.entity:getComponentsRecursive("Renderer")
                    for k = 0, renderers:size() - 1 do
                        local renderer = renderers:get(k)
                        if renderer then
                            renderer.entity.layer = cur_start_layer
                        end
                    end
                end
            end
            cur_start_order = cur_start_order + 1
            cur_start_layer = cur_start_layer + 1
        end

    elseif self.__lumi_type == "lumi_effect" then
        local cur_start_layer = _start_layer
        local cur_start_order = _start_order

        for i = 1, self.trans.children:size() do
            local child = self.trans.children:get(i-1)
            local lumi_obj_ext = LumiObjectExtension.getLumiObjExt(child.entity)
            if lumi_obj_ext then
                lumi_obj_ext:updateCameraLayerAndOrder(cur_start_layer, cur_start_order)
                local cam_count = lumi_obj_ext:getCameraCount()
                cur_start_layer = cur_start_layer + cam_count
                cur_start_order = cur_start_order + cam_count
            else
                local cam = child.entity:getComponent("Camera")
                if cam then
                    cam.renderOrder = cur_start_order
                    _setLayer(cam, cur_start_layer)
                    for j = 1, child.children:size() do
                        local rendererTrans = child.children:get(j-1)
                        local renderers = rendererTrans.entity:getComponentsRecursive("Renderer")
                        for k = 0, renderers:size() - 1 do
                            local renderer = renderers:get(k)
                            if renderer then
                                renderer.entity.layer = cur_start_layer
                            end
                        end
                    end
                    cur_start_order = cur_start_order + 1
                    cur_start_layer = cur_start_layer + 1
                end
            end
        end

    end

end

function LumiObjectExtension:setEffectAttr(key, value)
    if self.effect_lua and self.effect_lua.setEffectAttr ~= nil then
        self.effect_lua:setEffectAttr(key, value, self.scriptComp)
    else
        if self.effect_lua and self.effect_lua[key] ~= nil then
            self.effect_lua[key] = value
            if self.scriptComp and self.scriptComp.properties ~= nil then
                self.scriptComp.properties:set(key, value)
            end
        end
    end
end

function LumiObjectExtension:getEffectAttr(key)
    if  self.effect_lua and self.effect_lua.getEffectAttr ~= nil then
        return self.effect_lua:getEffectAttr(key, self.scriptComp)
    else
        if self.effect_lua and self.effect_lua[key] ~= nil then
            return self.effect_lua[key]
        end
    end
    return nil
end

function LumiObjectExtension:setSubEffectAttr(subName, key, value)
    local subObj = self:searchSubLumiObjExt(subName)
    if subObj then
        subObj:setEffectAttr(key, value)
    end
end


function LumiObjectExtension:getSubEffectAttr(subName, key)
    local subObj = self:searchSubLumiObjExt(subName)
    if subObj then
        subObj:getEffectAttr(key)
    end
end

function LumiObjectExtension:updateMaterials(time)
    if self.effect_lua and self.scriptComp then
        if self.effect_lua.updateMaterial ~= nil then
            self.effect_lua:updateMaterial(self.scriptComp, time)
        elseif self.effect_lua.onUpdate ~= nil then
            self.effect_lua:onUpdate(self.scriptComp, time)
        end

        for i = 1, self.trans.children:size() do
            local child = self.trans.children:get(i-1)
            local lumi_obj_ext = LumiObjectExtension.getLumiObjExt(child.entity)
            if lumi_obj_ext then
                lumi_obj_ext:updateMaterials(time)
            end
        end
    end
end


return LumiObjectExtension