converted to Jolt physics

This commit is contained in:
2025-11-23 02:00:31 +03:00
parent 3f0484e87c
commit cd82fb0eed
52 changed files with 4302 additions and 1458 deletions

View File

@@ -92,8 +92,8 @@ class OgreCollisionOp(bpy.types.Operator):
def get_subcollisions( self, ob, create=True ):
r = get_subcollisions( ob )
if not r and create:
method = getattr(self, 'create_%s'%ob.collision_mode)
p = method(ob)
# method = getattr(self, 'create_%s'%ob.collision_mode)
# p = method(ob)
p.name = '%s.%s' %(ob.collision_mode, ob.name)
p.subcollision = True
r.append( p )

View File

@@ -52,7 +52,7 @@ def dot_scene(path, scene_name=None):
linkedgroups = []
invalidnamewarnings = []
for ob in bpy.context.scene.objects:
if ob.subcollision:
if ob.subcollision or "collision_type" in ob:
continue
if ((config.get("EXPORT_HIDDEN") is False) and (ob not in bpy.context.visible_objects)):
continue
@@ -184,6 +184,7 @@ def dot_scene(path, scene_name=None):
mesh_collision_prims = {}
mesh_collision_files = {}
compound_collision_shapes = {}
# Export the objects in the scene
for root in roots:
@@ -193,6 +194,7 @@ def dot_scene(path, scene_name=None):
meshes = meshes,
mesh_collision_prims = mesh_collision_prims,
mesh_collision_files = mesh_collision_files,
compound_collision_shapes = compound_collision_shapes,
exported_armatures = exported_armatures,
prefix = prefix,
objects = objects,
@@ -655,14 +657,16 @@ def dot_scene_skybox_export( path ):
# Recursive Node export
def dot_scene_node_export( ob, path, doc=None, rex=None,
exported_meshes=[], meshes=[], mesh_collision_prims={}, mesh_collision_files={},
exported_meshes=[], meshes=[], mesh_collision_prims={}, mesh_collision_files={}, compound_collision_shapes={},
exported_armatures=[], prefix='', objects=[], xmlparent=None ):
print("Nodes... " + ob.name)
o = _ogre_node_helper( doc, ob )
xmlparent.appendChild(o)
# if config.get('EXPORT_USER') is True:
# Custom user props
user = None
if len(ob.items()) > 0:
user = doc.createElement('userData')
o.appendChild(user)
@@ -672,46 +676,116 @@ def dot_scene_node_export( ob, path, doc=None, rex=None,
if not propname.startswith('_'):
_property_helper(doc, user, propname, propvalue)
if ob.type == 'MESH' or ob.type == 'EMPTY':
if not user:
user = doc.createElement('userData')
o.appendChild(user)
if ob.rigid_body:
_property_helper(doc, user, "blenderCollisionType", ob.rigid_body.type)
_property_helper(doc, user, "blenderCollisionShape", ob.rigid_body.collision_shape)
_property_helper(doc, user, "blenderCollisionEnabled", ob.rigid_body.enabled)
_property_helper(doc, user, "blenderCollisionKinematic", ob.rigid_body.kinematic)
_property_helper(doc, user, "blenderCollisionMass", ob.rigid_body.mass)
if ob.rigid_body.collision_shape == "CONVEX_HULL":
_property_helper(doc, user, "collisionType", "convexHull")
elif ob.rigid_body.collision_shape == "MESH":
_property_helper(doc, user, "collisionType", "mesh")
elif ob.rigid_body.collision_shape == "COMPOUND":
_property_helper(doc, user, "collisionType", "compound")
_property_helper(doc, user, "collisionBodyMass", ob.rigid_body.mass)
if ob.type == 'MESH':
if (not ob.parent) or (ob.parent and not ob.parent.rigid_body) or (ob.parent and ob.parent.rigid_body and ob.parent.rigid_body.collision_shape != "COMPOUND"):
# no compound parent
if ob.rigid_body.collision_shape in ["CONVEX_HULL", "MESH"]:
mesh.dot_mesh(ob, path, force_name='%s_collision_%s' % (prefix, ob.data.name) )
skeleton.dot_skeleton(ob, path)
_property_helper(doc, user, "collisionFile", '%s_collision_%s.mesh' % (prefix, ob.data.name))
elif ob.parent and ob.parent.rigid_body.collision_shape == "COMPOUND":
# has compound parent
mesh.dot_mesh(ob, path, force_name='%s_collision_%s_%s' % (prefix, ob.parent.data.name, ob.data.name) )
skeleton.dot_skeleton(ob, path)
_property_helper(doc, user, "collisionFile", '%s_collision_%s_%s.mesh' % (prefix, ob.parent.data.name, ob.data.name))
if (not ob.parent) or (ob.parent and not ob.parent.rigid_body) or (ob.parent and ob.parent.rigid_body and ob.parent.rigid_body.collision_shape != "COMPOUND"):
if ob.rigid_body.type == 'ACTIVE':
if not ob.rigid_body.kinematic:
_property_helper(doc, user, "collisionBodyType", "dynamic")
else:
_property_helper(doc, user, "collisionBodyType", "ghost")
else:
if not ob.rigid_body.kinematic:
_property_helper(doc, user, "collisionBodyType", "static")
else:
_property_helper(doc, user, "collisionBodyType", "kinematic")
if ob.type == 'MESH':
# ob.data.tessfaces is empty. always until the following call
ob.data.update()
ob.data.calc_loop_triangles()
# if it has no faces at all, the object itself will not be exported, BUT
# it might have children
if ob.type == 'MESH' and len(ob.data.loop_triangles):
print("Loopie..." + ob.data.name + " ", ob.data.loop_triangles)
compoundParent = False
hasPhysics = False
if ob.rigid_body:
hasPhysics = True
if ob.parent:
if ob.parent.rigid_body:
if ob.parent.rigid_body.collision_shape == "COMPOUND":
compoundParent = True
createEntity = not (compoundParent and hasPhysics)
if ob.type == 'MESH' and len(ob.data.loop_triangles) and createEntity:
collisionFile = None
collisionPrim = None
compoundColliders = None
if ob.data.name in mesh_collision_prims:
collisionPrim = mesh_collision_prims[ ob.data.name ]
if ob.data.name in mesh_collision_files:
collisionFile = mesh_collision_files[ ob.data.name ]
e = doc.createElement('entity')
o.appendChild(e); e.setAttribute('name', ob.name)
prefix = ''
e.setAttribute('meshFile', '%s%s.mesh' % (prefix, clean_object_name(ob.data.name)) )
# Set the instancing attribute if the object belongs to the correct group
_mesh_instance_helper(e, ob, "static")
_mesh_instance_helper(e, ob, "instanced")
if ob.data.name in compound_collision_shapes:
compoundColliders = compound_collision_shapes[ ob.data.name ]
print("Meshie..." + ob.data.name)
if True:
e = doc.createElement('entity')
o.appendChild(e); e.setAttribute('name', ob.name)
prefix = ''
e.setAttribute('meshFile', '%s%s.mesh' % (prefix, clean_object_name(ob.data.name)) )
# Set the instancing attribute if the object belongs to the correct group
_mesh_instance_helper(e, ob, "static")
_mesh_instance_helper(e, ob, "instanced")
if not collisionPrim and not collisionFile:
print("Collisions..." + ob.data.name)
for child in ob.children:
if child.type == 'MESH':
print("\tCollisions... " + child.data.name)
#if child.rigid_body:
# print("physics body")
# if child.rigid_body.collision_shape == 'CONVEX_HULL':
# collisionFile = '%s_collision_%s.mesh' % (prefix, ob.data.name)
# elif child.rigid_body.collision_shape == 'MESH':
# collisionFile = '%s_collision_%s.mesh' % (prefix, ob.data.name)
# break
if child.subcollision and child.name.startswith('DECIMATE'):
collisionFile = '%s_collision_%s.mesh' % (prefix, ob.data.name)
break
elif "collision_type" in child and child.name.startswith('DECIMATE'):
collisionFile = '%s_collision_%s.mesh' % (prefix, ob.data.name)
break
elif "collision_type" in child:
collisionFile = '%s_collision_%s.mesh' % (prefix, ob.data.name)
break
if collisionFile:
print("CollisionFile:")
mesh_collision_files[ ob.data.name ] = collisionFile
mesh.dot_mesh(child, path, force_name='%s_collision_%s' % (prefix, ob.data.name) )
skeleton.dot_skeleton(child, path)
if not collisionPrim and not collisionFile:
for child in ob.children:
if child.subcollision and child.name.startswith('DECIMATE'):
collisionFile = '%s_collision_%s.mesh' % (prefix, ob.data.name)
break
if child.name.endswith("-collision")
collisionFile = '%s_collision_%s.mesh' % (prefix, ob.data.name)
if collisionFile:
mesh_collision_files[ ob.data.name ] = collisionFile
mesh.dot_mesh(child, path, force_name='%s_collision_%s' % (prefix, ob.data.name) )
skeleton.dot_skeleton(child, path)
if collisionPrim:
e.setAttribute('collisionPrim', collisionPrim )
elif collisionFile:
e.setAttribute('collisionFile', collisionFile )
if collisionPrim:
e.setAttribute('collisionPrim', collisionPrim )
elif collisionFile:
e.setAttribute('collisionFile', collisionFile )
#if config.get('EXPORT_USER') is True:
_mesh_entity_helper( doc, ob, e )

View File

@@ -769,14 +769,21 @@ def get_subcollision_meshes():
''' returns all collision meshes found in the scene '''
r = []
for ob in bpy.context.scene.objects:
if ob.type=='MESH' and ob.subcollision: r.append( ob )
if ob.type=='MESH' and (ob.subcollision or "collision_type" in ob):
r.append( ob )
return r
def get_objects_with_subcollision():
''' returns objects that have active sub-collisions '''
r = []
for ob in bpy.context.scene.objects:
if ob.type=='MESH' and ob.collision_mode not in ('NONE', 'PRIMITIVE'):
if ob.type != 'MESH':
continue
if not ob.rigid_body:
continue
if ob.rigid_body.collision_shape in ('CONVEX_HULL', 'MESH'):
r.append( ob )
elif ob.type=='MESH' and not ob.collision_mode in ('NONE', 'PRIMITIVE'):
r.append( ob )
return r
@@ -784,7 +791,7 @@ def get_subcollisions(ob):
prefix = '%s.' %ob.collision_mode
r = []
for child in ob.children:
if child.subcollision and child.name.startswith( prefix ):
if (child.subcollision or "collision_type" in ob) and child.name.startswith( prefix ):
r.append( child )
return r

View File

@@ -11,13 +11,18 @@ from math import radians, pi
argv = sys.argv
argv = argv[argv.index("--") + 1:]
sys.path.insert(0, os.getcwd() + "/assets/blender/scripts")
sys.path.insert(1, os.getcwd() + "/assets/blender/scripts/blender2ogre")
incpath = os.path.dirname(__file__)
sys.path.insert(0, incpath)
sys.path.insert(1, incpath + "/blender2ogre")
import io_ogre
io_ogre.register()
gltf_file = argv[0]
print("Exporting to " + gltf_file)
basepath = os.getcwd()
basepath = incpath
# bpy.ops.export_scene.gltf(filepath="", check_existing=True,
# export_import_convert_lighting_mode='SPEC', gltf_export_id="",
# export_format='GLB', ui_tab='GENERAL', export_copyright="", export_image_format='AUTO',
@@ -47,6 +52,7 @@ for obj in bpy.data.objects:
bpy.data.objects.remove(obj)
scene_file = gltf_file.replace(".glb", "").replace(".gltf", "") + ".scene"
bpy.ops.ogre.export(filepath=scene_file,
EX_SWAP_AXIS='xz-y',
EX_V2_MESH_TOOL_VERSION='v2',

BIN
assets/blender/vehicles/boat.blend (Stored with Git LFS)

Binary file not shown.