Added .geo import support for blender 2.80 .

master
TigerKat 4 years ago
parent 5b7c1abed4
commit bf0e940a57

@ -2,7 +2,7 @@
bl_info = {
"name": "City of Heroes (.geo)",
"author": "TigerKat",
"version": (0, 2, 0),
"version": (0, 2, 1),
"blender": (2, 80, 0),
"location": "File > Import/Export,",
"description": "City of Heroes (.geo)",
@ -94,7 +94,6 @@ class ExportGeoMetric(bpy.types.Operator, ExportHelper):
))
return export_geo.save(self, context, 1.0 / 0.30480000376701355, **keywords)
def menu_func_import(self, context):
self.layout.operator(ImportGeo.bl_idname,
text="City of Heroes (Feet) (.geo)")

@ -9,10 +9,12 @@ try:
from .bones import *
from .polygrid import PolyCell, PolyGrid
from .util import Data
from .geomesh import GeoMesh, GeoFace, GeoVertex
except:
from bones import *
from polygrid import PolyCell, PolyGrid
from util import Data
from geomesh import GeoMesh, GeoFace, GeoVertex
#Ver 0 .geo pre-header:
#Offset Size Description
@ -914,17 +916,29 @@ class Model:
uv = (0, 0)
if geomesh.have_weights:
weights = []
for i, w in enumerate(self.weights):
weights.append([self.weight_bones[i], w])
#print("verts #: %s weights #: %s weight bones #: %s" % (len(self.verts), len(self.weights), len(self.weight_bones)))
#for k, w in enumerate(self.weights):
w = self.weights[i]
w_bones = self.weight_bones[i]
for j, b in enumerate(w_bones):
if w[j] == 0:
continue
#print("vertex_idx: %s weight_bones: %s" % (i, b, ))
#print(" bone_id: %s" % (self.bone_ids[b], ))
w_name = BONES_LIST[b]
#weights.append((geomesh.getWeightIndex(w_name), w[j]))
geomesh.getWeightIndex(w_name)
weights.append([w_name, w[j]])
else:
weights = []
v = GeoVertex(coord, normal, uv, self.weights)
#print(" weights: %s" % (weights, ))
v = GeoVertex(coord, normal, uv, weights)
geomesh.getGeoVertexIndex(v)
texture_indexes = []
for t in self.tex_idx:
texture_indexes += [geomesh.getTextureIndex(self.geo.header_texnames[t[0]])] * t[1]
for i, t in enumerate(self.tris):
geomesh.addFace(geomesh.geovertex[t[0]], geomesh.geovertex[t[1]], geomesh.geovertex[t[2]], texture_indexes[i])
geomesh.addFace([geomesh.geovertex[t[0]], geomesh.geovertex[t[1]], geomesh.geovertex[t[2]]], texture_indexes[i])
return geomesh
def loadFromGeoMesh(self, geomesh):
self.tris = [] #uncompressDeltas(self.tris_data, 3, self.tri_count, "I")

