150 lines
5.7 KiB
Python
150 lines
5.7 KiB
Python
"""Geometry Script footholds from Blender's index_of_nearest demo."""
|
|
|
|
try:
|
|
from tools.geometry_script_loader import load_repo_geometry_script
|
|
except ModuleNotFoundError:
|
|
import sys
|
|
from pathlib import Path
|
|
|
|
sys.path.insert(0, str(Path(__file__).resolve().parents[2]))
|
|
from tools.geometry_script_loader import load_repo_geometry_script
|
|
|
|
load_repo_geometry_script()
|
|
|
|
from geometry_script import * # noqa: F403 - Geometry Script exposes node functions as DSL globals.
|
|
|
|
|
|
@tree("VG Boundary Step")
|
|
def vg_boundary_step(
|
|
geometry: Geometry,
|
|
vector: Vector = (0.0, 0.0, 0.0),
|
|
b: Float = 0.05000000074505806,
|
|
):
|
|
from_center = vector_math(operation=VectorMath.Operation.SUBTRACT, vector=(position(), vector))
|
|
distance = vector_math(operation=VectorMath.Operation.LENGTH, vector=from_center)
|
|
outside = compare(
|
|
operation=Compare.Operation.GREATER_THAN,
|
|
data_type=Compare.DataType.FLOAT,
|
|
mode=Compare.Mode.ELEMENT,
|
|
a=distance,
|
|
b=b,
|
|
)
|
|
clamped_xy = vector_math(
|
|
operation=VectorMath.Operation.MULTIPLY,
|
|
vector=(vector_math(operation=VectorMath.Operation.SCALE, vector=vector_math(operation=VectorMath.Operation.NORMALIZE, vector=from_center), scale=b), (1.0, 1.0, 0.0)),
|
|
)
|
|
return {"Geometry": set_position(geometry=geometry, selection=outside, position=clamped_xy, offset=(0.0, 0.0, 0.0))}
|
|
|
|
|
|
@tree("VG Update Velocity")
|
|
def vg_update_velocity(
|
|
current_velocity: Vector = (0.0, 0.0, 0.0),
|
|
last_position: Vector = (0.0, 0.0, 0.0),
|
|
):
|
|
movement = vector_math(operation=VectorMath.Operation.SUBTRACT, vector=(position(), last_position))
|
|
damped_movement = vector_math(operation=VectorMath.Operation.SCALE, vector=movement, scale=0.9599999785423279)
|
|
planar_movement = vector_math(operation=VectorMath.Operation.MULTIPLY, vector=(damped_movement, (1.0, 1.0, 0.0)))
|
|
fast_enough = compare(
|
|
operation=Compare.Operation.GREATER_THAN,
|
|
data_type=Compare.DataType.FLOAT,
|
|
mode=Compare.Mode.ELEMENT,
|
|
a=vector_math(operation=VectorMath.Operation.LENGTH, vector=planar_movement),
|
|
b=0.009999999776482582,
|
|
)
|
|
blended = vector_math(
|
|
operation=VectorMath.Operation.ADD,
|
|
vector=(
|
|
vector_math(operation=VectorMath.Operation.SCALE, vector=current_velocity, scale=0.75),
|
|
vector_math(operation=VectorMath.Operation.SCALE, vector=planar_movement, scale=0.25),
|
|
),
|
|
)
|
|
capped = vector_math(
|
|
operation=VectorMath.Operation.SCALE,
|
|
vector=vector_math(operation=VectorMath.Operation.NORMALIZE, vector=damped_movement),
|
|
scale=0.009999999776482582,
|
|
)
|
|
return {"velocity": switch(input_type=Switch.InputType.VECTOR, switch=fast_enough, false=blended, true=capped)}
|
|
|
|
|
|
@tree("VG Collision Step")
|
|
def vg_collision_step(geometry: Geometry):
|
|
current_position = position()
|
|
neighbor = index_of_nearest(position=position())
|
|
neighbor_position = evaluate_at_index(
|
|
domain="POINT",
|
|
data_type="FLOAT_VECTOR",
|
|
value=position(),
|
|
index=neighbor.index,
|
|
)
|
|
from_neighbor = vector_math(operation=VectorMath.Operation.SUBTRACT, vector=(current_position, neighbor_position))
|
|
too_close = compare(
|
|
operation=Compare.Operation.LESS_THAN,
|
|
data_type=Compare.DataType.FLOAT,
|
|
mode=Compare.Mode.ELEMENT,
|
|
a=vector_math(operation=VectorMath.Operation.LENGTH, vector=from_neighbor),
|
|
b=radius(),
|
|
)
|
|
push_strength = math(operation=Math.Operation.MULTIPLY, value=(too_close, 0.02500000037252903))
|
|
push = vector_math(
|
|
operation=VectorMath.Operation.MULTIPLY,
|
|
vector=(vector_math(operation=VectorMath.Operation.SCALE, vector=from_neighbor, scale=push_strength), (1.0, 1.0, 0.0)),
|
|
)
|
|
return {"Geometry": set_position(geometry=geometry, offset=push)}
|
|
|
|
|
|
@tree("VG Collider Step")
|
|
def vg_collider_step(geometry: Geometry, collider: Object = None):
|
|
collider_info = object_info(transform_space="ORIGINAL", object=collider, as_instance=False)
|
|
from_collider = vector_math(operation=VectorMath.Operation.SUBTRACT, vector=(position(), collider_info.location))
|
|
collider_radius = vector_math(operation=VectorMath.Operation.ABSOLUTE, vector=collider_info.scale)
|
|
inside = compare(
|
|
operation=Compare.Operation.LESS_THAN,
|
|
data_type=Compare.DataType.FLOAT,
|
|
mode=Compare.Mode.ELEMENT,
|
|
a=vector_math(operation=VectorMath.Operation.LENGTH, vector=from_collider),
|
|
b=collider_radius,
|
|
)
|
|
clamped = vector_math(
|
|
operation=VectorMath.Operation.ADD,
|
|
vector=(
|
|
vector_math(
|
|
operation=VectorMath.Operation.SCALE,
|
|
vector=vector_math(operation=VectorMath.Operation.NORMALIZE, vector=from_collider),
|
|
scale=collider_radius,
|
|
),
|
|
collider_info.location,
|
|
),
|
|
)
|
|
planar_clamped = vector_math(operation=VectorMath.Operation.MULTIPLY, vector=(clamped, (1.0, 1.0, 0.0)))
|
|
return {"Geometry": set_position(geometry=geometry, selection=inside, position=planar_clamped, offset=(0.0, 0.0, 0.0))}
|
|
|
|
|
|
def _finalize_groups():
|
|
import bpy
|
|
|
|
groups = []
|
|
for name in (
|
|
"VG Boundary Step",
|
|
"VG Update Velocity",
|
|
"VG Collision Step",
|
|
"VG Collider Step",
|
|
):
|
|
group = bpy.data.node_groups.get(name)
|
|
if group:
|
|
group.use_fake_user = True
|
|
groups.append(group)
|
|
return groups
|
|
|
|
|
|
_finalize_groups()
|
|
|
|
|
|
if __name__ == "__main__":
|
|
for group in _finalize_groups():
|
|
print(
|
|
"VG_INDEX_OF_NEAREST_GROUP",
|
|
group.name,
|
|
len(group.nodes),
|
|
len(group.links),
|
|
sorted(set(node.bl_idname for node in group.nodes)),
|
|
)
|