void testvector() { std::vector<boost::shared_ptr<A> > v(10); A *pA = new A(); A *pB = new A(); boost::shared_ptr<A> sp1(pA); boost::shared_ptr<A> sp2(pB); std::cout<<"The Smartptr now has "<<sp1.use_count()<<" references\n"; v[0] = sp1; std::cout<<"The Smartptr now has "<<sp1.use_count()<<" references\n"; std::vector<boost::shared_ptr<A> > ::iterator k = v.begin(); //v.erase(k);//删除第一个元素 //v.pop_back(); v[0] = sp2; std::cout<<"The Smartptr now has "<<sp1.use_count()<<" references\n"; // std::cout<<"vertor size :"<<v.len()<<" references\n"; }
void testmap() { std::map<std::string, boost::shared_ptr<A> > m; A *pA = new A(); A *pB = new A(); boost::shared_ptr<A> sp1(pA); boost::shared_ptr<A> sp2(pB); std::cout<<"The Smartptr now has "<<sp1.use_count()<<" references\n"; m["1"] = sp1; std::cout<<"The Smartptr now has "<<sp1.use_count()<<" references\n"; // std::vector<boost::shared_ptr<A> > ::iterator k = v.begin(); //v.erase(k);//删除第一个元素 //v.pop_back(); //v[0] = sp2; m["1"] = SMART_PTR_NULL_A; std::cout<<"The Smartptr now has "<<sp1.use_count()<<" references\n"; // std::cout<<"vertor size :"<<v.len()<<" references\n"; m["1"] = sp1; std::cout<<"The Smartptr now has "<<sp1.use_count()<<" references\n"; }
int main() { srand(std::time(0)); try { Span sp = Span(5); sp.addNumber(5); sp.addNumber(3); sp.addNumber(17); sp.addNumber(9); sp.addNumber(11); std::cout << sp.shortestSpan() << std::endl; std::cout << sp.longestSpan() << std::endl; Span big(10000); big.initAll(randNumber); std::cout << big.shortestSpan() << std::endl; std::cout << big.longestSpan() << std::endl; Span sp2(1); std::cout << sp2.shortestSpan() << std::endl; } catch (std::exception & e) { std::cout << e.what() << std::endl; } }
void step(float dtime, bool send_recommended) { ScopeProfiler sp2(g_profiler, "step avg", SPT_AVG); assert(m_env); const float interval = 0.2; if(m_move_interval.step(dtime, interval)==false) return; dtime = interval; core::aabbox3d<f32> box(-BS/3.,0.0,-BS/3., BS/3.,BS*2./3.,BS/3.); collisionMoveResult moveresult; // Apply gravity m_speed_f += v3f(0, -dtime*9.81*BS, 0); // Maximum movement without glitches f32 pos_max_d = BS*0.25; // Limit speed if(m_speed_f.getLength()*dtime > pos_max_d) m_speed_f *= pos_max_d / (m_speed_f.getLength()*dtime); v3f pos_f = getBasePosition(); v3f pos_f_old = pos_f; v3f accel_f = v3f(0,0,0); f32 stepheight = 0; IGameDef *gamedef = m_env->getGameDef(); moveresult = collisionMoveSimple(&m_env->getMap(), gamedef, pos_max_d, box, stepheight, dtime, pos_f, m_speed_f, accel_f); if(send_recommended == false) return; if(pos_f.getDistanceFrom(m_last_sent_position) > 0.05*BS) { setBasePosition(pos_f); m_last_sent_position = pos_f; std::ostringstream os(std::ios::binary); // command (0 = update position) writeU8(os, 0); // pos writeV3F1000(os, m_base_position); // create message and add to list ActiveObjectMessage aom(getId(), false, os.str()); m_messages_out.push_back(aom); } if(m_itemstring_changed) { m_itemstring_changed = false; std::ostringstream os(std::ios::binary); // command (1 = update itemstring) writeU8(os, 1); // itemstring os<<serializeString(m_itemstring); // create message and add to list ActiveObjectMessage aom(getId(), false, os.str()); m_messages_out.push_back(aom); } }
/** * \brief Render the players oxygen. * \param e (out) The scene elements. */ void ptb::throwable_item_component::render( scene_element_list& e ) const { bear::visual::coordinate_type pos_y = height() / 2; bear::visual::scene_sprite s1 ( get_render_position().x, ( pos_y - m_throwable_item_animation.get_sprite().height() ) / 2 + get_render_position().y, m_throwable_item_animation.get_sprite()); bear::visual::scene_writing s2 ( get_render_position().x + m_throwable_item_animation.get_max_size().x + s_margin, ( pos_y - m_throwable_item.get_height() ) / 2 + get_render_position().y , m_throwable_item ); e.push_back( s1 ); e.push_back( s2 ); floating_bonus_list::const_iterator it; for ( it = m_floating_bonus.begin(); it != m_floating_bonus.end(); ++it ) { bear::visual::scene_sprite sp2 ( it->get_position().x, it->get_position().y, get_level_globals().auto_sprite( "gfx/ui/ui-1.png", it->get_name() )); e.push_back( sp2 ); } } // throwable_item_component::render()
int main(int, const char * []) { IloEnv env; try { IloIntVarArray x(env); for (IloInt i = 0; i < 10; i++) { char name[6]; sprintf(name, "X%ld", i); x.add(IloIntVar(env, 0, 100 - 2*(i / 2), name)); } IloModel mdl(env); mdl.add(IloAllDiff(env, x)); mdl.add(x); IloIntVarChooser varChooser = ChooseSmallestCentroid(env); IloIntValueChooser valChooser = ChooseSmallestDistanceFromCentroid(env); IloSearchPhase sp1(env, x, varChooser, valChooser); IloIntVarEval varEval = Centroid(env); IloIntValueEval valEval = DistanceFromCentroid(env); IloSearchPhase sp2(env, x, IloSelectSmallest(varEval), IloSelectSmallest(valEval)); // sp2 can have ties as two variable or values could evaluate // to the same values. sp3 shows how to break these ties // choosing, for equivalent centroid and distance-to-centroid // evaluations, the lowest indexed variable in x and the // lowest value. IloVarSelectorArray selVar(env); selVar.add(IloSelectSmallest(varEval)); selVar.add(IloSelectSmallest(IloVarIndex(env, x))); // break ties on index IloValueSelectorArray selValue(env); selValue.add(IloSelectSmallest(valEval)); selValue.add(IloSelectSmallest(IloValue(env))); // break ties on smallest IloSearchPhase sp3(env, x, selVar, selValue); IloCP cp(mdl); cp.setParameter(IloCP::Workers, 1); cp.setParameter(IloCP::SearchType, IloCP::DepthFirst); cp.setParameter(IloCP::LogPeriod, 1); cp.out() << "Choosers" << std::endl; cp.solve(sp1); cp.out() << cp.domain(x) << std::endl; cp.out() << "Evaluators" << std::endl; cp.solve(sp2); cp.out() << cp.domain(x) << std::endl; cp.out() << "Evaluators (with tie-break)" << std::endl; cp.solve(sp3); cp.out() << cp.domain(x) << std::endl; cp.end(); } catch (IloException & ex) { env.out() << "Caught: " << ex << std::endl; } env.end(); return 0; }
static void BM_SharedPtrIncDecRef(benchmark::State& st) { auto sp = std::make_shared<int>(42); benchmark::DoNotOptimize(sp.get()); while (st.KeepRunning()) { std::shared_ptr<int> sp2(sp); benchmark::ClobberMemory(); } }
/* main entry */ submain(int argc, char **argv) { int c; /* get command line options */ while ((c = getopt(argc, argv, "?")) != EOF) { /* get options */ switch (c) { case '?': /* help message */ usage(argv[0]); return(0); default: /* error */ ERROR("invalid option.", EINVAL); usage(argv[0]); return(2); } } /* check if spectra and output file were given */ if ((optind + 3) > argc) { ERROR("missing spectrum or output file.", EINVAL); usage(argv[0]); return(2); } /* create spectra */ Spectrum sp1(argv[optind]); if ((errno = sp1.getStatus()) != OK) { ERRORS("spectrum constructor failed for spectrum.", argv[optind], errno); exit(2); } Spectrum sp2(argv[optind+1]); if ((errno = sp2.getStatus()) != OK) { ERRORS("spectrum constructor failed for spectrum.", argv[optind+1], errno); exit(2); } /* do correlation */ Spectrum corrsp = correlation(sp1, sp2); /* write out spectrum */ corrsp.writeSpectrum(argv[optind+2]); /* all done */ return(0); }
void ItemSAO::step(float dtime, bool send_recommended) { ScopeProfiler sp2(g_profiler, "ItemSAO::step avg", SPT_AVG); assert(m_env); const float interval = 0.2; if(m_move_interval.step(dtime, interval)==false) return; dtime = interval; core::aabbox3d<f32> box(-BS/3.,0.0,-BS/3., BS/3.,BS*2./3.,BS/3.); collisionMoveResult moveresult; // Apply gravity m_speed_f += v3f(0, -dtime*9.81*BS, 0); // Maximum movement without glitches f32 pos_max_d = BS*0.25; // Limit speed if(m_speed_f.getLength()*dtime > pos_max_d) m_speed_f *= pos_max_d / (m_speed_f.getLength()*dtime); v3f pos_f = getBasePosition(); v3f pos_f_old = pos_f; IGameDef *gamedef = m_env->getGameDef(); moveresult = collisionMoveSimple(&m_env->getMap(), gamedef, pos_max_d, box, dtime, pos_f, m_speed_f); if(send_recommended == false) return; if(pos_f.getDistanceFrom(m_last_sent_position) > 0.05*BS) { setBasePosition(pos_f); m_last_sent_position = pos_f; std::ostringstream os(std::ios::binary); char buf[6]; // command (0 = update position) buf[0] = 0; os.write(buf, 1); // pos writeS32((u8*)buf, m_base_position.X*1000); os.write(buf, 4); writeS32((u8*)buf, m_base_position.Y*1000); os.write(buf, 4); writeS32((u8*)buf, m_base_position.Z*1000); os.write(buf, 4); // create message and add to list ActiveObjectMessage aom(getId(), false, os.str()); m_messages_out.push_back(aom); } }
// Render radioitem bullet. void ClsXPMenu::RenderRadioBullet( ClsDC *pDC, ClsRect& rcRect, COLORREF crColor, DWORD dwItemState ) { // Snapshot... int sDC = pDC->SaveDC(); // Make ellipse rectangle. ClsRect rc = rcRect; rc.Right() = rc.Left() + 12; rc.Bottom() = rc.Top() + 12; rc.Offset( rcRect.Width() / 2 - 6, rcRect.Height() / 2 - 6 ); // Create GDI objects for unchecked radio-button. ClsPen p( PS_SOLID, 0, XPColors.GetXPColor( ClsXPColors::XPC_IMAGE_DISABLED )); ClsBrush b( XPColors.GetXPColor( ClsXPColors::XPC_TEXT_BACKGROUND )); // Brace the code so that the ClsSelector objects // go out of scope before the device context // is restored. { // Select brush and pen. ClsSelector sb( pDC, b ); ClsSelector sp( pDC, p ); // Render first ellipse... This yields better // results than the Ellipse() method... pDC->RoundRect( rc.Left(), rc.Top(), rc.Right(), rc.Bottom(), 11, 11 ); // Deflate rectangle by three pixels. rc.Deflate( 3, 3 ); // Checked? if ( dwItemState & ODS_CHECKED ) { // Destroy current GDI objects and create new // ones for the inner ellipse. b.Delete(); p.Delete(); b.CreateSolidBrush( crColor ); p.CreatePen( PS_SOLID, 1, crColor ); // Select them in the DC. ClsSelector sb2( pDC, b ); ClsSelector sp2( pDC, p ); // Rendert the ellipse. pDC->RoundRect( rc.Left(), rc.Top(), rc.Right(), rc.Bottom(), rc.Width() - 1, rc.Width() - 1 ); } } // Restore original content. pDC->RestoreDC( sDC ); }
TEST(Test, Correction) { StringPiece s1(g_s1, sizeof(g_s1) - 1); StringPiece s2(g_s2, sizeof(g_s2) - 1); StringPiece sp1(g_s1, sizeof(g_s1) - 1); StringPiece sp2(g_s2, sizeof(g_s2) - 1); EXPECT_EQ(s1 == s2, sp1 == sp2); EXPECT_EQ(s1 != s2, sp1 != sp2); EXPECT_EQ(s1 < s2, sp1 < sp2); EXPECT_EQ(s1 <= s2, sp1 <= sp2); EXPECT_EQ(s1 > s2, sp1 > sp2); EXPECT_EQ(s1 >= s2, sp1 >= sp2); }
void OpenSteer::SharedPointerTest::testAssignment() { // Testing assignment of shared pointers pointing to 0. { SharedPointer< SharedPointerTester< 0 > > sp0; SharedPointer< SharedPointerTester< 0 > > sp1( sp0 ); CPPUNIT_ASSERT( 0 == sp0.get() ); CPPUNIT_ASSERT( 0 == sp1.get() ); } CPPUNIT_ASSERT_EQUAL( 0, SharedPointerTester< 0 >::static_counter_ ); // Testing assignment to a shared pointer holding 0. { SharedPointerTester< 0 >* rawPointer = new SharedPointerTester< 0 >(); SharedPointer< SharedPointerTester< 0 > > sp0; SharedPointer< SharedPointerTester< 0 > > sp1( rawPointer ); SharedPointer< SharedPointerTester< 0 > > sp2( sp0 ); sp0 = sp1; CPPUNIT_ASSERT( 2 == sp0.useCount() ); CPPUNIT_ASSERT( 2 == sp1.useCount() ); CPPUNIT_ASSERT_EQUAL( rawPointer, sp0.get() ); CPPUNIT_ASSERT_EQUAL( rawPointer, sp1.get() ); CPPUNIT_ASSERT( 0 == sp2.get() ); } CPPUNIT_ASSERT_EQUAL( 0, SharedPointerTester< 0 >::static_counter_ ); // Testing assignment that should lead to a destruction. { SharedPointerTester< 0 >* rawPointer0 = new SharedPointerTester< 0 >(); SharedPointerTester< 0 >* rawPointer1 = new SharedPointerTester< 0 >(); CPPUNIT_ASSERT_EQUAL( 2, SharedPointerTester< 0 >::static_counter_ ); SharedPointer< SharedPointerTester< 0 > > sp0( rawPointer0 ); SharedPointer< SharedPointerTester< 0 > > sp1( rawPointer1 ); sp1 = sp0; CPPUNIT_ASSERT_EQUAL( 1, SharedPointerTester< 0 >::static_counter_ ); CPPUNIT_ASSERT( 2 == sp0.useCount() ); CPPUNIT_ASSERT( 2 == sp1.useCount() ); CPPUNIT_ASSERT_EQUAL( rawPointer0, sp0.get() ); CPPUNIT_ASSERT_EQUAL( rawPointer0, sp1.get() ); } CPPUNIT_ASSERT_EQUAL( 0, SharedPointerTester< 0 >::static_counter_ ); }
static int main_v() { a_template<int> sp1 = new int; a_template<B> sp2(new B); //the presence of this call, has no influence on whether the template using int implements the method sp2.optionalCompiledMethod(); //sp1.optionalCompiledMethod(); //this will give a compile error, because it forces the template to implement the method which uses a member function that int doesn't have std::cout << "press enter to close" << std::endl; std::cin.get(); return 0; }
float calVelUpdateStepLen(const FwiParams ¶ms, const float *wlt, const float *dobs, const float *derr, float epsil, const EnquistAbc2d &fmMethod, const ShotPosition &allSrcPos, const ShotPosition &allGeoPos ) { int nt = params.nt; int nz = params.nz; int nx = params.nx; int ng = params.ng; int ns = params.ns; std::vector<float> dcal(ng, 0); /* calculated/synthetic seismic data */ std::vector<float> sp0(nz * nx); /* source wavefield p0 */ std::vector<float> sp1(nz * nx); /* source wavefield p1 */ std::vector<float> sp2(nz * nx); /* source wavefield p2 */ std::vector<float> alpha1(ng, 0); /* numerator of alpha, length=ng */ std::vector<float> alpha2(ng, 0); /* denominator of alpha, length=ng */ for (int is = 0; is < ns; is++) { std::fill(sp0.begin(), sp0.end(), 0); std::fill(sp1.begin(), sp1.end(), 0); ShotPosition currSrcPos = allSrcPos.clip(is); for (int it = 0; it < nt; it++) { fmMethod.addSource(&sp1[0], &wlt[it], currSrcPos); fmMethod.stepForward(&sp0[0], &sp1[0], &sp2[0]); cycleSwap(sp0, sp1, sp2); fmMethod.recordSeis(&dcal[0], &sp0[0], allGeoPos); sum_alpha12(&alpha1[0], &alpha2[0], &dcal[0], &dobs[is * nt * ng + it * ng], &derr[is * ng * nt + it * ng], ng); } } float alpha = cal_alpha(&alpha1[0], &alpha2[0], epsil, ng); return alpha; }
int main() { iset data; spi sp0(new int(0)); spi sp1(new int(1)); spi sp2(new int(2)); spi sp3(sp1); spi sp4(new int(1)); data.insert(sp0); data.insert(sp1); data.insert(sp2); lookup(data, sp1); lookup(data, sp3); lookup(data, sp4); return 0; }
SetPartition CCPivot::Run(const SetPartitionVector& SPV) { srand((unsigned)time(NULL)); SetPartition sp(_Run(SPV)); int mindist = SPV.SumOfRandDistance(sp); for (int i = 0; i < 49; ++i) { SetPartition sp2(_Run(SPV)); int d = SPV.SumOfRandDistance(sp2); if (d < mindist) { mindist = d; sp = sp2; } } return sp; }
void SharedPtr() { struct Object { Object() { std::cout << "(Object ctor) " << std::flush; } ~Object() { std::cout << "(Object dtor) " << std::flush; } }; outHeader("shared_ptr"); outIdent(); std::cout << "(Creating Object) " << std::flush; std::shared_ptr<Object> sp(new Object); { std::cout << "(1st Sharing Object ownership) " << std::flush; std::shared_ptr<Object> sp2(sp); { std::cout << "(2nd Sharing Object ownership) " << std::flush; std::shared_ptr<Object> sp3(sp); } } std::cout << std::endl; }
/* Method swap() : exchange the content of the shared pointers. * not empty * not empty * is empty */ int main() { std::tr1::shared_ptr<std::string> sp1; std::tr1::shared_ptr<std::string> sp2(new std::string("demo")); PtrUtil::is_empty(sp1); PtrUtil::is_empty(sp2); sp1.swap(sp2); PtrUtil::is_empty(sp1); PtrUtil::is_empty(sp2); return 0; }
//------------------------------------------------------------------------- void StartingPolynomialTest::TestAllMethods() //------------------------------------------------------------------------- { /** scale operation*/ // StartingPolynomial<Degree> StartingPolynomial<Degree>::scale(const double& s) const StartingPolynomial<1> sp1; sp1.start = 50; StartingPolynomial<1> s1 = sp1.scale(2); CPPUNIT_ASSERT(s1.start == sp1.start*2); /** shift operation*/ // StartingPolynomial<Degree> StartingPolynomial<Degree>::shift(const double& s) const StartingPolynomial<1> sp2(sp1); StartingPolynomial<1> s2 = sp2.shift(10); CPPUNIT_ASSERT(s2.start == sp2.start+10); }
void testcopy() { A *pA = new A(); A *pB = new A(); boost::shared_ptr<A> sp1(pA); boost::shared_ptr<A> sp2(pB); boost::shared_ptr<A> sp3; std::cout<<"testcopy The Smartptr now has "<<sp1.use_count()<<" references\n"; sp3= sp1; std::cout<<"testcopy The Smartptr now has "<<sp1.use_count()<<" references\n"; //sp3= sp2; std::cout<<"testcopy The Smartptr now has "<<sp1.use_count()<<" references\n"; }
//Create a triangle that contains all other vertices Triangle createSuperTriangle(const std::vector<Vector2>& vertices) { float M = vertices[0].mX; //Get max X and Y for (std::vector<Vector2>::const_iterator it = vertices.begin(); it != vertices.end(); ++it) { float xAbs = fabs(it->mX); float yAbs = fabs(it->mY); if (xAbs > M) M = xAbs; if (yAbs > M) M = yAbs; } //Create super triangle Vector2 sp1(10 * M, 0); Vector2 sp2(0, 10 * M); Vector2 sp3(-10 * M, -10 * M); return Triangle(sp1, sp2, sp3); }
/** * \brief Render the players oxygen. * \param e (out) The scene elements. */ void ptb::corrupting_bonus_component::render( scene_element_list& e ) const { if ( m_corrupting_bonus.empty() ) return; bear::universe::position_type pos(get_render_position()); bear::visual::scene_sprite sp( 0, 0, m_corrupting_bonus.get_sprite() ); //sp.set_scale_factor(m_corrupting_bonus_scale, m_corrupting_bonus_scale); sp.set_position ( pos.x + (m_corrupting_bonus.width() - sp.get_bounding_box().width()) / 2, pos.y + (height() - sp.get_bounding_box().height()) / 2 ); e.push_back( sp ); pos.x += m_corrupting_bonus.width() + s_margin; bear::visual::scene_writing s( 0, 0, m_text_corrupting_bonus ); //s.set_scale_factor(m_corrupting_bonus_scale, m_corrupting_bonus_scale); s.set_position ( pos.x + ( m_text_corrupting_bonus.get_width() - s.get_bounding_box().width() ) / 2, pos.y + (height() - s.get_bounding_box().height()) / 2 ); e.push_back( s ); floating_corrupting_bonus_list::const_iterator it; for ( it = m_floating_corrupting_bonus.begin(); it != m_floating_corrupting_bonus.end(); ++it ) { bear::visual::scene_sprite sp2 ( it->get_position().x, it->get_position().y, m_corrupting_bonus.get_sprite() ); e.push_back( sp2 ); } } // corrupting_bonus_component::render()
void testSharePtrFree() { SharedPtr<int,Free<int>> sp1((int *)malloc(sizeof(int)*10)); SharedPtr<int,Free<int>> sp2(sp1); }
void testSharePtrDelete() { SharedPtr<int> sp1(new int(5)); SharedPtr<int> sp2(sp1); }
void FireflySAO::step(float dtime, bool send_recommended) { ScopeProfiler sp2(g_profiler, "FireflySAO::step avg", SPT_AVG); assert(m_env); if(m_is_active == false) { if(m_inactive_interval.step(dtime, 0.5)==false) return; } /* The AI */ // Apply (less) gravity m_speed_f.Y -= dtime*3*BS; /* Move around if some player is close */ bool player_is_close = false; // Check connected players core::list<Player*> players = m_env->getPlayers(true); core::list<Player*>::Iterator i; for(i = players.begin(); i != players.end(); i++) { Player *player = *i; v3f playerpos = player->getPosition(); if(m_base_position.getDistanceFrom(playerpos) < BS*10.0) { player_is_close = true; break; } } m_is_active = player_is_close; if(player_is_close == false) { m_speed_f.X = 0; m_speed_f.Z = 0; } else { // Move around v3f dir(cos(m_yaw/180*PI),0,sin(m_yaw/180*PI)); f32 speed = BS/2; m_speed_f.X = speed * dir.X; m_speed_f.Z = speed * dir.Z; if(m_touching_ground && (m_oldpos - m_base_position).getLength() < dtime*speed/2) { m_counter1 -= dtime; if(m_counter1 < 0.0) { m_counter1 += 1.0; m_speed_f.Y = 5.0*BS; } } { m_counter2 -= dtime; if(m_counter2 < 0.0) { m_counter2 += (float)(myrand()%100)/100*3.0; m_yaw += ((float)(myrand()%200)-100)/100*180; m_yaw = wrapDegrees(m_yaw); } } } m_oldpos = m_base_position; /* Move it, with collision detection */ core::aabbox3d<f32> box(-BS/3.,-BS*2/3.0,-BS/3., BS/3.,BS*4./3.,BS/3.); collisionMoveResult moveresult; // Maximum movement without glitches f32 pos_max_d = BS*0.25; // Limit speed if(m_speed_f.getLength()*dtime > pos_max_d) m_speed_f *= pos_max_d / (m_speed_f.getLength()*dtime); v3f pos_f = getBasePosition(); v3f pos_f_old = pos_f; IGameDef *gamedef = m_env->getGameDef(); moveresult = collisionMoveSimple(&m_env->getMap(), gamedef, pos_max_d, box, dtime, pos_f, m_speed_f); m_touching_ground = moveresult.touching_ground; setBasePosition(pos_f); if(send_recommended == false) return; if(pos_f.getDistanceFrom(m_last_sent_position) > 0.05*BS) { m_last_sent_position = pos_f; std::ostringstream os(std::ios::binary); // command (0 = update position) writeU8(os, 0); // pos writeV3F1000(os, m_base_position); // yaw writeF1000(os, m_yaw); // create message and add to list ActiveObjectMessage aom(getId(), false, os.str()); m_messages_out.push_back(aom); } }
void Oerkki1SAO::step(float dtime, bool send_recommended) { ScopeProfiler sp2(g_profiler, "Oerkki1SAO::step avg", SPT_AVG); assert(m_env); if(m_is_active == false) { if(m_inactive_interval.step(dtime, 0.5)==false) return; } /* The AI */ m_age += dtime; if(m_age > 120) { // Die m_removed = true; return; } m_after_jump_timer -= dtime; v3f old_speed = m_speed_f; // Apply gravity m_speed_f.Y -= dtime*9.81*BS; /* Move around if some player is close */ bool player_is_close = false; bool player_is_too_close = false; v3f near_player_pos; // Check connected players core::list<Player*> players = m_env->getPlayers(true); core::list<Player*>::Iterator i; for(i = players.begin(); i != players.end(); i++) { Player *player = *i; v3f playerpos = player->getPosition(); f32 dist = m_base_position.getDistanceFrom(playerpos); if(dist < BS*0.6) { m_removed = true; return; player_is_too_close = true; near_player_pos = playerpos; } else if(dist < BS*15.0 && !player_is_too_close) { player_is_close = true; near_player_pos = playerpos; } } m_is_active = player_is_close; v3f target_speed = m_speed_f; if(!player_is_close) { target_speed = v3f(0,0,0); } else { // Move around v3f ndir = near_player_pos - m_base_position; ndir.Y = 0; ndir.normalize(); f32 nyaw = 180./PI*atan2(ndir.Z,ndir.X); if(nyaw < m_yaw - 180) nyaw += 360; else if(nyaw > m_yaw + 180) nyaw -= 360; m_yaw = 0.95*m_yaw + 0.05*nyaw; m_yaw = wrapDegrees(m_yaw); f32 speed = 2*BS; if((m_touching_ground || m_after_jump_timer > 0.0) && !player_is_too_close) { v3f dir(cos(m_yaw/180*PI),0,sin(m_yaw/180*PI)); target_speed.X = speed * dir.X; target_speed.Z = speed * dir.Z; } if(m_touching_ground && (m_oldpos - m_base_position).getLength() < dtime*speed/2) { m_counter1 -= dtime; if(m_counter1 < 0.0) { m_counter1 += 0.2; // Jump target_speed.Y = 5.0*BS; m_after_jump_timer = 1.0; } } { m_counter2 -= dtime; if(m_counter2 < 0.0) { m_counter2 += (float)(myrand()%100)/100*3.0; //m_yaw += ((float)(myrand()%200)-100)/100*180; m_yaw += ((float)(myrand()%200)-100)/100*90; m_yaw = wrapDegrees(m_yaw); } } } if((m_speed_f - target_speed).getLength() > BS*4 || player_is_too_close) accelerate_xz(m_speed_f, target_speed, dtime*BS*8); else accelerate_xz(m_speed_f, target_speed, dtime*BS*4); m_oldpos = m_base_position; /* Move it, with collision detection */ core::aabbox3d<f32> box(-BS/3.,0.0,-BS/3., BS/3.,BS*5./3.,BS/3.); collisionMoveResult moveresult; // Maximum movement without glitches f32 pos_max_d = BS*0.25; /*// Limit speed if(m_speed_f.getLength()*dtime > pos_max_d) m_speed_f *= pos_max_d / (m_speed_f.getLength()*dtime);*/ v3f pos_f = getBasePosition(); v3f pos_f_old = pos_f; IGameDef *gamedef = m_env->getGameDef(); moveresult = collisionMovePrecise(&m_env->getMap(), gamedef, pos_max_d, box, dtime, pos_f, m_speed_f); m_touching_ground = moveresult.touching_ground; // Do collision damage float tolerance = BS*30; float factor = BS*0.5; v3f speed_diff = old_speed - m_speed_f; // Increase effect in X and Z speed_diff.X *= 2; speed_diff.Z *= 2; float vel = speed_diff.getLength(); if(vel > tolerance) { f32 damage_f = (vel - tolerance)/BS*factor; u16 damage = (u16)(damage_f+0.5); doDamage(damage); } setBasePosition(pos_f); if(send_recommended == false && m_speed_f.getLength() < 3.0*BS) return; if(pos_f.getDistanceFrom(m_last_sent_position) > 0.05*BS) { m_last_sent_position = pos_f; std::ostringstream os(std::ios::binary); // command (0 = update position) writeU8(os, 0); // pos writeV3F1000(os, m_base_position); // yaw writeF1000(os, m_yaw); // create message and add to list ActiveObjectMessage aom(getId(), false, os.str()); m_messages_out.push_back(aom); } }
void MobV2SAO::step(float dtime, bool send_recommended) { ScopeProfiler sp2(g_profiler, "MobV2SAO::step avg", SPT_AVG); assert(m_env); Map *map = &m_env->getMap(); m_age += dtime; if(m_die_age >= 0.0 && m_age >= m_die_age){ m_removed = true; return; } m_random_disturb_timer += dtime; if(m_random_disturb_timer >= 5.0) { m_random_disturb_timer = 0; // Check connected players core::list<Player*> players = m_env->getPlayers(true); core::list<Player*>::Iterator i; for(i = players.begin(); i != players.end(); i++) { Player *player = *i; v3f playerpos = player->getPosition(); f32 dist = m_base_position.getDistanceFrom(playerpos); if(dist < BS*16) { if(myrand_range(0,3) == 0){ actionstream<<"Mob id="<<m_id<<" at " <<PP(m_base_position/BS) <<" got randomly disturbed by " <<player->getName()<<std::endl; m_disturbing_player = player->getName(); m_disturb_timer = 0; break; } } } } Player *disturbing_player = m_env->getPlayer(m_disturbing_player.c_str()); v3f disturbing_player_off = v3f(0,1,0); v3f disturbing_player_norm = v3f(0,1,0); float disturbing_player_distance = 1000000; float disturbing_player_dir = 0; if(disturbing_player){ disturbing_player_off = disturbing_player->getPosition() - m_base_position; disturbing_player_distance = disturbing_player_off.getLength(); disturbing_player_norm = disturbing_player_off; disturbing_player_norm.normalize(); disturbing_player_dir = 180./PI*atan2(disturbing_player_norm.Z, disturbing_player_norm.X); } m_disturb_timer += dtime; if(!m_falling) { m_shooting_timer -= dtime; if(m_shooting_timer <= 0.0 && m_shooting){ m_shooting = false; std::string shoot_type = m_properties->get("shoot_type"); v3f shoot_pos(0,0,0); shoot_pos.Y += m_properties->getFloat("shoot_y") * BS; if(shoot_type == "fireball"){ v3f dir(cos(m_yaw/180*PI),0,sin(m_yaw/180*PI)); dir.Y = m_shoot_y; dir.normalize(); v3f speed = dir * BS * 10.0; v3f pos = m_base_position + shoot_pos; infostream<<__FUNCTION_NAME<<": Mob id="<<m_id <<" shooting fireball from "<<PP(pos) <<" at speed "<<PP(speed)<<std::endl; Settings properties; properties.set("looks", "fireball"); properties.setV3F("speed", speed); properties.setFloat("die_age", 5.0); properties.set("move_type", "constant_speed"); properties.setFloat("hp", 1000); properties.set("lock_full_brightness", "true"); properties.set("player_hit_damage", "9"); properties.set("player_hit_distance", "2"); properties.set("player_hit_interval", "1"); ServerActiveObject *obj = new MobV2SAO(m_env, pos, &properties); //m_env->addActiveObjectAsStatic(obj); m_env->addActiveObject(obj); } else { infostream<<__FUNCTION_NAME<<": Mob id="<<m_id <<": Unknown shoot_type="<<shoot_type <<std::endl; } } m_shoot_reload_timer += dtime; float reload_time = 15.0; if(m_disturb_timer <= 15.0) reload_time = 3.0; bool shoot_without_player = false; if(m_properties->getBool("mindless_rage")) shoot_without_player = true; if(!m_shooting && m_shoot_reload_timer >= reload_time && !m_next_pos_exists && (m_disturb_timer <= 60.0 || shoot_without_player)) { m_shoot_y = 0; if(m_disturb_timer < 60.0 && disturbing_player && disturbing_player_distance < 16*BS && fabs(disturbing_player_norm.Y) < 0.8){ m_yaw = disturbing_player_dir; sendPosition(); m_shoot_y += disturbing_player_norm.Y; } else { m_shoot_y = 0.01 * myrand_range(-30,10); } m_shoot_reload_timer = 0.0; m_shooting = true; m_shooting_timer = 1.5; { std::ostringstream os(std::ios::binary); // command (2 = shooting) writeU8(os, 2); // time writeF1000(os, m_shooting_timer + 0.1); // bright? writeU8(os, true); // create message and add to list ActiveObjectMessage aom(getId(), false, os.str()); m_messages_out.push_back(aom); } } } if(m_move_type == "ground_nodes") { if(!m_shooting){ m_walk_around_timer -= dtime; if(m_walk_around_timer <= 0.0){ m_walk_around = !m_walk_around; if(m_walk_around) m_walk_around_timer = 0.1*myrand_range(10,50); else m_walk_around_timer = 0.1*myrand_range(30,70); } } /* Move */ if(m_next_pos_exists){ v3f pos_f = m_base_position; v3f next_pos_f = intToFloat(m_next_pos_i, BS); v3f v = next_pos_f - pos_f; m_yaw = atan2(v.Z, v.X) / PI * 180; v3f diff = next_pos_f - pos_f; v3f dir = diff; dir.normalize(); float speed = BS * 0.5; if(m_falling) speed = BS * 3.0; dir *= dtime * speed; bool arrived = false; if(dir.getLength() > diff.getLength()){ dir = diff; arrived = true; } pos_f += dir; m_base_position = pos_f; if((pos_f - next_pos_f).getLength() < 0.1 || arrived){ m_next_pos_exists = false; } } v3s16 pos_i = floatToInt(m_base_position, BS); v3s16 size_blocks = v3s16(m_size.X+0.5,m_size.Y+0.5,m_size.X+0.5); v3s16 pos_size_off(0,0,0); if(m_size.X >= 2.5){ pos_size_off.X = -1; pos_size_off.Y = -1; } if(!m_next_pos_exists){ /* Check whether to drop down */ if(checkFreePosition(map, pos_i + pos_size_off + v3s16(0,-1,0), size_blocks)){ m_next_pos_i = pos_i + v3s16(0,-1,0); m_next_pos_exists = true; m_falling = true; } else { m_falling = false; } } if(m_walk_around) { if(!m_next_pos_exists){ /* Find some position where to go next */ v3s16 dps[3*3*3]; int num_dps = 0; for(int dx=-1; dx<=1; dx++) for(int dy=-1; dy<=1; dy++) for(int dz=-1; dz<=1; dz++){ if(dx == 0 && dy == 0) continue; if(dx != 0 && dz != 0 && dy != 0) continue; dps[num_dps++] = v3s16(dx,dy,dz); } u32 order[3*3*3]; get_random_u32_array(order, num_dps); for(int i=0; i<num_dps; i++){ v3s16 p = dps[order[i]] + pos_i; bool is_free = checkFreeAndWalkablePosition(map, p + pos_size_off, size_blocks); if(!is_free) continue; m_next_pos_i = p; m_next_pos_exists = true; break; } } } } else if(m_move_type == "constant_speed") { m_base_position += m_speed * dtime; v3s16 pos_i = floatToInt(m_base_position, BS); v3s16 size_blocks = v3s16(m_size.X+0.5,m_size.Y+0.5,m_size.X+0.5); v3s16 pos_size_off(0,0,0); if(m_size.X >= 2.5){ pos_size_off.X = -1; pos_size_off.Y = -1; } bool free = checkFreePosition(map, pos_i + pos_size_off, size_blocks); if(!free){ explodeSquare(map, pos_i, v3s16(3,3,3)); m_removed = true; return; } } else { errorstream<<"MobV2SAO::step(): id="<<m_id<<" unknown move_type=\"" <<m_move_type<<"\""<<std::endl; } if(send_recommended == false) return; if(m_base_position.getDistanceFrom(m_last_sent_position) > 0.05*BS) { sendPosition(); } }
int main(int argc, char **argv) { // Traits typedefs // {{{ // typedef ::World< ::CyclicWorldTraits<Real> > world_type; // typedef EGFRDSimulator< ::EGFRDSimulatorTraitsBase<world_type> > // simulator_type; typedef ecell4::egfrd::EGFRDWorld world_type; typedef ecell4::egfrd::EGFRDSimulator simulator_type; typedef simulator_type::multi_type multi_type; // }}} // Constants // {{{ const ecell4::Real L(1e-6); const ecell4::Real3 edge_lengths(L, L, L); const ecell4::Integer3 matrix_sizes(3, 3, 3); const ecell4::Real volume(L * L * L); const ecell4::Integer N(60); const ecell4::Real kd(0.1), U(0.5); const ecell4::Real ka(kd * volume * (1 - U) / (U * U * N)); const ecell4::Real k2(ka), k1(kd); const ecell4::Integer dissociation_retry_moves(3); // }}} boost::shared_ptr<ecell4::NetworkModel> model(new ecell4::NetworkModel()); // add ::SpeciesType to ::ParticleModel // {{{ ecell4::Species sp1( std::string("A"), std::string("2.5e-09"), std::string("1e-12")); model->add_species_attribute(sp1); ecell4::Species sp2( std::string("B"), std::string("2.5e-09"), std::string("1e-12")); model->add_species_attribute(sp2); ecell4::Species sp3( std::string("C"), std::string("2.5e-09"), std::string("1e-12")); model->add_species_attribute(sp3); // }}} // ReactionRules // {{{ // A -> B + C k1 // {{{ ecell4::ReactionRule rr1( ecell4::create_unbinding_reaction_rule(sp1, sp2, sp3, k1)); model->add_reaction_rule(rr1); // }}} // B + C -> A k2 // {{{ ecell4::ReactionRule rr2( ecell4::create_binding_reaction_rule(sp2, sp3, sp1, k2)); model->add_reaction_rule(rr2); // }}} // }}} // Random Number Generator (Instanciate and Initialize) // {{{ // boost::shared_ptr<ecell4::GSLRandomNumberGenerator> boost::shared_ptr<ecell4::RandomNumberGenerator> rng(new ecell4::GSLRandomNumberGenerator()); rng->seed((unsigned long int)0); // rng->seed(time(NULL)); // }}} // World Definition // {{{ boost::shared_ptr<world_type> world(new world_type(edge_lengths, matrix_sizes, rng)); world->bind_to(model); // }}} // add ecell4::Species( ::SpeciesInfo) to ::World // {{{ // world->add_species(ecell4::Species("A")); // world->add_species(ecell4::Species("B")); // world->add_species(ecell4::Species("C")); // }}} // Thorow particles into world at random // {{{ world->add_molecules(ecell4::Species("A"), N); typedef std::vector<std::pair<ecell4::ParticleID, ecell4::Particle> > particle_id_pair_list; const particle_id_pair_list particles(world->list_particles()); for (particle_id_pair_list::const_iterator i(particles.begin()); i != particles.end(); ++i) { const ecell4::Real3 pos((*i).second.position()); std::cout << "(" << pos[0] << pos[1] << pos[2] << ")" << std::endl; } // }}} // Logger Settings // {{{ boost::shared_ptr< ::LoggerManager> logger_mng( new ::LoggerManager("dummy", ::Logger::L_WARNING)); ::LoggerManager::register_logger_manager( "ecell.EGFRDSimulator", logger_mng); // }}} // EGFRDSimulator instance generated // {{{ boost::shared_ptr<simulator_type> sim( new simulator_type(world, model, dissociation_retry_moves)); // sim->paranoiac() = true; sim->initialize(); // }}} // Simulation Executed // {{{ ecell4::Real next_time(0.0), dt(0.02); std::cout << sim->t() << "\t" << world->num_molecules_exact(sp1) << "\t" << world->num_molecules_exact(sp2) << "\t" << world->num_molecules_exact(sp3) << "\t" << std::endl; // for (int i(0); i < 10; i++) // for (int i(0); i < 100; i++) for (int i(0); i < 100; i++) { next_time += dt; while (sim->step(next_time)) { // if (sim->last_reactions().size() > 0) // { // std::cout << sim->t() << "\t" // << world->num_molecules_exact(sp1) << "\t" // << world->num_molecules_exact(sp2) << "\t" // << world->num_molecules_exact(sp3) << "\t" << std::endl; // } } std::cout << sim->t() << "\t" << world->num_molecules_exact(sp1) << "\t" << world->num_molecules_exact(sp2) << "\t" << world->num_molecules_exact(sp3) << "\t" << std::endl; } // }}} // world->save("test.h5"); // Statistics // {{{ int num_single_steps_per_type[simulator_type::NUM_SINGLE_EVENT_KINDS]; num_single_steps_per_type[simulator_type::SINGLE_EVENT_REACTION] = sim->num_single_steps_per_type(simulator_type::SINGLE_EVENT_REACTION); num_single_steps_per_type[simulator_type::SINGLE_EVENT_ESCAPE] = sim->num_single_steps_per_type(simulator_type::SINGLE_EVENT_ESCAPE); std::cout << (boost::format("%1%: %2% \n") % "SINGLE_EVENT_REACTION" % num_single_steps_per_type[simulator_type::SINGLE_EVENT_REACTION]); std::cout << (boost::format("%1%: %2% \n") % "SINGLE_EVENT_ESCAPE" % num_single_steps_per_type[simulator_type::SINGLE_EVENT_ESCAPE]); std::cout << (boost::format("%1%: %2% \n") % "PAIR_EVENT_SINGLE_REACTION_0" % sim->num_pair_steps_per_type( simulator_type::PAIR_EVENT_SINGLE_REACTION_0)); std::cout << (boost::format("%1%: %2% \n") % "PAIR_EVENT_SINGLE_REACTION_1" % sim->num_pair_steps_per_type( simulator_type::PAIR_EVENT_SINGLE_REACTION_1)); std::cout << (boost::format("%1%: %2% \n") % "PAIR_EVENT_COM_ESCAPE" % sim->num_pair_steps_per_type(simulator_type::PAIR_EVENT_COM_ESCAPE)); std::cout << (boost::format("%1%: %2% \n") % "PAIR_EVENT_IV_UNDETERMINED" % sim->num_pair_steps_per_type( simulator_type::PAIR_EVENT_IV_UNDETERMINED)); std::cout << (boost::format("%1%: %2% \n") % "PAIR_EVENT_IV_ESCAPE" % sim->num_pair_steps_per_type(simulator_type::PAIR_EVENT_IV_ESCAPE)); std::cout << (boost::format("%1%: %2% \n") % "PAIR_EVENT_IV_REACTION" % sim->num_pair_steps_per_type(simulator_type::PAIR_EVENT_IV_REACTION)); std::cout << (boost::format("%1%: %2% \n") % "NONE" % sim->num_multi_steps_per_type(multi_type::NONE)); std::cout << (boost::format("%1%: %2% \n") % "ESCAPE" % sim->num_multi_steps_per_type(multi_type::ESCAPE)); std::cout << (boost::format("%1%: %2% \n") % "REACTION" % sim->num_multi_steps_per_type(multi_type::REACTION)); // }}} // { // boost::scoped_ptr<world_type> // world2(new world_type(ecell4::Real3(1, 2, 3), ecell4::Integer3(3, 6, 9))); // std::cout << "edge_lengths:" << world2->edge_lengths()[0] << " " << world2->edge_lengths()[1] << " " << world2->edge_lengths()[2] << std::endl; // std::cout << "matrix_sizes:" << world2->matrix_sizes()[0] << " " << world2->matrix_sizes()[1] << " " << world2->matrix_sizes()[2] << std::endl; // std::cout << "num_particles: " << world2->num_particles() << std::endl; // world2->load("test.h5"); // std::cout << "edge_lengths:" << world2->edge_lengths()[0] << " " << world2->edge_lengths()[1] << " " << world2->edge_lengths()[2] << std::endl; // std::cout << "matrix_sizes:" << world2->matrix_sizes()[0] << " " << world2->matrix_sizes()[1] << " " << world2->matrix_sizes()[2] << std::endl; // std::cout << "num_particles: " << world2->num_particles() << std::endl; // } return 0; }
collisionMoveResult collisionMoveSimple(Environment *env, IGameDef *gamedef, f32 pos_max_d, const aabb3f &box_0, f32 stepheight, f32 dtime, v3f *pos_f, v3f *speed_f, v3f accel_f, ActiveObject *self, bool collideWithObjects) { static bool time_notification_done = false; Map *map = &env->getMap(); //TimeTaker tt("collisionMoveSimple"); ScopeProfiler sp(g_profiler, "collisionMoveSimple avg", SPT_AVG); collisionMoveResult result; /* Calculate new velocity */ if (dtime > 0.5f) { if (!time_notification_done) { time_notification_done = true; infostream << "collisionMoveSimple: maximum step interval exceeded," " lost movement details!"<<std::endl; } dtime = 0.5f; } else { time_notification_done = false; } *speed_f += accel_f * dtime; // If there is no speed, there are no collisions if (speed_f->getLength() == 0) return result; // Limit speed for avoiding hangs speed_f->Y = rangelim(speed_f->Y, -5000, 5000); speed_f->X = rangelim(speed_f->X, -5000, 5000); speed_f->Z = rangelim(speed_f->Z, -5000, 5000); /* Collect node boxes in movement range */ std::vector<NearbyCollisionInfo> cinfo; { //TimeTaker tt2("collisionMoveSimple collect boxes"); ScopeProfiler sp2(g_profiler, "collisionMoveSimple collect boxes avg", SPT_AVG); v3f newpos_f = *pos_f + *speed_f * dtime; v3f minpos_f( MYMIN(pos_f->X, newpos_f.X), MYMIN(pos_f->Y, newpos_f.Y) + 0.01f * BS, // bias rounding, player often at +/-n.5 MYMIN(pos_f->Z, newpos_f.Z) ); v3f maxpos_f( MYMAX(pos_f->X, newpos_f.X), MYMAX(pos_f->Y, newpos_f.Y), MYMAX(pos_f->Z, newpos_f.Z) ); v3s16 min = floatToInt(minpos_f + box_0.MinEdge, BS) - v3s16(1, 1, 1); v3s16 max = floatToInt(maxpos_f + box_0.MaxEdge, BS) + v3s16(1, 1, 1); bool any_position_valid = false; v3s16 p; for (p.X = min.X; p.X <= max.X; p.X++) for (p.Y = min.Y; p.Y <= max.Y; p.Y++) for (p.Z = min.Z; p.Z <= max.Z; p.Z++) { bool is_position_valid; MapNode n = map->getNodeNoEx(p, &is_position_valid); if (is_position_valid && n.getContent() != CONTENT_IGNORE) { // Object collides into walkable nodes any_position_valid = true; const NodeDefManager *nodedef = gamedef->getNodeDefManager(); const ContentFeatures &f = nodedef->get(n); if (!f.walkable) continue; int n_bouncy_value = itemgroup_get(f.groups, "bouncy"); int neighbors = 0; if (f.drawtype == NDT_NODEBOX && f.node_box.type == NODEBOX_CONNECTED) { v3s16 p2 = p; p2.Y++; getNeighborConnectingFace(p2, nodedef, map, n, 1, &neighbors); p2 = p; p2.Y--; getNeighborConnectingFace(p2, nodedef, map, n, 2, &neighbors); p2 = p; p2.Z--; getNeighborConnectingFace(p2, nodedef, map, n, 4, &neighbors); p2 = p; p2.X--; getNeighborConnectingFace(p2, nodedef, map, n, 8, &neighbors); p2 = p; p2.Z++; getNeighborConnectingFace(p2, nodedef, map, n, 16, &neighbors); p2 = p; p2.X++; getNeighborConnectingFace(p2, nodedef, map, n, 32, &neighbors); } std::vector<aabb3f> nodeboxes; n.getCollisionBoxes(gamedef->ndef(), &nodeboxes, neighbors); // Calculate float position only once v3f posf = intToFloat(p, BS); for (auto box : nodeboxes) { box.MinEdge += posf; box.MaxEdge += posf; cinfo.emplace_back(false, false, n_bouncy_value, p, box); } } else { // Collide with unloaded nodes (position invalid) and loaded // CONTENT_IGNORE nodes (position valid) aabb3f box = getNodeBox(p, BS); cinfo.emplace_back(true, false, 0, p, box); } } // Do not move if world has not loaded yet, since custom node boxes // are not available for collision detection. // This also intentionally occurs in the case of the object being positioned // solely on loaded CONTENT_IGNORE nodes, no matter where they come from. if (!any_position_valid) { *speed_f = v3f(0, 0, 0); return result; } } // tt2 if(collideWithObjects) { ScopeProfiler sp2(g_profiler, "collisionMoveSimple objects avg", SPT_AVG); //TimeTaker tt3("collisionMoveSimple collect object boxes"); /* add object boxes to cinfo */ std::vector<ActiveObject*> objects; #ifndef SERVER ClientEnvironment *c_env = dynamic_cast<ClientEnvironment*>(env); if (c_env != 0) { f32 distance = speed_f->getLength(); std::vector<DistanceSortedActiveObject> clientobjects; c_env->getActiveObjects(*pos_f, distance * 1.5f, clientobjects); for (auto &clientobject : clientobjects) { if (!self || (self != clientobject.obj)) { objects.push_back((ActiveObject*) clientobject.obj); } } } else #endif { ServerEnvironment *s_env = dynamic_cast<ServerEnvironment*>(env); if (s_env != NULL) { f32 distance = speed_f->getLength(); std::vector<u16> s_objects; s_env->getObjectsInsideRadius(s_objects, *pos_f, distance * 1.5f); for (u16 obj_id : s_objects) { ServerActiveObject *current = s_env->getActiveObject(obj_id); if (!self || (self != current)) { objects.push_back((ActiveObject*)current); } } } } for (std::vector<ActiveObject*>::const_iterator iter = objects.begin(); iter != objects.end(); ++iter) { ActiveObject *object = *iter; if (object) { aabb3f object_collisionbox; if (object->getCollisionBox(&object_collisionbox) && object->collideWithObjects()) { cinfo.emplace_back(false, true, 0, v3s16(), object_collisionbox); } } } } //tt3 /* Collision detection */ /* Collision uncertainty radius Make it a bit larger than the maximum distance of movement */ f32 d = pos_max_d * 1.1f; // A fairly large value in here makes moving smoother //f32 d = 0.15*BS; // This should always apply, otherwise there are glitches assert(d > pos_max_d); // invariant int loopcount = 0; while(dtime > BS * 1e-10f) { //TimeTaker tt3("collisionMoveSimple dtime loop"); ScopeProfiler sp2(g_profiler, "collisionMoveSimple dtime loop avg", SPT_AVG); // Avoid infinite loop loopcount++; if (loopcount >= 100) { warningstream << "collisionMoveSimple: Loop count exceeded, aborting to avoid infiniite loop" << std::endl; break; } aabb3f movingbox = box_0; movingbox.MinEdge += *pos_f; movingbox.MaxEdge += *pos_f; int nearest_collided = -1; f32 nearest_dtime = dtime; int nearest_boxindex = -1; /* Go through every nodebox, find nearest collision */ for (u32 boxindex = 0; boxindex < cinfo.size(); boxindex++) { const NearbyCollisionInfo &box_info = cinfo[boxindex]; // Ignore if already stepped up this nodebox. if (box_info.is_step_up) continue; // Find nearest collision of the two boxes (raytracing-like) f32 dtime_tmp; int collided = axisAlignedCollision(box_info.box, movingbox, *speed_f, d, &dtime_tmp); if (collided == -1 || dtime_tmp >= nearest_dtime) continue; nearest_dtime = dtime_tmp; nearest_collided = collided; nearest_boxindex = boxindex; } if (nearest_collided == -1) { // No collision with any collision box. *pos_f += *speed_f * dtime; dtime = 0; // Set to 0 to avoid "infinite" loop due to small FP numbers } else { // Otherwise, a collision occurred. NearbyCollisionInfo &nearest_info = cinfo[nearest_boxindex]; const aabb3f& cbox = nearest_info.box; // Check for stairs. bool step_up = (nearest_collided != 1) && // must not be Y direction (movingbox.MinEdge.Y < cbox.MaxEdge.Y) && (movingbox.MinEdge.Y + stepheight > cbox.MaxEdge.Y) && (!wouldCollideWithCeiling(cinfo, movingbox, cbox.MaxEdge.Y - movingbox.MinEdge.Y, d)); // Get bounce multiplier float bounce = -(float)nearest_info.bouncy / 100.0f; // Move to the point of collision and reduce dtime by nearest_dtime if (nearest_dtime < 0) { // Handle negative nearest_dtime (can be caused by the d allowance) if (!step_up) { if (nearest_collided == 0) pos_f->X += speed_f->X * nearest_dtime; if (nearest_collided == 1) pos_f->Y += speed_f->Y * nearest_dtime; if (nearest_collided == 2) pos_f->Z += speed_f->Z * nearest_dtime; } } else { *pos_f += *speed_f * nearest_dtime; dtime -= nearest_dtime; } bool is_collision = true; if (nearest_info.is_unloaded) is_collision = false; CollisionInfo info; if (nearest_info.is_object) info.type = COLLISION_OBJECT; else info.type = COLLISION_NODE; info.node_p = nearest_info.position; info.old_speed = *speed_f; // Set the speed component that caused the collision to zero if (step_up) { // Special case: Handle stairs nearest_info.is_step_up = true; is_collision = false; } else if (nearest_collided == 0) { // X if (fabs(speed_f->X) > BS * 3) speed_f->X *= bounce; else speed_f->X = 0; result.collides = true; } else if (nearest_collided == 1) { // Y if(fabs(speed_f->Y) > BS * 3) speed_f->Y *= bounce; else speed_f->Y = 0; result.collides = true; } else if (nearest_collided == 2) { // Z if (fabs(speed_f->Z) > BS * 3) speed_f->Z *= bounce; else speed_f->Z = 0; result.collides = true; } info.new_speed = *speed_f; if (info.new_speed.getDistanceFrom(info.old_speed) < 0.1f * BS) is_collision = false; if (is_collision) { result.collisions.push_back(info); } } } /* Final touches: Check if standing on ground, step up stairs. */ aabb3f box = box_0; box.MinEdge += *pos_f; box.MaxEdge += *pos_f; for (const auto &box_info : cinfo) { const aabb3f &cbox = box_info.box; /* See if the object is touching ground. Object touches ground if object's minimum Y is near node's maximum Y and object's X-Z-area overlaps with the node's X-Z-area. Use 0.15*BS so that it is easier to get on a node. */ if (cbox.MaxEdge.X - d > box.MinEdge.X && cbox.MinEdge.X + d < box.MaxEdge.X && cbox.MaxEdge.Z - d > box.MinEdge.Z && cbox.MinEdge.Z + d < box.MaxEdge.Z) { if (box_info.is_step_up) { pos_f->Y += cbox.MaxEdge.Y - box.MinEdge.Y; box = box_0; box.MinEdge += *pos_f; box.MaxEdge += *pos_f; } if (std::fabs(cbox.MaxEdge.Y - box.MinEdge.Y) < 0.15f * BS) { result.touching_ground = true; if (box_info.is_object) result.standing_on_object = true; } } } return result; }
void LinearSMCimproved::predictionPerturbation(const SiconosVector& xTk, SimpleMatrix& CBstar) { if (_us->normInf() < _alpha) { if (_inDisceteTimeSlidingPhase) { SiconosVector& up = *_up; if (_measuredPert->full()) { if (_measuredPert->size() > 1) { _measuredPert->rotate(_measuredPert->end()-1); _predictedPert->rotate(_predictedPert->end()-1); } } else { // inject new vector in the case where the measurement vector is not full. SP::SiconosVector sp1(new SiconosVector(_us->size(), 0)); SP::SiconosVector sp2(new SiconosVector(_us->size(), 0)); _measuredPert->push_front(sp1); _predictedPert->push_front(sp2); } // inject new measured value and also perturbation prediction SiconosVector& predictedPertC = *(*_predictedPert)[0]; SiconosVector& measuredPertC = *(*_measuredPert)[0]; // Cp_k = s_k + Cp_k-tilde prod(*_Csurface, xTk, measuredPertC); measuredPertC += *(*_predictedPert)[std::min((unsigned int)1, (unsigned int)_predictedPert->size()-1)]; // compute prediction switch(_measuredPert->size()-1) { case 0: predictedPertC = measuredPertC; break; case 1: predictedPertC = 2*measuredPertC - *(*_measuredPert)[1]; break; case 2: predictedPertC = 3*measuredPertC - 3*(*(*_measuredPert)[1]) + *(*_measuredPert)[2]; break; default: RuntimeException::selfThrow("LinearSMCimproved::predictionPerturbation: unknown order " + _measuredPert->size()); } // Compute the control to counteract the perturbation up = predictedPertC; up *= -1; CBstar.PLUForwardBackwardInPlace(up); // project onto feasible set double norm = up.norm2(); if (norm > _ubPerturbation) { up *= _ubPerturbation/norm; predictedPertC *= _ubPerturbation/norm; } } else _inDisceteTimeSlidingPhase = true; } else if (_inDisceteTimeSlidingPhase) { _inDisceteTimeSlidingPhase = false; _up->zero(); } }