Skip to content

Commit

Permalink
Improve Animation value type detection
Browse files Browse the repository at this point in the history
  • Loading branch information
pixelpicosean committed Jun 17, 2021
1 parent 912c2c9 commit 28cca6b
Show file tree
Hide file tree
Showing 3 changed files with 144 additions and 39 deletions.
132 changes: 95 additions & 37 deletions src/engine/scene/animation/animation.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ import { AABB } from "engine/core/math/aabb";
import { Transform } from "engine/core/math/transform";
import { Color } from "engine/core/color";
import { cubic_bezier } from "engine/core/math/interpolations";
import { Plane } from "engine/core/math/plane";


export const TrackType_VALUE = 0; // value
Expand Down Expand Up @@ -49,6 +50,43 @@ export const ValueType_Basis = 17;
export const ValueType_Transform = 18;
export const ValueType_Color = 19;

const TypeMap = {
number: ValueType_Number,
boolean: ValueType_Boolean,
string: ValueType_String,
any: ValueType_Any,

TransformKey: ValueType_TransformKey,
Vector3: ValueType_Vector3,
Quat: ValueType_Quat,
Vector2: ValueType_Vector2,
Rect2: ValueType_Rect2,
Transform2D: ValueType_Transform2D,
Plane: ValueType_Plane,
AABB: ValueType_AABB,
Basis: ValueType_Basis,
Transform: ValueType_Transform,
Color: ValueType_Color,
};
const CtorMap: { [type: string]: new () => any } = {
number: null,
boolean: null,
string: null,
any: null,

TransformKey: null,
Vector3: Vector3,
Quat: Quat,
Vector2: Vector2,
Rect2: Rect2,
Transform2D: Transform2D,
Plane: Plane,
AABB: AABB,
Basis: Basis,
Transform: Transform,
Color: Color,
};

