R8: finish app/ pure C ABI migration (P3-P9) and make OTIO required
- app/ no longer includes engine C++ headers nor holds engine C++ types: engine access goes through the oakengine C ABI plus C++ wrappers (oakutil/oaknode.h, oakutil/oakvideo.h) and app-local mirror types (tooltypes, trackreferencehandle, timelinecommonapp, keyframetypes, subtitleapp, serializedlayoutinfoapp, nodevaluehandle, sliderdisplaytypeapp) - engine: new C ABI functions for block/track/clip/transition navigation and predicates, links, caches, waveform/playback, disk folder, sequence_track_list, node_free, footage_is_valid, block_get_track, get_brush; loadotio/saveotio ported to the current engine API - OTIO is now a required dependency: CI and CD build it on every platform, FindOpenTimelineIO fixed for OTIO 0.16/0.19 (the old deps include requirement silently disabled OTIO everywhere), runtime libraries are bundled into packages and copied next to macOS binaries (oak_copy_otio_runtime) - fix ProjectViewModel drag&drop mime read/write size mismatch (segfault) - unify color label naming (k_olive -> "Oak") in the app-side mirror - docs: OTIO required, FFmpeg minimum corrected to 6.0 (en/zh) - gtest suite: 1925 passed, 0 failed
This commit is contained in:
+45
-38
@@ -21,53 +21,57 @@
|
||||
#ifndef OAKVALUEHELPER_H
|
||||
#define OAKVALUEHELPER_H
|
||||
|
||||
#include <cstring>
|
||||
|
||||
#include <QVariant>
|
||||
#include <QVector2D>
|
||||
#include <QVector3D>
|
||||
#include <QVector4D>
|
||||
|
||||
#include "node/keyframe.h"
|
||||
#include "node/value.h"
|
||||
#include "nodevaluehandle.h"
|
||||
#include "oakengine/node.h"
|
||||
#include "olive/core/util/color.h"
|
||||
#include "olive/core/util/rational.h"
|
||||
|
||||
namespace olive {
|
||||
|
||||
/**
|
||||
* @brief Convert a per-track component QVariant into the C ABI oak_node_value POD.
|
||||
*
|
||||
* `type` is the declared input data type (e.g. k_float/k_color). For split-track
|
||||
* types the component is the track-0 scalar (float for k_color's red channel, etc.).
|
||||
* Returns false for types that have no POD representation.
|
||||
* `type` uses engine NodeValue::Type ordinals (see the NodeValueType mirror
|
||||
* in nodevaluehandle.h; an engine NodeValue::Type converts implicitly) and
|
||||
* is the declared input data type (e.g. k_float/k_color). For split-track
|
||||
* types the component is the track-0 scalar (float for k_color's red
|
||||
* channel, etc.). Returns false for types that have no POD representation.
|
||||
*/
|
||||
static inline bool QVariantToOakNodeValue(NodeValue::Type type, const QVariant &v,
|
||||
static inline bool QVariantToOakNodeValue(int type, const QVariant &v,
|
||||
oak_node_value *out)
|
||||
{
|
||||
memset(out, 0, sizeof(*out));
|
||||
switch (type) {
|
||||
case NodeValue::k_int:
|
||||
case NodeValue::k_combo:
|
||||
out->type = (type == NodeValue::k_combo) ? OAK_NODE_VALUE_COMBO
|
||||
: OAK_NODE_VALUE_INT;
|
||||
case NodeValueType::k_int:
|
||||
case NodeValueType::k_combo:
|
||||
out->type = (type == NodeValueType::k_combo) ? OAK_NODE_VALUE_COMBO
|
||||
: OAK_NODE_VALUE_INT;
|
||||
out->num = v.toLongLong();
|
||||
return true;
|
||||
case NodeValue::k_float:
|
||||
case NodeValueType::k_float:
|
||||
out->type = OAK_NODE_VALUE_FLOAT;
|
||||
out->f[0] = v.toDouble();
|
||||
return true;
|
||||
case NodeValue::k_boolean:
|
||||
case NodeValueType::k_boolean:
|
||||
out->type = OAK_NODE_VALUE_BOOL;
|
||||
out->num = v.toBool() ? 1 : 0;
|
||||
return true;
|
||||
case NodeValue::k_rational:
|
||||
case NodeValueType::k_rational:
|
||||
out->type = OAK_NODE_VALUE_RATIONAL;
|
||||
{
|
||||
const Rational r = v.value<Rational>();
|
||||
const core::Rational r = v.value<core::Rational>();
|
||||
out->num = r.numerator();
|
||||
out->den = r.denominator();
|
||||
}
|
||||
return true;
|
||||
case NodeValue::k_color:
|
||||
case NodeValueType::k_color:
|
||||
out->type = OAK_NODE_VALUE_COLOR;
|
||||
{
|
||||
const core::Color c = v.value<core::Color>();
|
||||
@@ -77,7 +81,7 @@ static inline bool QVariantToOakNodeValue(NodeValue::Type type, const QVariant &
|
||||
out->f[3] = c.alpha();
|
||||
}
|
||||
return true;
|
||||
case NodeValue::k_vec2:
|
||||
case NodeValueType::k_vec2:
|
||||
out->type = OAK_NODE_VALUE_VEC2;
|
||||
{
|
||||
const QVector2D vec = v.value<QVector2D>();
|
||||
@@ -85,7 +89,7 @@ static inline bool QVariantToOakNodeValue(NodeValue::Type type, const QVariant &
|
||||
out->f[1] = vec.y();
|
||||
}
|
||||
return true;
|
||||
case NodeValue::k_vec3:
|
||||
case NodeValueType::k_vec3:
|
||||
out->type = OAK_NODE_VALUE_VEC3;
|
||||
{
|
||||
const QVector3D vec = v.value<QVector3D>();
|
||||
@@ -94,7 +98,7 @@ static inline bool QVariantToOakNodeValue(NodeValue::Type type, const QVariant &
|
||||
out->f[2] = vec.z();
|
||||
}
|
||||
return true;
|
||||
case NodeValue::k_vec4:
|
||||
case NodeValueType::k_vec4:
|
||||
out->type = OAK_NODE_VALUE_VEC4;
|
||||
{
|
||||
const QVector4D vec = v.value<QVector4D>();
|
||||
@@ -116,49 +120,51 @@ static inline bool QVariantToOakNodeValue(NodeValue::Type type, const QVariant &
|
||||
* single track's component (e.g. one float for a k_color channel). The resulting
|
||||
* POD has the input's declared type with the component in f[0]/num, exactly what
|
||||
* the per-track facade commands expect.
|
||||
*
|
||||
* `type` uses engine NodeValue::Type ordinals (NodeValueType mirror).
|
||||
*/
|
||||
static inline bool NodeTrackComponentToOakNodeValue(NodeValue::Type type,
|
||||
static inline bool NodeTrackComponentToOakNodeValue(int type,
|
||||
const QVariant &v,
|
||||
oak_node_value *out)
|
||||
{
|
||||
memset(out, 0, sizeof(*out));
|
||||
switch (type) {
|
||||
case NodeValue::k_int:
|
||||
case NodeValue::k_combo:
|
||||
out->type = (type == NodeValue::k_combo) ? OAK_NODE_VALUE_COMBO
|
||||
: OAK_NODE_VALUE_INT;
|
||||
case NodeValueType::k_int:
|
||||
case NodeValueType::k_combo:
|
||||
out->type = (type == NodeValueType::k_combo) ? OAK_NODE_VALUE_COMBO
|
||||
: OAK_NODE_VALUE_INT;
|
||||
out->num = v.toLongLong();
|
||||
return true;
|
||||
case NodeValue::k_float:
|
||||
case NodeValue::k_bezier:
|
||||
case NodeValueType::k_float:
|
||||
case NodeValueType::k_bezier:
|
||||
out->type = OAK_NODE_VALUE_FLOAT;
|
||||
out->f[0] = v.toDouble();
|
||||
return true;
|
||||
case NodeValue::k_boolean:
|
||||
case NodeValueType::k_boolean:
|
||||
out->type = OAK_NODE_VALUE_BOOL;
|
||||
out->num = v.toBool() ? 1 : 0;
|
||||
return true;
|
||||
case NodeValue::k_rational:
|
||||
case NodeValueType::k_rational:
|
||||
out->type = OAK_NODE_VALUE_RATIONAL;
|
||||
{
|
||||
const Rational r = v.value<Rational>();
|
||||
const core::Rational r = v.value<core::Rational>();
|
||||
out->num = r.numerator();
|
||||
out->den = r.denominator();
|
||||
}
|
||||
return true;
|
||||
case NodeValue::k_color:
|
||||
case NodeValueType::k_color:
|
||||
out->type = OAK_NODE_VALUE_COLOR;
|
||||
out->f[0] = v.toFloat();
|
||||
return true;
|
||||
case NodeValue::k_vec2:
|
||||
case NodeValueType::k_vec2:
|
||||
out->type = OAK_NODE_VALUE_VEC2;
|
||||
out->f[0] = v.toFloat();
|
||||
return true;
|
||||
case NodeValue::k_vec3:
|
||||
case NodeValueType::k_vec3:
|
||||
out->type = OAK_NODE_VALUE_VEC3;
|
||||
out->f[0] = v.toFloat();
|
||||
return true;
|
||||
case NodeValue::k_vec4:
|
||||
case NodeValueType::k_vec4:
|
||||
out->type = OAK_NODE_VALUE_VEC4;
|
||||
out->f[0] = v.toFloat();
|
||||
return true;
|
||||
@@ -185,7 +191,7 @@ static inline QVariant OakNodeValueToQVariant(const oak_node_value &v)
|
||||
return QVariant::fromValue(v.num != 0);
|
||||
case OAK_NODE_VALUE_RATIONAL:
|
||||
return QVariant::fromValue(
|
||||
Rational(int(v.num), int(v.den)));
|
||||
core::Rational(int(v.num), int(v.den)));
|
||||
case OAK_NODE_VALUE_COLOR:
|
||||
return QVariant::fromValue(core::Color(
|
||||
float(v.f[0]), float(v.f[1]), float(v.f[2]), float(v.f[3])));
|
||||
@@ -206,16 +212,17 @@ static inline QVariant OakNodeValueToQVariant(const oak_node_value &v)
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Map an engine NodeKeyframe::Type to the facade easing type.
|
||||
* @brief Map engine NodeKeyframe::Type ordinals (NodeKeyframeType mirror)
|
||||
* to the facade easing type (0=linear, 1=bezier, 2=hold).
|
||||
*/
|
||||
static inline int NodeKeyframeTypeToFacade(NodeKeyframe::Type type)
|
||||
static inline int NodeKeyframeTypeToFacade(int type)
|
||||
{
|
||||
switch (type) {
|
||||
case NodeKeyframe::k_bezier:
|
||||
case NodeKeyframeType::k_bezier:
|
||||
return 1;
|
||||
case NodeKeyframe::k_hold:
|
||||
case NodeKeyframeType::k_hold:
|
||||
return 2;
|
||||
case NodeKeyframe::k_linear:
|
||||
case NodeKeyframeType::k_linear:
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user