Ticket #1988: anchor_no_floats.diff

File anchor_no_floats.diff, 31.9 KB (added by sanderd17, 11 years ago)
  • binaries/data/mods/public/simulation/templates/gaia/fauna_bear.xml

     
    1818    <SpecificName>Bear</SpecificName>
    1919    <Icon>gaia/fauna_bear.png</Icon>
    2020  </Identity>
     21  <Position>
     22    <Anchor>pitch</Anchor>
     23  </Position>
    2124  <Sound>
    2225    <SoundGroups>
    2326      <select>actor/fauna/animal/lion_select.xml</select>
  • binaries/data/mods/public/simulation/templates/gaia/fauna_boar.xml

     
    1818    <SpecificName>Boar</SpecificName>
    1919    <Icon>gaia/fauna_boar.png</Icon>
    2020  </Identity>
     21  <Position>
     22    <Anchor>pitch</Anchor>
     23  </Position>
    2124  <ResourceSupply>
    2225    <Amount>150</Amount>
    2326    <Type>food.meat</Type>
  • binaries/data/mods/public/simulation/templates/gaia/fauna_camel.xml

     
    1212  <Obstruction>
    1313    <Unit radius="1.5"/>
    1414  </Obstruction>
     15  <Position>
     16    <Anchor>pitch</Anchor>
     17  </Position>
    1518  <Sound>
    1619    <SoundGroups>
    1720      <select>actor/fauna/animal/camel.xml</select>
  • binaries/data/mods/public/simulation/templates/gaia/fauna_deer.xml

     
    55    <SpecificName>Deer</SpecificName>
    66    <Icon>gaia/fauna_deer.png</Icon>
    77  </Identity>
     8  <Position>
     9    <Anchor>pitch</Anchor>
     10  </Position>
    811  <UnitMotion>
    912    <WalkSpeed>2.0</WalkSpeed>
    1013    <Run>
  • binaries/data/mods/public/simulation/templates/gaia/fauna_elephant.xml

     
    1414    <SpecificName>Elephant</SpecificName>
    1515    <Icon>gaia/fauna_elephant.png</Icon>
    1616  </Identity>
     17  <Position>
     18    <Anchor>pitch</Anchor>
     19  </Position>
    1720  <Sound>
    1821    <SoundGroups>
    1922      <select>actor/fauna/animal/elephant_select.xml</select>
  • binaries/data/mods/public/simulation/templates/gaia/fauna_elephant_african_bush.xml

     
    5353  <Obstruction>
    5454    <Unit radius="3.5"/>
    5555  </Obstruction>
     56  <Position>
     57    <Anchor>pitch</Anchor>
     58  </Position>
    5659  <ResourceSupply>
    5760    <Amount>800</Amount>
    5861    <Type>food.meat</Type>
  • binaries/data/mods/public/simulation/templates/gaia/fauna_elephant_african_infant.xml

     
    1818  <Obstruction>
    1919    <Unit radius="1.5"/>
    2020  </Obstruction>
     21  <Position>
     22    <Anchor>pitch</Anchor>
     23  </Position>
    2124  <ResourceSupply>
    2225    <Amount>100</Amount>
    2326    <Type>food.meat</Type>
  • binaries/data/mods/public/simulation/templates/gaia/fauna_elephant_asian.xml

     
    5353  <Obstruction>
    5454    <Unit radius="2.7"/>
    5555  </Obstruction>
     56  <Position>
     57    <Anchor>pitch</Anchor>
     58  </Position>
    5659  <ResourceSupply>
    5760    <Amount>650</Amount>
    5861    <Type>food.meat</Type>
  • binaries/data/mods/public/simulation/templates/gaia/fauna_gazelle.xml

     
    55    <SpecificName>Gazelle</SpecificName>
    66    <Icon>gaia/fauna_gazelle.png</Icon>
    77  </Identity>
     8  <Position>
     9    <Anchor>pitch</Anchor>
     10  </Position>
    811  <UnitMotion>
    912    <Run>
    1013      <Range>600.0</Range>
  • binaries/data/mods/public/simulation/templates/gaia/fauna_giraffe.xml

     
    1616  <Obstruction>
    1717    <Unit radius="2.0"/>
    1818  </Obstruction>
     19  <Position>
     20    <Anchor>pitch</Anchor>
     21  </Position>
    1922  <ResourceSupply>
    2023    <Amount>350</Amount>
    2124    <Type>food.meat</Type>
  • binaries/data/mods/public/simulation/templates/gaia/fauna_giraffe_infant.xml

     
    1212  <Obstruction>
    1313    <Unit radius="1.5"/>
    1414  </Obstruction>
     15  <Position>
     16    <Anchor>pitch</Anchor>
     17  </Position>
    1518  <ResourceSupply>
    1619    <Amount>150</Amount>
    1720    <Type>food.meat</Type>
  • binaries/data/mods/public/simulation/templates/gaia/fauna_goat.xml

     
    1111    <SpecificName>Goat</SpecificName>
    1212    <Icon>gaia/fauna_goat.png</Icon>
    1313  </Identity>
     14  <Position>
     15    <Anchor>pitch</Anchor>
     16  </Position>
    1417  <ResourceSupply>
    1518    <Amount>120</Amount>
    1619    <Type>food.meat</Type>
  • binaries/data/mods/public/simulation/templates/gaia/fauna_horse.xml

     
    1212  <Obstruction>
    1313    <Unit radius="1.5"/>
    1414  </Obstruction>
     15  <Position>
     16    <Anchor>pitch</Anchor>
     17  </Position>
    1518  <ResourceSupply>
    1619    <Amount>200</Amount>
    1720  </ResourceSupply>
  • binaries/data/mods/public/simulation/templates/gaia/fauna_lion.xml

     
    1818    <SpecificName>Lion</SpecificName>
    1919    <Icon>gaia/fauna_lion.png</Icon>
    2020  </Identity>
     21  <Position>
     22    <Anchor>pitch</Anchor>
     23  </Position>
    2124  <Sound>
    2225    <SoundGroups>
    2326      <select>actor/fauna/animal/lion_select.xml</select>
  • binaries/data/mods/public/simulation/templates/gaia/fauna_lioness.xml

     
    1818    <SpecificName>Lion</SpecificName>
    1919    <Icon>gaia/fauna_lion.png</Icon>
    2020  </Identity>
     21  <Position>
     22    <Anchor>pitch</Anchor>
     23  </Position>
    2124  <Sound>
    2225    <SoundGroups>
    2326      <select>actor/fauna/animal/lion_select.xml</select>
  • binaries/data/mods/public/simulation/templates/gaia/fauna_muskox.xml

     
    99    <SpecificName>Muskox</SpecificName>
    1010    <Icon>gaia/fauna_muskox.png</Icon>
    1111  </Identity>
     12  <Position>
     13    <Anchor>pitch</Anchor>
     14  </Position>
    1215  <ResourceSupply>
    1316    <Amount>200</Amount>
    1417    <Type>food.meat</Type>
  • binaries/data/mods/public/simulation/templates/gaia/fauna_pig.xml

     
    55    <SpecificName>Pig</SpecificName>
    66    <Icon>gaia/fauna_pig.png</Icon>
    77  </Identity>
     8  <Position>
     9    <Anchor>pitch</Anchor>
     10  </Position>
    811  <StatusBars>
    912    <HeightOffset>5.0</HeightOffset>
    1013  </StatusBars>
  • binaries/data/mods/public/simulation/templates/gaia/fauna_rabbit.xml

     
    99    <SpecificName>Rabbit</SpecificName>
    1010    <Icon>gaia/fauna_rabbit.png</Icon>
    1111  </Identity>
     12  <Position>
     13    <Anchor>pitch</Anchor>
     14  </Position>
    1215  <ResourceSupply>
    1316    <Amount>50</Amount>
    1417    <Type>food.meat</Type>
  • binaries/data/mods/public/simulation/templates/gaia/fauna_sheep.xml

     
    1212    <Classes datatype="tokens">Domestic</Classes>
    1313    <Icon>gaia/fauna_sheep.png</Icon>
    1414  </Identity>
     15  <Position>
     16    <Anchor>pitch</Anchor>
     17  </Position>
    1518  <Sound>
    1619    <SoundGroups>
    1720      <select>actor/fauna/animal/sheep.xml</select>
  • binaries/data/mods/public/simulation/templates/gaia/fauna_tiger.xml

     
    1818    <SpecificName>Tiger</SpecificName>
    1919    <Icon>gaia/fauna_tiger.png</Icon>
    2020  </Identity>
     21  <Position>
     22    <Anchor>pitch</Anchor>
     23  </Position>
    2124  <Sound>
    2225    <SoundGroups>
    2326      <select>actor/fauna/animal/lion_select.xml</select>
  • binaries/data/mods/public/simulation/templates/gaia/fauna_walrus.xml

     
    2323    <SpecificName>Walrus</SpecificName>
    2424    <Icon>gaia/fauna_walrus.png</Icon>
    2525  </Identity>
     26  <Position>
     27    <Anchor>pitch</Anchor>
     28  </Position>
    2629  <ResourceSupply>
    2730    <Amount>300</Amount>
    2831    <Type>food.meat</Type>
  • binaries/data/mods/public/simulation/templates/gaia/fauna_wildebeest.xml

     
    1010    <History>The wildebeest (plural wildebeest, wildebeests or wildebai), also called the gnu, is an antelope of the genus Connochaetes. It is a hooved (ungulate) mammal. Wildebeest are well known for their annual migration to new pastures in which vast numbers of wildebeest can be seen crossing rivers, such as the Mara River and dying in large numbers as they attempt to reach the other side. Many of them are eaten by crocodiles while others simply drown. Herds of wildebeest possesses what is known as "swarm intelligence", whereby the animals systematically explore and overcome obstacles as one when, for instance, crossing a river or defending against predator attacks.</History>
    1111    <Icon>gaia/fauna_wildebeest.png</Icon>
    1212  </Identity>
     13  <Position>
     14    <Anchor>pitch</Anchor>
     15  </Position>
    1316  <ResourceSupply>
    1417    <Amount>150</Amount>
    1518    <Type>food.meat</Type>
  • binaries/data/mods/public/simulation/templates/gaia/fauna_wolf.xml

     
    1818    <SpecificName>Wolf</SpecificName>
    1919    <Icon>gaia/fauna_wolf.png</Icon>
    2020  </Identity>
     21  <Position>
     22    <Anchor>pitch</Anchor>
     23  </Position>
    2124  <VisualActor>
    2225    <Actor>fauna/wolf.xml</Actor>
    2326  </VisualActor>
  • binaries/data/mods/public/simulation/templates/gaia/fauna_wolf_snow.xml

     
    1818    <SpecificName>Snow Wolf</SpecificName>
    1919    <Icon>gaia/fauna_wolf_snow.png</Icon>
    2020  </Identity>
     21  <Position>
     22    <Anchor>pitch</Anchor>
     23  </Position>
    2124  <VisualActor>
    2225    <Actor>fauna/wolf_snow.xml</Actor>
    2326  </VisualActor>
  • binaries/data/mods/public/simulation/templates/gaia/fauna_zebra.xml

     
    99    <SpecificName>Zebra</SpecificName>
    1010    <Icon>gaia/fauna_zebra.png</Icon>
    1111  </Identity>
     12  <Position>
     13    <Anchor>pitch</Anchor>
     14  </Position>
    1215  <ResourceSupply>
    1316    <Amount>150</Amount>
    1417    <Type>food.meat</Type>
  • binaries/data/mods/public/simulation/templates/gaia/geology_metal_alpine.xml

     
    11<?xml version="1.0" encoding="utf-8"?>
    22<Entity parent="template_gaia_geo_mineral">
    3   <Position>
    4     <Anchor>pitch-roll</Anchor>
    5   </Position>
    63  <VisualActor>
    74    <Actor>geology/metalmine_alpine.xml</Actor>
    85  </VisualActor>
  • binaries/data/mods/public/simulation/templates/gaia/geology_metal_desert_small.xml

     
    11<?xml version="1.0" encoding="utf-8"?>
    22<Entity parent="template_gaia_geo_mineral">
    3   <Position>
    4     <Anchor>pitch-roll</Anchor>
    5   </Position>
    63  <VisualActor>
    74    <Actor>geology/metalmine_desert_small.xml</Actor>
    85  </VisualActor>
  • binaries/data/mods/public/simulation/templates/gaia/geology_metal_greek.xml

     
    11<?xml version="1.0" encoding="utf-8"?>
    22<Entity parent="template_gaia_geo_mineral">
    3   <Position>
    4     <Anchor>pitch-roll</Anchor>
    5   </Position>
    63  <VisualActor>
    74    <Actor>geology/metalmine_granite_greek.xml</Actor>
    85  </VisualActor>
  • binaries/data/mods/public/simulation/templates/gaia/geology_metal_mediterranean.xml

     
    11<?xml version="1.0" encoding="utf-8"?>
    22<Entity parent="template_gaia_geo_mineral">
    3   <Position>
    4     <Anchor>pitch-roll</Anchor>
    5   </Position>
    63  <VisualActor>
    74    <Actor>geology/metalmine_mediterranean.xml</Actor>
    85  </VisualActor>
  • binaries/data/mods/public/simulation/templates/gaia/geology_metal_temperate.xml

     
    11<?xml version="1.0" encoding="utf-8"?>
    22<Entity parent="template_gaia_geo_mineral">
    3   <Position>
    4     <Anchor>pitch-roll</Anchor>
    5   </Position>
    63  <VisualActor>
    74    <Actor>geology/metalmine_granite_temperate.xml</Actor>
    85  </VisualActor>
  • binaries/data/mods/public/simulation/templates/gaia/geology_metal_tropic.xml

     
    11<?xml version="1.0" encoding="utf-8"?>
    22<Entity parent="template_gaia_geo_mineral">
    3   <Position>
    4     <Anchor>pitch-roll</Anchor>
    5   </Position>
    63  <VisualActor>
    74    <Actor>geology/metalmine_tropic.xml</Actor>
    85  </VisualActor>
  • binaries/data/mods/public/simulation/templates/gaia/geology_stone_alpine_a.xml

     
    11<?xml version="1.0" encoding="utf-8"?>
    22<Entity parent="template_gaia_geo_rock">
    3   <Position>
    4     <Anchor>pitch-roll</Anchor>
    5   </Position>
    63  <VisualActor>
    74    <Actor>geology/stonemine_alpine_a.xml</Actor>
    85  </VisualActor>
  • binaries/data/mods/public/simulation/templates/gaia/geology_stone_desert_small.xml

     
    77  <Identity>
    88    <Icon>gaia/geology_stone_2.png</Icon>
    99  </Identity>
    10   <Position>
    11     <Anchor>pitch-roll</Anchor>
    12   </Position>
    1310  <VisualActor>
    1411    <Actor>geology/stonemine_desert_small.xml</Actor>
    1512  </VisualActor>
  • binaries/data/mods/public/simulation/templates/gaia/geology_stone_greek.xml

     
    11<?xml version="1.0" encoding="utf-8"?>
    22<Entity parent="template_gaia_geo_rock">
    3   <Position>
    4     <Anchor>pitch-roll</Anchor>
    5   </Position>
    63  <VisualActor>
    74    <Actor>geology/stonemine_granite_greek.xml</Actor>
    85  </VisualActor>
  • binaries/data/mods/public/simulation/templates/gaia/geology_stone_mediterranean.xml

     
    11<?xml version="1.0" encoding="utf-8"?>
    22<Entity parent="template_gaia_geo_rock">
    3   <Position>
    4     <Anchor>pitch-roll</Anchor>
    5   </Position>
    63  <VisualActor>
    74    <Actor>geology/stonemine_mediterranean.xml</Actor>
    85  </VisualActor>
  • binaries/data/mods/public/simulation/templates/gaia/geology_stone_savanna_small.xml

     
    77  <Identity>
    88    <Icon>gaia/geology_stone_2.png</Icon>
    99  </Identity>
    10   <Position>
    11     <Anchor>pitch-roll</Anchor>
    12   </Position>
    1310  <VisualActor>
    1411    <Actor>geology/stonemine_savanna_small.xml</Actor>
    1512  </VisualActor>
  • binaries/data/mods/public/simulation/templates/gaia/geology_stone_temperate.xml

     
    11<?xml version="1.0" encoding="utf-8"?>
    22<Entity parent="template_gaia_geo_rock">
    3   <Position>
    4     <Anchor>pitch-roll</Anchor>
    5   </Position>
    63  <VisualActor>
    74    <Actor>geology/stonemine_granite.xml</Actor>
    85  </VisualActor>
  • binaries/data/mods/public/simulation/templates/gaia/geology_stone_tropic_a.xml

     
    11<?xml version="1.0" encoding="utf-8"?>
    22<Entity parent="template_gaia_geo_rock">
    3   <Position>
    4     <Anchor>pitch-roll</Anchor>
    5   </Position>
    63  <VisualActor>
    74    <Actor>geology/stonemine_tropic.xml</Actor>
    85  </VisualActor>
  • binaries/data/mods/public/simulation/templates/template_gaia_geo.xml

     
    1010  <Obstruction>
    1111    <Static width="7.0" depth="7.0"/>
    1212  </Obstruction>
     13  <Position>
     14    <Anchor>pitch-roll</Anchor>
     15  </Position>
    1316  <Selectable>
    1417    <EditorOnly disable=""/>
    1518    <Overlay>
  • binaries/data/mods/public/simulation/templates/template_gaia_geo_mineral_slabs.xml

     
    77  <Obstruction>
    88    <Static width="13.0" depth="13.0"/>
    99  </Obstruction>
    10   <Position>
    11     <Anchor>pitch-roll</Anchor>
    12   </Position>
    1310  <ResourceSupply>
    1411    <Amount>5000</Amount>
    1512    <MaxGatherers>24</MaxGatherers>
  • binaries/data/mods/public/simulation/templates/template_gaia_geo_rock_slabs.xml

     
    77  <Obstruction>
    88    <Static width="13.0" depth="13.0"/>
    99  </Obstruction>
    10   <Position>
    11     <Anchor>pitch-roll</Anchor>
    12   </Position>
    1310  <ResourceSupply>
    1411    <Amount>5000</Amount>
    1512    <MaxGatherers>24</MaxGatherers>
  • binaries/data/mods/public/simulation/templates/template_unit_champion_cavalry.xml

     
    4242  <Obstruction>
    4343    <Unit radius="1.0"/>
    4444  </Obstruction>
     45  <Position>
     46    <Anchor>pitch</Anchor>
     47  </Position>
    4548  <Selectable>
    4649    <Overlay>
    4750      <Texture>
  • binaries/data/mods/public/simulation/templates/template_unit_champion_elephant.xml

     
    3131  <Obstruction>
    3232    <Unit radius="4.0"/>
    3333  </Obstruction>
     34  <Position>
     35    <Anchor>pitch</Anchor>
     36  </Position>
    3437  <Selectable>
    3538    <Overlay>
    3639      <Texture>
  • binaries/data/mods/public/simulation/templates/units/maur_support_elephant.xml

     
    3838    <stone>10</stone>
    3939    <metal>10</metal>
    4040  </Loot>
     41  <Position>
     42    <Anchor>pitch</Anchor>
     43  </Position>
    4144  <ResourceDropsite>
    4245    <Types>food wood stone metal</Types>
    4346  </ResourceDropsite>
  • source/simulation2/components/CCmpPosition.cpp

     
    3030#include "maths/MathUtil.h"
    3131#include "maths/Matrix3D.h"
    3232#include "maths/Vector3D.h"
     33#include "maths/Vector2D.h"
    3334#include "ps/CLogger.h"
    3435
    3536/**
     
    5859        UPRIGHT = 0,
    5960        PITCH = 1,
    6061        PITCH_ROLL = 2,
     62        ROLL=3,
    6163    } m_AnchorType;
    6264
    6365    bool m_Floating;
     
    7274    entity_pos_t m_YOffset;
    7375    bool m_RelativeToGround; // whether m_YOffset is relative to terrain/water plane, or an absolute height
    7476
    75     entity_angle_t m_RotX, m_RotY, m_RotZ;
     77    entity_angle_t m_RotX, m_RotY, m_RotZ, m_LastRotX, m_LastRotZ;
    7678    float m_InterpolatedRotY; // not serialized
    7779
     80    bool recalculateXZRotation;
     81
    7882    static std::string GetSchema()
    7983    {
    8084        return
     
    8993                "<choice>"
    9094                    "<value a:help='Always stand straight up'>upright</value>"
    9195                    "<value a:help='Rotate backwards and forwards to follow the terrain'>pitch</value>"
     96                    "<value a:help='Rotate sidewards to follow the terrain'>roll</value>"
    9297                    "<value a:help='Rotate in all direction to follow the terrain'>pitch-roll</value>"
    9398                "</choice>"
    9499            "</element>"
     
    110115            m_AnchorType = PITCH;
    111116        else if (anchor == L"pitch-roll")
    112117            m_AnchorType = PITCH_ROLL;
     118        else if (anchor == L"roll")
     119            m_AnchorType = ROLL;
    113120        else
    114121            m_AnchorType = UPRIGHT;
    115122
     
    123130
    124131        m_RotX = m_RotY = m_RotZ = entity_angle_t::FromInt(0);
    125132        m_InterpolatedRotY = 0;
     133
     134        m_LastRotX = entity_angle_t::Zero();
     135        m_LastRotZ = entity_angle_t::Zero();
     136
     137        recalculateXZRotation = true;
    126138    }
    127139
    128140    virtual void Deinit()
     
    152164            const char* anchor = "???";
    153165            switch (m_AnchorType)
    154166            {
    155             case UPRIGHT: anchor = "upright"; break;
    156             case PITCH: anchor = "pitch"; break;
    157             case PITCH_ROLL: anchor = "pitch-roll"; break;
     167            case PITCH:
     168                anchor = "pitch";
     169                break;
     170
     171            case PITCH_ROLL:
     172                anchor = "pitch-roll";
     173                break;
     174           
     175            case ROLL:
     176                anchor = "roll";
     177                break;
     178
     179            case UPRIGHT: // upright is the default
     180            default:
     181                anchor = "upright";
     182                break;
    158183            }
    159184            serialize.StringASCII("anchor", anchor, 0, 16);
    160185            serialize.Bool("floating", m_Floating);
     
    197222
    198223    virtual void MoveTo(entity_pos_t x, entity_pos_t z)
    199224    {
     225       
    200226        m_X = x;
    201227        m_Z = z;
    202228
     
    207233            m_LastZ = m_PrevZ = m_Z;
    208234        }
    209235
     236        UpdateXZRotation();
     237
    210238        AdvertisePositionChanges();
    211239    }
    212240
     
    216244        m_LastZ = m_PrevZ = m_Z = z;
    217245        m_InWorld = true;
    218246
     247        recalculateXZRotation = true;
     248
    219249        AdvertisePositionChanges();
    220250    }
    221251
     
    319349
    320350    virtual void TurnTo(entity_angle_t y)
    321351    {
     352
    322353        m_RotY = y;
    323354
     355        UpdateXZRotation();
     356
    324357        AdvertisePositionChanges();
    325358    }
    326359
     
    329362        m_RotY = y;
    330363        m_InterpolatedRotY = m_RotY.ToFloat();
    331364
     365        recalculateXZRotation = true;
     366
    332367        AdvertisePositionChanges();
    333368    }
    334369
     
    370405        rotY = m_InterpolatedRotY;
    371406    }
    372407
     408
     409    virtual void UpdateXZRotation()
     410    {
     411
     412        if (m_AnchorType == UPRIGHT)
     413            // change nothing if anchor is upright
     414            return;
     415       
     416        CmpPtr<ICmpTerrain> cmpTerrain(GetSimContext(), SYSTEM_ENTITY);
     417        if (!cmpTerrain)
     418                return;
     419
     420        // TODO average normal (average all the tiles?) for big units or for buildings
     421        CFixedVector3D normal = cmpTerrain->CalcNormal(m_X, m_Z);
     422
     423        // rotate the normal so the positive x direction is in the direction of the unit
     424        CFixedVector2D projected = CFixedVector2D(normal.X, normal.Z);
     425        projected = projected.Rotate(-m_RotY);
     426
     427        normal.X = projected.X;
     428        normal.Z = projected.Y;
     429
     430        if (m_AnchorType == PITCH || m_AnchorType == PITCH_ROLL)
     431            // project and calculate the angle
     432            m_RotX = -atan2_approx(normal.Z, normal.Y);
     433
     434        if (m_AnchorType == ROLL || m_AnchorType == PITCH_ROLL)
     435            // project and calculate the angle
     436            m_RotZ = atan2_approx(normal.X,normal.Y);
     437       
     438        return;
     439    }
     440
    373441    virtual CMatrix3D GetInterpolatedTransform(float frameOffset, bool forceFloating)
    374442    {
     443
     444
    375445        if (!m_InWorld)
    376446        {
    377447            LOGERROR(L"CCmpPosition::GetInterpolatedTransform called on entity when IsInWorld is false");
     
    400470
    401471        float y = baseY + m_YOffset.ToFloat();
    402472
    403         // TODO: do something with m_AnchorType
    404473
    405         CMatrix3D m;
    406         m.SetXRotation(m_RotX.ToFloat());
    407         m.RotateZ(m_RotZ.ToFloat());
     474        CMatrix3D m;
     475       
     476        // linear interpolation is good enough (for RotX/Z).
     477        // As you always stay close to zero angle. 
     478        m.SetXRotation(Interpolate(m_LastRotX.ToFloat(), m_RotX.ToFloat(), frameOffset));
     479        m.RotateZ(Interpolate(m_LastRotZ.ToFloat(), m_RotZ.ToFloat(), frameOffset));
     480   
    408481        m.RotateY(rotY + (float)M_PI);
    409482        m.Translate(CVector3D(x, y, z));
    410483       
     
    417490        {
    418491        case MT_Interpolate:
    419492        {
     493
    420494            const CMessageInterpolate& msgData = static_cast<const CMessageInterpolate&> (msg);
    421495
    422496            float rotY = m_RotY.ToFloat();
    423             float delta = rotY - m_InterpolatedRotY;
    424             // Wrap delta to -M_PI..M_PI
    425             delta = fmodf(delta + (float)M_PI, 2*(float)M_PI); // range -2PI..2PI
    426             if (delta < 0) delta += 2*(float)M_PI; // range 0..2PI
    427             delta -= (float)M_PI; // range -M_PI..M_PI
    428             // Clamp to max rate
    429             float deltaClamped = clamp(delta, -m_RotYSpeed*msgData.deltaSimTime, +m_RotYSpeed*msgData.deltaSimTime);
    430             // Calculate new orientation, in a peculiar way in order to make sure the
    431             // result gets close to m_orientation (rather than being n*2*M_PI out)
    432             m_InterpolatedRotY = rotY + deltaClamped - delta;
     497            if (rotY != m_InterpolatedRotY)
     498            {
     499                float delta = rotY - m_InterpolatedRotY;
     500                // Wrap delta to -M_PI..M_PI
     501                delta = fmodf(delta + (float)M_PI, 2*(float)M_PI); // range -2PI..2PI
     502                if (delta < 0) delta += 2*(float)M_PI; // range 0..2PI
     503                delta -= (float)M_PI; // range -M_PI..M_PI
     504                // Clamp to max rate
     505                float deltaClamped = clamp(delta, -m_RotYSpeed*msgData.deltaSimTime, +m_RotYSpeed*msgData.deltaSimTime);
     506                // Calculate new orientation, in a peculiar way in order to make sure the
     507                // result gets close to m_orientation (rather than being n*2*M_PI out)
     508                m_InterpolatedRotY = rotY + deltaClamped - delta;
     509                recalculateXZRotation = true;
     510            }
    433511
     512           
     513
    434514            break;
    435515        }
    436516        case MT_TurnStart:
    437         {
    438517            // Store the positions from the turn before
    439518            m_PrevX = m_LastX;
    440519            m_PrevZ = m_LastZ;
    441520           
    442521            m_LastX = m_X;
    443522            m_LastZ = m_Z;
     523               
     524            m_LastRotX = m_RotX;
     525            m_LastRotZ = m_RotZ;
    444526
     527            if (recalculateXZRotation)
     528            {
     529                UpdateXZRotation();
     530
     531                recalculateXZRotation = false;
     532            }
     533
    445534            break;
    446         }
    447         }
    448535    }
     536};
    449537
    450538private:
    451539    void AdvertisePositionChanges()