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

Вернуться   Форум Flasher.ru > Flash > API приложений и сред

Версия для печати  Отправить по электронной почте    « Предыдущая тема | Следующая тема »  
Опции темы Опции просмотра
 
Создать новую тему Ответ
Старый 17.05.2010, 15:27
KIVagant вне форума Посмотреть профиль Отправить личное сообщение для KIVagant Найти все сообщения от KIVagant
  № 1  
Ответить с цитированием
KIVagant

Регистрация: May 2009
Сообщений: 34
Question Away + jiglib: как заставить куб упасть нужной стороной кверху?

Здравствуйте, уважаемые эксперты.

Возникла необходимость сделать небольшую анимацию с падающими кубами. Цель в том, чтобы некоторое множество кубиков начали падать с высоты, отображаясь изначально стороной А к камере, а затем после падения перевернулись вверх стороной Х.

Я нашел реализацию, близкую к тому, что мне нужно. Для реализации полета кубов был использован Away3D + Jiglib. Немного разобравшись с кодом, я смог добиться некоторых успехов. Но возникает два вопроса, которые я не могу решить, т.к. не соображаю в трехмерной графике и тем более, движках.

1. Почему некоторые кубы падают сквозь плоскость? Как этого избежать? Рисовать несколько плоскостей друг под другом, "затормаживая" движение (обход бага)? При чем чем быстрее скорость и больше количество кубов, тем больше они проваливаются.

2. Как заставить кубики упасть нужной стороной вверх? Для этого я определил углы поворота для каждой из сторон (использую их при отправной точке полета). Думая над этой проблемой, я вижу два решения:
I) Заставить кубики катиться, прорисовывая анимацию. Абсолютно не представляю, как это сделать. Мне даже не удалось просто насильно передвинуть кубик по какой-нибудь траектории.
II) "Прикрепить" к нужной грани каждого куба (внутри него) "утяжелитель" - некий объект, масса которого создаст эффект неваляшки. Объект должен быть достаточно тяжелым и находиться с некоторым смещением от центра нужной грани, например так:
ооооооо
оооохоо
ооооооо
ооооооо
То есть, у куба будет смещенный центр тяжести, который заставит его перевернуться в нужную сторону. При этом он, конечно, может "хромать" при анимации, но это не критично.
Но опять же, я не представляю, как присоединить к существующему объекту ещё объект, чтобы они двигались неотрывно друг от друга. Я так понимаю, это нужно создавать другую модель, не куб.

Вот код, на который я опираюсь (используется слегка устаревший away3d для совместимости с jiglib):
Код AS3:
import away3d.cameras.*;
import away3d.containers.*;
import away3d.materials.*;
import away3d.primitives.*
import away3d.lights.DirectionalLight3D
 
import jiglib.physics.RigidBody;
import jiglib.plugin.away3d.Away3DPhysics;
import jiglib.plugin.away3d.Away3dMesh;
import jiglib.math.JNumber3D
 
import flash.utils.*; // Временно
 
var scene:Scene3D;
var camera:HoverCamera3D;
var view:View3D;
var light:DirectionalLight3D;
var physics:Away3DPhysics;
var speed:Number = 8; // Скорость физического движка
 
var boxWidth:Number = 400; // Ширина коробочки по X
var boxHeight:Number = 65; // Глубина коробочки по Z
var boxDepth:Number = 400; // Длина коробочки по Y
var boxThickness:Number = 0.5; // Ширина границ
 
var cubeTextures:Array = [ new WireColorMaterial(0xFF4444), //Куб
						   new WireColorMaterial(0x44FF44),
						   new WireColorMaterial(0x4444FF),
						   new WireColorMaterial(0xFFFF44),
						   new WireColorMaterial(0x44FFFF),
						   new WireColorMaterial(0xFF44FF) ]
var wallTexture:WireColorMaterial = new WireColorMaterial(0xFFFFFF); // Текстура стенок
var groundTexture:WireColorMaterial = new WireColorMaterial(0xFFFFFF); // Фон доски
var backgroundTexture:WireColorMaterial = new WireColorMaterial(0x000000); // Задний план
 
var cubeScale:Number = 15; // Размер кубиков
var cubes:Array = new Array()
var cubeMaxLinVel = 30; // Максимальная скорость линейного движения (не уверен)
var cubeMaxRotVel = 20; // Максимальная скорость вращения объекта (не уверен)
var flyHeight:Number = cubeScale*5+200; // Регулятор высоты полета
var cubeMass:Number = 10; // Масса кубика, влияет на скорость полета
// Стороны
var cubeNumbersRotation:Array = new Array();
cubeNumbersRotation[1] = new Array(0, 0, 90); //сторона 1
cubeNumbersRotation[2] = new Array(90, 90, 0); //сторона 2
cubeNumbersRotation[3] = new Array(270, 0, 270); //сторона 3
cubeNumbersRotation[4] = new Array(90, 0, 0);//сторона 4
cubeNumbersRotation[5] = new Array(0, 0, 0); //сторона 5
cubeNumbersRotation[6] = new Array(0, 0, 180); //сторона 6 (180, 0, 0)
var startSide = 1; // Какой стороной вверх начинать полет
var stopSide = 5; // Какой стороной вверх приземлиться (<<<<<<<<<<<<<<<<< как?)
 
