Esempio n. 1
0
/**
 * Initialize the scene
 * Set root data directory and load/init required assets
 */
int init_scene()
{
    /* data root directory is "[tutorials]/data" */
    set_datadir();

    /* Initialize default FPS camera, FPS cameras automically handle input and smoothing */
    vec4f pos;
    vec4f target;
    vec3_setf(&pos, 0.0f, 1.0f, -5.0f);
    vec3_setf(&target, 0.0f, 1.0f, 1.0f);
    cam_fps_init(&g_cam, &pos, &target, CAM_NEAR, CAM_FAR, math_torad(CAM_FOV));

    g_scene = scn_create_scene("main");
    if (g_scene == 0)   {
        err_print(__FILE__, __LINE__, "Initializing scene failed");
        return FALSE;
    }

    /* Activate the scene and the camera */
    scn_setactive(g_scene);
    wld_set_cam(&g_cam.c);

    /* create default timer */
    g_timer = timer_createinstance(TRUE);
    if (g_timer == NULL)    {
        err_print(__FILE__, __LINE__, "Could not create timer");
        return FALSE;
    }

    return tut02_load_data();
}
Esempio n. 2
0
struct aabb* aabb_merge(struct aabb* rb, const struct aabb* b1, const struct aabb* b2)
{
    struct vec4f minpt;
    struct vec4f maxpt;

    vec3_setf(&minpt, minf(b1->minpt.x, b2->minpt.x), minf(b1->minpt.y, b2->minpt.y),
              minf(b1->minpt.z, b2->minpt.z));
    vec3_setf(&maxpt, maxf(b1->maxpt.x, b2->maxpt.x), maxf(b1->maxpt.y, b2->maxpt.y),
              maxf(b1->maxpt.z, b2->maxpt.z));
    return aabb_setv(rb, &minpt, &maxpt);
}
Esempio n. 3
0
int sphere_intersects(const struct sphere* s1, const struct sphere* s2)
{
    struct vec3f d;
    vec3_setf(&d, s2->x - s1->x, s2->y - s1->y, s2->z - s1->z);
    float l = vec3_dot(&d, &d);
    float sr = s2->r + s1->r;
    return (l*l - sr*sr) < EPSILON;
}
Esempio n. 4
0
const struct mat3f* model_loadmat_pq(struct mat3f* rm, const float* pos, const float* quat)
{
    struct vec3f p;
    struct quat4f q;

    vec3_setf(&p, pos[0], pos[1], pos[2]);
    quat_setf(&q, quat[0], quat[1], quat[2], quat[3]);

    return mat3_set_trans_rot(rm, &p, &q);
}
Esempio n. 5
0
Vector Quat::getEuler()
{
    float rx;
    float ry;
    float rz;

    quat_geteuler(&rx, &ry, &rz, &this->q_);
    Vector r;
    vec3_setf(&r.v_, rx, ry, rz);
    return r;
}
Esempio n. 6
0
const struct vec4f* gfx_csm_get_cascades(const struct mat3f* view)
{
    static struct vec4f cascades[CSM_CASCADE_CNT];
    struct vec4f center;
    for (uint i = 0; i < CSM_CASCADE_CNT; i++)    {
        const struct sphere* s = &g_csm->cascades[i].bounds;
        vec3_setf(&center, s->x, s->y, s->z);
        vec3_transformsrt(&center, &center, view);
        vec4_setf(&cascades[i], center.x, center.y, center.z, s->r);
    }
    return cascades;
}
Esempio n. 7
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);
    }
}
Esempio n. 8
0
struct sphere* sphere_xform(struct sphere* rs, const struct sphere* s, const struct mat3f* m)
{
    /* we have to transform radius by scale value of transform matrix
     * to determine scale value, we find the highest scale component of the matrix */
    float xlen = m->m11*m->m11 + m->m12*m->m12 + m->m13*m->m13;
    float ylen = m->m21*m->m21 + m->m22*m->m22 + m->m23*m->m23;
    float zlen = m->m31*m->m31 + m->m32*m->m32 + m->m33*m->m33;
    float isqr_scale = maxf(xlen, ylen);
    isqr_scale = maxf(isqr_scale, zlen);

