Mob¶
Qualified name: algan.animatable\_base.mob.Mob
- class Mob(location=tensor([0., 0., 0.]), basis=tensor([1., 0., 0., 0., 1., 0., 0., 0., 1.]), color=None, opacity=1, glow=0, **kwargs)[source]¶
Bases:
MobHierarchyMixin,MobOrientationMixin,MobMovementMixin,MobLayoutMixin,MobMorphMixin,MobMaterialsMixin,AnimatableA Movable Object: an Animatable that exists at a point in 3-D space.
Mobs carry the animatable attributes
location,basis(orientation and scale),scale_coefficient,color,opacityandglow– assigning to any of them records an animation. Mobs can have child Mobs, forming a hierarchy, and a change to a parent propagates to its descendants.- Parameters:
location (torch.Tensor) – Initial location in 3-D world space, in world units. Defaults to
ORIGIN(the centre of the scene). Shape: (*, 3) where * denotes zero or more batch dimensions.basis (torch.Tensor) – The Mob’s orientation and scale, as a 3x3 matrix. The rows are the right, upwards and forwards directions, and each row’s norm is the scale along that direction. Accepts either the
(*, 3, 3)matrix or the(*, 9)flattened form it is stored in. Defaults to an identity matrix (no rotation, unit scale).color (Color | None) – The color of the Mob: an Algan
Color, a named constant such asBLUE, or anythingColor()accepts. Defaults toNone, meaning the class’s own default fromget_default_color()–BLACKfor a plain Mob,PURPLEfor a 2-D shape,GREENfor aSurface.opacity (float) – How opaque the Mob is, from
0(invisible) to1(fully opaque). Defaults to1.glow (float) – How much light the Mob emits of its own, on top of what it reflects.
0is an ordinary unlit surface and1a strongly glowing one; larger values keep brightening. Defaults to0.**kwargs – Passed to
Animatable– notablysceneandadd_to_scene.
- two_sided, closed_shell, casts_shadows, receives_shadows
Plain (non-animatable) geometry declarations, documented individually below. All four are read once when the Mob is spawned, so they must be set before
spawn().
Examples
Create a square and move it to the left:
Example: Example1Mob ¶
from algan import * square = Square().spawn() square.move(LEFT) Scene.save_video()
Create a mob with a specific color and scale:
Example: Example2Mob ¶
from algan import * circle = Circle(color=BLUE).scale(2).spawn() Scene.save_video()
Methods
Transform any Mob hierarchy into any other Mob hierarchy.
Remove the Mob from the video.
Hand this Mob's recorded animation to a hidden clone and start fresh.
Get the Mob's surface normal, i.e. the way it faces.
Flatten this Mob's hierarchy into a list.
Animate an attribute to a function of its own current value, across this Mob and every descendant at once.
Move the Mob by a displacement from wherever it currently is.
Move the Mob to an absolute location.
Play this Mob's spawn-in animation: a fade from transparent.
Play this Mob's despawn animation: a fade to transparent.
The child subtrees this Mob built for itself, when it aggregates.
Flash the Mob a different color and let it settle back.
Clear this Mob's recorded spawn so it counts as never spawned.
Rotate the Mob about an axis, optionally around a point in space.
Resize the Mob relative to its current size.
Set several animatable attributes at once, as one animation.
Animate one animatable attribute to a new value, by name.
Set the Mob's location, with control over whether children follow.
Set attributes on this Mob only, leaving its children untouched.
Fade the Mob by writing opacity into its color rather than its opacity.
Set the Mob's absolute scale, ignoring its current size.
Bring the Mob into the video.
Send a color pulse travelling across the Mob.
Attributes
animation_managerThis mob's scene-owned animation manager.
The Mob's orientation and scale, as a flattened 3x3 matrix of shape
(*, 9).Whether this Mob's geometry blocks light on its way from a light source to another surface -- whether it casts a shadow.
The Mobs attached below this one, in attachment order.
Whether this Mob's triangles form a CLOSED shell -- every camera ray that enters the geometry crosses a second time on its way out.
Whether
get_render_primitivesreturns geometry belonging to this Mob's DESCENDANTS as well as its own.forwardGet the direction the Mob is facing.
lifespanThis mob's [spawn, despawn) interval on its Scene timeline (a
Lifespan).The Mob's position in world space, shape
(*, 3).The Mob's orientation with scale divided out, shape
(*, 9).The Mobs this one is attached to, in attachment order.
Whether this Mob's surfaces are darkened by shadows cast onto them.
rightGet the Mob's own rightward direction.
The Mob's scale along its own right, up and forward axes, shape
(*, 3).Whether this Mob's geometry should be lit from whichever side the ray arrives on.
upGet the Mob's own upward direction.
xThe Mob's x coordinate in world units, shape
(*, 1).xyThe Mob's x and y coordinates in world units, shape
(*, 2).yThe Mob's y coordinate in world units, shape
(*, 1).zThe Mob's z coordinate in world units, shape
(*, 1).- property basis: Tensor¶
The Mob’s orientation and scale, as a flattened 3x3 matrix of shape
(*, 9).Unflattened, the three rows are the Mob’s own right, upward and forward directions in world space, and each row’s norm is the Mob’s scale along that axis. The identity matrix therefore means unrotated at unit scale.
Assigning to this animates the Mob to the new basis over the current context’s runtime (1 second by default), rotating and scaling its children with it. Concurrent writes compose rather than overwrite, so a rotate and a scale inside one
Syncboth take effect.
- become(other_mob, *, detach_history=True, minimize_movement=False, strategy='auto')¶
Transform any Mob hierarchy into any other Mob hierarchy.
Structural containers are transparent to pairing: renderer-facing primitives are matched by concrete type, primitive family and either traversal order or spatial proximity. Same-kind pairs use structural point alignment and different primitive families convert through a cubic-PN triangle soup. ImageMob pairs cross-dissolve because image textures have no geometric adapter, and so does a pair that changes whether a circuit is filled: that flag is read once per render rather than per frame, so no morph can show it changing. The pairing prefers a counterpart that does not force the change.
strategymay be"auto","morph"(reject every non-geometric pair), or"dissolve"(dissolve the whole root).With the default
detach_history=True, the returned Mob has the target’s hierarchy and is spliced into this Mob’s parent slot; use it for later animation. Surplus target primitives fade in as they grow from collapsed, target-shaped geometry at nearby source points, while surplus sources fade out as they shrink to points.detach_history=Falsekeeps identity for compatibility and therefore uses a dissolve where a target-class replacement would be required. Updaters remain attached to replaced sources rather than being migrated to replacements.Notes
Cross-kind geometric morphs pair independent PN triangles, so a surface can show seams while triangles move to new counterparts. Bezier outlines are triangulated at the primitive-family swap, making the silhouette at that instant an approximation. A mesh-to-bezier morph likewise travels through the target’s filled triangulation rather than growing cubic curves. Cached glyph views held before a cross-kind replacement remain views of the replaced source; reacquire them from the returned Mob when it is text.
- casts_shadows = True¶
Whether this Mob’s geometry blocks light on its way from a light source to another surface – whether it casts a shadow.
True(the default) is what every Mob did before the flag existed.Falsemakes the geometry invisible to shadow rays ONLY: it still renders to the camera, to reflections and to refraction exactly as it would have, and it still RECEIVES shadows unlessreceives_shadowssays otherwise.This is the per-Mob half of
SETTINGS.raytracing.shadows, which remains the switch for the feature as a whole – with shadows off globally, neither flag does anything. Use it where a shadow is physically implied but pedagogically in the way: a label plate lying on the scene’s floor, a wireframe cage around the object being explained, an annotation arrow whose shadow reads as a second arrow.Like
two_sided, set it before the Mob is spawned – the render primitive reads it once – and note that it is a plain attribute, not an animatable one: it cannot change over the course of a render.
- closed_shell = False¶
Whether this Mob’s triangles form a CLOSED shell – every camera ray that enters the geometry crosses a second time on its way out.
False(the default) leavesopacitycompositing once per crossing, which is right for anything open or unprovable: a 2-D shape, an uncappedCone, a partial sphere, user polyhedron geometry whose closedness cannot be proven.On a closed shell, one attenuation of what is behind it IS the documented meaning of
Mob.opacity– rendering at opacityamust givea * (the Mob rendered opaque) + (1 - a) * backdrop– so the renderer caps the shell’s total coverage per pixel instead of letting both shells composite (the far sheet would otherwise deliver the extraa * (1 - a)of coverage painted with the interior’s own shading). The built-in solids declare it; seetests/unit_tests/test_closed_shell_declaration.pyfor the proof that each declaration matches the geometry. Liketwo_sided, set it before the Mob is spawned: the render primitive reads it once.Known limit: the rule reaches PRIMARY visibility only. A REFLECTION of a half-transparent solid – its image in a mirror – still composites both shells and so reads more opaque than the authored value, because the bounce loop that shades reflections carries no surface identity. The same is true of any render at
samples_per_pixel > 1, which routes to the Monte Carlo tracer instead.
- despawn(animate=True)¶
Remove the Mob from the video.
The Mob stops being drawn from this point on, but the animation already recorded for it is untouched – everything it did before still plays. A despawned Mob cannot be brought back; clone it before despawning if you need it again later.
Despawning is recursive: children despawn with their parent. Despawning a Mob that is already despawned does nothing.
Animation
Recorded as an animation over the current context’s runtime (1 second by default): the Mob fades out.
despawn(animate=False)removes it instantly, which is what you want for something already off-screen.- Parameters:
animate (bool) – Whether to play the exit animation, by default a fade-out (see
on_destroy()). Defaults to True.- Returns:
This object, so calls can be chained.
- Return type:
- detach_history()[source]¶
Hand this Mob’s recorded animation to a hidden clone and start fresh.
The animation recorded so far keeps playing – it now belongs to a clone that despawns at this moment – while this Mob continues with a clean history from here. Use it before a change that cannot be interpolated from the old value, because the two states have different shapes: for example raising a
Surface’s resolution, or abecomebetween Mobs with different numbers of parts. Without detaching, the render-time replay tries to interpolate mismatched shapes and raises.Animation
Not animated: the swap happens instantly, inside
Off(), and the viewer sees no discontinuity. Everything recorded afterwards animates from the Mob’s state at this moment.- Returns:
This Mob, so calls can be chained.
- Return type:
- draws_descendants = False¶
Whether
get_render_primitivesreturns geometry belonging to this Mob’s DESCENDANTS as well as its own. Almost nothing does: aBezierCircuitCubicor aSurfacedraws its own rows and leaves its children to draw themselves.Polyhedronis the exception – it gathers every face under one_mesh_key– and the difference decides two things forbecome(): whether the Mob is one morph unit or several, and whether a descendant may be published to the Scene in its own right (doing so under an aggregator draws it twice, and draws geometry the aggregator deliberately omits, such as a Polyhedron’s vertex-and-edge graph).
- get_normal()[source]¶
Get the Mob’s surface normal, i.e. the way it faces.
An alias for
get_forward_direction(), named for the 2-D case: a flat shape’s normal is the direction it faces out of its own plane.- Returns:
Unit normal, shape
(*, 3).- Return type:
torch.Tensor
- get_parts_as_mobs()[source]¶
Flatten this Mob’s hierarchy into a list.
- Returns:
This Mob followed by every descendant, depth-first. The Mobs are the live objects, not copies, so changing one changes the scene.
- Return type:
list[
Mob]
- property location: Tensor¶
The Mob’s position in world space, shape
(*, 3).Assigning to this animates the Mob to the new position over the current context’s runtime (1 second by default), carrying its children along so their offsets from it are preserved.
mob.location = ORIGINandmob.move_to(ORIGIN)are the same operation.This is also the point the Mob turns and scales about, so a shape is anchored at its own centroid – the point it balances on, which for a
Triangleis a quarter of a unit below the middle of the box around it.get_center()reports that box’s midpoint instead, when what you want is the middle of what the viewer sees rather than the point it pivots on.
- map_animated_attribute(attr, func)[source]¶
Animate an attribute to a function of its own current value, across this Mob and every descendant at once.
set_animated_attribute()animates towards a value you supply. This animates towards a value derived from what each part already has, which is what you want for “half as bright as it is now” or “everything a quarter of its current size” – operations where each part has a different starting point and a different target.funcreceives every affected value stacked into one tensor of shape(1, N, D), whereNcounts the rows this Mob and its descendants own forattrandDis the attribute’s width (1 foropacity, 3 forlocation, 4 forcolor). It must return a tensor of that same shape – the target values, in the same order.Reach for it instead of a Python loop over
get_descendants(). A loop records one animation per descendant, which on a large group is thousands of separate recorded animations; this records one, and renders measurably faster for it.Animation
Recorded as an animation: every affected value moves from what it is now to its target over the current context’s runtime (1 second by default), all together inside a
Sync.funcis evaluated once, at the moment of the call – it computes the destination, it is not re-run per frame. For a value that must be recomputed every frame, useadd_updater()instead. Only spawned Mobs record; a Mob whose subtree is not on screen is changed immediately and silently.- Parameters:
attr (str) – Name of the animatable attribute, e.g.
"opacity","color","location","glow". It has to be one whose whole meaning is its per-row value, and two kinds are not, so both are rejected rather than silently half-applied. A derived property (scale_coefficient, the row norms ofbasis;Circle.radius;stroke_color) has no rows at all. A hierarchical one (basis) has rows, but they are only half the operation: a rotation or a scale has to carry the subtree’s locations along, which is whyrotate(),scale()and plain assignment are what change those.func (Callable) – Callable mapping the stacked current values to the stacked target values, both of shape
(1, N, D). It is passed a copy, so it may modify its argument in place and return it.
- Returns:
This Mob, so calls can be chained.
- Return type:
- Raises:
ValueError – If
funcreturns a tensor whose shape is not the shape it was given.AttributeError – If
attris not an animatable attribute of this Mob, or is a derived or hierarchical one that cannot be mapped row-wise.AlganConfigurationError – If
funcreturns a NaN or an infinity for any row, or a value outside[0, 1]whenattris"opacity". Both are checked on the targetfunccomputed, at this line: the target is what every later frame interpolates towards, and a bad one renders as a blank or missing shape rather than raising.
See also
set_animated_attribute()Animate an attribute to a value you supply, rather than to a function of the current one.
add_updater()Recompute a value every frame instead of once.
Examples
Example: Example1MobMapAnimatedAttribute ¶
from algan import * row = Group([Square().move(LEFT * 2), Circle(), Triangle().move(RIGHT * 2)]) row.spawn() # Dim everything to a tenth of however visible it already is, # then pull every point halfway in towards the world origin. row.map_animated_attribute('opacity', lambda o: o * 0.1) row.map_animated_attribute('location', lambda p: p * 0.5) Scene.save_video()
- move(displacement, **kwargs)¶
Move the Mob by a displacement from wherever it currently is.
Animation
Recorded as an animation: the Mob travels the displacement over the current context’s runtime (1 second by default). Retime it with
with Seq(runtime=2): mob.move(RIGHT), or apply it instantly withwith Off(): mob.move(RIGHT). Applies to this Mob and its descendants.- Parameters:
displacement (torch.Tensor) – How far and in which direction to move, shape
(*, 3), in world units. The spatial constants (RIGHT,UP,OUT, …) are unit vectors, somob.move(RIGHT * 3)moves three units right.**kwargs – Passed to
move_to()– notablyarc_angleto travel along a curve rather than a straight line.
- Returns:
This Mob, so calls can be chained.
- Return type:
Examples
Example: Example1MobMove ¶
from algan import * square = Square().spawn() square.move(RIGHT) square.move(UP * 2 + LEFT) square.move(DOWN, arc_angle=120) Scene.save_video()
- move_to(location, arc_angle=None, **kwargs)¶
Move the Mob to an absolute location.
The path is a straight line unless
arc_angleis given, in which case the Mob swings to the target along a circular arc.Animation
Recorded as an animation: the Mob travels from where it is to
locationover the current context’s runtime (1 second by default). Usewith Off(): mob.move_to(...)to teleport it instead. Applies to this Mob and its descendants.- Parameters:
location (torch.Tensor) – The target location, shape
(*, 3).arc_angle (float | None) – Signed sweep of the curved path, in degrees. Defaults to
None, meaning travel in a straight line.**kwargs – Passed to
set_location()(notablyrecursive), or tomove_to_point_along_arc()whenarc_angleis given (notablyarc_normal).
- Returns:
This Mob, so calls can be chained.
- Return type:
See also
move()Move by a relative displacement instead.
move_to_screen_position()Place the Mob in screen space.
- property normalized_basis: Tensor¶
The Mob’s orientation with scale divided out, shape
(*, 9).The same matrix as
basiswith every row normalized to unit length, so it carries the Mob’s rotation and nothing else. Read-only.
- on_create()[source]¶
Play this Mob’s spawn-in animation: a fade from transparent.
Called by
spawn()whenanimate=True. Override it in a subclass to give a Mob its own entrance; the override should record its animation the same way, and is free to ignore opacity entirely.Animation
Recorded as an animation over the current context’s runtime (1 second by default). The opacity write is non-recursive, so descendants run their own
on_create.
- on_destroy()[source]¶
Play this Mob’s despawn animation: a fade to transparent.
Called by
despawn()whenanimate=True. Override it in a subclass to give a Mob its own exit.Animation
Recorded as an animation over the current context’s runtime (1 second by default).
- owned_subtrees()[source]¶
The child subtrees this Mob built for itself, when it aggregates.
Only consulted when
draws_descendantsis set, and it narrows that claim: a Polyhedron speaks for the faces it draws and the vertex-and-edge graph it deliberately does not, but not for a child a user hung on it afterwards. Without the distinction, a morph into a Polyhedron carrying user geometry withheld that geometry from the Scene and it vanished. Returning an empty list means “everything below me”.- Return type:
list
- pulse_color(color=None, opacity=None, recursive=True, new_color=None)[source]¶
Flash the Mob a different color and let it settle back.
A two-stage animation: the color travels out to
colorby the halfway point and back tonew_colorby the end. Good for drawing the eye to one part of a diagram without leaving it recolored.Animation
Recorded as an animation over the current context’s runtime (1 second by default), with the peak of the pulse at the halfway mark. Color and opacity pulses run together inside a
Sync.- Parameters:
color (Tensor) – Color to pulse to. Defaults to
None, which pulses only the opacity (so pass at least one ofcolorandopacity).opacity (bool) – Alpha to hold for both stages of the pulse,
0to1. Defaults toNone, leaving opacity alone.recursive – Whether descendants pulse too. Defaults to True.
new_color – Color to end on. Defaults to
None, meaning every affected part returns to its own current color.
- Returns:
This Mob, so calls can be chained.
- Return type:
See also
wave_color()Run the same pulse across the Mob as a travelling wave.
- receives_shadows = True¶
Whether this Mob’s surfaces are darkened by shadows cast onto them.
True(the default) is what every Mob did before the flag existed.Falseshades the Mob as though every light reached it unobstructed, which is strictly cheaper than the default: no shadow ray is traced for its fragments at all.It does not change what the Mob does to OTHER surfaces – a Mob that receives no shadow still casts one unless
casts_shadowssays otherwise. Use it to keep a surface legible where a correct shadow would not be: a caption laid on a shadowed floor, a color key or legend that has to stay readable wherever it is placed.Set it before the Mob is spawned, and like
casts_shadowsit is a plain attribute rather than an animatable one.Two kinds of Mob ignore it, both because they were never shadowed to begin with: 2-D geometry (a shape,
Text) renders unlit, and so does anything withset_shader()None. A Mob carrying a custom fragment pipeline (set_fragment_shader()) also ignores it, because the slot this rides in the material block belongs to that pipeline’s own parameters – the same reason a custom pipeline is never asked abouttwo_sided.casts_shadowshas none of these exceptions: all three still cast.
- refresh_history()[source]¶
Clear this Mob’s recorded spawn so it counts as never spawned.
Resets the lifespan of this Mob and every descendant, which makes them behave as if freshly constructed. Mostly useful as part of
detach_history(); calling it on a live Mob leaves the Mob visible in already-recorded animation while claiming it was never spawned, so reach for it only if you know you want that.Animation
Not animated and not recorded. Takes effect immediately on the timeline.
- rotate(angle, axis=tensor([0., 0., 1.]), about=None, *, degrees=True)¶
Rotate the Mob about an axis, optionally around a point in space.
With the default
about=Noneonly the Mob’s orientation changes and it stays where it is. Given anaboutpoint, the Mob also travels around the axis through that point, like a planet spinning as it orbits. To move around a point without re-orienting the Mob, useorbit().Animation
Recorded as an animation: the rotation sweeps from 0 to
angleover the current context’s runtime (1 second by default), so the Mob turns rather than snapping. Retime it withwith Seq(runtime=3): mob.rotate(90), or apply it instantly withwith Off(): mob.rotate(90). Applies to this Mob and its descendants.- Parameters:
angle (float | torch.Tensor) – How far to rotate, counter-clockwise when looking down
axis, in degrees unlessdegreesis False. Accepts a tensor of shape(*, 1)to give each Mob of a batch its own angle.axis (torch.Tensor) – Axis to rotate around; need not be normalized. Defaults to
OUTWARD(the +z axis, pointing out of the screen), which spins a flat 2-D shape in the screen plane.about (torch.Tensor | None) – Point to rotate around, shape
(*, 3). Defaults toNone, meaning rotate in place about the Mob’s ownlocation, which for a shape is its centroid.degrees (bool) – Whether
angleis in degrees. Defaults to True; pass False to give it in radians.
- Returns:
This Mob, so calls can be chained.
- Return type:
Examples
Example: Example1MobRotate ¶
from algan import * square = Square().spawn() square.rotate(90) square.rotate(180, axis=UP) square.rotate(90, about=RIGHT * 2) Scene.save_video()
- scale(scale_factor, recursive=True)[source]¶
Resize the Mob relative to its current size.
The factor multiplies the size the Mob has now, so two calls to
scale(2)leave it four times its original size. For an absolute target, useset_scale().Animation
Recorded as an animation: the Mob grows or shrinks over the current context’s runtime (1 second by default).
- Parameters:
scale_factor (float | Tensor) – Multiplier on the current size:
2for twice as big,0.5for half. A tensor of shape(*, 3)scales the Mob’s right, up and forward axes separately, which is how you stretch a shape.recursive (bool) – Whether descendants scale too, keeping the Mob’s proportions. Defaults to True; False scales this Mob alone, so a Group’s children keep their own sizes.
- Returns:
This Mob, so calls can be chained.
- Return type:
- property scale_coefficient: Tensor¶
The Mob’s scale along its own right, up and forward axes, shape
(*, 3).Derived from
basisas the norm of each of its rows, so(1, 1, 1)is unscaled. Assigning to this resizes the Mob without rotating it, animated over the current context’s runtime (1 second by default);scale()andset_scale()are the usual way to do that. Note thatscaleis a method (scale()), not an attribute – assigning to it raises.
- set(**kwargs)[source]¶
Set several animatable attributes at once, as one animation.
The attributes change together rather than one after another, which is what you want for a single visual beat:
mob.set(location=RIGHT, color=BLUE)slides and recolors in the same second, where two separate statements would take two seconds inside aSeq.Animation
Recorded as an animation: all the writes go into one
Syncspanning the current context’s runtime (1 second by default). Changes propagate to descendants; useset_non_recursive()if they should not.- Parameters:
**kwargs – Animatable attribute names and their target values, e.g.
location,color,opacity,glow,scale_coefficient.- Returns:
This Mob, so calls can be chained.
- Return type:
- Raises:
AttributeError – If a name is not an animatable attribute of this Mob. The message lists the ones that are.
Examples
Move a square to the right and change its color to blue:
Example: Example1MobSet ¶
from algan import * mob = Square().spawn() mob.set(location=ORIGIN+RIGHT, color=BLUE) Scene.save_video()
- set_animated_attribute(attr, value, recursive=True)[source]¶
Animate one animatable attribute to a new value, by name.
The by-name equivalent of assigning to the attribute; useful when the attribute is chosen at runtime. To set several at once, use
set(). Attributes whose write is more than a row write – derived ones (scale_coefficient,Circle.radius,stroke_color) andbasis, which carries the subtree’s locations with it – are handed to their property setter, so every name behaves exactly as the assignment would.Animation
Recorded as an animation: the attribute interpolates from its current value to
valueover the current context’s runtime (1 second by default).- Parameters:
attr (str) – Name of the animatable attribute, e.g.
"location","color","opacity".value – Target value. Must be broadcastable against the attribute’s current shape.
recursive (bool) – Whether the change propagates to descendants. Defaults to True.
- Returns:
This Mob, so calls can be chained.
- Return type:
- set_location(location, recursive=True)[source]¶
Set the Mob’s location, with control over whether children follow.
Same as
move_to()without the arc option; the reason to reach for this one isrecursive=False.Animation
Recorded as an animation over the current context’s runtime (1 second by default).
- Parameters:
location (Tensor) – The target location, shape
(*, 3).recursive (bool) – Whether children move along, keeping their offsets from this Mob. Defaults to True; False moves only this Mob, leaving its children behind.
- Returns:
This Mob, so calls can be chained.
- Return type:
- set_non_recursive(**kwargs)[source]¶
Set attributes on this Mob only, leaving its children untouched.
The non-propagating counterpart of
set(). Use it when a parent’s own value should change while its children keep theirs – for instance recoloring a Group’s frame without recoloring its contents.Animation
Recorded as an animation: every attribute given moves to its new value together inside a
Sync, over the current context’s runtime (1 second by default).- Parameters:
**kwargs – Animatable attribute names and their target values, e.g.
mob.set_non_recursive(color=BLUE, opacity=0.5).- Returns:
This Mob, so calls can be chained.
- Return type:
- set_opacity_via_color(opacity)[source]¶
Fade the Mob by writing opacity into its color rather than its opacity.
Each descendant’s own color gets the given alpha, which fades parts that carry their own colors without a parent-level opacity write flattening them. Prefer setting
opacityfor ordinary fades; this exists for composites where per-part color must be preserved.Animation
Recorded as an animation. All descendants fade together inside a
Sync, over the current context’s runtime (1 second by default).- Parameters:
opacity (float | Tensor) – Target alpha,
0for fully transparent to1for fully opaque.- Returns:
This Mob, so calls can be chained.
- Return type:
- set_scale(scale, recursive=True)[source]¶
Set the Mob’s absolute scale, ignoring its current size.
set_scale(1)returns the Mob to the size it was built at, whatever scaling has happened since. For a relative change, usescale().Animation
Recorded as an animation over the current context’s runtime (1 second by default).
- Parameters:
scale (float | Tensor) – Target scale, where
1is the Mob’s construction size. A tensor of shape(*, 3)sets the Mob’s right, up and forward axes separately.recursive (bool) – Whether descendants are scaled too. Defaults to True.
- Returns:
This Mob, so calls can be chained.
- Return type:
- spawn(animate=True)¶
Bring the Mob into the video.
The mob does not appear on screen until it is spawned. Changes made before spawning are not animated. After spawning, changes to the Mob animate by default and are controlled by
AnimationContext.Spawning is recursive: children spawn with their parent. Spawning a Mob that is already spawned does nothing.
Animation
Recorded as an animation over the current context’s runtime (1 second by default): the Mob fades in.
spawn(animate=False)makes it appear immediately, no animation.- Parameters:
animate (bool) – Whether to play the entrance animation, by default a fade-in (see
on_create()). Defaults to True.- Returns:
This object, so calls can be chained – which is what makes
square = Square().spawn()work.- Return type:
See also
despawn()Remove the Mob from the video again.
- two_sided = True¶
Whether this Mob’s geometry should be lit from whichever side the ray arrives on.
True(the default) is for geometry with no meaningful outside – a 2-D shape,Text, a parametricSurface, an imported mesh whose winding nobody has checked – where a back-facing hit is shaded with its normal flipped toward the viewer, so the surface is lit from behind instead of coming out black.The built-in solids set it
False: their normals face out (seetests/unit_tests/test_normal_orientation.py), so a back-facing hit is genuinely the inside of the solid and is shaded as such. That is what stops a half-transparent solid’s far shell from being lit like a second front shell – the bright and dark “planes” through a fading Octahedron. Set itTrueon an instance to get the old two-sided lighting back (an openConeyou want lit inside, say); it must be set before the Mob is spawned, since the render primitive reads it once.
- wave_color(color=None, wave_length=2, reverse=False, direction=None, lag_duration=1, samples_per_wave=12, refine_resolution=True, restore_resolution=True, **kwargs)[source]¶
Send a color pulse travelling across the Mob.
Every renderable part of the Mob pulses, but each one starts a little later than the part behind it, so the color sweeps across the shape instead of flashing all at once. Parts are ordered by their position along
direction.The color is carried by the Mob’s vertices, so a Mob sampled more coarsely than the wave is wide would show the pulse as a few flat facets – a
Surfaceshaped like a flat sheet has vertices only at its corners, and a filledBezierCircuitCubichas a single color sample by default. Such Mobs are re-sampled finely enough to draw the wave and, by default, dropped back to their original resolution once the block containing the wave is over; seesamples_per_waveandrestore_resolution.Animation
Recorded as an animation. The total runtime is
lag_durationplus one part’s pulse, so it is set by these parameters rather than by the current context’s runtime. Re-sampling a part is a topology change, so it splits that Mob’s history the waydetach_history()does, at the start of the wave and, whenrestore_resolutionis True, again when the enclosing block ends. The split is invisible, but it is why the resolution only drops back at the end of the block rather than at the end of the wave.- Parameters:
color (Tensor) – Color for the wave to pulse to. Defaults to
None, which pulses only opacity (pass one through**kwargs).wave_length (float) – How spread out the wave is: each part’s own pulse lasts
wave_length / lag_durationseconds, so smaller values give a tighter, more sharply defined band. Defaults to2.reverse (bool) – Whether the wave travels the opposite way along
direction. Defaults to False.direction (Tensor | None) – Direction the wave travels, shape
(*, 3). Defaults toNone, meaning the Mob’s own upward direction (bottom to top).lag_duration – Seconds between the first part starting its pulse and the last one starting theirs. Defaults to
1.samples_per_wave (int | None) – How many color samples to fit across the width of the travelling band. Parts already sampled at least this finely along
directionare left alone; coarser ones are temporarily refined. Defaults to12– a pulse is two straight ramps, which color interpolation reproduces exactly, so this only has to round off the peak between them and raising it buys geometry rather than smoothness. PassNoneto leave every part’s resolution exactly as it is.refine_resolution (bool) – Whether parts sampled too coarsely to show the wave may be refined at all. Defaults to True. False leaves every part exactly as authored, however coarse – the explicit form of
samples_per_wave=None. Worth setting for small on-screen mobs: the refinement is judged in world units relative to the mob’s own extent, never in pixels, so a mob a few dozen pixels wide is refined as heavily as a full-screen one.restore_resolution (bool) – Whether refined color grids return to their original resolution when the enclosing animation block ends. Defaults to True. Set to False when a newly spawned object must retain one stable topology throughout and after its materialization wave.
**kwargs – Passed to
pulse_color()for each part – notablyopacityandnew_color.new_colormay also be a callable receiving the primitive part being pulsed; this lets a composite settle to each part’s own target color after one shared wave.
- Returns:
This Mob, so calls can be chained.
- Return type: