• Najnowsze pytania
  • Bez odpowiedzi
  • Zadaj pytanie
  • Kategorie
  • Tagi
  • Zdobyte punkty
  • Ekipa ninja
  • IRC
  • FAQ
  • Regulamin
  • Książki warte uwagi

question-closed WebGL, rozciąganie modeli

Object Storage Arubacloud
0 głosów
234 wizyt
pytanie zadane 31 października 2020 w C i C++ przez Jakub 0 Pasjonat (23,120 p.)
zamknięte 1 listopada 2020 przez Jakub 0

Witam, tworzę bibliotekę graficzną w Rust / WASM + ugli_webgl i stdweb. Myślę jednak że technologia ani cały kod nie mają tu żadnego znaczenia. Problem jest dość prozaiczny i polega na rozciąganiu się modeli w stosunku do wymiarów okna: 

Przedstawione powyżej bryły powinny być sześcianami. Perspektywa wygląda tak:

self.context.viewport(0, 0, window().inner_width(), window().inner_height());

projection = glm::perspective(
        (self.camera.get_zoom() as f32).to_radians(),
         window().inner_width() as f32 / window().inner_height() as f32,
         0.1,
         100.0,
);

FOV domyślnie jest ustawiony na 45 stopni, druki argument to tradycyjne stosunek szerokości do wysokości obszaru wyświetlania. Podobne rozwiązanie zastosowałem w wersji desktopowej w C++, tam jednak wszystko działało poprawnie. Nie wiem co mogłem pominąć, będę bardzo wdzięczny za wskazówki. Implementacja kamery:

use stdweb::web::TypedArray;
use ugli_webgl::WebGL2RenderingContext as gl;

use super::exceptions::{EngineResult, EngineRuntimeError};

use nalgebra_glm as glm;

use stdweb::console;

// -----------------------------------------------------------------------------------------------------------

pub enum MovementDirection {
    Forward,
    Backward,
    Left,
    Right,
}

// -----------------------------------------------------------------------------------------------------------

pub const DEFAULT_YAW: f32 = -90.0;
pub const DEFAULT_PITCH: f32 = 0.0;
pub const DEFAULT_MOVEMENT_SPEED: f32 = 6.0;
pub const DEFAULT_MOVEMENT_SENSITIVITY: f32 = 1.3;
pub const DEFAULT_ZOOM: f32 = 45.0;

// -----------------------------------------------------------------------------------------------------------

pub struct FPSCamera {
    position: glm::TVec3<f32>,
    front: glm::TVec3<f32>,
    up: glm::TVec3<f32>,
    right: glm::TVec3<f32>,
    world_up: glm::TVec3<f32>,
    yaw: f32,
    pitch: f32,
    zoom: f32,
    // const
    movement_speed: f32,
    mouse_sensitivity: f32,
}

// -----------------------------------------------------------------------------------------------------------

impl FPSCamera {
    pub fn new(
        position: glm::TVec3<f32>,
        world_up: glm::TVec3<f32>,
        yaw: f32,
        pitch: f32,
    ) -> FPSCamera {
        let mut camera = FPSCamera {
            front: glm::vec3(0.0, 0.0, -1.0),
            movement_speed: DEFAULT_MOVEMENT_SPEED,
            mouse_sensitivity: DEFAULT_MOVEMENT_SENSITIVITY,
            zoom: DEFAULT_ZOOM,
            position,
            world_up,
            yaw,
            pitch,
            right: glm::vec3(0.5, 0.0, 0.0),
            up: glm::vec3(0.5, 0.0, 0.0),
        };

        camera.update_camera_vectors();

        camera
    }

    fn update_camera_vectors(&mut self) {
        let mut front = glm::vec3(0.0, 0.0, 0.0);
        front.x = self.yaw.to_radians().cos() * &self.pitch.to_radians().cos();
        front.y = self.pitch.to_radians().sin();
        front.z = self.yaw.to_radians().sin() * self.pitch.to_radians().cos();
        self.front = glm::normalize(&front);
        self.right = glm::normalize(&glm::cross(&self.front, &self.world_up));
        self.up = glm::normalize(&glm::cross(&self.right, &self.front));
    }

