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

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

From Sukender, "I've fixed positions for 3DS writer. Points in 3DS must be in world coordinates and I added what was missing.
And by refactoring a bit of code, I may have fixed some StateSets? related bugs (was ignoring StateSets? for osg::Groups).
I also added support for Billboard's points, so now "osgconv lz.osg lz.3ds" has an acceptable output. However, there is no rotation depending on billboards' axis, hence the notice "Warning: 3DS writer is incomplete for Billboards (rotation not implemented).". You may want to remove this notice (or lower the notify severity) if you feel 3DS doesn't have to handle such rotations.
The attached archive contains 3 files from 3DS plugin, against rev. 11162.

Please note there is still the textures issue for cow.osg. I guess it's because it's not a "flat, dummy and standard" texture in slot 0... That is to say the only thing the writer can handle at the moment. I guess I won't address this soon.
"
and

"I've detected and fixed another bug in 3DS writer: support for automatic splitting of meshes having >65k faces/points was buggy (was deleting faces).
Here is my four 3DS modified files (in a ZIP), against rev. 11193, including previous fixes AND Stephan's fix about relative filenames."

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
[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
114int 
115WriterCompareTriangle::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
134int 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.