|
|
@@ -15,30 +15,65 @@ namespace anki {
|
|
|
//==============================================================================
|
|
|
|
|
|
/// The hash functor
|
|
|
-struct Hasher
|
|
|
+class Hasher
|
|
|
{
|
|
|
- size_t operator()(const Vec3& pos) const
|
|
|
+public:
|
|
|
+ PtrSize operator()(const Vec3& pos) const
|
|
|
{
|
|
|
F32 sum = pos.x() * 100.0 + pos.y() * 10.0 + pos.z();
|
|
|
- size_t hash = 0;
|
|
|
- memcpy(&hash, &sum, sizeof(F32));
|
|
|
+ PtrSize hash = 0;
|
|
|
+ std::memcpy(&hash, &sum, sizeof(F32));
|
|
|
return hash;
|
|
|
}
|
|
|
};
|
|
|
|
|
|
+/// The collision evaluation function
|
|
|
+class Equal
|
|
|
+{
|
|
|
+public:
|
|
|
+ Bool operator()(const Vec3& a, const Vec3& b) const
|
|
|
+ {
|
|
|
+ return a == b;
|
|
|
+ }
|
|
|
+};
|
|
|
+
|
|
|
/// The value of the hash map
|
|
|
-struct MapValue
|
|
|
+class MapValue
|
|
|
{
|
|
|
- U8 indicesCount = 0;
|
|
|
- Array<U32, 16> indices;
|
|
|
+public:
|
|
|
+ U8 m_indicesCount = 0;
|
|
|
+ Array<U32, 16> m_indices;
|
|
|
};
|
|
|
|
|
|
-typedef std::unordered_map<Vec3, MapValue, Hasher> FixNormalsMap;
|
|
|
+using FixNormalsMap = std::unordered_map<
|
|
|
+ Vec3, MapValue, Hasher, Equal,
|
|
|
+ TempResourceAllocator<std::pair<Vec3, MapValue>>>;
|
|
|
|
|
|
//==============================================================================
|
|
|
// MeshLoader =
|
|
|
//==============================================================================
|
|
|
|
|
|
+//==============================================================================
|
|
|
+MeshLoader::MeshLoader(TempResourceAllocator<U8>& alloc)
|
|
|
+: m_positions(alloc),
|
|
|
+ m_normals(alloc),
|
|
|
+ m_normalsF16(alloc),
|
|
|
+ m_tangents(alloc),
|
|
|
+ m_tangentsF16(alloc),
|
|
|
+ m_texCoords(alloc),
|
|
|
+ m_texCoordsF16(alloc),
|
|
|
+ m_weights(alloc),
|
|
|
+ m_tris(alloc),
|
|
|
+ m_vertIndices(alloc)
|
|
|
+{}
|
|
|
+
|
|
|
+//==============================================================================
|
|
|
+MeshLoader::MeshLoader(const char* filename, TempResourceAllocator<U8>& alloc)
|
|
|
+: MeshLoader(filename, alloc)
|
|
|
+{
|
|
|
+ load(filename);
|
|
|
+}
|
|
|
+
|
|
|
//==============================================================================
|
|
|
void MeshLoader::load(const char* filename)
|
|
|
{
|
|
|
@@ -53,7 +88,7 @@ void MeshLoader::load(const char* filename)
|
|
|
// Magic word
|
|
|
char magic[8];
|
|
|
file.read(magic, sizeof(magic));
|
|
|
- if(memcmp(magic, "ANKIMESH", 8))
|
|
|
+ if(std::memcmp(magic, "ANKIMESH", 8))
|
|
|
{
|
|
|
throw ANKI_EXCEPTION("Incorrect magic word");
|
|
|
}
|
|
|
@@ -66,10 +101,10 @@ void MeshLoader::load(const char* filename)
|
|
|
|
|
|
// Verts num
|
|
|
U vertsNum = file.readU32();
|
|
|
- positions.resize(vertsNum);
|
|
|
+ m_positions.resize(vertsNum);
|
|
|
|
|
|
// Vert coords
|
|
|
- for(Vec3& vertCoord : positions)
|
|
|
+ for(Vec3& vertCoord : m_positions)
|
|
|
{
|
|
|
for(U j = 0; j < 3; j++)
|
|
|
{
|
|
|
@@ -79,17 +114,17 @@ void MeshLoader::load(const char* filename)
|
|
|
|
|
|
// Faces num
|
|
|
U facesNum = file.readU32();
|
|
|
- tris.resize(facesNum);
|
|
|
+ m_tris.resize(facesNum);
|
|
|
|
|
|
// Faces IDs
|
|
|
- for(Triangle& tri : tris)
|
|
|
+ for(Triangle& tri : m_tris)
|
|
|
{
|
|
|
for(U j = 0; j < 3; j++)
|
|
|
{
|
|
|
- tri.vertIds[j] = file.readU32();
|
|
|
+ tri.m_vertIds[j] = file.readU32();
|
|
|
|
|
|
// a sanity check
|
|
|
- if(tri.vertIds[j] >= positions.size())
|
|
|
+ if(tri.m_vertIds[j] >= m_positions.size())
|
|
|
{
|
|
|
throw ANKI_EXCEPTION("Vert index out of bounds");
|
|
|
}
|
|
|
@@ -98,10 +133,10 @@ void MeshLoader::load(const char* filename)
|
|
|
|
|
|
// Tex coords num
|
|
|
U texCoordsNum = file.readU32();
|
|
|
- texCoords.resize(texCoordsNum);
|
|
|
+ m_texCoords.resize(texCoordsNum);
|
|
|
|
|
|
// Tex coords
|
|
|
- for(Vec2& texCoord : texCoords)
|
|
|
+ for(Vec2& texCoord : m_texCoords)
|
|
|
{
|
|
|
for(U32 i = 0; i < 2; i++)
|
|
|
{
|
|
|
@@ -111,10 +146,10 @@ void MeshLoader::load(const char* filename)
|
|
|
|
|
|
// Vert weights num
|
|
|
U weightsNum = file.readU32();
|
|
|
- weights.resize(weightsNum);
|
|
|
+ m_weights.resize(weightsNum);
|
|
|
|
|
|
// Vert weights
|
|
|
- for(VertexWeight& vw : weights)
|
|
|
+ for(VertexWeight& vw : m_weights)
|
|
|
{
|
|
|
// get the bone connections num
|
|
|
U32 boneConnections = file.readU32();
|
|
|
@@ -132,18 +167,18 @@ void MeshLoader::load(const char* filename)
|
|
|
throw ANKI_EXCEPTION("Cannot have more than %d "
|
|
|
"bones per vertex", tmp);
|
|
|
}
|
|
|
- vw.bonesNum = boneConnections;
|
|
|
+ vw.m_bonesCount = boneConnections;
|
|
|
|
|
|
// for all the weights of the current vertes
|
|
|
- for(U32 i = 0; i < vw.bonesNum; i++)
|
|
|
+ for(U32 i = 0; i < vw.m_bonesCount; i++)
|
|
|
{
|
|
|
// read bone id
|
|
|
U32 boneId = file.readU32();
|
|
|
- vw.boneIds[i] = boneId;
|
|
|
+ vw.m_boneIds[i] = boneId;
|
|
|
|
|
|
// read the weight of that bone
|
|
|
float weight = file.readF32();
|
|
|
- vw.weights[i] = weight;
|
|
|
+ vw.m_weights[i] = weight;
|
|
|
}
|
|
|
} // end for all vert weights
|
|
|
|
|
|
@@ -160,17 +195,19 @@ void MeshLoader::load(const char* filename)
|
|
|
void MeshLoader::doPostLoad()
|
|
|
{
|
|
|
// Sanity checks
|
|
|
- if(positions.size() < 1 || tris.size() < 1)
|
|
|
+ if(m_positions.size() < 1 || m_tris.size() < 1)
|
|
|
{
|
|
|
throw ANKI_EXCEPTION("Vert coords and tris must be filled");
|
|
|
}
|
|
|
- if(texCoords.size() != 0 && texCoords.size() != positions.size())
|
|
|
+
|
|
|
+ if(m_texCoords.size() != 0 && m_texCoords.size() != m_positions.size())
|
|
|
{
|
|
|
throw ANKI_EXCEPTION("Tex coords num must be "
|
|
|
"zero or equal to the vertex "
|
|
|
"coords num");
|
|
|
}
|
|
|
- if(weights.size() != 0 && weights.size() != positions.size())
|
|
|
+
|
|
|
+ if(m_weights.size() != 0 && m_weights.size() != m_positions.size())
|
|
|
{
|
|
|
throw ANKI_EXCEPTION("Vert weights num must be zero or equal to the "
|
|
|
"vertex coords num");
|
|
|
@@ -178,10 +215,12 @@ void MeshLoader::doPostLoad()
|
|
|
|
|
|
createAllNormals();
|
|
|
fixNormals();
|
|
|
- if(texCoords.size() > 0)
|
|
|
+
|
|
|
+ if(m_texCoords.size() > 0)
|
|
|
{
|
|
|
createVertTangents();
|
|
|
}
|
|
|
+
|
|
|
createVertIndeces();
|
|
|
compressBuffers();
|
|
|
}
|
|
|
@@ -189,13 +228,13 @@ void MeshLoader::doPostLoad()
|
|
|
//==============================================================================
|
|
|
void MeshLoader::createVertIndeces()
|
|
|
{
|
|
|
- vertIndices.resize(tris.size() * 3);
|
|
|
+ m_vertIndices.resize(m_tris.size() * 3);
|
|
|
U j = 0;
|
|
|
- for(U i = 0; i < tris.size(); ++i)
|
|
|
+ for(U i = 0; i < m_tris.size(); ++i)
|
|
|
{
|
|
|
- vertIndices[j + 0] = tris[i].vertIds[0];
|
|
|
- vertIndices[j + 1] = tris[i].vertIds[1];
|
|
|
- vertIndices[j + 2] = tris[i].vertIds[2];
|
|
|
+ m_vertIndices[j + 0] = m_tris[i].m_vertIds[0];
|
|
|
+ m_vertIndices[j + 1] = m_tris[i].m_vertIds[1];
|
|
|
+ m_vertIndices[j + 2] = m_tris[i].m_vertIds[2];
|
|
|
|
|
|
j += 3;
|
|
|
}
|
|
|
@@ -204,21 +243,21 @@ void MeshLoader::createVertIndeces()
|
|
|
//==============================================================================
|
|
|
void MeshLoader::createFaceNormals()
|
|
|
{
|
|
|
- for(Triangle& tri : tris)
|
|
|
+ for(Triangle& tri : m_tris)
|
|
|
{
|
|
|
- const Vec3& v0 = positions[tri.vertIds[0]];
|
|
|
- const Vec3& v1 = positions[tri.vertIds[1]];
|
|
|
- const Vec3& v2 = positions[tri.vertIds[2]];
|
|
|
+ const Vec3& v0 = m_positions[tri.m_vertIds[0]];
|
|
|
+ const Vec3& v1 = m_positions[tri.m_vertIds[1]];
|
|
|
+ const Vec3& v2 = m_positions[tri.m_vertIds[2]];
|
|
|
|
|
|
- tri.normal = (v1 - v0).cross(v2 - v0);
|
|
|
+ tri.m_normal = (v1 - v0).cross(v2 - v0);
|
|
|
|
|
|
- if(tri.normal != Vec3(0.0))
|
|
|
+ if(tri.m_normal != Vec3(0.0))
|
|
|
{
|
|
|
//tri.normal.normalize();
|
|
|
}
|
|
|
else
|
|
|
{
|
|
|
- tri.normal = Vec3(1.0, 0.0, 0.0);
|
|
|
+ tri.m_normal = Vec3(1.0, 0.0, 0.0);
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
@@ -226,21 +265,21 @@ void MeshLoader::createFaceNormals()
|
|
|
//==============================================================================
|
|
|
void MeshLoader::createVertNormals()
|
|
|
{
|
|
|
- normals.resize(positions.size());
|
|
|
+ m_normals.resize(m_positions.size());
|
|
|
|
|
|
- for(Vec3& vertNormal : normals)
|
|
|
+ for(Vec3& vertNormal : m_normals)
|
|
|
{
|
|
|
vertNormal = Vec3(0.0);
|
|
|
}
|
|
|
|
|
|
- for(Triangle& tri : tris)
|
|
|
+ for(Triangle& tri : m_tris)
|
|
|
{
|
|
|
- normals[tri.vertIds[0]] += tri.normal;
|
|
|
- normals[tri.vertIds[1]] += tri.normal;
|
|
|
- normals[tri.vertIds[2]] += tri.normal;
|
|
|
+ m_normals[tri.m_vertIds[0]] += tri.m_normal;
|
|
|
+ m_normals[tri.m_vertIds[1]] += tri.m_normal;
|
|
|
+ m_normals[tri.m_vertIds[2]] += tri.m_normal;
|
|
|
}
|
|
|
|
|
|
- for(Vec3& vertNormal : normals)
|
|
|
+ for(Vec3& vertNormal : m_normals)
|
|
|
{
|
|
|
if(vertNormal != Vec3(0.0))
|
|
|
{
|
|
|
@@ -252,25 +291,27 @@ void MeshLoader::createVertNormals()
|
|
|
//==============================================================================
|
|
|
void MeshLoader::createVertTangents()
|
|
|
{
|
|
|
- tangents.resize(positions.size(), Vec4(0.0)); // alloc
|
|
|
- Vector<Vec3> bitagents(positions.size(), Vec3(0.0));
|
|
|
+ m_tangents.resize(m_positions.size(), Vec4(0.0)); // alloc
|
|
|
+ MLVector<Vec3> bitagents(
|
|
|
+ m_positions.size(), Vec3(0.0), m_tangents.get_allocator());
|
|
|
|
|
|
- for(U32 i = 0; i < tris.size(); i++)
|
|
|
+ for(U32 i = 0; i < m_tris.size(); i++)
|
|
|
{
|
|
|
- const Triangle& tri = tris[i];
|
|
|
- const I i0 = tri.vertIds[0];
|
|
|
- const I i1 = tri.vertIds[1];
|
|
|
- const I i2 = tri.vertIds[2];
|
|
|
- const Vec3& v0 = positions[i0];
|
|
|
- const Vec3& v1 = positions[i1];
|
|
|
- const Vec3& v2 = positions[i2];
|
|
|
+ const Triangle& tri = m_tris[i];
|
|
|
+ const I i0 = tri.m_vertIds[0];
|
|
|
+ const I i1 = tri.m_vertIds[1];
|
|
|
+ const I i2 = tri.m_vertIds[2];
|
|
|
+ const Vec3& v0 = m_positions[i0];
|
|
|
+ const Vec3& v1 = m_positions[i1];
|
|
|
+ const Vec3& v2 = m_positions[i2];
|
|
|
Vec3 edge01 = v1 - v0;
|
|
|
Vec3 edge02 = v2 - v0;
|
|
|
- Vec2 uvedge01 = texCoords[i1] - texCoords[i0];
|
|
|
- Vec2 uvedge02 = texCoords[i2] - texCoords[i0];
|
|
|
+ Vec2 uvedge01 = m_texCoords[i1] - m_texCoords[i0];
|
|
|
+ Vec2 uvedge02 = m_texCoords[i2] - m_texCoords[i0];
|
|
|
|
|
|
F32 det = (uvedge01.y() * uvedge02.x()) -
|
|
|
(uvedge01.x() * uvedge02.y());
|
|
|
+
|
|
|
if(isZero(det))
|
|
|
{
|
|
|
det = 0.0001;
|
|
|
@@ -290,19 +331,19 @@ void MeshLoader::createVertTangents()
|
|
|
//t.normalize();
|
|
|
//b.normalize();
|
|
|
|
|
|
- tangents[i0] += Vec4(t, 1.0);
|
|
|
- tangents[i1] += Vec4(t, 1.0);
|
|
|
- tangents[i2] += Vec4(t, 1.0);
|
|
|
+ m_tangents[i0] += Vec4(t, 1.0);
|
|
|
+ m_tangents[i1] += Vec4(t, 1.0);
|
|
|
+ m_tangents[i2] += Vec4(t, 1.0);
|
|
|
|
|
|
bitagents[i0] += b;
|
|
|
bitagents[i1] += b;
|
|
|
bitagents[i2] += b;
|
|
|
}
|
|
|
|
|
|
- for(U i = 0; i < tangents.size(); i++)
|
|
|
+ for(U i = 0; i < m_tangents.size(); i++)
|
|
|
{
|
|
|
- Vec3 t = tangents[i].xyz();
|
|
|
- const Vec3& n = normals[i];
|
|
|
+ Vec3 t = m_tangents[i].xyz();
|
|
|
+ const Vec3& n = m_normals[i];
|
|
|
Vec3& b = bitagents[i];
|
|
|
|
|
|
t = t - n * n.dot(t);
|
|
|
@@ -319,20 +360,20 @@ void MeshLoader::createVertTangents()
|
|
|
|
|
|
F32 w = ((n.cross(t)).dot(b) < 0.0) ? 1.0 : -1.0;
|
|
|
|
|
|
- tangents[i] = Vec4(t, w);
|
|
|
+ m_tangents[i] = Vec4(t, w);
|
|
|
}
|
|
|
}
|
|
|
|
|
|
//==============================================================================
|
|
|
void MeshLoader::fixNormals()
|
|
|
{
|
|
|
- FixNormalsMap map;
|
|
|
+ FixNormalsMap map(10, Hasher(), Equal(), m_positions.get_allocator());
|
|
|
|
|
|
// For all verts
|
|
|
- for(U i = 1; i < positions.size(); i++)
|
|
|
+ for(U i = 1; i < m_positions.size(); i++)
|
|
|
{
|
|
|
- const Vec3& pos = positions[i];
|
|
|
- Vec3& norm = normals[i];
|
|
|
+ const Vec3& pos = m_positions[i];
|
|
|
+ Vec3& norm = m_normals[i];
|
|
|
|
|
|
// Find pos
|
|
|
FixNormalsMap::iterator it = map.find(pos);
|
|
|
@@ -343,8 +384,8 @@ void MeshLoader::fixNormals()
|
|
|
// Not found
|
|
|
|
|
|
MapValue val;
|
|
|
- val.indices[0] = i;
|
|
|
- val.indicesCount = 1;
|
|
|
+ val.m_indices[0] = i;
|
|
|
+ val.m_indicesCount = 1;
|
|
|
map[pos] = val;
|
|
|
}
|
|
|
else
|
|
|
@@ -352,13 +393,13 @@ void MeshLoader::fixNormals()
|
|
|
// Found
|
|
|
|
|
|
MapValue& mapVal = it->second;
|
|
|
- ANKI_ASSERT(mapVal.indicesCount > 0);
|
|
|
+ ANKI_ASSERT(mapVal.m_indicesCount > 0);
|
|
|
|
|
|
// Search the verts with the same position
|
|
|
- for(U j = 0; j < mapVal.indicesCount; j++)
|
|
|
+ for(U j = 0; j < mapVal.m_indicesCount; j++)
|
|
|
{
|
|
|
- const Vec3& posB = positions[mapVal.indices[j]];
|
|
|
- Vec3& normB = normals[mapVal.indices[j]];
|
|
|
+ const Vec3& posB = m_positions[mapVal.m_indices[j]];
|
|
|
+ Vec3& normB = m_normals[mapVal.m_indices[j]];
|
|
|
|
|
|
ANKI_ASSERT(posB == pos);
|
|
|
(void)posB;
|
|
|
@@ -377,7 +418,7 @@ void MeshLoader::fixNormals()
|
|
|
}
|
|
|
|
|
|
// Update the map
|
|
|
- mapVal.indices[mapVal.indicesCount++] = i;
|
|
|
+ mapVal.m_indices[mapVal.m_indicesCount++] = i;
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
@@ -385,73 +426,73 @@ void MeshLoader::fixNormals()
|
|
|
//==============================================================================
|
|
|
void MeshLoader::append(const MeshLoader& other)
|
|
|
{
|
|
|
- positions.insert(
|
|
|
- positions.end(), other.positions.begin(), other.positions.end());
|
|
|
+ m_positions.insert(
|
|
|
+ m_positions.end(), other.m_positions.begin(), other.m_positions.end());
|
|
|
|
|
|
//normals.insert(
|
|
|
// normals.end(), other.normals.begin(), other.normals.end());
|
|
|
|
|
|
- normalsF16.insert(
|
|
|
- normalsF16.end(), other.normalsF16.begin(), other.normalsF16.end());
|
|
|
+ m_normalsF16.insert(m_normalsF16.end(), other.m_normalsF16.begin(),
|
|
|
+ other.m_normalsF16.end());
|
|
|
|
|
|
//tangents.insert(
|
|
|
// tangents.end(), other.tangents.begin(), other.tangents.end());
|
|
|
|
|
|
- tangentsF16.insert(
|
|
|
- tangentsF16.end(), other.tangentsF16.begin(), other.tangentsF16.end());
|
|
|
+ m_tangentsF16.insert(m_tangentsF16.end(),
|
|
|
+ other.m_tangentsF16.begin(), other.m_tangentsF16.end());
|
|
|
|
|
|
//texCoords.insert(
|
|
|
// texCoords.end(), other.texCoords.begin(), other.texCoords.end());
|
|
|
|
|
|
- texCoordsF16.insert(
|
|
|
- texCoordsF16.end(), other.texCoordsF16.begin(),
|
|
|
- other.texCoordsF16.end());
|
|
|
+ m_texCoordsF16.insert(
|
|
|
+ m_texCoordsF16.end(), other.m_texCoordsF16.begin(),
|
|
|
+ other.m_texCoordsF16.end());
|
|
|
|
|
|
- weights.insert(
|
|
|
- weights.end(), other.weights.begin(), other.weights.end());
|
|
|
+ m_weights.insert(
|
|
|
+ m_weights.end(), other.m_weights.begin(), other.m_weights.end());
|
|
|
|
|
|
- U16 bias = positions.size();
|
|
|
- for(U16 index : other.vertIndices)
|
|
|
+ U16 bias = m_positions.size();
|
|
|
+ for(U16 index : other.m_vertIndices)
|
|
|
{
|
|
|
- vertIndices.push_back(bias + index);
|
|
|
+ m_vertIndices.push_back(bias + index);
|
|
|
}
|
|
|
}
|
|
|
|
|
|
//==============================================================================
|
|
|
void MeshLoader::compressBuffers()
|
|
|
{
|
|
|
- ANKI_ASSERT(positions.size() > 0);
|
|
|
+ ANKI_ASSERT(m_positions.size() > 0);
|
|
|
|
|
|
// Normals
|
|
|
- normalsF16.resize(normals.size());
|
|
|
+ m_normalsF16.resize(m_normals.size());
|
|
|
|
|
|
- for(U i = 0; i < normals.size(); i++)
|
|
|
+ for(U i = 0; i < m_normals.size(); i++)
|
|
|
{
|
|
|
for(U j = 0; j < 3; j++)
|
|
|
{
|
|
|
- normalsF16[i][j] = F16(normals[i][j]);
|
|
|
+ m_normalsF16[i][j] = F16(m_normals[i][j]);
|
|
|
}
|
|
|
}
|
|
|
|
|
|
// Tangents
|
|
|
- tangentsF16.resize(tangents.size());
|
|
|
+ m_tangentsF16.resize(m_tangents.size());
|
|
|
|
|
|
- for(U i = 0; i < tangents.size(); i++)
|
|
|
+ for(U i = 0; i < m_tangents.size(); i++)
|
|
|
{
|
|
|
for(U j = 0; j < 4; j++)
|
|
|
{
|
|
|
- tangentsF16[i][j] = F16(tangents[i][j]);
|
|
|
+ m_tangentsF16[i][j] = F16(m_tangents[i][j]);
|
|
|
}
|
|
|
}
|
|
|
|
|
|
// Texture coords
|
|
|
- texCoordsF16.resize(texCoords.size());
|
|
|
+ m_texCoordsF16.resize(m_texCoords.size());
|
|
|
|
|
|
- for(U i = 0; i < texCoords.size(); i++)
|
|
|
+ for(U i = 0; i < m_texCoords.size(); i++)
|
|
|
{
|
|
|
for(U j = 0; j < 2; j++)
|
|
|
{
|
|
|
- texCoordsF16[i][j] = F16(texCoords[i][j]);
|
|
|
+ m_texCoordsF16[i][j] = F16(m_texCoords[i][j]);
|
|
|
}
|
|
|
}
|
|
|
}
|