[3235] | 1 | #include "VisibilitySolutionConverter.h"
|
---|
[3234] | 2 | #include "SimpleTri.h"
|
---|
| 3 | #include "SimpleVec.h"
|
---|
| 4 | #include "gzstream.h"
|
---|
| 5 | #include <iostream>
|
---|
| 6 |
|
---|
| 7 |
|
---|
| 8 | using namespace std;
|
---|
| 9 |
|
---|
[3235] | 10 | // MAGIC of all bin exports
|
---|
| 11 | #ifndef MAGIC
|
---|
| 12 | #define MAGIC 0x827923
|
---|
| 13 | #endif
|
---|
[3234] | 14 |
|
---|
[3235] | 15 | #define BVH_VERSION 2.1
|
---|
[3234] | 16 |
|
---|
[3235] | 17 |
|
---|
[3234] | 18 | static void LoadIndices(char *str,
|
---|
| 19 | const VertexArray &vertices,
|
---|
| 20 | const VertexArray &normals,
|
---|
[3235] | 21 | const vector<pair<float, float> > &texCoords,
|
---|
[3234] | 22 | VertexArray &faceVertices,
|
---|
| 23 | VertexArray &faceNormals,
|
---|
[3235] | 24 | vector<TexCoord> &faceTexCoords
|
---|
[3234] | 25 | )
|
---|
| 26 | {
|
---|
| 27 | vector<string> triples;
|
---|
| 28 |
|
---|
| 29 | char *next_token;
|
---|
| 30 |
|
---|
| 31 | // extract the triples of the form v/t/n v/t/n ...
|
---|
| 32 | char *pch = strtok_s(str + 1, " ", &next_token);
|
---|
| 33 |
|
---|
| 34 | while (pch)
|
---|
| 35 | {
|
---|
| 36 | string s(pch);
|
---|
| 37 | //s += "\n",
|
---|
| 38 | triples.push_back(s);
|
---|
| 39 |
|
---|
| 40 | pch = strtok_s(NULL, " ", &next_token);
|
---|
| 41 | }
|
---|
| 42 |
|
---|
| 43 | vector<int> indices;
|
---|
| 44 | vector<int> nIndices;
|
---|
| 45 | vector<int> tIndices;
|
---|
| 46 |
|
---|
| 47 | char seps[] = " /\t\n";
|
---|
| 48 |
|
---|
| 49 | for (size_t i = 0; i < triples.size(); ++ i)
|
---|
| 50 | {
|
---|
| 51 | static int dummy = 0;
|
---|
| 52 |
|
---|
| 53 | size_t found;
|
---|
| 54 | found = triples[i].find_first_of(seps);
|
---|
| 55 | size_t prevfound = 0;
|
---|
| 56 | // vertex, normal, texture indices
|
---|
| 57 | string str = triples[i].substr(prevfound, found);
|
---|
| 58 |
|
---|
| 59 | int index = (int)strtol(str.c_str(), NULL, 10) - 1;
|
---|
| 60 |
|
---|
| 61 | int tIndex = index;
|
---|
| 62 | int nIndex = index;
|
---|
| 63 |
|
---|
| 64 | prevfound = found;
|
---|
| 65 | found = triples[i].find_first_of(seps, found + 1);
|
---|
| 66 |
|
---|
| 67 | if (found != string::npos)
|
---|
| 68 | {
|
---|
| 69 | str = triples[i].substr(prevfound, found);
|
---|
| 70 |
|
---|
| 71 | int idx = (int)strtol(str.c_str(), NULL, 10) - 1;
|
---|
| 72 | if (idx > 0) tIndex = idx;
|
---|
| 73 | }
|
---|
| 74 |
|
---|
| 75 | if ((found + 1) < triples[i].size())
|
---|
| 76 | {
|
---|
| 77 | str = triples[i].substr(found + 1);
|
---|
| 78 |
|
---|
| 79 | int idx = (int)strtol(str.c_str(), NULL, 10) - 1;
|
---|
| 80 | if (idx > 0) nIndex = idx;
|
---|
| 81 | }
|
---|
| 82 |
|
---|
| 83 | // store indices
|
---|
| 84 | if (index >= 0)
|
---|
| 85 | {
|
---|
| 86 | indices.push_back(index);
|
---|
| 87 | nIndices.push_back(nIndex);
|
---|
| 88 | tIndices.push_back(tIndex);
|
---|
| 89 | }
|
---|
| 90 |
|
---|
| 91 | // new triangle found
|
---|
| 92 | if (indices.size() > 2)
|
---|
| 93 | {
|
---|
| 94 | // change orientation of faces?
|
---|
| 95 | #if 1
|
---|
| 96 | int idx1 = 0;
|
---|
| 97 | int idx2 = (int)indices.size() - 2;
|
---|
| 98 | int idx3 = (int)indices.size() - 1;
|
---|
| 99 | #else
|
---|
| 100 | int idx3 = 0;
|
---|
| 101 | int idx2 = (int)indices.size() - 2;
|
---|
| 102 | int idx1 = (int)indices.size() - 1;
|
---|
| 103 | #endif
|
---|
| 104 | faceVertices.push_back(vertices[indices[idx1]]);
|
---|
| 105 | faceVertices.push_back(vertices[indices[idx2]]);
|
---|
| 106 | faceVertices.push_back(vertices[indices[idx3]]);
|
---|
| 107 |
|
---|
| 108 |
|
---|
| 109 | if (!normals.empty())
|
---|
| 110 | {
|
---|
| 111 | faceNormals.push_back(normals[nIndices[idx1]]);
|
---|
| 112 | faceNormals.push_back(normals[nIndices[idx2]]);
|
---|
| 113 | faceNormals.push_back(normals[nIndices[idx3]]);
|
---|
| 114 | }
|
---|
| 115 | else
|
---|
| 116 | {
|
---|
| 117 | // no face normals? => create normals
|
---|
| 118 | const SimpleTri tri(vertices[indices[idx1]],
|
---|
| 119 | vertices[indices[idx2]],
|
---|
| 120 | vertices[indices[idx3]]);
|
---|
[3235] | 121 |
|
---|
[3234] | 122 | const SimpleVec n = tri.GetNormal();
|
---|
| 123 |
|
---|
| 124 | faceNormals.push_back(n);
|
---|
| 125 | faceNormals.push_back(n);
|
---|
| 126 | faceNormals.push_back(n);
|
---|
| 127 | }
|
---|
| 128 |
|
---|
[3235] | 129 | if (!texCoords.empty())
|
---|
[3234] | 130 | {
|
---|
[3235] | 131 | faceTexCoords.push_back(texCoords[tIndices[idx1]]);
|
---|
| 132 | faceTexCoords.push_back(texCoords[tIndices[idx2]]);
|
---|
| 133 | faceTexCoords.push_back(texCoords[tIndices[idx3]]);
|
---|
[3234] | 134 | }
|
---|
| 135 | }
|
---|
| 136 | }
|
---|
| 137 | }
|
---|
| 138 |
|
---|
| 139 |
|
---|
[3235] | 140 | VisibilitySolutionConverter::VisibilitySolutionConverter()
|
---|
[3234] | 141 | {}
|
---|
| 142 |
|
---|
| 143 |
|
---|
[3235] | 144 | VisibilitySolutionConverter::~VisibilitySolutionConverter()
|
---|
[3234] | 145 | {
|
---|
| 146 | for (size_t i = 0; i < mGeometry.size(); ++ i)
|
---|
| 147 | {
|
---|
| 148 | delete [] mGeometry[i]->mVertices;
|
---|
| 149 | delete [] mGeometry[i]->mNormals;
|
---|
[3235] | 150 | delete [] mGeometry[i]->mTexCoords;
|
---|
[3234] | 151 |
|
---|
| 152 | delete mGeometry[i];
|
---|
| 153 | }
|
---|
| 154 |
|
---|
| 155 | mGeometry.clear();
|
---|
| 156 | }
|
---|
| 157 |
|
---|
| 158 |
|
---|
[3235] | 159 | void VisibilitySolutionConverter::LoadShape(const VertexArray &vertices,
|
---|
| 160 | const VertexArray &normals,
|
---|
| 161 | const vector<TexCoord> &texCoords)
|
---|
[3234] | 162 | {
|
---|
[3235] | 163 | int numElements = (int)vertices.size();
|
---|
[3234] | 164 | Geometry *geom = new Geometry();
|
---|
| 165 |
|
---|
| 166 | // convert the triangles to geometry
|
---|
| 167 | geom->mVertices = new SimpleVec[numElements];
|
---|
| 168 | geom->mNormals = new SimpleVec[numElements];
|
---|
[3235] | 169 | geom->mTexCoords = new TexCoord[numElements];
|
---|
[3234] | 170 |
|
---|
| 171 | geom->mVertexCount = numElements;
|
---|
[3235] | 172 | geom->mTexcoordCount = (int)texCoords.size();
|
---|
[3234] | 173 |
|
---|
| 174 | cout << "number of vertices=" << numElements << endl;
|
---|
| 175 |
|
---|
| 176 | for (int i = 0; i < numElements; ++ i)
|
---|
| 177 | {
|
---|
[3235] | 178 | #if 1
|
---|
[3234] | 179 | // convert to our camera system: change y and z
|
---|
[3235] | 180 | geom->mVertices[i].x = vertices[i].x;
|
---|
| 181 | geom->mVertices[i].y = -vertices[i].z;
|
---|
| 182 | geom->mVertices[i].z = vertices[i].y;
|
---|
[3234] | 183 |
|
---|
[3235] | 184 | geom->mNormals[i].x = normals[i].x;
|
---|
| 185 | geom->mNormals[i].y = -normals[i].z;
|
---|
| 186 | geom->mNormals[i].z = normals[i].y;
|
---|
[3234] | 187 |
|
---|
| 188 | #else
|
---|
[3235] | 189 | geom->mVertices[i].x = vertices[i].x;
|
---|
| 190 | geom->mVertices[i].y = vertices[i].y;
|
---|
| 191 | geom->mVertices[i].z = vertices[i].z;
|
---|
[3234] | 192 |
|
---|
[3235] | 193 | geom->mNormals[i].x = normals[i].x;
|
---|
| 194 | geom->mNormals[i].y = normals[i].y;
|
---|
| 195 | geom->mNormals[i].z = normals[i].z;
|
---|
[3234] | 196 |
|
---|
| 197 | #endif
|
---|
| 198 |
|
---|
| 199 | if (i < geom->mTexcoordCount)
|
---|
| 200 | {
|
---|
[3235] | 201 | geom->mTexCoords[i].first = texCoords[i].first;
|
---|
| 202 | geom->mTexCoords[i].second = texCoords[i].second;
|
---|
[3234] | 203 | }
|
---|
| 204 | }
|
---|
| 205 |
|
---|
| 206 | mGeometry.push_back(geom);
|
---|
| 207 | }
|
---|
| 208 |
|
---|
| 209 |
|
---|
[3235] | 210 | bool VisibilitySolutionConverter::Convert(const std::string &sceneInputFilename,
|
---|
| 211 | const std::string &sceneOutputFilename,
|
---|
| 212 | const std::string &bvhInputFilename,
|
---|
| 213 | const std::string &bvhOutputFilename)
|
---|
[3234] | 214 | {
|
---|
| 215 | mNumShapes = 0;
|
---|
| 216 |
|
---|
[3235] | 217 | // delete previous geometry
|
---|
[3234] | 218 | for (size_t i = 0; i < mGeometry.size(); ++ i)
|
---|
| 219 | {
|
---|
| 220 | delete [] mGeometry[i]->mVertices;
|
---|
| 221 | delete [] mGeometry[i]->mNormals;
|
---|
[3235] | 222 | delete [] mGeometry[i]->mTexCoords;
|
---|
[3234] | 223 |
|
---|
| 224 | delete mGeometry[i];
|
---|
| 225 | }
|
---|
| 226 |
|
---|
| 227 | mGeometry.clear();
|
---|
| 228 |
|
---|
[3235] | 229 | if (!LoadSolution(bvhInputFilename))
|
---|
[3234] | 230 | {
|
---|
| 231 | cerr << "could not read file" << endl;
|
---|
| 232 | return false;
|
---|
| 233 | }
|
---|
| 234 |
|
---|
[3235] | 235 | if (!ReadScene(sceneInputFilename))
|
---|
[3234] | 236 | {
|
---|
[3235] | 237 | cerr << "could not read file" << endl;
|
---|
| 238 | return false;
|
---|
| 239 | }
|
---|
| 240 |
|
---|
| 241 | if (!WriteScene(sceneOutputFilename))
|
---|
| 242 | {
|
---|
[3234] | 243 | cerr << "could not write file" << endl;
|
---|
| 244 | return false;
|
---|
| 245 | }
|
---|
| 246 |
|
---|
[3235] | 247 | /*if (!WriteBvh(bvhOutputFilename))
|
---|
| 248 | {
|
---|
| 249 | cerr << "could not write file" << endl;
|
---|
| 250 | return false;
|
---|
| 251 | }*/
|
---|
[3234] | 252 |
|
---|
| 253 | return true;
|
---|
| 254 | }
|
---|
| 255 |
|
---|
| 256 |
|
---|
[3235] | 257 | bool VisibilitySolutionConverter::ReadScene(const string &filename)
|
---|
[3234] | 258 | {
|
---|
| 259 | FILE *file;
|
---|
| 260 |
|
---|
| 261 | if ((file = fopen(filename.c_str(), "r")) == NULL)
|
---|
| 262 | {
|
---|
| 263 | return false;
|
---|
| 264 | }
|
---|
| 265 |
|
---|
| 266 | VertexArray faceVertices;
|
---|
| 267 | VertexArray faceNormals;
|
---|
[3235] | 268 | vector<TexCoord> faceTexcoords;
|
---|
[3234] | 269 |
|
---|
| 270 | VertexArray vertices;
|
---|
| 271 | VertexArray normals;
|
---|
[3235] | 272 | vector<TexCoord> texcoords;
|
---|
[3234] | 273 |
|
---|
| 274 | vector<int> indices;
|
---|
| 275 |
|
---|
| 276 | int line = 0;
|
---|
| 277 | const int len = 10000;
|
---|
| 278 | char str[len];
|
---|
| 279 |
|
---|
| 280 | while (fgets(str, len, file) != NULL)
|
---|
| 281 | {
|
---|
[3235] | 282 | if (line % 1000000 == 0)
|
---|
| 283 | cout << line << " " << str << endl;
|
---|
| 284 |
|
---|
| 285 | ++ line;
|
---|
| 286 |
|
---|
[3234] | 287 | switch (str[0])
|
---|
| 288 | {
|
---|
| 289 | case 'v': // vertex or normal
|
---|
| 290 | {
|
---|
| 291 | float x, y, z;
|
---|
| 292 |
|
---|
[3235] | 293 | if (vertices.size() >= 1000000 * 3) continue;
|
---|
| 294 |
|
---|
[3234] | 295 | switch (str[1])
|
---|
| 296 | {
|
---|
| 297 | case 'n' :
|
---|
| 298 | sscanf(str + 2, "%f %f %f", &x, &y, &z);
|
---|
| 299 | normals.push_back(SimpleVec(x, y, z));
|
---|
| 300 | break;
|
---|
| 301 | case 't':
|
---|
| 302 | sscanf(str + 2, "%f %f", &x, &y);
|
---|
| 303 | texcoords.push_back(pair<float, float>(x, y));
|
---|
| 304 | break;
|
---|
| 305 | default:
|
---|
| 306 | sscanf(str + 1, "%f %f %f", &x, &y, &z);
|
---|
| 307 | //const float scale = 5e-3f;
|
---|
[3235] | 308 | const float scale = 0.1f;
|
---|
| 309 | vertices.push_back(SimpleVec(x * scale, y * scale, z * scale));
|
---|
[3234] | 310 | //cout <<"v " << x << " " << y << " "<< z << " ";
|
---|
| 311 | }
|
---|
| 312 | break;
|
---|
| 313 | }
|
---|
| 314 | case 'f':
|
---|
| 315 | {
|
---|
| 316 | //////////
|
---|
| 317 | //-- indices in the current line
|
---|
| 318 |
|
---|
[3235] | 319 | if (faceVertices.size() >= 1000000 * 3) continue;
|
---|
| 320 |
|
---|
[3234] | 321 | LoadIndices(str,
|
---|
| 322 | vertices, normals, texcoords,
|
---|
| 323 | faceVertices, faceNormals, faceTexcoords);
|
---|
| 324 |
|
---|
| 325 | break;
|
---|
[3235] | 326 | }
|
---|
[3234] | 327 | break;
|
---|
| 328 | default:
|
---|
| 329 | // throw away line
|
---|
| 330 | break;
|
---|
| 331 | }
|
---|
| 332 | }
|
---|
| 333 |
|
---|
| 334 | if (!faceVertices.empty())
|
---|
| 335 | {
|
---|
| 336 | ++ mNumShapes;
|
---|
| 337 |
|
---|
[3235] | 338 | ConstructBvhObjects(faceVertices, faceNormals, faceTexcoords);
|
---|
[3234] | 339 |
|
---|
| 340 | faceVertices.clear();
|
---|
| 341 | faceNormals.clear();
|
---|
| 342 | faceTexcoords.clear();
|
---|
| 343 | }
|
---|
| 344 |
|
---|
| 345 | fclose(file);
|
---|
| 346 |
|
---|
| 347 | return true;
|
---|
| 348 | }
|
---|
| 349 |
|
---|
| 350 |
|
---|
[3235] | 351 | static inline float RandomColor(float x)
|
---|
[3234] | 352 | {
|
---|
[3235] | 353 | return x + (1.0f - x) * (float)rand() / RAND_MAX;
|
---|
| 354 | }
|
---|
| 355 |
|
---|
| 356 |
|
---|
| 357 | void VisibilitySolutionConverter::WriteGeometry(ogzstream &str, Geometry *geom)
|
---|
| 358 | {
|
---|
[3234] | 359 | int vertexCount = geom->mVertexCount;
|
---|
| 360 | str.write(reinterpret_cast<char *>(&vertexCount), sizeof(int));
|
---|
| 361 |
|
---|
| 362 | str.write(reinterpret_cast<char *>(geom->mVertices), sizeof(SimpleVec) * vertexCount);
|
---|
| 363 | str.write(reinterpret_cast<char *>(geom->mNormals), sizeof(SimpleVec) * vertexCount);
|
---|
| 364 |
|
---|
[3236] | 365 | int texCoordCount = 0;//geom->mTexcoordCount;
|
---|
[3234] | 366 | str.write(reinterpret_cast<char *>(&texCoordCount), sizeof(int));
|
---|
| 367 |
|
---|
| 368 | if (texCoordCount)
|
---|
[3235] | 369 | {
|
---|
| 370 | str.write(reinterpret_cast<char *>(geom->mTexCoords), sizeof(float) * texCoordCount * 2);
|
---|
| 371 | }
|
---|
[3234] | 372 |
|
---|
| 373 | ///////
|
---|
| 374 | //-- texture
|
---|
| 375 |
|
---|
| 376 | int texId = -1;
|
---|
| 377 | str.write(reinterpret_cast<char *>(&texId), sizeof(int));
|
---|
| 378 |
|
---|
| 379 | bool alphaTestEnabled = false;
|
---|
| 380 | bool cullFaceEnabled = true;
|
---|
| 381 |
|
---|
| 382 | str.write(reinterpret_cast<char *>(&alphaTestEnabled), sizeof(bool));
|
---|
| 383 | str.write(reinterpret_cast<char *>(&cullFaceEnabled), sizeof(bool));
|
---|
| 384 |
|
---|
| 385 | // material
|
---|
| 386 | bool hasMaterial = true;
|
---|
[3236] | 387 |
|
---|
[3234] | 388 | str.write(reinterpret_cast<char *>(&hasMaterial), sizeof(bool));
|
---|
| 389 |
|
---|
| 390 | if (hasMaterial)
|
---|
| 391 | {
|
---|
| 392 | SimpleVec ambient, diffuse, spec, emm;
|
---|
| 393 |
|
---|
| 394 | ambient.x = ambient.y = ambient.z = 0.2f;
|
---|
| 395 | //diffuse.x = diffuse.y = diffuse.z = 1.0f;
|
---|
[3235] | 396 |
|
---|
| 397 | diffuse.x = RandomColor(0.5f);
|
---|
| 398 | diffuse.y = RandomColor(0.5f);
|
---|
| 399 | diffuse.z = RandomColor(0.5f);
|
---|
| 400 |
|
---|
[3234] | 401 | spec.x = spec.y = spec.z = .0f;
|
---|
| 402 | emm = spec;
|
---|
| 403 |
|
---|
| 404 | // only write rgb part of the material
|
---|
| 405 | str.write(reinterpret_cast<char *>(&ambient), sizeof(SimpleVec));
|
---|
| 406 | str.write(reinterpret_cast<char *>(&diffuse), sizeof(SimpleVec));
|
---|
| 407 | str.write(reinterpret_cast<char *>(&spec), sizeof(SimpleVec));
|
---|
| 408 | str.write(reinterpret_cast<char *>(&emm), sizeof(SimpleVec));
|
---|
| 409 | }
|
---|
| 410 | }
|
---|
| 411 |
|
---|
| 412 |
|
---|
[3235] | 413 | bool VisibilitySolutionConverter::WriteScene(const string &filename)
|
---|
[3234] | 414 | {
|
---|
| 415 | ogzstream ofile(filename.c_str());
|
---|
| 416 |
|
---|
| 417 | if (!ofile.is_open())
|
---|
| 418 | return false;
|
---|
| 419 |
|
---|
| 420 |
|
---|
| 421 | int textureCount = 0;
|
---|
| 422 | ofile.write(reinterpret_cast<char *>(&textureCount), sizeof(int));
|
---|
| 423 |
|
---|
| 424 |
|
---|
| 425 | ///////////
|
---|
| 426 | //-- write shapes
|
---|
| 427 |
|
---|
[3236] | 428 | int numShapes = (int)mGeometry.size();
|
---|
| 429 | ofile.write(reinterpret_cast<char *>(&numShapes), sizeof(int));
|
---|
[3234] | 430 |
|
---|
| 431 | vector<Geometry *>::const_iterator it, it_end = mGeometry.end();
|
---|
| 432 |
|
---|
| 433 | for (it = mGeometry.begin(); it != it_end; ++ it)
|
---|
| 434 | {
|
---|
| 435 | WriteGeometry(ofile, *it);
|
---|
| 436 | }
|
---|
| 437 |
|
---|
| 438 |
|
---|
[3236] | 439 | int entityCount = numShapes;
|
---|
[3234] | 440 | ofile.write(reinterpret_cast<char *>(&entityCount), sizeof(int));
|
---|
| 441 |
|
---|
| 442 |
|
---|
| 443 | //////////
|
---|
[3236] | 444 | //-- write single scene entity for each shape
|
---|
[3234] | 445 |
|
---|
[3236] | 446 | // all shapes belong to this scene entity
|
---|
| 447 | for (int i = 0; i < numShapes; ++ i)
|
---|
| 448 | {
|
---|
| 449 | // no transformation
|
---|
| 450 | bool hasTrafo = false;
|
---|
| 451 | ofile.write(reinterpret_cast<char *>(&hasTrafo), sizeof(bool));
|
---|
[3234] | 452 |
|
---|
[3236] | 453 | // a dummy lod
|
---|
| 454 | int numLODs = 1;
|
---|
| 455 | ofile.write(reinterpret_cast<char *>(&numLODs), sizeof(int));
|
---|
[3234] | 456 |
|
---|
[3236] | 457 | float dist = 0;
|
---|
| 458 | ofile.write(reinterpret_cast<char *>(&dist), sizeof(float));
|
---|
[3234] | 459 |
|
---|
[3236] | 460 | int shapesPerEnt = 1;
|
---|
| 461 | ofile.write(reinterpret_cast<char *>(&shapesPerEnt), sizeof(int));
|
---|
[3234] | 462 |
|
---|
| 463 | int shapeId = i;
|
---|
| 464 | ofile.write(reinterpret_cast<char *>(&shapeId), sizeof(int));
|
---|
| 465 | }
|
---|
| 466 |
|
---|
| 467 | return true;
|
---|
[3235] | 468 | }
|
---|
| 469 |
|
---|
| 470 |
|
---|
| 471 | void VisibilitySolutionConverter::ConstructBvhObjects(const VertexArray &vertices,
|
---|
| 472 | const VertexArray &normals,
|
---|
| 473 | const vector<TexCoord> &texCoords)
|
---|
| 474 | {
|
---|
| 475 | cout << "vtx: " << vertices.size() << endl;
|
---|
| 476 |
|
---|
| 477 | for (size_t i = 0; i < mBvhNodes.size(); ++ i)
|
---|
| 478 | {
|
---|
| 479 | VertexArray _vertices;
|
---|
| 480 | VertexArray _normals;
|
---|
| 481 | vector<TexCoord> _texCoords;
|
---|
| 482 |
|
---|
| 483 | BvhNode *node = mBvhNodes[i];
|
---|
| 484 |
|
---|
| 485 | //for (size_t j = 0; j < node->mTriangleIds.size(); ++ j)
|
---|
| 486 | for (int j = node->first; j < node->last; ++ j)
|
---|
| 487 | {
|
---|
| 488 | const int idx = 3 * mGlobalTriangleIds[j];
|
---|
| 489 |
|
---|
| 490 | //cout << "idx: " << idx << " ";
|
---|
| 491 |
|
---|
| 492 | if (idx < 1000000 * 3)
|
---|
| 493 | {
|
---|
| 494 | for (int k = 0; k < 3; ++ k)
|
---|
| 495 | {
|
---|
| 496 | _vertices.push_back(vertices[idx + k]);
|
---|
| 497 | _normals.push_back(normals[idx + k]);
|
---|
| 498 | //_texCoords.push_back(texCoords[idx + k]);
|
---|
| 499 | }
|
---|
| 500 | }
|
---|
| 501 | }
|
---|
| 502 |
|
---|
[3236] | 503 | if (!_vertices.empty())
|
---|
| 504 | {
|
---|
| 505 | ++ mNumShapes;
|
---|
| 506 | LoadShape(_vertices, _normals, _texCoords);
|
---|
| 507 | }
|
---|
[3235] | 508 | }
|
---|
| 509 | }
|
---|
| 510 |
|
---|
| 511 |
|
---|
| 512 | bool VisibilitySolutionConverter::WriteBvh(const string &filename)
|
---|
| 513 | {
|
---|
| 514 |
|
---|
| 515 | return true;
|
---|
| 516 | }
|
---|
| 517 |
|
---|
| 518 |
|
---|
| 519 | bool VisibilitySolutionConverter::ReadBvh(FILE *fr)
|
---|
| 520 | {
|
---|
| 521 | int buffer[6];
|
---|
| 522 | fread(buffer, sizeof(int), 6, fr);
|
---|
| 523 |
|
---|
| 524 | if (buffer[0] != MAGIC)
|
---|
| 525 | {
|
---|
| 526 | cerr << "Error: Wrong file type" << endl;
|
---|
| 527 | return false;
|
---|
| 528 | }
|
---|
| 529 |
|
---|
| 530 | if (buffer[1] != (int)(1000 * BVH_VERSION))
|
---|
| 531 | {
|
---|
| 532 | cerr << "Error: Wrong BVH version" << endl;
|
---|
| 533 | return false;
|
---|
| 534 | }
|
---|
| 535 |
|
---|
| 536 | // load triangle ids
|
---|
| 537 | size_t numTriangles = buffer[2];
|
---|
| 538 |
|
---|
| 539 | for (size_t i = 0; i < numTriangles; ++i)
|
---|
| 540 | {
|
---|
| 541 | int id;
|
---|
| 542 | fread(&id, sizeof(int), 1, fr);
|
---|
[3236] | 543 | mGlobalTriangleIds.push_back(id);
|
---|
[3235] | 544 | //triangles[i] = scene->triangles[id];
|
---|
| 545 | }
|
---|
| 546 |
|
---|
| 547 | //if (mRoot) delete mRoot;
|
---|
| 548 |
|
---|
| 549 | mNumNodes = 0; // this was set to 1 in constructor!
|
---|
| 550 |
|
---|
| 551 | mRoot = LoadNode(fr, 0);
|
---|
| 552 |
|
---|
| 553 | if (mNumNodes != buffer[5])
|
---|
| 554 | {
|
---|
| 555 | cerr << "Warning: Loaded " << mNumNodes <<
|
---|
| 556 | " bvh nodes instead of " << buffer[5] << endl;
|
---|
| 557 | }
|
---|
| 558 |
|
---|
| 559 | fclose(fr);
|
---|
| 560 |
|
---|
| 561 | return true;
|
---|
| 562 | }
|
---|
| 563 |
|
---|
| 564 |
|
---|
| 565 | BvhNode *VisibilitySolutionConverter::LoadNode(FILE *fr, int depth)
|
---|
| 566 | {
|
---|
| 567 | ++ mNumNodes;
|
---|
| 568 |
|
---|
| 569 | int buffer[4];
|
---|
| 570 | fread(buffer, sizeof(int), 4, fr);
|
---|
| 571 |
|
---|
| 572 | if (buffer[2] != -1)
|
---|
| 573 | {
|
---|
| 574 | BvhInterior *interior = new BvhInterior();
|
---|
| 575 |
|
---|
| 576 | interior->first = buffer[0];
|
---|
| 577 | interior->last = buffer[1];
|
---|
| 578 | interior->axis = buffer[2];
|
---|
| 579 | interior->id = buffer[3];
|
---|
| 580 | interior->depth = depth;
|
---|
| 581 |
|
---|
| 582 | BvhNode *front, *back;
|
---|
| 583 |
|
---|
| 584 | front = LoadNode(fr, depth + 1);
|
---|
| 585 | back = LoadNode(fr, depth + 1);
|
---|
| 586 |
|
---|
| 587 | // front->parent = (BvhNode *)interior;
|
---|
| 588 | // back->parent = (BvhNode *)interior;
|
---|
| 589 | interior->front = front;
|
---|
| 590 | interior->back = back;
|
---|
| 591 |
|
---|
| 592 | //interior->box = Union(front->box, back->box);
|
---|
| 593 |
|
---|
| 594 | return (BvhNode *)interior;
|
---|
| 595 | }
|
---|
| 596 | else
|
---|
| 597 | {
|
---|
| 598 | // leaf
|
---|
| 599 | //Debug << "Info: Loading leaf (id: " << numberOfNodes << ", depth: " << depth << ")" << endl;
|
---|
| 600 | BvhLeaf *leaf = new BvhLeaf();
|
---|
| 601 | leaf->first = buffer[0];
|
---|
| 602 | leaf->last = buffer[1];
|
---|
| 603 | leaf->axis = buffer[2];
|
---|
| 604 | leaf->id = buffer[3];
|
---|
| 605 |
|
---|
| 606 | leaf->depth = depth;
|
---|
| 607 | //UpdateLeafBox(leaf);
|
---|
| 608 |
|
---|
| 609 | mBvhNodes.push_back(leaf);
|
---|
| 610 | // leaf->id = numberOfNodes;
|
---|
| 611 | return (BvhNode *)leaf;
|
---|
| 612 | }
|
---|
| 613 | }
|
---|
| 614 |
|
---|
| 615 |
|
---|
| 616 | bool VisibilitySolutionConverter::ReadDummyTree(FILE *fr)
|
---|
| 617 | {
|
---|
| 618 | int buffer[256];
|
---|
| 619 | fread(buffer, sizeof(int), 3, fr);
|
---|
| 620 |
|
---|
| 621 | // read dummy bounding box
|
---|
| 622 | float dummy[6];
|
---|
| 623 | fread(dummy, sizeof(float) * 6, 1, fr);
|
---|
| 624 |
|
---|
| 625 | int stack = 1;
|
---|
| 626 |
|
---|
| 627 | // read dummy tree
|
---|
| 628 | while (stack)
|
---|
| 629 | {
|
---|
| 630 | int axis;
|
---|
| 631 | fread(&axis, sizeof(int), 1, fr);
|
---|
| 632 | -- stack;
|
---|
| 633 |
|
---|
| 634 | if (axis != - 1)
|
---|
| 635 | {
|
---|
| 636 | float dummy;
|
---|
| 637 | fread(&dummy, sizeof(float), 1, fr);
|
---|
| 638 |
|
---|
| 639 | stack += 2;
|
---|
| 640 | }
|
---|
| 641 | }
|
---|
| 642 |
|
---|
| 643 | return true;
|
---|
| 644 | }
|
---|
| 645 |
|
---|
| 646 |
|
---|
| 647 |
|
---|
| 648 | bool VisibilitySolutionConverter::LoadSolution(const string &filename)
|
---|
| 649 | {
|
---|
| 650 | FILE *fr = fopen(filename.c_str(), "rb");
|
---|
| 651 |
|
---|
| 652 | cerr << "Info: Loading visibility solution from file '" + filename + "'" << endl;
|
---|
| 653 |
|
---|
| 654 | if (fr == NULL)
|
---|
| 655 | {
|
---|
| 656 | cerr << "Error: Cannot open file for reading" << endl;
|
---|
| 657 | return false;
|
---|
| 658 | }
|
---|
| 659 |
|
---|
| 660 | float totalSamples, totalTime;
|
---|
| 661 |
|
---|
| 662 | fread(&totalSamples, sizeof(float), 1, fr);
|
---|
| 663 | fread(&totalTime, sizeof(float), 1, fr);
|
---|
| 664 |
|
---|
| 665 | //viewCellsTree = new ViewCellsTree;
|
---|
| 666 | //bool ok = viewCellsTree->_LoadFromFile(fr);
|
---|
| 667 |
|
---|
| 668 | bool ok = ReadDummyTree(fr);
|
---|
| 669 |
|
---|
| 670 | if (ok)
|
---|
| 671 | {
|
---|
| 672 | //AllocateLeafViewCells();
|
---|
| 673 |
|
---|
| 674 | //objectsTree = new Bvh(*scene);
|
---|
| 675 | //ok = objectsTree->_LoadFromFile(fr);
|
---|
| 676 | ok = ReadBvh(fr);
|
---|
| 677 |
|
---|
| 678 | /*if (ok)
|
---|
| 679 | {
|
---|
| 680 | AllocatePvsObjects();
|
---|
| 681 | ok = LoadPvs(fr);
|
---|
| 682 | }
|
---|
| 683 | */
|
---|
| 684 | }
|
---|
| 685 |
|
---|
| 686 | fclose(fr);
|
---|
| 687 |
|
---|
| 688 | if (ok)
|
---|
| 689 | cout << "Info: visibility solution loaded" << endl;
|
---|
| 690 | else
|
---|
| 691 | cout << "Info: loading visibility solution failed" << endl;
|
---|
| 692 |
|
---|
| 693 | return true;
|
---|
| 694 | }
|
---|
| 695 |
|
---|
| 696 |
|
---|
| 697 | #if 0
|
---|
| 698 | bool VisibilitySolution::LoadPvs(FILE *fw)
|
---|
| 699 | {
|
---|
| 700 | int number, entries;
|
---|
| 701 |
|
---|
| 702 | fread(&number, sizeof(int), 1, fw);
|
---|
| 703 |
|
---|
| 704 | if (number == 0)
|
---|
| 705 | {
|
---|
| 706 | Message("Info: Warning empty PVSs in visibility solution");
|
---|
| 707 | return true;
|
---|
| 708 | }
|
---|
| 709 |
|
---|
| 710 | if (number != viewCells.size())
|
---|
| 711 | {
|
---|
| 712 | Message("Info: Number of view cells does not match when loading PVSs!");
|
---|
| 713 | return false;
|
---|
| 714 | }
|
---|
| 715 |
|
---|
| 716 | for (int i=0; i < number; i++)
|
---|
| 717 | {
|
---|
| 718 | fread(&entries, sizeof(int), 1, fw);
|
---|
| 719 |
|
---|
| 720 | for (int j=0; j < entries; j++)
|
---|
| 721 | {
|
---|
| 722 | int objectId;
|
---|
| 723 | float time;
|
---|
| 724 | fread(&objectId, sizeof(int), 1, fw);
|
---|
| 725 | fread(&time, sizeof(float), 1, fw);
|
---|
| 726 | viewCells[i]->pvs.Insert(objectId, time);
|
---|
| 727 | }
|
---|
| 728 | }
|
---|
| 729 | return true;
|
---|
| 730 | }
|
---|
| 731 |
|
---|
| 732 |
|
---|
| 733 | bool ViewCellsTree::_LoadFromFile(FILE *fr)
|
---|
| 734 | {
|
---|
| 735 | int buffer[256];
|
---|
| 736 | fread(buffer, sizeof(int), 3, fr);
|
---|
| 737 |
|
---|
| 738 | if (buffer[0] != MAGIC)
|
---|
| 739 | {
|
---|
| 740 | Message( "Error: Wrong file type");
|
---|
| 741 | return false;
|
---|
| 742 | }
|
---|
| 743 |
|
---|
| 744 | if (buffer[1] != (int)(1000*VIEWCELLS_VERSION))
|
---|
| 745 | {
|
---|
| 746 | Message( "Error: Wrong viewcells version" );
|
---|
| 747 |
|
---|
| 748 | return false;
|
---|
| 749 | }
|
---|
| 750 |
|
---|
| 751 | // get the bounding box
|
---|
| 752 | fread(&box, sizeof(AxisAlignedBox3), 1, fr);
|
---|
| 753 |
|
---|
| 754 | stack<ViewCellsTreeNode **> nodeStack;
|
---|
| 755 | nodeStack.push(&root);
|
---|
| 756 |
|
---|
| 757 | while(!nodeStack.empty())
|
---|
| 758 | {
|
---|
| 759 | ViewCellsTreeNode *&node = *nodeStack.top();
|
---|
| 760 |
|
---|
| 761 | nodeStack.pop();
|
---|
| 762 | node = new ViewCellsTreeNode;
|
---|
| 763 |
|
---|
| 764 | fread(&node->axis, sizeof(int), 1, fr);
|
---|
| 765 |
|
---|
| 766 | if (!node->IsLeaf())
|
---|
| 767 | {
|
---|
| 768 | fread(&node->position, sizeof(float), 1, fr);
|
---|
| 769 |
|
---|
| 770 | nodeStack.push(&node->front);
|
---|
| 771 | nodeStack.push(&node->back);
|
---|
| 772 | }
|
---|
| 773 | }
|
---|
| 774 |
|
---|
| 775 | return true;
|
---|
| 776 | }
|
---|
| 777 | #endif |
---|