export class Track {
type = 0;
interpolation = Interpolation_LINEAR;
Expand Down Expand Up @@ -144,48 +182,68 @@ export class ValueTrack extends Track {

const len = data.keys.times.length;

// guess value type
let ctor = null;
const first = data.keys.values[0];
// ValueType_Transform2D ?
// ValueType_Plane ?
// ValueType_AABB ?
// ValueType_Basis ?
// ValueType_Transform ?
switch (typeof first) {
case "number": {
this.value_type = ValueType_Number;
} break;
case "object": {
if (first.x !== undefined && first.y !== undefined) {
if (first.width !== undefined && first.height !== undefined) {
this.value_type = ValueType_Rect2;
ctor = Rect2;
} else if (first.z !== undefined) {
if (first.w !== undefined) {
this.value_type = ValueType_Quat;
ctor = Quat;

if (data.value_type) {
this.value_type = TypeMap[data.value_type as (keyof typeof TypeMap)] || ValueType_Any;
ctor = CtorMap[data.value_type as (keyof typeof CtorMap)] || null;
}

// guess value type
if (this.value_type === -1) {
// - find a valid value
let i = 0;
let first = data.keys.values[0];
while (first === null && i < data.keys.values.length) {
first = data.keys.values[i++];
}

// ValueType_Transform2D ?
// ValueType_Plane ?
// ValueType_AABB ?
// ValueType_Basis ?
// ValueType_Transform ?
switch (typeof first) {
case "number": {
this.value_type = ValueType_Number;
} break;
case "object": {
// is an instance of something, let's skip
if ("class" in first) {
this.value_type = ValueType_Any;
break;
}

if (first.x !== undefined && first.y !== undefined) {
if (first.width !== undefined && first.height !== undefined) {
this.value_type = ValueType_Rect2;
ctor = Rect2;
} else if (first.z !== undefined) {
if (first.w !== undefined) {
this.value_type = ValueType_Quat;
ctor = Quat;
} else {
this.value_type = ValueType_Vector3;
ctor = Vector3;
}
} else {
this.value_type = ValueType_Vector3;
ctor = Vector3;
this.value_type = ValueType_Vector2;
ctor = Vector2;
}
} else if (first.r !== undefined && first.g !== undefined && first.b !== undefined && first.a !== undefined) {
this.value_type = ValueType_Color;
ctor = Color;
} else {
this.value_type = ValueType_Vector2;
ctor = Vector2;
this.value_type = ValueType_Any;
}
} else if (first.r !== undefined && first.g !== undefined && first.b !== undefined && first.a !== undefined) {
this.value_type = ValueType_Color;
ctor = Color;
} else {
this.value_type = ValueType_Any;
}
} break;
case "boolean": {
this.value_type = ValueType_Boolean;
} break;
case "string": {
this.value_type = ValueType_String;
} break;
} break;
case "boolean": {
this.value_type = ValueType_Boolean;
} break;
case "string": {
this.value_type = ValueType_String;
} break;
}
}

this.values.length = len;
Expand Down
10 changes: 9 additions & 1 deletion tool/converter/res/Animation.js
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,8 @@ module.exports = (data) => {
let transitions = [];
let values = [];

let meta = { value_type: null };

let packed_transform = false;
if (track_type === 'transform') {
for (let i = 0; i < keys_data.length; i += 12) {
Expand Down Expand Up @@ -66,7 +68,7 @@ module.exports = (data) => {
} else {
times = PoolRealArray(keys_data.times);
transitions = PoolRealArray(keys_data.transitions);
values = GeneralArray(keys_data.values);
values = GeneralArray(keys_data.values, meta);
}

let track = {
Expand All @@ -81,8 +83,14 @@ module.exports = (data) => {
update: keys_data.update,
values,
},

value_type: undefined,
};

if (meta.value_type && meta.value_type !== "any") {
track.value_type = meta.value_type;
}

if (track_type === 'transform' && packed_transform) {
track.value_type = "PackedTransform";
} else if (track_type === 'value' && Array.isArray(track.keys.values[0]) && track.keys.values[0].length === 12) {
Expand Down
41 changes: 40 additions & 1 deletion tool/parser/type_converters.js
Original file line number Diff line number Diff line change
Expand Up @@ -641,16 +641,47 @@ module.exports.ColorArray = (arr) => {

/**
* @param {any} value
* @param {{ value_type: string }} [r_meta]
* @returns {any[]}
*/
module.exports.GeneralArray = (value) => {
module.exports.GeneralArray = (value, r_meta) => {
if (Array.isArray(value)) {
/** @type {Array} */
const array = value;

if (r_meta) {
r_meta.value_type = "any";

// guess type of array elements
let i = 0;
let first = array[0];
while (first === null && i < array.length) {
first = array[i++];
}

if (first.x !== undefined && first.y !== undefined) {
if (first.width !== undefined && first.height !== undefined) {
r_meta.value_type = "Rect2";
} else if (first.z !== undefined) {
if (first.w !== undefined) {
r_meta.value_type = "Quat";
} else {
r_meta.value_type = "Vector3";
}
} else {
r_meta.value_type = "Vector2";
}
} else if (first.r !== undefined && first.g !== undefined && first.b !== undefined && first.a !== undefined) {
r_meta.value_type = "Color";
}
}
return value;
}

if (typeof (value) === 'string') {
// Empty string?
if (value.length === 0) {
if (r_meta) r_meta.value_type = "any";
return [];
}

Expand Down Expand Up @@ -681,6 +712,8 @@ module.exports.GeneralArray = (value) => {
let value = param;
if (func) {
value = func(`${seg.func}( ${param} )`);

if (r_meta) r_meta.value_type = func;
}
segments.push(value);
}
Expand All @@ -703,9 +736,12 @@ module.exports.GeneralArray = (value) => {
} else {
segments.push(frag);
}

if (r_meta) r_meta.value_type = "string";
}
else if (Number.isFinite(parseFloat(frag))) {
segments.push(parseFloat(frag));
if (r_meta) r_meta.value_type = "number";
}
else if (frag === 'true' || frag === 'false') {
if (frag === 'true') {
Expand All @@ -714,6 +750,8 @@ module.exports.GeneralArray = (value) => {
else if (frag === 'false') {
segments.push(false);
}

if (r_meta) r_meta.value_type = "boolean";
}
else if (frag === 'null') {
segments.push(null);
Expand All @@ -728,6 +766,7 @@ module.exports.GeneralArray = (value) => {
return segments;
}

if (r_meta) r_meta.value_type = "undefined";
return undefined;
};

Expand Down

0 comments on commit 28cca6b

Please sign in to comment.