    pub fn get_view_matrix(&self) -> glm::TMat4<f32> {
        glm::look_at(&self.position, &(self.position + self.front), &self.up)
    }

    pub fn get_zoom(&self) -> f32 {
        self.zoom
    }

    pub fn get_position(&self) -> &glm::TVec3<f32> {
        &self.position
    }

    pub fn process_direction(&mut self, dir: MovementDirection) {
        let velocity = self.movement_speed * 0.01;
        match dir {
            MovementDirection::Forward => self.position += self.front * velocity,
            MovementDirection::Backward => self.position -= self.front * velocity,
            MovementDirection::Left => self.position -= self.right * velocity,
            MovementDirection::Right => self.position += self.right * velocity,
        }
    }

    pub fn process_mouse_movement(&mut self, mut xoffset: f32, mut yoffset: f32) {

        xoffset *= self.mouse_sensitivity;
        yoffset *= self.mouse_sensitivity;

        self.yaw += xoffset;
        self.pitch += yoffset;

        if self.pitch > 89.0 {
            self.pitch = 89.0;
        }
        if self.pitch < -89.0 {
            self.pitch = -89.0;
        }

        self.update_camera_vectors();
    }
}

W razie potrzeby mogę dać resztę kodu lub w ogóle link do repozytorium. Z góry dziękuje za pomoc i pozdrawiam :)

komentarz zamknięcia: problem rozwiązany
komentarz 31 października 2020 przez Jakub 0 Pasjonat (23,120 p.)
* Nie da się stworzyć bloku kodu dla Rust, dlatego dałem C++

1 odpowiedź

+1 głos
odpowiedź 1 listopada 2020 przez Jakub 0 Pasjonat (23,120 p.)
Problem rozwiązany, sprawa dotyczyła tego że nie wiedzieć dla czego, glm::perspective w tej wersji pobiera dwa pierwsze argumenty ( FOV i aspect ) odwrotnie.

Podobne pytania

0 głosów
1 odpowiedź 203 wizyt
pytanie zadane 26 maja 2020 w Inne języki przez Arcturus Bywalec (2,370 p.)
+1 głos
0 odpowiedzi 235 wizyt
pytanie zadane 3 października 2019 w Inne języki przez reaktywny Nałogowiec (40,990 p.)
0 głosów
0 odpowiedzi 67 wizyt
pytanie zadane 18 sierpnia 2021 w JavaScript przez Qjr Nowicjusz (120 p.)

92,570 zapytań

141,422 odpowiedzi

319,643 komentarzy

61,959 pasjonatów

Motyw:

Akcja Pajacyk

Pajacyk od wielu lat dożywia dzieci. Pomóż klikając w zielony brzuszek na stronie. Dziękujemy! ♡

Oto polecana książka warta uwagi.
Pełną listę książek znajdziesz tutaj.

Akademia Sekuraka

Kolejna edycja największej imprezy hakerskiej w Polsce, czyli Mega Sekurak Hacking Party odbędzie się już 20 maja 2024r. Z tej okazji mamy dla Was kod: pasjamshp - jeżeli wpiszecie go w koszyku, to wówczas otrzymacie 40% zniżki na bilet w wersji standard!

Więcej informacji na temat imprezy znajdziecie tutaj. Dziękujemy ekipie Sekuraka za taką fajną zniżkę dla wszystkich Pasjonatów!

Akademia Sekuraka

Niedawno wystartował dodruk tej świetnej, rozchwytywanej książki (około 940 stron). Mamy dla Was kod: pasja (wpiszcie go w koszyku), dzięki któremu otrzymujemy 10% zniżki - dziękujemy zaprzyjaźnionej ekipie Sekuraka za taki bonus dla Pasjonatów! Książka to pierwszy tom z serii o ITsec, który łagodnie wprowadzi w świat bezpieczeństwa IT każdą osobę - warto, polecamy!

...