Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
27 commits
Select commit Hold shift + click to select a range
df2285c
add ClusterEngine to group audio objects into persistent clusters by …
phevosccp Oct 10, 2026
8d08735
add a standalone harness to test, benchmark and run scenarios on Clus…
phevosccp Oct 10, 2026
27212c8
rewrite ObjectClusterFX around ClusterEngine
phevosccp Oct 10, 2026
b129256
align the premake script with the wwise 2025 scaffold
phevosccp Oct 10, 2026
8489ab6
rewrite the readme for the new clustering
phevosccp Oct 10, 2026
b887c4f
move the engine and its tests to core/ and the wwise project to wwise/
phevosccp Oct 15, 2026
bcde443
rename the plugin from ObjectCluster to SpatialClustering
phevosccp Oct 15, 2026
42c4a90
add a single plugin version and show it in the authoring dll's versio…
phevosccp Oct 15, 2026
436d015
add help pages for every parameter in the wwise property editor
phevosccp Oct 15, 2026
b783457
add a script that builds and packages the plugin as a wwise launcher …
phevosccp Oct 15, 2026
8b64386
split the docs out of the readme and add a changelog, contributing gu…
phevosccp Oct 15, 2026
6edff65
run the core tests on windows, linux and macos in ci, and add a .gita…
phevosccp Oct 15, 2026
6e4c5ca
add a battle scenario and a viewer that plays scenarios back without …
phevosccp Oct 15, 2026
04b2cae
make the release script build the authoring plugin without visual stu…
phevosccp Oct 15, 2026
caf53d8
ignore the visual studio 2026 solutions that premake generates
phevosccp Oct 15, 2026
75a577f
fold the docs back into the readme and drop the changelog file
phevosccp Oct 15, 2026
476754b
add a cmake build for the runtime plug-in package and the authoring p…
phevosccp Oct 16, 2026
e915b40
cluster stereo inputs by mixing them down to the mono cluster output
phevosccp Oct 16, 2026
d9e6041
default the join angle to 15 degrees
phevosccp Oct 16, 2026
152134c
drop the leave ratio and loudness weighting parameters and group the …
phevosccp Oct 16, 2026
423d540
move the core tests, scenarios, benchmark, viewer and their ci to a s…
phevosccp Oct 16, 2026
a62037a
split the readme into a short overview and docs, and correct the docs…
phevosccp Oct 16, 2026
2741625
Merge branch 'main' into plugin-overhaul
phevosccp Oct 16, 2026
2399bca
rename the protection parameter group to exclusions
phevosccp Oct 16, 2026
9a3605d
rename the parameters to names sound designers know: cluster width, o…
phevosccp Oct 16, 2026
a7d7811
only generate install rules for a standalone build, so games can add …
phevosccp Oct 16, 2026
1108dd8
build the runtime plug-in as a dll for dynamic loading
phevosccp Oct 16, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions .gitattributes
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
# Store text files with LF line endings and let git pick the checkout line endings.
* text=auto

*.png binary
*.jpg binary
*.gif binary
30 changes: 30 additions & 0 deletions .github/ISSUE_TEMPLATE/bug_report.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
---
name: Bug report
about: Something in the plug-in does not work as described
labels: bug
---

**What happened**
A clear description of the problem.

**Steps to reproduce**
1.
2.
3.

**What you expected**

**Versions**
- Spatial Clustering version:
- Wwise version (for example 2025.1.10):
- Platform (authoring and/or runtime, for example Windows x64):
- Game engine and Wwise integration, if any:

**Bus setup**
The bus channel configuration, the plug-in's parameter values, and roughly how many inputs reach the bus and of which kind (mono 3D one-shots, ambiences, ...).

**Capture Log**
Any messages from Spatial Clustering in the Wwise Capture Log.

**Anything else**
Screenshots of the Audio Object List or 3D Viewer, or a small project that shows the problem, help a lot.
14 changes: 14 additions & 0 deletions .github/ISSUE_TEMPLATE/feature_request.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
---
name: Feature request
about: Suggest something the plug-in could do
labels: enhancement
---

**Use case**
What are you trying to do, and in what kind of scene?

**What you would like**
What the plug-in could do to help.

**What you do today**
Any workaround you use now.
8 changes: 8 additions & 0 deletions .github/PULL_REQUEST_TEMPLATE.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
**What changed and why**


