[162] | 1 | #include <stack>
|
---|
| 2 | #include "common.h"
|
---|
| 3 | #include "SceneGraph.h"
|
---|
| 4 | #include "X3dExporter.h"
|
---|
| 5 | #include "Mesh.h"
|
---|
| 6 | #include "KdTree.h"
|
---|
| 7 |
|
---|
| 8 |
|
---|
| 9 | X3dExporter::X3dExporter(const string filename):Exporter(filename)
|
---|
| 10 | {
|
---|
| 11 | stream.open(mFilename.c_str());
|
---|
| 12 | stream<<"<?xml version=\"1.0\" encoding=\"UTF-8\"?>"<<endl;
|
---|
| 13 | stream<<"<X3D>"<<endl;
|
---|
| 14 | stream<<"<Scene>"<<endl;
|
---|
| 15 |
|
---|
| 16 | }
|
---|
| 17 |
|
---|
| 18 | X3dExporter::~X3dExporter()
|
---|
| 19 | {
|
---|
| 20 | stream<<"</Scene>"<<endl;
|
---|
| 21 | stream<<"</X3D>"<<endl;
|
---|
| 22 | stream.close();
|
---|
| 23 | }
|
---|
| 24 |
|
---|
[176] | 25 |
|
---|
[162] | 26 | bool
|
---|
[176] | 27 | X3dExporter::ExportRays(const vector<Ray> &rays,
|
---|
| 28 | const float length,
|
---|
| 29 | const RgbColor &color)
|
---|
[162] | 30 | {
|
---|
| 31 | vector<Ray>::const_iterator ri = rays.begin();
|
---|
| 32 | stream<<"<Shape>"<<endl;
|
---|
[176] | 33 | stream<<"<Appearance>"<<endl;
|
---|
| 34 | stream<<"<Material ambientColor=\""<<color.r<<" "<<color.g<<" "<<color.b<<
|
---|
| 35 | "\" />"<<endl;
|
---|
| 36 | stream<<"</Appearance>"<<endl;
|
---|
| 37 |
|
---|
[162] | 38 | stream<<"<IndexedLineSet ccw=\"TRUE\" coordIndex=\""<<endl;
|
---|
| 39 |
|
---|
| 40 | int index = 0;
|
---|
| 41 | for (; ri != rays.end(); ri++) {
|
---|
| 42 | stream<<index<<" "<<index+1<<" -1\n";
|
---|
| 43 | index+=2;
|
---|
| 44 | }
|
---|
| 45 |
|
---|
| 46 | stream<<"\" >"<<endl;
|
---|
| 47 |
|
---|
| 48 | stream<<"<Coordinate point=\""<<endl;
|
---|
| 49 |
|
---|
| 50 | ri = rays.begin();
|
---|
| 51 | for (; ri != rays.end(); ri++) {
|
---|
| 52 | Vector3 a = (*ri).GetLoc();
|
---|
| 53 |
|
---|
[176] | 54 | Vector3 b;
|
---|
| 55 | if (length < 0)
|
---|
| 56 | b = (*ri).GetLoc() - length*(*ri).GetDir();
|
---|
| 57 | else
|
---|
| 58 | if ((*ri).intersections.size()==0)
|
---|
| 59 | b = (*ri).GetLoc() + length*(*ri).GetDir();
|
---|
| 60 | else
|
---|
| 61 | b = (*ri).Extrap((*ri).intersections[0].mT);
|
---|
| 62 |
|
---|
[162] | 63 | stream<<a.x<<" "<<a.y<<" "<<a.z<<" ,";
|
---|
| 64 | stream<<b.x<<" "<<b.y<<" "<<b.z<<" ,\n";
|
---|
| 65 | }
|
---|
| 66 |
|
---|
| 67 | stream<<"\" >"<<endl;
|
---|
| 68 | stream<<"</Coordinate>"<<endl;
|
---|
| 69 | stream<<"</IndexedLineSet>"<<endl;
|
---|
| 70 | stream<<"</Shape>"<<endl;
|
---|
| 71 | return true;
|
---|
| 72 | }
|
---|
| 73 |
|
---|
| 74 | void
|
---|
| 75 | X3dExporter::ExportSceneNode(SceneGraphNode *node)
|
---|
| 76 | {
|
---|
| 77 | stream<<"<Group>"<<endl;
|
---|
| 78 |
|
---|
| 79 | SceneGraphNodeContainer::iterator ni = node->mChildren.begin();
|
---|
| 80 | for (; ni != node->mChildren.end(); ni++)
|
---|
| 81 | ExportSceneNode(*ni);
|
---|
| 82 |
|
---|
| 83 |
|
---|
[176] | 84 | ObjectContainer::const_iterator mi = node->mGeometry.begin();
|
---|
[162] | 85 | for (; mi != node->mGeometry.end(); mi++) {
|
---|
| 86 | // export the transform...
|
---|
[176] | 87 | ExportIntersectable(*mi);
|
---|
[162] | 88 | }
|
---|
| 89 |
|
---|
| 90 | stream<<"</Group>"<<endl;
|
---|
| 91 |
|
---|
| 92 | }
|
---|
[176] | 93 | void
|
---|
| 94 | X3dExporter::ExportIntersectable(Intersectable *object)
|
---|
| 95 | {
|
---|
| 96 | switch (object->Type()) {
|
---|
| 97 | case Intersectable::MESH_INSTANCE:
|
---|
| 98 | case Intersectable::TRANSFORMED_MESH_INSTANCE:
|
---|
| 99 | ExportMeshInstance((MeshInstance *)object);
|
---|
| 100 | break;
|
---|
| 101 | default:
|
---|
| 102 | cerr<<"Sorry the export for object not yet defined"<<endl;
|
---|
| 103 | break;
|
---|
| 104 | }
|
---|
| 105 | }
|
---|
[162] | 106 |
|
---|
| 107 | void
|
---|
[176] | 108 | X3dExporter::ExportMeshInstance(MeshInstance *object)
|
---|
| 109 | {
|
---|
| 110 | // $$JB$$
|
---|
| 111 | // in the future check whether the mesh was not already exportet
|
---|
| 112 | // and use a reference to the that mesh instead
|
---|
| 113 | ExportMesh(object->GetMesh());
|
---|
| 114 | }
|
---|
| 115 |
|
---|
| 116 | void
|
---|
[162] | 117 | X3dExporter::ExportMesh(Mesh *mesh)
|
---|
| 118 | {
|
---|
| 119 |
|
---|
| 120 | stream<<"<Shape>"<<endl;
|
---|
| 121 | stream<<"<Appearance>"<<endl;
|
---|
[176] | 122 |
|
---|
[162] | 123 | // $$ tmp -> random material
|
---|
| 124 |
|
---|
| 125 | float r, g, b;
|
---|
| 126 |
|
---|
[176] | 127 | if (mUseForcedMaterial) {
|
---|
| 128 | r = mForcedMaterial.mDiffuseColor.r;
|
---|
| 129 | g = mForcedMaterial.mDiffuseColor.g;
|
---|
| 130 | b = mForcedMaterial.mDiffuseColor.b;
|
---|
| 131 |
|
---|
| 132 | } else
|
---|
| 133 | if (mesh->mMaterial) {
|
---|
| 134 | r = mesh->mMaterial->mDiffuseColor.r;
|
---|
| 135 | g = mesh->mMaterial->mDiffuseColor.g;
|
---|
| 136 | b = mesh->mMaterial->mDiffuseColor.b;
|
---|
| 137 | } else {
|
---|
| 138 | r = RandomValue(0.5, 1.0);
|
---|
| 139 | g = RandomValue(0.5, 1.0);
|
---|
| 140 | b = RandomValue(0.5, 1.0);
|
---|
| 141 | }
|
---|
[162] | 142 | stream<<"<Material diffuseColor=\""<<r<<" "<<g<<" "<<b<<
|
---|
| 143 | "\" specularColor=\"0.0 0.0 0.0\"/>"<<endl;
|
---|
| 144 | stream<<"</Appearance>"<<endl;
|
---|
| 145 |
|
---|
| 146 |
|
---|
[191] | 147 | if (mWireframe)
|
---|
[162] | 148 | stream<<"<IndexedLineSet ccw=\"TRUE\" coordIndex=\""<<endl;
|
---|
| 149 | else
|
---|
| 150 | stream<<"<IndexedFaceSet ccw=\"TRUE\" coordIndex=\""<<endl;
|
---|
| 151 |
|
---|
| 152 | FaceContainer::const_iterator fi = mesh->mFaces.begin();
|
---|
| 153 |
|
---|
| 154 | int index = 0;
|
---|
| 155 |
|
---|
| 156 | for (; fi != mesh->mFaces.end(); fi++) {
|
---|
| 157 | Face *face = *fi;
|
---|
| 158 | VertexIndexContainer::const_iterator vi = face->mVertexIndices.begin();
|
---|
| 159 | for (; vi != face->mVertexIndices.end(); vi++)
|
---|
| 160 | stream<<*vi<<" ";
|
---|
| 161 | stream<<"-1"<<endl;
|
---|
| 162 | }
|
---|
| 163 | stream<<"\" >"<<endl;
|
---|
| 164 |
|
---|
| 165 | stream<<"<Coordinate point=\""<<endl;
|
---|
| 166 |
|
---|
| 167 | VertexContainer::const_iterator vi = mesh->mVertices.begin();
|
---|
| 168 | for (; vi != mesh->mVertices.end(); vi++) {
|
---|
| 169 | stream<<(*vi).x<<" "<<(*vi).y<<" "<<(*vi).z;
|
---|
| 170 | stream<<","<<endl;
|
---|
| 171 | }
|
---|
| 172 |
|
---|
| 173 | stream<<"\" >"<<endl;
|
---|
| 174 | stream<<"</Coordinate>"<<endl;
|
---|
| 175 |
|
---|
[191] | 176 | if (mWireframe)
|
---|
[162] | 177 | stream<<"</IndexedLineSet>"<<endl;
|
---|
| 178 | else
|
---|
| 179 | stream<<"</IndexedFaceSet>"<<endl;
|
---|
| 180 |
|
---|
| 181 | stream<<"</Shape>"<<endl;
|
---|
| 182 |
|
---|
| 183 | }
|
---|
| 184 |
|
---|
| 185 | bool
|
---|
| 186 | X3dExporter::ExportBox(const AxisAlignedBox3 &box)
|
---|
| 187 | {
|
---|
| 188 | Mesh *mesh = new Mesh;
|
---|
| 189 | // add 6 vertices of the box
|
---|
| 190 | int index = mesh->mVertices.size();
|
---|
| 191 | for (int i=0; i < 8; i++) {
|
---|
| 192 | Vector3 v;
|
---|
| 193 | box.GetVertex(i, v);
|
---|
| 194 | mesh->mVertices.push_back(v);
|
---|
| 195 | }
|
---|
| 196 |
|
---|
| 197 | mesh->AddFace(new Face(index + 0, index + 1, index + 3, index + 2) );
|
---|
| 198 | mesh->AddFace(new Face(index + 0, index + 2, index + 6, index + 4) );
|
---|
| 199 | mesh->AddFace(new Face(index + 4, index + 6, index + 7, index + 5) );
|
---|
| 200 |
|
---|
| 201 | mesh->AddFace(new Face(index + 3, index + 1, index + 5, index + 7) );
|
---|
| 202 | mesh->AddFace(new Face(index + 0, index + 4, index + 5, index + 1) );
|
---|
| 203 | mesh->AddFace(new Face(index + 2, index + 3, index + 7, index + 6) );
|
---|
| 204 |
|
---|
| 205 | ExportMesh(mesh);
|
---|
| 206 | delete mesh;
|
---|
| 207 | return true;
|
---|
| 208 | }
|
---|
| 209 |
|
---|
| 210 | bool
|
---|
| 211 | X3dExporter::ExportKdTree(const KdTree &tree)
|
---|
| 212 | {
|
---|
[191] | 213 | if (mExportRayDensity) {
|
---|
| 214 | return ExportKdTreeRayDensity(tree);
|
---|
| 215 | }
|
---|
| 216 |
|
---|
[162] | 217 | stack<KdNode *> tStack;
|
---|
| 218 |
|
---|
| 219 | tStack.push(tree.GetRoot());
|
---|
| 220 |
|
---|
| 221 | Mesh *mesh = new Mesh;
|
---|
| 222 |
|
---|
| 223 | while (!tStack.empty()) {
|
---|
| 224 | KdNode *node = tStack.top();
|
---|
| 225 | tStack.pop();
|
---|
| 226 | AxisAlignedBox3 box = tree.GetBox(node);
|
---|
| 227 | // add 6 vertices of the box
|
---|
| 228 | int index = mesh->mVertices.size();
|
---|
| 229 | for (int i=0; i < 8; i++) {
|
---|
| 230 | Vector3 v;
|
---|
| 231 | box.GetVertex(i, v);
|
---|
| 232 | mesh->mVertices.push_back(v);
|
---|
| 233 | }
|
---|
| 234 | mesh->AddFace(new Face(index + 0, index + 1, index + 3, index + 2) );
|
---|
| 235 | mesh->AddFace(new Face(index + 0, index + 2, index + 6, index + 4) );
|
---|
| 236 | mesh->AddFace(new Face(index + 4, index + 6, index + 7, index + 5) );
|
---|
| 237 |
|
---|
| 238 | mesh->AddFace(new Face(index + 3, index + 1, index + 5, index + 7) );
|
---|
| 239 | mesh->AddFace(new Face(index + 0, index + 4, index + 5, index + 1) );
|
---|
| 240 | mesh->AddFace(new Face(index + 2, index + 3, index + 7, index + 6) );
|
---|
| 241 |
|
---|
| 242 | if (!node->IsLeaf()) {
|
---|
| 243 | KdInterior *interior = (KdInterior *)node;
|
---|
| 244 | tStack.push(interior->mFront);
|
---|
| 245 | tStack.push(interior->mBack);
|
---|
| 246 | }
|
---|
| 247 | }
|
---|
| 248 |
|
---|
| 249 | ExportMesh(mesh);
|
---|
| 250 | delete mesh;
|
---|
| 251 | return true;
|
---|
| 252 | }
|
---|
| 253 |
|
---|
| 254 |
|
---|
[191] | 255 | bool
|
---|
| 256 | X3dExporter::ExportKdTreeRayDensity(const KdTree &tree)
|
---|
| 257 | {
|
---|
| 258 | stack<KdNode *> tStack;
|
---|
| 259 |
|
---|
| 260 | tStack.push(tree.GetRoot());
|
---|
| 261 |
|
---|
| 262 | bool fm = mUseForcedMaterial;
|
---|
| 263 | mUseForcedMaterial = true;
|
---|
| 264 | mForcedMaterial.mDiffuseColor.g = 1.0f;
|
---|
| 265 | mForcedMaterial.mDiffuseColor.b = 1.0f;
|
---|
| 266 | while (!tStack.empty()) {
|
---|
| 267 | KdNode *node = tStack.top();
|
---|
| 268 | tStack.pop();
|
---|
| 269 | if (node->IsLeaf()) {
|
---|
| 270 | AxisAlignedBox3 box = tree.GetBox(node);
|
---|
| 271 | Mesh *mesh = new Mesh;
|
---|
| 272 |
|
---|
| 273 | // add 6 vertices of the box
|
---|
| 274 | int index = mesh->mVertices.size();
|
---|
| 275 | for (int i=0; i < 8; i++) {
|
---|
| 276 | Vector3 v;
|
---|
| 277 | box.GetVertex(i, v);
|
---|
| 278 | mesh->mVertices.push_back(v);
|
---|
| 279 | }
|
---|
| 280 | mesh->AddFace(new Face(index + 0, index + 1, index + 3, index + 2) );
|
---|
| 281 | mesh->AddFace(new Face(index + 0, index + 2, index + 6, index + 4) );
|
---|
| 282 | mesh->AddFace(new Face(index + 4, index + 6, index + 7, index + 5) );
|
---|
| 283 |
|
---|
| 284 | mesh->AddFace(new Face(index + 3, index + 1, index + 5, index + 7) );
|
---|
| 285 | mesh->AddFace(new Face(index + 0, index + 4, index + 5, index + 1) );
|
---|
| 286 | mesh->AddFace(new Face(index + 2, index + 3, index + 7, index + 6) );
|
---|
| 287 |
|
---|
| 288 |
|
---|
| 289 | // set the mesh material according to the ray density
|
---|
| 290 | KdLeaf *leaf = (KdLeaf *) node;
|
---|
| 291 | if (leaf->mPassingRays.mRays) {
|
---|
| 292 | float importance = leaf->mPassingRays.mContributions/(float)leaf->mPassingRays.mRays;
|
---|
| 293 | // float importance = leaf->mPassingRays.mContributions/1000.0f;
|
---|
| 294 | // float importance = leaf->mPassingRays.mRays/1000.0f;
|
---|
| 295 | ///(float)leaf->mPassingRays.mRays;
|
---|
| 296 | // mForcedMaterial.mDiffuseColor.r = log10(leaf->mPassingRays.mRays)/3.0f;
|
---|
| 297 | mForcedMaterial.mDiffuseColor.r = importance;
|
---|
| 298 | mForcedMaterial.mDiffuseColor.g = 1.0f - mForcedMaterial.mDiffuseColor.r;
|
---|
| 299 | ExportMesh(mesh);
|
---|
| 300 | }
|
---|
| 301 | delete mesh;
|
---|
| 302 | } else {
|
---|
| 303 | KdInterior *interior = (KdInterior *)node;
|
---|
| 304 | tStack.push(interior->mFront);
|
---|
| 305 | tStack.push(interior->mBack);
|
---|
| 306 | }
|
---|
| 307 | }
|
---|
| 308 | // restore the state of forced material
|
---|
| 309 | mUseForcedMaterial = fm;
|
---|
| 310 | return true;
|
---|
| 311 | }
|
---|