started work on sorce and listener

This commit is contained in:
Nyx
2025-05-09 03:00:56 -06:00
parent 79bdb2254c
commit 6dd1337c4c
10 changed files with 273 additions and 8 deletions

View File

@@ -6,6 +6,8 @@ target_sources( ${PROJECT_NAME}
register_types.h
steam_audio.cpp
steam_audio.h
steam_audio_scene.cpp
steam_audio_scene.h
)
target_include_directories( ${PROJECT_NAME}

View File

@@ -1,6 +1,8 @@
// src/register_types.cpp
#include "register_types.h"
#include "steam_audio.h" // your SteamAudio class declaration
#include "steam_audio_scene.h"
using namespace godot;
@@ -8,13 +10,16 @@ void initialize_steam_audio(ModuleInitializationLevel p_level) {
if (p_level!=MODULE_INITIALIZATION_LEVEL_SERVERS) {
return;
}
/*if (p_level == MODULE_INITIALIZATION_LEVEL_EDITOR) {
GDREGISTER_CLASS(SteamAudioEditorPlugin);
}*/
GDREGISTER_CLASS(SteamAudio);
GDREGISTER_CLASS(SteamAudioScene);
}
void uninitialize_steam_audio(ModuleInitializationLevel p_level) {
if (p_level!=MODULE_INITIALIZATION_LEVEL_SERVERS) {
return;
}
}
extern "C" {

View File

@@ -13,6 +13,10 @@ using namespace godot;
iplContextRelease(&context);
context=nullptr;
}
if (embree_device) {
iplEmbreeDeviceRelease(&embree_device);
embree_device=nullptr;
}
}
void SteamAudio::_bind_methods() {
ClassDB::bind_method(D_METHOD("initialize"), &SteamAudio::initialize);
@@ -30,5 +34,10 @@ bool SteamAudio::initialize()
UtilityFunctions::printerr("SteamAudio::initialize()", err);
return false;
}
IPLEmbreeDeviceSettings emb_device_settings{};
if (iplEmbreeDeviceCreate(context, &emb_device_settings, &embree_device) != IPL_STATUS_SUCCESS) {
UtilityFunctions::printerr("SteamAudio::initialize(): failed to create Embree device");
return false;
}
return true;
}

View File

@@ -18,10 +18,14 @@ class SteamAudio : public RefCounted
private:
IPLContext context = nullptr;
IPLEmbreeDevice embree_device = nullptr;
protected:
static void _bind_methods();
public:
SteamAudio();
~SteamAudio() override;
bool initialize();
[[nodiscard]] IPLContext getContext() const{return context;}
[[nodiscard]] IPLEmbreeDevice getEmbreeDevice() const{return embree_device;}
};

View File

@@ -0,0 +1,32 @@
//
// Created by bryce on 5/8/2025.
//
#include "steam_audio_listener.h"
using namespace godot;
void SteamAudioListener::_bind_methods() {
ClassDB::bind_method(D_METHOD("set_context", "ctx"), &SteamAudioListener::set_context);
ClassDB::bind_method(D_METHOD("_process","delta"), &SteamAudioListener::_process);
ADD_PROPERTY(
PropertyInfo(Variant::OBJECT, "context", PROPERTY_HINT_RESOURCE_TYPE, "SteamAudio"),
"set_context", ""
);
}
void SteamAudioListener::set_context(const Ref<SteamAudio> &p_ctx) {
ERR_FAIL_COND(!p_ctx.is_valid());
ctx = p_ctx;
}
void SteamAudioListener::_process(double delta) {
ERR_FAIL_COND(!ctx.is_valid());
Transform3D transform = get_global_transform();
IPLCoordinateSpace3 ls{};
ls.origin = {transform.origin.x, transform.origin.y, transform.origin.z};
Vector3 fwd = transform.basis.xform(Vector3(0,0,-1)), upv = transform.basis.xform(Vector3(0,1,0));
ls.ahead = {fwd.x, fwd.y, fwd.z};
ls.up = {upv.x, upv.y, upv.z};
}

View File

@@ -0,0 +1,22 @@
//
// Created by bryce on 5/8/2025.
//
#pragma once
#include <godot_cpp/classes/node3d.hpp>
#include <godot_cpp/classes/audio_listener3d.hpp>
#include <godot_cpp/godot.hpp>
#include "steam_audio.h"
#include <phonon.h>
using namespace godot;
class SteamAudioListener : public AudioListener3D {
GDCLASS(SteamAudioListener,AudioListener3D)
Ref<SteamAudio> ctx;
protected:
static void _bind_methods();
public:
void set_context(const Ref<SteamAudio> &p_ctx);
void _process(double delta) override;
};

95
src/steam_audio_scene.cpp Normal file
View File