**Testing**
- [ ] The plug-in builds and was tested at runtime in Wwise or a game.

**Docs**
- [ ] If a parameter changed: `SpatialClustering.xml`, the help page in `wwise/WwisePlugin/res/Md/en`, and `docs/parameters.md` are updated.
11 changes: 11 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -475,3 +475,14 @@ ASALocalRun/
.localhistory/

# End of https://www.gitignore.io/api/archives,linux,xcode,macos,windows,visualstudio,premake-gmake

### Spatial Clustering ###
# Help pages and the missing-help report written by wp.py build Documentation
wwise/WwisePlugin/res/Html/
wwise/Output/
# Visual Studio 2026 solutions generated by wp.py premake
*.slnx
# Release bundles written by scripts/package.py
dist/
# Personal editor settings
.vscode/
212 changes: 212 additions & 0 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,212 @@
# Copyright 2026 CCP ehf.
#
# This software was developed by CCP Games for spatial audio object clustering
# in EVE Online and EVE Frontier.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#
# This license does not grant any rights to CCP's trademarks or game content.
# EVE Online and EVE Frontier are registered trademarks of CCP ehf.

# Builds the runtime plug-in as a static library for games that build with CMake, and on
# Windows optionally the authoring plug-in. The premake scripts in wwise/ remain the build
# for the Wwise Launcher bundle.

cmake_minimum_required(VERSION 3.16)

file(STRINGS wwise/SpatialClusteringVersion.h SPATIALCLUSTERING_VERSION_LINE
REGEX "#define SPATIALCLUSTERING_VERSION_STRING")
string(REGEX MATCH "[0-9]+\\.[0-9]+\\.[0-9]+" SPATIALCLUSTERING_VERSION "${SPATIALCLUSTERING_VERSION_LINE}")

project(SpatialClustering VERSION ${SPATIALCLUSTERING_VERSION} LANGUAGES CXX)

option(SPATIALCLUSTERING_BUILD_AUTHORING "Build the Wwise authoring plug-in (Windows only)" OFF)
option(SPATIALCLUSTERING_BUILD_SHARED "Build the runtime plug-in as a dynamic library that the sound engine loads at run time" OFF)

# A game that adds the plug-in with add_subdirectory links it into its own binaries, so by
# default only a standalone build installs it.
if(CMAKE_SOURCE_DIR STREQUAL CMAKE_CURRENT_SOURCE_DIR)
set(SPATIALCLUSTERING_STANDALONE ON)
else()
set(SPATIALCLUSTERING_STANDALONE OFF)
endif()
option(SPATIALCLUSTERING_INSTALL "Generate the install rules" ${SPATIALCLUSTERING_STANDALONE})

include(GNUInstallDirs)
include(CMakePackageConfigHelpers)

# The Wwise SDK comes from a Wwise CMake package (such as the wwise vcpkg port) when one is
# found, and otherwise from the SDK folder of a Wwise install.
if(NOT TARGET Wwise::Wwise)
find_package(Wwise CONFIG QUIET)
endif()
if(NOT TARGET Wwise::Wwise)
set(WWISE_SDK_DIR "$ENV{WWISESDK}" CACHE PATH "SDK folder of a Wwise install, the one that contains include/AK")
if(NOT EXISTS "${WWISE_SDK_DIR}/include/AK/AkWwiseSDKVersion.h")
message(FATAL_ERROR "Wwise SDK not found. Set WWISE_SDK_DIR, or the WWISESDK environment variable, to the SDK folder of a Wwise install.")
endif()
add_library(Wwise::Wwise INTERFACE IMPORTED)
set_target_properties(Wwise::Wwise PROPERTIES
INTERFACE_INCLUDE_DIRECTORIES "${WWISE_SDK_DIR}/include"
INTERFACE_COMPILE_DEFINITIONS "$<$<CONFIG:Release>:AK_OPTIMIZED>")
endif()

set(SPATIALCLUSTERING_RUNTIME_SOURCES
core/src/ClusterEngine.cpp
core/src/ClusterEngine.h
wwise/SoundEnginePlugin/SpatialClusteringFX.cpp
wwise/SoundEnginePlugin/SpatialClusteringFX.h
wwise/SoundEnginePlugin/SpatialClusteringFXParams.cpp
wwise/SoundEnginePlugin/SpatialClusteringFXParams.h
wwise/SpatialClusteringConfig.h)

