ধরে নিচ্ছি আপনার বোঝা এমন একটি ক্যামেরা যা মাউস আন্দোলনের উপর ভিত্তি করে ঘুরবে:
এটিকে বাস্তবায়নের একটি উপায় হ'ল ক্যামেরার অবস্থান এবং স্থানটিতে এর ঘূর্ণনের ট্র্যাক রাখা। গোলাকার স্থানাঙ্কগুলি এর জন্য সুবিধাজনক বলে মনে হয়, যেহেতু আপনি সরাসরি কোণগুলি উপস্থাপন করতে পারেন।
float m_theta;
float m_phi;
float m_radius;
float3 m_target;
ক্যামেরাটি পি তে অবস্থিত যা m_theta, m_phi এবং m_radius দ্বারা সংজ্ঞায়িত। এই তিনটি মান পরিবর্তন করে আমরা যেখানেই খুশি ঘোরাফেরা করতে এবং সরিয়ে নিতে পারি। যাইহোক, আমরা সবসময় এম_টারেজকে দেখি এবং চারদিকে ঘোরান। m_target হল গোলকের স্থানীয় উত্স। তবে আমরা বিশ্বের মহাকাশে যেখানেই চাই এই উত্সটিকে স্থানান্তর করতে স্বাধীন।
তিনটি প্রধান ক্যামেরা ফাংশন রয়েছে:
void Rotate(float dTheta, float dPhi);
void Zoom(float distance);
void Pan(float dx, float dy);
তাদের সহজতম ফর্মগুলিতে, ঘোরানো () এবং জুম () তুচ্ছ। যথাক্রমে কেবলমাত্র_পরিচালনা, এম_ফাই এবং এম_রাডিয়াস:
void Camera::Rotate(float dTheta, float dPhi) {
m_theta += dTheta;
m_phi += dPhi;
}
void Camera::Zoom(float distance) {
m_radius -= distance;
}
প্যানিং কিছুটা জটিল। একটি ক্যামেরা প্যানটিকে ক্যামেরাটি বাম / ডানদিকে এবং / অথবা উপরে / ডাউন বর্তমান ক্যামেরা দেখার সাথে সম্পর্কিত হিসাবে সংজ্ঞায়িত করা হয়েছে। আমরা এটি সম্পাদন করার সবচেয়ে সহজ উপায়টি হল আমাদের বর্তমান ক্যামেরা ভিউটিকে গোলাকার স্থানাঙ্ক থেকে কার্তেসিয়ান স্থানাঙ্কে রূপান্তর করা। এটি আমাদের একটি আপ এবং ডান ভেক্টর দেবে।
void Camera::Pan(float dx, float dy) {
float3 look = normalize(ToCartesian());
float3 worldUp = float3(0.0f, 1.0f, 0.0f, 0.0f);
float3 right = cross(look, worldUp);
float3 up = cross(look, right);
m_target = m_target + (right * dx) + (up * dy);
}
inline float3 ToCartesian() {
float x = m_radius * sinf(m_phi) * sinf(m_theta);
float y = m_radius * cosf(m_phi);
float z = m_radius * sinf(m_phi) * cosf(m_theta);
float w = 1.0f;
return float3(x, y, z, w);
}
সুতরাং, প্রথম, আমরা আমাদের গোলাকার তুল্য সিস্টেম কার্টিজিয়ান আমাদের পেতে রূপান্তর বর্ণন ভেক্টর। এরপরে, আমরা সঠিক ভেক্টর পাওয়ার জন্য আমরা বিশ্বের আপ ভেক্টরের সাথে ভেক্টর ক্রস পণ্যটি করি । এটি এমন একটি ভেক্টর যা ক্যামেরা দৃশ্যের সরাসরি ডানদিকে নির্দেশ করে। শেষ অবধি , আমরা ক্যামেরা আপ ভেক্টর পেতে অন্য ভেক্টর ক্রস পণ্য করি ।
প্যানটি শেষ করতে, আমরা উপরের এবং ডান ভেক্টরগুলির সাথে মি_টারেজ সরিয়ে নিয়েছি ।
আপনি যে প্রশ্নটি জিজ্ঞাসা করতে পারেন তা হ'ল: কেন সর্বদা কার্টেসিয়ান এবং গোলাকৃতির মধ্যে রূপান্তর (ভিউ ম্যাট্রিক্স তৈরি করতে আপনাকে রূপান্তর করতে হবে)।
ভাল প্রশ্ন. আমারও এই প্রশ্নটি ছিল এবং একচেটিয়াভাবে কার্টেসিয়ান ব্যবহার করার চেষ্টা করেছি। আপনি ঘূর্ণন সমস্যা সহ শেষ। যেহেতু ভাসমান পয়েন্ট অপারেশনগুলি হুবহু সুনির্দিষ্ট নয়, একাধিক ঘূর্ণনগুলি ত্রুটিগুলি জমা করে শেষ করে, যা ক্যামেরার সাথে ধীরে ধীরে মিলিত হয়, এবং অনিচ্ছাকৃতভাবে ঘূর্ণায়মান।
সুতরাং, শেষ পর্যন্ত, আমি গোলাকার স্থানাঙ্কের সাথে আটকে গেলাম। অতিরিক্ত গণনাগুলি মোকাবেলা করার জন্য, আমি ভিউ ম্যাট্রিক্সের ক্যাশে শেষ করেছিলাম এবং ক্যামেরাটি সরে গেলে কেবল এটি গণনা করি।
শেষ পদক্ষেপটি এই ক্যামেরা ক্লাসটি ব্যবহার করা । আপনার অ্যাপের মাউসডাউন / আপ / স্ক্রোল ফাংশনগুলির মধ্যে কেবল উপযুক্ত সদস্য ফাংশনটি কল করুন:
void MouseDown(WPARAM buttonState, int x, int y) {
m_mouseLastPos.x = x;
m_mouseLastPos.y = y;
SetCapture(m_hwnd);
}
void MouseUp(WPARAM buttonState, int x, int y) {
ReleaseCapture();
}
void MouseMove(WPARAM buttonState, int x, int y) {
if ((buttonState & MK_LBUTTON) != 0) {
if (GetKeyState(VK_MENU) & 0x8000) {
// Calculate the new phi and theta based on mouse position relative to where the user clicked
float dPhi = ((float)(m_mouseLastPos.y - y) / 300);
float dTheta = ((float)(m_mouseLastPos.x - x) / 300);
m_camera.Rotate(-dTheta, dPhi);
}
} else if ((buttonState & MK_MBUTTON) != 0) {
if (GetKeyState(VK_MENU) & 0x8000) {
float dx = ((float)(m_mouseLastPos.x - x));
float dy = ((float)(m_mouseLastPos.y - y));
m_camera.Pan(-dx * m_cameraPanFactor, dy * m_cameraPanFactor);
}
}
m_mouseLastPos.x = x;
m_mouseLastPos.y = y;
}
void MouseWheel(int zDelta) {
// Make each wheel dedent correspond to a size based on the scene
m_camera.Zoom((float)zDelta * m_cameraScrollFactor);
}
M_camera * ফ্যাক্টর ভেরিয়েবলগুলি কেবলমাত্র স্কেল ফ্যাক্টর যা আপনার ক্যামেরাটি কত দ্রুত / প্যান / স্ক্রোল ঘোরায় তা পরিবর্তন করে
: কোড আমি উপরের আছে ক্যামেরা সিস্টেম আমি একটি পার্শ্ব প্রকল্পের জন্য তৈরি একটি সরলীকৃত সিউডো-কোড সংস্করণ camera.h এবং camera.cpp । ক্যামেরাটি মায়া ক্যামেরা সিস্টেমটি অনুকরণ করার চেষ্টা করে। কোডটি নিখরচায় এবং মুক্ত উত্স, সুতরাং এটি আপনার নিজের প্রকল্পে বিনা দ্বিধায় অনুভব করুন।