Извините, ничего не найдено.

Не расстраивайся! Лучше выпей чайку!
Регистрация
Справка
Календарь

Вернуться   www.boolean.name > Программирование игр для компьютеров > Blitz3D > Полезные функции

Полезные функции Выкладываем полезные функции, чтоб не изобретать велосипед заново...

Ответ
 
Опции темы
Старый 15.05.2009, 07:46   #1
drwoland
AnyKey`щик
 
Регистрация: 15.05.2009
Сообщений: 3
Написано 0 полезных сообщений
(для 0 пользователей)
Сообщение синхронизация физики и анимации (newton)

Пользую newton для создания создания прототипа игрушки.
В процессе столкнулся с необходимостью подогнать физику под анимацию модели. Т.е. придать физическому телу (phBody) такие линейную и угловую скорость, что бы при следующем проходе phWorldStep() оно заняло то же положение, что и Entity, которому оно соответствует. В Ньютоне я подходящих инструментов не нашел. Пришлось писать самому. Все значения подгонял ручками на глазок, поэтому не везде работает гладко. Но если использовать предложенные значения, то результат получается достаточно точный. (у меня разница между координатами Entity и phBody при каждом проходе в среднем составляла 0,02 единицы)

Скажу большое спасибо тому, кто сумеет повысить точность и позволит использовать промежуточные значения шага phWorldStep, кроме указанных.

Function SyncBodyWithEntity(Body%,Entity%,phTiming#)
;Перемещает Физ.Тело в положение, которое занимает Entity 
;Криво работает со значениями шага phWorldStep(phTiming#) меньше 0.1
;Точнее всего работает со значениями 0.01, 0.05, 0.1 и выше. 
;При значении Меньше чем 0.01 - безбожно глючит

a#=1/phTiming ;обратная величина от шага phWorldStep()

;рассчитываем угловую скорость Entity исходя из разницы углов тела и Entity
Local deltaAngX=EntityPitch(Entity,1)- phBodyGetPitch(Body)
Local deltaAngY=EntityYaw(Entity,1)- phBodyGetYaw(Body)
Local deltaAngZ=EntityRoll(Entity,1)- phBodyGetRoll(Body)

;обрезаем полученный угол до диапазона от -180 до +180
If Abs(deltaAngX)> 180 Then deltaAngX = deltaAngX -360 * deltaAngX/Abs(deltaAngX)
If Abs(deltaAngY)> 180 Then deltaAngY = deltaAngY -360 * deltaAngY/Abs(deltaAngY)
If Abs(deltaAngZ)> 180 Then deltaAngZ = deltaAngZ -360 * deltaAngZ/Abs(deltaAngZ)
Local OmegaX#=(deltaAngZ)Mod 360
Local OmegaY#=(deltaAngZ)Mod 360
Local OmegaZ#=(deltaAngZ)Mod 360

;разворачиваем вектор скорости в обратную сторону
OmegaX=OmegaX*-1
OmegaY=OmegaY*-1
OmegaZ=OmegaZ*-1

;Вычисляем линейную скорость Entity исходя из разницы координат тела и Entity
Local fdeltax#=EntityX(Entity,1)-phBodyGetX(Body)
Local fdeltay#=EntityY(Entity,1)-phBodyGetY(Body)
Local fdeltaz#=EntityZ(Entity,1)-phBodyGetZ(Body)

Local k = phTiming*60 ;Коэффициент скорости. Пришлось оставить Int. Иначе падает точность :(  		

Local VelX# = fdeltax*a*k
Local VelY# = fdeltay*a*k
Local VelZ# = fdeltaz*a*k

;придаем телу угловую и линейную скорость
phBodySetVel(Body,VelX,VelY,VelZ)
phBodySetOmega(Body,OmegaX,OmegaY,OmegaZ)

End Function
P.s. На blitz'e пишу недавно, поэтому не ругайте, если в коде что то коряво.
(Offline)
 
Ответить с цитированием
Старый 20.01.2010, 21:08   #2
H@NON
Дэвелопер
 
Регистрация: 17.01.2007
Сообщений: 1,552
Написано 351 полезных сообщений
(для 772 пользователей)
Ответ: синхронизация физики и анимации (newton)

Решил вот дополнить для интересующихся синхронизацию физики с анимацией на Physics'е, да и работает стабильнее.
Global tempPiv = CreatePivot()

;--- Параметры : тело, ентити, масса тела, коэффициент упругости
Function pxSyncBodyWithEntity(body, ent, mass#, k#=1)
    Local x#, y#, z#
    Local pit#, yaw#, roll#
    
    Local dx#, dy#, dz#
    Local dPit#, dYaw#, dRoll#
    
    x = pxBodyGetPositionX(body)
    y = pxBodyGetPositionY(body)
    z = pxBodyGetPositionZ(body)
    pit = pxBodyGetRotationPitch(body)
    yaw = pxBodyGetRotationYaw(body)
    roll = pxBodyGetRotationRoll(body)
    
    RotateEntity tempPiv, pit, yaw, roll, 1
    
    dx = EntityX(ent,1) - x
    dy = EntityY(ent,1) - y
    dz = EntityZ(ent,1) - z
    
    TFormVector 0, 0, 1, ent, tempPiv
    x = TFormedX() : y = TFormedY() : z = TFormedZ()
    dPit = VectorAngle#(0,0,1, 0,y,z)
    dYaw = VectorAngle#(0,0,1, x,0,z)
    TFormVector 1, 0, 0, ent, tempPiv
    x = TFormedX() : y = TFormedY() : z = TFormedZ()
    dRoll = VectorAngle#(1,0,0, x,y,0)

    EntityParent ent, tempPiv
    dPit = dPit * Sgn(EntityPitch(ent,0))
    dYaw = dYaw * - Sgn(EntityYaw(ent,0))
    dRoll = dRoll * Sgn(EntityRoll(ent,0))
    EntityParent ent, 0
    
    ;---- ВАРИАНТ 1. действует трение
    x = pxBodyGetLinearSpeedX(body)
    y = pxBodyGetLinearSpeedY(body)
    z = pxBodyGetLinearSpeedZ(body)
    pxBodyAddForce(body, (dx*mass-x)*k, (dy*mass-y)*k, (dz*mass-z)*k, 2)
    x = pxBodyGetLocalAngularSpeedX(body)
    y = pxBodyGetLocalAngularSpeedY(body)
    z = pxBodyGetLocalAngularSpeedZ(body)
    pxBodyAddLocalTorque(body, (dPit-x)*k, (dYaw-y)*k, (dRoll-z)*k, 2)
    
    ;---- ВАРИАНТ 2. без воздействия трения
    ;pxBodySetLinearSpeed(body, dx*mass*k, dy*mass*k, dz*mass*k)
    ;pxBodySetLocalAngularSpeed(body, dPit*k, dYaw*k, dRoll*k)
End Function

Function VectorAngle#(Ax#,Ay#,Az#, Bx#,By#,Bz#)
    Local d# = VectorDot(Ax#,Ay#,Az#, Bx#,By#,Bz#)
    Local m# = VectorMagnitude(Ax#,Ay#,Az#)*VectorMagnitude(Bx#,By#,Bz#)
    Return ACos(d#/m#)
End Function

Function VectorDot#(Ax#,Ay#,Az#, Bx#,By#,Bz#)
    Return (Ax*Bx) + (Ay*By) + (Az*Bz)
End Function
    
Function VectorMagnitude#(Ax#,Ay#,Az#)
    Return Sqr(Ax*Ax + Ay*Ay + Az*Az)
End Function
PS
Обратная величина будет так :
a# = phTiming ^(-1)
(Offline)
 
Ответить с цитированием
Эти 4 пользователя(ей) сказали Спасибо H@NON за это полезное сообщение:
CRASHER (08.06.2011), Si-Jey (22.03.2010), St_AnGer (22.03.2010), tormoz (21.03.2010)
Ответ


Опции темы

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

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

Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
Спрайты,немного физики и прочяя шняга! Антихрист 3D-программирование 6 04.11.2007 07:33
Синхронизация HolyDel Blitz3D 31 19.08.2007 12:21
Вопрос по созданию физики. BAK$$$ 3D-программирование 7 17.07.2007 06:27
Анимации. Как загрузить много анимаций? Nunan 3D-программирование 23 17.01.2007 23:20
Физики-автолюбители, нужна помощь Platon 3D-программирование 8 19.11.2006 18:03


Часовой пояс GMT +1, время: 11:17.


vBulletin® Version 3.6.5.
Copyright ©2000 - 2018, Jelsoft Enterprises Ltd.
Перевод: zCarot
Style crйe par Allan - vBulletin-Ressources.com