Hello!
This weekend I was trying to enhance the sound module originaly posted by Shawak (origina post here: [Mod] Sound System . As I mentioned in there, it had one significat flaw I didn't like -> it was iterating table of sound zones, which were rectangles. That's cool if you don't want to define many zones, however sooner or later it stops beeing scalable.
Therefore, I implemented kd-tree which is able to locate nearby zones within few steps, even if you have 100k sound zones defined
It still has some flaws and areas to improve however, it brings a nice optimization, I wanted to share, so here we go
First grab this from my repository, and put in client main folder :
GitHub - Tarjei400/lua-tools
Great half way done. Now add this preferable to init.lua
I removed some gui stuff from there, but you can restore it from Shawak's script if you want to
[code/lua]dofile('lua-tools/main.lua')[/code]
And here is the modified file:
rcsound.lua:
This weekend I was trying to enhance the sound module originaly posted by Shawak (origina post here: [Mod] Sound System . As I mentioned in there, it had one significat flaw I didn't like -> it was iterating table of sound zones, which were rectangles. That's cool if you don't want to define many zones, however sooner or later it stops beeing scalable.
Therefore, I implemented kd-tree which is able to locate nearby zones within few steps, even if you have 100k sound zones defined
It still has some flaws and areas to improve however, it brings a nice optimization, I wanted to share, so here we go
First grab this from my repository, and put in client main folder :
GitHub - Tarjei400/lua-tools
Great half way done. Now add this preferable to init.lua
I removed some gui stuff from there, but you can restore it from Shawak's script if you want to
[code/lua]dofile('lua-tools/main.lua')[/code]
And here is the modified file:
rcsound.lua:
Lua:
Polygon.polygons = {}
local CONQUERIA = Polygon()
CONQUERIA:addPoint(1528, 1547)
CONQUERIA:addPoint(1537, 1547)
CONQUERIA:addPoint(1537, 1557)
CONQUERIA:addPoint(1528, 1557)
CONQUERIA.sound = "Fairy Tail - Main.ogg"
CONQUERIA.fadeIn = 3
CONQUERIA.priority = 1
CONQUERIA:normalize()
for i = 1, 100 do
local CONQUERIA2 = CONQUERIA:move(30*(i-1),30*i)
CONQUERIA2.sound = "Fairy Tail - Main.ogg"
CONQUERIA2.priority = 1
CONQUERIA2.fadeIn = 3
end
local centroids = Polygon.calculateAllCentroids();
local SoundZoneTree = KDTree(centroids);
SOUNDS_CONFIG = {
soundChannel = 1,
checkInterval = 1000,
folder = 'music/',
noSound = 'No sound file for this area.',
}
-- Sound
local rcSoundChannel
local showPosEvent
local playingSound
-- Design
soundWindow = nil
function init()
for k, v in pairs(Polygon.polygons) do
v.sound = SOUNDS_CONFIG.folder .. v.sound
end
connect(g_game, { onGameStart = onGameStart,
onGameEnd = onGameEnd })
rcSoundChannel = g_sounds.getChannel(SOUNDS_CONFIG.soundChannel)
if(g_game.isOnline()) then
onGameStart()
end
end
function terminate()
disconnect(g_game, { onGameStart = onGameStart,
onGameEnd = onGameEnd })
onGameEnd()
end
function onGameStart()
stopSound()
toggleSoundEvent = addEvent(toggleSound, SOUNDS_CONFIG.checkInterval)
end
function onGameEnd()
stopSound()
removeEvent(toggleSoundEvent)
end
local SongFadingOut = false;
local CurrentZone = nil
function toggleSound()
local player = g_game.getLocalPlayer()
if not player then return end
local pos = player:getPosition()
local toPlay = nil
local searchPos = Point(pos.x, pos.y)
if CurrentZone ~= nil then
if CurrentZone:contains(searchPos) then
toggleSoundEvent = scheduleEvent(toggleSound, SOUNDS_CONFIG.checkInterval)
return
else
CurrentZone = nil
end
end
local zones = {}
local p = SoundZoneTree:nearestTo(searchPos, function(lNorm, rNorm, node)
local poly = node.point.polygon
table.insert(zones, poly)
return lNorm < rNorm
end)
playingSound = playingSound or {sound='', priority=0, fadeIn = 0}
local inZones = 0
for k, zone in pairs(zones)do
if zone:contains(searchPos) then
toPlay = zone
inZones = inZones + 1
if(toPlay~=nil and playingSound.sound~=toPlay.sound) then
g_logger.info("RC Sounds: New sound area detected:")
g_logger.info(" Position: {x=" .. pos.x .. ", y=" .. pos.y .. ", z=" .. pos.z .. "}")
g_logger.info(" Music: " .. toPlay.sound)
stopSound(toPlay.fadeIn)
playSound(toPlay.sound, toPlay.fadeIn)
playingSound = toPlay
CurrentZone = zone
break
end
end
end
if(inZones == 0 and not (SongFadingOut) and playingSound ~= nil) then
g_logger.info("RC Sounds: New sound area detected:")
g_logger.info(" Left music area.")
SongFadingOut = true
scheduleEvent(function()
SongFadingOut = false
end, 1000*playingSound.fadeIn)
stopSound(playingSound.fadeIn)
end
toggleSoundEvent = scheduleEvent(toggleSound, SOUNDS_CONFIG.checkInterval)
end
function playSound(sound, fadeIn)
rcSoundChannel:enqueue(sound, fadeIn)
end
function clearName(soundName)
local explode = string.explode(soundName, "/")
soundName = explode[#explode]
explode = string.explode(soundName, ".ogg")
soundName = ''
for i = 1, #explode-1 do
soundName = soundName .. explode[i]
end
return soundName
end
function stopSound(fadeIn)
rcSoundChannel:stop(fadeIn)
playingSound = nil
end
Last edited: