I am trying to learn python for blender and a good place to start would be by creating a physics engine.
I made a function that uses F = ma to calculate the position and velocity of an object using the mass, force, initial position and initial velocity.
import bpy
mass = 1.0
substeps = 5
initial_velocity = [0.0, 0.0, 0.0]
timestep = 1/(bpy.data.scenes["Scene"].render.fps * substeps)
def simulate(force = [0.0, 0.0, 0.0], position = [0.0, 0.0, 0.0], velocity = [0.0, 0.0, 0.0]):
x = position[0]
y = position[1]
z = position[2]
vx = velocity[0]
vy = velocity[1]
vz = velocity[2]
acceleration = [force[0]/mass, force[1]/mass, force[2]/mass]
for j in range(substeps):
vx += acceleration[0] * timestep
vy += acceleration[1] * timestep
vz += acceleration[2] * timestep
x += vx * timestep
y += vy * timestep
z += vz * timestep
return [[x, y, z], [vx, vy, vz]]
current_speed = initial_velocity
for bpy.data.scenes["Scene"].frame_current in range(10,240):
simulation_data = [[0.0, 0.0, 0.0], [0.0, 0.0, 0.0]]
simulation_data = simulate([(bpy.data.scenes["Scene"].gravity[0] * mass), (bpy.data.scenes["Scene"].gravity[1] * mass), (bpy.data.scenes["Scene"].gravity[2] * mass)] , bpy.data.objects["Sphere"].location, current_speed)
bpy.data.objects["Sphere"].location = simulation_data[0]
bpy.ops.anim.keyframe_insert_menu(type='Location')
current_speed = simulation_data[1]
I have added unnecessary variables for better understanding, I will remove them. Running this script makes the ball nudge a bit but it does not move over different frames.
scene.frame_set(frame)to set the frame, orob.keyframe_insert(data_path, frame=frame)to insert a kf on frame. Btw with vectors canF = mass * scene.gravityrather than splitting into components – batFINGER Sep 18 '21 at 04:28