Creating Hive Animation
3D Voxel Animation Tutorial: Animated Hive
This guide walks you through how to generate a looping 3D voxel animation of a bustling hive using SpatialStudio.
The script creates a detailed honeycomb structure with animated bees buzzing around, producing honey, inside a cubic 3D space, then saves the animation to a .splv
file.
What this script does
- Creates a 3D scene of size 128×128×128
- Builds a hexagonal honeycomb hive with:
- Layered honeycomb cells
- Golden honey dripping effects
- Structural wooden frame
- Animates 12 bees that:
- Buzz around the hive in figure-8 patterns
- Change speed and direction naturally
- Have glowing wing effects
- Runs for 10 seconds at 30 FPS with smooth looping
- Outputs the file
hive.splv
that you can play in your viewer
How it works (simplified)
-
Voxel volume Each frame is a 3D grid filled with RGBA values (
SIZE × SIZE × SIZE × 4
). -
Honeycomb structure The hive is built using hexagonal patterns with golden honey-filled cells and brown wooden framework.
-
Bee animation Each bee follows a unique flight path using sine waves and circular motion to create realistic buzzing patterns.
-
Wing effects Semi-transparent white voxels create the illusion of rapidly beating wings.
-
Honey drips Golden droplets slowly fall from the honeycomb cells, adding dynamic movement.
-
Animation loop A normalized time variable
t
cycles from0 → 2π
, ensuring all motion loops seamlessly. -
Encoding Frames are passed into
splv.Encoder
, which writes them into the.splv
video file.
Try it yourself
Install requirements first:
pip install spatialstudio numpy tqdm
Then copy this script into hive.py
and run:
python hive.py
Full Script
import numpy as np
from spatialstudio import splv
from tqdm import tqdm
# Scene setup
SIZE, FPS, SECONDS = 128, 30, 10
FRAMES = FPS * SECONDS
CENTER_X = CENTER_Y = CENTER_Z = SIZE // 2
OUT_PATH = "../outputs/hive.splv"
# Hive settings
BEE_COUNT = 12
HIVE_WIDTH = 35
HIVE_HEIGHT = 40
CELL_SIZE = 4
def add_voxel(volume, x, y, z, color, alpha=255):
if 0 <= x < SIZE and 0 <= y < SIZE and 0 <= z < SIZE:
volume[x, y, z, :3] = color
volume[x, y, z, 3] = alpha
def generate_honeycomb(volume, cx, cy, cz, t):
# Honeycomb colors
wax_color = (255, 220, 177)
honey_color = (255, 193, 37)
wood_color = (139, 69, 19)
# Generate hexagonal cells
for layer in range(-3, 4):
for row in range(-8, 9):
for col in range(-6, 7):
# Hexagonal pattern offset
offset = (row % 2) * (CELL_SIZE // 2)
cell_x = cx + col * CELL_SIZE + offset
cell_y = cy + row * CELL_SIZE
cell_z = cz + layer * 6
# Skip cells outside hive bounds
if abs(cell_x - cx) > HIVE_WIDTH or abs(cell_y - cy) > HIVE_HEIGHT:
continue
# Generate cell walls
for dx in range(-2, 3):
for dy in range(-2, 3):
if abs(dx) == 2 or abs(dy) == 2: # Cell walls
add_voxel(volume, cell_x + dx, cell_y + dy, cell_z, wax_color)
elif np.random.random() > 0.3: # Honey inside cells
honey_level = int(np.sin(t * 0.5 + col * 0.2 + row * 0.3) * 2)
if dy <= honey_level:
add_voxel(volume, cell_x + dx, cell_y + dy, cell_z, honey_color)
# Wooden frame
frame_thickness = 2
for i in range(-HIVE_WIDTH-5, HIVE_WIDTH+6):
for j in range(frame_thickness):
# Top and bottom frame
add_voxel(volume, cx + i, cy - HIVE_HEIGHT - 5 + j, cz, wood_color)
add_voxel(volume, cx + i, cy + HIVE_HEIGHT + 5 - j, cz, wood_color)
# Side frames
add_voxel(volume, cx - HIVE_WIDTH - 5 + j, cy + i, cz, wood_color)
add_voxel(volume, cx + HIVE_WIDTH + 5 - j, cy + i, cz, wood_color)
def generate_honey_drips(volume, cx, cy, cz, t):
honey_color = (255, 193, 37)
drip_speed = 2
for i in range(8):
drip_x = cx + (i - 4) * 8 + int(np.sin(t + i) * 2)
drip_start_y = cy + HIVE_HEIGHT + 3
drip_length = int(6 + 4 * np.sin(t * 0.8 + i * 0.5))
for j in range(drip_length):
drip_y = drip_start_y - int((t * drip_speed + i * 10) % 20) - j
if drip_y > cy - HIVE_HEIGHT - 20:
add_voxel(volume, drip_x, drip_y, cz, honey_color)
def generate_bee(volume, bx, by, bz, t, bee_id):
# Bee colors
body_color = (255, 215, 0) # Golden yellow
stripe_color = (0, 0, 0) # Black stripes
wing_color = (255, 255, 255) # White wings
# Bee body (elliptical)
for dx in range(-2, 3):
for dy in range(-1, 2):
for dz in range(-3, 4):
if dx*dx + dy*dy*4 + dz*dz <= 8:
# Add black stripes
color = stripe_color if dz % 3 == 0 else body_color
add_voxel(volume, bx + dx, by + dy, bz + dz, color)
# Animated wings
wing_beat = np.sin(t * 15 + bee_id) * 0.5 + 0.5 # Fast wing beating
wing_alpha = int(wing_beat * 150 + 50)
# Wing positions
wing_positions = [(-3, 0, -1), (-3, 0, 1), (3, 0, -1), (3, 0, 1)]
for wx, wy, wz in wing_positions:
for i in range(3):
for j in range(2):
wing_x = bx + wx + int(np.sin(t * 15 + bee_id) * i)
wing_y = by + wy + j
wing_z = bz + wz
add_voxel(volume, wing_x, wing_y, wing_z, wing_color, wing_alpha)
def generate_buzzing_bees(volume, cx, cy, cz, t):
for i in range(BEE_COUNT):
# Each bee follows a unique flight pattern
angle_offset = (i / BEE_COUNT) * 2 * np.pi
radius = 25 + 15 * np.sin(t * 0.8 + i * 0.3)
height_offset = 10 * np.sin(t * 1.2 + i * 0.5)
speed_variation = 1.0 + 0.3 * np.sin(i * 0.7)
# Figure-8 pattern
figure8_x = radius * np.sin(t * speed_variation + angle_offset) * np.cos(t * 0.5 + angle_offset)
figure8_y = height_offset + 8 * np.sin(t * 2 * speed_variation + angle_offset)
figure8_z = radius * np.cos(t * speed_variation + angle_offset) * np.sin(t * 0.5 + angle_offset)
bee_x = int(cx + figure8_x)
bee_y = int(cy + figure8_y)
bee_z = int(cz + figure8_z)
generate_bee(volume, bee_x, bee_y, bee_z, t, i)
def generate_scene(volume, t):
generate_honeycomb(volume, CENTER_X, CENTER_Y, CENTER_Z, t)
generate_honey_drips(volume, CENTER_X, CENTER_Y, CENTER_Z, t)
generate_buzzing_bees(volume, CENTER_X, CENTER_Y, CENTER_Z, t)
# Initialize encoder
enc = splv.Encoder(SIZE, SIZE, SIZE, framerate=FPS, outputPath=OUT_PATH, motionVectors="off")
# Generate animation frames
for frame in tqdm(range(FRAMES), desc="Generating hive animation"):
volume = np.zeros((SIZE, SIZE, SIZE, 4), dtype=np.uint8)
t = (frame / FRAMES) * 2 * np.pi
generate_scene(volume, t)
enc.encode(splv.Frame(volume, lrAxis="x", udAxis="y", fbAxis="z"))
enc.finish()
print(f"Created {OUT_PATH}")
Next steps
- Increase
BEE_COUNT
to create a more bustling hive. - Modify
HIVE_WIDTH
andHIVE_HEIGHT
to change the hive size. - Add more honey drip points by increasing the range in
generate_honey_drips()
. - Experiment with different flight patterns by adjusting the figure-8 mathematics.
- Change the
honey_color
andwax_color
to create different hive varieties. - Add sound effects timing by noting the
t
values for wing beats and bee positions.