Форум Flasher.ru

Форум Flasher.ru (http://www.flasher.ru/forum/index.php)
-   ActionScript 3.0 (http://www.flasher.ru/forum/forumdisplay.php?f=83)
-   -   [Stage3D] Поворот без искажений c использованием Matrix3D (http://www.flasher.ru/forum/showthread.php?t=208617)

Dron1564 06.08.2014 23:18

Поворот без искажений c использованием Matrix3D
 
Здравствуйте,
Пытаюсь освоить Stage3D, все аспекты вполне ясны и имеется много уроков, но один вопрос не могу решить уже неделю:
Как правильно для Matrix3D присвоить значение поворота относительно оси Z. ( аналог "rotation" )
Позиция и размер вычисляются правильно, но как только добавляется поворот картинка растягивается.

Опробовал 2 метода:
1.
Код AS3:

_positionMatrix.identity();
var v3:Vector.<Vector3D> = new Vector.<Vector3D>(3);
v3 = _positionMatrix.decompose();
v3[0].incrementBy(new Vector3D( x, y, 0 ));// x, y, z
v3[1].incrementBy(new Vector3D(0,0,-rotation*Math.PI/180)); // rotationX, rotationY, rotationZ
v3[2].incrementBy(new Vector3D(width,height,0)); // scaleX, scaleY, scaleZ
_positionMatrix.recompose(v3);

2.
Код AS3:

 
_positionMatrix.identity();
_positionMatrix.appendScale(width,height,1);
_positionMatrix.appendTranslation(x,y,0);
_positionMatrix.appendRotation(-rotation,Vector3D.Z_AXIS );

Cправа Stage ( Спрайт с графикой ), слева Stage3D ( оба метода поворота дают один и тот же результат )
https://dl.dropboxusercontent.com/u/...trix3dbug1.jpg

Подозреваю, что тут как то замешан AspectRatio для Stage3D,
Помогите пожалуйста.

nuToH 07.08.2014 13:41

Здравствуйте. Возможно, вам поможет:
Код AS3:

//Translation, Rotation, Scale
public function trs( tx:Number, ty:Number, rotation:Number, xScale:Number, yScale:Number ):Matrix3D {
 
var data:Vector.<Number> = new <Number>[1, 0, 0, 00, 1, 0, 00, 0, 1, 00, 0, 0, 1];
 
var sin:Number = Math.sin( rotation );
var cos:Number = Math.cos( rotation );
data[0]cos * xScale;
data[1]sin * xScale;
data[4] = -sin * yScale;
data[5]cos * yScale;
data[12] = tx;
data[13] = ty;
 
 
var matrix:Matrix3D = new Matrix3D();
matrix.copyRawDataFrom(data);
return matrix;
 
}

а вообще логичнее использовать матрицу 3х3 для 2D.

Dron1564 07.08.2014 13:50

К сожалению результат, идентичен моему, на картинке с надписью Stage3D.

nuToH 07.08.2014 13:54

покажите perspective projection matrix ? (матрицу умножаемую на model view matrix)

Dron1564 07.08.2014 14:00

Цитата:

perspective projection matrix
Не используется ( не получается настроить ), может в этом и причина?
Не могли бы вы, показать пример того как надо использовать, или где можно найти детальную информацию об этом классе?

nuToH 07.08.2014 14:24

Код AS3:

var perspectiveProjectionMatrix:Matrix3D = new Matrix3D();
var scaleX:Number = 2.0 / WIDTH; //super.stage.stageWidth
var scaleY:Number = -2.0 / HEIGHT; //super.stage.stageHeight
 
perspectiveProjectionMatrix.copyRawDataFrom(
        new <Number>[
        scaleX, 0.0, 0.0, 0.0,
        0.0, scaleY, 0.0, 0.0,
        0.0, 0.0, -1.0, 0.0,
        -1.0, 1.0, 0.0, 1.0
        ]
);

переводит в 2D screen space

Добавлено через 2 минуты
для получения итоговой координаты вертекса надо perspectiveProjectionMatrix * modelViewMatrix * vertexCoord

Dron1564 07.08.2014 14:51

Код AS3:

 
        var perspectiveProjectionMatrix:Matrix3D = new Matrix3D();
        var scaleX:Number = 2.0 / _stage.stageWidth;  // 2.0 / 500
        var scaleY:Number = -2.0 / _stage.stageHeight; // -2.0 / 375
        perspectiveProjectionMatrix.copyRawDataFrom(
                new <Number>[
                    scaleX, 0.0, 0.0, 0.0,
                    0.0, scaleY, 0.0, 0.0,
                    0.0, 0.0, -1.0, 0.0,
                    -1.0, 1.0, 0.0, 1.0
                ]
        );
        var modelViewMatrix:Matrix3D = trs(0,0,-45*Math.PI/180, 0.05, 0.13 ); //( "trs" - функция, выше в комментариях )
        var resultMatrix:Matrix3D = new Matrix3D();
        //resultMatrix.append(perspectiveProjectionMatrix);
        resultMatrix.append(modelViewMatrix);
        _context.setProgramConstantsFromMatrix(Context3DProgramType.VERTEX, 0,resultMatrix , true);

Результат как на картинке


Код AS3:

 
        var perspectiveProjectionMatrix:Matrix3D = new Matrix3D();
        var scaleX:Number = 2.0 / _stage.stageWidth;  // 2.0 / 500
        var scaleY:Number = -2.0 / _stage.stageHeight; // -2.0 / 375
        perspectiveProjectionMatrix.copyRawDataFrom(
                new <Number>[
                    scaleX, 0.0, 0.0, 0.0,
                    0.0, scaleY, 0.0, 0.0,
                    0.0, 0.0, -1.0, 0.0,
                    -1.0, 1.0, 0.0, 1.0
                ]
        );
        var modelViewMatrix:Matrix3D = trs(0,0,-45*Math.PI/180, 0.05, 0.13 ); //( "trs" - функция, выше в комментариях )
        var resultMatrix:Matrix3D = new Matrix3D();
        resultMatrix.append(perspectiveProjectionMatrix);
        resultMatrix.append(modelViewMatrix);
        _context.setProgramConstantsFromMatrix(Context3DProgramType.VERTEX, 0,resultMatrix , true);

В результате, экранного объекта не видно ( судя по всему находится, где-то за stage3D )

nuToH 07.08.2014 15:02

2D screen space координатная система вверху слева 0 0. внизу справа +stageWidht, +stageHeight
соотв. для того, чтоб обьект был в центре:
и соотв scale (я не знаю, что у вас за меш, но предполагаю, что квад 1на1)
Код AS3:

var modelViewMatrix:Matrix3D = trs(stage.stageWidth/2,stage.stageHeight/2, -45*Math.PI/180, 200, 200 );
var resultMatrix:Matrix3D = new Matrix3D();
 
resultMatrix.prepend(perspectiveProjectionMatrix);//или copyFrom. без разницы
resultMatrix.prepend(modelViewMatrix);


Dron1564 07.08.2014 15:17

Wow! Огромное спасибо!
Немного не правильно поворачивается, но с этим уже разберусь быстро. :)

Код AS3:

var perspectiveProjectionMatrix:Matrix3D = new Matrix3D();
        var scaleX:Number = 2.0 / _stage.stageWidth;  // 2.0 / 500
        var scaleY:Number = -2.0 / _stage.stageHeight; // -2.0 / 375
        perspectiveProjectionMatrix.copyRawDataFrom(
                new <Number>[
                    scaleX, 0.0, 0.0, 0.0,
                    0.0, scaleY, 0.0, 0.0,
                    0.0, 0.0, -1.0, 0.0,
                    -1.0, 1.0, 0.0, 1.0
                ]
        );
        var modelViewMatrix:Matrix3D = trs(stage.stageWidth/2,stage.stageHeight/2, -_rotation*Math.PI/180, _width*_globalScaleX/2, _height*_globalScaleY/2 );
        var resultMatrix:Matrix3D = new Matrix3D();
        resultMatrix.prepend(perspectiveProjectionMatrix);
        resultMatrix.prepend(modelViewMatrix);
        _context.setProgramConstantsFromMatrix(Context3DProgramType.VERTEX, 0,resultMatrix , true);

Верхний элемент, это stage3D, нижний это Stage
https://dl.dropboxusercontent.com/u/...trix3dbug2.jpg
Как видно она зеркально относительно oX

nuToH - ты мой спаситель!

nuToH 07.08.2014 15:30

Покажите меш, вершины квада. И не понятно почему знак "-" вот тут "-_rotation*Math.PI/180".
Код AS3:

меш должен быть простым
var vertexData:Vector.<Number> = Vector.<Number>([
//      x, y, z, ... не знаю, что еще у вас на вершину идет
        0.0, 0.0, 0.0,  ...
        1.0, 0.0, 0.0,  ...
        0.0, 1.0, 0.0,  ...
        1.0, 1.0, 0.0,  ..
]);
//index 0, 1, 2, 3, 2, 1



Часовой пояс GMT +4, время: 04:02.

Copyright © 1999-2008 Flasher.ru. All rights reserved.
Работает на vBulletin®. Copyright ©2000 - 2024, Jelsoft Enterprises Ltd. Перевод: zCarot
Администрация сайта не несёт ответственности за любую предоставленную посетителями информацию. Подробнее см. Правила.