# Games include the factory header as <AK/Plugin/SpatialClusteringFXFactory.h>, like the
# Audiokinetic plug-ins.
set(SPATIALCLUSTERING_INCLUDE_DIR ${CMAKE_CURRENT_BINARY_DIR}/include)
configure_file(wwise/SoundEnginePlugin/SpatialClusteringFXFactory.h
${SPATIALCLUSTERING_INCLUDE_DIR}/AK/Plugin/SpatialClusteringFXFactory.h COPYONLY)

# Runtime plug-in. It takes AK_OPTIMIZED from Wwise::Wwise, so it matches the sound engine
# libraries of the configuration. Games link Wwise themselves, so it is not part of the
# installed interface.
add_library(SpatialClusteringFX STATIC ${SPATIALCLUSTERING_RUNTIME_SOURCES})
add_library(SpatialClustering::SpatialClusteringFX ALIAS SpatialClusteringFX)
target_include_directories(SpatialClusteringFX
PUBLIC
$<BUILD_INTERFACE:${SPATIALCLUSTERING_INCLUDE_DIR}>
$<INSTALL_INTERFACE:${CMAKE_INSTALL_INCLUDEDIR}>
PRIVATE
core/src)
target_link_libraries(SpatialClusteringFX PRIVATE $<BUILD_INTERFACE:Wwise::Wwise>)
target_compile_features(SpatialClusteringFX PRIVATE cxx_std_17)
target_compile_options(SpatialClusteringFX PRIVATE $<$<CXX_COMPILER_ID:MSVC>:/utf-8>)

if(SPATIALCLUSTERING_INSTALL)
install(TARGETS SpatialClusteringFX EXPORT SpatialClusteringTargets
ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR} COMPONENT Runtime)
install(FILES ${SPATIALCLUSTERING_INCLUDE_DIR}/AK/Plugin/SpatialClusteringFXFactory.h
DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/AK/Plugin COMPONENT Runtime)

set(SPATIALCLUSTERING_CONFIG_DIR ${CMAKE_INSTALL_DATADIR}/SpatialClustering)
install(EXPORT SpatialClusteringTargets
NAMESPACE SpatialClustering::
DESTINATION ${SPATIALCLUSTERING_CONFIG_DIR}
COMPONENT Runtime)
write_basic_package_version_file(${CMAKE_CURRENT_BINARY_DIR}/SpatialClusteringConfigVersion.cmake
COMPATIBILITY SameMajorVersion)
install(FILES
cmake/SpatialClusteringConfig.cmake
${CMAKE_CURRENT_BINARY_DIR}/SpatialClusteringConfigVersion.cmake
DESTINATION ${SPATIALCLUSTERING_CONFIG_DIR}
COMPONENT Runtime)
endif()

# Runtime plug-in as a dynamic library. The sound engine loads it from next to the executable,
# or from AkInitSettings::szPluginDLLPath, when a SoundBank needs it and it is not linked in.
# Release builds it for the Release sound engine and RelWithDebInfo for the Profile one.
if(SPATIALCLUSTERING_BUILD_SHARED)
add_library(SpatialClusteringShared SHARED
wwise/SoundEnginePlugin/SpatialClusteringFXShared.cpp
wwise/SoundEnginePlugin/SpatialClusteringFXFactory.h)
set_target_properties(SpatialClusteringShared PROPERTIES OUTPUT_NAME SpatialClustering)
target_link_libraries(SpatialClusteringShared PRIVATE SpatialClusteringFX Wwise::Wwise)
target_compile_features(SpatialClusteringShared PRIVATE cxx_std_17)
if(MSVC)
target_compile_options(SpatialClusteringFX PRIVATE /Z7)
target_compile_options(SpatialClusteringShared PRIVATE /utf-8 /Z7)
target_link_options(SpatialClusteringShared PRIVATE /DEBUG /INCREMENTAL:NO /OPT:REF /OPT:ICF)
endif()