function initAway3D():void {
	scene = new Scene3D();
 
	camera = new HoverCamera3D();
	camera.distance = 400; // Дистанция к объекту внимания
	camera.moveCamera(); // Надо подвинуть камеру после установки дистанции
	// Освещение
	light = new DirectionalLight3D({color:0xAAFFAA, ambient:0.25, diffuse:0.75, specular:0.9})
	scene.addChild(light)
 
	view=new View3D({scene:scene,camera:camera});
	view.x=stage.stageWidth/2; // Координаты расположения картинки
	view.y=stage.stageHeight/2; // Координаты расположения картинки
	addChild(view);
 
	physics = new Away3DPhysics(view,speed); // Старт физического движка
}
 
function createWalls():void { // Ограничиваем пространства для падения кубов, чтобы не выпадали
	//стенка
	var left:RigidBody = physics.createCube({width:boxThickness, height:boxHeight, depth:boxDepth+0.5});
	left.movable = false;
	left.x = -(boxWidth+boxThickness)/2
	Away3dMesh(left.skin).mesh.material = wallTexture
	//стенка
	var right:RigidBody = physics.createCube({width:boxThickness, height:boxHeight, depth:boxDepth+0.5});
	right.movable = false;
	right.x = (boxWidth+boxThickness)/2
	Away3dMesh(right.skin).mesh.material = wallTexture
	//стенка
	var front:RigidBody = physics.createCube({width:boxWidth, height:boxHeight, depth:boxThickness});
	front.movable = false;
	front.z =  (boxDepth+boxThickness)/2
	Away3dMesh(front.skin).mesh.material = wallTexture
	//стенка
	var back:RigidBody = physics.createCube({width:boxWidth, height:boxHeight, depth:boxThickness});
	back.movable = false;
	back.z = -(boxDepth+boxThickness)/2
	Away3dMesh(back.skin).mesh.material = wallTexture
	//пол
	var ground:RigidBody = physics.createCube({width:boxWidth, height:boxThickness, depth:boxDepth, segmentsW:2, segmentsH:2});
	ground.movable = false;
	ground.y = -(boxHeight+boxThickness)/2
	Away3dMesh(ground.skin).mesh.material = groundTexture
	Away3dMesh(ground.skin).mesh.pushback = true
}
function createBackground():void {
	var ground:RigidBody = physics.createCube({width:960, height:1, depth:960, segmentsW:2, segmentsH:2});
	ground.movable = false;
	ground.y = -(boxHeight+boxThickness)/2 - 10; // На 1 меньше, чем пол у пространства
	Away3dMesh(ground.skin).mesh.material = backgroundTexture;
	Away3dMesh(ground.skin).mesh.pushback = true; // отталкивать кубики
}
function createCube():void {
	var cube:RigidBody = physics.createCube({width:cubeScale, height:cubeScale, depth:cubeScale});
	cube.y=500;
	cube.movable=false;
	cube.mass = cubeMass;
	cube.maxRotVelocities = cubeMaxRotVel;
	cube.maxLinVelocities = cubeMaxLinVel;
	Cube(Away3dMesh(cube.skin).mesh).cubeMaterials.left = cubeTextures[0]
	Cube(Away3dMesh(cube.skin).mesh).cubeMaterials.right = cubeTextures[1]
	Cube(Away3dMesh(cube.skin).mesh).cubeMaterials.front = cubeTextures[2]
	Cube(Away3dMesh(cube.skin).mesh).cubeMaterials.back = cubeTextures[3]
	Cube(Away3dMesh(cube.skin).mesh).cubeMaterials.top = cubeTextures[4]
	Cube(Away3dMesh(cube.skin).mesh).cubeMaterials.bottom = cubeTextures[5]
	cubes.push(cube);
}
function resetAllCubesE(e:Event):void
{
	resetAllCubes();
}
function resetAllCubes():void {
	for(var i:int = 0; i<cubes.length; i++) {
		cubes[i].movable=true; // Разрешаем движение
		cubes[i].moveTo( new JNumber3D( i*(Math.random()*15)*(Math.random()*-1), flyHeight + i*(cubeScale*3) , i*(Math.random()*15)*(Math.random()*-1) ) ) // перемещаем по X, Z (высота полета) и Y
		cubes[i].rotationX = cubeNumbersRotation[startSide][0];
		cubes[i].rotationY = cubeNumbersRotation[startSide][1];
		cubes[i].rotationZ = cubeNumbersRotation[startSide][2];
	}
}
function initListeners():void {
	stage.addEventListener(Event.ENTER_FRAME, render);
	stage.addEventListener(MouseEvent.MOUSE_DOWN,resetAllCubesE)
}
function render( e:Event ):void {
	view.render();
	camera.targetpanangle = stage.mouseX/stage.stageWidth*360
	camera.targettiltangle = stage.mouseY/stage.stageHeight*30
	//camera.hover(); // Активация движения камеры мышью
	camera.x = 200;
	camera.z = 300;
	camera.y = 360
	physics.step();
 
	light.x = camera.x
	light.y = camera.y
	light.z = camera.z
}
initAway3D();
createBackground();
createWalls();
createCube();
createCube();
createCube();
createCube();
createCube();
createCube();
createCube();
initListeners();
Во вложении - fla-файл.

Заранее благодарю откликнувшихся за помощь.
Вложения
Тип файла: rar 3D Fly Cubes.rar (317.9 Кб, 116 просмотров)

Старый 17.05.2010, 19:20
KIVagant вне форума Посмотреть профиль Отправить личное сообщение для KIVagant Найти все сообщения от KIVagant
  № 2  
Ответить с цитированием
KIVagant

Регистрация: May 2009
Сообщений: 34
Таакс, кажется мне удалось связать два куба вместе. Сейчас попробую к каждому из кубов прилепить на какую-нибудь грань другой маленький и тяжелый объект... Посмотрим, чего из этого получится...

UPD: Нащупал два варианта связки объектов.
1. С помощью JConstraintPoint.
2. С помощью HingeJoint.

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


Последний раз редактировалось KIVagant; 17.05.2010 в 21:33.
Старый 19.05.2010, 02:56
Alex Lexcuk вне форума Посмотреть профиль Отправить личное сообщение для Alex Lexcuk Посетить домашнюю страницу Alex Lexcuk Найти все сообщения от Alex Lexcuk
  № 3  
Ответить с цитированием
Alex Lexcuk

блогер
Регистрация: Mar 2008
Адрес: Донецк_city
Сообщений: 1,094
Записей в блоге: 5
Ради прикола по тутору на своем же сайте сделал такуб анимашку с кубом, потратил минут 10 на втыкание в свой же контент, а пофиг чего анимировать кости персоонажа или кубы, один фиг работает.
ЗЫ: Blender рулит
Вложения
Тип файла: swf CubeGoBottom.swf (11.1 Кб, 387 просмотров)
__________________
Гоночка

Старый 19.05.2010, 03:15
KIVagant вне форума Посмотреть профиль Отправить личное сообщение для KIVagant Найти все сообщения от KIVagant
  № 4  
Ответить с цитированием
KIVagant

Регистрация: May 2009
Сообщений: 34
Alex Lexcuk, близко к теме, но это не совсем то, о чем я говорил или я просто не вижу в приложенном файле необходимой реализации.
Если я не прав - поправьте меня.

Насколько я вижу, это лишь анимация — то есть куб всегда летит строго по одной и той же траектории? Меня интересует вариант, который во вложении к теме - то есть кубы падают всегда по-разному. Но останавливаться должны одной стороной вверх.

Добавлено через 9 минут
Я нашел примеры использования Papervision плюс JigLib.
Там есть пример «Interactive boxes». В этом примере падает несколько кубов на плоскость. Отдельный куб можно захватить, включается привязка к мыши:
Код AS3:
mouseConstraint = new MouseConstraint(event.displayObject3D, new Number3D(0, 0, 1), camera, viewport);
Захватываем мышью куб за одну из граней, протаскиваем по плоскости и затем тянем вниз, прижимая его к "земле". Куб практически всегда ложиться одной и той же стороной вверх, так как мышь его сильно прижимает вниз.

Как это повторить, но вместо мыши кодом привязать какой-нибудь другой объект, чтобы он тянул куб вниз?


Последний раз редактировалось KIVagant; 19.05.2010 в 03:25.
Старый 22.05.2010, 21:00
Alex Lexcuk вне форума Посмотреть профиль Отправить личное сообщение для Alex Lexcuk Посетить домашнюю страницу Alex Lexcuk Найти все сообщения от Alex Lexcuk
  № 5  
Ответить с цитированием
Alex Lexcuk

блогер
Регистрация: Mar 2008
Адрес: Донецк_city
Сообщений: 1,094
Записей в блоге: 5
Цитата:
Сообщение от KIVagant Посмотреть сообщение
Захватываем мышью куб за одну из граней, протаскиваем по плоскости и затем тянем вниз, прижимая его к "земле". Куб практически всегда ложиться одной и той же стороной вверх, так как мышь его сильно прижимает вниз.

Как это повторить, но вместо мыши кодом привязать какой-нибудь другой объект, чтобы он тянул куб вниз?
Кубы простые геометрические тела и можно поступить так - кидаем кубы но в память, методом
Код AS3:
physic.engine.integrate(0.12);
естественно кадров за 300 они упадут, по ходу падения заносим матрицы объектов (кубов) в архив. Так заранее будет известно какой гранью упал куб на плоскость, Нетрудно догадаться что повернув куб на 90 градусов по пределенным осям он ляжет заранее нужной гранью. Теперь включаем кнопку "плай" и проигрывается эта просщитанная анимация.


ЗЫ: я на жиглибе гочку делал, жаль что она никого не проперла.
Вложения
Тип файла: swf CubeGoBottom.swf (56.8 Кб, 299 просмотров)
__________________
Гоночка

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

Теги
3d , Away3D , jiqlib , куб , полёт

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

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


 


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


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