Convert spm to GE spm
This commit is contained in:
parent
096b408b9c
commit
92accb352e
@ -37,6 +37,9 @@ const uint8_t VERSION_NOW = 1;
|
||||
#include <IVideoDriver.h>
|
||||
#include <IFileSystem.h>
|
||||
#ifndef SERVER_ONLY
|
||||
#include <ge_main.hpp>
|
||||
#include <ge_spm_buffer.hpp>
|
||||
#include <ge_spm.hpp>
|
||||
#include <ge_texture.hpp>
|
||||
#endif
|
||||
|
||||
@ -67,7 +70,19 @@ scene::IAnimatedMesh* SPMeshLoader::createMesh(io::IReadFile* f)
|
||||
m_joint_count = 0;
|
||||
m_frame_count = 0;
|
||||
m_mesh = NULL;
|
||||
m_mesh = real_spm ? new SP::SPMesh() : m_scene_manager->createSkinnedMesh();
|
||||
bool ge_spm = false;
|
||||
#ifndef SERVER_ONLY
|
||||
if (GE::getVKDriver())
|
||||
{
|
||||
ge_spm = true;
|
||||
m_mesh = new GE::GESPM();
|
||||
}
|
||||
#endif
|
||||
if (!m_mesh)
|
||||
{
|
||||
m_mesh = real_spm ?
|
||||
new SP::SPMesh() : m_scene_manager->createSkinnedMesh();
|
||||
}
|
||||
io::IFileSystem* fs = m_scene_manager->getFileSystem();
|
||||
std::string base_path = fs->getFileDir(f->getFileName()).c_str();
|
||||
std::string header;
|
||||
@ -257,6 +272,14 @@ scene::IAnimatedMesh* SPMeshLoader::createMesh(io::IReadFile* f)
|
||||
std::get<2>(sp_mat_map[mat_id]), vt,
|
||||
std::get<0>(sp_mat_map[mat_id]));
|
||||
}
|
||||
else if (ge_spm)
|
||||
{
|
||||
assert(mat_id < mat_map.size());
|
||||
decompressGESPM(f, vertices_count, indices_count, read_normal,
|
||||
read_vcolor, read_tangent, std::get<1>(mat_map[mat_id]),
|
||||
std::get<2>(mat_map[mat_id]), vt,
|
||||
std::get<0>(mat_map[mat_id]));
|
||||
}
|
||||
else
|
||||
{
|
||||
assert(mat_id < mat_map.size());
|
||||
@ -313,11 +336,11 @@ scene::IAnimatedMesh* SPMeshLoader::createMesh(io::IReadFile* f)
|
||||
spm->m_all_armatures = std::move(m_all_armatures);
|
||||
}
|
||||
m_mesh->finalize();
|
||||
if (!real_spm && has_armature)
|
||||
scene::CSkinnedMesh* cmesh = dynamic_cast<scene::CSkinnedMesh*>(m_mesh);
|
||||
if (cmesh && !real_spm && has_armature)
|
||||
{
|
||||
// Because the last frame in spm is usable
|
||||
static_cast<scene::CSkinnedMesh*>(m_mesh)->AnimationFrames =
|
||||
(float)m_frame_count + 1.0f;
|
||||
cmesh->AnimationFrames = (float)m_frame_count + 1.0f;
|
||||
}
|
||||
m_all_armatures.clear();
|
||||
m_to_bind_pose_matrices.clear();
|
||||
@ -431,6 +454,118 @@ void SPMeshLoader::decompressSPM(irr::io::IReadFile* spm,
|
||||
|
||||
} // decompressSPM
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
void SPMeshLoader::decompressGESPM(irr::io::IReadFile* spm,
|
||||
unsigned vertices_count,
|
||||
unsigned indices_count, bool read_normal,
|
||||
bool read_vcolor, bool read_tangent,
|
||||
bool uv_one, bool uv_two, SPVertexType vt,
|
||||
const video::SMaterial& m)
|
||||
{
|
||||
#ifndef SERVER_ONLY
|
||||
assert(vertices_count != 0);
|
||||
assert(indices_count != 0);
|
||||
|
||||
GE::GESPMBuffer* mb = new GE::GESPMBuffer();
|
||||
static_cast<GE::GESPM*>(m_mesh)->m_buffer.push_back(mb);
|
||||
std::vector<video::S3DVertexSkinnedMesh> vertices;
|
||||
const unsigned idx_size = vertices_count > 255 ? 2 : 1;
|
||||
for (unsigned i = 0; i < vertices_count; i++)
|
||||
{
|
||||
video::S3DVertexSkinnedMesh vertex = {};
|
||||
// 3 * float position
|
||||
spm->read(&vertex.m_position, 12);
|
||||
if (read_normal)
|
||||
{
|
||||
spm->read(&vertex.m_normal, 4);
|
||||
}
|
||||
else
|
||||
{
|
||||
// 0, 1, 0
|
||||
vertex.m_normal = 0x1FF << 10;
|
||||
}
|
||||
if (read_vcolor)
|
||||
{
|
||||
// Color identifier
|
||||
uint8_t ci;
|
||||
spm->read(&ci, 1);
|
||||
if (ci == 128)
|
||||
{
|
||||
// All white
|
||||
vertex.m_color = video::SColor(255, 255, 255, 255);
|
||||
}
|
||||
else
|
||||
{
|
||||
uint8_t r, g, b;
|
||||
spm->read(&r, 1);
|
||||
spm->read(&g, 1);
|
||||
spm->read(&b, 1);
|
||||
vertex.m_color = video::SColor(255, r, g, b);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
vertex.m_color = video::SColor(255, 255, 255, 255);
|
||||
}
|
||||
if (uv_one)
|
||||
{
|
||||
spm->read(&vertex.m_all_uvs[0], 4);
|
||||
if (uv_two)
|
||||
{
|
||||
spm->read(&vertex.m_all_uvs[2], 4);
|
||||
}
|
||||
if (read_tangent)
|
||||
{
|
||||
spm->read(&vertex.m_tangent, 4);
|
||||
}
|
||||
else
|
||||
{
|
||||
vertex.m_tangent = MiniGLM::quickTangent(vertex.m_normal);
|
||||
}
|
||||
}
|
||||
if (vt == SPVT_SKINNED)
|
||||
{
|
||||
spm->read(&vertex.m_joint_idx[0], 16);
|
||||
if (vertex.m_joint_idx[0] == -1 ||
|
||||
vertex.m_weight[0] == 0 ||
|
||||
// -0.0 in half float (16bit)
|
||||
vertex.m_weight[0] == -32768)
|
||||
{
|
||||
// For the skinned mesh shader
|
||||
vertex.m_joint_idx[0] = -32767;
|
||||
// 1.0 in half float (16bit)
|
||||
vertex.m_weight[0] = 15360;
|
||||
}
|
||||
}
|
||||
vertices.push_back(vertex);
|
||||
}
|
||||
|
||||
std::vector<uint16_t> indices;
|
||||
indices.resize(indices_count);
|
||||
if (idx_size == 2)
|
||||
{
|
||||
spm->read(indices.data(), indices_count * 2);
|
||||
}
|
||||
else
|
||||
{
|
||||
std::vector<uint8_t> tmp_idx;
|
||||
tmp_idx.resize(indices_count);
|
||||
spm->read(tmp_idx.data(), indices_count);
|
||||
for (unsigned i = 0; i < indices_count; i++)
|
||||
{
|
||||
indices[i] = tmp_idx[i];
|
||||
}
|
||||
}
|
||||
std::swap(mb->m_vertices, vertices);
|
||||
std::swap(mb->m_indices, indices);
|
||||
if (m.TextureLayer[0].Texture != NULL)
|
||||
{
|
||||
mb->m_material = m;
|
||||
}
|
||||
mb->recalculateBoundingBox();
|
||||
#endif
|
||||
} // decompressGESPM
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
void SPMeshLoader::decompress(irr::io::IReadFile* spm, unsigned vertices_count,
|
||||
unsigned indices_count, bool read_normal,
|
||||
@ -440,7 +575,8 @@ void SPMeshLoader::decompress(irr::io::IReadFile* spm, unsigned vertices_count,
|
||||
{
|
||||
assert(vertices_count != 0);
|
||||
assert(indices_count != 0);
|
||||
scene::SSkinMeshBuffer* mb = m_mesh->addMeshBuffer();
|
||||
scene::SSkinMeshBuffer* mb =
|
||||
static_cast<scene::CSkinnedMesh*>(m_mesh)->addMeshBuffer();
|
||||
if (uv_two)
|
||||
{
|
||||
mb->convertTo2TCoords();
|
||||
@ -603,17 +739,18 @@ void SPMeshLoader::createAnimationData(irr::io::IReadFile* spm)
|
||||
accumulated_joints += m_all_armatures[i].m_joint_used;
|
||||
}
|
||||
|
||||
scene::ISkinnedMesh* smesh = dynamic_cast<scene::ISkinnedMesh*>(m_mesh);
|
||||
// Only for legacy device
|
||||
if (m_joints.empty())
|
||||
if (!smesh || m_joints.empty())
|
||||
{
|
||||
return;
|
||||
}
|
||||
assert(m_joints.size() == m_mesh->getMeshBufferCount());
|
||||
assert(m_joints.size() == smesh->getMeshBufferCount());
|
||||
for (unsigned i = 0; i < m_to_bind_pose_matrices.size(); i++)
|
||||
{
|
||||
m_to_bind_pose_matrices[i].makeInverse();
|
||||
}
|
||||
for (unsigned i = 0; i < m_mesh->getMeshBufferCount(); i++)
|
||||
for (unsigned i = 0; i < smesh->getMeshBufferCount(); i++)
|
||||
{
|
||||
for (unsigned j = 0; j < m_joints[i].size(); j++)
|
||||
{
|
||||
@ -630,15 +767,15 @@ void SPMeshLoader::createAnimationData(irr::io::IReadFile* spm)
|
||||
core::vector3df cur_pos, cur_nor;
|
||||
m_to_bind_pose_matrices[m_joints[i][j].first[k]]
|
||||
.transformVect(cur_pos,
|
||||
m_mesh->getMeshBuffers()[i]->getVertex(j)->Pos);
|
||||
smesh->getMeshBuffers()[i]->getVertex(j)->Pos);
|
||||
bind_pos += cur_pos * m_joints[i][j].second[k];
|
||||
m_to_bind_pose_matrices[m_joints[i][j].first[k]]
|
||||
.rotateVect(cur_nor,
|
||||
m_mesh->getMeshBuffers()[i]->getVertex(j)->Normal);
|
||||
smesh->getMeshBuffers()[i]->getVertex(j)->Normal);
|
||||
bind_nor += cur_nor * m_joints[i][j].second[k];
|
||||
}
|
||||
m_mesh->getMeshBuffers()[i]->getVertex(j)->Pos = bind_pos;
|
||||
m_mesh->getMeshBuffers()[i]->getVertex(j)->Normal = bind_nor;
|
||||
smesh->getMeshBuffers()[i]->getVertex(j)->Pos = bind_pos;
|
||||
smesh->getMeshBuffers()[i]->getVertex(j)->Normal = bind_nor;
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -647,8 +784,9 @@ void SPMeshLoader::createAnimationData(irr::io::IReadFile* spm)
|
||||
// ----------------------------------------------------------------------------
|
||||
void SPMeshLoader::convertIrrlicht()
|
||||
{
|
||||
scene::ISkinnedMesh* smesh = dynamic_cast<scene::ISkinnedMesh*>(m_mesh);
|
||||
// Only for legacy device
|
||||
if (m_joints.empty())
|
||||
if (!smesh || m_joints.empty())
|
||||
{
|
||||
return;
|
||||
}
|
||||
@ -659,9 +797,9 @@ void SPMeshLoader::convertIrrlicht()
|
||||
}
|
||||
for (unsigned i = 0; i < total_joints; i++)
|
||||
{
|
||||
m_mesh->addJoint(NULL);
|
||||
smesh->addJoint(NULL);
|
||||
}
|
||||
core::array<scene::ISkinnedMesh::SJoint*>& joints = m_mesh->getAllJoints();
|
||||
core::array<scene::ISkinnedMesh::SJoint*>& joints = smesh->getAllJoints();
|
||||
std::vector<int> used_joints_map;
|
||||
used_joints_map.resize(m_joint_count);
|
||||
total_joints = 0;
|
||||
@ -723,7 +861,7 @@ void SPMeshLoader::convertIrrlicht()
|
||||
{
|
||||
break;
|
||||
}
|
||||
scene::ISkinnedMesh::SWeight* w = m_mesh->addWeight
|
||||
scene::ISkinnedMesh::SWeight* w = smesh->addWeight
|
||||
(joints[used_joints_map[m_joints[i][j].first[k]]]);
|
||||
w->buffer_id = (uint16_t)i;
|
||||
w->vertex_id = j;
|
||||
|
@ -53,6 +53,12 @@ private:
|
||||
bool read_tangent, bool uv_one, bool uv_two,
|
||||
SPVertexType vt, const video::SMaterial& m);
|
||||
// ------------------------------------------------------------------------
|
||||
void decompressGESPM(irr::io::IReadFile* spm, unsigned vertices_count,
|
||||
unsigned indices_count, bool read_normal,
|
||||
bool read_vcolor, bool read_tangent, bool uv_one,
|
||||
bool uv_two, SPVertexType vt,
|
||||
const video::SMaterial& m);
|
||||
// ------------------------------------------------------------------------
|
||||
void decompressSPM(irr::io::IReadFile* spm, unsigned vertices_count,
|
||||
unsigned indices_count, bool read_normal,
|
||||
bool read_vcolor, bool read_tangent, bool uv_one,
|
||||
@ -63,7 +69,7 @@ private:
|
||||
// ------------------------------------------------------------------------
|
||||
void convertIrrlicht();
|
||||
|
||||
scene::ISkinnedMesh* m_mesh;
|
||||
scene::IAnimatedMesh* m_mesh;
|
||||
|
||||
scene::ISceneManager* m_scene_manager;
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user