forum.boolean.name

forum.boolean.name (http://forum.boolean.name/index.php)
-   3D-программирование (http://forum.boolean.name/forumdisplay.php?f=12)
-   -   PhysX и перетаскивание предметов (http://forum.boolean.name/showthread.php?t=18392)

CostUm 22.07.2013 18:23

PhysX и перетаскивание предметов
 
И вновь я с новым вопросом касательно библиотеки PhysX. Не могу осуществить перетаскивание предметов, т.е. подошёл, мышь навёл, кнопку зажал и можно перетаскивать. Не знаю что лучше: лучи, магниты, ещё что-то? Пробовал и с тем и с тем, не вышло ничего даже приближенного. Прошу помощи в примере, или хотя бы пояснении какого-нибудь алгоритма.

Platon 22.07.2013 18:41

Ответ: PhysX и перетаскивание предметов
 
С помощью raypick определяешь обьект и крепишь его к игроку с помощью joint. Как там что в PhysX незнаю, почитай справку что-ли.

Arton 22.07.2013 18:50

Ответ: PhysX и перетаскивание предметов
 
Если не ошибаюсь такое достигается созданием соединения. К. п. вид от первого лица, кликаешь на объект который будешь таскать и в том месте создаётся "временный" joint, между пивотом(который весит перед камерой) и объектом, который берёшь. Как-то так.

St_AnGer 22.07.2013 19:46

Ответ: PhysX и перетаскивание предметов
 
Цитата:

Сообщение от Arton (Сообщение 264011)
Если не ошибаюсь такое достигается созданием соединения. К. п. вид от первого лица, кликаешь на объект который будешь таскать и в том месте создаётся "временный" joint, между пивотом(который весит перед камерой) и объектом, который берёшь. Как-то так.

Как то так. Только не путай человека, между пивотом (пивотом который CreatePivot(), если ты имел ввиду не его - извиняюсь) и телом не может быть создан joint. Joint создаётся только между двумя физическими (!!!) телами в данном враппере, ну или между телом и миром (опять же, физическим).

И да, велика вероятность того, что при соединении Joint'ом вся эта конструкция рухнет в какую нибудь сторону из за сместившегося центра массы (фактически они ведь станут одним телом). Хотя данную проблему можно решить временной заморозкой нужных осей главного тела (pxBodySetFrozenPos..., pxBodySetFrozenRot...), или перемещением центра массы "пикнутого" тела (pxBodySetCMassLocalPosition, pxBodySetCMassGlobalPosition).

Я реализовывал таскалку почти как в HL 2 магнитами, и это очень геморно было в плане реализации. Да, и, тело было в постоянном вращении от ударов (ну тогда я чего то не додумался использовать заморозку поворота, зря). И плюсом тело очень круто улетало если в момент "пиканья" резко убрать взгляд/мышку в сторону, из за очень сильного магнита. Мне, вообщем, не понравилось так.

CostUm 22.07.2013 20:01

Re: PhysX и перетаскивание предметов
 
Ух, думал чутка полегче будет)) а есть какой нибудь хелп, путеводитель по джоинтам?

Platon 22.07.2013 20:26

Ответ: PhysX и перетаскивание предметов
 
В качестве примера можно подсмотреть как подобное сделано в "Penumbra: Overture". Сорцы в свободном доступе, смотреть файл "PlayerState_Interact.cpp", метод cPlayerState_Grab::OnUpdate. Несмотря на то что код там на с++ и в качестве физ. движка используется Newton, суть понять думаю не составит особого труда. Там вроде-бы не используется джоинт, а просто прикладываются силы к телу.

CostUm 22.07.2013 20:54

Re: PhysX и перетаскивание предметов
 
Ну в С++ ладно уж, лезть не буду)

CostUm 22.07.2013 21:14

Re: PhysX и перетаскивание предметов
 
Попробовал сделать что-то вроде этого, но это равным счётом ничего)

If MouseHit(1) Then take()

....

Function take()
pxRaySetPosition(ray, EntityX(cam,1), EntityY(cam,1),EntityZ(cam,1))
TFormVector 0,0,1,cam, 0
DirX# = TFormedX()
DirY# = TFormedY()
DirZ# = TFormedZ()
pxRaySetDir(ray,DirX,DirY,DirZ)
Body = pxRayGetBody(ray,1)
If Body Then
j = pxJointCreateDistance(Body,my_hero, 0,0,0, 0, 0, 0)
pxJointDistanceSetPoint(j, 1, 3)
End If
End Function


Как надо было? :D
Может магнитами полегше будет?

CostUm 23.07.2013 00:59

Re: Ответ: PhysX и перетаскивание предметов
 
Цитата:

Сообщение от St_AnGer (Сообщение 264012)
Как то так. Только не путай человека, между пивотом (пивотом который CreatePivot(), если ты имел ввиду не его - извиняюсь) и телом не может быть создан joint. Joint создаётся только между двумя физическими (!!!) телами в данном враппере, ну или между телом и миром (опять же, физическим).

И да, велика вероятность того, что при соединении Joint'ом вся эта конструкция рухнет в какую нибудь сторону из за сместившегося центра массы (фактически они ведь станут одним телом). Хотя данную проблему можно решить временной заморозкой нужных осей главного тела (pxBodySetFrozenPos..., pxBodySetFrozenRot...), или перемещением центра массы "пикнутого" тела (pxBodySetCMassLocalPosition, pxBodySetCMassGlobalPosition).

