यहाँ कैमरा रोटेशन (मूसलूक) पर कुछ सुझाव दिए गए हैं। खरोंच से एक कैमरा क्लास को लागू करने के बाद, मैंने पाया कि मुझे अच्छे घूर्णी व्यवहार के लिए कुछ अतिरिक्त ट्वीक करने हैं:
रीसेट माउस प्रत्येक फ्रेम पर केंद्र-से-स्क्रीन के लिए समन्वय करता है, ताकि माउस स्क्रीन सीमाओं पर कभी भी पकड़ा न जाए
कैमरे के "अप" वेक्टर (रोल को अस्वीकृत करें) को बनाए रखें और "बग़ल में" वेक्टर को पुनः स्थापित करें
लंबवत + y अक्ष, या पिछले -y अक्ष के नीचे (बहुत दूर / नीचे) अतीत को देखना छोड़ें
रोटेशन का क्रम सही करें (पहले / नीचे, फिर बाएं / दाएं)
"अप", "उद्देश्य" और "बग़ल में" प्रत्येक फ्रेम को वैक्टर में बदल दें
उम्मीद है कि आप अपने लाभ के लिए इस कोड का उपयोग कर सकते हैं:
const int mouseDeltaX = mouseAxisX * (input.GetMouseX() - int(app.GetWidth()/2));
const int mouseDeltaY = -mouseAxisY * (input.GetMouseY() - int(app.GetHeight()/2)); // mouse y-offsets are upside-down!
// HACK: reset the cursor pos.:
app.SetCursorPosition(app.GetWidth()/2, app.GetHeight()/2);
float lookRightRads = mouseDeltaX * CAMERA_ANGULAR_SPEED_DEG * DEG_TO_RAD;
float lookUpRads = mouseDeltaY * CAMERA_ANGULAR_SPEED_DEG * DEG_TO_RAD;
// Limit the aim vector in such a way that the 'up' vector never drops below the horizon:
static const float zenithMinDeclination = DEG_TO_RAD * MIN_UPWARDS_TILT_DEG;
static const float zenithMaxDeclination = DEG_TO_RAD * (180.0f - MIN_UPWARDS_TILT_DEG);
const float currentDeclination = std::acosf(camera.aim_.y_); ///< declination from vertical y-axis
const float requestedDeclination = currentDeclination - lookUpRads;
// Clamp the up/down rotation to at most the min/max zenith:
if(requestedDeclination < zenithMinDeclination)
lookUpRads = currentDeclination - zenithMinDeclination;
else if(requestedDeclination > zenithMaxDeclination)
lookUpRads = currentDeclination - zenithMaxDeclination;
// Rotate both the "aim" vector and the "up" vector ccw by
// lookUpRads radians within their common plane -- which should
// also contain the y-axis: (i.e. no diagonal tilt allowed!)
camera.aim_.rotateAboutAxis(camera.right_, lookUpRads);
camera.up_.rotateAboutAxis(camera.right_, lookUpRads);
ASSERT_ORTHONORMAL(camera.aim_, camera.up_, camera.right_);
// Rotate both the "aim" and the "up" vector ccw about the vertical y-axis:
// (again, this keeps the y-axis in their common plane, and disallows diagonal tilt)
camera.aim_.rotateAboutAxis(Y_AXIS, -lookRightRads);
camera.up_.rotateAboutAxis(Y_AXIS, -lookRightRads);
camera.updateRightAxis();
ध्यान दें कि:
mouseAxisX और mouseAxisY को +/- 1 के रूप में परिभाषित किया गया है, जो इस बात पर निर्भर करता है कि आप x या y अक्ष मूसलूक को उल्टा चाहते हैं। आमतौर पर खेल इस विकल्प को कम से कम ऊर्ध्वाधर अक्ष के लिए प्रदान करते हैं।
MIN_UPWARDS_TILT_DEG को 1.0 डिग्री परिभाषित किया गया है (इसलिए दर्शक को -89 डिग्री से नीचे +89 डिग्री तक देखने की अनुमति दी जाती है, जो पूरी तरह से 180 डिग्री ऊर्ध्वाधर सीमा की तरह दिखता है - चरम पर लापता 2 डिग्री काफी नगण्य हैं) ।
camera.aim_, camera.right_, और camera.up_ बेशक 3D वैक्टर हैं, और रोटेटअबाउटिस () विधि आप विकिपीडिया और ऑनलाइन स्रोतों की किसी भी संख्या से एक साथ मिल सकते हैं। Y_AXIS एक निश्चित स्थिर (0,1,0) वेक्टर है।
ASSERT_ORTHONORMAL () एक डिबग-मोड-ओनली सैनिटरी चेक है, जो कभी भी अनुकूलित या रिलीज़ मोड में संकलित नहीं होता है।
सी-स्टाइल कोड के लिए अग्रिम में माफी ... फिर से, यहाँ आप मेदियोक्रिटस नामक एक व्यक्ति से सलाह ले रहे हैं! ; ^)