if(SPATIALCLUSTERING_INSTALL)
# The library only, without the import library that nothing links against.
if(WIN32)
set(SPATIALCLUSTERING_SHARED_DIR ${CMAKE_INSTALL_BINDIR})
else()
set(SPATIALCLUSTERING_SHARED_DIR ${CMAKE_INSTALL_LIBDIR})
endif()
install(FILES $<TARGET_FILE:SpatialClusteringShared>
DESTINATION ${SPATIALCLUSTERING_SHARED_DIR}
COMPONENT SharedRuntime)
if(MSVC)
install(FILES $<TARGET_PDB_FILE:SpatialClusteringShared>
DESTINATION ${SPATIALCLUSTERING_SHARED_DIR}
COMPONENT SharedRuntime
OPTIONAL)
endif()
endif()
endif()

# Authoring plug-in. Install it into a Wwise install, or a copy of one, with
# cmake --install <build> --config Release --component Authoring --prefix <Wwise install>
if(SPATIALCLUSTERING_BUILD_AUTHORING)
if(NOT WIN32)
message(FATAL_ERROR "The authoring plug-in builds on Windows only.")
endif()

# Wwise Authoring runs the Profile sound engine, so the runtime plug-in it embeds never
# gets AK_OPTIMIZED and only takes the SDK headers from Wwise::Wwise.
set(SPATIALCLUSTERING_WWISE_INCLUDE_DIRS $<TARGET_PROPERTY:Wwise::Wwise,INTERFACE_INCLUDE_DIRECTORIES>)

add_library(SpatialClusteringFXAuthoring STATIC ${SPATIALCLUSTERING_RUNTIME_SOURCES})
target_include_directories(SpatialClusteringFXAuthoring PRIVATE core/src ${SPATIALCLUSTERING_WWISE_INCLUDE_DIRS})
target_compile_definitions(SpatialClusteringFXAuthoring PRIVATE WIN64 WIN32_LEAN_AND_MEAN AK_ENABLE_ASSERTS)
target_compile_features(SpatialClusteringFXAuthoring PRIVATE cxx_std_17)
target_compile_options(SpatialClusteringFXAuthoring PRIVATE /utf-8 /Zc:inline)

# The GUI uses MFC through AK::Wwise::Plugin::PluginMFCWindows. The definitions are the
# ones from the Wwise SDK property sheets for authoring plug-ins.
set(CMAKE_MFC_FLAG 2)
add_library(SpatialClusteringAuthoring SHARED
wwise/WwisePlugin/SpatialClusteringPlugin.cpp
wwise/WwisePlugin/SpatialClusteringPlugin.h
wwise/WwisePlugin/Win32/SpatialClusteringPluginGUI.cpp
wwise/WwisePlugin/Win32/SpatialClusteringPluginGUI.h
wwise/WwisePlugin/resource.h
wwise/WwisePlugin/SpatialClustering.def
wwise/WwisePlugin/SpatialClustering.rc)
set_target_properties(SpatialClusteringAuthoring PROPERTIES OUTPUT_NAME SpatialClustering)
target_include_directories(SpatialClusteringAuthoring PRIVATE ${SPATIALCLUSTERING_WWISE_INCLUDE_DIRS})
target_compile_definitions(SpatialClusteringAuthoring PRIVATE
WIN64 WIN32_LEAN_AND_MEAN AK_ENABLE_ASSERTS
_WINDOWS _USRDLL _WINDLL _AFXDLL UNICODE _UNICODE WWISE_AUTHORING AUDIOKINETIC
_CRT_STDIO_ARBITRARY_WIDE_SPECIFIERS _CRT_SECURE_NO_DEPRECATE _CRT_NON_CONFORMING_SWPRINTFS)
target_compile_features(SpatialClusteringAuthoring PRIVATE cxx_std_17)
target_compile_options(SpatialClusteringAuthoring PRIVATE /utf-8 /Zc:inline /Z7)
target_link_options(SpatialClusteringAuthoring PRIVATE /DEBUG /OPT:REF /OPT:ICF)
target_link_libraries(SpatialClusteringAuthoring PRIVATE SpatialClusteringFXAuthoring)

if(SPATIALCLUSTERING_INSTALL)
# Same layout as a Wwise install: the plug-in and its XML next to the other authoring
# plug-ins, and the property help where the property editor looks for it.
set(SPATIALCLUSTERING_AUTHORING_PLUGIN_DIR Authoring/x64/Release/bin/Plugins)
install(FILES
$<TARGET_FILE:SpatialClusteringAuthoring>
wwise/WwisePlugin/SpatialClustering.xml
DESTINATION ${SPATIALCLUSTERING_AUTHORING_PLUGIN_DIR}
COMPONENT Authoring)
install(FILES $<TARGET_PDB_FILE:SpatialClusteringAuthoring>
DESTINATION ${SPATIALCLUSTERING_AUTHORING_PLUGIN_DIR}
COMPONENT Authoring
OPTIONAL)

