xmlNode* AddArray(xmlNode* parent, const char* id, const FloatList& values) { size_t valueCount = values.size(); FUSStringBuilder builder; builder.reserve(valueCount * FLOAT_STR_ESTIMATE); FUStringConversion::ToString(builder, values); return AddArray(parent, id, DAE_FLOAT_ARRAY_ELEMENT, builder.ToCharPtr(), valueCount); }
xmlNode* AddArray(xmlNode* parent, const char* id, const FMMatrix44List& values) { FUSStringBuilder builder; size_t valueCount = values.size(); builder.reserve(valueCount * 16 * FLOAT_STR_ESTIMATE); if (valueCount > 0) { FMMatrix44List::const_iterator itM = values.begin(); FUStringConversion::ToString(builder, *itM); for (++itM; itM != values.end(); ++itM) { builder.append(' '); FUStringConversion::ToString(builder, *itM); } } return AddArray(parent, id, DAE_FLOAT_ARRAY_ELEMENT, builder.ToCharPtr(), valueCount * 16); }
fm::string FUStringConversion::ToString(const fchar* value) { FUSStringBuilder builder; if (value != NULL) { uint32 length = (uint32) fstrlen(value); builder.reserve(length + 1); for (uint32 i = 0; i < length; ++i) { if (value[i] < 0xFF || (value[i] & (~0xFF)) >= 32) builder.append((char)value[i]); else builder.append('_'); // some generic enough character } } return builder.ToString(); }
xmlNode* AddArray(xmlNode* parent, const char* id, const FMVector3List& values) { // Reserve the necessary space within the string builder FUSStringBuilder builder; size_t valueCount = values.size(); builder.reserve(valueCount * 3 * FLOAT_STR_ESTIMATE); if (valueCount > 0) { // Write out the values FMVector3List::const_iterator itP = values.begin(); FUStringConversion::ToString(builder, *itP); for (++itP; itP != values.end(); ++itP) { builder.append(' '); FUStringConversion::ToString(builder, *itP); } } // Create the typed array node. return AddArray(parent, id, DAE_FLOAT_ARRAY_ELEMENT, builder.ToCharPtr(), valueCount * 3); }
// Convert a XML string to a text string: handles the '%' character fm::string XmlToString(const char* s) { // Replace any '%' character string into the wanted characters: %20 is common. FUSStringBuilder xmlSBuilder; char c; while ((c = *s) != 0) { if (c != '%') { xmlSBuilder.append(c); ++s; } else { ++s; // skip the '%' character uint32 value = FUStringConversion::HexToUInt32(&s, 2); xmlSBuilder.append((char) value); } } return xmlSBuilder.ToString(); }
xmlNode* AddSourceInterpolation(xmlNode* parent, const char* id, const FUDaeInterpolationList& interpolations) { xmlNode* sourceNode = AddChild(parent, DAE_SOURCE_ELEMENT); AddAttribute(sourceNode, DAE_ID_ATTRIBUTE, id); FUSStringBuilder arrayId(id); arrayId.append("-array"); FUSStringBuilder builder; size_t valueCount = interpolations.size(); if (valueCount > 0) { FUDaeInterpolationList::const_iterator itI = interpolations.begin(); builder.append(FUDaeInterpolation::ToString(*itI)); for (++itI; itI != interpolations.end(); ++itI) { builder.append(' '); builder.append(FUDaeInterpolation::ToString(*itI)); } } AddArray(sourceNode, arrayId.ToCharPtr(), DAE_NAME_ARRAY_ELEMENT, builder.ToCharPtr(), valueCount); xmlNode* techniqueCommonNode = AddChild(sourceNode, DAE_TECHNIQUE_COMMON_ELEMENT); const char* parameter = "INTERPOLATION"; AddAccessor(techniqueCommonNode, arrayId.ToCharPtr(), valueCount, 1, ¶meter, DAE_NAME_TYPE); return sourceNode; }
xmlNode* AddArray(xmlNode* parent, const char* id, const StringList& values, const char* arrayType) { size_t valueCount = values.size(); FUSStringBuilder builder; builder.reserve(valueCount * 18); // Pulled out of a hat if (valueCount > 0) { StringList::const_iterator itV = values.begin(); builder.set(*itV); for (++itV; itV != values.end(); ++itV) { builder.append(' '); builder.append(*itV); } } return AddArray(parent, id, arrayType, builder.ToCharPtr(), valueCount); }
// Calculate the target pointer for a targetable node void CalculateNodeTargetPointer(xmlNode* target, fm::string& pointer) { if (target != NULL) { // The target node should have either a subid or an id if (HasNodeProperty(target, DAE_ID_ATTRIBUTE)) { pointer = ReadNodeId(target); return; } else if (!HasNodeProperty(target, DAE_SID_ATTRIBUTE)) { pointer.clear(); return; } // Generate a list of parent nodes up to the first properly identified parent xmlNodeList traversal; traversal.reserve(16); traversal.push_back(target); xmlNode* current = target->parent; while (current != NULL) { traversal.push_back(current); if (HasNodeProperty(current, DAE_ID_ATTRIBUTE)) break; current = current->parent; } // The top parent should have the ID property FUSStringBuilder builder; intptr_t nodeCount = (intptr_t) traversal.size(); builder.append(ReadNodeId(traversal[nodeCount - 1])); if (builder.empty()) { pointer.clear(); return; } // Build up the target string for (intptr_t i = nodeCount - 2; i >= 0; --i) { xmlNode* node = traversal[i]; fm::string subId = ReadNodeProperty(node, DAE_SID_ATTRIBUTE); if (!subId.empty()) { builder.append('/'); builder.append(subId); } } pointer = builder.ToString(); } else pointer.clear(); }
fm::string FUStringConversion::ToString(const FMMatrix44& m) { FUSStringBuilder builder; ToString(builder, m); return builder.ToString(); }
// Convert a vector4 to a string fm::string FUStringConversion::ToString(const FMVector4& p) { FUSStringBuilder builder; ToString(builder, p); return builder.ToString(); }