/*!******************************************************************************************** @Function convert_signs @Input layer The map layer to extract the texts from. @Input atlas The texture atlas used for uv-coordinate calculation. @Output pivotquads The generated pivotquad vertex data. @Output triangles Triangle indices used for rendering of the pivotquads. @Description Generates pivotquads for the signs which will be screen-space aligned when being rendered. ***********************************************************************************************/ void convert_signs(const PVRTMapLayer &layer, const PVRTTextureAtlas &atlas, PVRTPivotQuadVertexVector &pivotquads, PVRTTriangleVector &triangles) { unsigned int numTotalSigns = layer.indexset.signs.size(); // Pre-allocate to prevent reallocations pivotquads.reserve(pivotquads.size() + numTotalSigns * 4); triangles.reserve(triangles.size() + numTotalSigns * 2); for (unsigned int j=0; j < numTotalSigns; j++) { const unsigned int index = pivotquads.size(); string name(layer.indexset.signs[j].szName); PVRTVec2 pos = layer.indexset.signs[j].position; if (!atlas.Contains(name)) { cerr << "Error: Texture atlas does not contain " << name << endl; continue; } PVRTMat3 texmat = atlas.GetTextureMatrix(name); PVRTVec3 uvcoords; PVRTPivotQuadVertex vertex; vertex.origin = pos; uvcoords = texmat * PVRTVec3(0.0f, 0.0f, 255.0f); vertex.word_index = 0; vertex.height_index = 0; vertex.u = (PVRTuint8)(uvcoords.x); vertex.v = (PVRTuint8)(uvcoords.y); pivotquads.push_back(vertex); uvcoords = texmat * PVRTVec3(255.0f, 0.0f, 255.0f); vertex.word_index = 1; vertex.height_index = 0; vertex.u = (PVRTuint8)(uvcoords.x); vertex.v = (PVRTuint8)(uvcoords.y); pivotquads.push_back(vertex); uvcoords = texmat * PVRTVec3(0.0f, 255.0f, 255.0f); vertex.word_index = 0; vertex.height_index = 1; vertex.u = (PVRTuint8)(uvcoords.x); vertex.v = (PVRTuint8)(uvcoords.y); pivotquads.push_back(vertex); uvcoords = texmat * PVRTVec3(255.0f, 255.0f, 255.0f); vertex.word_index = 1; vertex.height_index = 1; vertex.u = (PVRTuint8)(uvcoords.x); vertex.v = (PVRTuint8)(uvcoords.y); pivotquads.push_back(vertex); PVRTTriangle t0 = { index, index + 1, index + 3 }; PVRTTriangle t1 = { index, index + 3, index + 2 }; triangles.push_back(t0); triangles.push_back(t1); } }
/*!******************************************************************************************** @Function convert_texts @Input layer The map layer to extract the texts from. @Input atlas The texture atlas used for uv-coordinate calculation. @Output pivotquads The generated pivotquad vertex data. @Output triangles Triangle indices used for rendering of the pivotquads. @Description Generates pivotquads for the text strings which will be screen-space aligned when being rendered. ***********************************************************************************************/ void convert_texts(const PVRTMapLayer &layer, const PVRTTextureAtlas &atlas, PVRTPivotQuadVertexVector &pivotquads, PVRTTriangleVector &triangles) { unsigned int numTotalLetters = 0; for (unsigned int j=0; j < layer.indexset.texts.size(); j++) { numTotalLetters += strlen(layer.indexset.texts[j].szName); } // Pre-allocate to prevent reallocations pivotquads.reserve(pivotquads.size() + numTotalLetters * 4); triangles.reserve(triangles.size() + numTotalLetters * 2); for (unsigned int j=0; j < layer.indexset.texts.size(); j++) { const PVRTLinestrip &linestrip = layer.indexset.linestrips[layer.indexset.texts[j].index]; string name(layer.indexset.texts[j].szName); unsigned int numLetters = name.length(); float rand_pos = rand() / (float)RAND_MAX; // transform it to the range [0.2, 0.8] so that the streetnames are more in the middle of the street rand_pos = 0.2f + rand_pos * 0.6f; PVRTVec3 pos_3d = InterpolateLinestrip(layer.coordinates, linestrip, rand_pos); PVRTVec2 pos = PVRTVec2(pos_3d.x, pos_3d.y); int adjustedIndex = 0; unsigned int triangle_index = pivotquads.size(); // Calculate the total width unsigned int word_width = 0; for (unsigned int i=0; i < numLetters; i++) word_width += get_letter_spacing(name.at(i)); const int anchor_index = word_width / 2; size_t ordinal_pos; bool has_ordinal = contains_ordinal(name, ordinal_pos); for (unsigned int i=0; i < numLetters; i++) { if (name.at(i) == ' ') { adjustedIndex += get_letter_spacing(name.at(i)); continue; } triangle_index = pivotquads.size(); const int startIndex = adjustedIndex; int starty, endy; // If it contains an ordinal and the current letter is one if (has_ordinal && ((i == ordinal_pos) || i == (ordinal_pos + 1))) { adjustedIndex += 2; starty = 2; endy = 5; } else { adjustedIndex += get_letter_spacing(name.at(i)); get_height_indices(name.at(i), starty, endy); } string letter = name.substr(i, 1); PVRTMat3 texmat = atlas.GetTextureMatrix(letter); PVRTPivotQuadVertex vertex; vertex.origin = pos; PVRTVec3 uvcoords = texmat * PVRTVec3(0.0f, 0.0f, 255.0f); vertex.word_index = startIndex - anchor_index; vertex.height_index = starty; vertex.u = (PVRTuint8)(uvcoords.x); vertex.v = (PVRTuint8)(uvcoords.y); pivotquads.push_back(vertex); uvcoords = texmat * PVRTVec3(255.0f, 0.0f, 255.0f); vertex.word_index = adjustedIndex - anchor_index; vertex.height_index = starty; vertex.u = (PVRTuint8)(uvcoords.x); vertex.v = (PVRTuint8)(uvcoords.y); pivotquads.push_back(vertex); uvcoords = texmat * PVRTVec3(0.0f, 255.0f, 255.0f); vertex.word_index = startIndex - anchor_index; vertex.height_index = endy; vertex.u = (PVRTuint8)(uvcoords.x); vertex.v = (PVRTuint8)(uvcoords.y); pivotquads.push_back(vertex); uvcoords = texmat * PVRTVec3(255.0f, 255.0f, 255.0f); vertex.word_index = adjustedIndex - anchor_index; vertex.height_index = endy; vertex.u = (PVRTuint8)(uvcoords.x); vertex.v = (PVRTuint8)(uvcoords.y); pivotquads.push_back(vertex); PVRTTriangle t0 = { triangle_index, triangle_index + 1, triangle_index + 3 }; PVRTTriangle t1 = { triangle_index, triangle_index + 3, triangle_index + 2 }; triangles.push_back(t0); triangles.push_back(t1); } } }