Ticket #2337: Culling.patch

File Culling.patch, 50.3 KB (added by wraitii, 10 years ago)
  • source/graphics/Camera.cpp

     
    126126    m_ViewFrustum.m_aPlanes[5].m_Norm.Y = -scissor[0].Z*MatFinal._42 + MatFinal._32;
    127127    m_ViewFrustum.m_aPlanes[5].m_Norm.Z = -scissor[0].Z*MatFinal._43 + MatFinal._33;
    128128    m_ViewFrustum.m_aPlanes[5].m_Dist   = -scissor[0].Z*MatFinal._44 + MatFinal._34;
     129
     130    for (size_t i = 0; i < 6; ++i)
     131        m_ViewFrustum.m_aPlanes[i].Normalize();
    129132}
    130133
    131134void CCamera::ClipFrustum(const CPlane& clipPlane)
    132135{
    133     m_ViewFrustum.AddPlane(clipPlane);
     136    CPlane normClipPlane = clipPlane;
     137    normClipPlane.Normalize();
     138    m_ViewFrustum.AddPlane(normClipPlane);
    134139}
    135140
    136141void CCamera::SetViewPort(const SViewPort& viewport)
  • source/graphics/Frustum.cpp

     
    9393    }
    9494    return false;
    9595}
     96
    9697bool CFrustum::IsSphereVisible (const CVector3D &center, float radius) const
    9798{
    98     for (size_t i=0; i<m_NumPlanes; i++)
     99    for (size_t i = 0; i < m_NumPlanes; i++)
    99100    {
    100         float Dist = m_aPlanes[i].DistanceToPlane (center);
    101        
    102         //is it behind the plane
    103         if (Dist < 0)
    104         {
    105             //if non of it falls in front its outside the
    106             //frustum
    107             if (-Dist > radius)
    108                 return false;
    109         }
     101        float Dist = m_aPlanes[i].DistanceToPlane(center);
     102        // If none of the sphere is in front of the plane, then
     103        // it is outside the frustum
     104        if (-Dist > radius)
     105            return false;
    110106    }
    111107
    112108    return true;
    113109}
    114110
    115 
    116111bool CFrustum::IsBoxVisible (const CVector3D &position,const CBoundingBoxAligned &bounds) const
    117112{
    118113    //basically for every plane we calculate the furthest point
  • source/graphics/GameView.cpp

     
    486486        m->CullCamera.SetProjection(m->ViewNear, m->ViewFar, GetCullFOV());
    487487        m->CullCamera.UpdateFrustum();
    488488    }
     489    m->ViewCamera.UpdateFrustum();
    489490    g_Renderer.SetSceneCamera(m->ViewCamera, m->CullCamera);
    490491
    491492    CheckLightEnv();
     
    10551056
    10561057float CGameView::GetCullFOV() const
    10571058{
    1058     return m->ViewFOV + DEGTORAD(6.0f); //add 6 degrees to the default FOV for use with the culling frustum;
     1059    // XXXX
     1060    return m->ViewFOV;
    10591061}
    10601062
    10611063void CGameView::SetCameraProjection()
  • source/graphics/MapReader.cpp

     
    131131        RegMemFun(this, &CMapReader::UnpackMap, L"CMapReader::UnpackMap", 1200);
    132132
    133133    // read the corresponding XML file
    134     RegMemFun(this, &CMapReader::ReadXML, L"CMapReader::ReadXML", 5800);
     134    RegMemFun(this, &CMapReader::ReadXML, L"CMapReader::ReadXML", 50);
    135135
    136     // apply data to the world
     136    // apply terrain data to the world
     137    RegMemFun(this, &CMapReader::ApplyTerrainData, L"CMapReader::ApplyTerrainData", 5);
     138   
     139    // read entities
     140    RegMemFun(this, &CMapReader::ReadXMLEntities, L"CMapReader::ReadXMLEntities", 5800);
     141   
     142    // apply misc data to the world
    137143    RegMemFun(this, &CMapReader::ApplyData, L"CMapReader::ApplyData", 5);
    138144
    139145    // load map settings script (must be done after reading map)
     
    189195    // parse RMS results into camera settings
    190196    RegMemFun(this, &CMapReader::ParseCamera, L"CMapReader::ParseCamera", 5);
    191197
     198    // apply terrain data to the world
     199    RegMemFun(this, &CMapReader::ApplyTerrainData, L"CMapReader::ApplyTerrainData", 5);
     200
    192201    // parse RMS results into entities
    193202    RegMemFun(this, &CMapReader::ParseEntities, L"CMapReader::ParseEntities", 1000);
    194203
    195     // apply data to the world
     204    // apply misc data to the world
    196205    RegMemFun(this, &CMapReader::ApplyData, L"CMapReader::ApplyData", 5);
    197206
    198207    // load map settings script (must be done after reading map)
     
    264273    return 0;
    265274}
    266275
    267 // ApplyData: take all the input data, and rebuild the scene from it
    268 int CMapReader::ApplyData()
     276int CMapReader::ApplyTerrainData()
    269277{
    270278    if (m_PatchesPerSide == 0)
    271279    {
     
    295303            }
    296304        }
    297305    }
     306   
     307    CmpPtr<ICmpTerrain> cmpTerrain(*pSimContext, SYSTEM_ENTITY);
     308    if (cmpTerrain)
     309        cmpTerrain->ReloadTerrain();
     310   
     311    return 0;
     312}
     313
     314// ApplyData: take all the input data, and rebuild the scene from it
     315int CMapReader::ApplyData()
     316{
    298317
    299318    // copy over the lighting parameters
    300319    if (pLightEnv)
     
    327346        }
    328347    }
    329348
    330     CmpPtr<ICmpTerrain> cmpTerrain(*pSimContext, SYSTEM_ENTITY);
    331     if (cmpTerrain)
    332         cmpTerrain->ReloadTerrain();
    333 
    334349    return 0;
    335350}
    336351
     
    398413
    399414    CStr ReadScriptSettings();
    400415
     416    // read everything except for entities
     417    void ReadXML();
     418
    401419    // return semantics: see Loader.cpp!LoadFunc.
    402     int ProgressiveRead();
     420    int ProgressiveReadEntities();
    403421
    404422private:
    405423    CXeromyces xmb_file;
     
    10711089    return 0;
    10721090}
    10731091
    1074 int CXMLReader::ProgressiveRead()
     1092void CXMLReader::ReadXML()
    10751093{
    1076     // yield after this time is reached. balances increased progress bar
    1077     // smoothness vs. slowing down loading.
    1078     const double end_time = timer_Time() + 200e-3;
    1079 
    1080     int ret;
    1081 
    1082     while (node_idx < nodes.Count)
     1094    for (int i = 0; i < nodes.Count; ++i)
    10831095    {
    1084         XMBElement node = nodes.Item(node_idx);
     1096        XMBElement node = nodes.Item(i);
    10851097        CStr name = xmb_file.GetElementString(node.GetNodeName());
    10861098        if (name == "Terrain")
    10871099        {
     
    10971109        }
    10981110        else if (name == "ScriptSettings")
    10991111        {
    1100             //Already loaded - this is to prevent an assertion
     1112            // Already loaded - this is to prevent an assertion
    11011113        }
    11021114        else if (name == "Entities")
    11031115        {
    1104             if (!m_MapReader.m_SkipEntities)
    1105             {
    1106                 ret = ReadEntities(node, end_time);
    1107                 if (ret != 0)   // error or timed out
    1108                     return ret;
    1109             }
     1116            // Handled by ProgressiveReadEntities instead
    11101117        }
    11111118        else if (name == "Paths")
    11121119        {
     
    11261133            debug_printf(L"Invalid XML element in map file: %hs\n", name.c_str());
    11271134            debug_warn(L"Invalid map XML data");
    11281135        }
     1136               }
     1137    }
    11291138
     1139int CXMLReader::ProgressiveReadEntities()
     1140{
     1141    // yield after this time is reached. balances increased progress bar
     1142    // smoothness vs. slowing down loading.
     1143    const double end_time = timer_Time() + 200e-3;
     1144   
     1145    int ret;
     1146   
     1147    while (node_idx < nodes.Count)
     1148    {
     1149        XMBElement node = nodes.Item(node_idx);
     1150        CStr name = xmb_file.GetElementString(node.GetNodeName());
     1151        if (name == "Entities")
     1152        {
     1153            if (!m_MapReader.m_SkipEntities)
     1154            {
     1155                ret = ReadEntities(node, end_time);
     1156                if (ret != 0)   // error or timed out
     1157                    return ret;
     1158            }
     1159        }
    11301160        node_idx++;
    11311161    }
    1132 
     1162   
    11331163    return 0;
    11341164}
    11351165
     
    11671197    return 0;
    11681198}
    11691199
    1170 // progressive
    11711200int CMapReader::ReadXML()
    11721201{
    11731202    if (!xml_reader)
    11741203        xml_reader = new CXMLReader(filename_xml, *this);
     1204   
     1205    xml_reader->ReadXML();
     1206   
     1207    return 0;
     1208}
    11751209
    1176     int ret = xml_reader->ProgressiveRead();
     1210// progressive
     1211int CMapReader::ReadXMLEntities()
     1212{
     1213    if (!xml_reader)
     1214        xml_reader = new CXMLReader(filename_xml, *this);
     1215   
     1216    int ret = xml_reader->ProgressiveReadEntities();
    11771217    // finished or failed
    11781218    if (ret <= 0)
    11791219    {
  • source/graphics/MapReader.h

     
    7979
    8080    // ApplyData: take all the input data, and rebuild the scene from it
    8181    int ApplyData();
     82    int ApplyTerrainData();
    8283
    83     // ReadXML: read some other data (entities, etc) in XML format
     84    // read some misc data from the XML file
    8485    int ReadXML();
     86   
     87    // read entity data from the XML file
     88    int ReadXMLEntities();
    8589
    8690    // clean up everything used during delayed load
    8791    int DelayLoadFinished();
  • source/graphics/Overlay.h

     
    154154    CColor m_Color;
    155155};
    156156
     157struct SOverlaySphere
     158{
     159    SOverlaySphere() : m_Radius(0) { }
     160   
     161    CVector3D m_Center;
     162    float m_Radius;
     163    CColor m_Color;
     164};
     165
    157166// TODO: OverlayText
    158167
    159168#endif // INCLUDED_GRAPHICS_OVERLAY
  • source/maths/BoundingBoxAligned.h

     
    5454     * computing this result, and then taking the axis-aligned bounding boxes from the result again.
    5555     */
    5656    void Transform(const CMatrix3D& m, CBoundingBoxOriented& result) const;
    57 
     57   
     58    /**
     59     * Translates these bounds by @p v, and writes the result to @p result.
     60     */
     61    void Translate(const CVector3D& v, CBoundingBoxAligned& result) const
     62    {
     63        result.m_Data[0] = m_Data[0] + v;
     64        result.m_Data[1] = m_Data[1] + v;
     65    }
     66   
    5867    CVector3D& operator[](int index) { return m_Data[index]; }
    5968    const CVector3D& operator[](int index) const { return m_Data[index]; }
    6069
  • source/ps/CStrInternStatic.h

     
    107107X(normalMap)
    108108X(normalMap2)
    109109X(objectColor)
     110X(overlay_solid)
    110111X(particle)
    111112X(particle_solid)
    112113X(playerColor)
  • source/renderer/OverlayRenderer.cpp

     
    8888    std::vector<SOverlayTexturedLine*> texlines;
    8989    std::vector<SOverlaySprite*> sprites;
    9090    std::vector<SOverlayQuad*> quads;
     91    std::vector<SOverlaySphere*> spheres;
    9192
    9293    QuadBatchMap quadBatchMap;
    9394
     
    223224    m->quads.push_back(overlay);
    224225}
    225226
     227void OverlayRenderer::Submit(SOverlaySphere* overlay)
     228{
     229    m->spheres.push_back(overlay);
     230}
     231
    226232void OverlayRenderer::EndFrame()
    227233{
    228234    m->lines.clear();
    229235    m->texlines.clear();
    230236    m->sprites.clear();
    231237    m->quads.clear();
     238    m->spheres.clear();
     239   
    232240    // this should leave the capacity unchanged, which is okay since it
    233241    // won't be very large or very variable
    234242   
     
    384392
    385393    RenderTexturedOverlayLines();
    386394    RenderQuadOverlays();
     395    RenderSphereOverlays();
    387396}
    388397
    389398void OverlayRenderer::RenderTexturedOverlayLines()
     
    629638    glDisable(GL_TEXTURE_2D);
    630639#endif
    631640}
     641
     642static void TessellateSphereFace(const CVector3D& a, u16 ai,
     643                                 const CVector3D& b, u16 bi,
     644                                 const CVector3D& c, u16 ci,
     645                                 std::vector<float>& vertexes, std::vector<u16>& indexes, int level)
     646{
     647    if (level == 0)
     648    {
     649        indexes.push_back(ai);
     650        indexes.push_back(bi);
     651        indexes.push_back(ci);
     652    }
     653    else
     654    {
     655        CVector3D d = (a + b).Normalized();
     656        CVector3D e = (b + c).Normalized();
     657        CVector3D f = (c + a).Normalized();
     658        int di = vertexes.size() / 3; vertexes.push_back(d.X); vertexes.push_back(d.Y); vertexes.push_back(d.Z);
     659        int ei = vertexes.size() / 3; vertexes.push_back(e.X); vertexes.push_back(e.Y); vertexes.push_back(e.Z);
     660        int fi = vertexes.size() / 3; vertexes.push_back(f.X); vertexes.push_back(f.Y); vertexes.push_back(f.Z);
     661        TessellateSphereFace(a,ai, d,di, f,fi, vertexes, indexes, level-1);
     662        TessellateSphereFace(d,di, b,bi, e,ei, vertexes, indexes, level-1);
     663        TessellateSphereFace(f,fi, e,ei, c,ci, vertexes, indexes, level-1);
     664        TessellateSphereFace(d,di, e,ei, f,fi, vertexes, indexes, level-1);
     665    }
     666}
     667
     668static void TessellateSphere(std::vector<float>& vertexes, std::vector<u16>& indexes, int level)
     669{
     670    /* Start with a tetrahedron, then tessellate */
     671    float s = sqrtf(0.5f);
     672#define VERT(a,b,c) vertexes.push_back(a); vertexes.push_back(b); vertexes.push_back(c);
     673    VERT(-s,  0, -s);
     674    VERT( s,  0, -s);
     675    VERT( s,  0,  s);
     676    VERT(-s,  0,  s);
     677    VERT( 0, -1,  0);
     678    VERT( 0,  1,  0);
     679#define FACE(a,b,c) \
     680TessellateSphereFace( \
     681CVector3D(vertexes[a*3], vertexes[a*3+1], vertexes[a*3+2]), a, \
     682CVector3D(vertexes[b*3], vertexes[b*3+1], vertexes[b*3+2]), b, \
     683CVector3D(vertexes[c*3], vertexes[c*3+1], vertexes[c*3+2]), c, \
     684vertexes, indexes, level);
     685    FACE(0,4,1);
     686    FACE(1,4,2);
     687    FACE(2,4,3);
     688    FACE(3,4,0);
     689    FACE(1,5,0);
     690    FACE(2,5,1);
     691    FACE(3,5,2);
     692    FACE(0,5,3);
     693#undef FACE
     694#undef VERT
     695}
     696
     697void OverlayRenderer::RenderSphereOverlays()
     698{
     699    PROFILE3_GPU("overlays (spheres)");
     700   
     701    if (g_Renderer.GetRenderPath() != CRenderer::RP_SHADER)
     702        return;
     703   
     704    if (m->spheres.empty())
     705        return;
     706   
     707    glDisable(GL_TEXTURE_2D);
     708    glEnable(GL_BLEND);
     709    glDepthMask(0);
     710   
     711    glEnableClientState(GL_VERTEX_ARRAY);
     712   
     713    CShaderProgramPtr shader;
     714    CShaderTechniquePtr tech;
     715   
     716    tech = g_Renderer.GetShaderManager().LoadEffect(str_overlay_solid);
     717    tech->BeginPass();
     718    shader = tech->GetShader();
     719   
     720    static std::vector<float> vertexes;
     721    static std::vector<u16> indexes;
     722    ONCE(TessellateSphere(vertexes, indexes, 3));
     723   
     724    shader->VertexPointer(3, GL_FLOAT, 0, &vertexes[0]);
     725   
     726    for (size_t i = 0; i < m->spheres.size(); ++i)
     727    {
     728        SOverlaySphere* sphere = m->spheres[i];
     729       
     730        CMatrix3D transform;
     731        transform.SetIdentity();
     732        transform.Scale(sphere->m_Radius, sphere->m_Radius, sphere->m_Radius);
     733        transform.Translate(sphere->m_Center);
     734       
     735        shader->Uniform(str_transform, transform);
     736       
     737        shader->Uniform(str_color, sphere->m_Color);
     738       
     739        glDrawElements(GL_TRIANGLES, indexes.size(), GL_UNSIGNED_SHORT, &indexes[0]);
     740       
     741        g_Renderer.GetStats().m_DrawCalls++;
     742        g_Renderer.GetStats().m_OverlayTris = indexes.size()/3;
     743    }
     744   
     745    tech->EndPass();
     746   
     747    glDisableClientState(GL_VERTEX_ARRAY);
     748   
     749    glDepthMask(1);
     750    glDisable(GL_BLEND);
     751}
  • source/renderer/OverlayRenderer.h

     
    2424struct SOverlayTexturedLine;
    2525struct SOverlaySprite;
    2626struct SOverlayQuad;
     27struct SOverlaySphere;
    2728class CCamera;
    2829
    2930struct OverlayRendererInternals;
     
    7475     */
    7576    void Submit(SOverlayQuad* overlay);
    7677
     78    void Submit(SOverlaySphere* overlay);
     79
    7780    /**
    7881     * Prepare internal data structures for rendering.
    7982     * Must be called after all Submit calls for a frame, and before
     
    132135     */
    133136    void RenderQuadOverlays();
    134137
     138    void RenderSphereOverlays();
     139
    135140private:
    136141    OverlayRendererInternals* m;
    137142};
  • source/renderer/Renderer.cpp

     
    11271127
    11281128///////////////////////////////////////////////////////////////////////////////////////////////////
    11291129// RenderReflections: render the water reflections to the reflection texture
    1130 SScreenRect CRenderer::RenderReflections(const CShaderDefines& context, const CBoundingBoxAligned& scissor)
     1130void CRenderer::RenderReflections(Scene& scene, const CBoundingBoxAligned& scissor)
    11311131{
    11321132    PROFILE3_GPU("water reflections");
    11331133
     1134    CShaderDefines context = m->globalContext;
     1135
    11341136    WaterManager& wm = m->waterManager;
    11351137
    11361138    // Remember old camera
     
    11431145    // of the view so we can see wavy reflections of slightly off-screen objects.
    11441146    m_ViewCamera.m_Orientation.Scale(1, -1, 1);
    11451147    m_ViewCamera.m_Orientation.Translate(0, 2*wm.m_WaterHeight, 0);
    1146     m_ViewCamera.UpdateFrustum(scissor);
    11471148    m_ViewCamera.ClipFrustum(CVector4D(0, 1, 0, -wm.m_WaterHeight));
    11481149
    11491150    SViewPort vp;
     
    11521153    vp.m_X = 0;
    11531154    vp.m_Y = 0;
    11541155    m_ViewCamera.SetViewPort(vp);
    1155     m_ViewCamera.SetProjection(normalCamera.GetNearPlane(), normalCamera.GetFarPlane(), normalCamera.GetFOV()*1.05f); // Slightly higher than view FOV
    11561156    CMatrix3D scaleMat;
    11571157    scaleMat.SetScaling(m_Height/float(std::max(1, m_Width)), 1.0f, 1.0f);
    11581158    m_ViewCamera.m_ProjMat = scaleMat * m_ViewCamera.m_ProjMat;
     
    11621162    CVector4D camPlane(0, 1, 0, -wm.m_WaterHeight);
    11631163    SetObliqueFrustumClipping(camPlane);
    11641164
     1165    // enumerate objects for our frustrum.
     1166    m_ViewCamera.UpdateFrustum();
     1167    CFrustum frustum = m_ViewCamera.GetFrustum();
     1168    scene.EnumerateObjects(frustum, this);
     1169    m->particleManager.RenderSubmit(*this, frustum);
     1170   
     1171    m->terrainRenderer.PrepareForRendering();
     1172    m->particleRenderer.PrepareForRendering(context);
     1173
     1174   
    11651175    // Save the model-view-projection matrix so the shaders can use it for projective texturing
    11661176    wm.m_ReflectionMatrix = m_ViewCamera.GetViewProjection();
    11671177
    1168     SScreenRect screenScissor;
    1169     screenScissor.x1 = (GLint)floor((scissor[0].X*0.5f+0.5f)*vp.m_Width);
    1170     screenScissor.y1 = (GLint)floor((scissor[0].Y*0.5f+0.5f)*vp.m_Height);
    1171     screenScissor.x2 = (GLint)ceil((scissor[1].X*0.5f+0.5f)*vp.m_Width);
    1172     screenScissor.y2 = (GLint)ceil((scissor[1].Y*0.5f+0.5f)*vp.m_Height);
    1173 
    1174     if (screenScissor.x1 < screenScissor.x2 && screenScissor.y1 < screenScissor.y2)
    1175     {
    1176         glEnable(GL_SCISSOR_TEST);
    1177         glScissor(screenScissor.x1, screenScissor.y1, screenScissor.x2 - screenScissor.x1, screenScissor.y2 - screenScissor.y1);
    1178 
    1179         glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
    1180 
    1181         glFrontFace(GL_CW);
     1178    //glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
     1179   
     1180    // Save the post-processing framebuffer.
     1181    GLint fbo;
     1182    glGetIntegerv(GL_FRAMEBUFFER_BINDING_EXT, &fbo);
     1183   
     1184    GLuint waterBuffer = 0;
     1185    pglGenFramebuffersEXT(1, &waterBuffer);
     1186    pglBindFramebufferEXT(GL_FRAMEBUFFER_EXT, waterBuffer);
     1187   
     1188    glEnable(GL_TEXTURE_2D);
    11821189
    1183         // Render sky, terrain and models
    1184         m->skyManager.RenderSky();
    1185         ogl_WarnIfError();
    1186         RenderPatches(context, &m_ViewCamera.GetFrustum());
    1187         ogl_WarnIfError();
    1188         RenderModels(context, &m_ViewCamera.GetFrustum());
    1189         ogl_WarnIfError();
    1190         RenderTransparentModels(context, TRANSPARENT_OPAQUE, &m_ViewCamera.GetFrustum());
    1191         ogl_WarnIfError();
     1190    glBindTexture(GL_TEXTURE_2D, wm.m_ReflectionTexture);
     1191    pglFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT, GL_TEXTURE_2D, wm.m_ReflectionTexture, 0);
     1192   
     1193    glFrontFace(GL_CW);
    11921194
    1193         glFrontFace(GL_CCW);
     1195    glClearColor(0.5f,0.5f,1.0f,0.0f);
     1196    glClear(GL_COLOR_BUFFER_BIT);
    11941197
    1195         glDisable(GL_SCISSOR_TEST);
     1198   
     1199    // Render sky, terrain and models
     1200    m->skyManager.RenderSky();
     1201    ogl_WarnIfError();
     1202    RenderPatches(context, &m_ViewCamera.GetFrustum());
     1203    ogl_WarnIfError();
     1204    RenderModels(context, &m_ViewCamera.GetFrustum());
     1205    ogl_WarnIfError();
     1206    RenderTransparentModels(context, TRANSPARENT_OPAQUE, &m_ViewCamera.GetFrustum());
     1207    ogl_WarnIfError();
     1208   
     1209    glFrontFace(GL_CCW);
    11961210
    1197         // Copy the image to a texture
    1198         pglActiveTextureARB(GL_TEXTURE0);
    1199         glEnable(GL_TEXTURE_2D);
    1200         glBindTexture(GL_TEXTURE_2D, wm.m_ReflectionTexture);
    1201         glCopyTexSubImage2D(GL_TEXTURE_2D, 0,
    1202                 screenScissor.x1, screenScissor.y1,
    1203                 screenScissor.x1, screenScissor.y1,
    1204                 screenScissor.x2 - screenScissor.x1, screenScissor.y2 - screenScissor.y1);
    1205     }
     1211    // rebind post-processing frambuffer.
     1212    pglBindFramebufferEXT(GL_FRAMEBUFFER_EXT, fbo);
    12061213
    12071214    // Reset old camera
    12081215    m_ViewCamera = normalCamera;
    12091216    m->SetOpenGLCamera(m_ViewCamera);
    1210 
    1211     return screenScissor;
    12121217}
    12131218
    12141219
    12151220///////////////////////////////////////////////////////////////////////////////////////////////////
    12161221// RenderRefractions: render the water refractions to the refraction texture
    1217 SScreenRect CRenderer::RenderRefractions(const CShaderDefines& context, const CBoundingBoxAligned &scissor)
     1222void CRenderer::RenderRefractions(const CBoundingBoxAligned &scissor)
    12181223{
    12191224    PROFILE3_GPU("water refractions");
    12201225
     1226    CShaderDefines context = m->globalContext;
     1227   
    12211228    WaterManager& wm = m->waterManager;
    12221229
    12231230    // Remember old camera
     
    12491256    // Save the model-view-projection matrix so the shaders can use it for projective texturing
    12501257    wm.m_RefractionMatrix = m_ViewCamera.GetViewProjection();
    12511258
    1252     SScreenRect screenScissor;
    1253     screenScissor.x1 = (GLint)floor((scissor[0].X*0.5f+0.5f)*vp.m_Width);
    1254     screenScissor.y1 = (GLint)floor((scissor[0].Y*0.5f+0.5f)*vp.m_Height);
    1255     screenScissor.x2 = (GLint)ceil((scissor[1].X*0.5f+0.5f)*vp.m_Width);
    1256     screenScissor.y2 = (GLint)ceil((scissor[1].Y*0.5f+0.5f)*vp.m_Height);
    1257     if (screenScissor.x1 < screenScissor.x2 && screenScissor.y1 < screenScissor.y2)
    1258     {
    1259         glEnable(GL_SCISSOR_TEST);
    1260         glScissor(screenScissor.x1, screenScissor.y1, screenScissor.x2 - screenScissor.x1, screenScissor.y2 - screenScissor.y1);
    1261 
    1262         glClearColor(0.5f, 0.5f, 0.5f, 1.0f);       // a neutral gray to blend in with shores
    1263         glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
    1264 
    1265         // Render terrain and models
    1266         RenderPatches(context, &m_ViewCamera.GetFrustum());
    1267         ogl_WarnIfError();
    1268         RenderModels(context, &m_ViewCamera.GetFrustum());
    1269         ogl_WarnIfError();
    1270         RenderTransparentModels(context, TRANSPARENT_OPAQUE, &m_ViewCamera.GetFrustum());
    1271         ogl_WarnIfError();
    1272 
    1273         glDisable(GL_SCISSOR_TEST);
    1274 
    1275         // Copy the image to a texture
    1276         pglActiveTextureARB(GL_TEXTURE0);
    1277         glEnable(GL_TEXTURE_2D);
    1278         glBindTexture(GL_TEXTURE_2D, wm.m_RefractionTexture);
    1279         glCopyTexSubImage2D(GL_TEXTURE_2D, 0,
    1280                 screenScissor.x1, screenScissor.y1,
    1281                 screenScissor.x1, screenScissor.y1,
    1282                 screenScissor.x2 - screenScissor.x1, screenScissor.y2 - screenScissor.y1);
    1283     }
     1259    //glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
     1260   
     1261    // Save the post-processing framebuffer.
     1262    GLint fbo;
     1263    glGetIntegerv(GL_FRAMEBUFFER_BINDING_EXT, &fbo);
     1264   
     1265    GLuint waterBuffer = 0;
     1266    pglGenFramebuffersEXT(1, &waterBuffer);
     1267    pglBindFramebufferEXT(GL_FRAMEBUFFER_EXT, waterBuffer);
     1268   
     1269    glBindTexture(GL_TEXTURE_2D, wm.m_RefractionTexture);
     1270    pglFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT, GL_TEXTURE_2D, wm.m_RefractionTexture, 0);
     1271   
     1272    glClearColor(0.5f,0.5f,1.0f,0.0f);
     1273    glClear(GL_COLOR_BUFFER_BIT);
     1274   
     1275    glEnable(GL_TEXTURE_2D);
     1276   
     1277    // Render sky, terrain and models
     1278    m->skyManager.RenderSky();
     1279    ogl_WarnIfError();
     1280    RenderPatches(context, &m_ViewCamera.GetFrustum());
     1281    ogl_WarnIfError();
     1282    RenderModels(context, &m_ViewCamera.GetFrustum());
     1283    ogl_WarnIfError();
     1284    RenderTransparentModels(context, TRANSPARENT_OPAQUE, &m_ViewCamera.GetFrustum());
     1285    ogl_WarnIfError();
     1286   
     1287    // rebind post-processing frambuffer.
     1288    pglBindFramebufferEXT(GL_FRAMEBUFFER_EXT, fbo);
     1289    glBindTexture(GL_TEXTURE_2D, 0);
    12841290
    12851291    // Reset old camera
    12861292    m_ViewCamera = normalCamera;
    12871293    m->SetOpenGLCamera(m_ViewCamera);
    1288 
    1289     return screenScissor;
    12901294}
    12911295
    12921296
     
    14291433
    14301434///////////////////////////////////////////////////////////////////////////////////////////////////
    14311435// RenderSubmissions: force rendering of any batched objects
    1432 void CRenderer::RenderSubmissions()
     1436void CRenderer::RenderSubmissions(const CBoundingBoxAligned& waterScissor)
    14331437{
    14341438    PROFILE3("render submissions");
    14351439   
     
    14741478    }
    14751479
    14761480    ogl_WarnIfError();
    1477 
    1478     CBoundingBoxAligned waterScissor;
    1479     if (m_WaterManager->m_RenderWater)
    1480     {
    1481         waterScissor = m->terrainRenderer.ScissorWater(m_ViewCamera.GetViewProjection());
    1482         if (waterScissor.GetVolume() > 0 && m_WaterManager->WillRenderFancyWater())
    1483         {
    1484             PROFILE3_GPU("water scissor");
    1485             SScreenRect dirty = { 0, 0, 0, 0 };
    1486             if (m_Options.m_WaterRefraction && m_Options.m_WaterReflection)
    1487             {
    1488                 SScreenRect reflectionScissor = RenderReflections(context, waterScissor);
    1489                 SScreenRect refractionScissor = RenderRefractions(context, waterScissor);
    1490                 dirty.x1 = std::min(reflectionScissor.x1, refractionScissor.x1);
    1491                 dirty.y1 = std::min(reflectionScissor.y1, refractionScissor.y1);
    1492                 dirty.x2 = std::max(reflectionScissor.x2, refractionScissor.x2);
    1493                 dirty.y2 = std::max(reflectionScissor.y2, refractionScissor.y2);
    1494             }
    1495             else if (m_Options.m_WaterRefraction)
    1496             {
    1497                 SScreenRect refractionScissor = RenderRefractions(context, waterScissor);
    1498                 dirty.x1 = refractionScissor.x1;
    1499                 dirty.y1 = refractionScissor.y1;
    1500                 dirty.x2 = refractionScissor.x2;
    1501                 dirty.y2 = refractionScissor.y2;
    1502             }
    1503             else if (m_Options.m_WaterReflection)
    1504             {
    1505                 SScreenRect reflectionScissor = RenderReflections(context, waterScissor);
    1506                 dirty.x1 = reflectionScissor.x1;
    1507                 dirty.y1 = reflectionScissor.y1;
    1508                 dirty.x2 = reflectionScissor.x2;
    1509                 dirty.y2 = reflectionScissor.y2;
    1510             }
    1511             if (dirty.x1 < dirty.x2 && dirty.y1 < dirty.y2)
    1512             {
    1513                 glEnable(GL_SCISSOR_TEST);
    1514                 glScissor(dirty.x1, dirty.y1, dirty.x2 - dirty.x1, dirty.y2 - dirty.y1);
    1515                 glClearColor(m_ClearColor[0], m_ClearColor[1], m_ClearColor[2], m_ClearColor[3]);
    1516                 glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
    1517                 glDisable(GL_SCISSOR_TEST);
    1518             }
    1519         }
    1520     }
    1521 
    15221481    if (m_Options.m_ShowSky)
    15231482    {
    15241483        m->skyManager.RenderSky();
     
    15401499    ogl_WarnIfError();
    15411500
    15421501    // render water
    1543     if (m_WaterManager->m_RenderWater && g_Game && waterScissor.GetVolume() > 0)
     1502    if (m_WaterManager->m_RenderWater && g_Game && waterScissor.GetVolume() > 0.0f)
    15441503    {
    15451504        // render transparent stuff, but only the solid parts that can occlude block water
    15461505        RenderTransparentModels(context, TRANSPARENT_OPAQUE);
     
    17291688    m->overlayRenderer.Submit(overlay);
    17301689}
    17311690
     1691void CRenderer::Submit(SOverlaySphere* overlay)
     1692{
     1693    m->overlayRenderer.Submit(overlay);
     1694}
     1695
    17321696void CRenderer::Submit(CModelDecal* decal)
    17331697{
    17341698    m->terrainRenderer.Submit(decal);
     
    17801744
    17811745    m->particleManager.RenderSubmit(*this, frustum);
    17821746
     1747    CBoundingBoxAligned waterScissor;
     1748    waterScissor = m->terrainRenderer.ScissorWater(m_ViewCamera.GetViewProjection());
     1749
    17831750    ogl_WarnIfError();
    17841751
    1785     RenderSubmissions();
     1752    RenderSubmissions(waterScissor);
     1753
     1754    RenderRefractions(waterScissor);
     1755   
     1756    // empty lists
     1757    m->terrainRenderer.EndFrame();
     1758    m->overlayRenderer.EndFrame();
     1759    m->particleRenderer.EndFrame();
     1760   
     1761    // Finish model renderers
     1762    m->Model.NormalSkinned->EndFrame();
     1763    m->Model.TranspSkinned->EndFrame();
     1764    if (m->Model.NormalUnskinned != m->Model.NormalSkinned)
     1765        m->Model.NormalUnskinned->EndFrame();
     1766    if (m->Model.TranspUnskinned != m->Model.TranspSkinned)
     1767        m->Model.TranspUnskinned->EndFrame();
     1768
     1769    ogl_WarnIfError();
     1770   
     1771    RenderReflections(scene, waterScissor);
    17861772
    17871773    m_CurrentScene = NULL;
    17881774}
  • source/renderer/Renderer.h

     
    349349    void Submit(SOverlayQuad* overlay);
    350350    void Submit(CModelDecal* decal);
    351351    void Submit(CParticleEmitter* emitter);
     352    void Submit(SOverlaySphere* overlay);
    352353    void SubmitNonRecursive(CModel* model);
    353354    //END: Implementation of SceneCollector
    354355
    355356    // render any batched objects
    356     void RenderSubmissions();
     357    void RenderSubmissions(const CBoundingBoxAligned& waterScissor);
    357358
    358359    // patch rendering stuff
    359360    void RenderPatches(const CShaderDefines& context, const CFrustum* frustum = 0);
     
    370371    void RenderShadowMap(const CShaderDefines& context);
    371372
    372373    // render water reflection and refraction textures
    373     SScreenRect RenderReflections(const CShaderDefines& context, const CBoundingBoxAligned& scissor);
    374     SScreenRect RenderRefractions(const CShaderDefines& context, const CBoundingBoxAligned& scissor);
     374    void RenderReflections(Scene& scene, const CBoundingBoxAligned& scissor);
     375    void RenderRefractions(const CBoundingBoxAligned& scissor);
    375376
    376377    // debugging
    377378    void DisplayFrustum();
  • source/renderer/Scene.h

     
    4040struct SOverlayTexturedLine;
    4141struct SOverlaySprite;
    4242struct SOverlayQuad;
     43struct SOverlaySphere;
    4344
    4445class SceneCollector;
    4546
     
    110111    virtual void Submit(SOverlayQuad* overlay) = 0;
    111112
    112113    /**
     114     * Submit a sphere overlay.
     115     */
     116    virtual void Submit(SOverlaySphere* overlay) = 0;
     117   
     118    /**
    113119     * Submit a terrain decal.
    114120     */
    115121    virtual void Submit(CModelDecal* decal) = 0;
  • source/simulation2/MessageTypes.h

     
    2727
    2828#include "simulation2/components/ICmpPathfinder.h"
    2929
     30#include "maths/Vector3D.h"
     31
    3032#define DEFAULT_MESSAGE_IMPL(name) \
    3133    virtual int GetType() const { return MT_##name; } \
    3234    virtual const char* GetScriptHandlerName() const { return "On" #name; } \
     
    258260    entity_angle_t a;
    259261};
    260262
     263class CMessageInterpolatedPositionChanged : public CMessage
     264{
     265    public:
     266    DEFAULT_MESSAGE_IMPL(InterpolatedPositionChanged)
     267   
     268    CMessageInterpolatedPositionChanged(entity_id_t entity, bool inWorld, const CVector3D& pos0, const CVector3D& pos1) :
     269    entity(entity), inWorld(inWorld), pos0(pos0), pos1(pos1)
     270    {
     271    }
     272   
     273    entity_id_t entity;
     274    bool inWorld;
     275    CVector3D pos0;
     276    CVector3D pos1;
     277};
     278
    261279/**
    262280 * Sent by CCmpUnitMotion during Update, whenever the motion status has changed
    263281 * since the previous update.
     
    277295};
    278296
    279297/**
     298 * Sent when water height has been changed.
     299 */
     300class CMessageWaterChanged : public CMessage
     301{
     302    public:
     303    DEFAULT_MESSAGE_IMPL(WaterChanged)
     304   
     305    CMessageWaterChanged()
     306    {
     307    }
     308};
     309
     310/**
    280311 * Sent when terrain (texture or elevation) has been changed.
    281312 */
    282313class CMessageTerrainChanged : public CMessage
  • source/simulation2/Simulation2.cpp

     
    104104        componentManager.AddComponent(systemEntity, CID_TemplateManager, noParam);
    105105
    106106        componentManager.AddComponent(systemEntity, CID_CommandQueue, noParam);
     107        componentManager.AddComponent(systemEntity, CID_ModelRenderer, noParam);
    107108        componentManager.AddComponent(systemEntity, CID_ObstructionManager, noParam);
    108109        componentManager.AddComponent(systemEntity, CID_ParticleManager, noParam);
    109110        componentManager.AddComponent(systemEntity, CID_Pathfinder, noParam);
  • source/simulation2/TypeList.h

     
    4242MESSAGE(Destroy)
    4343MESSAGE(OwnershipChanged)
    4444MESSAGE(PositionChanged)
     45MESSAGE(InterpolatedPositionChanged)
    4546MESSAGE(MotionChanged)
    4647MESSAGE(RangeUpdate)
    4748MESSAGE(TerrainChanged)
     49MESSAGE(WaterChanged)
    4850MESSAGE(TerritoriesChanged)
    4951MESSAGE(PathResult)
    5052MESSAGE(ValueModification)
     
    9092INTERFACE(Minimap)
    9193COMPONENT(Minimap)
    9294
     95INTERFACE(ModelRenderer)
     96COMPONENT(ModelRenderer)
     97
    9398INTERFACE(Motion)
    9499COMPONENT(MotionBall)
    95100COMPONENT(MotionScripted)
  • source/simulation2/components/CCmpPosition.cpp

     
    4343    {
    4444        componentManager.SubscribeToMessageType(MT_TurnStart);
    4545        componentManager.SubscribeToMessageType(MT_Interpolate);
     46        componentManager.SubscribeToMessageType(MT_TerrainChanged);
     47        componentManager.SubscribeToMessageType(MT_WaterChanged);
    4648
    4749        // TODO: if this component turns out to be a performance issue, it should
    4850        // be optimised by creating a new PositionStatic component that doesn't subscribe
     
    5961        UPRIGHT = 0,
    6062        PITCH = 1,
    6163        PITCH_ROLL = 2,
    62         ROLL=3,
     64        ROLL = 3,
    6365    } m_AnchorType;
    6466
    65     bool m_Floating;
    6667    float m_RotYSpeed; // maximum radians per second, used by InterpolatedRotY to follow RotY
    6768
     69    bool m_Floating;
    6870    // Dynamic state:
    6971
    7072    bool m_InWorld;
    7173    // m_LastX/Z contain the position from the start of the most recent turn
    7274    // m_PrevX/Z conatain the position from the turn before that
     75    bool m_RelativeToGround; // whether m_YOffset is relative to terrain/water plane, or an absolute height
    7376    entity_pos_t m_X, m_Z, m_LastX, m_LastZ, m_PrevX, m_PrevZ; // these values contain undefined junk if !InWorld
    7477    entity_pos_t m_YOffset, m_LastYOffset;
    75     bool m_RelativeToGround; // whether m_YOffset is relative to terrain/water plane, or an absolute height
    7678
    7779    entity_angle_t m_RotX, m_RotY, m_RotZ;
    7880
     
    221223        m_InWorld = false;
    222224
    223225        AdvertisePositionChanges();
     226        AdvertiseInterpolatedPositionChanges();
    224227    }
    225228
    226229    virtual void MoveTo(entity_pos_t x, entity_pos_t z)
     
    237240        }
    238241
    239242        AdvertisePositionChanges();
     243        AdvertiseInterpolatedPositionChanges();
    240244    }
    241245   
    242246    virtual void MoveAndTurnTo(entity_pos_t x, entity_pos_t z, entity_angle_t ry)
     
    254258        }
    255259       
    256260        AdvertisePositionChanges();
     261        AdvertiseInterpolatedPositionChanges();
    257262    }
    258263
    259264    virtual void JumpTo(entity_pos_t x, entity_pos_t z)
     
    268273        m_LastInterpolatedRotZ = m_InterpolatedRotZ;
    269274
    270275        AdvertisePositionChanges();
     276        AdvertiseInterpolatedPositionChanges();
    271277    }
    272278
    273279    virtual void SetHeightOffset(entity_pos_t dy)
     
    284290        }
    285291
    286292        AdvertisePositionChanges();
     293        AdvertiseInterpolatedPositionChanges();
    287294    }
    288295
    289296    virtual entity_pos_t GetHeightOffset()
     
    303310            m_LastYOffset = m_YOffset;
    304311            m_YOffset = y; 
    305312        }
     313       
     314        AdvertisePositionChanges();
     315        AdvertiseInterpolatedPositionChanges();
    306316    }
    307317
    308318    virtual bool IsFloating()
     
    495505       
    496506        return m;
    497507    }
     508   
     509    void GetInterpolatedPositions(CVector3D& pos0, CVector3D& pos1)
     510    {
     511        float baseY0 = 0;
     512        float baseY1 = 0;
     513        float x0 = m_LastX.ToFloat();
     514        float z0 = m_LastZ.ToFloat();
     515        float x1 = m_X.ToFloat();
     516        float z1 = m_Z.ToFloat();
     517        if (m_RelativeToGround)
     518        {
     519            CmpPtr<ICmpTerrain> cmpTerrain(GetSimContext(), SYSTEM_ENTITY);
     520            if (cmpTerrain)
     521            {
     522                baseY0 = cmpTerrain->GetExactGroundLevel(x0, z0);
     523                baseY1 = cmpTerrain->GetExactGroundLevel(x1, z1);
     524            }
     525           
     526            if (m_Floating)
     527            {
     528                CmpPtr<ICmpWaterManager> cmpWaterManager(GetSimContext(), SYSTEM_ENTITY);
     529                if (cmpWaterManager)
     530                {
     531                    baseY0 = std::max(baseY0, cmpWaterManager->GetExactWaterLevel(x0, z0));
     532                    baseY1 = std::max(baseY1, cmpWaterManager->GetExactWaterLevel(x1, z1));
     533                }
     534            }
     535        }
     536       
     537        float y0 = baseY0 + m_LastYOffset.ToFloat();
     538        float y1 = baseY1 + m_YOffset.ToFloat();
     539       
     540        pos0 = CVector3D(x0, y0, z0);
     541        pos1 = CVector3D(x1, y1, z1);
     542    }
    498543
    499544    virtual void HandleMessage(const CMessage& msg, bool UNUSED(global))
    500545    {
     
    558603
    559604            break;
    560605        }
     606        case MT_TerrainChanged:
     607        case MT_WaterChanged:
     608        {
     609            AdvertiseInterpolatedPositionChanges();
     610            break;
     611        }
    561612    }
    562613};
    563614
     
    575626            GetSimContext().GetComponentManager().PostMessage(GetEntityId(), msg);
    576627        }
    577628    }
    578 
     629   
     630    void AdvertiseInterpolatedPositionChanges()
     631    {
     632        if (m_InWorld)
     633        {
     634            CVector3D pos0, pos1;
     635            GetInterpolatedPositions(pos0, pos1);
     636           
     637            CMessageInterpolatedPositionChanged msg(GetEntityId(), true, pos0, pos1);
     638            GetSimContext().GetComponentManager().PostMessage(GetEntityId(), msg);
     639        }
     640        else
     641        {
     642            CMessageInterpolatedPositionChanged msg(GetEntityId(), false, CVector3D(), CVector3D());
     643            GetSimContext().GetComponentManager().PostMessage(GetEntityId(), msg);
     644        }
     645    }
     646   
    579647    void UpdateXZRotation()
    580648    {
    581649        if (!m_InWorld)
  • source/simulation2/components/CCmpRangeManager.cpp

     
    13611361            return VIS_VISIBLE;
    13621362
    13631363        // Fogged if the 'retain in fog' flag is set, and in a non-visible explored region
    1364         if (los.IsExplored(i, j))
     1364        if (los.IsExplored(i, j, true))
    13651365        {
    13661366            CmpPtr<ICmpVision> cmpVision(ent);
    13671367            if (forceRetainInFog || (cmpVision && cmpVision->GetRetainInFog()))
  • source/simulation2/components/CCmpTerrain.cpp

     
    144144    virtual void MakeDirty(i32 i0, i32 j0, i32 i1, i32 j1)
    145145    {
    146146        CMessageTerrainChanged msg(i0, j0, i1, j1);
    147         GetSimContext().GetComponentManager().PostMessage(GetEntityId(), msg);
     147        GetSimContext().GetComponentManager().BroadcastMessage(msg);
    148148    }
    149149};
    150150
  • source/simulation2/components/CCmpVisualActor.cpp

     
    2323#include "simulation2/MessageTypes.h"
    2424
    2525#include "ICmpFootprint.h"
     26#include "ICmpModelRenderer.h"
    2627#include "ICmpOwnership.h"
    2728#include "ICmpPosition.h"
    2829#include "ICmpRangeManager.h"
     
    4041#include "graphics/Unit.h"
    4142#include "graphics/UnitAnimation.h"
    4243#include "graphics/UnitManager.h"
     44#include "maths/BoundingSphere.h"
    4345#include "maths/Matrix3D.h"
    4446#include "maths/Vector3D.h"
    4547#include "ps/CLogger.h"
     
    5456    static void ClassInit(CComponentManager& componentManager)
    5557    {
    5658        componentManager.SubscribeToMessageType(MT_Update_Final);
    57         componentManager.SubscribeToMessageType(MT_Interpolate);
    58         componentManager.SubscribeToMessageType(MT_RenderSubmit);
     59        //componentManager.SubscribeToMessageType(MT_Interpolate);
     60        componentManager.SubscribeToMessageType(MT_InterpolatedPositionChanged);
     61        //componentManager.SubscribeToMessageType(MT_RenderSubmit);
    5962        componentManager.SubscribeToMessageType(MT_OwnershipChanged);
    60         componentManager.SubscribeGloballyToMessageType(MT_TerrainChanged);
     63        componentManager.SubscribeToMessageType(MT_TerrainChanged);
     64        componentManager.SubscribeToMessageType(MT_Destroy);
    6165    }
    6266
    6367    DEFAULT_COMPONENT_ALLOCATOR(VisualActor)
     
    9296    /// Whether the visual actor has been rendered at least once.
    9397    /// Necessary because the visibility update runs on simulation update,
    9498    /// which may not occur immediately if the game starts paused.
    95     bool m_PreviouslyRendered;
     99    //bool m_PreviouslyRendered;
     100   
     101    bool m_VisibilityDirty;
     102   
     103    ICmpModelRenderer::tag_t m_ModelTag;
    96104
    97105public:
    98106    static std::string GetSchema()
     
    178186
    179187    virtual void Init(const CParamNode& paramNode)
    180188    {
    181         m_PreviouslyRendered = false;
     189        // m_PreviouslyRendered = false;
     190        m_VisibilityDirty = true;
    182191        m_Unit = NULL;
    183192        m_Visibility = ICmpRangeManager::VIS_HIDDEN;
    184193        m_R = m_G = m_B = fixed::FromInt(1);
     
    295304            Interpolate(msgData.deltaSimTime, msgData.offset);
    296305            break;
    297306        }
    298         case MT_RenderSubmit:
    299         {
    300             const CMessageRenderSubmit& msgData = static_cast<const CMessageRenderSubmit&> (msg);
    301             RenderSubmit(msgData.collector, msgData.frustum, msgData.culling);
    302             break;
    303         }
     307        //case MT_RenderSubmit:
     308        //{
     309        //  const CMessageRenderSubmit& msgData = static_cast<const CMessageRenderSubmit&> (msg);
     310        //  RenderSubmit(msgData.collector, msgData.frustum, msgData.culling);
     311        //  break;
     312        //}
    304313        case MT_OwnershipChanged:
    305314        {
    306315            const CMessageOwnershipChanged& msgData = static_cast<const CMessageOwnershipChanged&> (msg);
     
    313322            m_Unit->GetModel().SetTerrainDirty(msgData.i0, msgData.j0, msgData.i1, msgData.j1);
    314323            break;
    315324        }
     325        case MT_InterpolatedPositionChanged:
     326        {
     327            const CMessageInterpolatedPositionChanged& msgData = static_cast<const CMessageInterpolatedPositionChanged&> (msg);
     328            if (m_ModelTag.valid())
     329            {
     330                CmpPtr<ICmpModelRenderer> cmpModelRenderer(GetSimContext(), SYSTEM_ENTITY);
     331                cmpModelRenderer->UpdateUnitPos(m_ModelTag, msgData.inWorld, msgData.pos0, msgData.pos1);
     332            }
     333            break;
     334        }
     335        case MT_Destroy:
     336        {
     337            if (m_ModelTag.valid())
     338            {
     339                CmpPtr<ICmpModelRenderer> cmpModelRenderer(GetSimContext(), SYSTEM_ENTITY);
     340                cmpModelRenderer->RemoveUnit(m_ModelTag);
     341                m_ModelTag = ICmpModelRenderer::tag_t();
     342            }
     343            break;
     344        }
    316345        }
    317346    }
    318347
     
    450479        m_G = g;
    451480        m_B = b;
    452481        UNUSED2(a); // TODO: why is this even an argument?
     482
     483        if (m_Unit)
     484        {
     485            CModelAbstract& model = m_Unit->GetModel();
     486            model.SetShadingColor(CColor(m_R.ToFloat(), m_G.ToFloat(), m_B.ToFloat(), 1.0f));
     487        }
    453488    }
    454489
    455490    virtual void SetVariable(std::string name, float value)
     
    507542    void Update(fixed turnLength);
    508543    void UpdateVisibility();
    509544    void Interpolate(float frameTime, float frameOffset);
    510     void RenderSubmit(SceneCollector& collector, const CFrustum& frustum, bool culling);
     545    //void RenderSubmit(SceneCollector& collector, const CFrustum& frustum, bool culling);
    511546};
    512547
    513548REGISTER_COMPONENT_TYPE(VisualActor)
     
    516551
    517552void CCmpVisualActor::InitModel(const CParamNode& paramNode)
    518553{
    519     if (GetSimContext().HasUnitManager())
     554    if (!GetSimContext().HasUnitManager())
     555        return;
     556   
     557    std::set<CStr> selections;
     558    m_Unit = GetSimContext().GetUnitManager().CreateUnit(m_ActorName, GetActorSeed(), selections);
     559    if (!m_Unit)
     560        return;
     561   
     562    CModelAbstract& model = m_Unit->GetModel();
     563    if (model.ToCModel())
    520564    {
    521         std::set<CStr> selections;
    522         m_Unit = GetSimContext().GetUnitManager().CreateUnit(m_ActorName, GetActorSeed(), selections);
    523         if (m_Unit)
    524         {
    525             CModelAbstract& model = m_Unit->GetModel();
    526             if (model.ToCModel())
    527             {
    528                 u32 modelFlags = 0;
    529 
    530                 if (paramNode.GetChild("SilhouetteDisplay").ToBool())
    531                     modelFlags |= MODELFLAG_SILHOUETTE_DISPLAY;
    532 
    533                 if (paramNode.GetChild("SilhouetteOccluder").ToBool())
    534                     modelFlags |= MODELFLAG_SILHOUETTE_OCCLUDER;
    535 
    536                 CmpPtr<ICmpVision> cmpVision(GetEntityHandle());
    537                 if (cmpVision && cmpVision->GetAlwaysVisible())
    538                     modelFlags |= MODELFLAG_IGNORE_LOS;
    539 
    540                 model.ToCModel()->AddFlagsRec(modelFlags);
    541             }
    542 
    543             if (paramNode.GetChild("DisableShadows").IsOk())
    544             {
    545                 if (model.ToCModel())
    546                     model.ToCModel()->RemoveShadowsRec();
    547                 else if (model.ToCModelDecal())
    548                     model.ToCModelDecal()->RemoveShadows();
    549             }
    550 
    551             // Initialize the model's selection shape descriptor. This currently relies on the component initialization order; the
    552             // Footprint component must be initialized before this component (VisualActor) to support the ability to use the footprint
    553             // shape for the selection box (instead of the default recursive bounding box). See TypeList.h for the order in
    554             // which components are initialized; if for whatever reason you need to get rid of this dependency, you can always just
    555             // initialize the selection shape descriptor on-demand.
    556             InitSelectionShapeDescriptor(paramNode);
     565        u32 modelFlags = 0;
     566       
     567        if (paramNode.GetChild("SilhouetteDisplay").ToBool())
     568        modelFlags |= MODELFLAG_SILHOUETTE_DISPLAY;
     569       
     570        if (paramNode.GetChild("SilhouetteOccluder").ToBool())
     571        modelFlags |= MODELFLAG_SILHOUETTE_OCCLUDER;
     572       
     573        CmpPtr<ICmpVision> cmpVision(GetEntityHandle());
     574        if (cmpVision && cmpVision->GetAlwaysVisible())
     575        modelFlags |= MODELFLAG_IGNORE_LOS;
     576       
     577        model.ToCModel()->AddFlagsRec(modelFlags);
     578    }
    557579
    558             m_Unit->SetID(GetEntityId());
     580    if (paramNode.GetChild("DisableShadows").IsOk())
     581    {
     582        if (model.ToCModel())
     583        model.ToCModel()->RemoveShadowsRec();
     584        else if (model.ToCModelDecal())
     585        model.ToCModelDecal()->RemoveShadows();
     586    }
     587   
     588    // Initialize the model's selection shape descriptor. This currently relies on the component initialization order; the
     589    // Footprint component must be initialized before this component (VisualActor) to support the ability to use the footprint
     590    // shape for the selection box (instead of the default recursive bounding box). See TypeList.h for the order in
     591    // which components are initialized; if for whatever reason you need to get rid of this dependency, you can always just
     592    // initialize the selection shape descriptor on-demand.
     593    InitSelectionShapeDescriptor(paramNode);
     594   
     595    m_Unit->SetID(GetEntityId());
     596   
     597    model.SetShadingColor(CColor(m_R.ToFloat(), m_G.ToFloat(), m_B.ToFloat(), 1.0f));
     598   
     599    if (!m_ModelTag.valid())
     600    {
     601        CmpPtr<ICmpModelRenderer> cmpModelRenderer(GetSimContext(), SYSTEM_ENTITY);
     602        if (cmpModelRenderer)
     603        {
     604            // TODO: account for props, animations
     605            // TODO: use object bounds
     606            CBoundingBoxAligned bounds = m_Unit->GetModel().GetWorldBoundsRec();
     607            CBoundingSphere boundSphere = CBoundingSphere::FromSweptBox(bounds);
     608            m_ModelTag = cmpModelRenderer->AddUnit(GetEntityHandle(), m_Unit, boundSphere);
    559609        }
    560610    }
    561611}
     
    636686    if (!m_Unit)
    637687        return;
    638688
    639     std::set<CStr> selections;
    640     CUnit* newUnit = GetSimContext().GetUnitManager().CreateUnit(m_ActorName, GetActorSeed(), selections);
    641 
    642     if (!newUnit)
    643         return;
    644 
    645689    // Save some data from the old unit
    646690    CColor shading = m_Unit->GetModel().GetShadingColor();
    647691    player_id_t playerID = m_Unit->GetModel().GetPlayerID();
     
    669713    m_Unit->GetModel().SetShadingColor(shading);
    670714
    671715    m_Unit->GetModel().SetPlayerID(playerID);
     716   
     717    if (m_ModelTag.valid())
     718    {
     719        CmpPtr<ICmpModelRenderer> cmpModelRenderer(GetSimContext(), SYSTEM_ENTITY);
     720        CBoundingBoxAligned bounds = m_Unit->GetModel().GetWorldBoundsRec();
     721        CBoundingSphere boundSphere = CBoundingSphere::FromSweptBox(bounds);
     722        cmpModelRenderer->UpdateUnit(m_ModelTag, m_Unit, boundSphere);
     723    }
    672724}
    673725
    674726void CCmpVisualActor::Update(fixed UNUSED(turnLength))
    675727{
    676728    if (m_Unit == NULL)
    677729        return;
    678 
     730   
     731    if (m_ModelTag.valid())
     732    {
     733        CmpPtr<ICmpModelRenderer> cmpModelRenderer(GetSimContext(), SYSTEM_ENTITY);
     734        if(cmpModelRenderer->isCulled(m_ModelTag))
     735            return;
     736    }
    679737    UpdateVisibility();
    680 
    681738    // If we're in the special movement mode, select an appropriate animation
    682739    if (!m_AnimRunThreshold.IsZero())
    683740    {
     
    742799    }
    743800    else
    744801        m_Visibility = ICmpRangeManager::VIS_HIDDEN;
    745 
    746     if (m_Visibility != oldVisibility)
     802   
     803    bool oldHidden = (oldVisibility == ICmpRangeManager::VIS_HIDDEN);
     804    bool newHidden = (m_Visibility == ICmpRangeManager::VIS_HIDDEN);
     805    if (oldHidden != newHidden)
    747806    {
    748807        // Change the visibility of the visual actor's selectable if it has one.
    749808        CmpPtr<ICmpSelectable> cmpSelectable(GetEntityHandle());
    750809        if (cmpSelectable)
    751             cmpSelectable->SetVisibility(m_Visibility == ICmpRangeManager::VIS_HIDDEN ? false : true);
     810        cmpSelectable->SetVisibility(!newHidden);
     811       
     812        if (m_ModelTag.valid())
     813        {
     814            CmpPtr<ICmpModelRenderer> cmpModelRenderer(GetSimContext(), SYSTEM_ENTITY);
     815            cmpModelRenderer->UpdateUnitVisible(m_ModelTag, !newHidden);
     816        }
    752817    }
     818   
     819    m_VisibilityDirty = false;
    753820}
    754821
    755 void CCmpVisualActor::Interpolate(float frameTime, float frameOffset)
     822void CCmpVisualActor::Interpolate(float frameTime, float UNUSED(frameOffset))
    756823{
    757824    if (m_Unit == NULL)
    758825        return;
    759826
     827    if (m_VisibilityDirty)
     828        UpdateVisibility();
     829
     830    if (m_ModelTag.valid())
     831    {
     832        CmpPtr<ICmpModelRenderer> cmpModelRenderer(GetSimContext(), SYSTEM_ENTITY);
     833        if(cmpModelRenderer->isCulled(m_ModelTag))
     834            return;
     835    }
     836   
     837    m_Unit->UpdateModel(frameTime);
     838
     839    // If not hidden, then we need to set up some extra state for rendering
     840    if (m_Visibility != ICmpRangeManager::VIS_HIDDEN)
     841    {
     842        m_Unit->GetModel().ValidatePosition();
     843        m_Unit->GetModel().SetShadingColor(CColor(m_R.ToFloat(), m_G.ToFloat(), m_B.ToFloat(), 1.0f));
     844    }
     845
     846    /*
    760847    // Disable rendering of the unit if it has no position
    761848    CmpPtr<ICmpPosition> cmpPosition(GetEntityHandle());
    762849    if (!cmpPosition || !cmpPosition->IsInWorld())
     
    791878            {
    792879                CVector3D pos = transform.GetTranslation();
    793880                float ground = cmpTerrain->GetExactGroundLevel(pos.X, pos.Z);
    794                 dy += std::max(0.f, pos.Y - ground);
     881                dy = std::max(0.f, pos.Y - ground);
    795882            }
    796883
    797884            transform.Translate(0.0f, (m_ConstructionProgress.ToFloat() - 1.0f) * dy, 0.0f);
     
    801888    CModelAbstract& model = m_Unit->GetModel();
    802889
    803890    model.SetTransform(transform);
    804     m_Unit->UpdateModel(frameTime);
    805 
    806     // If not hidden, then we need to set up some extra state for rendering
    807     if (m_Visibility != ICmpRangeManager::VIS_HIDDEN)
    808     {
    809         model.ValidatePosition();
    810         model.SetShadingColor(CColor(m_R.ToFloat(), m_G.ToFloat(), m_B.ToFloat(), 1.0f));
    811     }
     891    */
    812892}
    813893
     894/*
    814895void CCmpVisualActor::RenderSubmit(SceneCollector& collector, const CFrustum& frustum, bool culling)
    815896{
    816897    if (m_Unit == NULL)
     
    832913
    833914    collector.SubmitRecursive(&model);
    834915}
     916 */
  • source/simulation2/components/CCmpWaterManager.cpp

     
    103103
    104104        // Tell the terrain it'll need to recompute its cached render data
    105105        GetSimContext().GetTerrain().MakeDirty(RENDERDATA_UPDATE_VERTICES);
     106
     107        CMessageWaterChanged msg;
     108        GetSimContext().GetComponentManager().BroadcastMessage(msg);
    106109    }
    107110
    108111    virtual entity_pos_t GetWaterLevel(entity_pos_t UNUSED(x), entity_pos_t UNUSED(z))
  • source/simulation2/components/ICmpRangeManager.h

     
    252252        /**
    253253         * Returns whether the given vertex is explored (i.e. was (or still is) within a unit's LOS).
    254254         */
    255         inline bool IsExplored(ssize_t i, ssize_t j)
     255        inline bool IsExplored(ssize_t i, ssize_t j, bool extended = false)
    256256        {
    257257            if (!(i >= 0 && j >= 0 && i < m_VerticesPerSide && j < m_VerticesPerSide))
    258258                return false;
     
    261261            if ((m_Data[j*m_VerticesPerSide + i] & m_PlayerMask) & 0x55555555u)
    262262                return true;
    263263            else
     264            {
     265                if (extended/*m_HighQual*/) // TODO: this should be a setting
     266                {
     267                    if (i > 0 && (m_Data[j*m_VerticesPerSide + i - 1] & m_PlayerMask) & 0x55555555u)
     268                        return true;
     269                    if (i < m_VerticesPerSide - 1 && (m_Data[j*m_VerticesPerSide + i + 1] & m_PlayerMask) & 0x55555555u)
     270                        return true;
     271                    if (j > 0 && (m_Data[(j-1)*m_VerticesPerSide + i] & m_PlayerMask) & 0x55555555u)
     272                        return true;
     273                    if (j < m_VerticesPerSide - 1 && (m_Data[(j+1)*m_VerticesPerSide + i] & m_PlayerMask) & 0x55555555u)
     274                        return true;
     275                }
    264276                return false;
     277            }
    265278        }
    266279
    267280        /**
  • source/simulation2/scripting/MessageTypeConversions.cpp

     
    216216
    217217////////////////////////////////
    218218
     219jsval CMessageInterpolatedPositionChanged::ToJSVal(ScriptInterface& UNUSED(scriptInterface)) const
     220{
     221    LOGWARNING(L"CMessageInterpolatedPositionChanged::ToJSVal not implemented");
     222    return JSVAL_VOID;
     223}
     224
     225CMessage* CMessageInterpolatedPositionChanged::FromJSVal(ScriptInterface& UNUSED(scriptInterface), jsval UNUSED(val))
     226{
     227    LOGWARNING(L"CMessageInterpolatedPositionChanged::FromJSVal not implemented");
     228    return NULL;
     229}
     230
     231////////////////////////////////
     232
     233
    219234jsval CMessageMotionChanged::ToJSVal(ScriptInterface& scriptInterface) const
    220235{
    221236    TOJSVAL_SETUP();
     
    256271
    257272////////////////////////////////
    258273
     274jsval CMessageWaterChanged::ToJSVal(ScriptInterface& scriptInterface) const
     275{
     276    TOJSVAL_SETUP();
     277    return OBJECT_TO_JSVAL(obj);
     278}
     279
     280CMessage* CMessageWaterChanged::FromJSVal(ScriptInterface& UNUSED(scriptInterface), jsval UNUSED(val))
     281{
     282    return new CMessageWaterChanged();
     283}
     284
     285////////////////////////////////
     286
     287
    259288jsval CMessageTerritoriesChanged::ToJSVal(ScriptInterface& scriptInterface) const
    260289{
    261290    TOJSVAL_SETUP();