Я реализовывал таскалку почти как в HL 2 магнитами, и это очень геморно было в плане реализации. Да, и, тело было в постоянном вращении от ударов (ну тогда я чего то не додумался использовать заморозку поворота, зря). И плюсом тело очень круто улетало если в момент "пиканья" резко убрать взгляд/мышку в сторону, из за очень сильного магнита. Мне, вообщем, не понравилось так.

Если есть можешь кусочек кода показать с перетаскиванием магнитами?

CostUm 23.07.2013 19:17

Re: PhysX и перетаскивание предметов
 
Почему нельзя позиционировать магнит так:

cam=CreateCamera()
piv=CreatePivot()
EntityParent piv,cam

mag=CreateMagnit(1,2,3)

...

While Not KeyDown(1)

pxMagnetSetPosition(mag,EntityX(piv),EntityY(piv), EntityZ(piv))

tirarex 23.07.2013 21:05

Ответ: PhysX и перетаскивание предметов
 

xkeyhit18= xKeyHit(18)
xCameraPick(cam,xMouseX(),xMouseY())

If control_body=0 And xkeyhit18=1

pxRaySetPosition ray,xEntityX(cam,1),xEntityY(cam,1), xEntityZ(cam,1)
pxRaySetDir(ray, xPickedX#() - xEntityX(cam,1), xPickedY#() - xEntityY(cam,1), xPickedZ#() - xEntityZ(cam,1))


cpos_x = pxRayGetPickX(ray,1)
cpos_y = pxRayGetPickY(ray,1)
cpos_z = pxRayGetPickZ(ray,1)
picked_body = pxRayGetBody(ray, 1)

If (picked_body)




control_body = pxBodyCreateSphere(1,1)
pxBodySetPosition(control_body,pxRayGetPickX#(ray, 1),pxRayGetPickY#(ray,1),pxRayGetPickZ#(ray,1))
pxKinematicSet(control_body)
pxBodySetFlagResponse(control_body, 0)



Pick_pos_x# = cpos_x - pxBodyGetPositionX#(picked_body)
Pick_pos_y# = cpos_y - pxBodyGetPositionY#(picked_body)
Pick_pos_z# = cpos_z - pxBodyGetPositionZ#(picked_body)


cJoint = pxJointCreateDistance(picked_body, control_body, Pick_pos_x, Pick_pos_y, Pick_pos_z, 0, 0, 0)


pxJointDistanceSetPoint(cJoint, 0,1)
pxJointSetBreakable (cJoint,550,100000000000)




EndIf
EndIf
;EndIf

If xkeyhit18=1 And control_body=1

pxDeleteBody(control_body)
control_body = 0
pxDeleteJoint(cJoint)
cJoint = 0
EndIf


If control_body
pxBodySetRotation picked_body,0,0,0
pxKinematicSetPosition (control_body, xEntityX(point,1),xEntityY(point,1), xEntityZ(point,1))
jointb=pxJointIsBroken (cJoint)

EndIf

If jointb
pxDeleteBody(control_body)
control_body = 0
pxDeleteJoint(cJoint)
cJoint = 0

EndIf


говнокод но работает , если доработать будет отлично !

CostUm 23.07.2013 21:18

Re: Ответ: PhysX и перетаскивание предметов
 
Цитата:

Сообщение от tirarex (Сообщение 264085)

xkeyhit18= xKeyHit(18)
xCameraPick(cam,xMouseX(),xMouseY())

If control_body=0 And xkeyhit18=1

pxRaySetPosition ray,xEntityX(cam,1),xEntityY(cam,1), xEntityZ(cam,1)
pxRaySetDir(ray, xPickedX#() - xEntityX(cam,1), xPickedY#() - xEntityY(cam,1), xPickedZ#() - xEntityZ(cam,1))


cpos_x = pxRayGetPickX(ray,1)
cpos_y = pxRayGetPickY(ray,1)
cpos_z = pxRayGetPickZ(ray,1)
picked_body = pxRayGetBody(ray, 1)

If (picked_body)




control_body = pxBodyCreateSphere(1,1)
pxBodySetPosition(control_body,pxRayGetPickX#(ray, 1),pxRayGetPickY#(ray,1),pxRayGetPickZ#(ray,1))
pxKinematicSet(control_body)
pxBodySetFlagResponse(control_body, 0)



Pick_pos_x# = cpos_x - pxBodyGetPositionX#(picked_body)
Pick_pos_y# = cpos_y - pxBodyGetPositionY#(picked_body)
Pick_pos_z# = cpos_z - pxBodyGetPositionZ#(picked_body)


cJoint = pxJointCreateDistance(picked_body, control_body, Pick_pos_x, Pick_pos_y, Pick_pos_z, 0, 0, 0)


pxJointDistanceSetPoint(cJoint, 0,1)
pxJointSetBreakable (cJoint,550,100000000000)




EndIf
EndIf
;EndIf

If xkeyhit18=1 And control_body=1

pxDeleteBody(control_body)
control_body = 0
pxDeleteJoint(cJoint)
cJoint = 0
EndIf


If control_body
pxBodySetRotation picked_body,0,0,0
pxKinematicSetPosition (control_body, xEntityX(point,1),xEntityY(point,1), xEntityZ(point,1))
jointb=pxJointIsBroken (cJoint)

EndIf

If jointb
pxDeleteBody(control_body)
control_body = 0
pxDeleteJoint(cJoint)
cJoint = 0

EndIf


говнокод но работает , если доработать будет отлично !

Взял код, стёр не нужные "х", не знаю у кого как, у меня вообще ничего не происходит) Но спасибо хоть за попытку помощи)


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

vBulletin® Version 3.6.5.
Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
Перевод: zCarot