Skip to content

Commit

Permalink
Signed-off-by: Ling Lin <[email protected]>
Browse files Browse the repository at this point in the history
  • Loading branch information
taellinglin committed Dec 7, 2024
1 parent 6384dca commit 2fd9f41
Show file tree
Hide file tree
Showing 62 changed files with 1,142 additions and 1,668 deletions.
2 changes: 1 addition & 1 deletion .pman
Original file line number Diff line number Diff line change
Expand Up @@ -13,4 +13,4 @@ main_file = "main.py"
physics_engine = "bullet"

[python]
path = "./Scripts/python.exe"
path = "C:/Users/User/Miniconda3"
2 changes: 1 addition & 1 deletion .pman.user
Original file line number Diff line number Diff line change
Expand Up @@ -13,4 +13,4 @@ main_file = "main.py"
physics_engine = "bullet"

[python]
path = "./Scripts/python.EXE"
path = "C:/Users/User/Miniconda3"
81 changes: 50 additions & 31 deletions ShadowCode/love_you.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
from panda3d.core import * # For other Panda3D classes you're using
from math import sin, cos, pi


class CameraSetup(ShowBase):
def __init__(self):
super().__init__()
Expand All @@ -11,7 +12,7 @@ def __init__(self):
self.camera.set_pos(0, 0, 100) # Higher up for better top-down view
self.camera.look_at(0, 0, 0)
self.camLens.setFov(60)

self.useTrackball()
self.create_scene()

Expand All @@ -26,27 +27,29 @@ def create_orb(self):
num_rings = 30
points_per_ring = 360 # Increased for more detail
max_radius = 25 # Base radius for torus

for ring in range(num_rings):
# Flatter scaling for torus shape
ring_ratio = (ring / (num_rings - 1)) * 2 - 1 # -1 to 1
ring_scale = 1 - (ring_ratio * ring_ratio) * 0.3 # Much flatter scaling
height = ring - (num_rings / 2)

for i in range(points_per_ring):
angle = i * (2 * pi / points_per_ring)
hue = angle / (2 * pi) # Color based on angle for rainbow effect

# More torus-like shape
radius = max_radius * (1 - 0.1 * abs(height) / (num_rings / 2)) # Very slight radius variation
radius = max_radius * (
1 - 0.1 * abs(height) / (num_rings / 2)
) # Very slight radius variation
x = radius * cos(angle)
y = radius * sin(angle)
z = height * 0.2 # Much flatter in z-direction

cube = self.create_single_cube()
cube.setPos(x, y, z)
cube.setScale(0.1) # Smaller cubes for finer detail

color = self.hue_to_rgb(hue)
material = Material()
material.setEmission((*color, 1))
Expand All @@ -58,25 +61,27 @@ def create_heart_curls(self):
num_rings = 80 # Doubled for more detail
points_per_ring = 360 # Increased for smoother curves
orb_radius = 25

# Create two curls
for curl in [-1, 1]: # Left and right curls
for ring in range(num_rings):
ring_progress = ring / num_rings
ring_scale = 1 - ring_progress * 0.95 # Slightly more gradual taper

# Base height starts from center of orb
base_height = ring * 0.3 # Reduced height increment for tighter spiral
curl_angle = ring_progress * pi * 2.5 # Increased rotation for tighter curl

curl_angle = (
ring_progress * pi * 2.5
) # Increased rotation for tighter curl

for i in range(points_per_ring):
angle = i * (2 * pi / points_per_ring)
hue = (ring / num_rings + i / points_per_ring) % 1.0

# Create curl shape
radius = 15 * ring_scale
base_x = radius * cos(angle) + (20 * curl * ring_scale)

# Rotate curls to be perpendicular to ground plane
if curl > 0:
x = base_x * cos(curl_angle)
Expand All @@ -86,17 +91,17 @@ def create_heart_curls(self):
x = base_x * cos(-curl_angle + pi)
y = base_height + base_x * sin(-curl_angle + pi)
z = radius * sin(angle)

# Scale everything to fit inside orb
scale_factor = 0.8
x *= scale_factor
y *= scale_factor
z *= scale_factor

cube = self.create_single_cube()
cube.setPos(x, y, z)
cube.setScale(0.1) # Smaller cubes for finer detail

color = self.hue_to_rgb(hue)
material = Material()
material.setEmission((*color, 1))
Expand All @@ -105,48 +110,62 @@ def create_heart_curls(self):

def create_single_cube(self):
format = GeomVertexFormat.get_v3()
vdata = GeomVertexData('cube', format, Geom.UH_static)
vertex_writer = GeomVertexWriter(vdata, 'vertex')
vdata = GeomVertexData("cube", format, Geom.UH_static)
vertex_writer = GeomVertexWriter(vdata, "vertex")

# Define vertices for a cube
vertices = [
(-0.5, -0.5, -0.5), (0.5, -0.5, -0.5), (0.5, 0.5, -0.5), (-0.5, 0.5, -0.5),
(-0.5, -0.5, 0.5), (0.5, -0.5, 0.5), (0.5, 0.5, 0.5), (-0.5, 0.5, 0.5)
(-0.5, -0.5, -0.5),
(0.5, -0.5, -0.5),
(0.5, 0.5, -0.5),
(-0.5, 0.5, -0.5),
(-0.5, -0.5, 0.5),
(0.5, -0.5, 0.5),
(0.5, 0.5, 0.5),
(-0.5, 0.5, 0.5),
]
for vertex in vertices:
vertex_writer.addData3(*vertex)

