Skip to content

Commit 4cff57c

Browse files
committed
more optimizations. Remove iss, move ptr check conditions outside of loop, use emplace_back
Signed-off-by: frederik <frederik.anilmarkus@gmail.com>
1 parent f0ff34f commit 4cff57c

File tree

1 file changed

+132
-75
lines changed

1 file changed

+132
-75
lines changed

graphics/src/ColladaLoader.cc

Lines changed: 132 additions & 75 deletions
Original file line numberDiff line numberDiff line change
@@ -346,8 +346,11 @@ struct Vector3Hash
346346
{
347347
std::size_t seed = 0;
348348
hash_combine(seed, _v.X());
349+
// std::cout << "seed after x" << seed << std::endl;
349350
hash_combine(seed, _v.Y());
351+
// std::cout << "seed after y" << seed << std::endl;
350352
hash_combine(seed, _v.Z());
353+
// std::cout << "seed after z" << seed << std::endl;
351354
return seed;
352355
}
353356
};
@@ -359,7 +362,9 @@ struct Vector2dHash
359362
{
360363
std::size_t seed = 0;
361364
hash_combine(seed, _v.X());
365+
// std::cout << "seed after x" << seed << std::endl;
362366
hash_combine(seed, _v.Y());
367+
// std::cout << "seed after y" << seed << std::endl;
363368
return seed;
364369
}
365370
};
@@ -884,7 +889,7 @@ void ColladaLoader::Implementation::LoadController(
884889

885890
std::vector<float> weights;
886891
for (unsigned int i = 0; i < wStrs.size(); ++i)
887-
weights.push_back(math::parseFloat(wStrs[i]));
892+
weights.emplace_back(math::parseFloat(wStrs[i]));
888893

889894
std::string cString = vertWeightsXml->FirstChildElement("vcount")->GetText();
890895
std::string vString = vertWeightsXml->FirstChildElement("v")->GetText();
@@ -895,10 +900,10 @@ void ColladaLoader::Implementation::LoadController(
895900
std::vector<unsigned int> v;
896901

897902
for (unsigned int i = 0; i < vCountStrs.size(); ++i)
898-
vCount.push_back(math::parseInt(vCountStrs[i]));
903+
vCount.emplace_back(math::parseInt(vCountStrs[i]));
899904

900905
for (unsigned int i = 0; i < vStrs.size(); ++i)
901-
v.push_back(math::parseInt(vStrs[i]));
906+
v.emplace_back(math::parseInt(vStrs[i]));
902907

903908
skeleton->SetNumVertAttached(vCount.size());
904909

@@ -1027,7 +1032,7 @@ void ColladaLoader::Implementation::LoadAnimationSet(tinyxml2::XMLElement *_xml,
10271032

10281033
std::vector<double> times;
10291034
for (unsigned int i = 0; i < timeStrs.size(); ++i)
1030-
times.push_back(math::parseFloat(timeStrs[i]));
1035+
times.emplace_back(math::parseFloat(timeStrs[i]));
10311036

10321037
tinyxml2::XMLElement *output =
10331038
frameTransXml->FirstChildElement("float_array");
@@ -1036,7 +1041,7 @@ void ColladaLoader::Implementation::LoadAnimationSet(tinyxml2::XMLElement *_xml,
10361041

10371042
std::vector<double> values;
10381043
for (unsigned int i = 0; i < outputStrs.size(); ++i)
1039-
values.push_back(math::parseFloat(outputStrs[i]));
1044+
values.emplace_back(math::parseFloat(outputStrs[i]));
10401045

10411046
tinyxml2::XMLElement *accessor =
10421047
frameTransXml->FirstChildElement("technique_common");
@@ -1541,6 +1546,7 @@ void ColladaLoader::Implementation::LoadPositions(const std::string &_id,
15411546
auto toDoubleVec = [](std::string_view sv, size_t totalCount)
15421547
{
15431548
std::vector<double> result;
1549+
// Preallocate memory based on known count
15441550
result.reserve(totalCount * 3);
15451551
const char *start = sv.data();
15461552
char *end{};
@@ -1552,40 +1558,33 @@ void ColladaLoader::Implementation::LoadPositions(const std::string &_id,
15521558
start = end;
15531559
if (errno == ERANGE)
15541560
throw std::runtime_error("strtod() overflow");
1555-
result.push_back(d);
1561+
result.emplace_back(d);
15561562
}
15571563
return result;
15581564
};
15591565

15601566
auto values = toDoubleVec(valueStr, totCount);
1567+
1568+
gz::math::Vector3d vec;
1569+
if (!_values)
1570+
_values = std::make_shared<std::vector<gz::math::Vector3d>>();
1571+
if (!_duplicates)
1572+
_duplicates = std::make_shared<std::unordered_map<unsigned int,
1573+
unsigned int>>();
15611574
for (int i = 0; i < totCount; i += stride)
15621575
{
1563-
gz::math::Vector3d vec(values[i],
1564-
values[i+1],
1565-
values[i+2]);
1576+
vec.Set(values[i],
1577+
values[i+1],
1578+
values[i+2]);
15661579

15671580
vec = _transform * vec;
1568-
if (!_values)
1569-
{
1570-
_values = std::make_shared<std::vector<gz::math::Vector3d>>();
1571-
}
1572-
(*_values).push_back(vec);
1573-
1574-
if (!_duplicates)
1575-
{
1576-
_duplicates = std::make_shared<std::unordered_map<unsigned int,
1577-
unsigned int>>();
1578-
}
1581+
(*_values).emplace_back(vec);
15791582

15801583
// create a map of duplicate indices
15811584
if (unique.find(vec) != unique.end())
1582-
{
15831585
(*_duplicates)[(*_values).size()-1] = unique[vec];
1584-
}
15851586
else
1586-
{
15871587
unique[vec] = (*_values).size()-1;
1588-
}
15891588
}
15901589

15911590
this->positionDuplicateMap[_id] = _duplicates;
@@ -1618,6 +1617,10 @@ void ColladaLoader::Implementation::LoadNormals(const std::string &_id,
16181617

16191618
tinyxml2::XMLElement *floatArrayXml =
16201619
normalsXml->FirstChildElement("float_array");
1620+
1621+
int totCount = 0;
1622+
int stride = 0;
1623+
16211624
if (!floatArrayXml || !floatArrayXml->GetText())
16221625
{
16231626
int count = 1;
@@ -1635,7 +1638,7 @@ void ColladaLoader::Implementation::LoadNormals(const std::string &_id,
16351638

16361639
if (count)
16371640
{
1638-
gzwarn << "Normal source missing float_array element, or count is "
1641+
gzerr << "Normal source missing float_array element, or count is "
16391642
<< "invalid.\n";
16401643
}
16411644
else
@@ -1646,43 +1649,103 @@ void ColladaLoader::Implementation::LoadNormals(const std::string &_id,
16461649

16471650
return;
16481651
}
1652+
// Read in the total number of normal coordinate values
1653+
else if (floatArrayXml->Attribute("count"))
1654+
totCount = std::stoi(floatArrayXml->Attribute("count"));
1655+
else
1656+
{
1657+
gzerr << "<float_array> has no count attribute in normal coordinate "
1658+
<< "element with id[" << _id << "]\n";
1659+
return;
1660+
}
1661+
1662+
normalsXml = normalsXml->FirstChildElement("technique_common");
1663+
if (!normalsXml)
1664+
{
1665+
gzerr << "Unable to find technique_common element for normals "
1666+
<< "coordinates with id[" << _id << "]\n";
1667+
return;
1668+
}
1669+
1670+
// Get the accessor XML element.
1671+
normalsXml = normalsXml->FirstChildElement("accessor");
1672+
if (!normalsXml)
1673+
{
1674+
gzerr << "Unable to find <accessor> as a child of <technique_common> "
1675+
<< "for normals coordinates with id[" << _id << "]\n";
1676+
return;
1677+
}
1678+
1679+
// Read in the stride for the normals coordinate values. The stride
1680+
// indicates the number of values in the float array the comprise
1681+
// a complete normal coordinate.
1682+
if (normalsXml->Attribute("stride"))
1683+
{
1684+
stride = std::stoi(normalsXml->Attribute("stride"));
1685+
}
1686+
else
1687+
{
1688+
gzerr << "<accessor> has no stride attribute in normal coordinate "
1689+
<< "element with id[" << _id << "]\n";
1690+
return;
1691+
}
1692+
1693+
// Nothing to read. Don't print a warning because the collada file is
1694+
// correct.
1695+
if (totCount == 0)
1696+
return;
16491697

16501698
std::unordered_map<gz::math::Vector3d,
16511699
unsigned int, Vector3Hash> unique;
16521700

16531701
std::string valueStr = floatArrayXml->GetText();
1654-
std::istringstream iss(valueStr);
1655-
do
1702+
// std::istringstream iss(valueStr);
1703+
1704+
auto toDoubleVec = [](std::string_view sv, size_t totalCount)
16561705
{
1657-
gz::math::Vector3d vec;
1658-
iss >> vec.X() >> vec.Y() >> vec.Z();
1659-
if (iss)
1706+
std::vector<double> result;
1707+
// Preallocate memory based on known count
1708+
result.reserve(totalCount * 3);
1709+
const char *start = sv.data();
1710+
char *end{};
1711+
while (true)
16601712
{
1661-
vec = rotMat * vec;
1662-
vec.Normalize();
1663-
if (!_values)
1664-
{
1665-
_values = std::make_shared<std::vector<gz::math::Vector3d>>();
1666-
}
1667-
(*_values).push_back(vec);
1713+
double d = std::strtod(start, &end);
1714+
if (start == end)
1715+
break;
1716+
start = end;
1717+
if (errno == ERANGE)
1718+
throw std::runtime_error("strtod() overflow");
1719+
result.emplace_back(d);
1720+
}
1721+
return result;
1722+
};
16681723

1669-
if (!_duplicates)
1670-
{
1724+
auto values = toDoubleVec(valueStr, totCount);
1725+
1726+
gz::math::Vector3d vec;
1727+
if (!_values)
1728+
_values = std::make_shared<std::vector<gz::math::Vector3d>>();
1729+
if (!_duplicates)
16711730
_duplicates = std::make_shared<std::unordered_map<unsigned int,
16721731
unsigned int>>();
1673-
}
16741732

1675-
// create a map of duplicate indices
1676-
if (unique.find(vec) != unique.end())
1677-
{
1678-
(*_duplicates)[(*_values).size()-1] = unique[vec];
1679-
}
1680-
else
1681-
{
1682-
unique[vec] = (*_values).size()-1;
1683-
}
1684-
}
1685-
} while (iss);
1733+
for (int i = 0; i < totCount; i += stride)
1734+
{
1735+
vec.Set(values[i],
1736+
values[i+1],
1737+
values[i+2]);
1738+
1739+
vec = rotMat * vec;
1740+
vec.Normalize();
1741+
(*_values).emplace_back(vec);
1742+
1743+
// create a map of duplicate indices
1744+
if (unique.find(vec) != unique.end())
1745+
(*_duplicates)[(*_values).size()-1] = unique[vec];
1746+
else
1747+
unique[vec] = (*_values).size()-1;
1748+
}
16861749

16871750
this->normalDuplicateMap[_id] = _duplicates;
16881751
this->normalIds[_id] = _values;
@@ -1820,6 +1883,7 @@ void ColladaLoader::Implementation::LoadTexCoords(const std::string &_id,
18201883
auto toDoubleVec = [](std::string_view sv, size_t totalCount)
18211884
{
18221885
std::vector<double> result;
1886+
// Preallocate memory based on known count
18231887
result.reserve(totalCount * 2);
18241888
const char *start = sv.data();
18251889
char *end{};
@@ -1831,7 +1895,7 @@ void ColladaLoader::Implementation::LoadTexCoords(const std::string &_id,
18311895
start = end;
18321896
if (errno == ERANGE)
18331897
throw std::runtime_error("strtod() overflow");
1834-
result.push_back(d);
1898+
result.emplace_back(d);
18351899
}
18361900
return result;
18371901
};
@@ -1840,30 +1904,23 @@ void ColladaLoader::Implementation::LoadTexCoords(const std::string &_id,
18401904
std::string valueStr = floatArrayXml->GetText();
18411905
auto values = toDoubleVec(valueStr, totCount);
18421906

1907+
gz::math::Vector2d vec;
1908+
if (!_values)
1909+
_values = std::make_shared<std::vector<gz::math::Vector2d>>();
1910+
if (!_duplicates)
1911+
_duplicates = std::make_shared<std::unordered_map<unsigned int,
1912+
unsigned int>>();
18431913
// Read in all the texture coordinates.
18441914
for (int i = 0; i < totCount; i += stride)
18451915
{
18461916
// We only handle 2D texture coordinates right now.
1847-
gz::math::Vector2d vec(values[i],
1848-
1.0 - values[i + 1]);
1849-
1850-
if (!_values)
1851-
{
1852-
_values = std::make_shared<std::vector<gz::math::Vector2d>>();
1853-
}
1854-
(*_values).push_back(vec);
1855-
1856-
if (!_duplicates)
1857-
{
1858-
_duplicates = std::make_shared<std::unordered_map<unsigned int,
1859-
unsigned int>>();
1860-
}
1917+
vec.Set(values[i],
1918+
1.0 - values[i + 1]);
1919+
(*_values).emplace_back(vec);
18611920

18621921
// create a map of duplicate indices
18631922
if (unique.find(vec) != unique.end())
1864-
{
18651923
(*_duplicates)[(*_values).size()-1] = unique[vec];
1866-
}
18671924
else
18681925
unique[vec] = (*_values).size()-1;
18691926
}
@@ -2187,7 +2244,7 @@ void ColladaLoader::Implementation::LoadPolylist(
21872244
set = gz::math::parseInt(setStr);
21882245
this->LoadTexCoords(source, texcoords[set], texDupMap[set]);
21892246
inputs[TEXCOORD].insert(offsetInt);
2190-
texcoordsOffsetToSet.push_back(std::make_pair(offsetInt, set));
2247+
texcoordsOffsetToSet.emplace_back(std::make_pair(offsetInt, set));
21912248
}
21922249
else
21932250
{
@@ -2211,7 +2268,7 @@ void ColladaLoader::Implementation::LoadPolylist(
22112268
std::vector<std::string> vcountStrs = split(vcountStr, " \t\r\n");
22122269
std::vector<int> vcounts;
22132270
for (unsigned int j = 0; j < vcountStrs.size(); ++j)
2214-
vcounts.push_back(math::parseInt(vcountStrs[j]));
2271+
vcounts.emplace_back(math::parseInt(vcountStrs[j]));
22152272

22162273
// read p
22172274
tinyxml2::XMLElement *pXml = _polylistXml->FirstChildElement("p");
@@ -2420,7 +2477,7 @@ void ColladaLoader::Implementation::LoadPolylist(
24202477
if (!inputs[VERTEX].empty())
24212478
{
24222479
std::vector<GeometryIndices> inputValues;
2423-
inputValues.push_back(input);
2480+
inputValues.emplace_back(input);
24242481
vertexIndexMap[daeVertIndex] = inputValues;
24252482
}
24262483
}
@@ -2548,7 +2605,7 @@ void ColladaLoader::Implementation::LoadTriangles(
25482605
set = gz::math::parseInt(setStr);
25492606
this->LoadTexCoords(source, texcoords[set], texDupMap[set]);
25502607
inputs[TEXCOORD].insert(offsetInt);
2551-
texcoordsOffsetToSet.push_back(std::make_pair(offsetInt, set));
2608+
texcoordsOffsetToSet.emplace_back(std::make_pair(offsetInt, set));
25522609
hasTexcoords = true;
25532610
}
25542611
else
@@ -2771,7 +2828,7 @@ void ColladaLoader::Implementation::LoadTriangles(
27712828
if (hasVertices)
27722829
{
27732830
std::vector<GeometryIndices> inputValues;
2774-
inputValues.push_back(input);
2831+
inputValues.emplace_back(input);
27752832
vertexIndexMap[daeVertIndex] = inputValues;
27762833
}
27772834
}
@@ -3014,7 +3071,7 @@ void ColladaLoader::Implementation::MergeSkeleton(SkeletonPtr _skeleton,
30143071
void ColladaLoader::Implementation::ApplyInvBindTransform(SkeletonPtr _skeleton)
30153072
{
30163073
std::list<SkeletonNode *> queue;
3017-
queue.push_back(_skeleton->RootNode());
3074+
queue.emplace_back(_skeleton->RootNode());
30183075

30193076
while (!queue.empty())
30203077
{
@@ -3026,6 +3083,6 @@ void ColladaLoader::Implementation::ApplyInvBindTransform(SkeletonPtr _skeleton)
30263083
if (node->HasInvBindTransform())
30273084
node->SetModelTransform(node->InverseBindTransform().Inverse(), false);
30283085
for (unsigned int i = 0; i < node->ChildCount(); i++)
3029-
queue.push_back(node->Child(i));
3086+
queue.emplace_back(node->Child(i));
30303087
}
30313088
}

0 commit comments

Comments
 (0)