|
|
« Предыдущая тема | Следующая тема » |
Опции темы | Опции просмотра |
|
|
|||||
Регистрация: May 2009
Сообщений: 34
|
Away + jiglib: как заставить куб упасть нужной стороной кверху?
Здравствуйте, уважаемые эксперты.
Возникла необходимость сделать небольшую анимацию с падающими кубами. Цель в том, чтобы некоторое множество кубиков начали падать с высоты, отображаясь изначально стороной А к камере, а затем после падения перевернулись вверх стороной Х. Я нашел реализацию, близкую к тому, что мне нужно. Для реализации полета кубов был использован Away3D + Jiglib. Немного разобравшись с кодом, я смог добиться некоторых успехов. Но возникает два вопроса, которые я не могу решить, т.к. не соображаю в трехмерной графике и тем более, движках. 1. Почему некоторые кубы падают сквозь плоскость? Как этого избежать? Рисовать несколько плоскостей друг под другом, "затормаживая" движение (обход бага)? При чем чем быстрее скорость и больше количество кубов, тем больше они проваливаются. 2. Как заставить кубики упасть нужной стороной вверх? Для этого я определил углы поворота для каждой из сторон (использую их при отправной точке полета). Думая над этой проблемой, я вижу два решения: I) Заставить кубики катиться, прорисовывая анимацию. Абсолютно не представляю, как это сделать. Мне даже не удалось просто насильно передвинуть кубик по какой-нибудь траектории. II) "Прикрепить" к нужной грани каждого куба (внутри него) "утяжелитель" - некий объект, масса которого создаст эффект неваляшки. Объект должен быть достаточно тяжелым и находиться с некоторым смещением от центра нужной грани, например так: ооооооо оооохоо ооооооо ооооооо То есть, у куба будет смещенный центр тяжести, который заставит его перевернуться в нужную сторону. При этом он, конечно, может "хромать" при анимации, но это не критично. Но опять же, я не представляю, как присоединить к существующему объекту ещё объект, чтобы они двигались неотрывно друг от друга. Я так понимаю, это нужно создавать другую модель, не куб. Вот код, на который я опираюсь (используется слегка устаревший away3d для совместимости с jiglib): 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(); Заранее благодарю откликнувшихся за помощь. |
|
|||||
Регистрация: May 2009
Сообщений: 34
|
Таакс, кажется мне удалось связать два куба вместе. Сейчас попробую к каждому из кубов прилепить на какую-нибудь грань другой маленький и тяжелый объект... Посмотрим, чего из этого получится...
UPD: Нащупал два варианта связки объектов. 1. С помощью JConstraintPoint. 2. С помощью HingeJoint. В обоих случаях добиться вменяемого результата не удаётся, т.к. они связываются не жестко и двигаются как на резинке. Секрет знает Limeflash в теме, но пока что этот полезный человек прячется от широкой общественности Последний раз редактировалось KIVagant; 17.05.2010 в 21:33. |
|
|||||
Регистрация: May 2009
Сообщений: 34
|
Alex Lexcuk, близко к теме, но это не совсем то, о чем я говорил или я просто не вижу в приложенном файле необходимой реализации.
Если я не прав - поправьте меня. Насколько я вижу, это лишь анимация — то есть куб всегда летит строго по одной и той же траектории? Меня интересует вариант, который во вложении к теме - то есть кубы падают всегда по-разному. Но останавливаться должны одной стороной вверх. Добавлено через 9 минут Я нашел примеры использования Papervision плюс JigLib. Там есть пример «Interactive boxes». В этом примере падает несколько кубов на плоскость. Отдельный куб можно захватить, включается привязка к мыши: mouseConstraint = new MouseConstraint(event.displayObject3D, new Number3D(0, 0, 1), camera, viewport); Как это повторить, но вместо мыши кодом привязать какой-нибудь другой объект, чтобы он тянул куб вниз? Последний раз редактировалось KIVagant; 19.05.2010 в 03:25. |
|
|||||
Цитата:
естественно кадров за 300 они упадут, по ходу падения заносим матрицы объектов (кубов) в архив. Так заранее будет известно какой гранью упал куб на плоскость, Нетрудно догадаться что повернув куб на 90 градусов по пределенным осям он ляжет заранее нужной гранью. Теперь включаем кнопку "плай" и проигрывается эта просщитанная анимация. ЗЫ: я на жиглибе гочку делал, жаль что она никого не проперла.
__________________
Гоночка |
Часовой пояс GMT +4, время: 18:00. |
|
« Предыдущая тема | Следующая тема » |
Теги |
3d , Away3D , jiqlib , куб , полёт |
|
|