[Gcblue-commits] gcb_wx/src/graphics cspSky.cpp,1.14,1.15 tc3DModel.cpp,1.27,1.28 tc3DViewer.cpp,1.2
Status: Alpha
Brought to you by:
ddcforge
|
From: Dewitt C. <ddc...@us...> - 2005-07-16 23:13:18
|
Update of /cvsroot/gcblue/gcb_wx/src/graphics In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv26502/src/graphics Modified Files: cspSky.cpp tc3DModel.cpp tc3DViewer.cpp tc3DWindow.cpp tcMapView.cpp tcTerrainView.cpp Log Message: Fix for horizon darkening bug, option cleanup Index: tc3DModel.cpp =================================================================== RCS file: /cvsroot/gcblue/gcb_wx/src/graphics/tc3DModel.cpp,v retrieving revision 1.27 retrieving revision 1.28 diff -C2 -d -r1.27 -r1.28 *** tc3DModel.cpp 14 Jul 2005 23:42:22 -0000 1.27 --- tc3DModel.cpp 16 Jul 2005 23:12:38 -0000 1.28 *************** *** 128,134 **** if (node.getNumParents() == 1) { ! ! osg::MatrixTransform *rotateTransform = new osg::MatrixTransform; ! rotateTransform->setDataVariance(osg::Object::DYNAMIC); // temporarily hold node to avoid delete when removing from parent --- 128,132 ---- if (node.getNumParents() == 1) { ! osg::MatrixTransform *rotateTransform = 0; // temporarily hold node to avoid delete when removing from parent *************** *** 139,146 **** if (osg::Group* pivotParent = GetPivotParent(parent, pivotRotate, childIdx)) // check if this is a pivot { osg::ref_ptr<osg::Group> temp = pivotRotate; pivotParent->setChild(childIdx, rotateTransform); rotateTransform->addChild(pivotRotate); ! if (tcOptions::Get()->OptionStringExists("Log3DModelDetails")) --- 137,148 ---- if (osg::Group* pivotParent = GetPivotParent(parent, pivotRotate, childIdx)) // check if this is a pivot { + rotateTransform = dynamic_cast<osg::MatrixTransform*>(pivotRotate); + wxASSERT(rotateTransform != 0); + + /* osg::ref_ptr<osg::Group> temp = pivotRotate; pivotParent->setChild(childIdx, rotateTransform); rotateTransform->addChild(pivotRotate); ! */ if (tcOptions::Get()->OptionStringExists("Log3DModelDetails")) *************** *** 151,154 **** --- 153,159 ---- else { + rotateTransform = new osg::MatrixTransform; + rotateTransform->setDataVariance(osg::Object::DYNAMIC); + childIdx = parent->getChildIndex(&node); osg::BoundingSphere bs = node.getBound(); Index: cspSky.cpp =================================================================== RCS file: /cvsroot/gcblue/gcb_wx/src/graphics/cspSky.cpp,v retrieving revision 1.14 retrieving revision 1.15 diff -C2 -d -r1.14 -r1.15 *** cspSky.cpp 1 Jun 2005 00:13:30 -0000 1.14 --- cspSky.cpp 16 Jul 2005 23:12:38 -0000 1.15 *************** *** 205,212 **** } ! bool computeBound() const { ! _bbox._min = Vec3(-1000100.0, -1000100.0, 0.0); ! _bbox._max = Vec3( 1000100.0, 1000100.0, 1000100.0); ! return true; } --- 205,213 ---- } ! // DDC modified for 0.9.9 ! osg::BoundingBox computeBound() const { ! _boundingBox._min = Vec3(-1000100.0, -1000100.0, 0.0); ! _boundingBox._max = Vec3( 1000100.0, 1000100.0, 1000100.0); ! return _boundingBox; } *************** *** 334,338 **** float ambient = background; if (ambient > 0.1) ambient = 0.1; ! // the sky shading at the sun's position is too blue when the sun // is high to use as the light color. instead we use the approximate --- 335,339 ---- float ambient = background; if (ambient > 0.1) ambient = 0.1; ! // the sky shading at the sun's position is too blue when the sun // is high to use as the light color. instead we use the approximate *************** *** 577,580 **** --- 578,582 ---- geom->setTexCoordArray(0,tcoords); + osg::Vec4Array* colours = new osg::Vec4Array(1); (*colours)[0].set(1.0f,1.0f,1.0,1.0f); *************** *** 1004,1007 **** --- 1006,1010 ---- rgb.check(); #endif // CUSTOM + return rgb; } *************** *** 1067,1070 **** --- 1070,1074 ---- void updateHorizonColors(Vec4Array const &colors) { + return; assert(int(colors.size()) == m_Segments); for (int i=0; i < m_Segments; i++) (*m_Colors)[i] = colors[i]; *************** *** 1078,1081 **** --- 1082,1086 ---- void updateHorizon(float altitude, float clip) { + return; float a = 0.0; float da = 2.0 * C_PI / m_Segments; *************** *** 1128,1132 **** m_lev = new float[90]; ! float base_elev = -10.0; m_nlev = 0; m_HorizonIndex = 0; --- 1133,1137 ---- m_lev = new float[90]; ! float base_elev = -20.0; m_nlev = 0; m_HorizonIndex = 0; *************** *** 1144,1154 **** } } ! m_nseg = 37; int i, j; float x, y, z; float alpha, theta; ! //float radius = 1100000.0f; ! float radius = 95000.0f; m_Horizon = new FalseHorizon; #ifdef TEXDOME --- 1149,1159 ---- } } ! m_nseg = 36; int i, j; float x, y, z; float alpha, theta; ! float radius = 1100000.0f; ! m_Horizon = new FalseHorizon; #ifdef TEXDOME *************** *** 1191,1196 **** colors[ci][3] = 1.0; ! tcoords[ci][0] = 0.5f + min(0.5f, (90.0f - m_lev[i]) / 180.0f) * cosf(theta); ! tcoords[ci][1] = 0.5f + min(0.5f, (90.0f - m_lev[i]) / 180.0f) * sinf(theta); (*cindex)[ci] = static_cast<unsigned short>(ci); --- 1196,1206 ---- colors[ci][3] = 1.0; ! /* DDC: this code produced dark horizon artifacts at 0, 90, 180, 270, ended up shutting off ! ** texturing for non TEXDOME mode */ ! // tcoords[ci][0] = 0.5f + min(0.5f, (90.0f - m_lev[i]) / 180.0f) * cosf(theta); ! // tcoords[ci][1] = 0.5f + min(0.5f, (90.0f - m_lev[i]) / 180.0f) * sinf(theta); ! ! tcoords[ci][0] = 0; ! tcoords[ci][1] = 1; (*cindex)[ci] = static_cast<unsigned short>(ci); *************** *** 1247,1250 **** --- 1257,1261 ---- dome_state->setMode(GL_CULL_FACE, StateAttribute::OFF); dome_state->setMode(GL_FOG, osg::StateAttribute::OFF); + dome_state->setMode(GL_TEXTURE_2D, osg::StateAttribute::OFF); // stops dark horizon artifacts in non TEXDOME mode // render bins: skydome and stars = -3, moon = -2, terrain = -1, rest = 0 (default) dome_state->setRenderBinDetails(-3,"RenderBin"); *************** *** 1343,1346 **** --- 1354,1358 ---- _updateShading(sun_h, sun_A); + // get the sky shading at the position of the sun m_ZenithColor = m_SkyShader.SkyColor(light_h, 0.0, 0.0, m_ZenithIntensity); *************** *** 1360,1364 **** --- 1372,1379 ---- #ifndef TEXDOME void Sky::_updateShading(double sun_h, double sun_A) { + Vec4Array& colors = *(dynamic_cast<Vec4Array*>(m_SkyDome->getColorArray())); + + double da = 2.0 * C_PI / (m_nseg); double min_a = 0.5*da; *************** *** 1370,1375 **** for (i = 0; i < m_nlev; ++i) { double elev = UnitConversions::toRadians(m_lev[i]); ! ! if (elev < 0.0) elev = 0.0; // sub horizon colors aren't correct double azimuth = -sun_A - 0.5 * C_PI; bool at_vertex = fabs(elev - sun_h) < min_a; // this is only a rough measure --- 1385,1393 ---- for (i = 0; i < m_nlev; ++i) { double elev = UnitConversions::toRadians(m_lev[i]); ! ! if (elev < 0.0) ! { ! elev = 0.0; // sub horizon colors aren't correct ! } double azimuth = -sun_A - 0.5 * C_PI; bool at_vertex = fabs(elev - sun_h) < min_a; // this is only a rough measure *************** *** 1392,1399 **** --- 1410,1419 ---- colors[ci][3] = 1.0; + if (i == m_HorizonIndex) { (*m_HorizonColors)[j] = colors[ci]; horizon_average += colors[ci]; } + ++ci; *************** *** 1533,1536 **** --- 1553,1557 ---- osg::Vec4 Sky::getHorizonColor(float angle) { static int avg = 0; + // skydome wraps around clockwise angle = -angle; Index: tcMapView.cpp =================================================================== RCS file: /cvsroot/gcblue/gcb_wx/src/graphics/tcMapView.cpp,v retrieving revision 1.30 retrieving revision 1.31 diff -C2 -d -r1.30 -r1.31 *** tcMapView.cpp 30 Jun 2005 01:06:10 -0000 1.30 --- tcMapView.cpp 16 Jul 2005 23:12:38 -0000 1.31 *************** *** 692,695 **** --- 692,696 ---- defaultFont.get(), color, 16.0, LEFT_BASE_LINE); + #if 0 if ((mpOptions!=NULL) && (mpOptions->mbShowMapDebug)) { *************** *** 704,707 **** --- 705,709 ---- defaultFont.get(), color, 16.0, LEFT_BASE_LINE); } + #endif /*** Draw map command graphics ***/ *************** *** 1847,1850 **** --- 1849,1858 ---- int fillMode = (mpOptions->mbFillRangeCircles) ? FILL_ON : FILL_OFF; + osg::Vec4 pieColor = symbolColor; + if (fillMode == FILL_ON) + { + pieColor._v[3] *= 0.5f; + } + osg::Geometry* rangeCircle; if (pMO->mfArc_deg >= 360.0f) *************** *** 2661,2667 **** //DrawGrid(); - if ((mpOptions!=NULL) && (mpOptions->mbShowMapDebug)) - { - } for(i=0;(i<(int)mnObjCount)&&(i<MAXWORLDMAPOBJ);i++) --- 2669,2672 ---- Index: tcTerrainView.cpp =================================================================== RCS file: /cvsroot/gcblue/gcb_wx/src/graphics/tcTerrainView.cpp,v retrieving revision 1.7 retrieving revision 1.8 diff -C2 -d -r1.7 -r1.8 *** tcTerrainView.cpp 1 Jun 2005 00:13:31 -0000 1.7 --- tcTerrainView.cpp 16 Jul 2005 23:12:38 -0000 1.8 *************** *** 175,188 **** { tsMapDataInfo sMDI; - bool mbTextureMaps; - - if (mpOptions != NULL) - { - mbTextureMaps = mpOptions->mbTextureMappedMaps == 1; - } - else - { - mbTextureMaps = true; - } mpMapData->GetMapDataInfo(&sMDI); // get size of map data arrays --- 175,178 ---- Index: tc3DWindow.cpp =================================================================== RCS file: /cvsroot/gcblue/gcb_wx/src/graphics/tc3DWindow.cpp,v retrieving revision 1.23 retrieving revision 1.24 diff -C2 -d -r1.23 -r1.24 *** tc3DWindow.cpp 11 Jun 2005 21:01:44 -0000 1.23 --- tc3DWindow.cpp 16 Jul 2005 23:12:38 -0000 1.24 *************** *** 31,34 **** --- 31,35 ---- #include <osg/Geode> #include <osg/Geometry> + #include <osg/Group> #include <osg/LineWidth> #include <osg/MatrixTransform> Index: tc3DViewer.cpp =================================================================== RCS file: /cvsroot/gcblue/gcb_wx/src/graphics/tc3DViewer.cpp,v retrieving revision 1.22 retrieving revision 1.23 diff -C2 -d -r1.22 -r1.23 *** tc3DViewer.cpp 14 Jul 2005 23:42:22 -0000 1.22 --- tc3DViewer.cpp 16 Jul 2005 23:12:38 -0000 1.23 *************** *** 25,29 **** #ifndef WX_PRECOMP #include "wx/wx.h" - #include "wx/msw/private.h" // for MS Windows specific definitions #endif --- 25,28 ---- *************** *** 32,35 **** --- 31,35 ---- #include "tc3DViewer.h" #include "math_constants.h" + #include <osg/AlphaFunc> #include <osg/BlendFunc> #include <osg/CullStack> *************** *** 359,363 **** int correctedY = parentHeight - (pos.y + size.GetHeight()); sceneView->setViewport(pos.x,correctedY, size.GetWidth(),size.GetHeight()); ! sceneViewFar->setViewport(pos.x,correctedY, size.GetWidth(),size.GetHeight()); mnWidth = size.GetWidth(); --- 359,367 ---- int correctedY = parentHeight - (pos.y + size.GetHeight()); sceneView->setViewport(pos.x,correctedY, size.GetWidth(),size.GetHeight()); ! ! if (sceneViewFar.valid()) ! { ! sceneViewFar->setViewport(pos.x,correctedY, size.GetWidth(),size.GetHeight()); ! } mnWidth = size.GetWidth(); *************** *** 435,455 **** { osgUtil::RenderStage* stage = sceneView->getRenderStage(); - osgUtil::RenderStage* stageFar = sceneViewFar->getRenderStage(); if (modeCode == 1) { stage->setClearMask(GL_DEPTH_BUFFER_BIT); - stageFar->setClearMask(GL_DEPTH_BUFFER_BIT); } else if (modeCode == 2) { ! stage->setClearMask(GL_DEPTH_BUFFER_BIT); ! stageFar->setClearMask(GL_DEPTH_BUFFER_BIT | GL_COLOR_BUFFER_BIT); } else { stage->setClearMask(0); - stageFar->setClearMask(0); } } --- 439,480 ---- { osgUtil::RenderStage* stage = sceneView->getRenderStage(); if (modeCode == 1) { stage->setClearMask(GL_DEPTH_BUFFER_BIT); } else if (modeCode == 2) { ! if (useFarSceneView) ! { ! stage->setClearMask(GL_DEPTH_BUFFER_BIT); ! } ! else ! { ! stage->setClearMask(GL_DEPTH_BUFFER_BIT | GL_COLOR_BUFFER_BIT); ! } } else { stage->setClearMask(0); } + + if (sceneViewFar.valid()) + { + osgUtil::RenderStage* stageFar = sceneViewFar->getRenderStage(); + if (modeCode == 1) + { + stageFar->setClearMask(GL_DEPTH_BUFFER_BIT); + } + else if (modeCode == 2) + { + stageFar->setClearMask(GL_DEPTH_BUFFER_BIT | GL_COLOR_BUFFER_BIT); + } + else + { + stageFar->setClearMask(0); + } + } + } *************** *** 460,464 **** { wxASSERT(foggedObjects.valid()); - wxASSERT(sceneViewFar.valid()); osg::StateSet* fogState = foggedObjects->getOrCreateStateSet(); --- 485,488 ---- *************** *** 470,477 **** } if (mode == FOG_OFF) { fogState->setMode(GL_FOG, osg::StateAttribute::OFF); ! sceneViewFar->setClearColor(osg::Vec4(0, 0, 0, 1)); return; } --- 494,504 ---- } + osgUtil::SceneView* view = (useFarSceneView) ? sceneViewFar.get() : sceneView.get(); + wxASSERT(view != 0); + if (mode == FOG_OFF) { fogState->setMode(GL_FOG, osg::StateAttribute::OFF); ! view->setClearColor(osg::Vec4(0, 0, 0, 1)); return; } *************** *** 490,494 **** fog->setEnd(60000.0f); fog->setDensity(0.000006f); ! sceneViewFar->setClearColor(airFog); } else --- 517,521 ---- fog->setEnd(60000.0f); fog->setDensity(0.000006f); ! view->setClearColor(airFog); } else *************** *** 498,502 **** fog->setEnd(60000.0f); fog->setDensity(0.0006f); ! sceneViewFar->setClearColor(waterFog); } --- 525,529 ---- fog->setEnd(60000.0f); fog->setDensity(0.0006f); ! view->setClearColor(waterFog); } *************** *** 831,835 **** rootnode->addChild(foggedObjects.get()); ! rootnodeFar->addChild(skyTransform.get()); /* For some strange reason, adding the orthoProjection to --- 858,866 ---- rootnode->addChild(foggedObjects.get()); ! ! if (useFarSceneView) ! { ! rootnodeFar->addChild(skyTransform.get()); ! } /* For some strange reason, adding the orthoProjection to *************** *** 922,930 **** guiView->draw(); ! if (isActive && sceneView.valid() && sceneViewFar.valid()) { ! sceneViewFar->update(); ! sceneViewFar->cull(); ! sceneViewFar->draw(); sceneView->update(); --- 953,964 ---- guiView->draw(); ! if (isActive && sceneView.valid()) { ! if (sceneViewFar.valid()) ! { ! sceneViewFar->update(); ! sceneViewFar->cull(); ! sceneViewFar->draw(); ! } sceneView->update(); *************** *** 1046,1050 **** } ! // workaround for sky issue, deactivate sky when camera underwater if (cameraPosition._v[2] < -1.0) --- 1080,1085 ---- } ! osg::Group* terrainRoot = (useFarSceneView) ? rootnodeFar.get() : rootnode.get(); ! // workaround for sky issue, deactivate sky when camera underwater if (cameraPosition._v[2] < -1.0) *************** *** 1052,1056 **** if (skyTransform->getNumParents()) { ! rootnodeFar->removeChild(skyTransform.get()); SetFogMode(FOG_WATER); } --- 1087,1091 ---- if (skyTransform->getNumParents()) { ! terrainRoot->removeChild(skyTransform.get()); SetFogMode(FOG_WATER); } *************** *** 1060,1064 **** if (isTerrainActive && (skyTransform->getNumParents() == 0)) { ! rootnodeFar->addChild(skyTransform.get()); SetFogMode(FOG_AIR); } --- 1095,1099 ---- if (isTerrainActive && (skyTransform->getNumParents() == 0)) { ! terrainRoot->addChild(skyTransform.get()); SetFogMode(FOG_AIR); } *************** *** 1079,1083 **** sceneView->setViewMatrixAsLookAt(cameraPosition, cameraTarget, osg::Vec3(0,0,1)); ! sceneViewFar->setViewMatrixAsLookAt(cameraPosition, cameraTarget, osg::Vec3(0,0,1)); //osgAL::SoundManager::instance()->getListener()->setPosition(cameraPosition.x(), cameraPosition.y(), --- 1114,1121 ---- sceneView->setViewMatrixAsLookAt(cameraPosition, cameraTarget, osg::Vec3(0,0,1)); ! if (sceneViewFar.valid()) ! { ! sceneViewFar->setViewMatrixAsLookAt(cameraPosition, cameraTarget, osg::Vec3(0,0,1)); ! } //osgAL::SoundManager::instance()->getListener()->setPosition(cameraPosition.x(), cameraPosition.y(), *************** *** 1428,1431 **** --- 1466,1470 ---- void tc3DViewer::InitSceneViewFar(wxPoint pos, wxSize size) { + wxASSERT(useFarSceneView); sceneViewFar = new osgUtil::SceneView(); *************** *** 1583,1594 **** osg::ref_ptr<osg::Node> terrainNode = terrainManager->GetTerrainNode().get(); if (state) { if (skyTransform->getNumParents() == 0) { ! rootnodeFar->addChild(skyTransform.get()); } foggedObjects->addChild(terrainNode.get()); foggedObjects->addChild(skyLights.get()); // update terrain here with current origin since it isn't updated while inactive terrainManager->SetOrigin(lonOrigin_rad, latOrigin_rad); --- 1622,1637 ---- osg::ref_ptr<osg::Node> terrainNode = terrainManager->GetTerrainNode().get(); + osg::Group* terrainRoot = (useFarSceneView) ? rootnodeFar.get() : rootnode.get(); + wxASSERT(terrainRoot); + if (state) { if (skyTransform->getNumParents() == 0) { ! terrainRoot->addChild(skyTransform.get()); } foggedObjects->addChild(terrainNode.get()); foggedObjects->addChild(skyLights.get()); + // update terrain here with current origin since it isn't updated while inactive terrainManager->SetOrigin(lonOrigin_rad, latOrigin_rad); *************** *** 1597,1601 **** { // skyTransform already removed if camera underwater ! rootnodeFar->removeChild(skyTransform.get()); if (unsigned int nParents = skyTransform->getNumParents()) { --- 1640,1645 ---- { // skyTransform already removed if camera underwater ! ! terrainRoot->removeChild(skyTransform.get()); if (unsigned int nParents = skyTransform->getNumParents()) { *************** *** 1603,1607 **** "skyTransform still has (%d) parents after removal\n", nParents); } ! if (!foggedObjects->removeChild(terrainNode.get()) || !foggedObjects->removeChild(skyLights.get())) --- 1647,1651 ---- "skyTransform still has (%d) parents after removal\n", nParents); } ! if (!foggedObjects->removeChild(terrainNode.get()) || !foggedObjects->removeChild(skyLights.get())) *************** *** 1799,1802 **** --- 1843,1854 ---- pm->setMode(osg::PolygonMode::Face::FRONT_AND_BACK, osg::PolygonMode::FILL); } + + if (useFarSceneView) + { + // do same for far sceneview + stateSet = rootnodeFar->getOrCreateStateSet(); + wxASSERT(stateSet); + stateSet->setAttribute(pm, osg::StateAttribute::ON); + } } *************** *** 1861,1873 **** wxASSERT(sceneView.valid()); - float zmid = sqrtf(zmin*zmax); - float aspectRatio = (float)windowSize.GetWidth() / (float)windowSize.GetHeight(); ! sceneView->setProjectionMatrixAsPerspective(45.0, aspectRatio, zmin, zmid); ! if (sceneViewFar.valid()) ! { ! sceneViewFar->setProjectionMatrixAsPerspective(45.0, aspectRatio, zmid-20, zmax); ! } } --- 1913,1931 ---- wxASSERT(sceneView.valid()); float aspectRatio = (float)windowSize.GetWidth() / (float)windowSize.GetHeight(); ! if (useFarSceneView) ! { ! float zmid = sqrtf(zmin*zmax); ! sceneView->setProjectionMatrixAsPerspective(45.0, aspectRatio, zmin, zmid); ! if (sceneViewFar.valid()) ! { ! sceneViewFar->setProjectionMatrixAsPerspective(45.0, aspectRatio, zmid-20, zmax); ! } ! } ! else ! { ! sceneView->setProjectionMatrixAsPerspective(45.0, aspectRatio, zmin, zmax); ! } } *************** *** 1890,1896 **** lonOrigin_rad = 0; zmin = 2.0f; ! zmax = 131072.0f; ! zmax = 50000.0f; ! shiftDistance = 50000.0f; --- 1948,1971 ---- lonOrigin_rad = 0; zmin = 2.0f; ! ! // user-selected options ------------------- ! tcOptions* options = tcOptions::Get(); ! if (options->max3Drange == 2) ! { ! zmax = 100000.0f; ! } ! else if (options->max3Drange == 1) ! { ! zmax = 75000.0f; ! } ! else ! { ! zmax = 50000.0f; ! } ! ! useFarSceneView = options->useFarSceneView; ! ! shakeAirCamera = options->OptionStringExists("ShakeAirCamera"); ! // ---------------------- shiftDistance = 50000.0f; *************** *** 1921,1925 **** InitSceneView(pos, size); ! InitSceneViewFar(pos, size); InitGuiView(); --- 1996,2003 ---- InitSceneView(pos, size); ! if (useFarSceneView) ! { ! InitSceneViewFar(pos, size); ! } InitGuiView(); *************** *** 1944,1952 **** rootnode = new osg::Group; - rootnodeFar = new osg::Group; - rootnodeFar->addChild(rootnode.get()); sceneView->setSceneData(rootnode.get()); ! sceneViewFar->setSceneData(rootnodeFar.get()); hudObjects = new osg::MatrixTransform; --- 2022,2034 ---- rootnode = new osg::Group; sceneView->setSceneData(rootnode.get()); ! ! if (useFarSceneView) ! { ! rootnodeFar = new osg::Group; ! rootnodeFar->addChild(rootnode.get()); ! sceneViewFar->setSceneData(rootnodeFar.get()); ! } hudObjects = new osg::MatrixTransform; *************** *** 1966,1971 **** tc3DModel::LoadUnknowns(); - shakeAirCamera = tcOptions::Get()->OptionStringExists("ShakeAirCamera"); - defaultSensorModel = new tc3DModel(); defaultSensorModel->LoadXml("unknown.xml"); --- 2048,2051 ---- |