JSFL: обнаружение, когда элемент был перевернут - PullRequest
1 голос
/ 03 октября 2011

Я пишу экспортер в JSFL, чтобы экспортировать Flash-анимацию в формат, который можно воспроизвести в пользовательском проигрывателе. Экспортер в основном выполняет итерации по временной шкале и по всем элементам в каждом ключевом кадре и записывает имя элемента, положение, поворот, масштаб и локальное смещение. Они считываются в пользовательский проигрыватель, который передает данные в механизм спрайтов для воссоздания каждого кадра анимации.

Что я хочу сделать, это определить, был ли данный элемент перевернут (т. Е. Во Flash вы выбираете элемент (символ), затем Modify-> Transform-> Flip Horizontal), чтобы экспортер мог включить это информация, позволяющая движку спрайтов в плеере переворачивать UV текстуры, чтобы копировать то, что происходит во Flash. Это было бы полезно, скажем, для использования одного символа для правой руки персонажа и просто перевернуть его, чтобы он стал его левой рукой, вместо создания целого нового символа.

К сожалению, я не вижу способа найти эту информацию. Кажется, что ни одна из информации, которую я имею в наличии для Элементов, не подразумевает какого-либо переворота. Как я могу обнаружить переворачивание? Если это невозможно сделать алгоритмически, я бы согласился на то, что аниматору нужно вручную указывать, что символ был перевернут (создавая какой-то плагин, который дает им флажок, который записывает значение в элемент с помощью setPersistentData ( ), например), но я не знаю, как сделать такой плагин. Помогите!

Ответы [ 3 ]

3 голосов
/ 07 октября 2011

scaleX не работает, всегда кажется, что дает положительное значение. В конце концов мне пришлось сделать это с матрицей, чтобы получить ответ. Это основано на идее, что мы знаем, что матрица всегда содержит двумерное вращение, и мы знаем угол, поэтому мы можем избавиться от вращения от элементов матрицы, чтобы просто оставить нас со шкалой. Это ужасно, но, похоже, работает.

Кроме того, вращение иногда проявляется как NaN, особенно когда элемент перевернут. использование значения skewX, кажется, работает для вещей, которые, как вы знаете, не перекошены, но я хочу, чтобы мой экспортер мог обрабатывать перекошенные элементы, поэтому я думаю, что это может послужить основой для другого вопроса.

var rotationRadians;
if(isNaN(someElement.rotation)) {
    rotationRadians = someElement.skewX * Math.PI / 180;
}
else {
    rotationRadians = someElement.rotation * Math.PI / 180;
}   

var sinRot = Math.sin(rotationRadians);
var cosRot = Math.cos(rotationRadians);
var SOME_EPSILON = 0.01;
var flipScaleX, flipScaleY;

if(Math.abs(cosRot) <  SOME_EPSILON) {
    // Avoid divide by zero. We can use sine and the other two elements of the matrix instead.
    flipScaleX = (someElement.matrix.b / sinRot);
    flipScaleY = (someElement.matrix.c / -sinRot);
}
else {
    flipScaleX = someElement.matrix.a / cosRot;
    flipScaleY = someElement.matrix.d / cosRot;
}

flipScaleX выходит на ~ -1, если он перевернут горизонтально, на ~ 1, если нет. flipScaleY равно ~ -1, если перевернуто вертикально, ~ 1, если нет.

0 голосов
/ 02 февраля 2017

Вот решение электродруида, упакованное в несколько удобных функций:

function isFlippedHorizontally (element) {
  return Math.round(getFlip(element)[0]) == -1;
}

function isFlippedVertically (element) {
  return Math.round(getFlip(element)[0]) == -1;
}

function getFlip (element) {
  var rotationRadians;
  if(isNaN(element.rotation)) {
    rotationRadians = element.skewX * Math.PI / 180;
  }
  else {
    rotationRadians = element.rotation * Math.PI / 180;
  }

  var sinRot = Math.sin(rotationRadians);
  var cosRot = Math.cos(rotationRadians);
  var SOME_EPSILON = 0.01;
  var flipScaleX, flipScaleY;

  if(Math.abs(cosRot) <  SOME_EPSILON) {
    // Avoid divide by zero. We can use sine and the other two elements of the matrix instead.
    flipScaleX = (element.matrix.b / sinRot);
    flipScaleY = (element.matrix.c / -sinRot);
  }
  else {
    flipScaleX = element.matrix.a / cosRot;
    flipScaleY = element.matrix.d / cosRot;
  }
  return [flipScaleX, flipScaleY];
}

Пример использования:

var element = currentDoc.getTimeline().layers[0].frames[0].elements[0];
trace("Element is flipped:" + isFlippedHorizontally(element));

Спасибо за код электродару.

0 голосов
/ 03 октября 2011
...