Пример #1
0
/* calculate sphere that goes through 4 points */
struct sphere* sphere_circum(struct sphere* rs, const struct vec4f* v0,
                             const struct vec4f* v1, const struct vec4f* v2, const struct vec4f* v3)
{
    struct vec4f a;
    vec3_sub(&a, v1, v0);
    struct vec4f b;
    vec3_sub(&b, v2, v0);
    struct vec4f c;
    vec3_sub(&c, v3, v0);
    struct vec4f o;
    struct vec4f tmp;

    struct mat3f m;
    mat3_setf(&m,
              a.x, a.y, a.z,
              b.x, b.y, b.z,
              c.x, c.y, c.z,
              0.0f, 0.0f, 0.0f);

    float denom = 2.0f * mat3_det(&m);
    vec3_muls(&o, vec3_cross(&tmp, &a, &b), vec3_dot(&c, &c));
    vec3_add(&o, &o, vec3_muls(&tmp, vec3_cross(&tmp, &c, &a), vec3_dot(&b, &b)));
    vec3_add(&o, &o, vec3_muls(&tmp, vec3_cross(&tmp, &b, &c), vec3_dot(&a, &a)));
    vec3_muls(&o, &o, 1.0f/denom);

    return sphere_setf(rs, v0->x + o.x, v0->y + o.y, v0->z + o.z, vec3_len(&o) + EPSILON);
}
Пример #2
0
struct sphere* sphere_merge(struct sphere* rs, const struct sphere* s1,
                            const struct sphere* s2)
{
    struct vec4f cdiff;
    vec3_setf(&cdiff, s2->x - s1->x, s2->y - s1->y, s2->z - s1->z);
    float rd = s2->r - s1->r;
    float rd_sqr = rd * rd;
    float ld_sqr = cdiff.x*cdiff.x + cdiff.y*cdiff.y + cdiff.z*cdiff.z;
    if (rd_sqr < ld_sqr)    {
        float ld = sqrtf(ld_sqr);
        struct vec4f c;
        vec3_setf(&c, s1->x, s1->y, s1->z);
        float k = (ld + s2->r - s1->r)/(2.0f*ld);
        vec3_add(&c, &c, vec3_muls(&cdiff, &cdiff, k));
        rs->x = c.x;
        rs->y = c.y;
        rs->z = c.z;
        rs->r = (ld + s1->r + s2->r)*0.5f;
        return rs;
    }    else    {
        if (rd >= 0.0f)     return sphere_sets(rs, s2);
        else                return sphere_sets(rs, s1);
    }
}
Пример #3
0
void gfx_csm_prepare(const struct gfx_view_params* params, const struct vec3f* light_dir,
    const struct aabb* world_bounds)
{
    static const float tolerance = 10.0f;

    struct vec3f dir;
    vec3_setv(&dir, light_dir);

    float texoffset_x = 0.5f + (0.5f/g_csm->shadowmap_size);
    float texoffset_y = 0.5f + (0.5f/g_csm->shadowmap_size);

    struct mat3f view_inv;
    struct mat4f tex_mat;
    struct mat4f tmp_mat;
    float splits[CSM_CASCADE_CNT+1];

    mat3_setf(&view_inv,
        params->view.m11, params->view.m21, params->view.m31,
        params->view.m12, params->view.m22, params->view.m32,
        params->view.m13, params->view.m23, params->view.m33,
        params->cam_pos.x, params->cam_pos.y, params->cam_pos.z);
    mat4_setf(&tex_mat,
        0.5f, 0.0f, 0.0f, 0.0f,
        0.0f, -0.5f, 0.0f, 0.0f,
        0.0f, 0.0f, 1.0f, 0.0f,
        texoffset_x, texoffset_y, 0.0f, 1.0f);

    float csm_far = minf(CSM_FAR_MAX, params->cam->ffar);
    csm_split_range(params->cam->fnear, csm_far, splits);

    /* calculate cascades */
    struct frustum f;   /* frustum points for cascades */
    struct plane vp_planes[6];

    for (uint i = 0; i < CSM_CASCADE_CNT; i++)    {
        cam_calc_frustumcorners(params->cam, (struct vec3f*)f.points, &splits[i], &splits[i+1]);
        csm_calc_minsphere(&g_csm->cascades[i].bounds, &f, &params->view, &view_inv);
        memcpy(&g_csm->cascade_frusts[i], &f, sizeof(f));

        /* cascade matrixes: first we find two extreme points of the world, related to cascade */
        struct vec3f scenter;
        struct ray r;
        struct plane upper_plane;
        struct plane lower_plane;
        struct vec3f upper_pt;
        struct vec3f lower_pt;
        struct vec3f xaxis;
        struct vec3f yaxis;
        struct vec3f viewpos;
        struct vec3f tmp;
        struct vec3f lowerpt_vs;

        float sr = g_csm->cascades[i].bounds.r;
        vec3_setf(&scenter, g_csm->cascades[i].bounds.x, g_csm->cascades[i].bounds.y,
            g_csm->cascades[i].bounds.z);
        ray_setv(&r, &scenter, &dir);
        plane_setv(&upper_plane, &g_vec3_unity_neg, fabs(world_bounds->maxpt.y));
        plane_setv(&lower_plane, &g_vec3_unity, fabs(world_bounds->minpt.y));
        vec3_sub(&upper_pt, &r.pt,
            vec3_muls(&tmp, &dir, fabs(ray_intersect_plane(&r, &upper_plane)) + tolerance));
        vec3_add(&lower_pt, &r.pt,
            vec3_muls(&tmp, &dir, fabs(ray_intersect_plane(&r, &lower_plane)) + tolerance));

        /* view matrix of light view for the cascade :
         * dir = light_dir
         * up = (1, 0, 0)
         * pos = sphere center
         */
        vec3_norm(&xaxis, vec3_cross(&tmp, &g_vec3_unitx, &dir));
        vec3_cross(&yaxis, &dir, &xaxis);
        vec3_sub(&viewpos, &upper_pt, vec3_muls(&tmp, &dir, tolerance));
        mat3_setf(&g_csm->cascades[i].view,
            xaxis.x, yaxis.x, dir.x,
            xaxis.y, yaxis.y, dir.y,
            xaxis.z, yaxis.z, dir.z,
            -vec3_dot(&xaxis, &viewpos), -vec3_dot(&yaxis, &viewpos), -vec3_dot(&dir, &viewpos));

        /* orthographic projection matrix for cascade */
        vec3_transformsrt(&lowerpt_vs, &lower_pt, &g_csm->cascades[i].view);
        float nnear = tolerance*0.5f;
        float nfar = lowerpt_vs.z + sr;
        csm_calc_orthoproj(&g_csm->cascades[i].proj,
            sr*2.0f + 1.0f/g_csm->shadowmap_size,
            sr*2.0f + 1.0f/g_csm->shadowmap_size,
            nnear, nfar);
        g_csm->cascades[i].nnear = nnear;
        g_csm->cascades[i].nfar = nfar;

        /* calculate final matrix */
        mat3_mul4(&g_csm->cascade_vps[i], &g_csm->cascades[i].view, &g_csm->cascades[i].proj);

        cam_calc_frustumplanes(vp_planes, &g_csm->cascade_vps[i]);
        csm_calc_cascadeplanes(&g_csm->cascade_planes[i*4], vp_planes, &g_csm->cascade_vps[i]);

        csm_round_mat(&g_csm->cascade_vps[i], &g_csm->cascade_vps[i], g_csm->shadowmap_size);

        mat4_mul(&g_csm->shadow_mats[i],
            mat3_mul4(&tmp_mat, &view_inv, &g_csm->cascade_vps[i]), &tex_mat);
    }

    /* caculate shadow area bounds (aabb) */
    struct aabb cascade_near;
    struct aabb cascade_far;
    aabb_setzero(&g_csm->frustum_bounds);

    aabb_from_sphere(&cascade_near, &g_csm->cascades[0].bounds);
    aabb_from_sphere(&cascade_far, &g_csm->cascades[CSM_CASCADE_CNT-1].bounds);
    aabb_merge(&g_csm->frustum_bounds, &cascade_near, &cascade_far);

    vec3_setv(&g_csm->light_dir, &dir);
}
Пример #4
0
Vector Vector::__mul__(float k)
{
    Vector r;
    vec3_muls(&r.v_, &this->v_, k);
    return r;
}
Пример #5
0
Vector Vector::__div__(float k)
{
    Vector r;
    vec3_muls(&r.v_, &this->v_, 1.0f/k);
    return r;
}
Пример #6
0
t_vec3 vec3_mix(t_vec3 a, t_vec3 b, float t)
{
	return (vec3_add(vec3_muls(a, (1.0f - t)), vec3_muls(b, t)));
}