What do you mean - inefficient?

void Enemy::moveTowardsPlayer( glm::vec3 playerPos ) { crossVec = glm::cross( faceDirection, upDirection ); //6 multiplications, 3 subtractions movementDirection = normalize( playerPos - position ); //3 multiplications, 3 additions, 3 subtractions, 3 divisions, 1 square root float dotProduct = dot( movementDirection, faceDirection ); // 3 multiplications, 3 additions float crossVecDotProduct = dot( movementDirection, crossVec ); // 3 multiplications, 3 additions if( crossVecDotProduct < 0 ) // If I turned left { rotation.w = std::acos( dotProduct ); // trig functions (these can be slow) } else //else I turned right { rotation.w = std::acos( -dotProduct ) + M_PI; // trig func, addition } rotation.y = 1.0f; }

15 multiplications, 8(9) additions, 6 subtractions, 3 divisions, 1 square root, 1 trig function

movementDirection = playerPos - position; // 3 subtractions // going to ignore elevation movementDirection .y = 0; movementDirection = normalize( movementDirection ); // 3 multiplications, 3 additions, 3 divisions, 1 square root rotation.x = 0; rotation.y = 1; rotation.z = 0; rotation.w = atan2(movementDirection.z, movementDirection.x); // trig func

3 multiplications, 3 additions, 3 subtractions, 3 divisions, 1 square root, 1 trig function.

Obviously I may have missed something and a few odd bits I didn't count. I don't know how glm is calculating it's dot prodcts or cross products but there's a limit to how efficient it can be made. I don't know how atan2/acos are compared to each other but the second option appears to do less work. It depends largely on how slow the trig functions are, if there's a huge difference then that may be the deciding factor. Of course it's likely that you don't have any performance issues so it's no problem anyway. Your solution certainly does what it's intended to and it's easy to see why you came up with that (it makes sense).