0
\$\begingroup\$

I am making a game from scratch using OpenGl and GLFW. Since my motivation is to learn computer graphics, I am using my own explicit math functions for rotation and translation. My current rotation code tries to rotate the player to the direction of mouse pointer; with the center of player as origin, I take two vectors and deduce the rotation angle by a dot product. My problem is that the rotation of the player never stops and the object keeps spinning even after rotation angle turns to 0, it again starts increasing.

Following is my current implementation of rotation : `

double safe_acos(double value) {
    if (value<=-1.0) {
        return 0;
    } else if (value>=1.0) {
        return 0;
    } else {
        return acos(value);
    }
}

void rotateObject(std::vector<float> &GameObjPos, double angle, GE_Vec3 centrePos) {
    auto cosVal = (float) cos(angle);
    auto sinVal = (float) sin(angle);
    for (size_t i = 0; i <= GameObjPos.size() - 3; i += 3) {
        float x = GameObjPos[i];
        float y = GameObjPos[i + 1];
        GameObjPos[i] = x * cosVal - y * sinVal - centrePos.x * cosVal + centrePos.y * sinVal + centrePos.x;
        GameObjPos[i + 1] = x * sinVal + y * cosVal - centrePos.x * sinVal - centrePos.y * cosVal + centrePos.y;
    }
}

double GetMagnitudeSq(GE_Vec3 GameObjPos) {
    return (GameObjPos.x * GameObjPos.x + GameObjPos.y * GameObjPos.y + 0.0f);
}

double GetDotProduct(GE_Vec3 GameObjPos1, GE_Vec3 GameObjPos2) {
    return (GameObjPos1.x * GameObjPos2.x + GameObjPos1.y * GameObjPos2.y);
}

double GetRotationAngle(GE_Vec3 GameObjPos1, GE_Vec3 GameObjPos2) {
    double dotProduct = GetDotProduct(GameObjPos1, GameObjPos2);
    double magnitudeProduct = GetMagnitudeSq(GameObjPos1) * GetMagnitudeSq(GameObjPos2);
    double magnitudeSqRoot = sqrt(magnitudeProduct);
    return safe_acos(dotProduct / magnitudeSqRoot);
}

GE_Vec3 GetGameObjCentre(std::vector<float> GameObjPos) {
    return {(GameObjPos[0] + GameObjPos[6]) / 2, (GameObjPos[1] + GameObjPos[7]) / 2, 0.0f};
}

GE_Vec3 GetObjFrontCentrePos(std::vector<float> GameObjPos){
    return {(GameObjPos[6] + GameObjPos[9]) / 2.0f, (GameObjPos[7] + GameObjPos[10]) / 2.0f };
}

void GE_Physics::update(std::vector<std::vector<float>> &GameObjPosVec, int PlayerDirection, MousePosition mousePos,
                        float deltaTime = 1.0f) {
    for (int i = 0; i < GameObjPosVec.size(); i++) {
        updatePosition(GameObjPosVec[i], PlayerDirection, deltaTime);
        MousePosition pos = {-1.0 + 2.0 * (double) mousePos.x / 1280, 1.0 - 2.0 * (double) mousePos.y / 720};
        updateRotation(GameObjPosVec[i], pos);
    }
}

void GE_Physics::updateRotation(std::vector<float> &GameObjPos, MousePosition mousePos) {
    if(mousePos.x ==-1 && mousePos.y ==1){
        return;
    }
    GE_Vec3 gameObjFront = GetObjFrontCentrePos(GameObjPos);
    GE_Vec3 gameObjCentre = GetGameObjCentre(GameObjPos);
    GE_Vec3 mousePosVec = {(float) mousePos.x - gameObjCentre.x, (float) mousePos.y - gameObjCentre.y, 0.0f};
    GE_Vec3 objFrontVec = {gameObjFront.x - gameObjCentre.x, gameObjFront.y = gameObjCentre.y, 0.0f};
    double rotAngle = GetRotationAngle(objFrontVec, mousePosVec);
#ifdef __DEBUG__
    std::clog<<"rotation angle : "<<rotAngle<<std::endl;
#endif
    rotateObject(GameObjPos, rotAngle, gameObjCentre);
}

`

\$\endgroup\$
3
  • \$\begingroup\$ What is the intention with rotAngle = GetRotationAngle(objFrontVec, mousePosVec);? Can't you just pass the angle of the mouse w.r.t the center of the screen and have your game object rotate toward it? Also, the GameObjPos in rotateObject is distracting: why do you need to jump three indices? \$\endgroup\$ Commented Sep 9, 2022 at 18:46
  • \$\begingroup\$ I was trying to rotate the object about its own centroid, the three idex jump is becaus xyz coordinates are stored in a linear vector, so each x value is three indices away, thanks for the recommendation. Can you also tell me why the cube won't stop rotating \$\endgroup\$ Commented Sep 10, 2022 at 13:50
  • \$\begingroup\$ Okay, I don't have the time to look thoroughly at your code now but typically, what you'll do, you'll keep for each object something like local transform: what translation and rotation should be applied to the object. When the local transform changes, you reapply the transform from the original local coordinate, not from the state of the currently transformed object. So in your case, for instance, you'll have two sets of coordinates: one for the "original" local frame vertices positions, and one set for those that are transformed (which you'll use to display your object). \$\endgroup\$ Commented Sep 10, 2022 at 14:36

0

You must log in to answer this question.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.