Форум Flasher.ru
Ближайшие курсы в Школе RealTime
Список интенсивных курсов: [см.]  
  
Специальные предложения: [см.]  
  
 
Блоги Правила Справка Пользователи Календарь Сообщения за день
 

Вернуться   Форум Flasher.ru > Flash > ActionScript 3.0

Версия для печати  Отправить по электронной почте    « Предыдущая тема | Следующая тема »  
Опции темы Опции просмотра
 
Создать новую тему  
Старый 18.01.2010, 13:11
gr_crd вне форума Посмотреть профиль Отправить личное сообщение для gr_crd Посетить домашнюю страницу gr_crd Найти все сообщения от gr_crd
  № 1  
Ответить с цитированием
gr_crd
 
Аватар для gr_crd

Регистрация: Mar 2009
Адрес: Kazakhstan, Almaty
Сообщений: 121
Arrow 5 Вопросов по 3D-графике и AS3

Изменение оси вращения

Допустим есть объект, состоящий из 6-ти спрайтов, каждый из которых имеет св-ва x, y, z, rotationX, rotationY, rotationZ, таким образом из них составлен куб, как показано на рис. Все эти шесть сторон куба помещены в контейнер «cube» Этот куб вращаю вокруг оси Y X или Z так:

Код AS3:
cube.rotationX+=0.7;
Но при попытке повернуть куб например сначала по оси Z на 30 градусов, а потом каждый кадр вращать по оси Y, допустим на 1,0 получается совсем не то, что ожидалось, как я понял при вращении объекта его оси не вращаются и остаются на месте, и это правильно.
Но тогда возникает вопрос, а как вращать объект по другой оси, назовем ее «A», она отличается от осей Z X и У.
Пробовал вращать по одной оси быстрее, по другой медленнее:

Код AS3:
cube.rotationZ+=0.7;
cube.rotationX+=0.3;
Получается тоже нечто очень странное.

Вопрос 1: Как вращать объект по оси «A» ? см. рисунок.



Вращение через Matrix3D

Возьмем к примеру тот же самый cube из предыдущего вопроса.
Каждый кадр поворачиваю его с помощью Matrix3D:

Код AS3:
var matrixCube:Matrix3D = cube.transform.matrix3D;
matrixCube.appendRotation(0.7, Vector3D.Y_AXIS);
cube.transform.matrix3D = matrixCube;
Все понятно, кроме одного. Куб вращается не вокруг своей оси и не вокруг точки регистрации, а вокруг точки, которая находится далеко от куба, неизвестно где.

Вопрос 2: Что это за точка? Как изменить эту точку? Или я что-то делаю неправильно?

Z-сортировка между плоскостью и другой плоскостью большего размера

Происходит сортировка всех плоскостей по величине Z.
Вот функция, вызывается каждый кадр.

Код AS3:
function sortByZMatrix(c:DisplayObjectContainer):void {
	var sortArray:Array = new Array();
	var objectsCount:int = c.numChildren;
 
	for (var i:int = 0; i < objectsCount; i++){
		var currentFace:DisplayObject = c.getChildAt(i);
 
		var m:Matrix3D = currentFace.transform.matrix3D.clone();
		m.append(c.transform.matrix3D);
 
		sortArray[i] = { obj:currentFace, z:m.position.z };
	}
 
	sortArray.sortOn("z", Array.NUMERIC | Array.DESCENDING);
 
	for (i = 0; i < objectsCount; i++){
		c.setChildIndex(sortArray[i].obj, i);
	}
 
	sortArray = null;
}//sort
Все работает замечательно, без глюков.
Но только в том случае, если все плоскости одинакового размера и не пересекаются между собой.
Если же сделать одну большую плоскость, допустим это каменный пол комнаты, то не всегда получается нужный результат.
Например на этом рисунке координата Z плоскости находится от нас дальше в глубь, чем координаты плоскостей куба, обведенного красным цветом → childIndex плоскостей куба больше чем childIndex плоскости пола и все отображается нормально.



Но если повернуть контейнер, в котором размещены все объекты, то...
Координаты Z плоскостей куба стали дальше, чем Z плоскости пола → плоскость пола отображается поверх плоскостей куба. Все логично, НО. Куб есть, а его не видно.



