![]() |
|
||||||||||
|
|||||||
|
|
« Предыдущая тема | Следующая тема » |
| Опции темы | Опции просмотра |
|
![]() |
![]() |
|
|||||
|
Регистрация: Oct 2008
Сообщений: 6
|
Я не сильно разбираюсь в 3D, скажу сразу. Поэтому вопрос может и глупый
![]() Есть такой вот кубик: [IMG]http://i.***********/i3/40/20/5afdd882179a970724ee9bf0a00e.jpeg[/IMG] Нужно сделать так, чтобы при нажатии на кнопки Вверх и Вниз кубик вращался по оси X на 90 градусов, а при нажатии кнопок Влево и Вправо - кубик вращался по оси Y на 90 градусов при нажатии Влево (либо на -90 при нажатии Вправо). Т.е. вращение всегда происходит только по двум осям относительно наблюдателя. Проблема: если кубик находится в исходном положении (0 градусов вращение по Х и 0 по Y), то по оси Х все отлично крутится. По оси Y тоже все отлично крутится, если не трогать вращение по оси Y. Но стоит например повернуть кубик по Y на 90 градусов, и кубик крутится по оси X, но уже как бы в другой плоскости. Т.е. относительно наблюдателя, вращение происходит уже не по оси Х. Более того, если проделать тоже самое (повернуть кубик по Y на 90 градусов из исходной позиции) то вращение по Z происходит в той же плоскости, что и вращение по X при повороте кубика на 90 по Y... Что я делаю не так и как его надо правильно крутить...? Последний раз редактировалось homersib; 20.03.2009 в 00:44. |
|
|||||
|
Регистрация: Oct 2008
Сообщений: 6
|
Кубик! Я ведь написал...
package { import flash.display.Sprite; import flash.ui.Keyboard; import flash.events.KeyboardEvent; import flash.events.Event; import org.papervision3d.scenes.*; import org.papervision3d.cameras.*; import org.papervision3d.objects.*; import org.papervision3d.objects.primitives.*; import org.papervision3d.materials.*; import org.papervision3d.materials.utils.*; import org.papervision3d.render.*; import org.papervision3d.view.*; import caurina.transitions.Tweener; public class Cube extends Sprite { // ---------------------------------------------------------------------------- // PUBLIC STATIC CONSTANTS // ---------------------------------------------------------------------------- public static const VERSION:String = "1.0"; // ---------------------------------------------------------------------------- // CLASS PROPERTIES // ---------------------------------------------------------------------------- private var _viewport:Viewport3D; private var _renderer:BasicRenderEngine; private var _scene:Scene3D; private var _camera:Camera3D; private var _cube:Cube; private var _animationInProgress:Boolean = false; // ---------------------------------------------------------------------------- // GETTERS AND SETTERS // ---------------------------------------------------------------------------- // ---------------------------------------------------------------------------- // CONSTRUCTOR // ---------------------------------------------------------------------------- public function Cube() { stage.addEventListener(KeyboardEvent.KEY_UP, globalKeyBoardListener); stage.focus = stage; build3D(); trace(_cube.rotationX, _cube.rotationY, _cube.rotationZ); } // ---------------------------------------------------------------------------- // PRIVATE METHODS // ---------------------------------------------------------------------------- private function build3D():void { _viewport = new Viewport3D(0, 0, true, true); _viewport.buttonMode = true; addChild(_viewport); _renderer = new BasicRenderEngine(); _scene = new Scene3D(); var _materialList:MaterialsList = new MaterialsList(); _materialList.addMaterial(new ColorMaterial(0xFF0000, 1, true), "front"); _materialList.addMaterial(new ColorMaterial(0x0066CC, 1, true), "back"); _materialList.addMaterial(new ColorMaterial(0x006600, 1, true), "left"); _materialList.addMaterial(new ColorMaterial(0xFFCC00, 1, true), "right"); _materialList.addMaterial(new ColorMaterial(0x000000, 1, true), "top"); _materialList.addMaterial(new ColorMaterial(0x333333, 1, true), "bottom"); _cube = new Cube(_materialList, 300, 300, 300, 1, 1, 1); _scene.addChild(_cube); _camera = new Camera3D(); _camera.zoom = 110; _camera.focus = 10; _camera.x = 400; _camera.y = 400; _camera.lookAt(_cube); this.addEventListener(Event.ENTER_FRAME, renderFrame); } private function animationComplete():void { _animationInProgress = false; _cube.rotationX %= 360; _cube.rotationY %= 360; _cube.rotationZ %= 360; trace(_cube.rotationX, _cube.rotationY, _cube.rotationZ); } private function rotateCube(_rotationX:int, _rotationY:int):void { if (!_animationInProgress) { _animationInProgress = true; var xRotation:int = _cube.rotationX + _rotationX; var yRotation:int = _cube.rotationY + _rotationY; Tweener.addTween(_cube, {rotationX:xRotation, rotationY:yRotation, time:0.3, transition:"linear", onComplete:animationComplete}); }; } private function globalKeyBoardListener(event:KeyboardEvent):void { switch (event.keyCode) { case Keyboard.UP: rotateCube(90, 0); break; case Keyboard.DOWN: rotateCube(-90, 0); break; case Keyboard.LEFT: rotateCube(0, 90); break; case Keyboard.RIGHT: rotateCube(0, -90); break; default: break; } } private function renderFrame(event:Event):void { _renderer.renderScene(_scene, _camera, _viewport); } // ---------------------------------------------------------------------------- // PUBLIC METHODS // ---------------------------------------------------------------------------- } } |
|
|||||
|
Вот делал подобное, только без паперВизион, если надо могу код для 10 плеера дать.
http://www.murmadillo.tut.su/m/TweenCube.swf |
|
|||||
|
Регистрация: Oct 2008
Сообщений: 6
|
Может я что-то не понимаю, и так задумано, но Ваш пример тоже глючно работает. Достаточно лишь немножко с ним поиграться.
Может кто-нибудь знает как нужно правильно крутить... |
|
|||||
|
Modus ponens
|
Не пробуя - скорее всего когда вы переназначаете rotationX и rotationY в сеттерах складываются матрицы, изза чего может получиться накапливающаяся ошибка. Что бы я сделал - в первую очередь выбросил твинер
(у вас и так есть renderScene за каким лешим туда еще 1 твин пихать?) и в renderScene пересчитывал был вращение - так хоть можно проконтролировать изменение матрицы на каждом шаге рендера. А так, как у вас это сделано - очень неудобно дебажить...
__________________
Hell is the possibility of sanity |
|
|||||
|
О!!! wvxvw прямую наводку дал. При ротацииХ, затем ротацииУ ротацияЗ тоже меняется не в лучшую сторону, при кручении при помощи матриц получается немного лучше контролировать процесс.
http://www.murmadillo.tut.su/m/TweenCube.swf Теперь действительно крутится в лево в право вверх и вниз. (Под 10 без твинеров и паперВизионов) однако папарВизион, как это не парадоксально меньше нагружает процессор при отрисовке (типа русует только то, что надо), чем родные 10 функции (Рисуем все), но на кубике этого не очень заметно. |
|
|||||
|
Регистрация: Oct 2008
Сообщений: 6
|
ну wvxvw как бы всегда радует своими ответами )
а что там про матрицы и кручения? поделитесь шаманским способом! |
|
|||||
package
{
import flash.display.*;
import flash.events.*;
import flash.geom.*;
import __AS3__.vec.*;
import fl.transitions.*; import fl.transitions.easing.*;//TWEEN
import fl.controls.*;
/**
* ...
* @author http://www.murmadillo.tut.su/
*/
public class DocCube extends Sprite
{
private var cube:Cube, i:int, btn:Button,
tween:Tween, o:Object, yxTr:Boolean, xCube:Sprite, curObjMatArr:Object,
sp:Sprite, spAr:Array, sXPos:Number, sYPos:Number, mat:Matrix3D, angArr:Array,
angTester:Array;
public function DocCube() {
angArr = [0, 90, 180, 270, 360, -360, -270, -180, -90];
angTester = [];
stage.scaleMode = StageScaleMode.NO_SCALE;
stage.align = StageAlign.TOP_LEFT;
yxTr = false;
curObjMatArr = new Object;
addChild(xCube = new Sprite);
xCube.x = 400;
xCube.y = 300;
xCube.z = 0;
xCube.addChild(cube = new Cube);
cube.x = 0;
cube.y = 0;
cube.z = 0;
child3DSort(cube, this);
addChild(btn = new Button);
btn.label = "влево";
btn.addEventListener(MouseEvent.CLICK, buttonClick);
addChild(btn = new Button);
btn.label = "вправо";
btn.addEventListener(MouseEvent.CLICK, buttonClick);
btn.x = 100;
addChild(btn = new Button);
btn.addEventListener(MouseEvent.CLICK, buttonClick);
btn.label = "вверх";
btn.x = 200;
addChild(btn = new Button);
btn.label = "вниз";
btn.addEventListener(MouseEvent.CLICK, buttonClick);
btn.x = 300;
o = new Object();
addChild(btn = new Button);
btn.addEventListener(MouseEvent.CLICK, buttonClick);
btn.label = "назад";
btn.x = 400;
addChild(btn = new Button);
btn.label = "вперед";
btn.addEventListener(MouseEvent.CLICK, buttonClick);
btn.x = 500;
o = new Object();
o.i = 0;
o.type = 'rotationX';
o.plus = false;
o.rotX = o.rotY = o.xCor = o.yCor = o.finX = o.finY = o.finZ = o.finZ = o.zCor = o.zCor = 0;
tween = new Tween(o, "i", Regular.easeOut, 0, 100, 2, true);
tween.addEventListener(TweenEvent.MOTION_CHANGE, tweenChange);
tween.addEventListener(TweenEvent.MOTION_FINISH, tweenFin);
tween.stop();
}
private function buttonClick(e:MouseEvent):void {
var button:Button = e.target as Button;//Object Button
trace(button.label);
if (button.label == "влево" || button.label == "вправо") o.type = 'rotationY';
if (button.label == "вверх" || button.label == "вниз") o.type = 'rotationX';
if (button.label == "назад" || button.label == "вперед") o.type = 'rotationZ';
if (button.label == "вверх" || button.label == "вправо"|| button.label == "вперед") o.plus = false;
if (button.label == "влево" || button.label == "вниз"|| button.label == "назад") o.plus = true;
o.rotX = cube.rotationX;
o.rotY = cube.rotationY;
if (o.type == 'rotationX') {
if (o.plus == true) o.xCor = 90/100;
if (o.plus == false) o.xCor = -90/100;
o.finY = 90 * Math.floor(o.rotY / 90);
}
if (o.type == 'rotationY') {
if (o.plus == true) o.yCor = 90/100;
if (o.plus == false) o.yCor = -90/100;
o.finX = 90 * Math.floor(o.rotX / 90);
}
//o.xCor = 90/100;
trace(o.plus);
//cube.rotationX = cu
//cube.transform.matrix3D.appendRotation(o.xCor * o.i,Vector3D.X_AXIS);
mat = cube.transform.matrix3D.clone();
tween.start();
}
private function tweenChange(evt:TweenEvent):void {
//mat = cube.transform.matrix3D.clone();
cube.transform.matrix3D = mat.clone();
if (o.type == 'rotationX') cube.transform.matrix3D.appendRotation(o.xCor * o.i,Vector3D.X_AXIS);
if (o.type == 'rotationY') cube.transform.matrix3D.appendRotation(o.yCor * o.i, Vector3D.Y_AXIS);
child3DSort(cube, this);
}
private function tweenFin(evt:TweenEvent):void {
var len:int = angArr.length;
var p:Point = new Point;
var p1:Point = new Point;
//angTester
//коррекции
for (i = 0; i < len; i++) {
p.x = cube.rotationX;
p1.x = angArr[i];
angTester[i] = [Point.distance(p,p1), i];
}
angTester.sort(byDist);
//trace(angTester);
cube.rotationX = angArr[angTester[len - 1][1]];
for (i = 0; i < len; i++) {
p.x = cube.rotationY;
p1.x = angArr[i];
angTester[i] = [Point.distance(p,p1), i];
}
angTester.sort(byDist);
cube.rotationY = angArr[angTester[len - 1][1]];
for (i = 0; i < len; i++) {
p.x = cube.rotationZ;
p1.x = angArr[i];
angTester[i] = [Point.distance(p,p1), i];
}
angTester.sort(byDist);
cube.rotationZ = angArr[angTester[len - 1][1]];
//trace(angTester);
trace("Финал анимации " + cube.rotationX + ' ' + cube.rotationY);
child3DSort(cube, this);
}
//_general спрайт с гранями; _doc - документ класс
private function child3DSort(_general:Sprite, _doc:Sprite):void {
var len:int = _general.numChildren,dist:Number,chSp:Sprite,
distArray:Array = [],spArr:Array = [];
for (i = 0; i < len; i++) {
spArr[i] = chSp = _general.getChildAt(i) as Sprite;
dist = chSp.transform.getRelativeMatrix3D(_doc).position.z;
distArray[i] = [dist, i];
}
distArray.sort(byDist);
for (i = 0; i < len; i++) {//сортировка граней
_general.setChildIndex(spArr[distArray[i][1]],i);
}
}
private function byDist(v:Array,w:Array):Number {
if (v[0]>w[0]){return -1;} else if (v[0]<w[0]){return 1;} else {return 0;}
}
}
}
import flash.display.*;import flash.geom.*;import __AS3__.vec.*;
class Cube extends Sprite
{
private var cbSize:Number = 4;
private var sp:Sprite,
i:int,
pVec:Vector3D,
mat3D:Matrix3D;
public function Cube(_colorArr:Array=null, _cbSize:Number = 150)
{
if (_colorArr == null) _colorArr = [0xFF0000, 0x0066CC, 0x006600, 0xFFCC00, 0x000000, 0x333333];
cbSize = _cbSize;
pVec = new Vector3D();
mat3D = new Matrix3D();
for (i = 0; i < 6; i++) {
addChild(sp = new Sprite());
if (i<4){
pVec.x = pVec.y = 0;
pVec.z = -cbSize;
mat3D.appendRotation(90, Vector3D.Y_AXIS);
}else {
pVec.x = 0;
pVec.y = 0;
if (i == 5) pVec.z = cbSize;
if (i==6) pVec.z = -cbSize;
mat3D = new Matrix3D();
mat3D.appendRotation(90, Vector3D.X_AXIS);
}
pVec = mat3D.transformVector(pVec);
sp.transform.matrix3D = mat3D.clone();
sp.x = pVec.x;
sp.y = pVec.y;
sp.z = pVec.z;
sp.addChild(sp = new Sprite());
//sp.graphics.lineStyle(1,0xfffff);
sp.graphics.beginFill(_colorArr[i],0.9);//залить цветом
sp.graphics.drawRect( 0, 0, cbSize*2, cbSize*2);
sp.x = -cbSize;
sp.y = -cbSize;
}
}
}
|
|
|||||
package { import flash.display.Sprite; import org.papervision3d.core.math.Matrix3D; import flash.ui.Keyboard; import flash.events.KeyboardEvent; import flash.events.Event; import org.papervision3d.scenes.*; import org.papervision3d.cameras.*; import org.papervision3d.objects.*; import org.papervision3d.objects.primitives.*; import org.papervision3d.materials.*; import org.papervision3d.materials.utils.*; import org.papervision3d.render.*; import org.papervision3d.view.*; import caurina.transitions.Tweener; public class MyCube extends Sprite { // ---------------------------------------------------------------------------- // PUBLIC STATIC CONSTANTS // ---------------------------------------------------------------------------- public static const VERSION:String = "1.0"; // ---------------------------------------------------------------------------- // CLASS PROPERTIES // ---------------------------------------------------------------------------- private var _viewport:Viewport3D; private var _renderer:BasicRenderEngine; private var _scene:Scene3D; private var _camera:Camera3D; private var _cube:Cube; private var _curX:Number = 0; private var _curY:Number = 0; private var _targX:Number = 0; private var _targY:Number = 0; public function MyCube() { addEventListener(Event.ADDED_TO_STAGE, addedToStageHandler); build3D(); trace(_cube.rotationX, _cube.rotationY, _cube.rotationZ); } private function addedToStageHandler(evnt:Event):void { removeEventListener(Event.ADDED_TO_STAGE, addedToStageHandler); stage.addEventListener(KeyboardEvent.KEY_UP, globalKeyBoardListener); stage.focus = stage; } // ---------------------------------------------------------------------------- // PRIVATE METHODS // ---------------------------------------------------------------------------- private function build3D():void { _viewport = new Viewport3D(0, 0, true, true); _viewport.buttonMode = true; addChild(_viewport); _renderer = new BasicRenderEngine(); _scene = new Scene3D(); var _materialList:MaterialsList = new MaterialsList(); _materialList.addMaterial(new ColorMaterial(0xFF0000, 1, true), "front"); _materialList.addMaterial(new ColorMaterial(0x0066CC, 1, true), "back"); _materialList.addMaterial(new ColorMaterial(0x006600, 1, true), "left"); _materialList.addMaterial(new ColorMaterial(0xFFCC00, 1, true), "right"); _materialList.addMaterial(new ColorMaterial(0x000000, 1, true), "top"); _materialList.addMaterial(new ColorMaterial(0x333333, 1, true), "bottom"); _cube = new Cube(_materialList, 300, 300, 300, 1, 1, 1); _scene.addChild(_cube); _camera = new Camera3D(); _camera.zoom = 110; _camera.focus = 10; _camera.x = 400; _camera.y = 400; _camera.lookAt(_cube); this.addEventListener(Event.ENTER_FRAME, renderFrame); } private function globalKeyBoardListener(event:KeyboardEvent):void { switch (event.keyCode) { case Keyboard.UP: _targX = _curX + 90; break; case Keyboard.DOWN: _targX = _curX - 90; break; case Keyboard.LEFT: _targY = _curY + 90; break; case Keyboard.RIGHT: _targY = _curY - 90; break; default: break; } } private function renderFrame(event:Event):void { var dx:Number = (_targX - _curX) / 20; var dy:Number = (_targY - _curY) / 20; _curX += dx; _curY += dy; var mX:Matrix3D = Matrix3D.rotationX(Math.PI / 180 * dx); var mY:Matrix3D = Matrix3D.rotationY(Math.PI / 180 * dy); _cube.transformVertices(mX); _cube.transformVertices(mY); _renderer.renderScene(_scene, _camera, _viewport); } } } |
![]() |
![]() |
Часовой пояс GMT +4, время: 02:43. |
|
|
« Предыдущая тема | Следующая тема » |
|
|