started work on sorce and listener
This commit is contained in:
@@ -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}
|
||||
|
||||
@@ -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" {
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
@@ -16,12 +16,16 @@ class SteamAudio : public RefCounted
|
||||
{
|
||||
GDCLASS( SteamAudio,RefCounted ) // NOLINT(readability-use-auto)
|
||||
|
||||
private:
|
||||
private:
|
||||
IPLContext context = nullptr;
|
||||
protected:
|
||||
IPLEmbreeDevice embree_device = nullptr;
|
||||
protected:
|
||||
static void _bind_methods();
|
||||
public:
|
||||
public:
|
||||
SteamAudio();
|
||||
~SteamAudio() override;
|
||||
bool initialize();
|
||||
|
||||
[[nodiscard]] IPLContext getContext() const{return context;}
|
||||
[[nodiscard]] IPLEmbreeDevice getEmbreeDevice() const{return embree_device;}
|
||||
};
|
||||
32
src/steam_audio_listener.cpp
Normal file
32
src/steam_audio_listener.cpp
Normal 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};
|
||||
}
|
||||
22
src/steam_audio_listener.h
Normal file
22
src/steam_audio_listener.h
Normal 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
95
src/steam_audio_scene.cpp
Normal 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 Audio’s 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
34
src/steam_audio_scene.h
Normal 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;
|
||||
};
|
||||
30
src/steam_audio_source.cpp
Normal file
30
src/steam_audio_source.cpp
Normal 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
32
src/steam_audio_source.h
Normal 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();
|
||||
};
|
||||
Reference in New Issue
Block a user