diff --git a/resources/EngineResources/audio/music/I_alone_am_the_layerd_one.ogg b/resources/EngineResources/audio/music/I_alone_am_the_layerd_one.ogg new file mode 100644 index 0000000..1bc0d3b Binary files /dev/null and b/resources/EngineResources/audio/music/I_alone_am_the_layerd_one.ogg differ diff --git a/resources/EngineResources/audio/music/Piano_Contour.ogg b/resources/EngineResources/audio/music/Piano_Contour.ogg new file mode 100644 index 0000000..8d25e6d Binary files /dev/null and b/resources/EngineResources/audio/music/Piano_Contour.ogg differ diff --git a/resources/EngineResources/audio/music/chimken_wing.ogg b/resources/EngineResources/audio/music/chimken_wing.ogg new file mode 100644 index 0000000..4cbf6d7 Binary files /dev/null and b/resources/EngineResources/audio/music/chimken_wing.ogg differ diff --git a/resources/EngineResources/audio/music/groovy_fight.ogg b/resources/EngineResources/audio/music/groovy_fight.ogg new file mode 100644 index 0000000..9da3e52 Binary files /dev/null and b/resources/EngineResources/audio/music/groovy_fight.ogg differ diff --git a/resources/EngineResources/audio/sounds/LaidBackLobby.ogg b/resources/EngineResources/audio/sounds/LaidBackLobby.ogg new file mode 100644 index 0000000..d973c9c Binary files /dev/null and b/resources/EngineResources/audio/sounds/LaidBackLobby.ogg differ diff --git a/src/main/java/net/halbear/Terrain4J/EngineCore/Audio/AudioManager.java b/src/main/java/net/halbear/Terrain4J/EngineCore/Audio/AudioManager.java new file mode 100644 index 0000000..885cb8c --- /dev/null +++ b/src/main/java/net/halbear/Terrain4J/EngineCore/Audio/AudioManager.java @@ -0,0 +1,125 @@ +package net.halbear.Terrain4J.EngineCore.Audio; + +import net.halbear.Terrain4J.EngineCore.Main.Scene.Camera; +import org.joml.Matrix4f; +import org.joml.Vector3f; +import org.lwjgl.openal.AL; +import org.lwjgl.openal.ALC; +import org.lwjgl.openal.ALCCapabilities; +import org.tinylog.Logger; + +import java.nio.ByteBuffer; +import java.nio.IntBuffer; +import java.util.HashMap; +import java.util.Map; + +import static java.sql.Types.NULL; +import static org.lwjgl.openal.AL10.alDistanceModel; +import static org.lwjgl.openal.ALC10.*; + +public class AudioManager { + private final long Context; + private final long Device; + private final Map SoundBufferMap; + private final Map SoundSourceMap; + private SoundListener listener; + + public AudioManager(){ + SoundBufferMap = new HashMap<>(); + SoundSourceMap = new HashMap<>(); + Device = alcOpenDevice((ByteBuffer)null); + if(Device == NULL){ + throw new IllegalStateException("Failed to open default OpenAL device"); + } + ALCCapabilities deviceCapabilies = ALC.createCapabilities(Device); + this.Context = alcCreateContext(Device,(IntBuffer) null); + if(Context == NULL){ + throw new IllegalStateException("Failed to create OpenAL context."); + } + alcMakeContextCurrent(Context); + AL.createCapabilities(deviceCapabilies); + } + + public void AddSoundBuffer(String name, SoundBuffer soundBuffer){ + this.SoundBufferMap.put(name,soundBuffer); + } + public void AddSoundSource(String name, AudioSource source){ + this.SoundSourceMap.put(name,source); + } + public void CleanUp(){ + SoundSourceMap.values().forEach(AudioSource::CleanUp); + SoundSourceMap.clear(); + SoundBufferMap.values().forEach(SoundBuffer::CleanUp); + SoundBufferMap.clear(); + if(Context != NULL){ + alcDestroyContext(Context); + } + if(Device != NULL){ + alcCloseDevice(Device); + } + } + + public AudioSource GetAudioSource(String Name){ + return this.SoundSourceMap.get(Name); + } + + public void Pause(String SourceID){ + AudioSource source = SoundSourceMap.get(SourceID); + if (source == null) { + Logger.warn("Unknown audio source [{}]", SourceID); + return; + } + source.Pause(); + } + + public void Play(String SourceID, String BufferID){ + AudioSource audioSource = SoundSourceMap.get(SourceID); + if (audioSource == null) { + Logger.warn("Unknown audio source [{}]", SourceID); + return; + } + SoundBuffer soundBuffer = SoundBufferMap.get(BufferID); + if (soundBuffer == null) { + Logger.warn("Unknown audio buffer [{}]", BufferID); + return; + } + audioSource.SetBuffer(soundBuffer.GetBufferID()); + audioSource.Play(); + } + + public void PlayAudioSource(String name){ + AudioSource audioSource = this.SoundSourceMap.get(name); + if(audioSource != null && !audioSource.isPlaying()){ + audioSource.Play(); + } + } + + public void RemoveAudioSource(String name){ + this.SoundSourceMap.remove(name); + } + + public void SetAttenuationModel(int model){ + alDistanceModel(model); + } + public void SetListener(SoundListener listener){ + this.listener = listener; + } + public void Stop(String SourceID){ + AudioSource source = SoundSourceMap.get(SourceID); + if (source == null) { + Logger.warn("Unknown audio source [{}]", SourceID); + return; + } + source.Stop(); + } + public void UpdateListenerPosition(Camera camera){ + Matrix4f viewMatrix = camera.GetViewMatrix(); + listener.SetPosition(camera.GetPosition()); + Vector3f at = new Vector3f(); + viewMatrix.positiveZ(at).negate(); + Vector3f up = new Vector3f(); + viewMatrix.positiveY(up); + listener.SetOrientation(at,up); + } +} + diff --git a/src/main/java/net/halbear/Terrain4J/EngineCore/Audio/AudioSource.java b/src/main/java/net/halbear/Terrain4J/EngineCore/Audio/AudioSource.java new file mode 100644 index 0000000..d9c37b5 --- /dev/null +++ b/src/main/java/net/halbear/Terrain4J/EngineCore/Audio/AudioSource.java @@ -0,0 +1,29 @@ +package net.halbear.Terrain4J.EngineCore.Audio; + +import org.joml.Vector3f; + +import static org.lwjgl.openal.AL10.*; + +public class AudioSource { + private final int SourceID; + public AudioSource(boolean loop, boolean relative){ + this.SourceID = alGenSources(); + alSourcei(SourceID, AL_LOOPING, loop ? AL_TRUE: AL_FALSE); + alSourcei(SourceID, AL_SOURCE_RELATIVE, relative ? AL_TRUE : AL_FALSE); + } + + public void CleanUp(){ + Stop(); + alDeleteSources(SourceID); + } + public void SetBuffer(int Buffer){ + Stop(); + alSourcei(SourceID, AL_BUFFER, Buffer); + } + public boolean isPlaying(){return alGetSourcei(SourceID, AL_SOURCE_STATE) == AL_PLAYING;} + public void Pause(){alSourcePause(SourceID);} + public void Play(){alSourcePlay(SourceID);} + public void SetGain(float gain){alSourcef(SourceID, AL_GAIN, gain);} + public void SetPosition(Vector3f position){alSource3f(SourceID, AL_POSITION, position.x,position.y,position.z);} + public void Stop(){alSourceStop(SourceID);} +} diff --git a/src/main/java/net/halbear/Terrain4J/EngineCore/Audio/SoundBuffer.java b/src/main/java/net/halbear/Terrain4J/EngineCore/Audio/SoundBuffer.java new file mode 100644 index 0000000..607f5d6 --- /dev/null +++ b/src/main/java/net/halbear/Terrain4J/EngineCore/Audio/SoundBuffer.java @@ -0,0 +1,52 @@ +package net.halbear.Terrain4J.EngineCore.Audio; + +import org.lwjgl.stb.STBVorbisInfo; +import org.lwjgl.system.MemoryStack; +import org.lwjgl.system.MemoryUtil; + +import java.nio.IntBuffer; +import java.nio.ShortBuffer; + +import static java.sql.Types.NULL; +import static org.lwjgl.openal.AL10.*; +import static org.lwjgl.stb.STBVorbis.*; + +public class SoundBuffer { + private final int BufferID; + private final ShortBuffer pcm; + + public SoundBuffer(String FilePath){ + this.BufferID = alGenBuffers(); + try(STBVorbisInfo info = STBVorbisInfo.malloc()){ + pcm = ReadVorbis(FilePath, info); + alBufferData(BufferID, info.channels() == 1 ? AL_FORMAT_MONO16 : AL_FORMAT_STEREO16, pcm, info.sample_rate()); + } + } + + public void CleanUp(){ + alDeleteBuffers(this.BufferID); + if(pcm != null){ + MemoryUtil.memFree(pcm); + } + } + public int GetBufferID(){ + return this.BufferID; + } + private ShortBuffer ReadVorbis(String FilePath, STBVorbisInfo info){ + try(var MemStack = MemoryStack.stackPush()){ + IntBuffer error = MemStack.mallocInt(1); + long Decoder = stb_vorbis_open_filename(FilePath,error,null); + if(Decoder == NULL){ + throw new RuntimeException("Failed to open OGG Vorbis File, error -> " + error.get(0)); + } + stb_vorbis_get_info(Decoder, info); + int Channels = info.channels(); + int LengthSamples = stb_vorbis_stream_length_in_samples(Decoder); + + ShortBuffer result = MemoryUtil.memAllocShort(LengthSamples * Channels); + result.limit(stb_vorbis_get_samples_short_interleaved(Decoder,Channels,result) * Channels); + stb_vorbis_close(Decoder); + return result; + } + } +} diff --git a/src/main/java/net/halbear/Terrain4J/EngineCore/Audio/SoundListener.java b/src/main/java/net/halbear/Terrain4J/EngineCore/Audio/SoundListener.java new file mode 100644 index 0000000..6824a13 --- /dev/null +++ b/src/main/java/net/halbear/Terrain4J/EngineCore/Audio/SoundListener.java @@ -0,0 +1,28 @@ +package net.halbear.Terrain4J.EngineCore.Audio; + +import org.joml.Vector3f; + +import static org.lwjgl.openal.AL10.*; + +public class SoundListener { + public SoundListener(Vector3f Position){ + alListener3f(AL_POSITION, Position.x, Position.y, Position.z); + alListener3f(AL_VELOCITY, 0,0,0); + } + public void SetOrientation(Vector3f at, Vector3f up){ + float[] data = new float[6]; + data[0] = at.x; + data[1] = at.y; + data[2] = at.z; + data[3] = up.x; + data[4] = up.y; + data[5] = up.z; + alListenerfv(AL_ORIENTATION,data); + } + public void SetPosition(Vector3f Position){ + alListener3f(AL_POSITION, Position.x,Position.y,Position.z); + } + public void SetSpeed(Vector3f Speed){ + alListener3f(AL_VELOCITY,Speed.x,Speed.y,Speed.z); + } +} diff --git a/src/main/java/net/halbear/Terrain4J/EngineCore/Logic/EngineInstance.java b/src/main/java/net/halbear/Terrain4J/EngineCore/Logic/EngineInstance.java index 569d824..5524174 100644 --- a/src/main/java/net/halbear/Terrain4J/EngineCore/Logic/EngineInstance.java +++ b/src/main/java/net/halbear/Terrain4J/EngineCore/Logic/EngineInstance.java @@ -1,5 +1,6 @@ package net.halbear.Terrain4J.EngineCore.Logic; +import net.halbear.Terrain4J.EngineCore.Audio.AudioManager; import net.halbear.Terrain4J.EngineCore.Display.Render; import net.halbear.Terrain4J.EngineCore.Main.PrimaryRuntime; import net.halbear.Terrain4J.EngineCore.Main.Scene.Scene; @@ -8,8 +9,9 @@ import net.halbear.Terrain4J.EngineCore.Threads.FastTickThread; import net.halbear.Terrain4J.EngineCore.Threads.MainThread; import net.halbear.Terrain4J.EngineCore.Threads.RenderThread; -public record EngineInstance(Window window, Scene scene, PrimaryRuntime PrimaryThread) { +public record EngineInstance(Window window, Scene scene, PrimaryRuntime PrimaryThread, AudioManager audioManager) { public void cleanup(){ window.cleanup(); + audioManager.CleanUp(); } } diff --git a/src/main/java/net/halbear/Terrain4J/EngineCore/Main/GameCore.java b/src/main/java/net/halbear/Terrain4J/EngineCore/Main/GameCore.java index 760d46a..4eaca96 100644 --- a/src/main/java/net/halbear/Terrain4J/EngineCore/Main/GameCore.java +++ b/src/main/java/net/halbear/Terrain4J/EngineCore/Main/GameCore.java @@ -6,6 +6,10 @@ import imgui.ImGuiViewport; import imgui.ImVec2; import imgui.flag.ImGuiCond; import imgui.flag.ImGuiWindowFlags; +import net.halbear.Terrain4J.EngineCore.Audio.AudioManager; +import net.halbear.Terrain4J.EngineCore.Audio.AudioSource; +import net.halbear.Terrain4J.EngineCore.Audio.SoundBuffer; +import net.halbear.Terrain4J.EngineCore.Audio.SoundListener; import net.halbear.Terrain4J.EngineCore.Display.Window; import net.halbear.Terrain4J.EngineCore.Input.KeyboardInput; import net.halbear.Terrain4J.EngineCore.Input.MouseListener; @@ -13,6 +17,7 @@ import net.halbear.Terrain4J.EngineCore.Logic.*; import net.halbear.Terrain4J.EngineCore.Logic.Rendering.ModelLoader; import net.halbear.Terrain4J.EngineCore.Main.Scene.Actor; import net.halbear.Terrain4J.EngineCore.Main.Scene.Camera; +import net.halbear.Terrain4J.EngineCore.Main.Scene.ParticleActor; import net.halbear.Terrain4J.EngineCore.Main.Scene.Scene; import net.halbear.Terrain4J.EngineCore.Profiling.CPUMonitor; import net.halbear.Terrain4J.EngineCore.Profiling.GPUProfiler; @@ -22,6 +27,7 @@ import net.halbear.Terrain4J.EngineCore.Vulkan.Rendering.VkModel.ModelData; import net.halbear.Terrain4J.EngineCore.Vulkan.Structure.DisplayToScreen.SceneRender; import org.joml.Vector2f; import org.joml.Vector3f; +import org.lwjgl.openal.AL11; import java.util.ArrayList; import java.util.List; @@ -32,7 +38,13 @@ import static org.lwjgl.glfw.GLFW.*; public class GameCore implements GameLogic { private static final float MOUSE_SENSITIVITY = 0.1f; - private static final float MOVEMENT_SPEED = 0.05f; + private static final float MOVEMENT_SPEED = 0.025f; + + private static final String SOUND_BUFFER_MUSIC = "music-sound-buffer"; + private static final String SOUND_BUFFER_PLAYER = "player-sound-buffer"; + private static final String SOUND_SOURCE_MUSIC = "music-sound-source"; + private static final String SOUND_SOURCE_PLAYER = "player-sound-source"; + private final Vector3f rotatingAngle = new Vector3f(0, 1, 0); private float angle = 180; private List angles = new ArrayList<>(); @@ -40,6 +52,7 @@ public class GameCore implements GameLogic { private List Velocities = new ArrayList<>(); private Actor CubeActor; private List CubeActors = new ArrayList<>(); + private List particleActors = new ArrayList<>(); private Vector2f LastMousePos = new Vector2f(0,0); private int Ticks = 0; private int GUI_MODE = 0; @@ -51,6 +64,7 @@ public class GameCore implements GameLogic { private int NextAAMode = -1; private long LastFrameTime = 0; private long CoolDown = 1000; + private ModelData MusicParticle; @Override public void cleanup() { @@ -61,15 +75,18 @@ public class GameCore implements GameLogic { public InitData Initialise(EngineInstance engineInstance) { Scene scene = engineInstance.scene(); List models = new ArrayList<>(); - + MusicParticle = ModelLoader.LoadModel("resources/models/MusicParticle/MusicParticle.json"); + List MusicParticleMat = ModelLoader.LoadMaterials("resources/models/MusicParticle/MusicParticle_mat.json"); ModelData SponzaData = ModelLoader.LoadModel("resources/models/Forest/forest.json"); List SponzaMaterial = ModelLoader.LoadMaterials("resources/models/Forest/forest_mat.json"); + ModelData SponzaData1 = ModelLoader.LoadModel("resources/models/radio/radio.json"); + List SponzaMaterial1 = ModelLoader.LoadMaterials("resources/models/radio/radio_mat.json"); //ModelData SponzaData = ModelLoader.LoadModel("resources/models/Cafe/exterior.json"); //List SponzaMaterial = ModelLoader.LoadMaterials("resources/models/Cafe/exterior_mat.json"); //ModelData SponzaData1 = ModelLoader.LoadModel("resources/models/Cafe/interior.json"); //List SponzaMaterial1= ModelLoader.LoadMaterials("resources/models/Cafe/interior_mat.json"); - scene.AddActor(new Actor("Sponza1", SponzaData.ID(), new Vector3f(0,0,-5f))); - //scene.AddActor(new Actor("Sponza2", SponzaData1.ID(), new Vector3f(0,0,-5f))); + scene.AddActor(new Actor("Sponza1", SponzaData.ID(), new Vector3f(0,0f,-5f))); + scene.AddActor(new Actor("Sponza2", SponzaData1.ID(), new Vector3f(40.0f, 155.0f, -42.0f)).SetScale(0.01f)); models.add(ModelLoader.LoadModel("resources/models/Metro/OBJ/MetroLeadCar.json")); models.add(ModelLoader.LoadModel("resources/models/melona/melona.json")); @@ -91,22 +108,47 @@ public class GameCore implements GameLogic { materials.addAll(ModelLoader.LoadMaterials("resources/models/Alice/Welsh040Alice_mat.json")); materials.addAll(ModelLoader.LoadMaterials("resources/models/Sloop/SloopOBJ_mat.json")); materials.addAll(SponzaMaterial); - //materials.addAll(SponzaMaterial1); + materials.addAll(MusicParticleMat); + materials.addAll(SponzaMaterial1); models.add(SponzaData); - //models.add(SponzaData1); + models.add(MusicParticle); + models.add(SponzaData1); Camera camera = scene.GetCamera(); camera.SetPosition(40.0f, 155.0f, -42.0f); - camera.SetPosition(0,0,0); + //camera.SetPosition(0,0,0); camera.SetRotation((float) Math.toRadians(10.0f), (float) Math.toRadians(-90.0f),0); - camera.SetRotation(0,0,0); + //camera.SetRotation(0,0,0); guiTexture = new GuiTexture("resources/EngineResources/Texture/DefaultTexture.png"); List guiTextures = new ArrayList<>(); guiTextures.add(guiTexture); + InitiateAudio(engineInstance); + return new InitData(models,materials,guiTextures); } + private void InitiateAudio(EngineInstance engineInstance){ + AudioManager audioManager = engineInstance.audioManager(); + Camera camera = engineInstance.scene().GetCamera(); + audioManager.SetAttenuationModel(AL11.AL_EXPONENT_DISTANCE); + audioManager.SetListener(new SoundListener(camera.GetPosition())); + + SoundBuffer buffer = new SoundBuffer("resources/EngineResources/audio/sounds/LaidBackLobby.ogg"); + audioManager.AddSoundBuffer(SOUND_BUFFER_PLAYER, buffer); + AudioSource playerAudioSource = new AudioSource(true,false); + playerAudioSource.SetPosition(new Vector3f(40.0f, 155.0f, -42.0f)); + playerAudioSource.SetBuffer(buffer.GetBufferID()); + audioManager.AddSoundSource(SOUND_SOURCE_PLAYER,playerAudioSource); + playerAudioSource.Play(); + buffer = new SoundBuffer("resources/EngineResources/audio/music/chimken_wing.ogg"); + audioManager.AddSoundBuffer(SOUND_BUFFER_MUSIC,buffer); + AudioSource source = new AudioSource(true, true); + source.SetBuffer(buffer.GetBufferID()); + audioManager.AddSoundSource(SOUND_SOURCE_MUSIC,source); + //source.Play(); + } + @Override public void CameraInput(EngineInstance engineInstance, long FrameDiffNanoSeconds) { float Multiplier = MOUSE_SENSITIVITY; @@ -129,6 +171,7 @@ public class GameCore implements GameLogic { camera.AddRotation((float)Math.toRadians(-deltaPos.y * Multiplier),(float)Math.toRadians(-deltaPos.x * Multiplier),0); } + engineInstance.audioManager().UpdateListenerPosition(camera); } @Override @@ -326,12 +369,28 @@ public class GameCore implements GameLogic { @Override public void UpdateFastThread(EngineInstance engineInstance, long FrameDiffNanoSeconds) { float DeltaTime = (float)(FrameDiffNanoSeconds/16000000.0); + List ParticlesToDelete = new ArrayList<>(); + if((int)(Math.random() * 60) == 0){ + ParticleActor particle = new ParticleActor("particle" + particleActors.size(), MusicParticle.ID(), new Vector3f(40.0f, 155.0f, -42.0f),new Vector3f(1,1,1),0,new Vector3f(-1f + (float)Math.random() * 2,-1f + (float)Math.random() * 2,-1f + (float)Math.random() * 2),0.0005f,1000); + particleActors.add(particle); + engineInstance.scene().AddActor(particle); + } for(int i = 0; i < angles.size(); i++) { angles.set(i, (angles.get(i) + 1.0f* DeltaTime) % 360); CubeActors.get(i).GetRotation().identity().rotateAxis((float) EngineConfig.DegToRad * angles.get(i), rotatingAngles.get(i)); CubeActors.get(i).GetPosition().add((Velocities.get(i).x/100.0f) * DeltaTime,(Velocities.get(i).y/100.0f) * DeltaTime,(Velocities.get(i).z/100.0f) * DeltaTime); CubeActors.get(i).UpdateModelMatrix(); } + for(int i = 0; i < particleActors.size(); i++){ + particleActors.get(i).TickUpdate(); + if(particleActors.get(i).TicksLeft() <= 0){ + engineInstance.scene().RemoveActor(particleActors.get(i)); + ParticlesToDelete.add(i); + } + } + for(int i = ParticlesToDelete.size() - 1; i >= 0; i--){ + particleActors.remove((int)ParticlesToDelete.get(i)); + } } @Override diff --git a/src/main/java/net/halbear/Terrain4J/EngineCore/Main/PrimaryRuntime.java b/src/main/java/net/halbear/Terrain4J/EngineCore/Main/PrimaryRuntime.java index ce5da37..d903dfd 100644 --- a/src/main/java/net/halbear/Terrain4J/EngineCore/Main/PrimaryRuntime.java +++ b/src/main/java/net/halbear/Terrain4J/EngineCore/Main/PrimaryRuntime.java @@ -1,5 +1,6 @@ package net.halbear.Terrain4J.EngineCore.Main; +import net.halbear.Terrain4J.EngineCore.Audio.AudioManager; import net.halbear.Terrain4J.EngineCore.Display.Window; import net.halbear.Terrain4J.EngineCore.Logic.*; import net.halbear.Terrain4J.EngineCore.Logic.Rendering.VulkanContext; @@ -53,7 +54,7 @@ public class PrimaryRuntime { } window = new Window(windowTitle); gameLogic = appLogic; - engineInstance = new EngineInstance(window, new Scene(window),this); + engineInstance = new EngineInstance(window, new Scene(window),this, new AudioManager()); InitData initData = appLogic.Initialise(engineInstance); PrimaryThread = new MainThread(engineInstance, appLogic); FastThread = new FastTickThread(engineInstance, appLogic); diff --git a/src/main/java/net/halbear/Terrain4J/EngineCore/Main/Scene/Actor.java b/src/main/java/net/halbear/Terrain4J/EngineCore/Main/Scene/Actor.java index c05992f..0b8cea6 100644 --- a/src/main/java/net/halbear/Terrain4J/EngineCore/Main/Scene/Actor.java +++ b/src/main/java/net/halbear/Terrain4J/EngineCore/Main/Scene/Actor.java @@ -36,9 +36,10 @@ public class Actor{ UpdateModelMatrix(); } - public void SetScale(float Scale){ + public Actor SetScale(float Scale){ this.Scale = Scale; UpdateModelMatrix(); + return this; } public void UpdateModelMatrix(){ diff --git a/src/main/java/net/halbear/Terrain4J/EngineCore/Main/Scene/ParticleActor.java b/src/main/java/net/halbear/Terrain4J/EngineCore/Main/Scene/ParticleActor.java new file mode 100644 index 0000000..6ca1bdd --- /dev/null +++ b/src/main/java/net/halbear/Terrain4J/EngineCore/Main/Scene/ParticleActor.java @@ -0,0 +1,38 @@ +package net.halbear.Terrain4J.EngineCore.Main.Scene; + +import net.halbear.Terrain4J.EngineCore.Logic.EngineConfig; +import org.joml.Matrix4f; +import org.joml.Quaternionf; +import org.joml.Vector3f; + +public class ParticleActor extends Actor { + + private Vector3f Velocity; + private Vector3f RotatingAngles; + private float Angle = 0.0f; + private int LifeTicks = 1000; + private float decelerationRate = 0.1f; + + public ParticleActor(String ID, String ModelID, Vector3f Position, Vector3f RotatingAngles, float Rotation, Vector3f Velocity, float Deceleration, int LifeTicks){ + super(ID,ModelID,Position); + this.Angle = Rotation; + this.RotatingAngles = RotatingAngles; + this.decelerationRate = Deceleration; + this.LifeTicks = LifeTicks; + this.Velocity = Velocity; + } + public int TicksLeft(){return LifeTicks;} + public float Deleration(){return decelerationRate;} + public Vector3f GetVelocity(){return Velocity;} + + public void TickUpdate(){ + Angle = (Angle + 1.0f) % 360; + GetRotation().identity().rotateAxis((float) EngineConfig.DegToRad * Angle, RotatingAngles); + GetPosition().add((Velocity.x/100.0f),(Velocity.y/100.0f) ,(Velocity.z/100.0f)); + Velocity.x = Velocity.x != 0? Velocity.x > 0 ? Math.max(Velocity.x - decelerationRate, 0) : Math.min(Velocity.x + decelerationRate, 0) : 0; + Velocity.y = Velocity.y != 0? Velocity.y > 0 ? Math.max(Velocity.y - decelerationRate, 0) : Math.min(Velocity.y + decelerationRate, 0) : 0; + Velocity.z = Velocity.z != 0? Velocity.z > 0 ? Math.max(Velocity.z - decelerationRate, 0) : Math.min(Velocity.z + decelerationRate, 0) : 0; + UpdateModelMatrix(); + LifeTicks--; + } +} diff --git a/src/main/java/net/halbear/Terrain4J/EngineCore/Vulkan/Structure/DisplayToScreen/SceneRender.java b/src/main/java/net/halbear/Terrain4J/EngineCore/Vulkan/Structure/DisplayToScreen/SceneRender.java index 2561867..86dd3c1 100644 --- a/src/main/java/net/halbear/Terrain4J/EngineCore/Vulkan/Structure/DisplayToScreen/SceneRender.java +++ b/src/main/java/net/halbear/Terrain4J/EngineCore/Vulkan/Structure/DisplayToScreen/SceneRender.java @@ -312,53 +312,21 @@ public class SceneRender implements SceneRenderer {//dynamic rendering int ActorCount = Actors.size(); List translucentObjects = new ArrayList<>(); for(int i = 0; i < ActorCount; i++){ - var Actor = Actors.get(i); - VulkanModel model = modelsCache.GetModel(Actor.GetModelID()); - List VkMeshList = model.GetVkMeshList(); - int MeshCount = VkMeshList.size(); - for(int j = 0; j < MeshCount; j++){ - var VkMesh = VkMeshList.get(j); - String MaterialID = VkMesh.MaterialID(); - int MaterialIndex = materialsCache.GetPosition(MaterialID); - VulkanMaterial vulkanMaterial = materialsCache.GetMaterial(MaterialID); - if(vulkanMaterial == null){ - Logger.warn("Mesh [{}] in model [{}] does not have material",j,model.GetID()); - continue; - } - if( DualPassRendering || vulkanMaterial.HasTransparency() == Transparent) { - //if(Transparent){ - // if(!translucentObjects.contains(Actor))translucentObjects.add(Actor); - //}else { - SetPushConstants(CommandHandle, Actor.GetModelMatrix(), MaterialIndex); - vertexBuffer.put(0, VkMesh.VerticesBuffer().GetBuffer()); - vkCmdBindVertexBuffers(CommandHandle, 0, vertexBuffer, offsets); - vkCmdBindIndexBuffer(CommandHandle, VkMesh.IndicesBuffer().GetBuffer(), 0, VK_INDEX_TYPE_UINT32); - vkCmdDrawIndexed(CommandHandle, VkMesh.IndicesCount(), 1, 0, 0, 0); - //} - } - } - } - /*if(Transparent){ - translucentObjects.sort((actor1, actor2) -> { - float distSq1 = actor1.GetPosition().distanceSquared(scene.GetCamera().GetPosition()); - float distSq2 = actor2.GetPosition().distanceSquared(scene.GetCamera().GetPosition()); - return Float.compare(distSq2, distSq1); - }); - for(int i = 0; i < translucentObjects.size(); i++){ - var Actor = translucentObjects.get(i); + if(i < Actors.size()) { + var Actor = Actors.get(i); VulkanModel model = modelsCache.GetModel(Actor.GetModelID()); List VkMeshList = model.GetVkMeshList(); int MeshCount = VkMeshList.size(); - for(int j = 0; j < MeshCount; j++){ + for (int j = 0; j < MeshCount; j++) { var VkMesh = VkMeshList.get(j); String MaterialID = VkMesh.MaterialID(); int MaterialIndex = materialsCache.GetPosition(MaterialID); VulkanMaterial vulkanMaterial = materialsCache.GetMaterial(MaterialID); - if(vulkanMaterial == null){ - Logger.warn("Mesh [{}] in model [{}] does not have material",j,model.GetID()); + if (vulkanMaterial == null) { + Logger.warn("Mesh [{}] in model [{}] does not have material", j, model.GetID()); continue; } - if(vulkanMaterial.HasTransparency() == Transparent) { + if (DualPassRendering || vulkanMaterial.HasTransparency() == Transparent) { SetPushConstants(CommandHandle, Actor.GetModelMatrix(), MaterialIndex); vertexBuffer.put(0, VkMesh.VerticesBuffer().GetBuffer()); vkCmdBindVertexBuffers(CommandHandle, 0, vertexBuffer, offsets); @@ -367,7 +335,7 @@ public class SceneRender implements SceneRenderer {//dynamic rendering } } } - }*/ + } } }