0

I have a drone composed of multiple objects. The problem is that when I rotate the drone and move it to some other point it looses its shape (torn to pieces), every part of the drone disconnects from the main body. How can I rotate and move the drone without loosing its shape?

I have tried to make the body of the drone the parent of all the pieces. It's working when I only rotate or move the body. config

import math
import bpy
import mathutils
import subprocess as sp
from math import sqrt, degrees, acos, pow

sp.call('cls', shell=True)

drone_objects_names = ['Cube.008', 'Cylinder.007', 'Cube.007', 'Cube.006', 'Sphere.005', 'Sphere.004', 'Cylinder.008',
                       'Sphere.003', 'Cylinder.006', 'Cube.005', 'Cube.004', 'Sphere.002', 'Cylinder.005', 'Sphere.001',
                       'Cylinder.004', 'Sphere', 'Cylinder.003', 'Cube.003', 'Cylinder.002', 'Cylinder.001', 'Cube.002',
                       'Cube.001', 'Cylinder', 'Cube']

X = 10
Y = 10
Z = 5

frame_num = 0
teta = 0

factor = 0.97


def set_keyframe():
    for object_name in drone_objects_names:
        bpy.data.objects[object_name].keyframe_insert(data_path="location", index=-1)


def send_drone_to_center():
    move_drone(-bpy.data.objects['Cylinder.003'].location)


def select_drone():
    for object_name in drone_objects_names:
        bpy.data.objects[object_name].select_set(True)


def move_drone(v):
    bpy.ops.transform.translate(value=v)


def angle_between_z(vc, uc):
    nominator = vc[0] * uc[0] + vc[2] * uc[2]
    denominator = sqrt(pow(vc[0], 2) + pow(vc[2], 2)) * sqrt(pow(uc[0], 2) + pow(uc[2], 2))
    return acos(nominator / denominator)


def angle_between_y(vc, uc):
    nominator = vc[0] * uc[0] + vc[2] * uc[2]
    denominator = sqrt(pow(vc[0], 2) + pow(vc[2], 2)) * sqrt(pow(uc[0], 2) + pow(uc[2], 2))
    return acos(nominator / denominator)


def do_step():
    global factor, teta, frame_num, X, Y, Z
    factor = 0.97

    x_new = X * math.cos(math.radians(teta))
    y_new = Y * math.sin(math.radians(teta))

    bpy.context.scene.frame_set(frame_num)

    move_drone(-bpy.data.objects['Cylinder.003'].location)
    move_drone((x_new, y_new, Z * factor))

    angle = angle_between_z((x_new, y_new, Z * factor), (X, Y, Z))
    bpy.data.objects['Cylinder.003'].rotate_euler[2] = angle

    set_keyframe()

    frame_num += 3

    X *= factor
    Y *= factor
    Z *= factor
    teta += 10


select_drone()
send_drone_to_center()
move_drone((X, Y, Z))

while math.sqrt(X * X + Y * Y + Z * Z) > 1:
    do_step()
    e = bpy.data.objects['Cylinder.003'].location
    print(X, Y, e[0], e[2])

bpy.context.scene.frame_end = frame_num

I'm expecting to get the drone in the center of the referential without losing its shape... drone lose it's shape

The drone I'm using in this project (if you want to try it...): drone

  • I'm not familiar with blender, but you might find the explanation of the math involved in [my answer](https://stackoverflow.com/a/14842362/355230) to the question [Rotate line around center point given two vertices](https://stackoverflow.com/questions/14842090/rotate-line-around-center-point-given-two-vertices) helpful since the same concepts apply to 3D geometry. – martineau Oct 18 '19 at 22:51
  • In your script `rotate_euler` should be `rotation_euler`. Also you are only keyframing the location, you may also want to keyframe the rotation. – sambler Oct 20 '19 at 05:09

1 Answers1

0

Your script is applying the same movement to every part of the drone. As a child, the objects location is relative to the parent object, by changing the location of a child it is being moved away from the parent, which is also being moved.

Either remove the parenting, or only animate the parent object.

sambler
  • 6,917
  • 1
  • 16
  • 23