mirror of https://github.com/AxioDL/metaforce.git
Optimization refinements in mesh cooker
This commit is contained in:
parent
2044a4b9b1
commit
3a4647e4c3
|
@ -654,7 +654,8 @@ uint32_t BlenderConnection::DataStream::Mesh::SkinBanks::addSurface
|
|||
if (banks.empty())
|
||||
addSkinBank(skinSlotCount);
|
||||
std::vector<uint32_t> toAdd;
|
||||
toAdd.reserve(skinSlotCount);
|
||||
if (skinSlotCount > 0)
|
||||
toAdd.reserve(skinSlotCount);
|
||||
std::vector<std::vector<uint32_t>>::iterator bankIt = banks.begin();
|
||||
for (;;)
|
||||
{
|
||||
|
@ -668,7 +669,7 @@ uint32_t BlenderConnection::DataStream::Mesh::SkinBanks::addSurface
|
|||
if (!VertInBank(bank, v.iSkin) && !VertInBank(toAdd, v.iSkin))
|
||||
{
|
||||
toAdd.push_back(v.iSkin);
|
||||
if (bank.size() + toAdd.size() > skinSlotCount)
|
||||
if (skinSlotCount > 0 && bank.size() + toAdd.size() > skinSlotCount)
|
||||
{
|
||||
toAdd.clear();
|
||||
done = false;
|
||||
|
|
|
@ -290,16 +290,19 @@ public:
|
|||
{
|
||||
atVec2f val;
|
||||
Vector2f(BlenderConnection& conn) {conn._readBuf(&val, 8);}
|
||||
operator const atVec2f&() const {return val;}
|
||||
};
|
||||
struct Vector3f
|
||||
{
|
||||
atVec3f val;
|
||||
Vector3f(BlenderConnection& conn) {conn._readBuf(&val, 12);}
|
||||
operator const atVec3f&() const {return val;}
|
||||
};
|
||||
struct Index
|
||||
{
|
||||
uint32_t val;
|
||||
Index(BlenderConnection& conn) {conn._readBuf(&val, 4);}
|
||||
operator const uint32_t&() const {return val;}
|
||||
};
|
||||
|
||||
/* Cumulative AABB */
|
||||
|
@ -370,7 +373,8 @@ public:
|
|||
std::vector<std::vector<uint32_t>>::iterator addSkinBank(int skinSlotCount)
|
||||
{
|
||||
banks.emplace_back();
|
||||
banks.back().reserve(skinSlotCount);
|
||||
if (skinSlotCount > 0)
|
||||
banks.back().reserve(skinSlotCount);
|
||||
return banks.end() - 1;
|
||||
}
|
||||
uint32_t addSurface(const Surface& surf, int skinSlotCount);
|
||||
|
|
|
@ -133,6 +133,34 @@ class VertPool:
|
|||
sp = struct.pack('I', self.get_skin_idx(loop.vert))
|
||||
writebuf(sp)
|
||||
|
||||
def sort_faces_by_skin_group(dlay, faces):
|
||||
faces_out = []
|
||||
done_sg = set()
|
||||
ref_sg = None
|
||||
while len(faces_out) < len(faces):
|
||||
for f in faces:
|
||||
found = False
|
||||
for v in f.verts:
|
||||
sg = tuple(sorted(v[dlay].items()))
|
||||
if sg not in done_sg:
|
||||
ref_sg = sg
|
||||
done_sg.add(ref_sg)
|
||||
found = True
|
||||
break
|
||||
if found:
|
||||
break
|
||||
|
||||
for f in faces:
|
||||
if f in faces_out:
|
||||
continue
|
||||
for v in f.verts:
|
||||
sg = tuple(sorted(v[dlay].items()))
|
||||
if sg == ref_sg:
|
||||
faces_out.append(f)
|
||||
break
|
||||
|
||||
return faces_out
|
||||
|
||||
def recursive_faces_islands(dlay, list_out, rem_list, skin_slot_set, skin_slot_count, face):
|
||||
if face not in rem_list:
|
||||
return []
|
||||
|
@ -140,9 +168,10 @@ def recursive_faces_islands(dlay, list_out, rem_list, skin_slot_set, skin_slot_c
|
|||
if dlay:
|
||||
for v in face.verts:
|
||||
sg = tuple(sorted(v[dlay].items()))
|
||||
if sg not in skin_slot_set and len(skin_slot_set) == skin_slot_count:
|
||||
return False
|
||||
skin_slot_set.add(sg)
|
||||
if sg not in skin_slot_set:
|
||||
if skin_slot_count > 0 and len(skin_slot_set) == skin_slot_count:
|
||||
return False
|
||||
skin_slot_set.add(sg)
|
||||
|
||||
list_out.append(face)
|
||||
rem_list.remove(face)
|
||||
|
@ -321,5 +350,6 @@ def write_out_surface(writebuf, vert_pool, island_faces, mat_idx):
|
|||
for f in max_sl:
|
||||
island_faces.remove(f)
|
||||
last_loop, next_idx = stripify_primitive(writebuf, vert_pool, max_sl, last_loop, next_idx)
|
||||
|
||||
writebuf(struct.pack('B', 0))
|
||||
|
||||
|
|
|
@ -166,12 +166,52 @@ def cook(writebuf, mesh_obj, max_skin_banks, max_octant_length=None):
|
|||
if len(bm_master.verts.layers.deform):
|
||||
dlay = bm_master.verts.layers.deform[0]
|
||||
|
||||
# Generate island meshes
|
||||
# Generate material meshes (if opaque)
|
||||
for mat_idx in sorted_material_idxs:
|
||||
mat = mesh_obj.data.materials[mat_idx]
|
||||
if mat.game_settings.alpha_blend != 'OPAQUE':
|
||||
continue
|
||||
mat_faces_rem = []
|
||||
for face in bm_master.faces:
|
||||
if face.material_index == mat_idx:
|
||||
mat_faces_rem.append(face)
|
||||
if dlay:
|
||||
mat_faces_rem = HMDLMesh.sort_faces_by_skin_group(dlay, mat_faces_rem)
|
||||
while len(mat_faces_rem):
|
||||
the_list = []
|
||||
skin_slot_set = set()
|
||||
faces = list(mat_faces_rem)
|
||||
for f in faces:
|
||||
ret_faces = None
|
||||
for v in f.verts:
|
||||
sg = tuple(sorted(v[dlay].items()))
|
||||
if sg not in skin_slot_set:
|
||||
if max_skin_banks > 0 and len(skin_slot_set) == max_skin_banks:
|
||||
ret_faces = False
|
||||
break
|
||||
skin_slot_set.add(sg)
|
||||
|
||||
if ret_faces == False:
|
||||
break
|
||||
|
||||
the_list.append(f)
|
||||
mat_faces_rem.remove(f)
|
||||
|
||||
writebuf(struct.pack('B', 1))
|
||||
HMDLMesh.write_out_surface(writebuf, vert_pool, the_list, mat_idx)
|
||||
|
||||
|
||||
# Generate island meshes (if transparent)
|
||||
for mat_idx in sorted_material_idxs:
|
||||
mat = mesh_obj.data.materials[mat_idx]
|
||||
if mat.game_settings.alpha_blend == 'OPAQUE':
|
||||
continue
|
||||
mat_faces_rem = []
|
||||
for face in bm_master.faces:
|
||||
if face.material_index == mat_idx:
|
||||
mat_faces_rem.append(face)
|
||||
if dlay:
|
||||
mat_faces_rem = HMDLMesh.sort_faces_by_skin_group(dlay, mat_faces_rem)
|
||||
while len(mat_faces_rem):
|
||||
the_list = []
|
||||
skin_slot_set = set()
|
||||
|
|
|
@ -414,7 +414,15 @@ struct GX : IBackend
|
|||
color[0] = uint8_t(std::min(std::max(vec.vec[0] * 255.f, 0.f), 255.f));
|
||||
color[1] = uint8_t(std::min(std::max(vec.vec[1] * 255.f, 0.f), 255.f));
|
||||
color[2] = uint8_t(std::min(std::max(vec.vec[2] * 255.f, 0.f), 255.f));
|
||||
color[3] = 0;
|
||||
color[3] = uint8_t(std::min(std::max(vec.vec[3] * 255.f, 0.f), 255.f));
|
||||
return *this;
|
||||
}
|
||||
Color& operator=(const atVec3f& vec)
|
||||
{
|
||||
color[0] = uint8_t(std::min(std::max(vec.vec[0] * 255.f, 0.f), 255.f));
|
||||
color[1] = uint8_t(std::min(std::max(vec.vec[1] * 255.f, 0.f), 255.f));
|
||||
color[2] = uint8_t(std::min(std::max(vec.vec[2] * 255.f, 0.f), 255.f));
|
||||
color[3] = 0xff;
|
||||
return *this;
|
||||
}
|
||||
Color& operator=(uint8_t val)
|
||||
|
@ -426,6 +434,7 @@ struct GX : IBackend
|
|||
return *this;
|
||||
}
|
||||
Color(const atVec4f& vec) {*this = vec;}
|
||||
Color(const atVec3f& vec) {*this = vec;}
|
||||
Color(uint8_t val) {*this = val;}
|
||||
bool operator==(const Color& other) const {return num == other.num;}
|
||||
bool operator!=(const Color& other) const {return num != other.num;}
|
||||
|
@ -444,6 +453,68 @@ struct GX : IBackend
|
|||
|
||||
int m_alphaTraceStage = -1;
|
||||
|
||||
bool operator==(const GX& other) const
|
||||
{
|
||||
if (m_tcgCount != other.m_tcgCount)
|
||||
return false;
|
||||
if (m_tevCount != other.m_tevCount)
|
||||
return false;
|
||||
if (m_blendSrc != other.m_blendSrc)
|
||||
return false;
|
||||
if (m_blendDst != other.m_blendDst)
|
||||
return false;
|
||||
if (m_kcolorCount != other.m_kcolorCount)
|
||||
return false;
|
||||
for (unsigned i=0 ; i<m_tcgCount ; ++i)
|
||||
{
|
||||
const TexCoordGen& a = m_tcgs[i];
|
||||
const TexCoordGen& b = other.m_tcgs[i];
|
||||
if (a.m_src != b.m_src)
|
||||
return false;
|
||||
if (a.m_mtx != b.m_mtx)
|
||||
return false;
|
||||
}
|
||||
for (unsigned i=0 ; i<m_tevCount ; ++i)
|
||||
{
|
||||
const TEVStage& a = m_tevs[i];
|
||||
const TEVStage& b = other.m_tevs[i];
|
||||
for (unsigned j=0 ; j<4 ; ++j)
|
||||
if (a.m_color[j] != b.m_color[j])
|
||||
return false;
|
||||
for (unsigned j=0 ; j<4 ; ++j)
|
||||
if (a.m_alpha[j] != b.m_alpha[j])
|
||||
return false;
|
||||
if (a.m_cop != b.m_cop)
|
||||
return false;
|
||||
if (a.m_aop != b.m_aop)
|
||||
return false;
|
||||
if (a.m_kColor != b.m_kColor)
|
||||
return false;
|
||||
if (a.m_kAlpha != b.m_kAlpha)
|
||||
return false;
|
||||
if (a.m_cRegOut != b.m_cRegOut)
|
||||
return false;
|
||||
if (a.m_aRegOut != b.m_aRegOut)
|
||||
return false;
|
||||
if (a.m_texMapIdx != b.m_texMapIdx)
|
||||
return false;
|
||||
if (a.m_texGenIdx != b.m_texGenIdx)
|
||||
return false;
|
||||
}
|
||||
for (unsigned i=0 ; i<m_kcolorCount ; ++i)
|
||||
{
|
||||
const Color& a = m_kcolors[i];
|
||||
const Color& b = other.m_kcolors[i];
|
||||
if (a.num != b.num)
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
bool operator!=(const GX& other) const
|
||||
{
|
||||
return !(*this == other);
|
||||
}
|
||||
|
||||
void reset(const IR& ir, Diagnostics& diag);
|
||||
|
||||
private:
|
||||
|
|
|
@ -14,6 +14,7 @@ unsigned GX::addKColor(Diagnostics& diag, const SourceLocation& loc, const Color
|
|||
if (m_kcolorCount >= 4)
|
||||
diag.reportBackendErr(loc, "GX KColor overflow");
|
||||
m_kcolors[m_kcolorCount] = color;
|
||||
m_kcolors[m_kcolorCount].color[3] = 0;
|
||||
return m_kcolorCount++;
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue