ฉันจะใช้กล้องของบุคคลที่หนึ่งได้อย่างไร


12

ฉันเป็นโปรแกรมเมอร์มือใหม่และฉันกำลังสร้างโปรเจ็กต์ที่ช่วยให้ฉันเดินไปรอบ ๆ ห้องด้วยกล้องตัวแรก จนถึงตอนนี้ฉันมีอาคารที่ถูกวาดขึ้นมาแล้ว แต่ตอนนี้ฉันติดอยู่และไม่รู้ว่าจะสร้างกล้องตัวแรกเพื่อให้ฉันเดินไปรอบ ๆ ได้อย่างไร

ใครช่วยชี้ให้ฉันไปที่ชั้นเรียนกล้องที่ฉันสามารถใช้หรือรหัสที่มีประโยชน์?


คำตอบ:


7

นี่คือเคล็ดลับบางอย่างเกี่ยวกับการหมุนกล้อง (mouselook) หลังจากใช้คลาสกล้องตั้งแต่เริ่มแรกฉันพบว่าฉันต้องปรับแต่งเพิ่มเติมสองสามครั้งเพื่อพฤติกรรมการหมุนที่ดี:

  1. รีเซ็ตพิกัดของเมาส์ไปที่กึ่งกลางของหน้าจอในแต่ละเฟรมเพื่อไม่ให้เมาส์ติดกับขอบของหน้าจอ

  2. รักษาเวกเตอร์ "up" ของกล้อง (ไม่อนุญาตให้ม้วน) และคำนวณ "เวกเตอร์" ด้านข้างใหม่

  3. ไม่อนุญาตให้มองผ่านแกนแนวตั้ง + y หรือเลื่อนผ่านแกน -y (ไกลเกินไปขึ้น / ลง)

  4. รับลำดับการหมุนที่ถูกต้อง (ขึ้น / ลงก่อนจากนั้นซ้าย / ขวา)

  5. ปรับภาพเวกเตอร์ "up", "aim" และ "Sideways" ใหม่แต่ละเฟรม

หวังว่าคุณสามารถใช้รหัสนี้เพื่อประโยชน์ของคุณ:

    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 แกน mouselook กลับด้าน โดยปกติเกมจะเสนอตัวเลือกนี้อย่างน้อยแกนแนวตั้ง

MIN_UPWARDS_TILT_DEG ถูกกำหนดให้เป็น 1.0 องศา (ดังนั้นผู้ชมจะได้รับอนุญาตให้ดูจาก -89 องศาลงไปที่ +89 องศาขึ้นไปซึ่งดูเหมือนจะค่อนข้างมั่นใจเหมือนช่วงแนวตั้งเต็ม 180 องศา - ที่หายไป 2 องศาที่ปลายสุดนั้นค่อนข้างเล็กน้อย) .

camera.aim_, camera.right_ และ camera.up_ แน่นอนว่าเป็นเวกเตอร์ 3 มิติและวิธี rotateAboutAxis () ที่คุณสามารถใช้ร่วมกันจากวิกิพีเดียและแหล่งข้อมูลออนไลน์จำนวนเท่าใดก็ได้ Y_AXIS เป็นค่าคงที่เวกเตอร์คงที่ (0,1,0)

ASSERT_ORTHONORMAL () เป็นการตรวจสอบสติในโหมดดีบักเท่านั้นซึ่งไม่เคยถูกคอมไพล์ในโหมดออปติไมซ์ / รีลีส

ขออภัยล่วงหน้าสำหรับโค้ดสไตล์ C ... จากนั้นอีกครั้งที่นี่คุณกำลังรับคำแนะนำจากผู้ชายที่ชื่อ Mediocritus! ; ^)


คุณกำลังพูดเรื่องอะไร โค้ดสไตล์ C คือหัวใจสำคัญของจิตวิญญาณของแฮ็กเกอร์! 8-)
blissfreak

5

มีหลายวิธีที่จะไปเกี่ยวกับเรื่องนี้ (บทเรียนเห็นที่นี่ , ที่นี่และที่นี่มีมากมายเช่นมีมากขึ้นบนอินเทอร์เน็ตผ่านทางของ Google) เทคโนโลยีที่ใช้ในแหล่งข้อมูลที่คุณอาจพบออนไลน์อาจแตกต่างกันเล็กน้อย (ในแง่ของ D3D, XNA, OpenGL และอื่น ๆ ) แต่หลักการพื้นฐานจะเหมือนกัน:

  • วัตถุกล้องของคุณรักษาตำแหน่งและทิศทางของมันและเวกเตอร์อีกคู่หนึ่งที่เป็นทางเลือกนั้นเป็นพื้นฐานมุมฉากสำหรับระบบพิกัดของกล้อง
  • API สาธารณะของกล้องของคุณแสดงให้เห็นถึงวิธีการหาว, การทอยและการหมุนกล้องรอบ ๆ เวกเตอร์พื้นฐาน - การปรับทิศทางกล้องจะอัพเดตเวกเตอร์พื้นฐานสำหรับการใช้งานในภายหลัง

คุณสามารถเลือกที่จะเก็บเวกเตอร์โดยตรงหรือคำนวณเมทริกซ์มุมมองพื้นฐานทุกครั้งตามที่คุณต้องการและต้องการ มีความยืดหยุ่นมากกับเทคนิคดังนั้นหากคุณต้องการความช่วยเหลือนอกเหนือจากขั้นตอนทั่วไปคุณอาจต้องการโพสต์คำถามใหม่ด้วยคำถามที่เฉพาะเจาะจงมากขึ้น


2

สำหรับการอ้างอิงที่เฉพาะเจาะจงกับการดำเนินการของระบบกล้องใช้ Direct3D ผมขอแนะนำให้บทความนี้: http://www.toymaker.info/Games/html/camera.html ผู้เขียนยังอธิบายถึงวิธีการและคุณสมบัติอื่น ๆ ที่อาจใช้เพื่อขยายการใช้งาน

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.