Дэвелопер
Регистрация: 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
|