void GeneralizedCylinder :: Plot (const class ROT3D & rot) const { Point<2> p2d; Point<3> p, oldp; double t, tmin, tmax, dt; tmin = crosssection.MinParam(); tmax = crosssection.MaxParam(); dt = (tmax - tmin)/ 500; p2d = crosssection.Eval(tmin); p = planep + p2d(0) * planee1 + p2d(1) * planee2; for (t = tmin; t <= tmax+dt; t += dt) { if (crosssection.SectionUsed (t)) MySetColor (RED); else MySetColor (BLUE); oldp = p; p2d = crosssection.Eval(t); p = planep + p2d(0) * planee1 + p2d(1) * planee2; MyLine3D (p, oldp, rot); } }
void GeneralizedCylinder :: Project (Point<3> & p) const { Point<2> p2d; double z; p2d = Point<2> (planee1 * (p - planep), planee2 * (p - planep)); z = planee3 * (p - planep); crosssection.Project (p2d); p = planep + p2d(0) * planee1 + p2d(1) * planee2 + z * planee3; }
bool EmergeThread::getBlockOrStartGen(v3s16 p, MapBlock **b, BlockMakeData *data, bool allow_gen) { v2s16 p2d(p.X, p.Z); //envlock: usually takes <=1ms, sometimes 90ms or ~400ms to acquire JMutexAutoLock envlock(m_server->m_env_mutex); // Load sector if it isn't loaded if (map->getSectorNoGenerateNoEx(p2d) == NULL) map->loadSectorMeta(p2d); // Attempt to load block MapBlock *block = map->getBlockNoCreateNoEx(p); if (!block || block->isDummy() || !block->isGenerated()) { EMERGE_DBG_OUT("not in memory, attempting to load from disk"); block = map->loadBlock(p); if (block && block->isGenerated()) map->prepareBlock(block); } // If could not load and allowed to generate, // start generation inside this same envlock if (allow_gen && (block == NULL || !block->isGenerated())) { EMERGE_DBG_OUT("generating"); *b = block; return map->initBlockMake(data, p); } *b = block; return false; }
CRhinoCommand::result CCommandSampleDimLinear2::RunCommand( const CRhinoCommandContext& context ) { ON_3dPoint origin( 1, 1, 0 ); ON_3dPoint offset( 11, 1, 0 ); ON_3dPoint pt( (offset.x-origin.x)/2, 3, 0 ); CRhinoLinearDimension* dim_obj = new CRhinoLinearDimension(); ON_Plane plane( ON_xy_plane ); plane.SetOrigin( origin ); dim_obj->SetPlane( plane ); double u, v; plane.ClosestPointTo( origin, &u, &v ); dim_obj->SetPoint( 0, ON_2dPoint(u,v) ); plane.ClosestPointTo( offset, &u, &v ); dim_obj->SetPoint( 2, ON_2dPoint(u,v) ); plane.ClosestPointTo( pt, &u, &v ); ON_2dPoint p2d( u, v ); dim_obj->UpdateDimPoints( p2d ); dim_obj->UpdateText(); if( context.m_doc.AddObject(dim_obj) ) context.m_doc.Redraw(); else delete dim_obj; return CRhinoCommand::success; }
DLL_HEADER int Ngx_Mesh :: FindElementOfPoint <2> (double * p, double * lami, bool build_searchtree, int * const indices, int numind) const { Array<int> dummy(numind); for (int i = 0; i < numind; i++) dummy[i] = indices[i]+1; double lam3[3]; Point<3> p2d(p[0], p[1], 0); int ind = mesh->GetElementOfPoint(p2d, lam3, &dummy, build_searchtree); if (ind > 0) { if(mesh->SurfaceElement(ind).GetType()==QUAD) { lami[0] = lam3[0]; lami[1] = lam3[1]; } else { lami[0] = 1-lam3[0]-lam3[1]; lami[1] = lam3[0]; } } return ind-1; }
void Refinement2d :: ProjectToEdge (Point<3> & p, int /*surfi1*/, int /*surfi2*/, const EdgePointGeomInfo & egi) const { Point<2> p2d (p(0), p(1)), pp; double t; geometry.GetSplines().Get(egi.edgenr) -> Project (p2d, pp, t); p = Point<3> (pp(0), pp(1), 0); }
void Refinement2d :: PointBetween (const Point<3> & /*p1*/, const Point<3> & /*p2*/, double secpoint, int /*surfi1*/, int /*surfi2*/, const EdgePointGeomInfo & ap1, const EdgePointGeomInfo & ap2, Point<3> & newp, EdgePointGeomInfo & newgi) const { Point<2> p2d; p2d = geometry.GetSplines().Get(ap1.edgenr) -> GetPoint (((1-secpoint)*ap1.dist+secpoint*ap2.dist)); // (*testout) << "refine 2d line, ap1.dist, ap2.dist = " << ap1.dist << ", " << ap2.dist << endl; // (*testout) << "p1, p2 = " << p1 << p2 << ", newp = " << p2d << endl; newp = Point3d (p2d(0), p2d(1), 0); newgi.edgenr = ap1.edgenr; newgi.dist = ((1-secpoint)*ap1.dist+secpoint*ap2.dist); }
BOOST_FIXTURE_TEST_CASE(test_ostream_operator, F) { egen::Point<double> p2d(2.2, 1.0); egen::Point<double> p3d(3.0, 2.0, 1.0); std::ostringstream actual2d; actual2d << p2d; BOOST_CHECK_EQUAL("(2.2, 1)", actual2d.str()); std::ostringstream actual3d; actual3d << p3d; BOOST_CHECK_EQUAL("(3, 2, 1)", actual3d.str()); }
GameAlgorithm::Point2DArr GameAlgorithm::getInitialBoard( void ) { Point2DArr board; for (int row = 0; row < m_nSideLen; row++) { for (int col = 0; col < m_nSideLen; col++) { Point2D p2d(row, col, m_board[row][col]); board.push_back(p2d); } } return board; }
void MapSector::insertBlock(MapBlock *block) { s16 block_y = block->getPos().Y; MapBlock *block2 = getBlockBuffered(block_y); if(block2 != NULL){ throw AlreadyExistsException("Block already exists"); } v2s16 p2d(block->getPos().X, block->getPos().Z); assert(p2d == m_pos); // Insert into container m_blocks.insert(block_y, block); }
void MapSector::insertBlock(MapBlock *block) { s16 block_y = block->getPos().Y; MapBlock *block2 = getBlockBuffered(block_y); if(block2 != NULL){ //throw AlreadyExistsException("Block already exists"); errorstream<<"Block already exists" /*<PP(block->getPos())*/ <<std::endl; } v2s16 p2d(block->getPos().X, block->getPos().Z); assert(p2d == m_pos); // Insert into container m_blocks[block_y] = block; }
GameAlgorithm::GameAlgorithm(int nDim) : m_nSideLen(nDim) , m_nScore(0) , m_mt19937((unsigned long)QDateTime::currentMSecsSinceEpoch()) { clearBoard(); Point2DArr freeSlots; for (int row = 0; row < m_nSideLen; row++) { for (int col = 0; col < m_nSideLen; col++) { m_board[row][col] = NULL; Point2D p2d(row, col, NULL); freeSlots.push_back(p2d); } } putNextNumbersOnBoard(2 * (m_nSideLen / 4) * (m_nSideLen / 4), freeSlots); }
Point<3> GeneralizedCylinder :: GetSurfacePoint () const { Point<2> p2d; p2d = crosssection.Eval(0); return planep + p2d(0) * planee1 + p2d(1) * planee2; }
bica::ShapeList EKFLocalization::getGrDebugAbs() { shapeListAbs.clear(); pthread_mutex_lock(&mutex); { Point2D p2d, p22; p2d.x = (float)ekf.filter->x(); p2d.y = (float)ekf.filter->y(); p22.x = (float)ekf.filter->x() + 600.0 * cos(ekf.filter->t()); p22.y = (float)ekf.filter->y() + 600.0 * sin(ekf.filter->t()); bica::Point3DPtr src(new bica::Point3D); bica::Point3DPtr dst(new bica::Point3D); bica::ArrowPtr a(new bica::Arrow); //cerr<<"---> ("<<(*it)->x()<<", "<<(*it)->y()<<", "<<(*it)->t()<<")"<<endl; src->x = (float)ekf.filter->x(); src->y = (float)ekf.filter->y(); src->z = 600.0; dst->x = (float)ekf.filter->x() + 600.0 * cos(ekf.filter->t()); dst->y = (float)ekf.filter->y() + 600.0 * sin(ekf.filter->t()); dst->z = 600.0; a->src = src; a->dst = dst; a->width = 10.0; a->color = bica::BLUE; a->filled = true; a->opacity = 255; a->accKey = "c"; a->label = "KFE"; shapeListAbs.push_back(a); bica::EllipsePtr e(new bica::Ellipse); bica::Point3DPtr c(new bica::Point3D); c->x = (float)ekf.filter->x(); c->y = (float)ekf.filter->y(); c->z = 550; e->center = c; GaussianDistribution2D distrib; distrib.mean[0] = ekf.filter->x(); distrib.mean[1] = ekf.filter->y(); distrib.covariance[0][0] = ekf.filter->get_P()->e(0, 0); distrib.covariance[0][1] = ekf.filter->get_P()->e(0, 1); distrib.covariance[1][0] = ekf.filter->get_P()->e(1, 0); distrib.covariance[1][1] = ekf.filter->get_P()->e(1, 1); double va1, va2; Vector2D_BH<double> ve1, ve2; double x,y; distrib.getEigenVectorsAndEigenValues(ve1, ve2, va1, va2); double angle; angle = atan2(ve1[1], ve1[0]); if(ekf.filter->get_P()->e(0, 0)<ekf.filter->get_P()->e(1, 1)) angle = normalizePi(angle+pi_2); e->width = (float)sqrt(va1); e->length = (float)sqrt(va2); e->angle = (float)angle; e->color = bica::WHITE; e->filled = true; e->opacity = 125; e->accKey = "c"; e->label = "KFEE"; shapeListAbs.push_back(e); } //cerr<<endl; for(int i=0; i<mgrid->getRows(); i++) for(int j=0; j<mgrid->getColumns(); j++) { bica::RectanglePtr a(new bica::Rectangle); bica::Point3DPtr p2d(new bica::Point3D); bica::Point3DPtr p22(new bica::Point3D); p2d->x=(i*CELL_SIZE)-3000.0; p2d->y=(j*CELL_SIZE)-2000.0; p2d->z=500.0; p22->x = ((i+1)*CELL_SIZE)-3000.0; p22->y = ((j+1)*CELL_SIZE)-2000.0; p22->z=500.0; float media; media = 1.0/((float)mgrid->getRows()*(float)mgrid->getColumns()); float value = (((mgrid->getProbIJ(i,j)/media)*255.0))/2.0; float p = mgrid->getProbIJ(i,j); if (p>0.01) value = (p/0.02)*255.0; else value = 0.0; //value = mgrid->getProbIJ(i,j); if (value>255.0f) value = 255.0f; //cerr<<"("<<p2d->x<<", "<<p2d->y<<"," <<value<<") "; a->p1 = p2d; a->p2 = p22; a->color = bica::RED; a->filled = true; a->opacity = value; a->accKey = "c"; a->label = "KF"; shapeListAbs.push_back(a); bica::Point3DPtr src(new bica::Point3D); bica::Point3DPtr dst(new bica::Point3D); bica::ArrowPtr r(new bica::Arrow); float cx, cy; cx = (((((float)i)*CELL_SIZE)-3000.0) + ((((float)(i+1))*CELL_SIZE)-3000.0))/2.0; cy = (((((float)j)*CELL_SIZE)-2000.0) + ((((float)(j+1))*CELL_SIZE)-2000.0))/2.0; src->x = cx; src->y = cy; src->z = 600.0; dst->x = cx + (CELL_SIZE/2.0) * cos(mgrid->getThetaIJ(i, j)); dst->y = cy + (CELL_SIZE/2.0) * sin(mgrid->getThetaIJ(i, j)); dst->z = 600.0; r->src = src; r->dst = dst; r->width = 10.0; r->color = bica::BLUE; r->filled = true; r->opacity = 255; r->accKey = "c"; r->label = "KFE"; shapeListAbs.push_back(r); } //cerr<<endl; pthread_mutex_unlock(&mutex); return shapeListAbs; }
void MapgenV5::actuallyGenerate() { ManualMapVoxelManipulator &vmanip = *vm; v2s16 p2d_center(node_min.X+MAP_BLOCKSIZE/2, node_min.Z+MAP_BLOCKSIZE/2); /* Get average ground level from noise */ s16 minimum_groundlevel = (s16)get_sector_minimum_ground_level( seed, node_min, node_max); // Minimum amount of ground above the top of the central block s16 minimum_ground_depth = minimum_groundlevel - node_max.Y; s16 maximum_groundlevel = (s16)get_sector_maximum_ground_level( seed, node_min, node_max, 1); // Maximum amount of ground above the bottom of the central block s16 maximum_ground_depth = maximum_groundlevel - node_min.Y; #if 0 /* Special case for high air or water: Just fill with air and water. */ if(maximum_ground_depth < -20) { for(s16 x=node_min.X; x<=node_max.X; x++) for(s16 z=node_min.Z; z<=node_max.Z; z++) { // Node position v2s16 p2d(x,z); { // Use fast index incrementing v3s16 em = vmanip.m_area.getExtent(); u32 i = vmanip.m_area.index(v3s16(p2d.X, node_min.Y, p2d.Y)); for(s16 y=node_min.Y; y<=node_max.Y; y++) { // Only modify places that have no content if(vmanip.m_data[i].getContent() == CONTENT_IGNORE) { if(y <= WATER_LEVEL) vmanip.m_data[i] = MapNode(c_water_source); else vmanip.m_data[i] = MapNode(CONTENT_AIR); } vmanip.m_area.add_y(em, i, 1); } } } // We're done return; } #endif /* If block is deep underground, this is set to true and ground density noise is not generated, for speed optimization. */ bool all_is_ground_except_caves = (minimum_ground_depth > 40); /* Create a block-specific seed */ u32 blockseed = (u32)(seed%0x100000000ULL) + full_node_min.Z*38134234 + full_node_min.Y*42123 + full_node_min.X*23; /* Make some 3D noise */ //OldNoiseBuffer noisebuf1; //OldNoiseBuffer noisebuf2; OldNoiseBuffer noisebuf_cave; OldNoiseBuffer noisebuf_ground; OldNoiseBuffer noisebuf_ground_crumbleness; OldNoiseBuffer noisebuf_ground_wetness; { v3f minpos_f(node_min.X, node_min.Y, node_min.Z); v3f maxpos_f(node_max.X, node_max.Y, node_max.Z); //TimeTaker timer("noisebuf.create"); /* Cave noise */ #if 1 noisebuf_cave.create(get_cave_noise1_params(seed), minpos_f.X, minpos_f.Y, minpos_f.Z, maxpos_f.X, maxpos_f.Y, maxpos_f.Z, 2, 2, 2); noisebuf_cave.multiply(get_cave_noise2_params(seed)); #endif /* Ground noise */ // Sample length v3f sl = v3f(4.0, 4.0, 4.0); /* Density noise */ if(all_is_ground_except_caves == false) //noisebuf_ground.create(seed+983240, 6, 0.60, false, noisebuf_ground.create(get_ground_noise1_params(seed), minpos_f.X, minpos_f.Y, minpos_f.Z, maxpos_f.X, maxpos_f.Y, maxpos_f.Z, sl.X, sl.Y, sl.Z); /* Ground property noise */ sl = v3f(2.5, 2.5, 2.5); noisebuf_ground_crumbleness.create( get_ground_crumbleness_params(seed), minpos_f.X, minpos_f.Y, minpos_f.Z, maxpos_f.X, maxpos_f.Y+5, maxpos_f.Z, sl.X, sl.Y, sl.Z); noisebuf_ground_wetness.create( get_ground_wetness_params(seed), minpos_f.X, minpos_f.Y, minpos_f.Z, maxpos_f.X, maxpos_f.Y+5, maxpos_f.Z, sl.X, sl.Y, sl.Z); } /* Make base ground level */ for(s16 x=node_min.X; x<=node_max.X; x++) for(s16 z=node_min.Z; z<=node_max.Z; z++) { // Node position v2s16 p2d(x,z); { // Use fast index incrementing v3s16 em = vmanip.m_area.getExtent(); u32 i = vmanip.m_area.index(v3s16(p2d.X, node_min.Y, p2d.Y)); for(s16 y=node_min.Y; y<=node_max.Y; y++) { // Only modify places that have no content if(vmanip.m_data[i].getContent() == CONTENT_IGNORE) { // First priority: make air and water. // This avoids caves inside water. if(all_is_ground_except_caves == false && val_is_ground(noisebuf_ground.get(x,y,z), v3s16(x,y,z), seed) == false) { if(y <= WATER_LEVEL) vmanip.m_data[i] = MapNode(c_water_source); else vmanip.m_data[i] = MapNode(CONTENT_AIR); } else if(noisebuf_cave.get(x,y,z) > CAVE_NOISE_THRESHOLD) vmanip.m_data[i] = MapNode(CONTENT_AIR); else vmanip.m_data[i] = MapNode(c_stone); } vmanip.m_area.add_y(em, i, 1); } } } /* Add mud and sand and others underground (in place of stone) */ for(s16 x=node_min.X; x<=node_max.X; x++) for(s16 z=node_min.Z; z<=node_max.Z; z++) { // Node position v2s16 p2d(x,z); { // Use fast index incrementing v3s16 em = vmanip.m_area.getExtent(); u32 i = vmanip.m_area.index(v3s16(p2d.X, node_max.Y, p2d.Y)); for(s16 y=node_max.Y; y>=node_min.Y; y--) { if(vmanip.m_data[i].getContent() == c_stone) { if(noisebuf_ground_crumbleness.get(x,y,z) > 1.3) { if(noisebuf_ground_wetness.get(x,y,z) > 0.0) vmanip.m_data[i] = MapNode(c_dirt); else vmanip.m_data[i] = MapNode(c_sand); } else if(noisebuf_ground_crumbleness.get(x,y,z) > 0.7) { if(noisebuf_ground_wetness.get(x,y,z) < -0.6) vmanip.m_data[i] = MapNode(c_gravel); } else if(noisebuf_ground_crumbleness.get(x,y,z) < -3.0 + MYMIN(0.1 * sqrt((float)MYMAX(0, -y)), 1.5)) { vmanip.m_data[i] = MapNode(c_lava_source); // TODO: Is this needed? /*for(s16 x1=-1; x1<=1; x1++) for(s16 y1=-1; y1<=1; y1++) for(s16 z1=-1; z1<=1; z1++) data->transforming_liquid.push_back( v3s16(p2d.X+x1, y+y1, p2d.Y+z1));*/ } } vmanip.m_area.add_y(em, i, -1); } } } // Add dungeons { DungeonParams dp; dp.np_rarity = nparams_dungeon_rarity; dp.np_density = nparams_dungeon_density; dp.np_wetness = nparams_dungeon_wetness; dp.c_water = c_water_source; // TODO //if (getBiome(0, v2s16(node_min.X, node_min.Z)) == BT_NORMAL) { if (1) { dp.c_cobble = c_cobble; dp.c_moss = c_mossycobble; dp.c_stair = c_stair_cobble; dp.diagonal_dirs = false; dp.mossratio = 3.0; dp.holesize = v3s16(1, 2, 1); dp.roomsize = v3s16(0, 0, 0); dp.notifytype = GENNOTIFY_DUNGEON; } /*else { dp.c_cobble = c_sandbrick; dp.c_moss = c_sandbrick; // should make this 'cracked sandstone' later dp.c_stair = c_stair_sandstone; dp.diagonal_dirs = true; dp.mossratio = 0.0; dp.holesize = v3s16(2, 3, 2); dp.roomsize = v3s16(2, 5, 2); dp.notifytype = GENNOTIFY_TEMPLE; }*/ DungeonGen dgen(this, &dp); dgen.generate(blockseed, full_node_min, full_node_max); } /* If close to ground level */ //if(abs(approx_ground_depth) < 30) if(minimum_ground_depth < 5 && maximum_ground_depth > -5) { /* Add grass and mud */ for(s16 x=node_min.X; x<=node_max.X; x++) for(s16 z=node_min.Z; z<=node_max.Z; z++) { // Node position v2s16 p2d(x,z); { bool possibly_have_sand = get_have_sand(seed, p2d); bool have_sand = false; u32 current_depth = 0; bool air_detected = false; bool water_detected = false; // Use fast index incrementing s16 start_y = node_max.Y+2; v3s16 em = vmanip.m_area.getExtent(); u32 i = vmanip.m_area.index(v3s16(p2d.X, start_y, p2d.Y)); for(s16 y=start_y; y>=node_min.Y-3; y--) { if(vmanip.m_data[i].getContent() == c_water_source) water_detected = true; if(vmanip.m_data[i].getContent() == CONTENT_AIR) air_detected = true; if((vmanip.m_data[i].getContent() == c_stone || vmanip.m_data[i].getContent() == c_dirt_with_grass || vmanip.m_data[i].getContent() == c_dirt || vmanip.m_data[i].getContent() == c_sand || vmanip.m_data[i].getContent() == c_gravel ) && (air_detected || water_detected)) { if(current_depth == 0 && y <= WATER_LEVEL+2 && possibly_have_sand) have_sand = true; if(current_depth < 4) { if(have_sand) vmanip.m_data[i] = MapNode(c_sand); #if 1 else if(current_depth==0 && !water_detected && y >= WATER_LEVEL && air_detected) vmanip.m_data[i] = MapNode(c_dirt_with_grass); #endif else vmanip.m_data[i] = MapNode(c_dirt); } else { if(vmanip.m_data[i].getContent() == c_dirt || vmanip.m_data[i].getContent() == c_dirt_with_grass) vmanip.m_data[i] = MapNode(c_stone); } current_depth++; if(current_depth >= 8) break; } else if(current_depth != 0) break; vmanip.m_area.add_y(em, i, -1); } } } } }
void Meshing2 :: BlockFillLocalH (Mesh & mesh, const MeshingParameters & mp) { double filldist = mp.filldist; cout << "blockfill local h" << endl; cout << "rel filldist = " << filldist << endl; PrintMessage (3, "blockfill local h"); Array<Point<3> > npoints; // adfront -> CreateTrees(); Box<3> bbox ( Box<3>::EMPTY_BOX ); double maxh = 0; for (int i = 0; i < adfront->GetNFL(); i++) { const FrontLine & line = adfront->GetLine (i); const Point<3> & p1 = adfront->GetPoint(line.L().I1()); const Point<3> & p2 = adfront->GetPoint(line.L().I2()); double hi = Dist (p1, p2); if (hi > maxh) maxh = hi; bbox.Add (p1); bbox.Add (p2); } cout << "bbox = " << bbox << endl; // Point<3> mpc = bbox.Center(); bbox.Increase (bbox.Diam()/2); Box<3> meshbox = bbox; LocalH loch2 (bbox, 1); if (mp.maxh < maxh) maxh = mp.maxh; bool changed; do { mesh.LocalHFunction().ClearFlags(); for (int i = 0; i < adfront->GetNFL(); i++) { const FrontLine & line = adfront->GetLine(i); Box<3> bbox (adfront->GetPoint (line.L().I1())); bbox.Add (adfront->GetPoint (line.L().I2())); double filld = filldist * bbox.Diam(); bbox.Increase (filld); mesh.LocalHFunction().CutBoundary (bbox); } mesh.LocalHFunction().FindInnerBoxes (adfront, NULL); npoints.SetSize(0); mesh.LocalHFunction().GetInnerPoints (npoints); changed = false; for (int i = 0; i < npoints.Size(); i++) { if (mesh.LocalHFunction().GetH(npoints[i]) > 1.5 * maxh) { mesh.LocalHFunction().SetH (npoints[i], maxh); changed = true; } } } while (changed); if (debugparam.slowchecks) (*testout) << "Blockfill with points: " << endl; *testout << "loch = " << mesh.LocalHFunction() << endl; *testout << "npoints = " << endl << npoints << endl; for (int i = 1; i <= npoints.Size(); i++) { if (meshbox.IsIn (npoints.Get(i))) { PointIndex gpnum = mesh.AddPoint (npoints.Get(i)); adfront->AddPoint (npoints.Get(i), gpnum); if (debugparam.slowchecks) { (*testout) << npoints.Get(i) << endl; Point<2> p2d (npoints.Get(i)(0), npoints.Get(i)(1)); if (!adfront->Inside(p2d)) { cout << "add outside point" << endl; (*testout) << "outside" << endl; } } } } // find outer points loch2.ClearFlags(); for (int i = 0; i < adfront->GetNFL(); i++) { const FrontLine & line = adfront->GetLine(i); Box<3> bbox (adfront->GetPoint (line.L().I1())); bbox.Add (adfront->GetPoint (line.L().I2())); loch2.SetH (bbox.Center(), bbox.Diam()); } for (int i = 0; i < adfront->GetNFL(); i++) { const FrontLine & line = adfront->GetLine(i); Box<3> bbox (adfront->GetPoint (line.L().I1())); bbox.Add (adfront->GetPoint (line.L().I2())); bbox.Increase (filldist * bbox.Diam()); loch2.CutBoundary (bbox); } loch2.FindInnerBoxes (adfront, NULL); npoints.SetSize(0); loch2.GetOuterPoints (npoints); for (int i = 1; i <= npoints.Size(); i++) { if (meshbox.IsIn (npoints.Get(i))) { PointIndex gpnum = mesh.AddPoint (npoints.Get(i)); adfront->AddPoint (npoints.Get(i), gpnum); } } }
MapBlock* Database_SQLite3::loadBlock(v3s16 blockpos) { v2s16 p2d(blockpos.X, blockpos.Z); verifyDatabase(); if(sqlite3_bind_int64(m_database_read, 1, getBlockAsInteger(blockpos)) != SQLITE_OK) infostream<<"WARNING: Could not bind block position for load: " <<sqlite3_errmsg(m_database)<<std::endl; if(sqlite3_step(m_database_read) == SQLITE_ROW) { /* Make sure sector is loaded */ MapSector *sector = srvmap->createSector(p2d); /* Load block */ const char * data = (const char *)sqlite3_column_blob(m_database_read, 0); size_t len = sqlite3_column_bytes(m_database_read, 0); std::string datastr(data, len); // srvmap->loadBlock(&datastr, blockpos, sector, false); try { std::istringstream is(datastr, std::ios_base::binary); u8 version = SER_FMT_VER_INVALID; is.read((char*)&version, 1); if(is.fail()) throw SerializationError("ServerMap::loadBlock(): Failed" " to read MapBlock version"); MapBlock *block = NULL; bool created_new = false; block = sector->getBlockNoCreateNoEx(blockpos.Y); if(block == NULL) { block = sector->createBlankBlockNoInsert(blockpos.Y); created_new = true; } // Read basic data block->deSerialize(is, version, true); // If it's a new block, insert it to the map if(created_new) sector->insertBlock(block); /* Save blocks loaded in old format in new format */ //if(version < SER_FMT_VER_HIGHEST || save_after_load) // Only save if asked to; no need to update version //if(save_after_load) // saveBlock(block); // We just loaded it from, so it's up-to-date. block->resetModified(); } catch(SerializationError &e) { errorstream<<"Invalid block data in database" <<" ("<<blockpos.X<<","<<blockpos.Y<<","<<blockpos.Z<<")" <<" (SerializationError): "<<e.what()<<std::endl; // TODO: Block should be marked as invalid in memory so that it is // not touched but the game can run if(g_settings->getBool("ignore_world_load_errors")){ errorstream<<"Ignoring block load error. Duck and cover! " <<"(ignore_world_load_errors)"<<std::endl; } else { throw SerializationError("Invalid block data in database"); //assert(0); } } sqlite3_step(m_database_read); // We should never get more than 1 row, so ok to reset sqlite3_reset(m_database_read); return srvmap->getBlockNoCreateNoEx(blockpos); // should not be using this here } sqlite3_reset(m_database_read); return(NULL); }
MapBlock* Database_LevelDB::loadBlock(v3s16 blockpos) { v2s16 p2d(blockpos.X, blockpos.Z); std::string datastr; leveldb::Status s = m_database->Get(leveldb::ReadOptions(), getBlockAsString(blockpos), &datastr); if (!datastr.length()) { s = m_database->Get(leveldb::ReadOptions(), i64tos(getBlockAsInteger(blockpos)), &datastr); if (datastr.length() == 0 && s.ok()) { errorstream << "Blank block data in database (datastr.length() == 0) (" << blockpos.X << "," << blockpos.Y << "," << blockpos.Z << ")" << std::endl; if (g_settings->getBool("ignore_world_load_errors")) { errorstream << "Ignoring block load error. Duck and cover! " << "(ignore_world_load_errors)" << std::endl; } else { throw SerializationError("Blank block data in database"); } return NULL; } } if (s.ok()) { try { std::istringstream is(datastr, std::ios_base::binary); u8 version = SER_FMT_VER_INVALID; is.read((char *)&version, 1); if (is.fail()) throw SerializationError("ServerMap::loadBlock(): Failed" " to read MapBlock version"); MapBlock *block = NULL; bool created_new = false; block = srvmap->getBlockNoCreateNoEx(blockpos); if (block == NULL) { block = srvmap->createBlankBlockNoInsert(blockpos); created_new = true; } // Read basic data block->deSerialize(is, version, true); // If it's a new block, insert it to the map if (created_new) srvmap->insertBlock(block); /* Save blocks loaded in old format in new format */ //if(version < SER_FMT_VER_HIGHEST || save_after_load) // Only save if asked to; no need to update version //if(save_after_load) // saveBlock(block); // We just loaded it from, so it's up-to-date. block->resetModified(); } catch (SerializationError &e) { errorstream << "Invalid block data in database" << " (" << blockpos.X << "," << blockpos.Y << "," << blockpos.Z << ") (SerializationError): " << e.what() << std::endl; // TODO: Block should be marked as invalid in memory so that it is // not touched but the game can run if (g_settings->getBool("ignore_world_load_errors")) { errorstream << "Ignoring block load error. Duck and cover! " << "(ignore_world_load_errors)" << std::endl; } else { throw SerializationError("Invalid block data in database"); //assert(0); } } return srvmap->getBlockNoCreateNoEx(blockpos); // should not be using this here } return NULL; }
GameAlgorithm::Point2DArrPair GameAlgorithm::updateBoard(GameAlgorithm::Move move) { GameAlgorithm::Point2DArrPair result; for (int row = 0; row < m_nSideLen; row++) { for (int col = 0; col < m_nSideLen; col++) { m_board[row][col].m = false; m_board[row][col].n = false; m_board[row][col].ids.clear(); if (m_board[row][col] != ZERO) m_board[row][col].ids.push_back(row * m_nSideLen + col); } } for (int row = 0; row < m_nSideLen; row++) { for (int col = 0; col < m_nSideLen; col++) { Point2D p2d(row, col, m_board[row][col]); result.first.push_back(p2d); } } switch (move) { case UP: mergeUp(); moveUp(); break; case DOWN: mergeDown(); moveDown(); break; case LEFT: mergerLeft(); moveLeft(); break; case RIGHT: mergeRight(); moveRight(); break; } Point2DArr freeSlots; for (int row = 0; row < m_nSideLen; row++) { for (int col = 0; col < m_nSideLen; col++) { if (m_board[row][col] == NULL) { Point2D p2d(row, col, NULL); freeSlots.push_back(p2d); } } } putNextNumbersOnBoard(1 * (m_nSideLen / 4) * (m_nSideLen / 4), freeSlots); for (int row = 0; row < m_nSideLen; row++) { for (int col = 0; col < m_nSideLen; col++) { Point2D p2d(row, col, m_board[row][col]); result.second.push_back(p2d); } } return result; }
MapBlock* Database_Dummy::loadBlock(v3s16 blockpos) { v2s16 p2d(blockpos.X, blockpos.Z); if(m_database.count(getBlockAsInteger(blockpos))) { /* Make sure sector is loaded */ MapSector *sector = srvmap->createSector(p2d); /* Load block */ std::string datastr = m_database[getBlockAsInteger(blockpos)]; // srvmap->loadBlock(&datastr, blockpos, sector, false); try { std::istringstream is(datastr, std::ios_base::binary); u8 version = SER_FMT_VER_INVALID; is.read((char*)&version, 1); if(is.fail()) throw SerializationError("ServerMap::loadBlock(): Failed" " to read MapBlock version"); MapBlock *block = NULL; bool created_new = false; block = sector->getBlockNoCreateNoEx(blockpos.Y); if(block == NULL) { block = sector->createBlankBlockNoInsert(blockpos.Y); created_new = true; } // Read basic data block->deSerialize(is, version, true); // If it's a new block, insert it to the map if(created_new) sector->insertBlock(block); /* Save blocks loaded in old format in new format */ //if(version < SER_FMT_VER_HIGHEST || save_after_load) // Only save if asked to; no need to update version //if(save_after_load) // saveBlock(block); // We just loaded it from, so it's up-to-date. block->resetModified(); } catch(SerializationError &e) { errorstream<<"Invalid block data in database" <<" ("<<blockpos.X<<","<<blockpos.Y<<","<<blockpos.Z<<")" <<" (SerializationError): "<<e.what()<<std::endl; // TODO: Block should be marked as invalid in memory so that it is // not touched but the game can run if(g_settings->getBool("ignore_world_load_errors")){ errorstream<<"Ignoring block load error. Duck and cover! " <<"(ignore_world_load_errors)"<<std::endl; } else { throw SerializationError("Invalid block data in database"); //assert(0); } } return srvmap->getBlockNoCreateNoEx(blockpos); // should not be using this here } return(NULL); }
/** * The goal is to return the best sample point that we can split this * edge on. Returns the index of said sample point. */ int Geom_2D::get_sample_point(Mesh::EdgeHandle &ehandle){ /* * The goal is to convert these coordinates into 2 dimensions * and do the necessary calculations there. The position of the * translated points is arbitrary, we shall merely calculate a * distance then use a unit vector to find the relevant sample point */ Mesh::HalfedgeHandle heh = mesh->halfedge_handle(ehandle, 0); //starting point. We position our edge along the x-axis. vector<Point_2D> p; p.push_back(Point_2D(0.0, 0.0, 0.0)); //0 p.push_back(Point_2D(mesh->calc_edge_length(heh), 0.0, 0.0)); //1 p.push_back(get_2D_point(heh, p[0], p[1])); //2 Mesh::HalfedgeLoopIter heIt; heIt = mesh->hl_begin(heh); heIt ++; p.push_back(get_2D_point(mesh->opposite_halfedge_handle(*heIt), p[2], p[1])); //3 heIt ++; p.push_back(get_2D_point(mesh->opposite_halfedge_handle(*heIt), p[0], p[2])); //4 Mesh::HalfedgeHandle heh2 = mesh->opposite_halfedge_handle(heh); p.push_back(get_2D_point(heh2, p[1], p[0])); //5 heIt = mesh->hl_begin(heh2); heIt ++; p.push_back(get_2D_point(mesh->opposite_halfedge_handle(*heIt), p[5], p[0])); //6 heIt ++; p.push_back(get_2D_point(mesh->opposite_halfedge_handle(*heIt), p[1], p[5])); //7 /* * We aim for simplicity and accuracy over speed in this section. * cc and r contain the circumcenter and the radius of the circumcircles * of the provided triangles. */ double cc[2*6], r[6]; get_circumcircle(p[0], p[2], p[5], &cc[0], r[0]); get_circumcircle(p[1], p[2], p[5], &cc[2], r[1]); get_circumcircle(p[1], p[2], p[3], &cc[4], r[2]); get_circumcircle(p[1], p[7], p[5], &cc[6], r[3]); get_circumcircle(p[0], p[2], p[4], &cc[8], r[4]); get_circumcircle(p[0], p[6], p[5], &cc[10], r[5]); vector<Mesh::Point>* samps; samps = &(mesh->property(*samples, ehandle)); double score; Point_2D p2d(0.0,0.0,0.0); int maxScore = 0; int maxIndex = 0; if (samps->size()==0){ cout<<"*************************"<<endl<<"0 samples"<<endl; output_point(ehandle); cout<<"*************************"<<endl; //this should never happen....but it does. return -1; } for (int i = 0; i < samps->size(); i++){ //first two circles if the sample points are in both we //score 5 //void Geom_2D::mesh_to_plane(Mesh::HalfedgeHandle heh, Mesh::Point &samp, Point_2D &p0, Point_2D &p1, Point_2D &dest){ score = 0; mesh_to_plane(heh, (*samps)[i], (p[0]), (p[1]), p2d); if (score_type == 1){ if (distance2d(cc, p2d)<r[0]){ score += 1.5; } if (distance2d(cc+2, p2d)<r[1]){ score += 1.5; } }else if (score_type == 0){ if (distance2d(cc, p2d)<r[0]){ score ++; } if (distance2d(cc+2, p2d)<r[1]){ score ++; } }else if (score_type == 2){ if ((distance2d(cc, p2d)<r[0])&&(distance2d(cc+2, p2d)<r[1])){ score += 5; } } for (int j = 2; j < 6; j++){ if (distance2d(cc+(2*j), p2d)>r[j]){ score++; } } if (score>maxScore){ maxScore = score; maxIndex = i; } } //cout<<"max Score: "<<maxScore<<endl; //if ((maxIndex == 0)||(maxIndex == samps->size()-1)) { if(samps->size()==0){ cout<<"*************************"<<endl; cout<<"******************index: "<<maxIndex<<endl; cout<<"*************************"<<endl; cout<<"samples size: "<<samps->size()<<endl; cout<<" is flippable "<< mesh->property(*is_flippable, ehandle)<<endl; cout<<" is Delaunay "<< mesh->property(*is_NDE, ehandle)<<endl; output_point(ehandle); cout<<"length: "<<mesh->calc_edge_length(ehandle)<<endl; cout<<"max score "<<maxScore<<endl; } return maxIndex; }
void Database_SQLite3::saveBlock(MapBlock *block) { DSTACK(__FUNCTION_NAME); /* Dummy blocks are not written */ if(block->isDummy()) { /*v3s16 p = block->getPos(); infostream<<"Database_SQLite3::saveBlock(): WARNING: Not writing dummy block " <<"("<<p.X<<","<<p.Y<<","<<p.Z<<")"<<std::endl;*/ return; } // Format used for writing u8 version = SER_FMT_VER_HIGHEST; // Get destination v3s16 p3d = block->getPos(); #if 0 v2s16 p2d(p3d.X, p3d.Z); std::string sectordir = getSectorDir(p2d); createDirs(sectordir); std::string fullpath = sectordir+DIR_DELIM+getBlockFilename(p3d); std::ofstream o(fullpath.c_str(), std::ios_base::binary); if(o.good() == false) throw FileNotGoodException("Cannot open block data"); #endif /* [0] u8 serialization version [1] data */ verifyDatabase(); std::ostringstream o(std::ios_base::binary); o.write((char*)&version, 1); // Write basic data block->serialize(o, version, true); // Write block to database std::string tmp = o.str(); const char *bytes = tmp.c_str(); if(sqlite3_bind_int64(m_database_write, 1, getBlockAsInteger(p3d)) != SQLITE_OK) infostream<<"WARNING: Block position failed to bind: "<<sqlite3_errmsg(m_database)<<std::endl; if(sqlite3_bind_blob(m_database_write, 2, (void *)bytes, o.tellp(), NULL) != SQLITE_OK) // TODO this mught not be the right length infostream<<"WARNING: Block data failed to bind: "<<sqlite3_errmsg(m_database)<<std::endl; int written = sqlite3_step(m_database_write); if(written != SQLITE_DONE) infostream<<"WARNING: Block failed to save ("<<p3d.X<<", "<<p3d.Y<<", "<<p3d.Z<<") " <<sqlite3_errmsg(m_database)<<std::endl; // Make ready for later reuse sqlite3_reset(m_database_write); // We just wrote it to the disk so clear modified flag block->resetModified(); }
/* sender_peer_id given to this shall be quaranteed to be a valid peer */ void Client::ProcessData(u8 *data, u32 datasize, u16 sender_peer_id) { DSTACK(__FUNCTION_NAME); // Ignore packets that don't even fit a command if(datasize < 2) { m_packetcounter.add(60000); return; } ToClientCommand command = (ToClientCommand)readU16(&data[0]); //infostream<<"Client: received command="<<command<<std::endl; m_packetcounter.add((u16)command); /* If this check is removed, be sure to change the queue system to know the ids */ if(sender_peer_id != PEER_ID_SERVER) { infostream<<"Client::ProcessData(): Discarding data not " "coming from server: peer_id="<<sender_peer_id <<std::endl; return; } u8 ser_version = m_server_ser_ver; //infostream<<"Client received command="<<(int)command<<std::endl; if(command == TOCLIENT_INIT) { if(datasize < 3) return; u8 deployed = data[2]; infostream<<"Client: TOCLIENT_INIT received with " "deployed="<<((int)deployed&0xff)<<std::endl; if(deployed < SER_FMT_VER_LOWEST || deployed > SER_FMT_VER_HIGHEST) { infostream<<"Client: TOCLIENT_INIT: Server sent " <<"unsupported ser_fmt_ver"<<std::endl; return; } m_server_ser_ver = deployed; // Get player position v3s16 playerpos_s16(0, BS*2+BS*20, 0); if(datasize >= 2+1+6) playerpos_s16 = readV3S16(&data[2+1]); v3f playerpos_f = intToFloat(playerpos_s16, BS) - v3f(0, BS/2, 0); { //envlock //JMutexAutoLock envlock(m_env_mutex); //bulk comment-out // Set player position Player *player = m_env.getLocalPlayer(); assert(player != NULL); player->setPosition(playerpos_f); } if(datasize >= 2+1+6+8) { // Get map seed m_map_seed = readU64(&data[2+1+6]); infostream<<"Client: received map seed: "<<m_map_seed<<std::endl; } // Reply to server u32 replysize = 2; SharedBuffer<u8> reply(replysize); writeU16(&reply[0], TOSERVER_INIT2); // Send as reliable m_con.Send(PEER_ID_SERVER, 1, reply, true); return; } if(command == TOCLIENT_ACCESS_DENIED) { // The server didn't like our password. Note, this needs // to be processed even if the serialisation format has // not been agreed yet, the same as TOCLIENT_INIT. m_access_denied = true; m_access_denied_reason = L"Unknown"; if(datasize >= 4) { std::string datastring((char*)&data[2], datasize-2); std::istringstream is(datastring, std::ios_base::binary); m_access_denied_reason = deSerializeWideString(is); } return; } if(ser_version == SER_FMT_VER_INVALID) { infostream<<"Client: Server serialization" " format invalid or not initialized." " Skipping incoming command="<<command<<std::endl; return; } // Just here to avoid putting the two if's together when // making some copypasta {} if(command == TOCLIENT_REMOVENODE) { if(datasize < 8) return; v3s16 p; p.X = readS16(&data[2]); p.Y = readS16(&data[4]); p.Z = readS16(&data[6]); //TimeTaker t1("TOCLIENT_REMOVENODE"); // This will clear the cracking animation after digging ((ClientMap&)m_env.getMap()).clearTempMod(p); removeNode(p); } else if(command == TOCLIENT_ADDNODE) { if(datasize < 8 + MapNode::serializedLength(ser_version)) return; v3s16 p; p.X = readS16(&data[2]); p.Y = readS16(&data[4]); p.Z = readS16(&data[6]); //TimeTaker t1("TOCLIENT_ADDNODE"); MapNode n; n.deSerialize(&data[8], ser_version); addNode(p, n); } else if(command == TOCLIENT_BLOCKDATA) { // Ignore too small packet if(datasize < 8) return; v3s16 p; p.X = readS16(&data[2]); p.Y = readS16(&data[4]); p.Z = readS16(&data[6]); /*infostream<<"Client: Thread: BLOCKDATA for (" <<p.X<<","<<p.Y<<","<<p.Z<<")"<<std::endl;*/ /*infostream<<"Client: Thread: BLOCKDATA for (" <<p.X<<","<<p.Y<<","<<p.Z<<")"<<std::endl;*/ std::string datastring((char*)&data[8], datasize-8); std::istringstream istr(datastring, std::ios_base::binary); MapSector *sector; MapBlock *block; v2s16 p2d(p.X, p.Z); sector = m_env.getMap().emergeSector(p2d); assert(sector->getPos() == p2d); //TimeTaker timer("MapBlock deSerialize"); // 0ms block = sector->getBlockNoCreateNoEx(p.Y); if(block) { /* Update an existing block */ //infostream<<"Updating"<<std::endl; block->deSerialize(istr, ser_version); } else { /* Create a new block */ //infostream<<"Creating new"<<std::endl; block = new MapBlock(&m_env.getMap(), p); block->deSerialize(istr, ser_version); sector->insertBlock(block); //DEBUG /*NodeMod mod; mod.type = NODEMOD_CHANGECONTENT; mod.param = CONTENT_MESE; block->setTempMod(v3s16(8,10,8), mod); block->setTempMod(v3s16(8,9,8), mod); block->setTempMod(v3s16(8,8,8), mod); block->setTempMod(v3s16(8,7,8), mod); block->setTempMod(v3s16(8,6,8), mod);*/ } #if 0 /* Acknowledge block */ /* [0] u16 command [2] u8 count [3] v3s16 pos_0 [3+6] v3s16 pos_1 ... */ u32 replysize = 2+1+6; SharedBuffer<u8> reply(replysize); writeU16(&reply[0], TOSERVER_GOTBLOCKS); reply[2] = 1; writeV3S16(&reply[3], p); // Send as reliable m_con.Send(PEER_ID_SERVER, 1, reply, true); #endif /* Update Mesh of this block and blocks at x-, y- and z-. Environment should not be locked as it interlocks with the main thread, from which is will want to retrieve textures. */ //m_env.getClientMap().updateMeshes(block->getPos(), getDayNightRatio()); /* Add it to mesh update queue and set it to be acknowledged after update. */ //infostream<<"Adding mesh update task for received block"<<std::endl; addUpdateMeshTaskWithEdge(p, true); } else if(command == TOCLIENT_PLAYERPOS) { infostream<<"Received deprecated TOCLIENT_PLAYERPOS" <<std::endl; /*u16 our_peer_id; { //JMutexAutoLock lock(m_con_mutex); //bulk comment-out our_peer_id = m_con.GetPeerID(); } // Cancel if we don't have a peer id if(our_peer_id == PEER_ID_INEXISTENT){ infostream<<"TOCLIENT_PLAYERPOS cancelled: " "we have no peer id" <<std::endl; return; }*/ { //envlock //JMutexAutoLock envlock(m_env_mutex); //bulk comment-out u32 player_size = 2+12+12+4+4; u32 player_count = (datasize-2) / player_size; u32 start = 2; for(u32 i=0; i<player_count; i++) { u16 peer_id = readU16(&data[start]); Player *player = m_env.getPlayer(peer_id); // Skip if player doesn't exist if(player == NULL) { start += player_size; continue; } // Skip if player is local player if(player->isLocal()) { start += player_size; continue; } v3s32 ps = readV3S32(&data[start+2]); v3s32 ss = readV3S32(&data[start+2+12]); s32 pitch_i = readS32(&data[start+2+12+12]); s32 yaw_i = readS32(&data[start+2+12+12+4]); /*infostream<<"Client: got " <<"pitch_i="<<pitch_i <<" yaw_i="<<yaw_i<<std::endl;*/ f32 pitch = (f32)pitch_i / 100.0; f32 yaw = (f32)yaw_i / 100.0; v3f position((f32)ps.X/100., (f32)ps.Y/100., (f32)ps.Z/100.); v3f speed((f32)ss.X/100., (f32)ss.Y/100., (f32)ss.Z/100.); player->setPosition(position); player->setSpeed(speed); player->setPitch(pitch); player->setYaw(yaw); /*infostream<<"Client: player "<<peer_id <<" pitch="<<pitch <<" yaw="<<yaw<<std::endl;*/ start += player_size; } } //envlock } else if(command == TOCLIENT_PLAYERINFO) { u16 our_peer_id; { //JMutexAutoLock lock(m_con_mutex); //bulk comment-out our_peer_id = m_con.GetPeerID(); } // Cancel if we don't have a peer id if(our_peer_id == PEER_ID_INEXISTENT){ infostream<<"TOCLIENT_PLAYERINFO cancelled: " "we have no peer id" <<std::endl; return; } //infostream<<"Client: Server reports players:"<<std::endl; { //envlock //JMutexAutoLock envlock(m_env_mutex); //bulk comment-out u32 item_size = 2+PLAYERNAME_SIZE; u32 player_count = (datasize-2) / item_size; u32 start = 2; // peer_ids core::list<u16> players_alive; for(u32 i=0; i<player_count; i++) { // Make sure the name ends in '\0' data[start+2+20-1] = 0; u16 peer_id = readU16(&data[start]); players_alive.push_back(peer_id); /*infostream<<"peer_id="<<peer_id <<" name="<<((char*)&data[start+2])<<std::endl;*/ // Don't update the info of the local player if(peer_id == our_peer_id) { start += item_size; continue; } Player *player = m_env.getPlayer(peer_id); // Create a player if it doesn't exist if(player == NULL) { player = new RemotePlayer( m_device->getSceneManager()->getRootSceneNode(), m_device, -1); player->peer_id = peer_id; m_env.addPlayer(player); infostream<<"Client: Adding new player " <<peer_id<<std::endl; } player->updateName((char*)&data[start+2]); start += item_size; } /* Remove those players from the environment that weren't listed by the server. */ //infostream<<"Removing dead players"<<std::endl; core::list<Player*> players = m_env.getPlayers(); core::list<Player*>::Iterator ip; for(ip=players.begin(); ip!=players.end(); ip++) { // Ingore local player if((*ip)->isLocal()) continue; // Warn about a special case if((*ip)->peer_id == 0) { infostream<<"Client: Removing " "dead player with id=0"<<std::endl; } bool is_alive = false; core::list<u16>::Iterator i; for(i=players_alive.begin(); i!=players_alive.end(); i++) { if((*ip)->peer_id == *i) { is_alive = true; break; } } /*infostream<<"peer_id="<<((*ip)->peer_id) <<" is_alive="<<is_alive<<std::endl;*/ if(is_alive) continue; infostream<<"Removing dead player "<<(*ip)->peer_id <<std::endl; m_env.removePlayer((*ip)->peer_id); } } //envlock } else if(command == TOCLIENT_SECTORMETA) { infostream<<"Client received DEPRECATED TOCLIENT_SECTORMETA"<<std::endl; #if 0 /* [0] u16 command [2] u8 sector count [3...] v2s16 pos + sector metadata */ if(datasize < 3) return; //infostream<<"Client received TOCLIENT_SECTORMETA"<<std::endl; { //envlock //JMutexAutoLock envlock(m_env_mutex); //bulk comment-out std::string datastring((char*)&data[2], datasize-2); std::istringstream is(datastring, std::ios_base::binary); u8 buf[4]; is.read((char*)buf, 1); u16 sector_count = readU8(buf); //infostream<<"sector_count="<<sector_count<<std::endl; for(u16 i=0; i<sector_count; i++) { // Read position is.read((char*)buf, 4); v2s16 pos = readV2S16(buf); /*infostream<<"Client: deserializing sector at " <<"("<<pos.X<<","<<pos.Y<<")"<<std::endl;*/ // Create sector assert(m_env.getMap().mapType() == MAPTYPE_CLIENT); ((ClientMap&)m_env.getMap()).deSerializeSector(pos, is); } } //envlock #endif } else if(command == TOCLIENT_INVENTORY) { if(datasize < 3) return; //TimeTaker t1("Parsing TOCLIENT_INVENTORY", m_device); { //envlock //TimeTaker t2("mutex locking", m_device); //JMutexAutoLock envlock(m_env_mutex); //bulk comment-out //t2.stop(); //TimeTaker t3("istringstream init", m_device); std::string datastring((char*)&data[2], datasize-2); std::istringstream is(datastring, std::ios_base::binary); //t3.stop(); //m_env.printPlayers(infostream); //TimeTaker t4("player get", m_device); Player *player = m_env.getLocalPlayer(); assert(player != NULL); //t4.stop(); //TimeTaker t1("inventory.deSerialize()", m_device); player->inventory.deSerialize(is); //t1.stop(); m_inventory_updated = true; //infostream<<"Client got player inventory:"<<std::endl; //player->inventory.print(infostream); } } //DEBUG else if(command == TOCLIENT_OBJECTDATA) { // Strip command word and create a stringstream std::string datastring((char*)&data[2], datasize-2); std::istringstream is(datastring, std::ios_base::binary); u8 buf[12]; /* Read players */ is.read((char*)buf, 2); u16 playercount = readU16(buf); for(u16 i=0; i<playercount; i++) { is.read((char*)buf, 2); u16 peer_id = readU16(buf); is.read((char*)buf, 12); v3s32 p_i = readV3S32(buf); is.read((char*)buf, 12); v3s32 s_i = readV3S32(buf); is.read((char*)buf, 4); s32 pitch_i = readS32(buf); is.read((char*)buf, 4); s32 yaw_i = readS32(buf); Player *player = m_env.getPlayer(peer_id); // Skip if player doesn't exist if(player == NULL) { continue; } // Skip if player is local player if(player->isLocal()) { continue; } f32 pitch = (f32)pitch_i / 100.0; f32 yaw = (f32)yaw_i / 100.0; v3f position((f32)p_i.X/100., (f32)p_i.Y/100., (f32)p_i.Z/100.); v3f speed((f32)s_i.X/100., (f32)s_i.Y/100., (f32)s_i.Z/100.); player->setPosition(position); player->setSpeed(speed); player->setPitch(pitch); player->setYaw(yaw); } /* Read block objects NOTE: Deprecated stuff */ // Read active block count u16 blockcount = readU16(is); if(blockcount != 0){ infostream<<"TOCLIENT_OBJECTDATA: blockcount != 0 " "not supported"<<std::endl; return; } } else if(command == TOCLIENT_TIME_OF_DAY) { if(datasize < 4) return; u16 time_of_day = readU16(&data[2]); time_of_day = time_of_day % 24000; //infostream<<"Client: time_of_day="<<time_of_day<<std::endl; /* time_of_day: 0 = midnight 12000 = midday */ { m_env.setTimeOfDay(time_of_day); u32 dr = m_env.getDayNightRatio(); infostream<<"Client: time_of_day="<<time_of_day <<", dr="<<dr <<std::endl; } } else if(command == TOCLIENT_CHAT_MESSAGE) { /* u16 command u16 length wstring message */ u8 buf[6]; std::string datastring((char*)&data[2], datasize-2); std::istringstream is(datastring, std::ios_base::binary); // Read stuff is.read((char*)buf, 2); u16 len = readU16(buf); std::wstring message; for(u16 i=0; i<len; i++) { is.read((char*)buf, 2); message += (wchar_t)readU16(buf); } /*infostream<<"Client received chat message: " <<wide_to_narrow(message)<<std::endl;*/ m_chat_queue.push_back(message); } else if(command == TOCLIENT_ACTIVE_OBJECT_REMOVE_ADD) { //if(g_settings->getBool("enable_experimental")) { /* u16 command u16 count of removed objects for all removed objects { u16 id } u16 count of added objects for all added objects { u16 id u8 type u32 initialization data length string initialization data } */ char buf[6]; // Get all data except the command number std::string datastring((char*)&data[2], datasize-2); // Throw them in an istringstream std::istringstream is(datastring, std::ios_base::binary); // Read stuff // Read removed objects is.read(buf, 2); u16 removed_count = readU16((u8*)buf); for(u16 i=0; i<removed_count; i++) { is.read(buf, 2); u16 id = readU16((u8*)buf); // Remove it { //JMutexAutoLock envlock(m_env_mutex); //bulk comment-out m_env.removeActiveObject(id); } } // Read added objects is.read(buf, 2); u16 added_count = readU16((u8*)buf); for(u16 i=0; i<added_count; i++) { is.read(buf, 2); u16 id = readU16((u8*)buf); is.read(buf, 1); u8 type = readU8((u8*)buf); std::string data = deSerializeLongString(is); // Add it { //JMutexAutoLock envlock(m_env_mutex); //bulk comment-out m_env.addActiveObject(id, type, data); } } } } else if(command == TOCLIENT_ACTIVE_OBJECT_MESSAGES) { //if(g_settings->getBool("enable_experimental")) { /* u16 command for all objects { u16 id u16 message length string message } */ char buf[6]; // Get all data except the command number std::string datastring((char*)&data[2], datasize-2); // Throw them in an istringstream std::istringstream is(datastring, std::ios_base::binary); while(is.eof() == false) { // Read stuff is.read(buf, 2); u16 id = readU16((u8*)buf); if(is.eof()) break; is.read(buf, 2); u16 message_size = readU16((u8*)buf); std::string message; message.reserve(message_size); for(u16 i=0; i<message_size; i++) { is.read(buf, 1); message.append(buf, 1); } // Pass on to the environment { //JMutexAutoLock envlock(m_env_mutex); //bulk comment-out m_env.processActiveObjectMessage(id, message); } } } } else if(command == TOCLIENT_HP) { std::string datastring((char*)&data[2], datasize-2); std::istringstream is(datastring, std::ios_base::binary); Player *player = m_env.getLocalPlayer(); assert(player != NULL); u8 hp = readU8(is); player->hp = hp; } else if(command == TOCLIENT_MOVE_PLAYER) { std::string datastring((char*)&data[2], datasize-2); std::istringstream is(datastring, std::ios_base::binary); Player *player = m_env.getLocalPlayer(); assert(player != NULL); v3f pos = readV3F1000(is); f32 pitch = readF1000(is); f32 yaw = readF1000(is); player->setPosition(pos); /*player->setPitch(pitch); player->setYaw(yaw);*/ infostream<<"Client got TOCLIENT_MOVE_PLAYER" <<" pos=("<<pos.X<<","<<pos.Y<<","<<pos.Z<<")" <<" pitch="<<pitch <<" yaw="<<yaw <<std::endl; /* Add to ClientEvent queue. This has to be sent to the main program because otherwise it would just force the pitch and yaw values to whatever the camera points to. */ ClientEvent event; event.type = CE_PLAYER_FORCE_MOVE; event.player_force_move.pitch = pitch; event.player_force_move.yaw = yaw; m_client_event_queue.push_back(event); // Ignore damage for a few seconds, so that the player doesn't // get damage from falling on ground m_ignore_damage_timer = 3.0; } else if(command == TOCLIENT_PLAYERITEM) { std::string datastring((char*)&data[2], datasize-2); std::istringstream is(datastring, std::ios_base::binary); u16 count = readU16(is); for (u16 i = 0; i < count; ++i) { u16 peer_id = readU16(is); Player *player = m_env.getPlayer(peer_id); if (player == NULL) { infostream<<"Client: ignoring player item " << deSerializeString(is) << " for non-existing peer id " << peer_id << std::endl; continue; } else if (player->isLocal()) { infostream<<"Client: ignoring player item " << deSerializeString(is) << " for local player" << std::endl; continue; } else { InventoryList *inv = player->inventory.getList("main"); std::string itemstring(deSerializeString(is)); if (itemstring.empty()) { inv->deleteItem(0); infostream <<"Client: empty player item for peer " << peer_id << std::endl; } else { std::istringstream iss(itemstring); delete inv->changeItem(0, InventoryItem::deSerialize(iss)); infostream<<"Client: player item for peer " << peer_id << ": "; player->getWieldItem()->serialize(infostream); infostream<<std::endl; } } } } else if(command == TOCLIENT_DEATHSCREEN) { std::string datastring((char*)&data[2], datasize-2); std::istringstream is(datastring, std::ios_base::binary); bool set_camera_point_target = readU8(is); v3f camera_point_target = readV3F1000(is); ClientEvent event; event.type = CE_DEATHSCREEN; event.deathscreen.set_camera_point_target = set_camera_point_target; event.deathscreen.camera_point_target_x = camera_point_target.X; event.deathscreen.camera_point_target_y = camera_point_target.Y; event.deathscreen.camera_point_target_z = camera_point_target.Z; m_client_event_queue.push_back(event); } else { infostream<<"Client: Ignoring unknown command " <<command<<std::endl; } }