@ -11,11 +11,12 @@ class GeoVertex:
self.coord = coord
self.normal = normal
self.uv = uv
self.weights = weights
self.weights = tuple(weights)
def __eq__(self, other):
return self.coord == other.coord and self.normal == other.normal and self.uv == other.uv and self.weights == other.weights
def __hash__(self):
#print("__hash__: %s" % ((tuple(self.coord), tuple(self.normal), tuple(self.uv), tuple(self.weights)), ))
#self.dump()
return hash((tuple(self.coord), tuple(self.normal), tuple(self.uv), tuple_weights(self.weights)))
def selectWeights(self, count = None):
"""Returns the list of weights attached to this vertex. List is sorted by weight, with the strongest first. If 'count' is given, only 'count' strongest are return. The final list is normalized so the sum is 1."""
@ -104,7 +105,7 @@ class GeoMesh:
return
for i in range(3):
for w in geovertices[i].weights:
w[0] = self.getWeightIndex(w[0])
# w_index = self.getWeightIndex(w[0])
self.have_weights = True
geovertices_index = [self.getGeoVertexIndex(geovertices[0]),
self.getGeoVertexIndex(geovertices[1]),

@ -1,13 +1,81 @@
from .geo import Geo
from .geomesh import *
from .bones import *
import bpy.path
import bpy
import mathutils
def import_scale_coord(v, scale):
return (v[0] * scale, v[1] * scale, v[2] * scale)
if 0:
def import_fix_coord(v):
return (v[0], v[2], -v[1])
def import_fix_normal(v):
return (-v[0], -v[2], v[1])
def import_fix_winding(l):
l = list(l)
l.reverse()
return l
else:
def import_fix_coord(v):
return (-v[0], v[2], -v[1])
def import_fix_normal(v):
return ( v[0], -v[2], v[1])
def import_fix_winding(l):
return l
def convert_model(geo_model, mesh_data, obj, scale):
#Convert the geo_model into a GeoMesh.
geomesh = geo_model.saveToGeoMesh()
indices = [i for face in geomesh.face for i in import_fix_winding(face.vert_indexes)]
texture_indices = [face.texture_index for face in geomesh.face]
mesh_data.vertices.add(len(geomesh.geovertex))
mesh_data.loops.add(len(indices))
mesh_data.polygons.add(len(geomesh.face))
coords = [c for v in geomesh.geovertex for c in import_scale_coord(import_fix_coord(v.coord), scale)]
normals = [n for v in geomesh.geovertex for n in import_fix_normal(v.normal)]
loop_totals = []
loop_starts = []
i = 0
for f in geomesh.face:
loop_totals.append(len(f.vert_indexes))
loop_starts.append(i)
i += loop_totals[-1]
mesh_data.vertices.foreach_set("co", coords)
mesh_data.vertices.foreach_set("normal", normals)
mesh_data.loops.foreach_set("vertex_index", indices)
mesh_data.polygons.foreach_set("loop_start", loop_starts)
mesh_data.polygons.foreach_set("loop_total", loop_totals)
mesh_data.polygons.foreach_set("material_index", texture_indices)
#mesh_data.update()
vgroup = {}
for w_name in geomesh.weights:
vgroup[w_name] = obj.vertex_groups.new(name=w_name)
for i, v in enumerate(geomesh.geovertex):
for w in v.weights:
#print("vertex idx: %s group: %s weight: %s" % (i, w[0], w[1]))
vgroup[w[0]].add([i], w[1], 'REPLACE')
#for v in ob.vertices:
# weight_values.append( v.groups[o.vertex_groups[vg_name].index].weight )
#???mesh_data.validate(False)
d = mesh_data.uv_layers.new().data
uvs = [c for f in geomesh.face for i in f.vert_indexes for c in geomesh.geovertex[i].uv]
d.foreach_set('uv', uvs)
mesh_data.validate()
mesh_data.update()
mesh_data.vertices.foreach_set("normal", normals)
mesh_data.update()
def convert_model(geo_model, mesh, obj):
#Create vertices
#todo: populate coordinates
#todo: populate normals
#todo: create edges
#todo: create faces
#todo: populate uvs
mesh.validate()
mesh.update()
#todo: attempt to load textures/images
@ -19,15 +87,16 @@ def load(operator, context, scale = 1.0, filepath = "", global_matrix = None, us
fh_in.close()
for geo_model in geo.models:
#create object matching model's name (or next equivilant)
mesh = bpy.data.meshes.new(name = model.name.decode("utf-8"))
mesh = bpy.data.meshes.new(name = geo_model.name.decode("utf-8"))
obj = bpy.data.objects.new(geo_model.name.decode("utf-8"), mesh)
#convert model to mesh
convert_mode(geo_model, mesh, None)
convert_model(geo_model, mesh, obj, scale)
#Create object for this mesh
scn = bpy.context.scene
obj = bpy.data.objects.new(ply_name, mesh)
scn.objects.link(obj)
scn.objects.active = obj
obj.select = True
bpy.context.collection.objects.link(obj)
bpy.context.view_layer.objects.active = obj
obj.select_set(True)
pass
pass
return {'FINISHED'}

Loading…
Cancel
Save