Skip to content

Commit

Permalink
Merge pull request #2 from smlu/develop
Browse files Browse the repository at this point in the history
Fix exporting to 3DO
  • Loading branch information
smlu authored May 31, 2020
2 parents ba6099c + d4c236a commit a67f90f
Show file tree
Hide file tree
Showing 4 changed files with 48 additions and 99 deletions.
32 changes: 27 additions & 5 deletions ijim/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
"name": "Indiana Jones and the Infernal Machine",
"description": "Import-Export game model (.3do) and material (.mat)",
"author": "smlu",
"version": (0, 9, 1),
"version": (0, 9, 2),
"blender": (2, 79, 0),
"location": "File > Import-Export",
"wiki_url": "https://github.com/smlu/blender-ijim",
Expand All @@ -12,6 +12,28 @@
"category": "Import-Export"
}

# Reload imported submodules if script is reloaded
if "bpy" in locals():
import importlib
if "key" in locals():
importlib.reload(key)
if "keyImporter" in locals():
importlib.reload(keyImporter)
if "keyExporter" in locals():
importlib.reload(keyExporter)
if "material" in locals():
importlib.reload(material)
if "model" in locals():
importlib.reload(model)
if "model3doImporter" in locals():
importlib.reload(model3doImporter)
if "model3doExporter" in locals():
importlib.reload(model3doExporter)
if "text" in locals():
importlib.reload(text)
if "utils" in locals():
importlib.reload(utils)


import mathutils
import math
Expand Down Expand Up @@ -122,10 +144,10 @@ def execute(self, context):
space.grid_scale = 0.027
space.grid_subdivisions = 14

obj_radius = model3doImporter.getObjRadiusObj(obj)
model_radius = model3doImporter.getModelRadiusObj(obj)
mesh_radius = model3doImporter.getMeshRadiusObj(obj)
if getRadius(obj_radius) >= getRadius(mesh_radius):
obj = obj_radius
if getRadius(model_radius) >= getRadius(mesh_radius):
obj = model_radius
else:
obj = mesh_radius

Expand Down Expand Up @@ -432,4 +454,4 @@ def unregister():
unregister()
except:
pass
register()
register()
97 changes: 12 additions & 85 deletions ijim/model/model3doExporter.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@
from collections import defaultdict, OrderedDict

from .model3do import *
from .model3doImporter import getObjByName, getObjRadiusObj, getMeshRadiusObj
from .model3doImporter import getObjByName, getModelRadiusObj, getMeshRadiusObj
from . import model3doWriter
from .utils import *
from ijim.utils.utils import *
Expand Down Expand Up @@ -51,7 +51,7 @@ def _get_mat_name(mat: bpy.types.Material):
return name

def _is_aux_obj(obj: bpy.types.Object):
return (kObjRadius in obj.name) or (kMeshRadius in obj.name) or (kPivotObj in obj.name)
return (kModelRadius in obj.name) or (kMeshRadius in obj.name) or (kPivotObj in obj.name)

def _get_face_property_or_default(face: bmesh.types.BMFace, tag: bmesh.types.BMLayerAccessFace, default):
v = face[tag]
Expand All @@ -76,7 +76,7 @@ def _get_face_tex_mode(face: bmesh.types.BMFace, bmesh: bmesh.types.BMesh):
return _get_face_property_or_default(face, tag, 3)


def _add_mesh_to_model3d(mesh: bpy.types.Mesh, model: Model) -> int:
def _model3do_add_mesh(model: Model, mesh: bpy.types.Mesh) -> int:
if mesh is None:
return -1

Expand Down Expand Up @@ -187,14 +187,13 @@ def _get_obj_hnode_name(obj: bpy.types.Object):

def _get_hnode_idx(nodes: List[MeshHierarchyNode], name):
for idx, node in enumerate(nodes):
if name in node.name:
if name == node.name:
return idx
return -1

def _get_obj_hnode_idx(nodes: List[MeshHierarchyNode], obj: bpy.types.Object):
if obj is None:
return -1

name = _get_obj_hnode_name(obj)
return _get_hnode_idx(nodes, name)

