#
root/OpenSceneGraph/trunk/src/osgPlugins/3ds/WriterCompareTriangle.cpp
@
11194

Revision 11194, 5.3 kB (checked in by robert, 5 years ago) |
---|

Rev | Line | |
---|---|---|

[11056] | 1 | #include "WriterCompareTriangle.h" |

2 | ||

3 | WriterCompareTriangle::WriterCompareTriangle(const osg::Geode & geode, unsigned int nbVertices) : geode(geode) | |

4 | { | |

5 | cutscene(nbVertices, geode.getBoundingBox()); | |

6 | } | |

7 | ||

8 | bool | |

9 | WriterCompareTriangle::operator()(const std::pair<Triangle, int> & t1, | |

10 | const std::pair<Triangle, int> & t2) const | |

11 | { | |

12 | const osg::Geometry *g = geode.getDrawable( t1.second )->asGeometry(); | |

13 | ||

14 | const osg::Vec3Array * vecs= static_cast<const osg::Vec3Array *>(g->getVertexArray()); | |

15 | const osg::BoundingBox::vec_type v1( (*vecs)[t1.first.t1] ); | |

16 | ||

17 | if (t1.second != t2.second) | |

18 | { | |

19 | const osg::Geometry *g = geode.getDrawable( t2.second )->asGeometry(); | |

20 | vecs = static_cast<const osg::Vec3Array *>(g->getVertexArray()); | |

21 | }; | |

22 | const osg::BoundingBox::vec_type v2( (*vecs)[t2.first.t1] ); | |

23 | int val1 = inWhichBox(v1); | |

24 | int val2 = inWhichBox(v2); | |

25 | ||

26 | return (val1 < val2); | |

27 | } | |

28 | ||

29 | void | |

30 | WriterCompareTriangle::setMaxMin(unsigned int & nbVerticesX, | |

31 | unsigned int & nbVerticesY, | |

32 | unsigned int & nbVerticesZ) const | |

33 | { | |

34 | static const unsigned int min = 1; | |

35 | static const unsigned int max = 5; // Number of blocks used to divide the scene (arbitrary but seems ok) | |

36 | nbVerticesX = osg::clampBetween<unsigned int>(nbVerticesX, min, max); | |

37 | nbVerticesY = osg::clampBetween<unsigned int>(nbVerticesY, min, max); | |

38 | nbVerticesZ = osg::clampBetween<unsigned int>(nbVerticesZ, min, max); | |

39 | } | |

40 | ||

41 | void WriterCompareTriangle::cutscene(int nbVertices, const osg::BoundingBox & sceneBox) | |

42 | { | |

43 | osg::BoundingBox::vec_type length = sceneBox._max - sceneBox._min; | |

44 | ||

45 | static const float k = 1.3f; // Arbitrary constant multiplier for density computation ("simulates" non-uniform point distributions) | |

46 | // Computes "density" of points, and thus the number of blocks to divide the mesh into | |

47 | unsigned int nbVerticesX = static_cast<unsigned int>( (nbVertices * k) / (length.z() * length.y()) ); | |

48 | unsigned int nbVerticesY = static_cast<unsigned int>( (nbVertices * k) / (length.z() * length.x()) ); | |

49 | unsigned int nbVerticesZ = static_cast<unsigned int>( (nbVertices * k) / (length.x() * length.y()) ); | |

50 | ||

[11194] | 51 | setMaxMin (nbVerticesX, nbVerticesY, nbVerticesZ); // This function prevent from cutting the scene in too many blocs |

[11056] | 52 | |

[11194] | 53 | osg::notify(osg::INFO) |

54 | << "Cutting x by " << nbVerticesX << std::endl | |

[11056] | 55 | << "Cutting y by " << nbVerticesY << std::endl |

56 | << "Cutting z by " << nbVerticesZ << std::endl; | |

57 | ||

[11194] | 58 | osg::BoundingBox::value_type blocX = length.x() / nbVerticesX; // These 3 lines set the size of a bloc in x, y and z |

[11056] | 59 | osg::BoundingBox::value_type blocY = length.y() / nbVerticesY; |

60 | osg::BoundingBox::value_type blocZ = length.z() / nbVerticesZ; | |

61 | ||

62 | boxList.reserve(nbVerticesX * nbVerticesY * nbVerticesZ); | |

63 | short yinc = 1; | |

64 | short xinc = 1; | |

65 | unsigned int y = 0; | |

66 | unsigned int x = 0; | |

67 | for (unsigned int z = 0; z < nbVerticesZ; ++z) | |

68 | { | |

69 | while (x < nbVerticesX && x >= 0) | |

70 | { | |

71 | while (y < nbVerticesY && y >= 0) | |

72 | { | |

73 | osg::BoundingBox::value_type xMin = sceneBox.xMin() + x * blocX; | |

74 | if (x == 0) //to prevent from mesh with no case | |

75 | xMin -= 10; | |

76 | ||

77 | osg::BoundingBox::value_type yMin = sceneBox.yMin() + y * blocY; | |

78 | if (y == 0) //to prevent from mesh with no case | |

79 | yMin -= 10; | |

80 | ||

81 | osg::BoundingBox::value_type zMin = sceneBox.zMin() + z * blocZ; | |

82 | if (z == 0) //to prevent from mesh with no case | |

83 | zMin -= 10; | |

84 | ||

85 | osg::BoundingBox::value_type xMax = sceneBox.xMin() + (x + 1) * blocX; | |

86 | if (x == nbVerticesX - 1) //to prevent from mesh with no case | |

87 | xMax += 10; | |

88 | ||

89 | osg::BoundingBox::value_type yMax = sceneBox.yMin() + (y + 1) * blocY; | |

90 | if (y == nbVerticesY - 1) //to prevent from mesh with no case | |

91 | yMax += 10; | |

92 | ||

93 | osg::BoundingBox::value_type zMax = sceneBox.zMin() + (z + 1) * blocZ; | |

94 | if (z == nbVerticesZ - 1) //to prevent from mesh with no case | |

95 | zMax += 10; | |

96 | ||

97 | boxList.push_back(osg::BoundingBox(xMin, // Add a bloc to the list | |

98 | yMin, | |

99 | zMin, | |

100 | xMax, | |

101 | yMax, | |

102 | zMax)); | |

103 | y += yinc; | |

104 | } | |

105 | yinc = -yinc; | |

106 | y += yinc; | |

107 | x += xinc; | |

108 | } | |

109 | xinc = -xinc; | |

110 | x += xinc; | |

111 | } | |

112 | } | |

113 | ||

114 | int | |

115 | WriterCompareTriangle::inWhichBox(const osg::BoundingBox::value_type x, | |

116 | const osg::BoundingBox::value_type y, | |

117 | const osg::BoundingBox::value_type z) const | |

118 | { | |

119 | for (unsigned int i = 0; i < boxList.size(); ++i) | |

120 | { | |

121 | if (x >= boxList[i].xMin() && | |

122 | x < boxList[i].xMax() && | |

123 | y >= boxList[i].yMin() && | |

124 | y < boxList[i].yMax() && | |

125 | z >= boxList[i].zMin() && | |

126 | z < boxList[i].zMax()) | |

127 | { | |

128 | return i; | |

129 | } | |

130 | } | |

131 | throw "Point is not in any blocs"; | |

132 | } | |

133 | ||

134 | int WriterCompareTriangle::inWhichBox(const osg::BoundingBox::vec_type & point) const { | |

135 | return inWhichBox(point.x(), point.y(), point.z()); | |

136 | } |

**Note:**See TracBrowser for help on using the browser.