Birinci şahıs kamerasını nasıl uygulamalıyım?


12

Yeni başlayan bir programcıyım ve birinci şahıs kamera ile odalar arasında dolaşmamı sağlayan bir proje oluşturuyorum. Şimdiye kadar, binaları çizdim ve sürdüm, ama şimdi takıldım ve dolaşmamı sağlamak için nasıl birinci şahıs kamera yapacağımı bilmiyorum.

Birisi beni kullanabileceğim bir kamera sınıfına veya bazı faydalı kodlara yönlendirebilir mi?


Yanıtlar:


7

İşte kamera döndürme (mouselook) ile ilgili bazı ipuçları. Bir kamera sınıfını sıfırdan uyguladıktan sonra, iyi dönme davranışı için birkaç ek ayar yapmak zorunda kaldım:

  1. Fare koordinatlarını her karede ekranın ortasına sıfırlayın, böylece fare asla ekran kenarlıklarına takılmaz

  2. Kameranın "yukarı" vektörünü (ruloya izin verme) koruyun ve "yana doğru" vektörü yeniden hesaplayın

  3. Dikey + y eksenini geçmeye veya -y eksenini geçmeye izin verme (çok yukarı / aşağı)

  4. Dönüş sırası doğru olsun (önce yukarı / aşağı, sonra sola / sağa)

  5. Her kareyi "yukarı", "amaç" ve "yana doğru" vektörleri yeniden normalleştirin

Umarım bu kodlardan bazılarını kendi yararınıza kullanabilirsiniz:

    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();

Bunu not et:

mouseAxisX ve mouseAxisY, x veya y eksenli fare görüntüsünün ters çevrilmesini isteyip istemediğinize bağlı olarak +/- 1 olarak tanımlanır. Genellikle oyunlar bu seçeneği en azından dikey eksen için sunar.

MIN_UPWARDS_TILT_DEG 1.0 derece olarak tanımlanır (bu nedenle izleyicinin -89 dereceden aşağıya doğru +89 dereceye kadar bakmasına izin verilir, bu da tam 180 derece dikey bir aralığa oldukça ikna edici görünür - aşırı uçlarda eksik 2 derece oldukça önemsizdir) .

camera.aim_, camera.right_ ve camera.up_, elbette 3B vektörler ve rotateAboutAxis () yöntemiyle wikipedia'dan ve istediğiniz sayıda çevrimiçi kaynaktan birlikte toparlayabilirsiniz. Y_AXIS sabit bir sabit (0,1,0) vektörüdür.

ASSERT_ORTHONORMAL (), hiçbir zaman optimize edilmiş / serbest bırakma modunda derlenmeyen bir hata ayıklama modu yalnızca sağlık kontrolüdür.

C tarzı kod için şimdiden özür dileriz ... o zaman yine Mediocritus adlı bir adamdan tavsiye alıyorsunuz! ; ^)


Neden bahsediyorsun? C tarzı kod, hacker ruhunun temel taşıdır! 8-)
blissfreak

5

(Öğreticiler bakın bu konuda gidiş birkaç yolu vardır burada , burada ve burada Google üzerinden internette daha fazla kullanılabilir bol örneğin). Çevrimiçi olarak bulabileceğiniz kaynaklarda kullanılan teknoloji biraz değişebilir (D3D, XNA, OpenGL, et cetera açısından), ancak temel prensipler aynı olacaktır:

  • kamera nesneniz konumunu ve yönünü korur ve isteğe bağlı olarak yönün yanı sıra kameranın koordinat sistemi için dikey bir temel oluşturan başka bir vektör çifti.
  • kameranızın genel API'sı, kamerayı temel vektörleri çevresinde saptırma, eğme ve isteğe bağlı olarak döndürme yöntemlerini sunar - kamera yönünü ayarlama eylemi, sonraki kullanım için temel vektörleri güncelleyecektir.

Vektörleri doğrudan depolamayı seçebilir veya temel görünüm matrisini istediğiniz zaman ve istediğiniz gibi yeniden hesaplayabilirsiniz. Tekniğe çok fazla esneklik vardır, bu nedenle bu genel adımların ötesinde yardıma ihtiyacınız varsa, daha spesifik bir sorgu ile yeni bir soru göndermek isteyebilirsiniz.


Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.