# wp.py build Documentation generates the help pages from wwise/WwisePlugin/res/Md.
set(SPATIALCLUSTERING_HELP_DIR ${CMAKE_CURRENT_SOURCE_DIR}/wwise/WwisePlugin/res/Html)
if(EXISTS ${SPATIALCLUSTERING_HELP_DIR})
install(DIRECTORY ${SPATIALCLUSTERING_HELP_DIR}/
DESTINATION Authoring/Data/Plugins/SpatialClustering/Html
COMPONENT Authoring)
else()
message(WARNING "wwise/WwisePlugin/res/Html does not exist, so the property help is not installed. Run wp.py build Documentation in the wwise folder to generate it.")
endif()
endif()
endif()
37 changes: 37 additions & 0 deletions CONTRIBUTING.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
# Contributing

We welcome contributions: feature requests, bug fixes, documentation improvements, or new functionality.

## Opening an issue

- Search existing open and closed issues before creating a new one.
- For bug reports, use the bug report template. Include the plug-in and Wwise versions, the platform, steps to reproduce and any Capture Log messages from the plug-in.
- For feature requests, include the use case.

## Submitting a pull request

- Fork the repository and create a feature branch.
- Build and test your changes at runtime before submitting.
- Submit a PR with a clear description of what changed and why.

Contributions are accepted under the [Apache License 2.0](LICENSE.txt), the license of this project.

## Building and testing your changes

[Building from source](docs/building.md) covers the toolchain, the plug-in build and ways to try the plug-in in a game.

## Where things are

| Path | Contents |
|---|---|
| `core/src/ClusterEngine.h/.cpp` | The clustering. Plain C++17 with no Wwise headers; all memory goes through a `ClusterAllocator`. |
| `wwise/` | The Wwise plug-in project. Run `wp.py` from this folder. |
| `wwise/SoundEnginePlugin/SpatialClusteringFX.h/.cpp` | The Wwise object processor: reads the input objects, runs the engine, creates and updates output objects and mixes the inputs into them with gain ramps. |
| `wwise/SoundEnginePlugin/SpatialClusteringFXParams.h/.cpp` | Parameters, read from banks and RTPCs. |
| `wwise/WwisePlugin/` | The authoring plug-in, the property definitions (`SpatialClustering.xml`) and the property help (`res/Md`). |
| `wwise/SpatialClusteringVersion.h` | The plug-in version. |
| `wwise/SpatialClusteringConfig.h` | The company and plug-in IDs. |
| `scripts/package.py` | Builds and packages a release. |
| `docs/` | User documentation. |

When you add or change a parameter, update `SpatialClustering.xml`, `GetBankParameters` in `SpatialClusteringPlugin.cpp`, `SpatialClusteringFXParams`, the help page in `wwise/WwisePlugin/res/Md/en` and the table in `docs/parameters.md`. The order in which `GetBankParameters` writes the values must match the order in which `SpatialClusteringFXParams` reads them.
16 changes: 10 additions & 6 deletions NOTICE
Original file line number Diff line number Diff line change
@@ -1,9 +1,13 @@
Spatial Audio Object Clustering Plugin for Wwise
Spatial Clustering for Wwise
Copyright 2026 Fenris Creations

This product includes software developed for audio object clustering
in spatial audio applications, specifically designed for large-scale
space battle scenarios in EVE Online and EVE Frontier.
This product was developed by CCP Games for audio object clustering in
spatial audio applications, specifically designed for large-scale space
battle scenarios in EVE Online and EVE Frontier.

This software includes the following third-party components:
- Wwise SDK (Copyright Audiokinetic Inc.)
This product is built with the Audiokinetic Wwise SDK, which is not
included in this product and is licensed separately by Audiokinetic Inc.

Some files are derived from the plug-in templates in the Wwise SDK
(Copyright Audiokinetic Inc.). They are used under the Apache License,
Version 2.0, and keep their original copyright headers.
Loading