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())
|
if (banks.empty())
|
||||||
addSkinBank(skinSlotCount);
|
addSkinBank(skinSlotCount);
|
||||||
std::vector<uint32_t> toAdd;
|
std::vector<uint32_t> toAdd;
|
||||||
toAdd.reserve(skinSlotCount);
|
if (skinSlotCount > 0)
|
||||||
|
toAdd.reserve(skinSlotCount);
|
||||||
std::vector<std::vector<uint32_t>>::iterator bankIt = banks.begin();
|
std::vector<std::vector<uint32_t>>::iterator bankIt = banks.begin();
|
||||||
for (;;)
|
for (;;)
|
||||||
{
|
{
|
||||||
|
@ -668,7 +669,7 @@ uint32_t BlenderConnection::DataStream::Mesh::SkinBanks::addSurface
|
||||||
if (!VertInBank(bank, v.iSkin) && !VertInBank(toAdd, v.iSkin))
|
if (!VertInBank(bank, v.iSkin) && !VertInBank(toAdd, v.iSkin))
|
||||||
{
|
{
|
||||||
toAdd.push_back(v.iSkin);
|
toAdd.push_back(v.iSkin);
|
||||||
if (bank.size() + toAdd.size() > skinSlotCount)
|
if (skinSlotCount > 0 && bank.size() + toAdd.size() > skinSlotCount)
|
||||||
{
|
{
|
||||||
toAdd.clear();
|
toAdd.clear();
|
||||||
done = false;
|
done = false;
|
||||||
|
|
|
@ -290,16 +290,19 @@ public:
|
||||||
{
|
{
|
||||||
atVec2f val;
|
atVec2f val;
|
||||||
Vector2f(BlenderConnection& conn) {conn._readBuf(&val, 8);}
|
Vector2f(BlenderConnection& conn) {conn._readBuf(&val, 8);}
|
||||||
|
operator const atVec2f&() const {return val;}
|
||||||
};
|
};
|
||||||
struct Vector3f
|
struct Vector3f
|
||||||
{
|
{
|
||||||
atVec3f val;
|
atVec3f val;
|
||||||
Vector3f(BlenderConnection& conn) {conn._readBuf(&val, 12);}
|
Vector3f(BlenderConnection& conn) {conn._readBuf(&val, 12);}
|
||||||
|
operator const atVec3f&() const {return val;}
|
||||||
};
|
};
|
||||||
struct Index
|
struct Index
|
||||||
{
|
{
|
||||||
uint32_t val;
|
uint32_t val;
|
||||||
Index(BlenderConnection& conn) {conn._readBuf(&val, 4);}
|
Index(BlenderConnection& conn) {conn._readBuf(&val, 4);}
|
||||||
|
operator const uint32_t&() const {return val;}
|
||||||
};
|
};
|
||||||
|
|
||||||
/* Cumulative AABB */
|
/* Cumulative AABB */
|
||||||
|
@ -370,7 +373,8 @@ public:
|
||||||
std::vector<std::vector<uint32_t>>::iterator addSkinBank(int skinSlotCount)
|
std::vector<std::vector<uint32_t>>::iterator addSkinBank(int skinSlotCount)
|
||||||
{
|
{
|
||||||
banks.emplace_back();
|
banks.emplace_back();
|
||||||
banks.back().reserve(skinSlotCount);
|
if (skinSlotCount > 0)
|
||||||
|
banks.back().reserve(skinSlotCount);
|
||||||
return banks.end() - 1;
|
return banks.end() - 1;
|
||||||
}
|
}
|
||||||
uint32_t addSurface(const Surface& surf, int skinSlotCount);
|
uint32_t addSurface(const Surface& surf, int skinSlotCount);
|
||||||
|
|
|
@ -133,6 +133,34 @@ class VertPool:
|
||||||
sp = struct.pack('I', self.get_skin_idx(loop.vert))
|
sp = struct.pack('I', self.get_skin_idx(loop.vert))
|
||||||
writebuf(sp)
|
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):
|
def recursive_faces_islands(dlay, list_out, rem_list, skin_slot_set, skin_slot_count, face):
|
||||||
if face not in rem_list:
|
if face not in rem_list:
|
||||||
return []
|
return []
|
||||||
|
@ -140,9 +168,10 @@ def recursive_faces_islands(dlay, list_out, rem_list, skin_slot_set, skin_slot_c
|
||||||
if dlay:
|
if dlay:
|
||||||
for v in face.verts:
|
for v in face.verts:
|
||||||
sg = tuple(sorted(v[dlay].items()))
|
sg = tuple(sorted(v[dlay].items()))
|
||||||
if sg not in skin_slot_set and len(skin_slot_set) == skin_slot_count:
|
if sg not in skin_slot_set:
|
||||||
return False
|
if skin_slot_count > 0 and len(skin_slot_set) == skin_slot_count:
|
||||||
skin_slot_set.add(sg)
|
return False
|
||||||
|
skin_slot_set.add(sg)
|
||||||
|
|
||||||
list_out.append(face)
|
list_out.append(face)
|
||||||
rem_list.remove(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:
|
for f in max_sl:
|
||||||
island_faces.remove(f)
|
island_faces.remove(f)
|
||||||
last_loop, next_idx = stripify_primitive(writebuf, vert_pool, max_sl, last_loop, next_idx)
|
last_loop, next_idx = stripify_primitive(writebuf, vert_pool, max_sl, last_loop, next_idx)
|
||||||
|
|
||||||
writebuf(struct.pack('B', 0))
|
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):
|
if len(bm_master.verts.layers.deform):
|
||||||
dlay = bm_master.verts.layers.deform[0]
|
dlay = bm_master.verts.layers.deform[0]
|
||||||
|
|
||||||
# Generate island meshes
|
# Generate material meshes (if opaque)
|
||||||
for mat_idx in sorted_material_idxs:
|
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 = []
|
mat_faces_rem = []
|
||||||
for face in bm_master.faces:
|
for face in bm_master.faces:
|
||||||
if face.material_index == mat_idx:
|
if face.material_index == mat_idx:
|
||||||
mat_faces_rem.append(face)
|
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):
|
while len(mat_faces_rem):
|
||||||
the_list = []
|
the_list = []
|
||||||
skin_slot_set = set()
|
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[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[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[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;
|
return *this;
|
||||||
}
|
}
|
||||||
Color& operator=(uint8_t val)
|
Color& operator=(uint8_t val)
|
||||||
|
@ -426,6 +434,7 @@ struct GX : IBackend
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
Color(const atVec4f& vec) {*this = vec;}
|
Color(const atVec4f& vec) {*this = vec;}
|
||||||
|
Color(const atVec3f& vec) {*this = vec;}
|
||||||
Color(uint8_t val) {*this = val;}
|
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;}
|
||||||
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;
|
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);
|
void reset(const IR& ir, Diagnostics& diag);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
|
@ -14,6 +14,7 @@ unsigned GX::addKColor(Diagnostics& diag, const SourceLocation& loc, const Color
|
||||||
if (m_kcolorCount >= 4)
|
if (m_kcolorCount >= 4)
|
||||||
diag.reportBackendErr(loc, "GX KColor overflow");
|
diag.reportBackendErr(loc, "GX KColor overflow");
|
||||||
m_kcolors[m_kcolorCount] = color;
|
m_kcolors[m_kcolorCount] = color;
|
||||||
|
m_kcolors[m_kcolorCount].color[3] = 0;
|
||||||
return m_kcolorCount++;
|
return m_kcolorCount++;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue