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

Répondre à