Skip to content

Commit

Permalink
more optimizations. Remove iss, move ptr check conditions outside of …
Browse files Browse the repository at this point in the history
…loop, use emplace_back

Signed-off-by: frederik <[email protected]>
  • Loading branch information
frede791 committed Jan 12, 2024
1 parent f0ff34f commit 4cff57c
Showing 1 changed file with 132 additions and 75 deletions.
207 changes: 132 additions & 75 deletions graphics/src/ColladaLoader.cc
Original file line number Diff line number Diff line change
Expand Up @@ -346,8 +346,11 @@ struct Vector3Hash
{
std::size_t seed = 0;
hash_combine(seed, _v.X());
// std::cout << "seed after x" << seed << std::endl;
hash_combine(seed, _v.Y());
// std::cout << "seed after y" << seed << std::endl;
hash_combine(seed, _v.Z());
// std::cout << "seed after z" << seed << std::endl;
return seed;
}
};
Expand All @@ -359,7 +362,9 @@ struct Vector2dHash
{
std::size_t seed = 0;
hash_combine(seed, _v.X());
// std::cout << "seed after x" << seed << std::endl;
hash_combine(seed, _v.Y());
// std::cout << "seed after y" << seed << std::endl;
return seed;
}
};
Expand Down Expand Up @@ -884,7 +889,7 @@ void ColladaLoader::Implementation::LoadController(

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

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

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

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

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

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

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

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

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

tinyxml2::XMLElement *accessor =
frameTransXml->FirstChildElement("technique_common");
Expand Down Expand Up @@ -1541,6 +1546,7 @@ void ColladaLoader::Implementation::LoadPositions(const std::string &_id,
auto toDoubleVec = [](std::string_view sv, size_t totalCount)
{
std::vector<double> result;
// Preallocate memory based on known count
result.reserve(totalCount * 3);
const char *start = sv.data();
char *end{};
Expand All @@ -1552,40 +1558,33 @@ void ColladaLoader::Implementation::LoadPositions(const std::string &_id,
start = end;
if (errno == ERANGE)
throw std::runtime_error("strtod() overflow");
result.push_back(d);
result.emplace_back(d);
}
return result;
};

auto values = toDoubleVec(valueStr, totCount);

gz::math::Vector3d vec;
if (!_values)
_values = std::make_shared<std::vector<gz::math::Vector3d>>();
if (!_duplicates)
_duplicates = std::make_shared<std::unordered_map<unsigned int,
unsigned int>>();
for (int i = 0; i < totCount; i += stride)
{
gz::math::Vector3d vec(values[i],
values[i+1],
values[i+2]);
vec.Set(values[i],
values[i+1],
values[i+2]);

vec = _transform * vec;
if (!_values)
{
_values = std::make_shared<std::vector<gz::math::Vector3d>>();
}
(*_values).push_back(vec);

if (!_duplicates)
{
_duplicates = std::make_shared<std::unordered_map<unsigned int,
unsigned int>>();
}
(*_values).emplace_back(vec);

// create a map of duplicate indices
if (unique.find(vec) != unique.end())
{
(*_duplicates)[(*_values).size()-1] = unique[vec];
}
else
{
unique[vec] = (*_values).size()-1;
}
}

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

tinyxml2::XMLElement *floatArrayXml =
normalsXml->FirstChildElement("float_array");

int totCount = 0;
int stride = 0;

if (!floatArrayXml || !floatArrayXml->GetText())
{
int count = 1;
Expand All @@ -1635,7 +1638,7 @@ void ColladaLoader::Implementation::LoadNormals(const std::string &_id,

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

return;
}
// Read in the total number of normal coordinate values
else if (floatArrayXml->Attribute("count"))
totCount = std::stoi(floatArrayXml->Attribute("count"));
else
{
gzerr << "<float_array> has no count attribute in normal coordinate "
<< "element with id[" << _id << "]\n";
return;
}

normalsXml = normalsXml->FirstChildElement("technique_common");
if (!normalsXml)
{
gzerr << "Unable to find technique_common element for normals "
<< "coordinates with id[" << _id << "]\n";
return;
}

// Get the accessor XML element.
normalsXml = normalsXml->FirstChildElement("accessor");
if (!normalsXml)
{
gzerr << "Unable to find <accessor> as a child of <technique_common> "
<< "for normals coordinates with id[" << _id << "]\n";
return;
}

// Read in the stride for the normals coordinate values. The stride
// indicates the number of values in the float array the comprise
// a complete normal coordinate.
if (normalsXml->Attribute("stride"))
{
stride = std::stoi(normalsXml->Attribute("stride"));
}
else
{
gzerr << "<accessor> has no stride attribute in normal coordinate "
<< "element with id[" << _id << "]\n";
return;
}

// Nothing to read. Don't print a warning because the collada file is
// correct.
if (totCount == 0)
return;

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

std::string valueStr = floatArrayXml->GetText();
std::istringstream iss(valueStr);
do
// std::istringstream iss(valueStr);

auto toDoubleVec = [](std::string_view sv, size_t totalCount)
{
gz::math::Vector3d vec;
iss >> vec.X() >> vec.Y() >> vec.Z();
if (iss)
std::vector<double> result;
// Preallocate memory based on known count
result.reserve(totalCount * 3);
const char *start = sv.data();
char *end{};
while (true)
{
vec = rotMat * vec;
vec.Normalize();
if (!_values)
{
_values = std::make_shared<std::vector<gz::math::Vector3d>>();
}
(*_values).push_back(vec);
double d = std::strtod(start, &end);
if (start == end)
break;
start = end;
if (errno == ERANGE)
throw std::runtime_error("strtod() overflow");
result.emplace_back(d);
}
return result;
};

if (!_duplicates)
{
auto values = toDoubleVec(valueStr, totCount);

gz::math::Vector3d vec;
if (!_values)
_values = std::make_shared<std::vector<gz::math::Vector3d>>();
if (!_duplicates)
_duplicates = std::make_shared<std::unordered_map<unsigned int,
unsigned int>>();
}

// create a map of duplicate indices
if (unique.find(vec) != unique.end())
{
(*_duplicates)[(*_values).size()-1] = unique[vec];
}
else
{
unique[vec] = (*_values).size()-1;
}
}
} while (iss);
for (int i = 0; i < totCount; i += stride)
{
vec.Set(values[i],
values[i+1],
values[i+2]);

vec = rotMat * vec;
vec.Normalize();
(*_values).emplace_back(vec);

// create a map of duplicate indices
if (unique.find(vec) != unique.end())
(*_duplicates)[(*_values).size()-1] = unique[vec];
else
unique[vec] = (*_values).size()-1;
}

this->normalDuplicateMap[_id] = _duplicates;
this->normalIds[_id] = _values;
Expand Down Expand Up @@ -1820,6 +1883,7 @@ void ColladaLoader::Implementation::LoadTexCoords(const std::string &_id,
auto toDoubleVec = [](std::string_view sv, size_t totalCount)
{
std::vector<double> result;
// Preallocate memory based on known count
result.reserve(totalCount * 2);
const char *start = sv.data();
char *end{};
Expand All @@ -1831,7 +1895,7 @@ void ColladaLoader::Implementation::LoadTexCoords(const std::string &_id,
start = end;
if (errno == ERANGE)
throw std::runtime_error("strtod() overflow");
result.push_back(d);
result.emplace_back(d);
}
return result;
};
Expand All @@ -1840,30 +1904,23 @@ void ColladaLoader::Implementation::LoadTexCoords(const std::string &_id,
std::string valueStr = floatArrayXml->GetText();
auto values = toDoubleVec(valueStr, totCount);

gz::math::Vector2d vec;
if (!_values)
_values = std::make_shared<std::vector<gz::math::Vector2d>>();
if (!_duplicates)
_duplicates = std::make_shared<std::unordered_map<unsigned int,
unsigned int>>();
// Read in all the texture coordinates.
for (int i = 0; i < totCount; i += stride)
{
// We only handle 2D texture coordinates right now.
gz::math::Vector2d vec(values[i],
1.0 - values[i + 1]);

if (!_values)
{
_values = std::make_shared<std::vector<gz::math::Vector2d>>();
}
(*_values).push_back(vec);

if (!_duplicates)
{
_duplicates = std::make_shared<std::unordered_map<unsigned int,
unsigned int>>();
}
vec.Set(values[i],
1.0 - values[i + 1]);
(*_values).emplace_back(vec);

// create a map of duplicate indices
if (unique.find(vec) != unique.end())
{
(*_duplicates)[(*_values).size()-1] = unique[vec];
}
else
unique[vec] = (*_values).size()-1;
}
Expand Down Expand Up @@ -2187,7 +2244,7 @@ void ColladaLoader::Implementation::LoadPolylist(
set = gz::math::parseInt(setStr);
this->LoadTexCoords(source, texcoords[set], texDupMap[set]);
inputs[TEXCOORD].insert(offsetInt);
texcoordsOffsetToSet.push_back(std::make_pair(offsetInt, set));
texcoordsOffsetToSet.emplace_back(std::make_pair(offsetInt, set));
}
else
{
Expand All @@ -2211,7 +2268,7 @@ void ColladaLoader::Implementation::LoadPolylist(
std::vector<std::string> vcountStrs = split(vcountStr, " \t\r\n");
std::vector<int> vcounts;
for (unsigned int j = 0; j < vcountStrs.size(); ++j)
vcounts.push_back(math::parseInt(vcountStrs[j]));
vcounts.emplace_back(math::parseInt(vcountStrs[j]));

// read p
tinyxml2::XMLElement *pXml = _polylistXml->FirstChildElement("p");
Expand Down Expand Up @@ -2420,7 +2477,7 @@ void ColladaLoader::Implementation::LoadPolylist(
if (!inputs[VERTEX].empty())
{
std::vector<GeometryIndices> inputValues;
inputValues.push_back(input);
inputValues.emplace_back(input);
vertexIndexMap[daeVertIndex] = inputValues;
}
}
Expand Down Expand Up @@ -2548,7 +2605,7 @@ void ColladaLoader::Implementation::LoadTriangles(
set = gz::math::parseInt(setStr);
this->LoadTexCoords(source, texcoords[set], texDupMap[set]);
inputs[TEXCOORD].insert(offsetInt);
texcoordsOffsetToSet.push_back(std::make_pair(offsetInt, set));
texcoordsOffsetToSet.emplace_back(std::make_pair(offsetInt, set));
hasTexcoords = true;
}
else
Expand Down Expand Up @@ -2771,7 +2828,7 @@ void ColladaLoader::Implementation::LoadTriangles(
if (hasVertices)
{
std::vector<GeometryIndices> inputValues;
inputValues.push_back(input);
inputValues.emplace_back(input);
vertexIndexMap[daeVertIndex] = inputValues;
}
}
Expand Down Expand Up @@ -3014,7 +3071,7 @@ void ColladaLoader::Implementation::MergeSkeleton(SkeletonPtr _skeleton,
void ColladaLoader::Implementation::ApplyInvBindTransform(SkeletonPtr _skeleton)
{
std::list<SkeletonNode *> queue;
queue.push_back(_skeleton->RootNode());
queue.emplace_back(_skeleton->RootNode());

while (!queue.empty())
{
Expand All @@ -3026,6 +3083,6 @@ void ColladaLoader::Implementation::ApplyInvBindTransform(SkeletonPtr _skeleton)
if (node->HasInvBindTransform())
node->SetModelTransform(node->InverseBindTransform().Inverse(), false);
for (unsigned int i = 0; i < node->ChildCount(); i++)
queue.push_back(node->Child(i));
queue.emplace_back(node->Child(i));
}
}

0 comments on commit 4cff57c

Please sign in to comment.