87 lines
2.7 KiB
Python
87 lines
2.7 KiB
Python
#!/usr/bin/env python3
|
|
"""Convert Ogre3D .mesh.xml to Three.js geometry modules."""
|
|
|
|
import xml.etree.ElementTree as ET
|
|
import json
|
|
import os
|
|
import sys
|
|
|
|
def parse_mesh_xml(filepath):
|
|
tree = ET.parse(filepath)
|
|
root = tree.getroot()
|
|
|
|
sharedgeom = root.find('sharedgeometry')
|
|
vertices = []
|
|
if sharedgeom is not None:
|
|
for vb in sharedgeom.findall('vertexbuffer'):
|
|
for vertex in vb.findall('vertex'):
|
|
pos = vertex.find('position')
|
|
normal = vertex.find('normal')
|
|
v = {}
|
|
if pos is not None:
|
|
v['x'] = float(pos.get('x', 0))
|
|
v['y'] = float(pos.get('y', 0))
|
|
v['z'] = float(pos.get('z', 0))
|
|
if normal is not None:
|
|
v['nx'] = float(normal.get('x', 0))
|
|
v['ny'] = float(normal.get('y', 0))
|
|
v['nz'] = float(normal.get('z', 0))
|
|
vertices.append(v)
|
|
|
|
faces = []
|
|
for submeshes in root.findall('submeshes'):
|
|
for submesh in submeshes.findall('submesh'):
|
|
for faces_elem in submesh.findall('faces'):
|
|
for face in faces_elem.findall('face'):
|
|
v1 = int(face.get('v1', 0))
|
|
v2 = int(face.get('v2', 0))
|
|
v3 = int(face.get('v3', 0))
|
|
faces.append((v1, v2, v3))
|
|
|
|
return vertices, faces
|
|
|
|
|
|
def main():
|
|
base_dir = '/var/home/nico/Gamedev/Wackelpeter/extracted/Models'
|
|
output_dir = '/var/home/nico/Gamedev/Wackelpeter/web/public/models'
|
|
|
|
os.makedirs(output_dir, exist_ok=True)
|
|
|
|
for model_name in ['blob/Blob', 'sword/sword', 'shield/shield']:
|
|
filepath = os.path.join(base_dir, f'{model_name}.mesh.xml')
|
|
if not os.path.exists(filepath):
|
|
print(f'Skipping {filepath} - not found')
|
|
continue
|
|
|
|
print(f'Converting {model_name}...')
|
|
vertices, faces = parse_mesh_xml(filepath)
|
|
|
|
positions = []
|
|
normals = []
|
|
indices = []
|
|
|
|
for v in vertices:
|
|
positions.extend([v.get('x', 0), v.get('y', 0), v.get('z', 0)])
|
|
normals.extend([v.get('nx', 0), v.get('ny', 0), v.get('nz', 0)])
|
|
|
|
for f in faces:
|
|
indices.extend(list(f))
|
|
|
|
model_data = {
|
|
'positions': positions,
|
|
'normals': normals,
|
|
'indices': indices,
|
|
'vertexCount': len(vertices),
|
|
'faceCount': len(faces),
|
|
}
|
|
|
|
name = os.path.basename(model_name).lower()
|
|
outpath = os.path.join(output_dir, f'{name}.json')
|
|
with open(outpath, 'w') as f:
|
|
json.dump(model_data, f)
|
|
|
|
print(f' -> {outpath} ({len(vertices)} vertices, {len(faces)} faces)')
|
|
|
|
if __name__ == '__main__':
|
|
main()
|