8
$\begingroup$

I'm writing a scene exporter from blender to a format to be used by a game. I need to be able to export physics information the game needs, mainly the collision shape of every object (either the one set in Blender Render or Blender Game but the latter is better).

I cannot seem to find anywhere that the collision shape is available to python. I've seen references to PhysicsConstraints.exportBulletFile() but this appears to be under the bge module, which as far as I can tell, is not accessible by exporter scripts. Is there any way to determine the details of a shape (rotation and scale, width, height, depth for box or radius and height for cylinder, vertices for convex hull, etc...)?

$\endgroup$
  • $\begingroup$ Do you need the data from bullet, or can you generate your own shapes? (e.g. for convex hull) $\endgroup$ – gandalf3 Dec 8 '13 at 6:45
  • $\begingroup$ I can (and intend to) generate my own shapes. I need to know the parameters of these shapes though. $\endgroup$ – luminus Dec 8 '13 at 6:47
  • $\begingroup$ I mean, can you write your own script to generate bounding cylinders, convex hulls, etc.? Does it have to be from bullet for any particular reason? $\endgroup$ – gandalf3 Dec 8 '13 at 7:26
  • $\begingroup$ I'm trying to have defining the collision shapes require little work from the user of Blender which is why I want to use whatever shapes Blender has already when the user selected the shape type (assuming they're accurate). If, for instance, I added a second menu that generated a myScriptCone for the selected object the script wouldn't be able to determine what that shape's rotation, height and radius should be to fit the object without the user defining it (which will make their workflow more complicated) $\endgroup$ – luminus Dec 8 '13 at 17:04
  • $\begingroup$ Unless I'm missing something, you should be able to get all the information you need from the object's data in python. $\endgroup$ – gandalf3 Dec 8 '13 at 17:35
6
$\begingroup$

Finding the parameters necessary to generate such a shape should be possible with python.

From the wiki:

The Shape setting determines the collision shape of the object. The following shapes are available:

Primitive shapes - these are best in terms of memory/performance but don't necessarily reflect the actual shape of the object. They're calculated based on the object's bounding box. The center of gravity is always in the middle for now.

  • Box: The size per axis is calculated from the bounding box
  • Sphere: The radius is the largest axis of the bounding box
  • Capsule: This points up the Z-Axis.
  • Cylinder: This points up the Z-Axis. The height is taken from the z-axis, while the radius is the larger of the x/y-axes.
  • Cone: This points up the Z-Axis. The height is taken from the z-axis, while the radius is the larger of the x/y-axes.

'Mesh based shapes' - these are calculated based on the geometry of the object so they are a better representation of the object. The center of gravity for these shapes is the object origin.

  • Convex Hull: Convex approximation of the object, has good performance and stability.
  • Mesh: Allows to simulate concave objects, but is rather slow and unstable.

To build these shapes using the UI:

Box:

  1. Select the target object and press CtrlShiftAltC > Origin to goemetry, and then press F6 and select bounds center.

  2. With the target object selected, press ShiftS> Cursor to selected to move the cursor to the objects origin.

  3. Add a cube to be the bounding box. It will automatically be centered at the 3D cursor, which is snapped to the target object's origin point.

  4. Copy the Dimension and Rotation values from the target object to the bounding cube. These values are located on the Properties region (N in the 3D view):

    enter image description here

    You can quickly copy and paste values by hovering over the number field and pressing CtrlC/CtrlV accordingly.

    Since this process of copying and pasting the values of each channel can be a bit tedious, you can use a quick bit of python to do this for you:

    import bpy
    
    active = bpy.context.active_object
    selected = bpy.context.selected_objects
    
    for obj in selected:
        obj.dimensions = active.dimensions
    

    This copies the dimensions from the active object to the selected objects.

  5. Parent the bounding box to the target object so the relative location, rotation, and scale is kept the same. You can also set the bounding cube's Draw type to Wire in Properties > Object > Display > Maximum Draw Type.

Sphere

  1. Do steps 1 to 3 from the Box instructions, adding a sphere instead of a cube.

  2. Copy only the largest dimension value from the target into all three dimensions of the sphere.

  3. Do step 3 of the instructions for Box (Parent the bounding mesh and set the draw type to wire)

Cylinder

  1. Do steps 1 to 3 from the Box instructions, adding a cylinder instead of a cube.

  2. Copy the largest dimension value of the target excluding the Z axis, so the value of either X or Y into both the X and Y dimensions of the Cylinder.

  3. Copy the Z dimension value of the target to the Cylinder.

  4. Do step 3 of the instructions for Box (Parent the bounding mesh and set the draw type to wire).

Cone

  1. Do the same as for Sphere.

Convex Hull

This is more complex. you could try to generate your own using python, or you could try one of these existing options:


Existing addons

I also found a couple existing scripts/addons from a quick google search:

$\endgroup$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.