Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Generate Capsule collider #387

Closed
Weisl opened this issue Jun 4, 2023 · 0 comments
Closed

Generate Capsule collider #387

Weisl opened this issue Jun 4, 2023 · 0 comments
Labels
enhancement New feature or request
Milestone

Comments

@Weisl
Copy link
Owner

Weisl commented Jun 4, 2023

ChatGPT code:

bl_info = {
    "name": "Bounding Capsule",
    "author": "Your Name",
    "version": (1, 0),
    "blender": (2, 80, 0),
    "location": "View3D > Object",
    "description": "Generate a bounding capsule for a selected object",
    "category": "Object"
}

import bpy
import math

# Function to calculate the distance between two points
def distance(p1, p2):
    return math.sqrt(sum((p1[i] - p2[i]) ** 2 for i in range(len(p1))))

# Function to calculate the distance between a point and a line segment
def point_line_segment_distance(p, p1, p2):
    v = [p2[i] - p1[i] for i in range(len(p1))]
    w = [p[i] - p1[i] for i in range(len(p1))]

    t = max(0, min(1, sum(w[i] * v[i] for i in range(len(v))) / sum(v[i] * v[i] for i in range(len(v)))))
    closest_point = [p1[i] + t * v[i] for i in range(len(p1))]
    return distance(p, closest_point)

# Function to calculate the radius and height of the bounding capsule
def calculate_radius_height(points):
    max_distance = 0
    for i in range(len(points)):
        for j in range(i + 1, len(points)):
            d = distance(points[i], points[j])
            if d > max_distance:
                max_distance = d

    radius = max_distance / 2
    height = max_distance - radius
    return radius, height

# Operator to generate the bounding capsule
class OBJECT_OT_generate_bounding_capsule(bpy.types.Operator):
    bl_idname = "object.generate_bounding_capsule"
    bl_label = "Generate Bounding Capsule"
    bl_description = "Generate a bounding capsule for the selected object"

    def execute(self, context):
        # Check if there is an active object and it's selected
        if bpy.context.active_object and bpy.context.active_object.select_get():
            selected_object = bpy.context.active_object

            # Get the object's vertices
            vertices = [selected_object.matrix_world @ v.co for v in selected_object.data.vertices]
            points = [list(vertex) for vertex in vertices]

            # Calculate the radius and height of the bounding capsule
            radius, height = calculate_radius_height(points)

            # Create a new mesh object for the cylinder
            bpy.ops.mesh.primitive_cylinder_add(radius=radius, depth=height)
            cylinder = bpy.context.object

            # Create a new mesh object for the top hemisphere
            bpy.ops.mesh.primitive_uv_sphere_add(radius=radius, location=(0, 0, height/2))
            top_hemisphere = bpy.context.object

            # Create a new mesh object for the bottom hemisphere
            bpy.ops.mesh.primitive_uv_sphere_add(radius=radius, location=(0, 0, -height/2))
            bottom_hemisphere = bpy.context.object

            # Combine the objects into a single object
            bpy.ops.object.select_all(action='DESELECT')
            cylinder.select_set(True)
            top_hemisphere.select_set(True)
            bottom_hemisphere.select_set(True)
            bpy.context.view_layer.objects.active = cylinder
            bpy.ops.object.join()

            # Get the combined object
            bounding_capsule = bpy.context.object

            # Move the bounding capsule to the same location as the original object
            bounding_capsule.location = selected_object.location

            # Align the bounding capsule with the original object's rotation
            bounding_capsule.rotation_euler = selected_object.rotation_euler

            # Set the bounding capsule as the parent of the original object
            selected_object.parent = bounding_capsule

        else:
            self.report({'ERROR'}, "No selected object found.")

        return {'FINISHED'}

# Panel to display the Generate Bounding Capsule button
class OBJECT_PT_bounding_capsule_panel(bpy.types.Panel):
    bl_idname = "OBJECT_PT_bounding_capsule_panel"
    bl_label = "Bounding Capsule"
    bl_category = "Tool"
    bl_space_type = "VIEW_3D"
    bl_region_type = "UI"

    def draw(self, context):
        layout = self.layout

        row = layout.row()
        row.operator("object.generate_bounding_capsule", text="Generate Bounding Capsule")

# Register the addon
def register():
    bpy.utils.register_class(OBJECT_OT_generate_bounding_capsule)
    bpy.utils.register_class(OBJECT_PT_bounding_capsule_panel)

def unregister():
    bpy.utils.unregister_class(OBJECT_OT_generate_bounding_capsule)
    bpy.utils.unregister_class(OBJECT_PT_bounding_capsule_panel)

if __name__ == "__main__":
    register()

@Weisl Weisl added the enhancement New feature or request label Jun 4, 2023
@Weisl Weisl added this to the 1.4 milestone Jun 4, 2023
@Weisl Weisl closed this as completed Jun 17, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request
Projects
None yet
Development

No branches or pull requests

1 participant