geom = Geom(vdata)
prim = GeomTriangles(Geom.UH_static)

indices = [
(0, 1, 2), (2, 3, 0), # Bottom
(4, 5, 6), (6, 7, 4), # Top
(0, 1, 5), (5, 4, 0), # Front
(2, 3, 7), (7, 6, 2), # Back
(0, 3, 7), (7, 4, 0), # Left
(1, 2, 6), (6, 5, 1) # Right
(0, 1, 2),
(2, 3, 0), # Bottom
(4, 5, 6),
(6, 7, 4), # Top
(0, 1, 5),
(5, 4, 0), # Front
(2, 3, 7),
(7, 6, 2), # Back
(0, 3, 7),
(7, 4, 0), # Left
(1, 2, 6),
(6, 5, 1), # Right
]

for tri in indices:
prim.addVertices(*tri)

geom.addPrimitive(prim)
geom_node = GeomNode('cube')
geom_node = GeomNode("cube")
geom_node.addGeom(geom)

cube = NodePath(geom_node)
cube.setTwoSided(True)
return cube

def hue_to_rgb(self, hue):
import colorsys

return colorsys.hsv_to_rgb(hue, 1.0, 1.0)

def add_lighting(self):
# Empty method - we're using only emissive materials
pass


if __name__ == "__main__":
app = CameraSetup()
app.run()
9 changes: 8 additions & 1 deletion audio3d.py
Original file line number Diff line number Diff line change
@@ -1,10 +1,13 @@

from direct.showbase import Audio3DManager

from random import choice

from random import shuffle




class audio3d:
def __init__(self):
self.audio3d = Audio3DManager.Audio3DManager(base.sfxManagerList[0], camera)
Expand All @@ -25,8 +28,10 @@ def __init__(self):

self.audio3d.setDopplerFactor(3)


self.playing_loops = []


def enter(self):
base.task_mgr.add(self.update, "update")

Expand Down Expand Up @@ -67,17 +72,19 @@ def playSfx(self, sfx=None, obj=None, loop=False):
if loop:
self.playing_loops.append(sfx3d)


print("Attached sound to object.")

print(str(obj))

def update(self, task):
self.audio3d.update()


# print(str(self.audio3d.getListenerVelocity()))

return task.cont

def stopLoopingAudio(self):
for s, sound in enumerate(self.playing_loops):
sound.stop()
sound.stop()
119 changes: 119 additions & 0 deletions audioHandler.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,119 @@

import pyaudio
import numpy as np
import threading
import queue
import time




class AudioHandler:
def __init__(self, buffer_size=256, fs=96000):
self.buffer_size = buffer_size
self.fs = fs
self.audio_amplitude = [] # Store amplitudes for analysis
self.stream = None
self.running = False
self.audio_thread = None
self.data_queue = queue.Queue() # Thread-safe queue for audio data

def compute_amplitude(self, data):
"""
Calculate the root mean square (RMS) amplitude of audio data.
"""
return np.sqrt(np.mean(data**2))

def process_audio_eq(self, audio_data):
"""
Example placeholder for EQ processing.
Modify this to apply actual EQ logic.
"""
# Simulating EQ processing (e.g., applying a filter)
return audio_data * 0.5 # Example: Reduce amplitude

def audio_callback(self, in_data, frame_count, time_info, status_flags):
"""
PyAudio callback function for real-time audio capture.
"""
if status_flags:
print(f"Audio callback status: {status_flags}")

try:
# Convert input audio data to NumPy array
audio = np.frombuffer(in_data, dtype=np.int16)
self.data_queue.put(audio) # Send data to the processing queue
except Exception as e:
print(f"Error in audio callback: {e}")

return (None, pyaudio.paContinue)

def start_audio(self):
"""
Initialize and start the audio stream and processing thread.
"""
if self.stream:
print("Audio stream already running.")
return

p = pyaudio.PyAudio()
try:
self.stream = p.open(
format=pyaudio.paInt16,
channels=1,
rate=self.fs,
input=True,
frames_per_buffer=self.buffer_size,
stream_callback=self.audio_callback,
)
self.running = True
self.stream.start_stream()

# Start the EQ processing thread
self.audio_thread = threading.Thread(target=self._process_eq, daemon=True)
self.audio_thread.start()

except Exception as e:
print(f"Failed to start audio stream: {e}")
self.stop_audio()

def _process_eq(self):
"""
EQ processing thread: continuously process audio data from the queue.
"""
while self.running:
try:
# Fetch audio data from the queue
audio_data = self.data_queue.get(
timeout=0.1
) # Timeout prevents deadlock
processed_audio = self.process_audio_eq(audio_data)
amplitude = self.compute_amplitude(processed_audio)
self.audio_amplitude.append(amplitude)

# Log or handle the processed audio/amplitude
print(f"Processed Amplitude: {amplitude}")

except queue.Empty:
# No data available in the queue, avoid busy-waiting
time.sleep(0.01)

def stop_audio(self):
"""
Safely stop the audio stream and processing thread.
"""
if self.stream:
print("Stopping audio stream...")
self.stream.stop_stream()
self.stream.close()
self.stream = None
self.running = False

def cleanup(self):
"""
Clean up audio resources and ensure proper thread termination.
"""
self.stop_audio()
if self.audio_thread and self.audio_thread.is_alive():
self.audio_thread.join() # Wait for thread to finish
print("Audio resources cleaned up.")
Loading

0 comments on commit 2fd9f41

Please sign in to comment.