void shMapLevel::darkRoom (int sx, int sy, int ex, int ey) { for (int x = sx; x <= ex; ++x) { for (int y = sy; y <= ey; ++y) { setLit (x, y, x > sx and y > sy ? -1 : 0, //NW x < ex and y > sy ? -1 : 0, //NE x > sx and y < ey ? -1 : 0, //SW x < ex and y < ey ? -1 : 0); //SE } } /* Chances are someone broke/stole/ate the lightbulb. -- MB */ if (!RNG (4)) { mSquares[(sx+ex)/2][(sy+ey)/2].mTerr = kBrokenLightAbove; } }
void Entity::loadBillboard(char *filename, f32 w, f32 h) { ISceneNode *billboard; if(type == LIGHT_TYPE) { billboard = Scene->addBillboardSceneNode(lightNode, dimension2d<f32>(w,h)); billboard->setMaterialFlag(EMF_LIGHTING, false); billboard->setMaterialType(video::EMT_TRANSPARENT_ADD_COLOR); billboard->setMaterialTexture(0, Video->getTexture(filename)); } else if(type == MESH_TYPE) { sceneNode = Scene->addBillboardSceneNode(0, dimension2d<f32>(w,h)); sceneNode->setMaterialType(video::EMT_TRANSPARENT_ADD_COLOR); sceneNode->setMaterialTexture(0, Video->getTexture(filename)); setLit(false); } else return; }
int shMapLevel::buildBunkerRooms () { #define MSX 10 #define MSY 4 #define MAXROOMS 20 /* macro sq 5x6 cells of regular squares */ int macrosq[MSX][MSY]; int x, y; int i, n; int retry; int firstroom; struct { int sx, sy, ex, ey; /* macro dimensions */ int rsx, rsy, rex, rey; /* real dimensions */ int mark; } rooms[MAXROOMS]; char connect [MAXROOMS][MAXROOMS]; int maxcorridorlength = 3; mMapType = kBunkerRooms; // I->debug ("building bunker rooms"); n = 7 + RNG (3) + RNG (3); // n = 5; for (x = 0; x < MSX; x++) for (y = 0; y < MSY; y++) macrosq[x][y] = -1; for (x = 0; x < MAXROOMS; x++) for (y = 0; y < MAXROOMS; y++) connect[x][y] = 0; firstroom = 0; /* first step: determine the macro dimensions of the rooms */ reloop: retry = 0; for (i = firstroom; i < n; ++i) { rooms[i].mark = 0; retry: if (++retry > 100) { n = i; break; } x = RNG (MSX); if (RNG (2)) { /* a wide room */ y = RNG (MSY); if (-1 == macrosq[x][y] and x < MSX - 1 and -1 == macrosq[x+1][y]) { if (RNG(3) and y > 0 and (-1 != macrosq[x][y-1] or -1 != macrosq[x+1][y-1])) { goto retry; } if (RNG(2) and y < MSY - 1 and (-1 != macrosq[x][y+1] or -1 != macrosq[x+1][y+1])) { goto retry; } macrosq[x][y] = i; macrosq[x+1][y] = i; rooms[i].sx = x; rooms[i].sy = y; if (RNG(4) and x < MSX - 2 and -1 == macrosq[x+2][y]) { macrosq[x+2][y] = i; rooms[i].ex = x+2; } else { rooms[i].ex = x+1; if (y < MSY - 1 and -1 == macrosq[x][y+1] and -1 == macrosq[x+1][y+1]) { macrosq[x][y+1] = i; macrosq[x+1][y+1] = i; rooms[i].ey = y + 1; } } rooms[i].ey = y; } else { goto retry; } } else { /* a tall room */ y = RNG (MSY-1); if (-1 == macrosq[x][y] and -1 == macrosq[x][y+1]) { macrosq[x][y] = i; macrosq[x][y+1] = i; rooms[i].sx = x; rooms[i].sy = y; rooms[i].ey = y+1; rooms[i].ex = x; if (RNG (4) and x < MSX - 1 and -1 == macrosq[x+1][y] and -1 == macrosq[x+1][y+1]) { macrosq[x+1][y] = i; macrosq[x+1][y+1] = i; rooms[i].ex = x+1; } if (RNG (4) and x > 0 and -1 == macrosq[x-1][y] and -1 == macrosq[x-1][y+1]) { macrosq[x-1][y] = i; macrosq[x-1][y+1] = i; rooms[i].sx = x-1; } } else { goto retry; } } } /* deterimine real dimensions, and actually make the rooms: */ for (i = firstroom; i < n; i++) { int w, h; w = 6 * (rooms[i].ex - rooms[i].sx); if (w > 0) w -= 2; w = 5 + RNG (2) + RNG (w / 2, w); x = (RNG (1 + 6 * (1 + rooms[i].ex - rooms[i].sx) - w) + RNG (1 + 6 * (1 + rooms[i].ex - rooms[i].sx) - w)) / 2; if (rooms[i].sy != rooms[i].ey) { h = 5 + RNG (5); y = RNG (1 + 5 * (1 + rooms[i].ey - rooms[i].sy) - h); } else { h = RNG (5) ? 5 : 4; y = RNG (1 + 5 - h); } rooms[i].rsx = rooms[i].sx * 6 + x; rooms[i].rex = rooms[i].rsx + w - 1; rooms[i].rsy = rooms[i].sy * 5 + y; rooms[i].rey = rooms[i].rsy + h - 1; layRoom (rooms[i].rsx, rooms[i].rsy, rooms[i].rex, rooms[i].rey); } /* connect the rooms with corridors */ corridor: for (i = 0; i < n; i++) { int j; int cnt; int dir[4]; dir[0] = kNorth; dir[1] = kEast; dir[2] = kWest; dir[3] = kSouth; shuffle (dir, 4, sizeof (int)); for (j = 0; j < 4; j++) { int sx, sy, ex, ey; x = RNG (rooms[i].sx, rooms[i].ex); y = RNG (rooms[i].sy, rooms[i].ey); sx = x; sy = y; assert (x >= 0 and y >= 0); for (cnt = maxcorridorlength; cnt; --cnt) { int room; moveForward ((shDirection) dir[j], &x, &y); if (x < 0 or x >= MSX or y < 0 or y >= MSY) { break; } room = macrosq[x][y]; if (i == room) { sx = x; sy = y; continue; } else if (-2 == room) { /* we hit another corridor */ break; } else if (-1 != room) { /* we hit another room */ if (connect[i][room]) { /* but there's already a connecting corridor*/ break; } if (isHorizontal ((shDirection) dir[j])) { int lo, hi; lo = maxi (y * 5, 1 + maxi(rooms[room].rsy, rooms[i].rsy)); hi = mini (y * 5 + 4, mini(rooms[room].rey, rooms[i].rey) - 1); if (lo > hi) { break; } ex = maxi (x, sx); sx = mini (x, sx); for (x = sx + 1; x < ex; x++) { macrosq[x][y] = -2; } sx = mini (rooms[room].rex, rooms[i].rex); ex = maxi (rooms[room].rsx, rooms[i].rsx); /* I->debug ("y %d (%d, %d) (%d, %d)", y, rooms[room].rsy, rooms[room].rey, rooms[i].rsy, rooms[i].rey); */ y = RNG (lo, hi); /* Test for neighboring corridors or rooms. */ for (x = sx + 1; x <= ex - 1; ++x) { if (GETSQ (x, y) != kStone) break; } if (x != ex) break; int dark = RNG (mDLevel + 6) > 7; for (x = sx; x <= ex; x++) { SETSQ (x, y, kFloor); SETSQFLAG (x, y, kHallway); if (kStone == GETSQ (x, y - 1)) SETSQ (x, y - 1, kHWall); if (kStone == GETSQ (x, y + 1)) SETSQ (x, y + 1, kHWall); if (dark) { //NW NE SW SE setLit (x, y, x > sx ? -1 : 0, x < ex ? -1 : 0, x > sx ? -1 : 0, x < ex ? -1 : 0); setLit (x, y - 1, 0, 0, x > sx ? -1 : 0, x < ex ? -1 : 0); setLit (x, y + 1, x > sx ? -1 : 0, x < ex ? -1 : 0, 0, 0); } } addDoor (sx, y, 0); addDoor (ex, y, 0); } else { /* vertical */ if (rooms[room].rsx + 1 > rooms[i].rex - 1 or rooms[room].rex - 1 < rooms[i].rsx + 1) { break; } ey = maxi (y, sy); sy = mini (y, sy); for (y = sy + 1; y < ey; y++) { macrosq[x][y] = -2; } sy = mini (rooms[room].rey, rooms[i].rey); ey = maxi (rooms[room].rsy, rooms[i].rsy); x = RNG (1 + maxi(rooms[room].rsx, rooms[i].rsx), mini(rooms[room].rex, rooms[i].rex) - 1); /* Test for neighboring corridors or rooms. */ for (y = sy + 1; y <= ey - 1; ++y) { if (GETSQ (x, y) != kStone) break; } if (y != ey) break; int dark = RNG (mDLevel + 6) > 7; for (y = sy; y <= ey; y++) { SETSQ (x, y, kFloor); SETSQFLAG (x, y, kHallway); if (kStone == GETSQ (x - 1, y)) SETSQ (x - 1, y, kVWall); if (kStone == GETSQ (x + 1, y)) SETSQ (x + 1, y, kVWall); if (dark) { setLit (x, y, y > sy ? -1 : 0, y > sy ? -1 : 0, y < ey ? -1 : 0, y < ey ? -1 : 0); setLit (x - 1, y, 0, y > sy ? -1 : 0, 0, y < ey ? -1 : 0); setLit (x + 1, y, y > sy ? -1 : 0, 0, y < ey ? -1 : 0, 0); } } addDoor (x, sy, 1); addDoor (x, ey, 1); } j += RNG (3); connect[i][room] = 1; connect[room][i] = 1; break; } } } } /* The final check: are the rooms connected? Do a breadth first search, marking all the rooms reachable from room 0 */ { int j; int k; int bfs[MAXROOMS]; for (i = 0; i < n; ++i) { bfs[i] = -1; rooms[i].mark = 0; } k = 1; bfs[0] = 0; rooms[0].mark = 1; for (i = 0; i < k; i++) { int room = bfs[i]; for (j = 0; j < n; j++) { if (room != j and (connect[j][room] or connect[room][j]) and 0 == rooms[j].mark) { /* mark this room, add it to the search queue: */ rooms[j].mark = 1; bfs[k++] = j; } } } if (k != n) { // I->debug ("not connected!!! %d %d", k, n); /* add a new room? */ if (RNG (3) and n < MAXROOMS) { firstroom = n; n++; //I->debug ("desperately adding a room!"); goto reloop; } /* try again, with longer corridors */ ++maxcorridorlength; if (maxcorridorlength < MSX) { goto corridor; } else { /* miserable failure! */ //I->debug ("giving up :-("); for (i = 0; i < mFeatures.count (); i++) { delete mFeatures.get(i); } mFeatures.reset (); return 0; } } else { //I->debug ("connected! %d", n); } } for (i = 0; i < n; i++) { decorateRoom (rooms[i].rsx, rooms[i].rsy, rooms[i].rex, rooms[i].rey); } /* All newly dug tunnels will be dark. */ for (int y = 0; y < mRows ; ++y) { for (int x = 0; x < mColumns; ++x) { if (kStone == GETSQ (x, y)) setLit (x, y, -1, -1, -1, -1); } } /* for (y = 0; y < MSY; y++) { char buff[MSX+1]; for (x = 0; x < MSX; x++) { macrosq[x][y]; buff[x] = c >= 0 ? c + 'A' : c == -1 ? ' ' : '0' - c; } buff[MSX] = 0; I->debug ("%s", buff); } */ return 1; #undef MSX #undef MSY }
void loadVtk(string path, VRTransformPtr res) { cout << "load VTK file " << path << endl; VRGeoData geo; vtkDataSetReader* reader = vtkDataSetReader::New(); reader->SetFileName(path.c_str()); reader->ReadAllScalarsOn(); reader->ReadAllVectorsOn(); reader->ReadAllNormalsOn(); reader->ReadAllTensorsOn(); reader->ReadAllTCoordsOn(); reader->ReadAllFieldsOn(); reader->ReadAllColorScalarsOn(); reader->Update(); vtkDataSet* dataset = reader->GetOutput(); int npoints = dataset->GetNumberOfPoints(); int ncells = dataset->GetNumberOfCells(); int nscalars = reader->GetNumberOfScalarsInFile(); int nvectors = reader->GetNumberOfVectorsInFile(); int ntensors = reader->GetNumberOfTensorsInFile(); cout << "dataset sizes: " << npoints << " " << ncells << " " << nscalars << " " << nvectors << " " << ntensors << endl; for (int i=0; i<npoints; i++) { auto p = dataset->GetPoint(i); Vec3d v(p[0], p[1], p[2]); geo.pushVert(v); cout << "point " << v << endl; } auto getCellPIDs = [](vtkCell* c) { vector<int> res; auto ids = c->GetPointIds(); for (int k=0; k<ids->GetNumberOfIds(); k++) { res.push_back( ids->GetId(k) ); } return res; }; for (int i=0; i<ncells; i++) { vtkCell* c = dataset->GetCell(i); //int d = c->GetCellDimension(); //int t = c->GetCellType(); string type = c->GetClassName(); cout << "cell type " << type << endl; if (type == "vtkQuad") { auto j = getCellPIDs(c); geo.pushQuad(j[0], j[1], j[2], j[3]); } } //vtkCellData* cells = dataset->GetCellData(); vtkPointData* points = dataset->GetPointData(); cout << "POINT_DATA:\n"; if (points) { std::cout << " contains point data with " << points->GetNumberOfArrays() << " arrays." << std::endl; for (int i = 0; i < points->GetNumberOfArrays(); i++) { std::cout << "\tArray " << i << " is named " << (points->GetArrayName(i) ? points->GetArrayName(i) : "NULL") << std::endl; } for(int i=0; vtkDataArray* a = points->GetArray(i); i++ ) { int size = a->GetNumberOfTuples(); int comp = a->GetNumberOfComponents(); cout << " data array " << size << " " << comp << endl; for (int j=0; j<size; j++) { cout << "pnt:"; for (int k=0; k<comp; k++) cout << " " << a->GetComponent(j, k); cout << endl; } } } cout << "FIELD_DATA:\n"; if (dataset->GetFieldData()) { std::cout << " contains field data with " << dataset->GetFieldData()->GetNumberOfArrays() << " arrays." << std::endl; for (int i = 0; i < dataset->GetFieldData()->GetNumberOfArrays(); i++) { std::cout << "\tArray " << i << " is named " << dataset->GetFieldData()->GetArray(i)->GetName() << std::endl; } } cout << "CELL_DATA:\n"; vtkCellData *cd = dataset->GetCellData(); if (cd) { std::cout << " contains cell data with " << cd->GetNumberOfArrays() << " arrays." << std::endl; for (int i = 0; i < cd->GetNumberOfArrays(); i++) { std::cout << "\tArray " << i << " is named " << (cd->GetArrayName(i) ? cd->GetArrayName(i) : "NULL") << std::endl; } } /*if (cells) { for(int i=0; vtkDataArray* a = points->GetArray(i); i++ ) { int size = a->GetNumberOfTuples(); int comp = a->GetNumberOfComponents(); for (int j=0; j<size; j++) { cout << "cell:"; for (int k=0; k<comp; k++) cout << " " << a->GetComponent(j, k); cout << endl; } } }*/ string name = "vtk"; auto m = VRMaterial::create(name + "_mat"); m->setLit(0); m->setDiffuse(Color3f(0.3,0.7,1.0)); VRGeometryPtr g = geo.asGeometry(name); g->setMaterial(m); //g->updateNormals(); res->addChild( g ); }
void loadVtk_old(string path, VRTransformPtr res) { cout << "load VTK file " << path << endl; ifstream file(path.c_str()); string line; auto next = [&]() -> string& { getline(file, line); return line; }; VTKProject project; project.version = splitString( next() )[4]; project.title = next(); project.format = next(); project.dataset = splitString( next() )[1]; VRGeoData geo; // build geometry if (project.dataset == "STRUCTURED_POINTS") { auto r = splitString( next() ); Vec3i dims = toValue<Vec3i>( r[1] + " " + r[2] + " " + r[3] ); r = splitString( next() ); Vec3d p0 = toValue<Vec3d>( r[1] + " " + r[2] + " " + r[3] ); r = splitString( next() ); Vec3d d = toValue<Vec3d>( r[1] + " " + r[2] + " " + r[3] ); for (int k=0; k<dims[2]; k++) { for (int j=0; j<dims[1]; j++) { for (int i=0; i<dims[0]; i++) { geo.pushVert(p0 + Vec3d(d[0]*i, d[1]*j, d[2]*k) ); geo.pushPoint(); } } } } if (project.dataset == "STRUCTURED_GRID") { auto r = splitString( next() ); Vec3i dims = toValue<Vec3i>( r[1] + " " + r[2] + " " + r[3] ); r = splitString( next() ); int N = toInt(r[1]); string type = r[2]; // points vector<Vec3d> points; for (int i=0; i<N; i++) { Vec3d p = toValue<Vec3d>( next() ); points.push_back(p); geo.pushVert(p); geo.pushPoint(); } } if (project.dataset == "RECTILINEAR_GRID") { ; } if (project.dataset == "UNSTRUCTURED_GRID") { ; } if (project.dataset == "POLYDATA") { auto r = splitString( next() ); int N = toInt(r[1]); string type = r[2]; // points for (int i=0; i<N; i++) geo.pushVert( toValue<Vec3d>( next() ) ); while (next() != "") { r = splitString( line ); string type = r[0]; N = toInt(r[1]); //int size = toInt(r[2]); for (int i=0; i<N; i++) { // for each primitive r = splitString( next() ); int Ni = toInt(r[0]); // length of primitive cout << line << " " << Ni << endl; //if (Ni == 2) geo.pushLine(toInt(r[1]), toInt(r[2])); if (Ni == 3) geo.pushTri(toInt(r[1]), toInt(r[2]), toInt(r[3])); if (Ni == 4) geo.pushQuad(toInt(r[1]), toInt(r[2]), toInt(r[3]), toInt(r[4])); } } } if (project.dataset == "FIELD") { ; } // parsing finished cout << project.toString() << endl; file.close(); auto m = VRMaterial::create(project.title + "_mat"); m->setLit(0); m->setDiffuse(Color3f(0.3,0.7,1.0)); VRGeometryPtr g = geo.asGeometry(project.title); g->setMaterial(m); //g->updateNormals(); res->addChild( g ); }
int shMapLevel::buildSewer () { int x, y, i, n; int lighting = RNG (2) ? -1 : 1; SewerRoom nodes[NODECOLS][NODEROWS]; mMapType = kSewer; x = RNG (NODECOLS); y = RNG (NODEROWS); //first pass buildSewerHelper (nodes, x, y, 0); //second pass, make more tightly connected for (n = 10; n; n--) { if (RNG(3)) { x = RNG (NODECOLS-1); y = RNG (NODEROWS); nodes[x][y].mWalls[1] = 0; nodes[x+1][y].mWalls[2] = 0; } else { x = RNG (NODECOLS); y = RNG (NODEROWS-1); nodes[x][y].mWalls[3] = 0; nodes[x][y+1].mWalls[0] = 0; } } for (x = 0; x < NODECOLS; x++) { for (y = 0; y < NODEROWS; y++) { if (nodes[x][y].mDeadEnd or !RNG(7)) { nodes[x][y].mBulbous = 1; } } } // force 2 bulbous rooms x = RNG (NODECOLS/3); y = RNG (NODEROWS); nodes[x][y].mBulbous = 1; x = NODECOLS - 1 - RNG (NODECOLS/3); y = RNG (NODEROWS); nodes[x][y].mBulbous = 1; // don't have adjacent bulbous rooms (looks bad) for (x = 0; x < NODECOLS-1; x++) { for (y = 0; y < NODEROWS; y++) { if (nodes[x][y].mBulbous and nodes[x+1][y].mBulbous and nodes[x][y].mWalls[1]) { if (RNG(2)) nodes[x][y].mBulbous = 0; else nodes[x+1][y].mBulbous = 0; } } } for (x = 0; x < NODECOLS; x++) { for (y = 0; y < NODEROWS-1; y++) { if (nodes[x][y].mBulbous and nodes[x][y+1].mBulbous and nodes[x][y].mWalls[3]) { if (RNG(2)) nodes[x][y].mBulbous = 0; else nodes[x][y+1].mBulbous = 0; } } } for (x = 0; x < NODECOLS; x++) { for (y = 0; y < NODEROWS; y++) { buildSewerRoom (nodes, x, y); } } for (n = NDX(2,4); n; n--) { floodMuck (RNG(NODECOLS)*6+5, RNG(NODEROWS)*4+2, kSewage, NDX(8,20)); } for (i = NDX (2, 3); i; --i) { findUnoccupiedSquare (&x, &y); switch (RNG (4)) { case 0: addTrap (x, y, shFeature::kPit); break; case 1: addTrap (x, y, shFeature::kHole); break; case 2: addTrap (x, y, shFeature::kTrapDoor); break; case 3: addTrap (x, y, shFeature::kRadTrap); break; } } for (i = 0; i < 8; i++) { findUnoccupiedSquare (&x, &y); putObject (generateObject (mDLevel), x, y); } for (x = 0; x < mColumns; x++) for (y = 0; y < mRows; y++) setLit (x, y, lighting, lighting, lighting, lighting); return 1; }