void plane_transform(struct plane *dst, const struct plane *p, const struct matrix3 *m) { struct vec3 temp; vec3_transform(&dst->dir, &p->dir, m); vec3_norm(&dst->dir, &dst->dir); vec3_transform(&temp, &m->t, m); dst->dist = p->dist - vec3_dot(&dst->dir, &temp); }
static vec3 GetTransformedPos(float x, float y, const matrix4 &mat) { vec3 result; vec3_set(&result, x, y, 0.0f); vec3_transform(&result, &result, &mat); return result; }
void OBSBasicPreview::SnapStretchingToScreen(vec3 &tl, vec3 &br) { uint32_t stretchFlags = (uint32_t)stretchHandle; vec3 newTL = GetTransformedPos(tl.x, tl.y, itemToScreen); vec3 newTR = GetTransformedPos(br.x, tl.y, itemToScreen); vec3 newBL = GetTransformedPos(tl.x, br.y, itemToScreen); vec3 newBR = GetTransformedPos(br.x, br.y, itemToScreen); vec3 boundingTL; vec3 boundingBR; vec3_copy(&boundingTL, &newTL); vec3_min(&boundingTL, &boundingTL, &newTR); vec3_min(&boundingTL, &boundingTL, &newBL); vec3_min(&boundingTL, &boundingTL, &newBR); vec3_copy(&boundingBR, &newTL); vec3_max(&boundingBR, &boundingBR, &newTR); vec3_max(&boundingBR, &boundingBR, &newBL); vec3_max(&boundingBR, &boundingBR, &newBR); vec3 offset = GetScreenSnapOffset(boundingTL, boundingBR); vec3_add(&offset, &offset, &newTL); vec3_transform(&offset, &offset, &screenToItem); vec3_sub(&offset, &offset, &tl); if (stretchFlags & ITEM_LEFT) tl.x += offset.x; else if (stretchFlags & ITEM_RIGHT) br.x += offset.x; if (stretchFlags & ITEM_TOP) tl.y += offset.y; else if (stretchFlags & ITEM_BOTTOM) br.y += offset.y; }
static bool FindItemAtPos(obs_scene_t scene, obs_sceneitem_t item, void *param) { SceneFindData *data = reinterpret_cast<SceneFindData*>(param); matrix4 transform; vec3 transformedPos; vec3 pos3; vec3_set(&pos3, data->pos.x, data->pos.y, 0.0f); obs_sceneitem_get_box_transform(item, &transform); matrix4_inv(&transform, &transform); vec3_transform(&transformedPos, &pos3, &transform); if (transformedPos.x >= 0.0f && transformedPos.x <= 1.0f && transformedPos.y >= 0.0f && transformedPos.y <= 1.0f) { if (data->selectBelow && obs_sceneitem_selected(item)) { if (data->item) return false; else data->selectBelow = false; } data->item = item; } UNUSED_PARAMETER(scene); return true; }
static bool project(vec3 *out, vec3 const *in, mat4 const *model, mat4 const *projection, viewport const *viewport) { mat4 transform; mat4_transform(&transform, model, projection); vec3_transform(out, in, &transform); float w = transform.x.w * in->x + transform.y.w * in->y + transform.z.w * in->z + transform.t.w; if (out->z < -w || out->z > w) { return false; } out->x /= w; out->y /= w; out->z /= w; out->x = out->x * 0.5f + 0.5f; out->y = out->y * 0.5f + 0.5f; out->x = out->x * viewport->width + viewport->x; out->y = out->y * viewport->height + viewport->y; return true; }
void matrix3_mul(struct matrix3 *dst, const struct matrix3 *m1, const struct matrix3 *m2) { vec3_rotate(&dst->x, &m1->x, m2); vec3_rotate(&dst->y, &m1->y, m2); vec3_rotate(&dst->z, &m1->z, m2); vec3_transform(&dst->t, &m1->t, m2); }
static vec3 GetTransformedPosScaled(float x, float y, const matrix4 &mat, float scale) { vec3 result; vec3_set(&result, x, y, 0.0f); vec3_transform(&result, &result, &mat); vec3_mulf(&result, &result, scale); return result; }
void matrix3_transpose(struct matrix3 *dst, const struct matrix3 *m) { __m128 tmp1, tmp2; vec3_transform(&dst->t, &m->t, m); vec3_neg(&dst->t, &dst->t); tmp1 = _mm_movelh_ps(m->x.m, m->y.m); tmp2 = _mm_movehl_ps(m->y.m, m->x.m); dst->x.m = _mm_shuffle_ps(tmp1, m->z.m, _MM_SHUFFLE(3, 0, 2, 0)); dst->y.m = _mm_shuffle_ps(tmp1, m->z.m, _MM_SHUFFLE(3, 1, 3, 1)); dst->z.m = _mm_shuffle_ps(tmp2, m->z.m, _MM_SHUFFLE(3, 2, 2, 0)); }
static void DrawCircleAtPos(float x, float y, matrix4 &matrix, float previewScale) { struct vec3 pos; vec3_set(&pos, x, y, 0.0f); vec3_transform(&pos, &pos, &matrix); vec3_mulf(&pos, &pos, previewScale); gs_matrix_push(); gs_matrix_translate(&pos); gs_draw(GS_LINESTRIP, 0, 0); gs_matrix_pop(); }
void bounds_transform(struct bounds *dst, const struct bounds *b, const struct matrix4 *m) { struct bounds temp = {0}; bool b_init = false; int i; for (i = 0; i < 8; i++) { struct vec3 p; bounds_get_point(&p, b, i); vec3_transform(&p, &p, m); if (!b_init) { vec3_copy(&temp.min, &p); vec3_copy(&temp.max, &p); b_init = true; } else { if (p.x < temp.min.x) temp.min.x = p.x; else if (p.x > temp.max.x) temp.max.x = p.x; if (p.y < temp.min.y) temp.min.y = p.y; else if (p.y > temp.max.y) temp.max.y = p.y; if (p.z < temp.min.z) temp.min.z = p.z; else if (p.z > temp.max.z) temp.max.z = p.z; } } bounds_copy(dst, &temp); }
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); }