collision collision_none() { collision col; col.collided = false; col.time = FLT_MAX; col.point = vec3_zero(); col.norm = vec3_zero(); col.flags = 0; return col; }
void collision_response_slide(void* x, vec3* position, vec3* velocity, collision (*colfunc)(void* x, vec3* pos, vec3* vel) ) { collision col = colfunc(x, position, velocity); int count = 0; while (col.collided) { //renderer_add(x, render_object_line(*position, vec3_add(*position, col.norm), vec3_red(), count+1)); if (count++ == 100) { *velocity = vec3_zero(); break; } vec3 fwrd = vec3_mul(*velocity, col.time); float len = max(vec3_length(fwrd) - 0.001, 0.0) / vec3_length(fwrd); vec3 move = vec3_add(*position, vec3_mul(fwrd, len)); vec3 proj = vec3_project(vec3_mul(*velocity, (1.0-col.time)), col.norm); //renderer_add(x, render_object_line(*position, vec3_add(*position, vec3_normalize(proj)), vec3_green(), count+1)); *position = move; *velocity = proj; col = colfunc(x, position, velocity); } *position = vec3_add(*position, *velocity); }
void matrix3_from_quat(struct matrix3 *dst, const struct quat *q) { float norm = quat_dot(q, q); float s = (norm > 0.0f) ? (2.0f/norm) : 0.0f; float xx = q->x * q->x * s; float yy = q->y * q->y * s; float zz = q->z * q->z * s; float xy = q->x * q->y * s; float xz = q->x * q->z * s; float yz = q->y * q->z * s; float wx = q->w * q->x * s; float wy = q->w * q->y * s; float wz = q->w * q->z * s; dst->x.x = 1.0f - (yy + zz); dst->x.y = xy + wz; dst->x.z = xz - wy; dst->x.w = 0.0f; dst->y.x = xy - wz; dst->y.y = 1.0f - (xx + zz); dst->y.z = yz + wx; dst->y.w = 0.0f; dst->z.x = xz + wy; dst->z.y = yz - wx; dst->z.z = 1.0f - (xx + yy); dst->z.w = 0.0f; vec3_zero(&dst->t); }
camera* camera_new() { camera* c = malloc(sizeof(camera)); c->position = vec3_new(10, 10, 10); c->target = vec3_zero(); c->fov = 0.785398163; c->near_clip = 0.1; c->far_clip = 512.0; return c; }
static void build_sprite(struct vb_data *data, float fcx, float fcy, float start_u, float end_u, float start_v, float end_v) { struct vec2 *tvarray = data->tvarray[0].array; vec3_zero(data->points); vec3_set(data->points+1, fcx, 0.0f, 0.0f); vec3_set(data->points+2, 0.0f, fcy, 0.0f); vec3_set(data->points+3, fcx, fcy, 0.0f); vec2_set(tvarray, start_u, start_v); vec2_set(tvarray+1, end_u, start_v); vec2_set(tvarray+2, start_u, end_v); vec2_set(tvarray+3, end_u, end_v); }
void cart_to_polar(struct vec3 *dst, const struct vec3 *v) { struct vec3 polar; polar.z = vec3_len(v); if (close_float(polar.z, 0.0f, EPSILON)) { vec3_zero(&polar); } else { polar.x = asinf(v->y / polar.z); polar.y = atan2f(v->x, v->z); } vec3_copy(dst, &polar); }
animated_object* animated_object_new() { animated_object* ao = malloc(sizeof(animated_object)); ao->position = vec3_zero(); ao->scale = vec3_one(); ao->rotation = quat_id(); ao->renderable = asset_hndl_null(); ao->skeleton = asset_hndl_null(); ao->animation = asset_hndl_null(); ao->animation_time = 0; ao->pose = NULL; return ao; }
static inline void build_sprite(struct vb_data *data, float fcx, float fcy, uint32_t flip) { struct vec2 *tvarray = data->tvarray[0].array; float start_u, end_u; float start_v, end_v; assign_sprite_uv(&start_u, &end_u, (flip & GS_FLIP_U) != 0); assign_sprite_uv(&start_v, &end_v, (flip & GS_FLIP_V) != 0); vec3_zero(data->points); vec3_set(data->points+1, fcx, 0.0f, 0.0f); vec3_set(data->points+2, 0.0f, fcy, 0.0f); vec3_set(data->points+3, fcx, fcy, 0.0f); vec2_set(tvarray, start_u, start_v); vec2_set(tvarray+1, end_u, start_v); vec2_set(tvarray+2, start_u, end_v); vec2_set(tvarray+3, end_u, end_v); }
animated_object* animated_object_new() { animated_object* ao = malloc(sizeof(animated_object)); ao->position = vec3_zero(); ao->scale = vec3_one(); ao->rotation = quaternion_id(); ao->active = true; ao->recieve_shadows = true; ao->cast_shadows = true; ao->renderable = asset_hndl_null(); ao->skeleton = asset_hndl_null(); ao->animation = asset_hndl_null(); ao->animation_time = 0; ao->pose = NULL; return ao; }
vec3 OBSBasicPreview::CalculateStretchPos(const vec3 &tl, const vec3 &br) { uint32_t alignment = obs_sceneitem_getalignment(stretchItem); vec3 pos; vec3_zero(&pos); if (alignment & OBS_ALIGN_LEFT) pos.x = tl.x; else if (alignment & OBS_ALIGN_RIGHT) pos.x = br.x; else pos.x = (br.x - tl.x) * 0.5f + tl.x; if (alignment & OBS_ALIGN_TOP) pos.y = tl.y; else if (alignment & OBS_ALIGN_BOTTOM) pos.y = br.y; else pos.y = (br.y - tl.y) * 0.5f + tl.y; return pos; }
vec3 OBSBasicPreview::GetScreenSnapOffset(const vec3 &tl, const vec3 &br) { OBSBasic *main = reinterpret_cast<OBSBasic*>(App()->GetMainWindow()); vec2 screenSize = GetOBSScreenSize(); vec3 clampOffset; vec3_zero(&clampOffset); const float clampDist = CLAMP_DISTANCE / main->previewScale; if (fabsf(tl.x) < clampDist) clampOffset.x = -tl.x; if (fabsf(clampOffset.x) < EPSILON && fabsf(screenSize.x - br.x) < clampDist) clampOffset.x = screenSize.x - br.x; if (fabsf(tl.y) < clampDist) clampOffset.y = -tl.y; if (fabsf(clampOffset.y) < EPSILON && fabsf(screenSize.y - br.y) < clampDist) clampOffset.y = screenSize.y - br.y; return clampOffset; }
void OBSBasicPreview::StretchItem(const vec2 &pos) { Qt::KeyboardModifiers modifiers = QGuiApplication::keyboardModifiers(); obs_bounds_type boundsType = obs_sceneitem_get_bounds_type(stretchItem); uint32_t stretchFlags = (uint32_t)stretchHandle; bool shiftDown = (modifiers & Qt::ShiftModifier); vec3 tl, br, pos3; vec3_zero(&tl); vec3_set(&br, stretchItemSize.x, stretchItemSize.y, 0.0f); vec3_set(&pos3, pos.x, pos.y, 0.0f); vec3_transform(&pos3, &pos3, &screenToItem); if (stretchFlags & ITEM_LEFT) tl.x = pos3.x; else if (stretchFlags & ITEM_RIGHT) br.x = pos3.x; if (stretchFlags & ITEM_TOP) tl.y = pos3.y; else if (stretchFlags & ITEM_BOTTOM) br.y = pos3.y; if (!(modifiers & Qt::ControlModifier)) SnapStretchingToScreen(tl, br); obs_source_t source = obs_sceneitem_getsource(stretchItem); vec2 baseSize; vec2_set(&baseSize, float(obs_source_getwidth(source)), float(obs_source_getheight(source))); vec2 size; vec2_set(&size,br. x - tl.x, br.y - tl.y); if (boundsType != OBS_BOUNDS_NONE) { if (shiftDown) ClampAspect(tl, br, size, baseSize); if (tl.x > br.x) std::swap(tl.x, br.x); if (tl.y > br.y) std::swap(tl.y, br.y); vec2_abs(&size, &size); obs_sceneitem_set_bounds(stretchItem, &size); } else { if (!shiftDown) ClampAspect(tl, br, size, baseSize); vec2_div(&size, &size, &baseSize); obs_sceneitem_setscale(stretchItem, &size); } pos3 = CalculateStretchPos(tl, br); vec3_transform(&pos3, &pos3, &itemToScreen); vec2 newPos; vec2_set(&newPos, std::round(pos3.x), std::round(pos3.y)); obs_sceneitem_setpos(stretchItem, &newPos); }
static void reset_eye(void) { vec3_set(&gc.eye, 0, 0, -BASE_EYE_Z - .5f*WAVE_TITLE_TICS); vec3_zero(&delta_eye); }
static void terrain_new_chunk(terrain* ter, int i) { const int SUBDIVISIONS = NUM_TERRAIN_SUBDIVISIONS+1; terrain_chunk* tc = malloc(sizeof(terrain_chunk)); tc->id = i; tc->x = i % ter->num_cols; tc->y = i / ter->num_cols; tc->width = ter->chunk_width; tc->height = ter->chunk_height; int x_max = tc->width * SUBDIVISIONS + 1; int y_max = tc->height * SUBDIVISIONS + 1; tc->num_verts = x_max * y_max + x_max * 2 + y_max * 2; vec3* vertex_buffer = malloc(sizeof(vec3) * 4 * tc->num_verts); int index = 0; for(int x = 0; x < x_max; x++) for(int y = 0; y < y_max; y++) { float gx = tc->x * ter->chunk_width + (float)x/SUBDIVISIONS; float gy = tc->y * ter->chunk_height + (float)y/SUBDIVISIONS; float height = terrain_height(ter, vec2_new(gx, gy)); mat3 axis = terrain_tbn(ter, vec2_new(gx, gy)); vec3 pos = vec3_new(gx, height, gy); vec3 tangent = mat3_mul_vec3(axis, vec3_new(1,0,0)); vec3 normal = mat3_mul_vec3(axis, vec3_new(0,1,0)); vec3 binorm = mat3_mul_vec3(axis, vec3_new(0,0,1)); vertex_buffer[index] = pos; index++; vertex_buffer[index] = normal; index++; vertex_buffer[index] = tangent; index++; vertex_buffer[index] = binorm; index++; } /* Adding fins. Don't look, horrible code */ const float FIN_DEPTH = 5.0; for(int y = 0; y < y_max; y++) { int gx = tc->x * ter->chunk_width + 0; int gy = tc->y * ter->chunk_height + (float)y/SUBDIVISIONS; float height = terrain_height(ter, vec2_new(gx, gy)) - FIN_DEPTH; mat3 axis = terrain_tbn(ter, vec2_new(gx, gy)); vec3 pos = vec3_new(gx, height, gy); vec3 tangent = mat3_mul_vec3(axis, vec3_new(1,0,0)); vec3 normal = mat3_mul_vec3(axis, vec3_new(0,1,0)); vec3 binorm = mat3_mul_vec3(axis, vec3_new(0,0,1)); vertex_buffer[index] = pos; index++; vertex_buffer[index] = normal; index++; vertex_buffer[index] = tangent; index++; vertex_buffer[index] = binorm; index++; } for(int y = 0; y < y_max; y++) { int gx = tc->x * ter->chunk_width + ter->chunk_width; int gy = tc->y * ter->chunk_height + (float)y/SUBDIVISIONS; float height = terrain_height(ter, vec2_new(gx, gy)) - FIN_DEPTH; mat3 axis = terrain_tbn(ter, vec2_new(gx, gy)); vec3 pos = vec3_new(gx, height, gy); vec3 tangent = mat3_mul_vec3(axis, vec3_new(1,0,0)); vec3 normal = mat3_mul_vec3(axis, vec3_new(0,1,0)); vec3 binorm = mat3_mul_vec3(axis, vec3_new(0,0,1)); vertex_buffer[index] = pos; index++; vertex_buffer[index] = normal; index++; vertex_buffer[index] = tangent; index++; vertex_buffer[index] = binorm; index++; } for(int x = 0; x < x_max; x++) { int gx = tc->x * ter->chunk_width + (float)x/SUBDIVISIONS; int gy = tc->y * ter->chunk_height + 0; float height = terrain_height(ter, vec2_new(gx, gy)) - FIN_DEPTH; mat3 axis = terrain_tbn(ter, vec2_new(gx, gy)); vec3 pos = vec3_new(gx, height, gy); vec3 tangent = mat3_mul_vec3(axis, vec3_new(1,0,0)); vec3 normal = mat3_mul_vec3(axis, vec3_new(0,1,0)); vec3 binorm = mat3_mul_vec3(axis, vec3_new(0,0,1)); vertex_buffer[index] = pos; index++; vertex_buffer[index] = normal; index++; vertex_buffer[index] = tangent; index++; vertex_buffer[index] = binorm; index++; } for(int x = 0; x < x_max; x++) { int gx = tc->x * ter->chunk_width + (float)x/SUBDIVISIONS; int gy = tc->y * ter->chunk_height + ter->chunk_height; float height = terrain_height(ter, vec2_new(gx, gy)) - FIN_DEPTH; mat3 axis = terrain_tbn(ter, vec2_new(gx, gy)); vec3 pos = vec3_new(gx, height, gy); vec3 tangent = mat3_mul_vec3(axis, vec3_new(1,0,0)); vec3 normal = mat3_mul_vec3(axis, vec3_new(0,1,0)); vec3 binorm = mat3_mul_vec3(axis, vec3_new(0,0,1)); vertex_buffer[index] = pos; index++; vertex_buffer[index] = normal; index++; vertex_buffer[index] = tangent; index++; vertex_buffer[index] = binorm; index++; } tc->bound.center = vec3_zero(); for (int i = 0; i < index; i+=4) { tc->bound.center = vec3_add(tc->bound.center, vertex_buffer[i]); } tc->bound.center = vec3_div(tc->bound.center, tc->num_verts); tc->bound.radius = 0; for (int i = 0; i < index; i+=4) { tc->bound.radius = max(tc->bound.radius, vec3_dist(tc->bound.center, vertex_buffer[i])); } if (net_is_client()) { glGenBuffers(1, &tc->vertex_buffer); glBindBuffer(GL_ARRAY_BUFFER, tc->vertex_buffer); glBufferData(GL_ARRAY_BUFFER, sizeof(vec3) * 4 * tc->num_verts, vertex_buffer, GL_STATIC_DRAW); } free(vertex_buffer); if (net_is_client()) { glGenBuffers(NUM_TERRAIN_BUFFERS, tc->index_buffers); } for(int j = 0; j < NUM_TERRAIN_BUFFERS; j++) { int off = pow(2, j); int x_max = tc->width * SUBDIVISIONS; int y_max = tc->height * SUBDIVISIONS; tc->num_indicies[j] = (x_max / off) * (y_max / off) * 6 + (x_max / off) * 12 + (y_max / off) * 12; uint32_t* index_buffer = malloc(sizeof(uint32_t) * tc->num_indicies[j]); index = 0; for(int x = 0; x < x_max; x+=off) for(int y = 0; y < y_max; y+=off) { index_buffer[index] = x + y * (x_max+1); index++; index_buffer[index] = (x+off) + y * (x_max+1); index++; index_buffer[index] = (x+off) + (y+off) * (x_max+1); index++; index_buffer[index] = x + y * (x_max+1); index++; index_buffer[index] = (x+off) + (y+off) * (x_max+1); index++; index_buffer[index] = x + (y+off) * (x_max+1); index++; } /* Again, adding fins. Don't look horrible code */ int x_base = (x_max + 1) * (y_max + 1); int y_base = (x_max + 1) * (y_max + 1) + (x_max + 1) * 2; for(int x = 0; x < x_max; x+=off) { index_buffer[index] = x + 0 * (x_max+1); index++; index_buffer[index] = x_base + x; index++; index_buffer[index] = (x+off) + 0 * (x_max+1); index++; index_buffer[index] = (x+off) + 0 * (x_max+1); index++; index_buffer[index] = x_base + x; index++; index_buffer[index] = x_base + x+off; index++; } for(int x = 0; x < x_max; x+=off) { index_buffer[index] = x + y_max * (x_max+1); index++; index_buffer[index] = (x+off) + y_max * (x_max+1); index++; index_buffer[index] = x_base + y_max+1 + x; index++; index_buffer[index] = (x+off) + y_max * (x_max+1); index++; index_buffer[index] = x_base + x_max+1 + x+off; index++; index_buffer[index] = x_base + x_max+1 + x; index++; } for(int y = 0; y < y_max; y+=off) { index_buffer[index] = 0 + y * (x_max+1); index++; index_buffer[index] = 0 + (y+off) * (x_max+1); index++; index_buffer[index] = y_base + y; index++; index_buffer[index] = 0 + (y+off) * (x_max+1); index++; index_buffer[index] = y_base + y+off; index++; index_buffer[index] = y_base + y; index++; } for(int y = 0; y < y_max; y+=off) { index_buffer[index] = x_max + y * (x_max+1); index++; index_buffer[index] = y_base + y_max+1 + y; index++; index_buffer[index] = x_max + (y+off) * (x_max+1); index++; index_buffer[index] = x_max + (y+off) * (x_max+1); index++; index_buffer[index] = y_base + y_max+1 + y; index++; index_buffer[index] = y_base + y_max+1 + y+off; index++; } if (net_is_client()) { glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, tc->index_buffers[j]); glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(uint32_t) * tc->num_indicies[j], index_buffer, GL_DYNAMIC_DRAW); } free(index_buffer); } tc->colmesh = malloc(sizeof(cmesh)); tc->colmesh->is_leaf = true; tc->colmesh->triangles_num = (tc->width/4) * (tc->height/4) * 2; tc->colmesh->triangles = malloc(sizeof(ctri) * tc->colmesh->triangles_num); int tri_i = 0; for (int x = 0; x < tc->width; x += 4) for (int y = 0; y < tc->height; y += 4) { float gx = tc->x * ter->chunk_width + (float)x; float gy = tc->y * ter->chunk_height + (float)y; vec3 a = vec3_new(gx , terrain_height(ter, vec2_new(gx , gy )) , gy ); vec3 b = vec3_new(gx+4, terrain_height(ter, vec2_new(gx+4, gy )) , gy ); vec3 c = vec3_new(gx+4, terrain_height(ter, vec2_new(gx+4, gy+4)) , gy+4); vec3 d = vec3_new(gx , terrain_height(ter, vec2_new(gx , gy+4)) , gy+4); vec3 tang = vec3_normalize(vec3_sub(b, a)); vec3 binorm = vec3_normalize(vec3_sub(d, a)); vec3 norm = vec3_cross( binorm, tang ); tc->colmesh->triangles[tri_i] = ctri_new(a, c, b, norm); tri_i++; tc->colmesh->triangles[tri_i] = ctri_new(a, d, c, norm); tri_i++; } tc->colmesh->bound = cmesh_bound(tc->colmesh); /* For some reason this is not working correctly */ cmesh_subdivide(tc->colmesh, 5); ter->chunks[i] = tc; }