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

Revision 10853, 5.4 kB (checked in by robert, 4 years ago) |
---|

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

[10853] | 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 | ||

51 | setMaxMin (nbVerticesX, nbVerticesY, nbVerticesZ); // This function prevent from cut scene in too many blocs | |

52 | ||

53 | osg::notify(osg::ALWAYS) << "Cutting x by " << nbVerticesX << std::endl | |

54 | << "Cutting y by " << nbVerticesY << std::endl | |

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

56 | ||

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

58 | osg::BoundingBox::value_type blocY = length.y() / nbVerticesY; | |

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

60 | ||

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

62 | short yinc = 1; | |

63 | short xinc = 1; | |

64 | unsigned int y = 0; | |

65 | unsigned int x = 0; | |

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

67 | { | |

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

69 | { | |

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

71 | { | |

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

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

74 | xMin -= 10; | |

75 | ||

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

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

78 | yMin -= 10; | |

79 | ||

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

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

82 | zMin -= 10; | |

83 | ||

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

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

86 | xMax += 10; | |

87 | ||

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

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

90 | yMax += 10; | |

91 | ||

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

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

94 | zMax += 10; | |

95 | ||

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

97 | yMin, | |

98 | zMin, | |

99 | xMax, | |

100 | yMax, | |

101 | zMax)); | |

102 | y += yinc; | |

103 | } | |

104 | yinc = -yinc; | |

105 | y += yinc; | |

106 | x += xinc; | |

107 | } | |

108 | xinc = -xinc; | |

109 | x += xinc; | |

110 | } | |

111 | } | |

112 | ||

113 | int | |

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

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

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

117 | { | |

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

119 | { | |

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

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

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

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

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

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

126 | { | |

127 | return i; | |

128 | } | |

129 | } | |

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

131 | } | |

132 | ||

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

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

135 | } |

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