in the previous tutorial, you successfully created your first spatial - a simple red cube moving through 3d space. now it's time to unlock the full potential of spatialstudio by exploring its powerful api in greater depth.
you now have example.splv
from our previous tutorial - a basic but complete spatial video. today, we'll create something far more intricate and learn the techniques professional developers use to craft compelling voxel content.
the frame
object is the heart of spatialstudio. think of each frame as a 3d canvas where you paint voxels to create a single moment in your 4d video. understanding how to manipulate frames efficiently is crucial for creating complex spatial content.
a frame
represents a single 3d voxel snapshot with defined width, height, and depth dimensions. it's your building block for creating spatial videos:
from spatialstudio import splv
# Create a frame with specific dimensions
w, h, d = 128, 128, 128
frame = splv.Frame(w, h, d)
let's explore the most important methods for manipulating voxels within frames:
# Set a single voxel at coordinates (x, y, z)
frame.set_voxel(64, 64, 64, voxel=(255, 128, 0)) # Orange voxel
# Get the color of a voxel at specific coordinates
color = frame.get_voxel(64, 64, 64)
print(f"Voxel color: {color}") # Returns (255, 128, 0)
the fill
method is your primary tool for creating larger voxel structures:
# Fill a rectangular region with voxels
frame.fill(xMin, yMin, zMin, xMax, yMax, zMax, voxel=(r, g, b))
# Example: Create a blue wall
frame.fill(10, 50, 10, 15, 80, 40, voxel=(0, 100, 255))
let's put these methods to work by creating a frame with multiple colored objects:
# Create a complex scene in a single frame
frame = splv.Frame(128, 128, 128)
# Add a red floor
frame.fill(0, 0, 0, 128, 5, 128, voxel=(150, 50, 50))
# Add a blue pillar
frame.fill(30, 5, 30, 40, 60, 40, voxel=(50, 50, 200))
# Add a green cube floating above
frame.fill(70, 40, 70, 90, 60, 90, voxel=(50, 200, 50))
# Add individual yellow accent voxels
for i in range(0, 128, 16):
frame.set_voxel(i, 65, 64, voxel=(255, 255, 0))
now let's create a sophisticated spatial that demonstrates advanced techniques. we'll build an animation featuring two objects with different movement patterns and color evolution:
from spatialstudio import splv
import math
# Set up our voxel space
w = h = d = 128
enc = splv.Encoder(w, h, d, framerate=30.0, outputPath="complex_animation.splv")
# Generate 150 frames (5 seconds at 30fps)
for frame_num in range(150):
# Create a new frame
f = splv.Frame(w, h, d)
# Calculate animation progress (0.0 to 1.0)
progress = frame_num / 149.0
# Animated red cube - moves in a sine wave pattern
red_x = int(20 + 60 * progress) # Move horizontally
red_y = int(40 + 20 * math.sin(progress * math.pi * 4)) # Sine wave vertically
red_z = int(30 + 30 * math.sin(progress * math.pi * 2)) # Different sine wave in Z
# Color shifts from bright red to dark red over time
red_intensity = int(255 - 100 * progress)
f.fill(red_x, red_y, red_z, red_x + 15, red_y + 15, red_z + 15,
voxel=(red_intensity, 0, 0))
# Animated blue cube - moves in opposite direction with rotation effect
blue_x = int(88 - 60 * progress) # Move in opposite direction
blue_y = int(60 + 15 * math.cos(progress * math.pi * 6)) # Cosine wave
blue_z = int(50 + 40 * math.cos(progress * math.pi * 3)) # Different frequency
# Color evolves from blue to cyan
blue_green = int(100 * progress)
f.fill(blue_x, blue_y, blue_z, blue_x + 12, blue_y + 12, blue_z + 12,
voxel=(0, blue_green, 255))
# Add a static green base that grows over time
base_height = int(5 + 15 * progress)
f.fill(50, 0, 50, 78, base_height, 78, voxel=(0, 150, 0))
# Add sparkle effect - random yellow voxels
if frame_num % 5 == 0: # Every 5th frame
for _ in range(8):
spark_x = int(20 + 88 * (frame_num * 0.1) % 1.0)
spark_y = int(80 + 20 * math.sin(frame_num * 0.3))
spark_z = int(20 + 88 * (frame_num * 0.07) % 1.0)
f.set_voxel(spark_x, spark_y, spark_z, voxel=(255, 255, 100))
# Encode this frame
enc.encode(f)
# Finalize the animation
enc.finish()
print("Complex animation saved as 'complex_animation.splv'")
this example demonstrates several sophisticated techniques:
math.sin()
and math.cos()
to create smooth, natural-looking motionprogress
variablethe encoder
class offers powerful configuration options beyond the basic parameters we've used. while the defaults work well for most projects, understanding these options gives you professional-level control:
# Standard encoder setup
enc = splv.Encoder(
width=128,
height=128,
depth=128,
framerate=30.0,
outputPath="output.splv"
)
# Advanced encoder with optional parameters
enc = splv.Encoder(
width=128, height=128, depth=128,
framerate=30.0,
outputPath="advanced_output.splv",
# Advanced compression settings
gopSize=30, # Group of Pictures size for compression
motionVectors=True, # Enable motion vector compression
vqMaxCentroids=256, # Vector quantization settings
)
after running the complex animation script, you now have complex_animation.splv
- a sophisticated 5-second spatial featuring:
from today's exploration, here are key techniques to remember:
fill()
for efficiency - it's much faster than setting individual voxels for large structuressin()
, cos()
, and other math functions create natural motionyou've now mastered the fundamentals of creating sophisticated spatial content with spatialstudio! you can generate complex voxel animations with multiple objects, advanced movement patterns, and visual effects.
in our next tutorial, "viewing spatials on the web with spatialjs", we'll shift gears and learn how to display your amazing voxel creations on the web. you'll discover how to embed spatial players in websites, control playback through javascript, and share your 4d voxel videos with the world through interactive web experiences.