1. Introduction
This tutorial covers the implementation of dynamic object formations in the MiniScript environment with XRXplorer. The goal is to demonstrate the transformation of a set of 3D objects (cubes) from an initial grid structure into a spherical arrangement and back. In doing so, fundamental concepts of 3D graphics programming, such as transformations, time management, and mathematical interpolation, will be explored in depth.
MiniScript is a lightweight scripting language designed for embedded applications. It offers clear syntax and fundamental mathematical functions that are essential for manipulating objects in a 3D environment.
2. Fundamentals of 3D Transformations
In 3D environments, objects are positioned, oriented, and scaled through transformations in space. Each object has a “transformation matrix” that defines its position (translation), rotation, and scale in world space.
- Position (Translation): Describes an object’s location in 3D space (X, Y, Z coordinates).
- Scale: Defines an object’s size along its axes.
- Rotation: Describes an object’s orientation in space.
In XRXplorer these transformations are directly applied using specific commands such as moveObject
and scaleObject
. Understanding whether these commands operate in the global world coordinate system or in a local, hierarchical system (parenting) is crucial. In this case study, we assume that moveObject
positions objects directly in global space.
3. The Concept of Interpolation (Lerp)
To achieve a smooth transition between two states (here: grid formation and sphere formation), linear interpolation (often referred to as “Lerp”) is used. Lerp calculates an intermediate value between two given values based on an interpolation factor, which typically ranges from 0 to 1.
The formula for linear interpolation between two values A and B with a factor t is: Value=Acdot(1−t)+Bcdott
- If t=0, the Value=A.
- If t=1, the Value=B.
- For 0\<t\<1, the Value is proportionally between A and B.
This can be applied to 3D vectors (positions) by interpolating each component (X, Y, Z) separately.
4. Mathematical Foundations of Sphere Distribution
To distribute 100 cubes approximately evenly on the surface of a sphere, a method based on the Golden Angle is used. This is an efficient way to distribute points spirally on a sphere’s surface without requiring complex algorithms for exact sphere packing.
The formulas for the position of a point (x, y, z) on a sphere with radius R for the i-th point (out of N points) are:
- Golden Angle (phi): phi=picdot(3−sqrt5)
- Y-Coordinate: y=1−(i/(N−1))cdot2 (distributes y from 1 to −1)
- Radius in XY-Plane (r_xy): r_xy=sqrt1−y2cdotR
- Angle around the Y-axis (alpha): alpha=phicdoti
- X-Coordinate: x=r_xycdotcos(alpha)
- Z-Coordinate: z=r_xycdotsin(alpha)
These calculations allow the cubes to be placed in an appealing spherical arrangement.
5. Analysis of the MiniScript Code
Let’s now examine the MiniScript code for the “Cube-Sphere Formation Animation” in detail:
numCubes = 100
cubeBaseName = "Cube"
cubeScale = 0.25 // Uniform scaling for all cubes
// Grid Parameters (Start/End Position)
gridSize = 10 // 10x10 Grid
initialSpacing = 0.5 // Spacing between cubes in the grid
gridYPos = 0.5 // Fixed Y-position of the grid
// Sphere Parameters (Target Formation)
sphereRadius = 4 // Radius of the sphere formation
sphereYPos = 2 // Y-position of the sphere formation
// Animation Parameters
animationDuration = 5 // Duration of an animation phase (Grid to Sphere or Sphere to Grid)
animationSpeed = 1 // Overall animation speed
cubeNames = []
for i in range(1, numCubes)
cubeNames.push(cubeBaseName + i)
end for
// Initial scaling of all cubes
for i in range(0, numCubes - 1)
currentCubeName = cubeNames[i]
scaleObject currentCubeName, cubeScale, cubeScale, cubeScale
end for
// Main animation loop for the sphere formation
while true
currentTime = time
// Phase Calculation: Switch between Grid -> Sphere and Sphere -> Grid
// Modulo 2 * animationDuration to divide time into phases
phaseTime = currentTime * animationSpeed % (2 * animationDuration)
// Interpolation factor (from 0 to 1 and back)
// If phaseTime < animationDuration: Grid to Sphere (factor from 0 to 1)
// If phaseTime >= animationDuration: Sphere to Grid (factor from 1 to 0)
interpFactor = 0
if phaseTime < animationDuration then
interpFactor = phaseTime / animationDuration
else
interpFactor = 1 - ((phaseTime - animationDuration) / animationDuration)
end if
for i in range(0, numCubes - 1)
currentCubeName = cubeNames[i]
// 1. Grid Start Position (independent of expansion)
row = floor(i / gridSize)
col = i % gridSize
gridPosX = (col - (gridSize - 1) / 2) * initialSpacing
gridPosZ = (row - (gridSize - 1) / 2) * initialSpacing
// 2. Sphere Target Position
// Even distribution of cubes on a sphere surface
// (Approximation: Fibonacci grid or spiral arrangement on sphere)
// Here, a simple spiral arrangement for 100 points on a sphere
goldenAngle = pi * (3 - sqrt(5)) // Golden angle in radians
y = 1 - (i / (numCubes - 1)) * 2 // Y from 1 to -1
radiusAtY = sqrt(1 - y*y) * sphereRadius
angle = goldenAngle * i
spherePosX = radiusAtY * cos(angle)
spherePosY = y * sphereRadius
spherePosZ = radiusAtY * sin(angle)
// Interpolation between grid and sphere position
// lerp = linear interpolation
finalPosX = gridPosX * (1 - interpFactor) + spherePosX * interpFactor
finalPosY = gridYPos * (1 - interpFactor) + spherePosY * interpFactor
finalPosZ = gridPosZ * (1 - interpFactor) + spherePosZ * interpFactor
moveObject currentCubeName, finalPosX, finalPosY, finalPosZ
end for
end while
5.1. Initialization and Parameters (Lines 1-28)
numCubes
,cubeBaseName
,cubeScale
: Define the number, name prefix, and size of the cubes.gridSize
,initialSpacing
,gridYPos
: Set the dimensions and Y-position of the initial grid formation.gridSize = 10
means a 10×10 grid for 100 cubes.initialSpacing
is the spacing between cubes in the grid.
sphereRadius
,sphereYPos
: Determine the radius and Y-position of the target sphere formation.animationDuration
,animationSpeed
: Control the duration of a single transformation phase (e.g., grid to sphere) and the overall animation speed.- The loops for populating
cubeNames
and for initialscaleObject
application are standard procedures.
5.2. Main Animation Loop and Phase Calculation (Lines 31-44)
while true
: An infinite loop that continuously runs the animation.currentTime = time
: Retrieves the current system time.time
is an intrinsic MiniScript function that returns seconds since program start.phaseTime = currentTime * animationSpeed % (2 * animationDuration)
:currentTime * animationSpeed
: Scales time to control the overall animation speed.% (2 * animationDuration)
: The modulo operator ensures thatphaseTime
always remains in the range of0
to2 * animationDuration
. This divides the animation into recurring cycles (e.g., 0–10 seconds for one cycle ifanimationDuration
is 5).
- Interpolation Factor (
interpFactor
):- This factor controls the transition between the grid and sphere formations.
- If
phaseTime
is less thananimationDuration
(first half of the cycle: grid to sphere),interpFactor
increases linearly from 0 to 1. - If
phaseTime
is greater than or equal toanimationDuration
(second half of the cycle: sphere to grid),interpFactor
decreases linearly from 1 to 0.
5.3. Position Calculation for Grid and Sphere (Lines 46-70)
Within the for
loop for each cube, two target positions are calculated:
- Grid Position (
gridPosX
,gridPosZ
):row = floor(i / gridSize)
andcol = i % gridSize
: Calculate the row and column of the current cube in the grid.- The formulas
(col - (gridSize - 1) / 2) * initialSpacing
and(row - (gridSize - 1) / 2) * initialSpacing
center the grid around the origin (0,0) of the XZ plane.
- Sphere Position (
spherePosX
,spherePosY
,spherePosZ
):goldenAngle = pi * (3 - sqrt(5))
: Defines the Golden Angle for spiral distribution.y = 1 - (i / (numCubes - 1)) * 2
: Calculates the Y-coordinate of the point on the sphere, distributed linearly from 1 to -1 over the number of cubes.radiusAtY = sqrt(1 - y*y) * sphereRadius
: Calculates the radius of the circle on the Y-plane, used for the XZ position of the point on the sphere.angle = goldenAngle * i
: Calculates the angle around the Y-axis for the current point in the spiral.spherePosX = radiusAtY * cos(angle)
andspherePosZ = radiusAtY * sin(angle)
: Calculate the X and Z coordinates on the circle at the respective Y-plane.spherePosY = y * sphereRadius
: Scales the Y-coordinate to the sphere radius.
5.4. Interpolation and Application of Transformation (Lines 72-78)
finalPosX = gridPosX * (1 - interpFactor) + spherePosX * interpFactor
(and similarly for Y and Z):- This is the application of linear interpolation. The final position of each cube is a blend of its grid position and its sphere position, controlled by the
interpFactor
. - Note that
finalPosY
is also interpolated betweengridYPos
andspherePosY
to control the Y-transition.
- This is the application of linear interpolation. The final position of each cube is a blend of its grid position and its sphere position, controlled by the
moveObject currentCubeName, finalPosX, finalPosY, finalPosZ
: Moves the cube to the calculated interpolated position.
6. Implementation and Customization
- Galaxies Preparation: Ensure that 100 cubes are present in your scene and are named exactly from
Cube1
toCube100
. Their initial position is not critical for this script, as they will be immediately repositioned. - Insert Script: Copy the entire MiniScript code into the designated editor of your galaxy.
- Parameter Adjustment: Experiment with the values of the variables in the upper section of the script (
gridSize
,initialSpacing
,sphereRadius
,animationDuration
,animationSpeed
). SmalleranimationDuration
values lead to faster transitions, higher values to slower ones. - Execution: Start the script in your galaxy. The cubes should now continuously move between the grid and sphere formations.
7. Conclusion
This tutorial has demonstrated how complex dynamic object formations can be realized in MiniScript by combining mathematical principles (sine, cosine, Golden Angle) and the concept of linear interpolation. Such effects can be achieved through precise mathematical calculations in global space. Understanding the underlying algorithms is crucial for creating compelling and dynamic 3D scenes.
8. Download
data string: formation.txt