    /* transform center */
    struct vec4f c;
    vec3_setf(&c, s->x, s->y, s->z);
    vec3_transformsrt(&c, &c, m);
    return sphere_setf(rs, c.x, c.y, c.z, s->r*sqrtf(isqr_scale));
}
Esempio n. 9
0
void csm_calc_minsphere(struct sphere* bounds, const struct frustum* f,
    const struct mat3f* view, const struct mat3f* view_inv)
{
    /* reference:
     * http://www.gamedev.net/topic/604797-minimum-bounding-sphere-of-a-frustum/
     */
    struct vec3f a;
    struct vec3f b;
    struct vec3f p;
    struct vec3f tmp;

    vec3_transformsrt(&a, &f->points[1], view);
    vec3_transformsrt(&b, &f->points[5], view);

    float z = (vec3_dot(&b, &b) - vec3_dot(&a, &a))/(2.0f*(b.z - a.z));
    vec3_setf(&p, 0.0f, 0.0f, z);
    vec3_transformsrt(&p, &p, view_inv);

    sphere_setf(bounds, p.x, p.y, p.z, vec3_len(vec3_sub(&tmp, &f->points[5], &p)) + 0.01f);
}
Esempio n. 10
0
result_t wld_initmgr()
{
    result_t r;
    r = hashtable_open_create(mem_heap(), &g_wld.stable, 5, 10, 0);
    if (IS_FAIL(r)) {
        err_print(__FILE__, __LINE__, "Initializing world manager failed");
        return r;
    }

    r = arr_create(mem_heap(), &g_wld.sections, sizeof(struct wld_section), 5, 10, 0);
    if (IS_FAIL(r)) {
        err_print(__FILE__, __LINE__, "Initializing world manager failed");
        return r;
    }

    /* camera */
    struct vec3f pos;
    cam_init(&g_wld.default_cam, vec3_setf(&pos, 0.0f, 0.0f, -1.0f), &g_vec3_zero, CAM_NEAR,
        CAM_FAR, math_torad(CAM_FOV));
    g_wld.cam = &g_wld.default_cam;

    return RET_OK;
}
Esempio n. 11
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);
}
Esempio n. 12
0
Vector::Vector(float x, float y, float z)
{
    vec3_setf(&v_, x, y, z);
}
Esempio n. 13
0
int import_anim(const struct import_params* params)
{
    uint flags = 0;
    if (params->coord == COORD_NONE)
        flags |= aiProcess_MakeLeftHanded;

    const struct aiScene* scene = aiImportFileEx(params->in_filepath, flags, NULL);

    if (scene == NULL)  {
        printf(TERM_BOLDRED "Error: (assimp) %s\n" TERM_RESET, aiGetErrorString());
        return FALSE;
    }

    if (scene->mNumAnimations == 0) {
        printf(TERM_BOLDRED "Error: no animation exist in the file '%s'" TERM_RESET,
            params->in_filepath);
        return FALSE;
    }

    g_anim_coord = params->coord;
    uint fps = params->anim_fps != 0 ? params->anim_fps : DEFAULT_FPS;
    uint channel_cnt = 0;
    uint frame_cnt = 0;
    int has_scale = FALSE;

    /* channel count is the sum of all animation channels */
    /* frame_cnt is the maximum of all animation channel key counts */
    for (uint i = 0; i < scene->mNumAnimations; i++)  {
        const struct aiAnimation* anim = scene->mAnimations[i];
        channel_cnt += anim->mNumChannels;
        for (uint k = 0; k < anim->mNumChannels; k++) {
            frame_cnt = maxui(frame_cnt, maxui(anim->mChannels[k]->mNumPositionKeys,
                maxui(anim->mChannels[k]->mNumRotationKeys, anim->mChannels[k]->mNumScalingKeys)));
        }
    }

    if (channel_cnt == 0)   {
        printf(TERM_BOLDRED "Error: no animation channels exist in the file '%s'" TERM_RESET,
            params->in_filepath);
        return FALSE;
    }

    /* parse my data from assimp data */
    struct anim_ext h3danim;
    memset(&h3danim, 0x00, sizeof(h3danim));

    /* channels */
    struct anim_channel_ext* h3dchannels = (struct anim_channel_ext*)
        ALLOC(sizeof(struct anim_channel_ext)*channel_cnt, 0);
    ASSERT(h3dchannels != NULL);
    memset(h3dchannels, 0x00, sizeof(struct anim_channel_ext)*channel_cnt);

    uint channel_offset = 0;
    for (uint i = 0; i < scene->mNumAnimations; i++)  {
        struct aiAnimation* anim = scene->mAnimations[i];

        for (uint k = 0; k < anim->mNumChannels; k++) {
            struct aiNodeAnim* channel = anim->mChannels[k];
            struct anim_channel_ext* h3dchannel = &h3dchannels[k + channel_offset];

            str_safecpy(h3dchannel->c.bindto, sizeof(h3dchannel->c.bindto), channel->mNodeName.data);
            h3dchannel->pos_scale = (struct vec4f*)ALLOC(sizeof(struct vec4f)*frame_cnt, 0);
            h3dchannel->rot = (struct quat4f*)ALLOC(sizeof(struct quat4f)*frame_cnt, 0);
            ASSERT(h3dchannel->pos_scale && h3dchannel->rot);

            struct vec3f pos;
            struct quat4f quat;
            float scale = 1.0f;

            /* fill channel data */
            for (uint f = 0; f < frame_cnt; f++)  {
                if (f < channel->mNumPositionKeys)  {
                    vec3_setf(&pos,
                        channel->mPositionKeys[f].mValue.x,
                        channel->mPositionKeys[f].mValue.y,
                        channel->mPositionKeys[f].mValue.z);
                }

                if (f < channel->mNumRotationKeys)  {
                    quat_setf(&quat,
                        channel->mRotationKeys[f].mValue.x,
                        channel->mRotationKeys[f].mValue.y,
                        channel->mRotationKeys[f].mValue.z,
                        channel->mRotationKeys[f].mValue.w);
                }

                if (f < channel->mNumScalingKeys)   {
                    scale = (channel->mScalingKeys[f].mValue.x +
                        channel->mScalingKeys[f].mValue.y +
                        channel->mScalingKeys[f].mValue.z) / 3.0f;
                    has_scale |= !math_isequal(scale, 1.0f);
                }

                import_convert_vec3(&pos, &pos, g_anim_coord);
                import_convert_quat(&quat, &quat, g_anim_coord);

                vec4_setf(&h3dchannel->pos_scale[f], pos.x, pos.y, pos.z, scale);
                quat_setf(&h3dchannel->rot[f], quat.x, quat.y, quat.z, quat.w);
            }
        }

        channel_offset += anim->mNumChannels;
    }

    /* write to file */
    h3danim.a.channel_cnt = channel_cnt;
    h3danim.a.frame_cnt = frame_cnt;
    h3danim.a.has_scale = has_scale;
    h3danim.a.fps = fps;
    h3danim.channels = h3dchannels;

    /* parse json clip file */
    h3danim.clips = import_loadclips(params->clips_json_filepath, frame_cnt, &h3danim.a.clip_cnt);

    /* write */
    int r = import_writeanim(params->out_filepath, &h3danim);

    /* report */
    if (r)  {
        printf(TERM_BOLDGREEN "ok, saved: \"%s\".\n" TERM_RESET, params->out_filepath);

        if (params->verbose)    {
            printf(TERM_WHITE);
            printf("Animation report:\n"
                "  animation count: %d\n"
                "  frame count: %d\n"
                "  channel count: %d\n"
                "  has_scale: %s\n"
                "  fps: %d\n",
                scene->mNumAnimations,
                frame_cnt,
                channel_cnt,
                has_scale ? "yes" : "no",
                fps);
            printf(TERM_RESET);
        }
    }

    /* cleanup */
    for (uint i = 0; i < h3danim.a.channel_cnt; i++)    {
        if (h3danim.channels[i].pos_scale != NULL)
            FREE(h3danim.channels[i].pos_scale);
        if (h3danim.channels[i].rot != NULL)
            FREE(h3danim.channels[i].rot);
    }
    FREE(h3danim.clips);
    FREE(h3danim.channels);
    aiReleaseImport(scene);

    return r;
}