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

Revision 11203, 5.3 kB (checked in by robert, 4 years ago) |
---|

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

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

[11203] | 2 | #include <assert.h> |

[11056] | 3 | |

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

5 | { | |

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

7 | } | |

8 | ||

9 | bool | |

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

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

12 | { | |

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

14 | ||

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

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

17 | ||

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

19 | { | |

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

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

22 | }; | |

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

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

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

26 | ||

27 | return (val1 < val2); | |

28 | } | |

29 | ||

30 | void | |

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

32 | unsigned int & nbVerticesY, | |

33 | unsigned int & nbVerticesZ) const | |

34 | { | |

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

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

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

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

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

40 | } | |

41 | ||

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

43 | { | |

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

45 | ||

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

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

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

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

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

51 | ||

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

[11056] | 53 | |

[11203] | 54 | OSG_NOTIFY(osg::INFO) |

[11194] | 55 | << "Cutting x by " << nbVerticesX << std::endl |

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

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

58 | ||

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

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

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

62 | ||

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

64 | short yinc = 1; | |

65 | short xinc = 1; | |

66 | unsigned int y = 0; | |

67 | unsigned int x = 0; | |

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

69 | { | |

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

71 | { | |

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

73 | { | |

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

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

76 | xMin -= 10; | |

77 | ||

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

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

80 | yMin -= 10; | |

81 | ||

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

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

84 | zMin -= 10; | |

85 | ||

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

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

88 | xMax += 10; | |

89 | ||

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

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

92 | yMax += 10; | |

93 | ||

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

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

96 | zMax += 10; | |

97 | ||

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

99 | yMin, | |

100 | zMin, | |

101 | xMax, | |

102 | yMax, | |

103 | zMax)); | |

104 | y += yinc; | |

105 | } | |

106 | yinc = -yinc; | |

107 | y += yinc; | |

108 | x += xinc; | |

109 | } | |

110 | xinc = -xinc; | |

111 | x += xinc; | |

112 | } | |

113 | } | |

114 | ||

115 | int | |

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

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

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

119 | { | |

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

121 | { | |

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

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

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

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

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

[11203] | 127 | z < boxList[i].zMax()) |

[11056] | 128 | { |

129 | return i; | |

130 | } | |

131 | } | |

[11203] | 132 | assert(false && "Point is not in any blocs"); |

133 | return 0; | |

[11056] | 134 | } |

135 | ||

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

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

138 | } |

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