diff --git a/source/glest_game/graphics/renderer.cpp b/source/glest_game/graphics/renderer.cpp index ac36002c..2842aff0 100644 --- a/source/glest_game/graphics/renderer.cpp +++ b/source/glest_game/graphics/renderer.cpp @@ -3477,8 +3477,15 @@ void Renderer::renderUnits(const int renderFps) { glTranslatef(currVec.x, currVec.y, currVec.z); //rotate + float zrot=unit->getRotationZ(); + float xrot=unit->getRotationX(); + if(zrot!=.0f){ + glRotatef(zrot, 0.f, 0.f, 1.f); + } + if(xrot!=.0f){ + glRotatef(xrot, 1.f, 0.f, 0.f); + } glRotatef(unit->getRotation(), 0.f, 1.f, 0.f); - glRotatef(unit->getVerticalRotation(), 1.f, 0.f, 0.f); //dead alpha float alpha= 1.0f; diff --git a/source/glest_game/type_instances/unit.cpp b/source/glest_game/type_instances/unit.cpp index eef0bc32..f62663a6 100644 --- a/source/glest_game/type_instances/unit.cpp +++ b/source/glest_game/type_instances/unit.cpp @@ -252,6 +252,12 @@ Unit::Unit(int id, UnitPathInterface *unitpath, const Vec2i &pos, const UnitType usePathfinderExtendedMaxNodes = false; this->currentAttackBoostOriginatorEffect.skillType = NULL; + float targetRotationZ=.0f; + float targetRotationX=.0f; + float rotationZ=.0f; + float rotationX=.0f; + + RandomGen random; if(map->isInside(pos) == false || map->isInsideSurface(map->toSurfCoords(pos)) == false) { @@ -468,15 +474,118 @@ Vec2i Unit::getCellPos() const { return pos; } -float Unit::getVerticalRotation() const{ - /*if(type->getProperty(UnitType::pRotatedClimb) && currSkill->getClass()==scMove){ - float heightDiff= map->getCell(pos)->getHeight() - map->getCell(targetPos)->getHeight(); - float dist= pos.dist(targetPos); - return radToDeg(streflop::atan2(heightDiff, dist)); - }*/ - return 0.f; + + +void Unit::calculateXZRotation(){ + //if(type->getProperty(UnitType::pRotatedClimb) && currSkill->getClass()==scMove){ + //if(currSkill->getClass()==scMove) + if(lastPos != pos){ // targetPosCalc ( maybe also sometimes needed if no move ? terrain flatting... ) + SurfaceCell* sc= map->getSurfaceCell(Map::toSurfCoords(pos)); + const Vec3f normal= sc->getNormal(); + + float targetRotationZ= radToDeg(streflop::atan2(abs(normal.x), abs(normal.y))); + + if((normal.y < 0 || normal.x < 0) && !(normal.y < 0 && normal.x < 0)){ + targetRotationZ= targetRotationZ * -1; + } + targetRotationZ= targetRotationZ * -1; + + targetRotationX= radToDeg(streflop::atan2(abs(normal.z), abs(normal.y))); + + if((normal.y < 0 || normal.z < 0) && !(normal.y < 0 && normal.z < 0)){ + targetRotationX= targetRotationX * -1; + } + } + + //For smooth rotation we now softly adjust the angle + int adjustStep= 2; + if(rotationZ < targetRotationZ){ + if(rotationZ + adjustStep > targetRotationZ){ + rotationZ= targetRotationZ; + } + else{ + rotationZ= rotationZ + adjustStep; + } + } + else if(rotationZ > targetRotationZ){ + if(rotationZ - adjustStep < targetRotationZ){ + rotationZ= targetRotationZ; + } + else{ + rotationZ= rotationZ - adjustStep; + } + } + + if(rotationX < targetRotationX){ + if(rotationX + adjustStep > targetRotationX){ + rotationX= targetRotationX; + } + else{ + rotationX= rotationX + adjustStep; + } + } + else if(rotationX > targetRotationX){ + if(rotationX - adjustStep < targetRotationX){ + rotationX= targetRotationX; + } + else{ + rotationX= rotationX - adjustStep; + } + } } +float Unit::getRotationZ() const{ + return rotationZ; +} + +float Unit::getRotationX() const{ + return rotationX; +} + +//float Unit::getRotationZ() const{ +// //if(type->getProperty(UnitType::pRotatedClimb) && currSkill->getClass()==scMove){ +// //if(currSkill->getClass()==scMove) +// { +// SurfaceCell* sc=map->getSurfaceCell(Map::toSurfCoords(pos)); +// const Vec3f normal=sc->getNormal(); +// //printf("normal x y z %f %f %f \n",normal.x,normal.y,normal.z ); +// +// +// float result=radToDeg(streflop::atan2(abs(normal.x), abs(normal.y))); +// //printf("pre result=%f\n",result); +// if((normal.y<0 || normal.x<0)&& !(normal.y<0 && normal.x<0)) +// result=result*-1; +// +// result=result*-1; +// //printf("heightDiff=%f xdiff=%f zdiff=%f grad=%f result=%f rotation=%f \n",heightDiff,xdiff,zdiff, radToDeg(streflop::atan2(heightDiff, xdiff)),result,rotation); +// return result; +// } +// //else +// return 0.f; +//} +// +//float Unit::getRotationX() const{ +// //if(type->getProperty(UnitType::pRotatedClimb) && currSkill->getClass()==scMove){ +// //if(currSkill->getClass()==scMove) +// { +// SurfaceCell* sc=map->getSurfaceCell(Map::toSurfCoords(pos)); +// const Vec3f normal=sc->getNormal(); +// //printf("normal x y z %f %f %f \n",normal.x,normal.y,normal.z ); +// +// +// float result=radToDeg(streflop::atan2(abs(normal.z), abs(normal.y))); +// //printf("pre result=%f\n",result); +// if((normal.y<0 || normal.z<0)&& !(normal.y<0 && normal.z<0)) +// result=result*-1; +// +// //result=result*-1; +// //printf("heightDiff=%f xdiff=%f zdiff=%f grad=%f result=%f rotation=%f \n",heightDiff,xdiff,zdiff, radToDeg(streflop::atan2(heightDiff, xdiff)),result,rotation); +// return result; +// } +// //else +// return 0.f; +//} + int Unit::getProductionPercent() const{ if(anyCommand()){ const ProducibleType *produced= commands.front()->getCommandType()->getProduced(); @@ -1392,6 +1501,10 @@ bool Unit::update() { } } + if(type->getProperty(UnitType::pRotatedClimb)){ + calculateXZRotation(); + } + if(Renderer::getInstance().validateParticleSystemStillExists(fire,rsGame) == false) { fire = NULL; } diff --git a/source/glest_game/type_instances/unit.h b/source/glest_game/type_instances/unit.h index 4dde7372..d4d6082f 100644 --- a/source/glest_game/type_instances/unit.h +++ b/source/glest_game/type_instances/unit.h @@ -304,6 +304,10 @@ private: float lastRotation; //in degrees float targetRotation; float rotation; + float targetRotationZ; + float targetRotationX; + float rotationZ; + float rotationX; const UnitType *type; const ResourceType *loadType; @@ -418,7 +422,8 @@ public: const SkillType *getCurrSkill() const {return currSkill;} const TotalUpgrade *getTotalUpgrade() const {return &totalUpgrade;} float getRotation() const {return rotation;} - float getVerticalRotation() const; + float getRotationX() const; + float getRotationZ() const; ParticleSystem *getFire() const {return fire;} int getKills() const {return kills;} int getEnemyKills() const {return enemyKills;} @@ -576,6 +581,7 @@ public: private: float computeHeight(const Vec2i &pos) const; + void calculateXZRotation(); void updateTarget(); void clearCommands(); void deleteQueuedCommand(Command *command);