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

Revision 11056, 5.3 kB (checked in by robert, 5 years ago)

From Sukender, "- Added support for extended filenames (=not 8.3) for images: reads without crashing, optionnally write extended filenames (correctly truncate names if option is OFF). Write option is OFF by default.
- Improved identifiers generation in duplicate name handling (was limited to 1000 name collisions, which can be very short for some usages).
- Set all read/write operations use a custom log function that will redirect lib3DS log to osg::notify() (was only used for streams)
- Removed custom code (now uses osgDB::getFilePath())
- Added missing supportsOption() calls
- Cleaned a few minor things"

RevLine 
[11056]1#include "WriterCompareTriangle.h"
2
3WriterCompareTriangle::WriterCompareTriangle(const osg::Geode & geode, unsigned int nbVertices) : geode(geode)
4{
5    cutscene(nbVertices, geode.getBoundingBox());
6}
7
8bool 
9WriterCompareTriangle::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
29void
30WriterCompareTriangle::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
41void 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
113int 
114WriterCompareTriangle::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
133int 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.