⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 projector.cpp

📁 国外游戏开发者杂志2003年第七期配套代码
💻 CPP
字号:
#include "../framework.h"
#include "projector.h"

#include <math.h>

const double YON_RANGE = 4000.0;

Projector::Projector() {
    fov = M_PI * 0.5f;
    z_viewport = 0;
    i_z_viewport = 1;
    offset_x = 0;
    offset_y = 0;
    center_x = 0;
    center_y = 0;
    viewport_width = 0;
    viewport_height = 0;
    pixels_per_unit = 0;
    offset_x = offset_y = 0;
}

Projector::~Projector() {
}

void Projector::auto_compute_offsets() {
    double h = viewport_height;

    offset_x = center_x;
    offset_y = h - center_y;

    my_frustum.recalibrate(this);
}

void Projector::get_cop(float *x, float *y) {
    *x = center_x;
    *y = center_y;
}

void Projector::set_cop(float x, float y) {
    center_x = x;
    center_y = y;

    auto_compute_offsets();
}

void Projector::set_fov(double radians) {
    double w = viewport_width;
    double h = viewport_height;
    
    double z0 = w / (2.0 * tan(radians * 0.5));
    z_viewport = z0;
    i_z_viewport = 1.0 / z_viewport;

    fov = radians;

    auto_compute_offsets();
}

void Projector::set_viewport(float width, float height) {
    viewport_width = width;
    viewport_height = height;

    center_x = viewport_width * 0.5;
    center_y = viewport_height * 0.5;
    set_fov(fov);
}

void Projector::set_viewport_parameters(float ox, float oy,
                                        float wx, float wy) {
    center_x = ox;
    center_y = oy;

    viewport_width = wx;
    viewport_height = wy;

    set_fov(fov);
}


Frustum::Frustum() {
    clip_signal_flags[LEFT] = AGAINST_LEFT;
    clip_signal_flags[RIGHT] = AGAINST_RIGHT;
    clip_signal_flags[FLOOR] = AGAINST_FLOOR;
    clip_signal_flags[CEILING] = AGAINST_CEILING;
    clip_signal_flags[HITHER] = AGAINST_HITHER;
    clip_signal_flags[YON] = AGAINST_YON;

    num_planes = 5;
    most_planes = 5;

    weird = false;
    have_constraint = false;
    calibration_number = 0;

    cx0 = cy0 = cx1 = cy1 = cx2 = cy2 = cx3 = cy3 = 0;
}

void Frustum::recalibrate(Projector *projector) {
    calibration_number++;
    if (have_constraint) {
        recalibrate(projector, cx0, cy0, cx1, cy1, cx2, cy2, cx3, cy3);
    } else {
        float w = projector->viewport_width;
        float h = projector->viewport_height;

        recalibrate(projector, 0, 0, 0, h, w, h, w, 0);
    }
}

inline void Clamp2(float *val, float min, float max) {
    if (*val < min) *val = min;
    if (*val > max) *val = max;
}

void Frustum::recalibrate(Projector *projector,
                          float x0, float y0, float x1, float y1,
                          float x2, float y2, float x3, float y3) {

    float border = 0.1;
    float fudge = 0.6;

    Clamp2(&x0, 0, projector->viewport_width);
    Clamp2(&x1, 0, projector->viewport_width);
    Clamp2(&x2, 0, projector->viewport_width);
    Clamp2(&x3, 0, projector->viewport_width);

    Clamp2(&y0, 0, projector->viewport_height);
    Clamp2(&y1, 0, projector->viewport_height);
    Clamp2(&y2, 0, projector->viewport_height);
    Clamp2(&y3, 0, projector->viewport_height);

    float left, right, bottom, top;
    left = x0;
    right = x2;
    bottom = y0;
    top = y2;

    float lambda_numerator = projector->z_viewport;
    float offset_x = projector->offset_x;
    float offset_y = projector->offset_y;

    plane[Frustum::LEFT] = Plane3(lambda_numerator,
                                  offset_x - left - border + fudge, 0, 0);

    plane[Frustum::RIGHT] =
        Plane3(-lambda_numerator, -(offset_x - right + border), 0, 0);

    plane[Frustum::FLOOR] =
        Plane3(0, -(bottom + border) + offset_y, lambda_numerator, 0);

    plane[Frustum::CEILING] =
        Plane3(0, (top - offset_y - border + fudge), -lambda_numerator, 0);

    plane[Frustum::HITHER] = Plane3(0, 1, 0, -0.01);

    plane[Frustum::YON] = Plane3(0, -1, 0, YON_RANGE);

    int i;
    for (i = 0; i < num_planes; i++) {
        plane[i].normalize();
    }
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -