Показать сообщение отдельно
Старый 02.04.2009, 09:55   #7
Venom
Оператор ЭВМ
 
Регистрация: 25.02.2008
Сообщений: 24
Написано 8 полезных сообщений
(для 30 пользователей)
Ответ: Памагитяяяяяяяяяя...

Сообщение от NitE Посмотреть сообщение
ну вот ябы сделал конус, припарентил-бы его к голове бота, сделалбы колизийй с игроком, если коллизится то типа заметил
Зачем же извращатся так Как-то мне приходилось решать эту задачу. Математика выручила Надо найти скалярное произведение вектора между наблюдающим и наблюдаемым обьектов и вектора из матрицы трансформации наблюдаемого обьекта:
Local xang#, yang#
Local what%, from%, temp#, view#, dist#

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

;Наблюдаемый обьект
what = CreateSphere()
PositionEntity(what, 0.0, 0.0, 5.0)

;Наблюдающий обьект (для наглядности - камера)
from = CreateCamera()

;Угол обзора +\- 25 градусов
;косинус нужен т.к. сравниваем со скалярным произведением (фактически косинусом угла между векторами)
view = Cos(25) 

;Квадат дистанции "видимости" (сравнивать будет тоже с квадратом для оптимизации)
dist = 100 ;10 ^ 2

;Для наглядности установим такой же угол обзора у камеры
CameraZoom(from, 1.0 / Tan(25)) 

Repeat
    
    ;Управление камерой
    ;-------------------------------------
    xang = xang - MouseXSpeed() * 0.35
    yang = yang + MouseYSpeed() * 0.35
    MoveMouse(400, 300)
    xang = xang - Int(xang * 0.00277778) * 360.0
    If (xang < 0.0) Then
        xang = 360 + xang
    EndIf
    If (yang > +85.0) Then
        yang = +85.0
    EndIf
    If (yang < -85.0) Then
        yang = -85.0
    EndIf
    RotateEntity(from, yang, xang, 0.0)
    If (KeyDown(200)) Then
        MoveEntity(from, 0.0, 0.0, +0.5)
    EndIf
    If (KeyDown(208)) Then
        MoveEntity(from, 0.0, 0.0, -0.5)
    EndIf
    ;-------------------------------------
    
    RenderWorld()
    
    ;-------------------------------------
    ;Матрица трансформации
    ;  0  1  2
    ;0 xx xy xz \
    ;1 yx yy yz  - матрица трансформации (поворот + масштаб)
    ;2 zx zy zz /
    ;3 tx ty tz - вектор сдвига
    ;Вектор из from в what
    xsub = EntityX(what) - EntityX(from);GetMatElement(what, 3, 0) - GetMatElement(from, 3, 0)
    ysub = EntityY(what) - EntityY(from);GetMatElement(what, 3, 1) - GetMatElement(from, 3, 1)
    zsub = EntityZ(what) - EntityZ(from);GetMatElement(what, 3, 2) - GetMatElement(from, 3, 2)
    ;Квадрат длины вектора (квадрат дистанции между обьектами)
    temp = xsub * xsub + ysub * ysub + zsub * zsub
    ;Проверяем квадрат дистанции
    If (temp < dist) Then
        
        Text(10, 10, "Центр обьекта на расстоянии обзора")
        
        ;Обьект на расстоянии видимости, можно вычислять дальше
        ;квадратный корень и обратная величина(чтобы заменить деления умножениями)
        temp = 1.0 / Sqr(temp)
        ;Нормализация
        xsub = xsub * temp
        ysub = ysub * temp
        zsub = zsub * temp
        ;Скалярное произведение с последней строкой from матрицы трансформации
        temp = xsub * GetMatElement(from, 2, 0) + ysub * GetMatElement(from, 2, 1) + zsub * GetMatElement(from, 2, 2)
        ;Сравниваем углы и выводим сообщение
        If (temp > view) Then
        
            Text(10, 20, "Центр обьекта в поле зрения")
            
        EndIf
    EndIf
    ;-------------------------------------
    
    Flip()
Until (KeyDown(1))
End
лучше заюзать вариант на С, т.к. квадратный корень и деление не есть хорошо и можно заменить их быстрым float-magic трюком
extern long entity_in_view(float *from, float *what, float dist, float view) {
    float xsub, ysub, zsub, temp, half;
    long conv;
    xsub = what[16] - from[16];
    ysub = what[17] - from[17];
    zsub = what[18] - from[18];
    temp = xsub * xsub + ysub * ysub + zsub * zsub;
    if (dist < dist) {
        half = temp * 0.5F;
        conv = *(long*)&temp;
        conv = 0x5F3759DF - (conv >> 1);
        temp = *(float*)&conv;
        temp = temp * (1.5F - half * temp * temp);
        xsub *= temp;
        ysub *= temp;
        zsub *= temp;
        return ((xsub * from[28] + ysub * from[29] + zsub * from[30]) > view) ? 1 : 0;
    }
    return 0;
}
И на PureBasic, кому С не в радость
Structure FPTR
    f.f[0]
EndStructure

ProcedureDLL entity_in_view(*from.FPTR, *what.FPTR, dist.f, view.f)
    Static xsub.f, ysub.f, zsub.f, temp.f, half.f, conv, *int.LONG, *flt.FLOAT
    xsub = *what\f[16] - *from\f[16]
    ysub = *what\f[17] - *from\f[17]
    zsub = *what\f[18] - *from\f[18]
    temp = xsub * xsub + ysub * ysub + zsub * zsub
    If (temp < dist)
        half = temp * 0.5
        *int = @temp
        conv = *int\l
        conv = $5F3759DF - (conv >> 1)
        *flt = @conv
        temp = *flt\f
        temp * (1.5 - half * temp * temp)
        xsub * temp
        ysub * temp
        zsub * temp
        temp = xsub * *from\f[28] + ysub * *from\f[29] + zsub * *from\f[30]
        If (temp > view)
            ProcedureReturn 1
        EndIf
    EndIf
    ProcedureReturn 0
EndProcedure
правка: опечатка

Последний раз редактировалось Venom, 02.04.2009 в 17:01.
(Offline)
 
Ответить с цитированием