Added .geo import support for blender 2.80 .

master
TigerKat 4 years ago
parent 5b7c1abed4
commit bf0e940a57

@ -2,7 +2,7 @@
bl_info = { bl_info = {
"name": "City of Heroes (.geo)", "name": "City of Heroes (.geo)",
"author": "TigerKat", "author": "TigerKat",
"version": (0, 2, 0), "version": (0, 2, 1),
"blender": (2, 80, 0), "blender": (2, 80, 0),
"location": "File > Import/Export,", "location": "File > Import/Export,",
"description": "City of Heroes (.geo)", "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) return export_geo.save(self, context, 1.0 / 0.30480000376701355, **keywords)
def menu_func_import(self, context): def menu_func_import(self, context):
self.layout.operator(ImportGeo.bl_idname, self.layout.operator(ImportGeo.bl_idname,
text="City of Heroes (Feet) (.geo)") text="City of Heroes (Feet) (.geo)")

@ -9,10 +9,12 @@ try:
from .bones import * from .bones import *
from .polygrid import PolyCell, PolyGrid from .polygrid import PolyCell, PolyGrid
from .util import Data from .util import Data
from .geomesh import GeoMesh, GeoFace, GeoVertex
except: except:
from bones import * from bones import *
from polygrid import PolyCell, PolyGrid from polygrid import PolyCell, PolyGrid
from util import Data from util import Data
from geomesh import GeoMesh, GeoFace, GeoVertex
#Ver 0 .geo pre-header: #Ver 0 .geo pre-header:
#Offset Size Description #Offset Size Description
@ -914,17 +916,29 @@ class Model:
uv = (0, 0) uv = (0, 0)
if geomesh.have_weights: if geomesh.have_weights:
weights = [] weights = []
for i, w in enumerate(self.weights): #print("verts #: %s weights #: %s weight bones #: %s" % (len(self.verts), len(self.weights), len(self.weight_bones)))
weights.append([self.weight_bones[i], w]) #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: else:
weights = [] weights = []
v = GeoVertex(coord, normal, uv, self.weights) #print(" weights: %s" % (weights, ))
v = GeoVertex(coord, normal, uv, weights)
geomesh.getGeoVertexIndex(v) geomesh.getGeoVertexIndex(v)
texture_indexes = [] texture_indexes = []
for t in self.tex_idx: for t in self.tex_idx:
texture_indexes += [geomesh.getTextureIndex(self.geo.header_texnames[t[0]])] * t[1] texture_indexes += [geomesh.getTextureIndex(self.geo.header_texnames[t[0]])] * t[1]
for i, t in enumerate(self.tris): 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 return geomesh
def loadFromGeoMesh(self, geomesh): def loadFromGeoMesh(self, geomesh):
self.tris = [] #uncompressDeltas(self.tris_data, 3, self.tri_count, "I") self.tris = [] #uncompressDeltas(self.tris_data, 3, self.tri_count, "I")

@ -11,11 +11,12 @@ class GeoVertex:
self.coord = coord self.coord = coord
self.normal = normal self.normal = normal
self.uv = uv self.uv = uv
self.weights = weights self.weights = tuple(weights)
def __eq__(self, other): def __eq__(self, other):
return self.coord == other.coord and self.normal == other.normal and self.uv == other.uv and self.weights == other.weights return self.coord == other.coord and self.normal == other.normal and self.uv == other.uv and self.weights == other.weights
def __hash__(self): def __hash__(self):
#print("__hash__: %s" % ((tuple(self.coord), tuple(self.normal), tuple(self.uv), tuple(self.weights)), )) #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))) return hash((tuple(self.coord), tuple(self.normal), tuple(self.uv), tuple_weights(self.weights)))
def selectWeights(self, count = None): 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.""" """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 return
for i in range(3): for i in range(3):
for w in geovertices[i].weights: for w in geovertices[i].weights:
w[0] = self.getWeightIndex(w[0]) # w_index = self.getWeightIndex(w[0])
self.have_weights = True self.have_weights = True
geovertices_index = [self.getGeoVertexIndex(geovertices[0]), geovertices_index = [self.getGeoVertexIndex(geovertices[0]),
self.getGeoVertexIndex(geovertices[1]), 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 #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() fh_in.close()
for geo_model in geo.models: for geo_model in geo.models:
#create object matching model's name (or next equivilant) #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 model to mesh
convert_mode(geo_model, mesh, None) convert_model(geo_model, mesh, obj, scale)
#Create object for this mesh #Create object for this mesh
scn = bpy.context.scene scn = bpy.context.scene
obj = bpy.data.objects.new(ply_name, mesh) bpy.context.collection.objects.link(obj)
scn.objects.link(obj) bpy.context.view_layer.objects.active = obj
scn.objects.active = obj obj.select_set(True)
obj.select = True
pass pass
pass pass
return {'FINISHED'}

Loading…
Cancel
Save