Attached is patch which has all of my optimisations from yesterday and today.
src/character/character.cpp: This change is not in finished form, but just to test the effect if FootsInVacuum wasn't calculated two times for every cycle. Gain is very noticeable. To finish it, FootsInVacuum result should be saved and served until next frame or tick. src/character/body.cpp: Here we don't animate if character is not visible. Gain is very noticeable, but might cause some problems with animations. Apparently MustBeDrawn isn't perfectly good to detect if character is visible or not. member->RefreshSprite() is limited in same way and gain is also good. Not sure about side effects. src/object/physical_obj.h/cpp Discussed with Kurosu on IRC. MeterDistance is surprisingly costly function. src/graphic/sprite.cpp: This was biggest user of software division after MeterDistance and it save a few cycles. Here is a call graph, nodes with >3.0% of time are shown http://img838.imageshack.us/img838/8206/callgraph9.png
Index: src/character/character.h =================================================================== --- src/character/character.h (revision 8358) +++ src/character/character.h (working copy) @@ -96,7 +96,6 @@ Body* body; private: - bool MustBeDrawn() const; bool MustDrawLostEnergy() const; bool MustDrawEnergyBar() const; bool MustDrawName() const; @@ -123,6 +122,7 @@ bool ComputeHeightMovement(int & height); public: + bool MustBeDrawn() const; Character (Team& my_team, const std::string &name, Body *char_body); Character (const Character& acharacter); ~Character(); Index: src/character/character.cpp =================================================================== --- src/character/character.cpp (revision 8358) +++ src/character/character.cpp (working copy) @@ -607,7 +607,7 @@ Time * global_time = Time::GetInstance(); - // center on character who is falling +/* // center on character who is falling if (FootsInVacuum()) { bool closely = false; if (IsActiveCharacter() && @@ -616,7 +616,7 @@ closely = true; Camera::GetInstance()->FollowObject(this, closely); } - +*/ if (IsDiseased()) { Point2i bubble_pos = GetPosition(); Index: src/character/body.cpp =================================================================== --- src/character/body.cpp (revision 8358) +++ src/character/body.cpp (working copy) @@ -457,6 +457,7 @@ { // Increase frame number if needed unsigned int last_frame = current_frame; + bool visible = owner->MustBeDrawn(); if (walking || current_mvt->GetType() != "walk") { @@ -498,7 +499,8 @@ ResetMovement(); ApplySqueleton(); - ApplyMovement(current_mvt, current_frame); + if (visible) + ApplyMovement(current_mvt, current_frame); int layersCount = (int)current_clothe->GetLayers().size(); @@ -530,7 +532,8 @@ body_mvt.pos.y = GetSize().y - y_max + current_mvt->GetTestBottom(); body_mvt.pos.x = ONE_HALF*(GetSize().x - skel_lst.front()->member->GetSprite().GetWidth()); body_mvt.SetAngle(main_rotation_rad); - skel_lst.front()->member->ApplyMovement(body_mvt, skel_lst); + if (visible) + skel_lst.front()->member->ApplyMovement(body_mvt, skel_lst); need_rebuild = false; } @@ -539,11 +542,12 @@ { Member* member; int layersCount = (int)current_clothe->GetLayers().size(); + bool visible = owner->MustBeDrawn(); for (int layer=0; layer < layersCount; layer++) { member = current_clothe->GetLayers()[layer]; - if ("weapon" != member->GetName()) { + if ("weapon" != member->GetName() && visible) { member->RefreshSprite(direction); } } Index: src/object/physical_obj.cpp =================================================================== --- src/object/physical_obj.cpp (revision 8358) +++ src/object/physical_obj.cpp (working copy) @@ -49,11 +49,6 @@ const int Y_OBJET_MIN = -10000; -Double MeterDistance(const Point2i &p1, const Point2i &p2) -{ - return p1.Distance(p2) / PIXEL_PER_METER; -} - PhysicalObj::PhysicalObj (const std::string &name, const std::string &xml_config) : m_collides_with_ground(true), m_collides_with_characters(false), Index: src/object/physical_obj.h =================================================================== --- src/object/physical_obj.h (revision 8358) +++ src/object/physical_obj.h (working copy) @@ -44,8 +44,12 @@ #define PIXEL_PER_METER 40 -Double MeterDistance(const Point2i &p1, const Point2i &p2); +inline Double MeterDistance(const Point2i &p1, const Point2i &p2) { + static const Double METER_PER_PIXEL = (1.0f/PIXEL_PER_METER); + return p1.Distance(p2) * METER_PER_PIXEL; +}; + class PhysicalObj : public Physics { // collision management Index: src/graphic/sprite.cpp =================================================================== --- src/graphic/sprite.cpp (revision 8358) +++ src/graphic/sprite.cpp (working copy) @@ -152,12 +152,12 @@ // Calculate offset of the surface depending on hotspot rotation position : int surfaceHeight = surface.GetHeight(); int surfaceWidth = surface.GetWidth(); - int halfHeight = surfaceHeight / 2; - int halfWidth = surfaceWidth / 2; + int halfHeight = surfaceHeight >> 1; + int halfWidth = surfaceWidth >> 1; //Do as if hotspot is center of picture: - rotation_point.x = halfWidth /*surfaceWidth / 2*/ - tmp_surface.GetWidth() / 2; - rotation_point.y = halfHeight /*surfaceHeight / 2*/ - tmp_surface.GetHeight() / 2; + rotation_point.x = halfWidth /*surfaceWidth / 2*/ - (tmp_surface.GetWidth() >> 1); + rotation_point.y = halfHeight /*surfaceHeight / 2*/ - (tmp_surface.GetHeight() >> 1); if (rot_hotspot == center) { return; @@ -186,7 +186,7 @@ surfaceHeight = static_cast<int>(surfaceHeight * scale_y); //Calculate the position of the hotspot after a rotation around the center of the surface: - Point2i center(surfaceWidth / 2, surfaceHeight / 2); + Point2i center(surfaceWidth >> 1, surfaceHeight >> 1); // Don't let the compiler any choice with which types the resulting program will calculate with. Point2i old_hotspot_delta_i = center - rhs_pos_tmp; Point2d old_hotspot_delta = old_hotspot_delta_i;
_______________________________________________ Wormux-dev mailing list Wormux-dev@gna.org https://mail.gna.org/listinfo/wormux-dev