Можно решить эту проблему, создав пол из кучи таких же маленьких плоскостей, и тогда все отображается нормально.
Но колисчество плоскостей значительно возрастает
(10 х 10 плиток пола = 100 плоскостей)
И все начинает жутко тормозить.

Вопрос 3: Можно ли организовать сортировку таким образом,
чтобы она корректно работала с разными размерами плоскостей и не возникало ситуаций, описанных выше?
Если можно, то как примерно она должна быть устроена?
Или же все-таки остается собирать из маленьких плоскостей?
Каков вообще правильный подход к решению таких задач?



Производительность

Делаю следующим образом:
Собираю из плоскостей трехмерные объекты путем размещения и поворота этих плоскостей.
Каждая плоскость — это Shape, создается следующей функцией:

Код AS3:
function createPlane(ox:Number = 0, oy:Number = 0, oz:Number = 0, rtx:Number = 0, rty:Number = 
 
0,rtz:Number=0,b:BitmapData=null,size:Number=0):void {
	stor = new Shape();
	stor.graphics.beginFill(0xFFFFFF);
	stor.graphics.beginBitmapFill(b);
	stor.graphics.lineStyle(1, 0x000000, 1.0);
	stor.graphics.drawTriangles(
Vector.<Number>([-50-size, -50-size, 50+size, -50-size, -50+size, 50+size, 50+size, 50+size]),
Vector.<int>([0, 1, 2, 1, 3, 2]))
stor.x = ox; stor.y = oy; stor.z = oz; 
stor.rotationX = rtx; stor.rotationY = rty; stor.rotationZ = rtz;
	cube.addChild(stor);
	stors.push(stor);
	stc++;
}
Такой функцией строится куб:

Код AS3:
function createBox(ox:Number = 0,oy:Number=0,oz:Number=0):void {
	createPlane(ox+0, oy+0, oz+-50, 0, 0, 0,textureBitmapData);
	createPlane(ox+0, oy+0, oz+50, 0, 0, 0,textureBitmapData);
	createPlane(ox+50, oy+0, oz+0, 0, 90, 0,textureBitmapData);
	createPlane(ox+-50, oy+0, oz+0, 0, 90, 0,textureBitmapData);
	createPlane(ox+0, oy+50, oz+0, 90, 0, 0,textureBitmapData);
	createPlane(ox+0, oy+-50, oz+0, 90, 0, 0,textureBitmapData);
}
Создаю 10 кубов. В итоге получается 60 плоскостей. При 31 кадр/сек
все работает нормально, без подвисаний.

Код AS3:
for (t = 0; t < 10;t++){
createBox(-500+Math.random()*1000,-500+Math.random()*1000,-500+Math.random()*1000);
}
Но если создать 100 кубиков — все начинает жутко тормозить.

Вопрос 4: Нужно ли создавать каждую плоскость как отдельный Shape?
Как вообще можно повысить скорость отрисовки всего этого?
Ясно, что-то я делаю неправильно, как будет сделать разумнее и оптимизировать хоть как-то все это?




Каков правильный подход

Все яснее становится, что используя готовые классы Shape или там Sprite и создавая трехмерность таким образом, как описано выше — неправильный путь.

Вопрос 5: Так каков же тогда правильный путь? Писать все 3D вручную?
Как вообще устроены простейшие 3D-движки на флеше?

И если уж все идет на то, что нужно писать все самому, какую литературу посоветуете?
Я уже нашел статьи, но хочется именно книгу, в которой бы описывалось программирование 3D-графики с азов.

Ну, конечно, кроме учебников по математике и геометрии

Создать новую тему   Часовой пояс GMT +4, время: 01:13.
Быстрый переход
  « Предыдущая тема | Следующая тема »  

Теги
3d , графика , движок , программирование , учебники

Ваши права в разделе
Вы не можете создавать новые темы
Вы не можете отвечать в темах
Вы не можете прикреплять вложения
Вы не можете редактировать свои сообщения

BB коды Вкл.
Смайлы Вкл.
[IMG] код Вкл.
HTML код Выкл.


 


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


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