forum.boolean.name

forum.boolean.name (http://forum.boolean.name/index.php)
-   Полезные функции (http://forum.boolean.name/forumdisplay.php?f=17)
-   -   Автоповорот камеры до нужного угла (http://forum.boolean.name/showthread.php?t=16679)

Жека 21.04.2012 16:58

Автоповорот камеры до нужного угла
 
Вложений: 1
Такая тема: нужно довернуть камеру до нужного угла в автоматическом режиме - сказал проге "доверни!" и камера сама туда поехала по направлению наименьшего угла с возможностью прервать поворачивание.

Я сделал это вот таким образом:
Код:

Graphics3D(600,600,0,2)
SetBuffer(BackBuffer())
AppTitle ("Автоповорот камеры до нужного угла")

Local camPivot% = CreatePivot()
Local cam% = CreateCamera(camPivot)
MoveEntity(cam,0,6,8)
PointEntity(cam,camPivot)
CameraClsColor(cam,50,50,170)

Local cube% = CreateCube()
ScaleEntity(cube,1,2,3)
Local light% = CreateLight()
RotateEntity(light,60,0,0)

Local angle%
Local targetCamAngle#, curCamAngle#, deltaCamAngle#
Local bMoveCam%

Local timeCycleStart%, timeCycleDelta%, timeCycleInterval% = 1000/50

SetFont(LoadFont("Arial Cyr",14))

While Not KeyHit(1)
        ;запоминаем время начала цикла
        timeCycleStart = MilliSecs()
        ;поворот кубика стрелками влево и вправо, при этом отключаем автоповорот
        If(KeyDown(203)) Then TurnEntity(camPivot,0,-2,0) : bMoveCam = False
        If(KeyDown(205)) Then TurnEntity(camPivot,0,2,0) : bMoveCam = False
        angle = -1 ;сбрасываем переменную
        ;кнопками 1-2-3-4 задаём поворот кратный 90 градусов
        If(KeyHit(2)) Then angle = 0
        If(KeyHit(3)) Then angle = 90
        If(KeyHit(4)) Then angle = 180
        If(KeyHit(5)) Then angle = 270
        If(KeyHit(57)) Then angle = Rand(0,360) ;пробел - случайный поворот
        If(angle <> -1) ;тут рандомный угол может получиться -1 и не сработает поворот, но это всего лишь пример
                If(angle > 180) Then angle = angle - 360 ;переводим в блитцевский угол: [0;180]&[-180;0]
                targetCamAngle = angle ;до этого угла надо довернуть
                curCamAngle = EntityYaw(camPivot) ;текущий угол
                deltaCamAngle = targetCamAngle-curCamAngle ;разность
                If(Abs(deltaCamAngle) > 180) Then deltaCamAngle = -deltaCamAngle ;определяем кратчайшее направление
                deltaCamAngle = 3.3*Sgn(deltaCamAngle) ;скорость вращения камеры
                bMoveCam = True ;флаг того что идёт автоповорот
        EndIf
        If(bMoveCam = True) ;автоповорот
                TurnEntity(camPivot,0,deltaCamAngle,0)
                curCamAngle = EntityYaw(camPivot)
                ;если достигли окрестности нужного угла, то ставим точный угол и прекращаем крутить
                ;дробные числа нельзя сравнивать точным равенством, поэтому берётся окрестность
                ;чуть большего размера чем приращение угла
                If(Abs(curCamAngle-targetCamAngle) < Abs(deltaCamAngle)*1.1)
                        bMoveCam = False
                        RotateEntity(camPivot,EntityPitch(camPivot),targetCamAngle,EntityRoll(camPivot))
                EndIf
        EndIf
        RenderWorld()
        Text 10,10,"Текущий угол: "+EntityYaw(camPivot)
        Text 10,30,"Куда надо: "+targetCamAngle
        Text 20,600-100,"Управление:"
        Line(10,600-85,100,600-85)
        Text 10,600-80,"Стрелки влево и вправо - вращать куб"
        Text 10,600-60,"Цифры 1,2,3,4 - начать поворот к углам 0,90,180,270 градусов"
        Text 10,600-40,"Пробел - начать поворот к случайному углу"
        Flip()
        ;сколько времени занял цикл
        timeCycleDelta = MilliSecs()-timeCycleStart
        If(timeCycleDelta < timeCycleInterval) Then Delay(timeCycleInterval-timeCycleDelta) ;если выполнился быстрее чем надо - подождём
Wend

End


Картинка:


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

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