From 72c11e58c69428befadd6fbf4398e22e9330dede Mon Sep 17 00:00:00 2001 From: madbad Date: Fri, 21 Apr 2023 14:34:25 +0000 Subject: [PATCH] Merge branch 'osghud-improvements' git-svn-id: https://svn.code.sf.net/p/speed-dreams/code/trunk@8892 30fe4595-0a0c-4342-8851-515496e4dcbd Former-commit-id: 04aadc7f04df7f2caacd030505cad745d62bad05 Former-commit-id: 47be97407410efcd21ef0dd37db1fdb2fe150a14 --- .../graphic/osggraph/Viewer/OsgHUD.cpp | 621 +++++++++++++++++- src/modules/graphic/osggraph/Viewer/OsgHUD.h | 8 + src/modules/racing/standardgame/racecars.cpp | 4 +- 3 files changed, 611 insertions(+), 22 deletions(-) diff --git a/src/modules/graphic/osggraph/Viewer/OsgHUD.cpp b/src/modules/graphic/osggraph/Viewer/OsgHUD.cpp index 36ba4ad0..a323c1dc 100644 --- a/src/modules/graphic/osggraph/Viewer/OsgHUD.cpp +++ b/src/modules/graphic/osggraph/Viewer/OsgHUD.cpp @@ -85,6 +85,8 @@ int hudScreenW = 0; //edithud bool hudEditModeEnabled = false; +float tempVal = 0.0f; + // TODO[START]: move this to utils? /src/modules/graphic/osggraph/Utils static void split(const std::string &s, char delim, std::vector &elems) { @@ -98,6 +100,13 @@ static void split(const std::string &s, char delim, std::vector &el } } +double getCathetusTwoLength(double cateto1, double angoloVertice1) { + double angoloVertice2 = 45 - angoloVertice1; + double ipotenusa = cateto1 / cos(angoloVertice1 * M_PI / 180); + double cateto2 = ipotenusa * tan(angoloVertice2 * M_PI / 180); + return cateto2; +} + static std::vector split(const std::string &s, char delim) { std::vector elems; @@ -671,6 +680,364 @@ void SDHUD::changeImageSize(osg::Geometry *geom, } } +void SDHUD::changeImageVertex(osg::Geometry *geom, + float fromAngle, + float toAngle, + float currValue, + float newPosX, + float newPosY, + float hudScale) + +{ + GfLogInfo("pos %f %f\n", newPosX, newPosY); + osg::TextureRectangle* texture; + + //get the texture data of this object + texture = dynamic_cast(geom->getStateSet()->getTextureAttribute(0,osg::StateAttribute::TEXTURE)); + + //get the image from the texture data + osg::Image* img; + img = texture->getImage(); + + //get image dimensions + float width = img->s(); + float height = img->t(); + + //rerieve to start modifing vertex and UVs + osg::Vec3Array* vertices = dynamic_cast(geom->getVertexArray()); + osg::Vec2Array* texcoords = dynamic_cast(geom->getTexCoordArray(0)); + + //determine the start and end triangle + int startTriangle = ceil((fromAngle+0.0001)/45.0)-1; + int endTriangle = ceil((toAngle)/45.0)-1; + + if(startTriangle < 0){ + startTriangle = startTriangle + 8; + } + + //determine the range of angle we will be using to cover 100% of the value + float angleRange = 0.0f; + if(fromAngle > toAngle){ + angleRange = (360-fromAngle)+toAngle; + }else{ + angleRange = toAngle-fromAngle; + } + + //what angle we need to add to the start angle to reach the current value angle + float currValueAngle = angleRange*currValue; + + //determine the angle we can use for the first triangle (in case the start is not at his 0 angle) + float startTriangleStartAngle = std::fmod( fromAngle, 45.0f ); + float startTriangleAngleCapacity = 45.0f - std::fmod( fromAngle, 45.0f ); + + //determine the angle we can use for final triangle (in case the start is not at his 0 angle) + float finalTriangleAngleCapacity = std::fmod( toAngle , 45.0f ); + + //determine how many triangles we will need to process + int trianglesNeeded = ceil((currValueAngle - startTriangleAngleCapacity) / 45)+1; + + //determine what will be the last triangle given the current value + int currValueLastTriangle = ((startTriangle + trianglesNeeded) % 8 ) - 1; + if(currValueLastTriangle < 0){ + currValueLastTriangle = currValueLastTriangle + 8; + } + + //determine a modifier for the triangle index that we will use in the next for cicle, so that we will start processing from the start to the final triangle + //despite the starting triangle being greater than the final triangle + int indexModifier = 0; + if(startTriangle <= endTriangle){ + indexModifier = 0; + }else{ + indexModifier = startTriangle; + } + + float angleRangeToBeUsed = currValueAngle; + + for (int triangle = 0; triangle <= 7; triangle++) { + int triangleIdx = triangle + indexModifier; + if(triangleIdx > 7){ + triangleIdx = triangleIdx - 8; + } + float newAngle=0.0; + + //se è il primo triangolo e ci sta tutto il valore uso il valore necessario + if(triangleIdx == startTriangle){ + if(angleRangeToBeUsed <= startTriangleAngleCapacity){ + newAngle = angleRangeToBeUsed; + angleRangeToBeUsed = angleRangeToBeUsed - newAngle; + }else{ + newAngle = startTriangleAngleCapacity; + angleRangeToBeUsed = angleRangeToBeUsed - newAngle; + } + //if it's the first triangle the initial start angle may not be the local 0 so + //we need to add to the startingPointAngle to the desidered value + //we will fix this when calculating vertex 2 + } + + //vale per tutti gli altri angoli (se è zero resta zero, se è maggiore di 45 uso 45) + if( + (startTriangle <= endTriangle ) && (triangleIdx > startTriangle) + || (startTriangle > endTriangle ) && (triangleIdx > startTriangle || triangleIdx <= endTriangle) + ){ + if(angleRangeToBeUsed <= 45.0){ + newAngle = angleRangeToBeUsed; + angleRangeToBeUsed = angleRangeToBeUsed - newAngle; + }else{ + newAngle = 45.0; + angleRangeToBeUsed = angleRangeToBeUsed - newAngle; + } + } + + /* + GfLogDebug("TriangleIndex %i (%i)", triangleIdx, triangle); + GfLogDebug(" CurrValueAngle %f\n", currValueAngle); + GfLogDebug(" Angoli richiesti %i \n",trianglesNeeded); + GfLogDebug(" Triangle index (Start/End) %i ## %i\n", startTriangle, currValueLastTriangle); + GfLogDebug(" Angle to be used %f \n",angleRangeToBeUsed); + GfLogDebug(" My angle %f \n",newAngle ); + GfLogDebug(" Start Triangle start angle %f \n",startTriangleStartAngle ); + */ + + for (int vertex = 0;vertex <= 2; vertex++ ){ + int vertexIndex= (triangleIdx*3)+vertex; + float CathetusTwoLength = 0.0; + float newX = 0.0; + float newY = 0.0; + + //GfLogDebug("VertexIndex %i \n", vertexIndex); + /*----------------------------------------------------------------------------------------------------------------------------*/ + //for all vertex start by restoring their original status + + if (vertex == 0){ + newX = 0.5f; + newY = 0.5f; + } + if (vertex == 1){ + switch (triangleIdx) { + case 0: + newX = 0.0; + newY = 0.5; + break; + case 2: + newX = 0.5; + newY = 1.0; + break; + case 4: + newX = 1.0; + newY = 0.5; + break; + case 6: + newX = 0.5; + newY = 0.0; + break; + //------------------------------------------------------------------------------ + case 1: + newX = 0.0; + newY = 1.0; + break; + case 3: + newX = 1.0; + newY = 1.0; + break; + case 5: + newX = 1.0; + newY = 0.0; + break; + case 7: + newX = 0.0; + newY = 0.0; + break; + default: + break; + } + } + + if (vertex == 2){ + switch (triangleIdx) { + case 0: + newX = 0.0; + newY = 1.0; + break; + case 2: + newX = 1.0; + newY = 1.0; + break; + case 4: + newX = 1.0; + newY = 0.0; + break; + case 6: + newX = 0.0; + newY = 0.0; + break; + //------------------------------------------------------------- + case 1: + newX = 0.5; + newY = 1.0; + break; + case 3: + newX = 1.0; + newY = 0.5; + break; + case 5: + newX = 0.5; + newY = 0.0; + break; + case 7: + newX = 0.0; + newY = 0.5; + break; + default: + break; + } + } + (*vertices)[vertexIndex][0] = newPosX + newX * width * hudScale; //imgWidth; //x + (*vertices)[vertexIndex][1] = newPosY + newY * height * hudScale; //imgHeight; //y + //update uvs + (*texcoords)[vertexIndex][0] = newX; + (*texcoords)[vertexIndex][1] = newY; + /*----------------------------------------------------------------------------------------------------------------------------*/ + + //now adjust what is needed: + //for start triangle we need to update the second vertice + //for end triangle we need to update the third vertice + //for hidden triangles we just hide everything + + //start triangle + if (triangleIdx == startTriangle && vertex ==1){ + switch (triangleIdx) { + case 0: + CathetusTwoLength = getCathetusTwoLength(0.5, startTriangleStartAngle); + newX = 0.0; + newY = 1.0 - CathetusTwoLength; + break; + case 2: + CathetusTwoLength = getCathetusTwoLength(0.5, startTriangleStartAngle); + newX = 1.0-CathetusTwoLength; + newY = 1.0; + break; + case 4: + CathetusTwoLength = getCathetusTwoLength(0.5, startTriangleStartAngle); + newX = 1.0; + newY = CathetusTwoLength; + break; + case 6: + CathetusTwoLength = getCathetusTwoLength(0.5, startTriangleStartAngle); + newX = CathetusTwoLength; + newY = 0.0; + break; + //------------------------------------------------------------------------------ + case 1: + CathetusTwoLength = getCathetusTwoLength(0.5, startTriangleStartAngle); + newX = 0.5-CathetusTwoLength; + newY = 1.0; + break; + case 3: + CathetusTwoLength = getCathetusTwoLength(0.5, startTriangleStartAngle); + newX = 1.0; + newY = 0.5+CathetusTwoLength; + break; + case 5: + CathetusTwoLength = getCathetusTwoLength(0.5, startTriangleStartAngle); + newX = 0.5+CathetusTwoLength; + newY = 0.0; + break; + case 7: + CathetusTwoLength = getCathetusTwoLength(0.5, startTriangleStartAngle); + newX = 0.0; + newY = 0.5-CathetusTwoLength; + break; + default: + break; + } + //update vertices + (*vertices)[vertexIndex][0] = newPosX + newX * width * hudScale; //imgWidth; //x + (*vertices)[vertexIndex][1] = newPosY + newY * height * hudScale; //imgHeight; //y + //update uvs + (*texcoords)[vertexIndex][0]= newX; + (*texcoords)[vertexIndex][1]= newY; + } + + //end triangle + if (triangleIdx == currValueLastTriangle && vertex == 2){ + //we need to fix a special case in case the first triangle is also the last triangle + //in this case we want the startingAngle to be added to the desiredValueAngle + if (triangleIdx == startTriangle){ + newAngle = newAngle + startTriangleStartAngle; + } + + switch (triangleIdx) { + case 0: + CathetusTwoLength = getCathetusTwoLength(0.5, 45.0-newAngle); + newX = 0.0; + newY = 0.5+CathetusTwoLength; + break; + case 2: + CathetusTwoLength = getCathetusTwoLength(0.5, 45.0-newAngle); + newX = 0.5+CathetusTwoLength; + newY = 1.0; + break; + case 4: + CathetusTwoLength = getCathetusTwoLength(0.5, 45.0-newAngle); + newX = 1.0; + newY = 0.5-CathetusTwoLength; + break; + case 6: + CathetusTwoLength = getCathetusTwoLength(0.5, 45.0-newAngle); + newX = 0.5-CathetusTwoLength; + newY = 0.0; + break; + //------------------------------------------------------------- + case 1: + CathetusTwoLength = getCathetusTwoLength(0.5, 45.0-newAngle); + newX = CathetusTwoLength; + newY = 1.0; + break; + case 3: + CathetusTwoLength = getCathetusTwoLength(0.5, 45.0-newAngle); + newX = 1.0; + newY = 1.0-CathetusTwoLength; + break; + case 5: + CathetusTwoLength = getCathetusTwoLength(0.5, 45.0-newAngle); + newX = 1.0-CathetusTwoLength; + newY = 0.0; + break; + case 7: + CathetusTwoLength = getCathetusTwoLength(0.5, 45.0-newAngle); + newX = 0.0; + newY = CathetusTwoLength; + break; + default: + break; + } + (*vertices)[vertexIndex][0] = newPosX + newX * width * hudScale; //imgWidth; //x + (*vertices)[vertexIndex][1] = newPosY + newY * height * hudScale; //imgHeight; //y + //update uvs + (*texcoords)[vertexIndex][0]= newX; + (*texcoords)[vertexIndex][1]= newY; + } + + //if hidden triangle + if( newAngle <= 0.0 ){ + newX = 0.0f; + newY = 0.0f; + (*vertices)[vertexIndex][0] = newX * width * hudScale; //imgWidth; //x + (*vertices)[vertexIndex][1] = newY * height * hudScale; //imgHeight; //y + //update uvs + (*texcoords)[vertexIndex][0]= newX; + (*texcoords)[vertexIndex][1]= newY; + } + } + } + //adapt the geometry + vertices->dirty(); + geom->setVertexArray(vertices); + //adapt the texture + geom->setTexCoordArray(0,texcoords); +} + + void SDHUD::changeImagePosition(osg::Geometry *geom, float newX, float newY, @@ -694,19 +1061,6 @@ void SDHUD::changeImagePosition(osg::Geometry *geom, //osg::Vec3Array* vertices = new osg::Vec3Array; osg::Vec3Array* vertices = dynamic_cast(geom->getVertexArray()); - /* - * how vertices are arranged: - * 3_______2 - * | | - * y | | - * | | - * 0_______1 - * x - * - * [vertices(0-3)][0]=x - * [vertices(0-3)][1]=y - * */ - //change the position (*vertices)[0][0] = newX; (*vertices)[0][1] = newY; @@ -1426,10 +1780,8 @@ void SDHUD::Refresh(tSituation *s, const SDFrameInfo* frameInfo, if (currCar->_bestLapTime != 0){ float deltabest = currCar->_currLapTimeAtTrackPosition[(int)currCar->_distFromStartLine] - currCar->_bestLapTimeAtTrackPosition[(int)currCar->_distFromStartLine]; - GfLogDebug("OSGHUD curr: %f \n", currCar->_currLapTimeAtTrackPosition[(int)currCar->_distFromStartLine]); - - GfLogDebug("OSGHUD best: %f \n", currCar->_bestLapTimeAtTrackPosition[(int)currCar->_distFromStartLine]); - + GfLogDebug("OSGHUD curr: %f \n", currCar->_currLapTimeAtTrackPosition[(int)currCar->_distFromStartLine]); + GfLogDebug("OSGHUD best: %f \n", currCar->_bestLapTimeAtTrackPosition[(int)currCar->_distFromStartLine]); if(deltabest > 0){//we are slower float scale = 0.0f; @@ -1457,9 +1809,41 @@ void SDHUD::Refresh(tSituation *s, const SDFrameInfo* frameInfo, changeImageSize(hudImgElements["delta-gaining"], 0, "left", hudScale); changeImageSize(hudImgElements["delta-losing"], 0, "right", hudScale); } - - +//tachometer + osg::BoundingBox newtachobb =hudImgElements["tachometer"]->getBoundingBox(); + //let the final 15% be redline + float redLinePercent = 0.15f; //15% + float whiteLinePercent = 1.0f-redLinePercent; //85% + float rpmVal1 = 0.0f; + float rpmVal2 = 0.0f; + float startAngle = 291.0f; + float endAngle = 180.0f; + float totalAngleRange = 0.0f; + float endOfWhiteLineAngle = 0.0f; + + if(startAngle < endAngle){ + totalAngleRange = endAngle - startAngle; + endOfWhiteLineAngle = (totalAngleRange * whiteLinePercent) + startAngle; + }else{ + totalAngleRange = (360.0f - startAngle) + endAngle; + endOfWhiteLineAngle = (totalAngleRange * whiteLinePercent) - (360.0f - startAngle); + if(endOfWhiteLineAngle < 0){ + endOfWhiteLineAngle = endOfWhiteLineAngle + 360.0f; + } + } + + if(currCar->_enginerpm <= (currCar->_enginerpmRedLine * whiteLinePercent)){ + rpmVal1 = currCar->_enginerpm / (currCar->_enginerpmRedLine * whiteLinePercent); + rpmVal2 = 0.0; + }else{ + rpmVal1 = 1.0; + rpmVal2 = (currCar->_enginerpm - (currCar->_enginerpmRedLine * whiteLinePercent)) / (currCar->_enginerpmRedLine * redLinePercent); + } + + changeImageVertex(hudImgVertexElements["newtacho-rpmon"], startAngle, endOfWhiteLineAngle, rpmVal1, newtachobb.xMin(), newtachobb.yMin(), hudScale); + changeImageVertex(hudImgVertexElements["newtacho-rpmonred"], endOfWhiteLineAngle, endAngle, rpmVal2, newtachobb.xMin(), newtachobb.yMin(), hudScale); + //edithud if (hudEditModeEnabled){ //if there is some widgetGroup selected display the edithud and relative controls around it else keep it hidden @@ -1714,6 +2098,7 @@ void SDHUD::ToggleHUD() hudElementsVisibilityStatus["racelapsWidget"] = (int)hudWidgets["racelapsWidget"]->getNodeMask(); hudElementsVisibilityStatus["laptimeWidget"] = (int)hudWidgets["laptimeWidget"]->getNodeMask(); hudElementsVisibilityStatus["carinfoWidget"] = (int)hudWidgets["carinfoWidget"]->getNodeMask(); + hudElementsVisibilityStatus["newtacho-rpmon"]= (int)hudImgVertexElements["newtacho-rpmon"]->getNodeMask(); hudElementsVisibilityStatus["carstatusWidget"] = (int)hudWidgets["carstatusWidget"]->getNodeMask(); hudElementsVisibilityStatus["driverinputWidget"] = (int)hudWidgets["driverinputWidget"]->getNodeMask(); hudElementsVisibilityStatus["driverinput-wheel"] = (int)hudImgRotableElements["driverinput-wheel"]->getNodeMask(); @@ -1732,6 +2117,7 @@ void SDHUD::ToggleHUD() hudWidgets["racelapsWidget"]->setNodeMask(0); hudWidgets["laptimeWidget"]->setNodeMask(0); hudWidgets["carinfoWidget"]->setNodeMask(0); + hudImgVertexElements["newtacho-rpmon"]->setNodeMask(0); hudWidgets["carstatusWidget"]->setNodeMask(0); hudWidgets["driverinputWidget"]->setNodeMask(0); hudImgRotableElements["driverinput-wheel"]->setNodeMask(0); @@ -1751,6 +2137,7 @@ void SDHUD::ToggleHUD() hudWidgets["racelapsWidget"]->setNodeMask(hudElementsVisibilityStatus["racelapsWidget"]); hudWidgets["laptimeWidget"]->setNodeMask(hudElementsVisibilityStatus["laptimeWidget"]); hudWidgets["carinfoWidget"]->setNodeMask(hudElementsVisibilityStatus["carinfoWidget"]); + hudImgVertexElements["newtacho-rpmon"]->setNodeMask(hudElementsVisibilityStatus["newtacho-rpmon"]); hudWidgets["carstatusWidget"]->setNodeMask(hudElementsVisibilityStatus["carstatusWidget"]); hudWidgets["driverinputWidget"]->setNodeMask(hudElementsVisibilityStatus["driverinputWidget"]); hudImgRotableElements["driverinput-wheel"]->setNodeMask(hudElementsVisibilityStatus["driverinput-wheel"]); @@ -1835,6 +2222,7 @@ osg::ref_ptr SDHUD::generateHudFromXmlFile(int scrH, int scrW) { widgetsSectionName = GfParmListGetCurEltName(paramHandle, mainSection.c_str()); widgetsSectionPath = mainSection + "/" + widgetsSectionName; + GfLogDebug("OSGHUD: Generating hud: %s \n", widgetsSectionName.c_str()); osg::ref_ptr geode = new osg::Geode; geode->setName(widgetsSectionName); @@ -2086,6 +2474,199 @@ osg::ref_ptr SDHUD::generateHudFromXmlFile(int scrH, int scrW) } } } + else if( type == "imagevertex") + { + /* ============================ + CREATE OSG IMAGEVERTEX + ============================*/ + //read data into local variables + const std::string &elementId = subSectionName; + std::string url = GfParmGetStr (paramHandle, subSectionPath.c_str(),"url", "" ); + std::string positionRefObj = GfParmGetStr (paramHandle, subSectionPath.c_str(),"position-refObj", "" ); + std::string positionRefObjPoint = GfParmGetStr (paramHandle, subSectionPath.c_str(),"position-refObjPoint", "tl" ); + std::string positionMyPoint = GfParmGetStr (paramHandle, subSectionPath.c_str(),"position-myPoint", "tl" ); + float positionVerticalModifier = GfParmGetNum (paramHandle, subSectionPath.c_str(),"position-verticalModifier", "",0 ) * hudScale; + float positionHorizontalModifier = GfParmGetNum (paramHandle, subSectionPath.c_str(),"position-horizontalModifier", "",0 ) * hudScale; + + GfLogDebug("OSGHUD: Generate imagevertex object: %s \n", elementId.c_str()); + + osg::ref_ptr myGeode = new osg::Geode; + osg::ref_ptr myGeometry = new osg::Geometry; + osg::ref_ptr myVertices = new osg::Vec3Array; + osg::ref_ptr myNormals = new osg::Vec3Array; + osg::ref_ptr myTexCoords = new osg::Vec2Array; //(UV) + + //start preparing the image + std::string myFilename = GetDataDir(); + //std::string myUrl = "data/img/osg-hud/tachometerv2-on.png"; + //myFilename.append(myUrl); + myFilename.append(url); + //check that the image file exist + if (!GfFileExists(myFilename.c_str())) + { + GfLogError ("OSGHUD: Specified image file does not exist: %s.\n", myFilename.c_str()); + } + + // setup texture + osg::Image* myImg = osgDB::readImageFile(myFilename); + osg::TextureRectangle* myTexture = new osg::TextureRectangle; + myTexture->setImage(myImg); + //get image size + //get image dimensions + float width = myImg->s(); + float height = myImg->t(); + + + //set the position + //find the referenceObj bounding box + osg::BoundingBox refObjBb = getBoundigBoxFromWidgetName(positionRefObj); + + //get object bounding box + osg::BoundingBox myObjBb; + myObjBb.expandBy(osg::Vec3(0.0f,0.0f,0.0f)); + myObjBb.expandBy(osg::Vec3(width,height,0.0f)); + + //calculate the positioning + osg::Vec3 position = calculatePosition(myObjBb,positionMyPoint,refObjBb,positionRefObjPoint, positionVerticalModifier, positionHorizontalModifier); + + //asign the position + float positionLeft = position.x(); + float positionBottom = position.y(); + + //vertices + //triangle 1 + myVertices->push_back ( osg::Vec3(0.5*width+positionLeft, 0.5*height+positionBottom, 1.0)); //1 + myVertices->push_back ( osg::Vec3(0.0*width+positionLeft, 0.5*height+positionBottom, 1.0)); //2 + myVertices->push_back ( osg::Vec3(0.0*width+positionLeft, 1.0*height+positionBottom, 1.0)); //3 + //triangle 2 + myVertices->push_back ( osg::Vec3(0.5*width+positionLeft, 0.5*height+positionBottom, 1.0)); //1 + myVertices->push_back ( osg::Vec3(0.0*width+positionLeft, 1.0*height+positionBottom, 1.0)); //2 + myVertices->push_back ( osg::Vec3(0.5*width+positionLeft, 1.0*height+positionBottom, 1.0)); //3 + //triangle 3 + myVertices->push_back ( osg::Vec3(0.5*width+positionLeft, 0.5*height+positionBottom, 1.0)); //1 + myVertices->push_back ( osg::Vec3(0.5*width+positionLeft, 1.0*height+positionBottom, 1.0)); //2 + myVertices->push_back ( osg::Vec3(1.0*width+positionLeft, 1.0*height+positionBottom, 1.0)); //3 + //triangle 4 + myVertices->push_back ( osg::Vec3(0.5*width+positionLeft, 0.5*height+positionBottom, 1.0)); //1 + myVertices->push_back ( osg::Vec3(1.0*width+positionLeft, 1.0*height+positionBottom, 1.0)); //2 + myVertices->push_back ( osg::Vec3(1.0*width+positionLeft, 0.5*height+positionBottom, 1.0)); //3 + //triangle 5 + myVertices->push_back ( osg::Vec3(0.5*width+positionLeft, 0.5*height+positionBottom, 1.0)); //1 + myVertices->push_back ( osg::Vec3(1.0*width+positionLeft, 0.5*height+positionBottom, 1.0)); //2 + myVertices->push_back ( osg::Vec3(1.0*width+positionLeft, 0.0*height+positionBottom, 1.0)); //3 + //triangle 6 + myVertices->push_back ( osg::Vec3(0.5*width+positionLeft, 0.5*height+positionBottom, 1.0)); //1 + myVertices->push_back ( osg::Vec3(1.0*width+positionLeft, 0.0*height+positionBottom, 1.0)); //2 + myVertices->push_back ( osg::Vec3(0.5*width+positionLeft, 0.0*height+positionBottom, 1.0)); //3 + //triangle 7 + myVertices->push_back ( osg::Vec3(0.5*width+positionLeft, 0.5*height+positionBottom, 1.0)); //1 + myVertices->push_back ( osg::Vec3(0.5*width+positionLeft, 0.0*height+positionBottom, 1.0)); //2 + myVertices->push_back ( osg::Vec3(0.0*width+positionLeft, 0.0*height+positionBottom, 1.0)); //3 + //triangle 8 + myVertices->push_back ( osg::Vec3(0.5*width+positionLeft, 0.5*height+positionBottom, 1.0)); //1 + myVertices->push_back ( osg::Vec3(0.0*width+positionLeft, 0.0*height+positionBottom, 1.0)); //2 + myVertices->push_back ( osg::Vec3(0.0*width+positionLeft, 0.5*height+positionBottom, 1.0)); //3 + + myGeometry->setVertexArray ( myVertices ); + + //UV's + //triangle 1 + myTexCoords->push_back( osg::Vec2(0.5, 0.5)); //1 + myTexCoords->push_back( osg::Vec2(0.0, 0.5)); //2 + myTexCoords->push_back( osg::Vec2(0.0, 1.0)); //3 + //triangle 2 + myTexCoords->push_back( osg::Vec2(0.5, 0.5)); //1 + myTexCoords->push_back( osg::Vec2(0.0, 1.0)); //2 + myTexCoords->push_back( osg::Vec2(0.5, 1.0)); //3 + //triangle 3 + myTexCoords->push_back( osg::Vec2(0.5, 0.5)); //1 + myTexCoords->push_back( osg::Vec2(0.5, 1.0)); //2 + myTexCoords->push_back( osg::Vec2(1.0, 1.0)); //3 + //triangle 4 + myTexCoords->push_back( osg::Vec2(0.5, 0.5)); //1 + myTexCoords->push_back( osg::Vec2(1.0, 1.0)); //2 + myTexCoords->push_back( osg::Vec2(1.0, 0.5)); //3 + //triangle 5 + myTexCoords->push_back( osg::Vec2(0.5, 0.5)); //1 + myTexCoords->push_back( osg::Vec2(1.0, 0.5)); //2 + myTexCoords->push_back( osg::Vec2(1.0, 0.0)); //3 + //triangle 6 + myTexCoords->push_back( osg::Vec2(0.5, 0.5)); //1 + myTexCoords->push_back( osg::Vec2(1.0, 0.0)); //2 + myTexCoords->push_back( osg::Vec2(0.5, 0.0)); //3 + //triangle 7 + myTexCoords->push_back( osg::Vec2(0.5, 0.5)); //1 + myTexCoords->push_back( osg::Vec2(0.5, 0.0)); //2 + myTexCoords->push_back( osg::Vec2(0.0, 0.0)); //3 + //triangle 8 + myTexCoords->push_back( osg::Vec2(0.5, 0.5)); //1 + myTexCoords->push_back( osg::Vec2(0.0, 0.0)); //2 + myTexCoords->push_back( osg::Vec2(0.0, 0.5)); //3 + + myGeometry->setTexCoordArray( 0, myTexCoords ); + + // calculate normals + osg::Vec3Array* normals = new osg::Vec3Array(8); + (*normals)[0].set(0.0f,-1.0f,0.0f); + (*normals)[1].set(0.0f,-1.0f,0.0f); + (*normals)[2].set(0.0f,-1.0f,0.0f); + (*normals)[3].set(0.0f,-1.0f,0.0f); + (*normals)[4].set(0.0f,-1.0f,0.0f); + (*normals)[5].set(0.0f,-1.0f,0.0f); + (*normals)[6].set(0.0f,-1.0f,0.0f); + (*normals)[7].set(0.0f,-1.0f,0.0f); + myGeometry->setNormalArray(normals); + myGeometry->setNormalBinding(osg::Geometry::BIND_OVERALL); + + // assign colors + osg::Vec4Array* colors = new osg::Vec4Array(8); + (*colors)[0].set(1.0f,1.0f,1.0f,1.0f); + (*colors)[1].set(1.0f,1.0f,1.0f,1.0f); + (*colors)[2].set(1.0f,1.0f,1.0f,1.0f); + (*colors)[3].set(1.0f,1.0f,1.0f,1.0f); + (*colors)[4].set(1.0f,1.0f,1.0f,1.0f); + (*colors)[5].set(1.0f,1.0f,1.0f,1.0f); + (*colors)[6].set(1.0f,1.0f,1.0f,1.0f); + (*colors)[7].set(1.0f,1.0f,1.0f,1.0f); + myGeometry->setColorArray(colors); + myGeometry->setColorBinding(osg::Geometry::BIND_OVERALL); + + + // draw the vertices as quads + myGeometry->addPrimitiveSet(new osg::DrawArrays(GL_TRIANGLES, 0, myVertices->size())); + + // disable display list so our modified tex coordinates show up + myGeometry->setUseDisplayList(false); + + // setup stateset + osg::StateSet* myState = myGeometry->getOrCreateStateSet(); + myState->setTextureAttributeAndModes(0, myTexture, osg::StateAttribute::ON); + + //Conversely, disable write depth cache, + //Make objects behind transparent polygons visible + //OSG draws transparent polygons first, then draws opaque polygons + osg :: Depth * myImgDepth = new osg :: Depth; + myImgDepth-> setWriteMask (false); + myState-> setAttributeAndModes (myImgDepth, osg :: StateAttribute :: ON); + + // setup material + osg::TexMat* myTexmat = new osg::TexMat; + myTexmat->setScaleByTextureRectangleSize(true); + myState->setTextureAttributeAndModes(0, myTexmat, osg::StateAttribute::ON); + + //enable gl_blending (for texture transparency) + myState->setMode(GL_BLEND, osg::StateAttribute::ON); + osg::BlendFunc* myBlend = new osg::BlendFunc; + myBlend->setFunction(osg::BlendFunc::SRC_ALPHA, osg::BlendFunc::ONE_MINUS_DST_ALPHA); + + // turn off lighting (light always on) + myState->setMode(GL_LIGHTING, osg::StateAttribute::OFF); + + //myGeode->setName("mytachograph"); + myGeode->addDrawable( myGeometry ); + osgGroupWidgets->addChild(myGeode); + hudImgVertexElements[elementId] = myGeometry; + } else if( type == "graph") { /* ============================ @@ -2510,4 +3091,4 @@ SDHUD::~SDHUD() { for (std::map::iterator it = hudGraphElements.begin(); it != hudGraphElements.end(); ++it) delete(it->second); -} +} diff --git a/src/modules/graphic/osggraph/Viewer/OsgHUD.h b/src/modules/graphic/osggraph/Viewer/OsgHUD.h index 6c412226..010a8b8f 100644 --- a/src/modules/graphic/osggraph/Viewer/OsgHUD.h +++ b/src/modules/graphic/osggraph/Viewer/OsgHUD.h @@ -125,6 +125,7 @@ class SDHUD osg::ref_ptr osgGroupHud; std::map hudWidgets; std::map hudImgElements; + std::map hudImgVertexElements; std::map hudImgRotableElements; std::map hudGraphElements; @@ -149,6 +150,13 @@ class SDHUD float newY, float hudScale); static void changeImageAlpha(osg::Geometry *geom, float newAlpha); + static void changeImageVertex(osg::Geometry *geom, + float angleFrom, + float angleTo, + float currValue, + float newX, + float newY, + float hudScale); osg::BoundingBox getBoundigBoxFromWidgetName(std::string widgetName); osg::BoundingBox getBoundigBoxFromWidgetGroupName(std::string widgetGroupName); void recalculateImageWidgetPosition(std::string widgetGroupName, std::string widgetName, float hudScale); diff --git a/src/modules/racing/standardgame/racecars.cpp b/src/modules/racing/standardgame/racecars.cpp index 6a992de3..7091a49f 100644 --- a/src/modules/racing/standardgame/racecars.cpp +++ b/src/modules/racing/standardgame/racecars.cpp @@ -917,12 +917,12 @@ ReCarsManageCar(tCarElt *car, bool& bestLapChanged) if (distFromStartLine < 0) { distFromStartLine = 0; - GfLogError("distFromStartLine = %d trackPositionCount = %d\n", distFromStartLine, car->_trackPositionCount); + //GfLogError("distFromStartLine = %d trackPositionCount = %d\n", distFromStartLine, car->_trackPositionCount); } else if (distFromStartLine>= car->_trackPositionCount) { distFromStartLine = car->_trackPositionCount - 1; - GfLogError("distFromStartLine = %d trackPositionCount = %d\n", distFromStartLine, car->_trackPositionCount); + //GfLogError("distFromStartLine = %d trackPositionCount = %d\n", distFromStartLine, car->_trackPositionCount); } car->_currLapTimeAtTrackPosition[distFromStartLine] = (float)car->_curLapTime; }