Expand All @@ -204,7 +203,7 @@ def _get_hnode_last_sibling(first_child: MeshHierarchyNode, nodes: List[MeshHier
return _get_hnode_last_sibling(nodes[sidx], nodes)
return first_child

def _update_model3do_hirarchy(model: Model, mesh_idx: int, obj: bpy.types.Object, parent: bpy.types.Object):
def _model3do_add_hnode(model: Model, mesh_idx: int, obj: bpy.types.Object, parent: bpy.types.Object):
name = _get_obj_hnode_name(obj)
if name in model.hierarchyNodes:
return
Expand Down Expand Up @@ -232,108 +231,36 @@ def _update_model3do_hirarchy(model: Model, mesh_idx: int, obj: bpy.types.Object
_set_hnode_location(node, obj)
model.hierarchyNodes.append(node)

def _sort_model3do_hirarchy(model: Model):
ohl = model.hierarchyNodes

# First stage: Order node idxs by type
otd = {
MeshNodeType.Nothing : [],
MeshNodeType.Vehicle : [],
MeshNodeType.Torso : [],
MeshNodeType.Head : [],
MeshNodeType.Torso : [],
MeshNodeType.LeftArm : [],
MeshNodeType.LeftHand : [],
MeshNodeType.LeftHand2 : [],
MeshNodeType.RightArm : [],
MeshNodeType.RightHand : [],
MeshNodeType.RightHand2 : [],
MeshNodeType.Hip : [],
MeshNodeType.RightLeg : [],
MeshNodeType.LeftLeg : [],
MeshNodeType.BackPart : [],
MeshNodeType.FrontPart : [],
MeshNodeType.BackWheel : [],
MeshNodeType.FrontWheel : [],
}

for idx, n in enumerate(ohl):
otd[n.type] += [idx]

# Second stage: Grup node idxs by parent and order by parents by type
hnond = OrderedDict()
for v in otd.values():
for idx in v:
n = ohl[idx]
hnond[n.name] = idx

lidx = []
for idx in hnond.values():
if idx not in lidx:
n = ohl[idx]
if n.parentIdx > -1:
pn = ohl[n.parentIdx].name
pidx = hnond[pn]
if pidx not in lidx:
lidx.append(pidx)
lidx.append(idx)

# Third stage: Make new list of hirarchy nodes and update child/sibling idxs
nhl = []
for idx in lidx:
n = ohl[idx]

if n.parentIdx > -1:
n.parentIdx = _get_hnode_idx(nhl, ohl[n.parentIdx].name)
pn = nhl[n.parentIdx]

node_idx = len(nhl)
if pn.firstChildIdx == -1:
pn.firstChildIdx = node_idx
else:
snode = nhl[pn.firstChildIdx]
snode = _get_hnode_last_sibling(snode, nhl)
snode.siblingIdx = node_idx

n.siblingIdx = -1
n.firstChildIdx = -1
nhl.append(n)

# Set new hirarchy list
model.hierarchyNodes = nhl

def _add_obj_to_model3do(obj: bpy.types.Object, model: Model, parent: bpy.types.Object = None):
def _model3do_add_obj(model: Model, obj: bpy.types.Object, parent: bpy.types.Object = None):
if 'EMPTY' != obj.type != 'MESH' or _is_aux_obj(obj):
return

mesh_idx = _add_mesh_to_model3d(obj.data, model)
mesh_idx = _model3do_add_mesh(model, obj.data)
if mesh_idx > -1:
mesh = model.geosets[0].meshes[mesh_idx]
_set_mesh_properties(mesh, obj)

_update_model3do_hirarchy(model, mesh_idx, obj, parent)
_model3do_add_hnode(model, mesh_idx, obj, parent)
for child in obj.children:
_add_obj_to_model3do(child, model, obj)
_model3do_add_obj(model, child, obj)

def makeModel3doFromObj(name, obj: bpy.types.Object):
model = Model(name)
model.geosets.append(ModelGeoSet())

model.insertOffset = Vector3f(*obj.location)
radius_obj = getObjRadiusObj(obj)
radius_obj = getModelRadiusObj(obj)
if radius_obj is None:
print("\nWarning: no model radius object found, using calculated value!")
model.radius = getRadius(obj)
else:
model.radius = radius_obj.dimensions[0] / 2

for child in obj.children:
_add_obj_to_model3do(child, model, obj)

_sort_model3do_hirarchy(model)
_model3do_add_obj(model, child, obj)

return model


def exportObject(obj: bpy.types.Object, path: str):
bpy.path.ensure_ext(path, '.3do')
print("exporting 3DO: %r..." % (path), end="")
Expand Down
14 changes: 7 additions & 7 deletions ijim/model/model3doImporter.py
Original file line number Diff line number Diff line change
Expand Up @@ -71,8 +71,8 @@ def _make_radius_obj(name, parent, radius):
bm.to_mesh(mesh)
bm.free()

def _set_obj_radius(obj, radius):
_make_radius_obj(kObjRadius + obj.name, obj, radius)
def _set_model_radius(obj, radius):
_make_radius_obj(kModelRadius + obj.name, obj, radius)

def _set_mesh_radius(obj, radius):
_make_radius_obj(kMeshRadius + obj.name, obj, radius)
Expand Down Expand Up @@ -155,12 +155,12 @@ def _make_mesh(mesh3do: ModelMesh, mat_list: List):



def getObjRadiusObj(obj):
return _get_radius_obj(kObjRadius + obj.name)
def getModelRadiusObj(obj):
return _get_radius_obj(kModelRadius + obj.name)

def getMeshRadiusObj(mesh):
obj = getObjByName(mesh.name)
return _get_radius_obj(kMeshRadius + obj.name)
return _get_radius_obj(kMeshRadius + stripOrderPrefix(obj.name))

def importObject(file_path, mat_paths = [], b_preserve_order = True, b_clear_scene = True):
print("importing 3DO: %r..." % (file_path), end="")
Expand Down Expand Up @@ -238,7 +238,7 @@ def importObject(file_path, mat_paths = [], b_preserve_order = True, b_clear_sce
bpy.context.scene.objects.link(baseObj)

baseObj.location = model.insert_offset
_set_obj_radius(baseObj, model.radius)
_set_model_radius(baseObj, model.radius)

firstCName = model.hierarchyNodes[0].name
firstChild = getObjByName(firstCName)
Expand All @@ -253,4 +253,4 @@ def importObject(file_path, mat_paths = [], b_preserve_order = True, b_clear_sce
group.objects.link(baseObj)

print(" done in %.4f sec." % (time.process_time() - startTime))
return baseObj
return baseObj
4 changes: 2 additions & 2 deletions ijim/model/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@

kImEulerOrder = "YXZ" # Infernal machine euler orientation order
kGModel3do = "Model3do"
kObjRadius = "OBJ_RADIUS_"
kModelRadius = "MODEL_RADIUS_"
kMeshRadius = "MESH_RADIUS_"
kPivotObj = "PIVOT_OBJ_"
kGeometryMode = "geometry mode"
Expand Down Expand Up @@ -144,4 +144,4 @@ def importMaterials(mat_names: List, search_paths: List):
mat_path = getFilePathInDir(name, path)
if mat_path is not None:
importMatFile(mat_path)
break
break

0 comments on commit a67f90f

Please sign in to comment.