@ -60,9 +60,7 @@ class PhysicsConverter:
indices + = ( v [ 0 ] , v [ 2 ] , v [ 3 ] , )
indices + = ( v [ 0 ] , v [ 2 ] , v [ 3 ] , )
return indices
return indices
def _convert_mesh_data ( self , bo , physical , local_space , indices = True ) :
def _convert_mesh_data ( self , bo , physical , local_space , mat , indices = True ) :
mat = bo . matrix_world
mesh = bo . to_mesh ( bpy . context . scene , True , " RENDER " , calc_tessface = False )
mesh = bo . to_mesh ( bpy . context . scene , True , " RENDER " , calc_tessface = False )
with TemporaryObject ( mesh , bpy . data . meshes . remove ) :
with TemporaryObject ( mesh , bpy . data . meshes . remove ) :
if local_space :
if local_space :
@ -211,29 +209,39 @@ class PhysicsConverter:
if tree_xformed :
if tree_xformed :
bo_xformed = bo . plasma_object . has_transform_animation
bo_xformed = bo . plasma_object . has_transform_animation
# Always pin these objects - otherwise they may start falling through the floor.
_set_phys_prop ( plSimulationInterface . kPinned , simIface , physical )
# MOUL: only objects that have animation data are kPhysAnim
# MOUL: only objects that have animation data are kPhysAnim
if ver != pvMoul or bo_xformed :
if ver != pvMoul or bo_xformed :
_set_phys_prop ( plSimulationInterface . kPhysAnim , simIface , physical )
_set_phys_prop ( plSimulationInterface . kPhysAnim , simIface , physical )
# PotS: objects inheriting parent animation only are not pinned
# MOUL: animated objects in subworlds are not pinned
# Any physical that is parented by not kickable (dynamic) is passive -
if bo_xformed and ( ver != pvMoul or subworld is None ) :
# meaning we don't need to report back any changes from physics. Same for
_set_phys_prop ( plSimulationInterface . kPinned , simIface , physical )
# plFilterCoordInterface, which filters out some axes.
# MOUL: child objects are kPassive
if ( bo . parent is not None and not mod . dynamic ) or bo . plasma_object . ci_type == plFilterCoordInterface :
if ver == pvMoul and bo . parent is not None :
_set_phys_prop ( plSimulationInterface . kPassive , simIface , physical )
# FilterCoordinateInterfaces are kPassive
if bo . plasma_object . ci_type == plFilterCoordInterface :
_set_phys_prop ( plSimulationInterface . kPassive , simIface , physical )
_set_phys_prop ( plSimulationInterface . kPassive , simIface , physical )
# If the mass is zero, then we will fail to animate. Fix that.
# If the mass is zero, then we will fail to animate. Fix that.
if physical . mass == 0.0 :
if physical . mass == 0.0 :
physical . mass = 1.0
physical . mass = 1.0
# Different Plasma versions have different ways they expect to get physical transforms.
# With Havok, massless objects are in absolute worldspace while massed (movable) objects
# are in object-local space.
# In PhysX, objects with a coordinate interface are in local to SUBWORLD space, otherwise
# they are in absolute worldspace.
if ver < = pvPots :
if ver < = pvPots :
local_space = physical . mass > 0.0
local_space , mat = physical . mass > 0.0 , bo . matrix_world
elif ver == pvMoul :
if self . _exporter ( ) . has_coordiface ( bo ) :
local_space = True
mat = subworld . matrix_world . inverted ( ) * bo . matrix_world if subworld else bo . matrix_world
else :
local_space , mat = False , bo . matrix_world
else :
else :
local_space = self . _exporter ( ) . has_coordiface ( bo )
raise NotImplementedError ( " ODE physical transform " )
self . _bounds_converters [ bounds ] ( bo , physical , local_space )
self . _bounds_converters [ bounds ] ( bo , physical , local_space , mat )
else :
else :
simIface = so . sim . object
simIface = so . sim . object
physical = simIface . physical . object
physical = simIface . physical . object
@ -245,14 +253,14 @@ class PhysicsConverter:
self . _apply_props ( simIface , physical , kwargs )
self . _apply_props ( simIface , physical , kwargs )
def _export_box ( self , bo , physical , local_space ) :
def _export_box ( self , bo , physical , local_space , mat ) :
""" Exports box bounds based on the object """
""" Exports box bounds based on the object """
physical . boundsType = plSimDefs . kBoxBounds
physical . boundsType = plSimDefs . kBoxBounds
vertices = self . _convert_mesh_data ( bo , physical , local_space , indices = False )
vertices = self . _convert_mesh_data ( bo , physical , local_space , mat , indices = False )
physical . calcBoxBounds ( vertices )
physical . calcBoxBounds ( vertices )
def _export_hull ( self , bo , physical , local_space ) :
def _export_hull ( self , bo , physical , local_space , mat ) :
""" Exports convex hull bounds based on the object """
""" Exports convex hull bounds based on the object """
physical . boundsType = plSimDefs . kHullBounds
physical . boundsType = plSimDefs . kHullBounds
@ -260,7 +268,6 @@ class PhysicsConverter:
# bake them to convex hulls. Specifically, Windows 32-bit w/PhysX 2.6. Everything else just
# bake them to convex hulls. Specifically, Windows 32-bit w/PhysX 2.6. Everything else just
# needs to have us provide some friendlier data...
# needs to have us provide some friendlier data...
with bmesh_from_object ( bo ) as mesh :
with bmesh_from_object ( bo ) as mesh :
mat = bo . matrix_world
if local_space :
if local_space :
physical . pos = hsVector3 ( * mat . to_translation ( ) )
physical . pos = hsVector3 ( * mat . to_translation ( ) )
physical . rot = utils . quaternion ( mat . to_quaternion ( ) )
physical . rot = utils . quaternion ( mat . to_quaternion ( ) )
@ -273,24 +280,24 @@ class PhysicsConverter:
verts = itertools . takewhile ( lambda x : isinstance ( x , BMVert ) , result [ " geom " ] )
verts = itertools . takewhile ( lambda x : isinstance ( x , BMVert ) , result [ " geom " ] )
physical . verts = [ hsVector3 ( * i . co ) for i in verts ]
physical . verts = [ hsVector3 ( * i . co ) for i in verts ]
def _export_sphere ( self , bo , physical , local_space ) :
def _export_sphere ( self , bo , physical , local_space , mat ) :
""" Exports sphere bounds based on the object """
""" Exports sphere bounds based on the object """
physical . boundsType = plSimDefs . kSphereBounds
physical . boundsType = plSimDefs . kSphereBounds
vertices = self . _convert_mesh_data ( bo , physical , local_space , indices = False )
vertices = self . _convert_mesh_data ( bo , physical , local_space , mat , indices = False )
physical . calcSphereBounds ( vertices )
physical . calcSphereBounds ( vertices )
def _export_trimesh ( self , bo , physical , local_space ) :
def _export_trimesh ( self , bo , physical , local_space , mat ) :
""" Exports an object ' s mesh as exact physical bounds """
""" Exports an object ' s mesh as exact physical bounds """
# Triangle meshes MAY optionally specify a proxy object to fetch the triangles from...
# Triangle meshes MAY optionally specify a proxy object to fetch the triangles from...
mod = bo . plasma_modifiers . collision
mod = bo . plasma_modifiers . collision
if mod . enabled and mod . proxy_object is not None :
if mod . enabled and mod . proxy_object is not None :
physical . boundsType = plSimDefs . kProxyBounds
physical . boundsType = plSimDefs . kProxyBounds
vertices , indices = self . _convert_mesh_data ( mod . proxy_object , physical , local_space )
vertices , indices = self . _convert_mesh_data ( mod . proxy_object , physical , local_space , mat )
else :
else :
physical . boundsType = plSimDefs . kExplicitBounds
physical . boundsType = plSimDefs . kExplicitBounds
vertices , indices = self . _convert_mesh_data ( bo , physical , local_space )
vertices , indices = self . _convert_mesh_data ( bo , physical , local_space , mat )
physical . verts = vertices
physical . verts = vertices
physical . indices = indices
physical . indices = indices