@@ -0,0 +1,95 @@
//
// Created by bryce on 5/8/2025.
//
#include "steam_audio_scene.h"
using namespace godot;
SteamAudioScene::SteamAudioScene() = default;
SteamAudioScene::~SteamAudioScene() {
if (scene) {
iplSceneRelease(&scene);
}
}
void SteamAudioScene::_bind_methods() {
ClassDB::bind_method(D_METHOD("set_context","ctx"), &SteamAudioScene::set_context);
ClassDB::bind_method(D_METHOD("add_mesh","mesh_node"), &SteamAudioScene::add_mesh);
ClassDB::bind_method(D_METHOD("commit"), &SteamAudioScene::commit);
ADD_PROPERTY(PropertyInfo(Variant::OBJECT,"context",PROPERTY_HINT_RESOURCE_TYPE,"SteamAudio"), "set_context","");
}
void SteamAudioScene::set_context(const Ref<SteamAudio> &p_ctx) {
ERR_FAIL_COND(!p_ctx.is_valid());
ctx = p_ctx;
if (scene) {
iplSceneRelease(&scene);
scene = nullptr;
}
IPLSceneSettings settings{};
settings.type = ctx-> getEmbreeDevice() ? IPL_SCENETYPE_EMBREE : IPL_SCENETYPE_DEFAULT;
settings.embreeDevice = ctx-> getEmbreeDevice();
iplSceneCreate(ctx->getContext(), &settings, &scene);
}
void SteamAudioScene::commit() const {
ERR_FAIL_COND(!scene);
ERR_FAIL_COND(!ctx.is_valid());
iplSceneCommit(scene) ;
}
void SteamAudioScene::add_mesh(MeshInstance3D *mesh_node) {
ERR_FAIL_COND(!ctx.is_valid());
ERR_FAIL_COND(!scene);
ERR_FAIL_COND(!mesh_node);
// 1) Fetch the ArrayMesh from the MeshInstance3D
Ref<Mesh> mesh = mesh_node->get_mesh();
ERR_FAIL_COND(!mesh.is_valid());
ArrayMesh *raw_am = Object::cast_to<ArrayMesh>(mesh.ptr());
ERR_FAIL_COND(!raw_am);
Ref<ArrayMesh> am(raw_am);
ERR_FAIL_COND(!am.is_valid());
// 2) Pull out the raw arrays
Array arrays = am->surface_get_arrays(0);
PackedVector3Array verts = arrays[ArrayMesh::ARRAY_VERTEX];
PackedInt32Array idxs = arrays[ArrayMesh::ARRAY_INDEX];
int vertex_count = verts.size();
int index_count = idxs.size();
int triangle_count = index_count / 3;
// 3) Build Steam Audios settings struct
IPLStaticMeshSettings sm{};
sm.numVertices = vertex_count;
sm.numTriangles = triangle_count;
sm.numMaterials = 0;
sm.vertices = reinterpret_cast<IPLVector3*>(
const_cast<Vector3*>(verts.ptr())
);
sm.materialIndices = nullptr;
sm.materials = nullptr;
// 4) Convert the flat index list into IPLTriangle[]
IPLTriangle *tris = static_cast<IPLTriangle*>(
malloc(sizeof(IPLTriangle) * triangle_count)
);
for (int i = 0; i < triangle_count; ++i) {
tris[i].indices[0] = idxs.ptr()[3*i + 0];
tris[i].indices[1] = idxs.ptr()[3*i + 1];
tris[i].indices[2] = idxs.ptr()[3*i + 2];
}
sm.triangles = tris;
// 5) Create & add the static mesh to the scene
IPLStaticMesh static_mesh = nullptr;
iplStaticMeshCreate(scene, &sm, &static_mesh);
iplStaticMeshAdd (static_mesh, scene);
iplStaticMeshRelease(&static_mesh);
// 6) Clean up our temporary triangle array
::free(tris);
}

34
src/steam_audio_scene.h Normal file
View File

@@ -0,0 +1,34 @@
#pragma once
#include <godot_cpp/classes/array_mesh.hpp>
#include <godot_cpp/classes/mesh_instance3d.hpp>
#include <godot_cpp/classes/ref_counted.hpp>
#include <godot_cpp/variant/typed_array.hpp>
#include <godot_cpp/variant/utility_functions.hpp>
#include <godot_cpp/variant/packed_vector3_array.hpp>
#include <godot_cpp/variant/packed_int32_array.hpp>
#include <godot_cpp/classes/object.hpp>
#include "godot_cpp/godot.hpp"
#include "phonon.h"
#include "steam_audio.h"
using namespace godot;
class SteamAudioScene : public RefCounted {
GDCLASS(SteamAudioScene, RefCounted);
IPLScene scene = nullptr;
Ref<SteamAudio> ctx;
protected:
static void _bind_methods();
public:
SteamAudioScene();
~SteamAudioScene() override;
void set_context(const Ref<SteamAudio> &p_ctx);
void add_mesh(MeshInstance3D *mesh_node);
void commit() const;
};

View File

@@ -0,0 +1,30 @@
//
// Created by bryce on 5/9/2025.
//
#include "steam_audio_source.h"
#include "steam_audio.h"
using namespace godot;
SteamAudioSource::SteamAudioSource() {
}
SteamAudioSource::~SteamAudioSource() {
if (steam_audio_source) {
iplSourceRelease(&steam_audio_source);
steam_audio_source = nullptr;
}
}
void SteamAudioSource::_bind_methods() {
ClassDB::bind_method(D_METHOD("play"), &SteamAudioSource::play);
ClassDB::bind_method(D_METHOD("stop"), &SteamAudioSource::stop);
ClassDB::bind_method(D_METHOD("set_stream","stream"), &SteamAudioSource::set_stream);
}
void SteamAudioSource::play() {
audio_player = memnew(AudioStreamPlayer3D);
add_child(audio_player);
}

32
src/steam_audio_source.h Normal file
View File

@@ -0,0 +1,32 @@
//
// Created by bryce on 5/9/2025.
//
#pragma once
#include <godot_cpp/classes/audio_stream_player3d.hpp>
#include <godot_cpp/classes/node3d.hpp>
#include "phonon.h"
using namespace godot;
class SteamAudioSource:Node3D {
GDCLASS(SteamAudioSource, Node3D)
private:
AudioStreamPlayer3D* audio_player = nullptr;
IPLSource steam_audio_source = nullptr;
bool initialized = false;
public:
SteamAudioSource();
~SteamAudioSource();
void _ready() override;
void _process(double p_delta) override;
void play();
void stop();
void set_stream(const Ref<AudioStream>& p_stream);
protected:
static void _bind_methods();
};