Тема: Armored Fury
Показать сообщение отдельно
Старый 09.01.2010, 18:56   #110
H@NON
Дэвелопер
 
Регистрация: 17.01.2007
Сообщений: 1,552
Написано 351 полезных сообщений
(для 774 пользователей)
Ответ: Armored Fury

Поофтопю про инверсную кинематику. Кому интересно, то вот когда-то писал пример, ссылка на статью прилагается
;====================================================================
; Project: Invers Kinematics for rag doll
; Version: 0.01b
; Author: H@non
; Email: [email protected]
; Copyright: © H@non, 2009 г.
; Description:    http://www.gamedev.ru/articles/?id=30035
;                 книга Рика Пэрента
; http://number-none.com/product/IK%20with%20Quaternion%20Joint%20Limits/index.html                 
;====================================================================


Graphics3D 800, 600, 32, 2
SetBuffer BackBuffer()

Global Camera=CreateCamera ()
MoveEntity Camera, 0, 0, -30

Local lit = CreateLight()
RotateEntity lit, 45, 45, 0

Const GameUPS=60 ; Updates per second
Local Period=1000/GameUPS 
Local FrameTime=MilliSecs()-Period

Local Tween#, Ticks,i,Remaining,StartTime,Elapsed


Global joint1 = CreateCube()
ScaleMesh joint1, 1.5, 1.5, 1.5
EntityColor joint1, 0, 255, 0
PositionEntity joint1, -5,0,0

Global bone1 = CreateCube(joint1)
ScaleMesh bone1, 5, 1, 1
PositionMesh bone1, -5, 0, 0
MoveEntity bone1, 10, 0, 0
EntityParent bone1, joint1

Global joint2 = CopyMesh(joint1,bone1)
EntityColor joint2, 0, 255, 0

Global bone2 = CopyMesh(bone1, joint2)
MoveEntity bone2, 10, 0, 0

Global target = CreateCube()
EntityColor target, 255, 0, 0
PositionEntity target, 7, 10, 5

While Not KeyHit(1)
    
    StartTime = MilliSecs()
    
    Repeat
        Elapsed=MilliSecs()-FrameTime
    Until Elapsed
    
    Ticks=Elapsed / Period
    Tween=Float(Elapsed Mod Period)/Float(Period)
    
    For i=1 To Ticks
        FrameTime=FrameTime+Period
        If i=Ticks Then
            CaptureWorld
        End If
        
        Updatebones()
        
        MoveCamera(Camera)
        
        UpdateWorld
    Next
    RenderWorld Tween
    
    Remaining = Period - (MilliSecs() - StartTime)
    If Remaining > 1 Then 
        Delay (Remaining-1) ; Free some CPU time
    End If
    
    Flip 0
    
Wend

End

Function MoveCamera(camera, speed#=0.5)
    If MouseDown(1) Then
        Local mxs# = MouseXSpeed()
        Local mys# = MouseYSpeed()
        If MouseHit(1) Then
            mxs = 0
            mys = 0
        EndIf
        RotateEntity camera, EntityPitch(camera)+mys*0.5, EntityYaw(camera)-mxs*0.5, 0
        MoveMouse 400, 300
    EndIf
    
    Local up = KeyDown(200) Or KeyDown(17)
    Local down = KeyDown(208) Or KeyDown(31)
    Local Left = KeyDown(203) Or KeyDown(30)
    Local Right = KeyDown(205) Or KeyDown(32)
    
    MoveEntity camera, (Right-Left)*speed, 0, (up-down)*speed
End Function

Function Updatebones()
    Local Rx# = Cos(EntityRoll(joint1,1)+90)
    Local Ry# = Sin(EntityRoll(joint1,1)+90)
    
    Local Fx# = EntityX(target,1) - EntityX(bone2,1)
    Local Fy# = EntityY(target,1) - EntityY(bone2,1)
    
    Local k# = 0.2
    
    Local torque1# = (Fx*Rx+Fy*Ry)*k
    
    ;If torque1 > 1 Then 
    ;    torque1 = 1
    ;ElseIf torque1 < -1 Then
    ;    torque1 = -1
    ;EndIf
        
    
    ;TurnEntity joint1, 0, 0, torque1, True
    
    
    Local Rz# = Sin(EntityPitch(joint1,1)+90)
    Ry# = Sin(EntityPitch(joint1,1)+90)
    
    Local Fz# = EntityZ(target,1) - EntityZ(bone2,1)
    Fy# = EntityY(target,1) - EntityY(bone2,1)
    
    Local torque2# = (Fz*Rz+Fy*Ry)*k
    
    ;TurnEntity joint1, torque1, 0, 0, True
    RotateEntity joint1, EntityPitch(joint1,1), EntityYaw(joint1,1)+torque2, EntityRoll(joint1,1)+torque1
    
    k# = 0.2
    
    Rx# = Cos(EntityRoll(joint2,1)+90)
    Ry# = Sin(EntityRoll(joint2,1)+90)
    
    Fx# = EntityX(target,1) - EntityX(bone2,1)
    Fy# = EntityY(target,1) - EntityY(bone2,1)
    
    torque1# = (Fx*Rx+Fy*Ry)*k
    
    ;If torque2 > 1 Then 
    ;    torque2 = 1
    ;ElseIf torque2 < -1 Then
    ;    torque2 = -1
    ;EndIf
    
    TurnEntity joint2, 0, 0, torque2 , True
    
    Rz# = Sin(EntityPitch(joint2,1)+90)
    Ry# = Sin(EntityPitch(joint2,1)+90)
    
    Fz# = EntityZ(target,1) - EntityZ(bone2,1)
    Fy# = EntityY(target,1) - EntityY(bone2,1)
    
    torque2# = 0;(Fz*Rz+Fy*Ry)*k
    
    ;If torque2 > 1 Then 
    ;    torque2 = 1
    ;ElseIf torque2 < -1 Then
    ;    torque2 = -1
    ;EndIf
    
    RotateEntity joint2, EntityPitch(joint2,0)+torque2, EntityYaw(joint2,0), EntityRoll(joint2,0)+torque1, False
    
    ;TurnEntity joint2, torque2, 0, 0, True
End Function
(Offline)
 
Эти 5 пользователя(ей) сказали Спасибо H@NON за это полезное сообщение:
IGR (11.01.2010), is.SarCasm (09.01.2010), Mr_F_ (10.01.2010), Randomize (12.01.2010), viper86 (11.01.2010)