Beispiel #1
0
/******************************************************************************\
 Adjusts globe vertices to show the tile's height. Updates the globe with data
 from the [r_tiles] array.
\******************************************************************************/
void R_configure_globe(void)
{
        c_vec2_t tile;
        float left, right, top, bottom, tmp;
        int i, tx, ty, terrain;

        C_debug("Configuring globe");
        C_var_unlatch(&r_globe_transitions);

        /* UV dimensions of tile boundary box */
        tile.x = 2.f * (r_terrain_tex->surface->w / R_TILE_SHEET_W) /
                 r_terrain_tex->surface->w;
        tile.y = 2.f * (int)(C_SIN_60 * r_terrain_tex->surface->h /
                             R_TILE_SHEET_H / 2) / r_terrain_tex->surface->h;

        for (i = 0; i < r_tiles_max; i++) {
                set_tile_height(i, r_tiles[i].height);

                /* Tile terrain texture */
                terrain = tile_terrain(i);
                ty = terrain / R_TILE_SHEET_W;
                tx = terrain - ty * R_TILE_SHEET_W;
                left = tx / 2 * tile.x + C_SIN_60 * R_TILE_BORDER;
                right = (tx / 2 + 1) * tile.x - C_SIN_60 * R_TILE_BORDER;
                if (tx & 1) {
                        bottom = ty * tile.y + C_SIN_30 * R_TILE_BORDER;
                        top = (ty + 1.f) * tile.y - C_SIN_60 * R_TILE_BORDER;
                        left += tile.x / 2.f;
                        right += tile.x / 2.f;
                } else {
                        top = ty * tile.y + R_TILE_BORDER;
                        bottom = (ty + 1.f) * tile.y - C_SIN_30 * R_TILE_BORDER;
                }

                /* Flip tiles are mirrored over the middle */
                if (i < flip_limit) {
                        tmp = left;
                        left = right;
                        right = tmp;
                }

                r_globe_verts[3 * i].v.uv = C_vec2((left + right) / 2.f, top);
                r_globe_verts[3 * i + 1].v.uv = C_vec2(left, bottom);
                r_globe_verts[3 * i + 2].v.uv = C_vec2(right, bottom);
        }
        for (i = 0; i < r_tiles_max; i++)
                compute_tile_vectors(i);
        smooth_normals();

        /* We can update normals dynamically from now on */
        r_globe_smooth.edit = C_VE_FUNCTION;
        r_globe_smooth.update = globe_smooth_update;

        /* If Vertex Buffer Objects are supported, upload the vertices now */
        R_vbo_cleanup(&r_globe_vbo);
        R_vbo_init(&r_globe_vbo, &r_globe_verts[0].v,
                   3 * r_tiles_max, sizeof (*r_globe_verts),
                   R_VERTEX3_FORMAT, NULL, 0);
}
Beispiel #2
0
/******************************************************************************\
 Called when [r_globe_smooth] changes.
\******************************************************************************/
static int globe_smooth_update(c_var_t *var, c_var_value_t value)
{
        int i;

        if (value.f > 0.f) {
                r_globe_smooth.value.f = value.f;
                smooth_normals();
        } else
                for (i = 0; i < r_tiles_max * 3; i++)
                        r_globe_verts[i].v.no = r_tiles[i / 3].normal;
        R_vbo_update(&r_globe_vbo);
        return TRUE;
}
Beispiel #3
0
// particle simulation
void simulate(Scene* scene) {
    
    //put_your_code_here("Implement simulation");
    
    // for each mesh
    for(auto m : scene->meshes){
        // skip if no simulation
        if(!m->simulation){continue;}
        // compute time per step
        float timeperstep = scene->animation->dt/scene->animation->simsteps;
        // foreach simulation steps
        for(int step = 0; step < scene->animation->simsteps; step++){

            // foreach particle, compute external forces
            for(int particle: range(0, m->simulation->force.size())){
                // initialize particle forces to zero3f
                m->simulation->force[particle] = zero3f;
                // compute force of gravity
                auto g = scene->animation->gravity;
                // compute force of wind
                //EXTRA CREDIT DON"T DO WIND
                // accumulate sum of forces on particle
                m->simulation->force[particle] += g;
              }
            //SPRING EXTRA CREDIT
            // for each spring, compute spring force on points
                // compute spring distance and length
                // compute static force
                // accumulate static force on points
                // compute dynamic force
                // accumulate dynamic force on points

            // foreach particle, integrate using newton laws
            for(int particle: range(0, m->simulation->force.size())){
                // if pinned, skip
                if(m->simulation->pinned[particle]){continue;}
                // compute acceleration
                auto acceleration = m->simulation->force[particle]/m->simulation->mass[particle];
                // update velocity and positions using Euler's method
                m->simulation->vel[particle] = m->simulation->vel[particle] + acceleration*timeperstep ;

                m->pos[particle] = m->pos[particle] + m->simulation->vel[particle]*timeperstep + acceleration*timeperstep*timeperstep*.5;
                // for each surface, check for collision
                bool inside;
                for(auto surface : scene->surfaces){
                    inside = false;
                    // compute local position
                    auto L_pos = transform_point_to_local(surface->frame, m->pos[particle]);
                    auto R = surface->radius;
                    // if quad
                    vec3f col_pos;
                    vec3f col_norm;
                    if(surface->isquad){
                        // perform inside test
                        if(L_pos.x < R && L_pos.x > -R && L_pos.z < 0 && L_pos.y < R && L_pos.y > -R){
                            inside = true;
//                            vec3f col_pos = m->pos[particle];
                           col_norm = surface->frame.z;
                           col_pos = transform_point_from_local(surface->frame, vec3f(L_pos.x, L_pos.y, 0));


                        }
                    }
                    // if sphere
                    if(!surface->isquad){
                        // inside test
                        if(dist(zero3f, L_pos) < R){
//                            // if inside, compute a collision position and normal
                            inside = true;
//                            vec3f col_pos = m->pos[particle];

                            vec3f C = surface->frame.o; //sphere center
                            vec3f E = surface->frame.o; //camera origin

                            float a = lengthSqr(C - m->pos[particle]);
                            float b = dot(2*(C - m->pos[particle]), C-E);
                            float c = lengthSqr(C - m->pos[particle])-sqr(R);

                            float det = sqr(b) - 4*a*c;


                            //if(det < 0){continue;}
                            //calculate t1 and t2
                            float t1 = (-b + sqrt(det))/(2*a);
                            float t2 = (-b - sqrt(det))/(2*a);
                            //             just grab only the first hit
                            float t = fminf(t1, t2);
                            //check if computed param is within ray.tmin and ray.tmax

                            col_pos =  m->pos[particle] + t*(C - m->pos[particle]);       //find intersection point with quad
                            col_norm = normalize(col_pos - C);


                        }
                    }
                    // if inside
                    if(inside == true){
                        m->pos[particle]=col_pos;
                         // update velocity (particle bounces), taking into account loss of kinetic energy
                        vec3f ref = reflect(m->simulation->vel[particle], col_norm);

                        auto v1 = ref - dot(ref, col_norm)*col_norm;
                        auto v2 = dot(ref, col_norm)*col_norm;
                        m->simulation->vel[particle] = (1 - scene->animation->bounce_dump.x)*v1 +(1 - scene->animation->bounce_dump.y)*v2;
                    }
                }
             }
             }

        // smooth normals if it has triangles or quads
    if(m->quad.size() != 0 || m->triangle.size() != 0){
        smooth_normals(m);
    }
    }
}